import React, { useState } from 'react'; import { View, ScrollView, Alert, FlatList, TouchableOpacity } from 'react-native'; import { theme, AppContainer, MyText, tw, useManualRefresh, useMarkDataFetchers, MyTouchableOpacity, RawBottomDialog, BottomDialog, } from 'common-ui'; import { trpc } from '../../../src/trpc-client'; import MaterialIcons from '@expo/vector-icons/MaterialIcons'; import { Ionicons, Entypo } from '@expo/vector-icons'; import { LinearGradient } from 'expo-linear-gradient'; import AvailabilityScheduleForm from '../../../components/AvailabilityScheduleForm'; interface Schedule { id: number; scheduleName: string; time: string; action: 'in' | 'out'; createdAt: string; lastUpdated: string; productIds: number[]; groupIds: number[]; productCount: number; groupCount: number; } const ScheduleItem = ({ schedule, onDelete, index, onViewProducts, onViewGroups, onReplicate, }: { schedule: Schedule; onDelete: (id: number) => void; index: number; onViewProducts: (productIds: number[]) => void; onViewGroups: (groupIds: number[]) => void; onReplicate: (schedule: Schedule) => void; }) => { const isIn = schedule.action === 'in'; const [menuOpen, setMenuOpen] = useState(false); return ( {/* Top Header: Name & Action Badge */} Schedule Name {schedule.scheduleName} {isIn ? 'In Stock' : 'Out of Stock'} setMenuOpen(true)} style={tw`p-1`} hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }} > {/* Menu Dialog */} setMenuOpen(false)}> {schedule.scheduleName} { setMenuOpen(false); onReplicate(schedule); }} style={tw`py-4 border-b border-gray-200`} > Replicate items { setMenuOpen(false); Alert.alert('Coming Soon', 'Edit functionality will be available soon'); }} style={tw`py-4 border-b border-gray-200`} > Edit { setMenuOpen(false); onDelete(schedule.id); }} style={tw`py-4 border-b border-gray-200`} > Delete setMenuOpen(false)} style={tw`py-4 mt-2`} > Cancel {/* Middle: Time Banner */} {schedule.time} Daily at this time {/* Stats & Actions */} onViewProducts(schedule.productIds)} style={tw`flex-row items-center mr-4`} > {schedule.productCount} Products {schedule.groupCount > 0 && ( onViewGroups(schedule.groupIds)} style={tw`flex-row items-center`} > {schedule.groupCount} Groups )} ); }; export default function StockingSchedules() { const { data: schedules, isLoading, error, refetch, } = trpc.admin.productAvailabilitySchedules.getAll.useQuery(); const { data: productsData } = trpc.common.product.getAllProductsSummary.useQuery({}); const { data: groupsData } = trpc.admin.product.getGroups.useQuery(); const deleteSchedule = trpc.admin.productAvailabilitySchedules.delete.useMutation(); const [showCreateForm, setShowCreateForm] = useState(false); // Dialog state const [dialogOpen, setDialogOpen] = useState(false); const [dialogType, setDialogType] = useState<'products' | 'groups'>('products'); const [selectedIds, setSelectedIds] = useState([]); // Replication state const [replicatingSchedule, setReplicatingSchedule] = useState(null); useManualRefresh(refetch); useMarkDataFetchers(() => { refetch(); }); const handleCreate = () => { setShowCreateForm(true); }; const handleDelete = (id: number) => { Alert.alert( 'Delete Schedule', 'Are you sure you want to delete this schedule? This action cannot be undone.', [ { text: 'Cancel', style: 'cancel' }, { text: 'Delete', style: 'destructive', onPress: () => { deleteSchedule.mutate( { id }, { onSuccess: () => { refetch(); }, onError: (error: any) => { Alert.alert('Error', error.message || 'Failed to delete schedule'); }, }, ); }, }, ], ); }; const handleViewProducts = (productIds: number[]) => { setDialogType('products'); setSelectedIds(productIds); setDialogOpen(true); }; const handleViewGroups = (groupIds: number[]) => { setDialogType('groups'); setSelectedIds(groupIds); setDialogOpen(true); }; const handleReplicate = (schedule: Schedule) => { setReplicatingSchedule(schedule); setShowCreateForm(true); }; const handleCloseForm = () => { setShowCreateForm(false); setReplicatingSchedule(null); }; // Get product/group names from IDs const getProductNames = () => { const allProducts = productsData?.products || []; return selectedIds.map(id => { const product = allProducts.find(p => p.id === id); return product?.name || `Product #${id}`; }); }; const getGroupNames = () => { const allGroups = groupsData?.groups || []; return selectedIds.map(id => { const group = allGroups.find(g => g.id === id); return group?.groupName || `Group #${id}`; }); }; if (showCreateForm) { return ( { refetch(); handleCloseForm(); }} initialProductIds={replicatingSchedule?.productIds} initialGroupIds={replicatingSchedule?.groupIds} /> ); } if (isLoading) { return ( Loading schedules... ); } if (error) { return ( Error loading schedules ); } return ( <> {schedules && schedules.length === 0 ? ( No Schedules Yet Start by creating your first availability schedule using the button below. ) : ( schedules?.map((schedule, index) => ( {index < schedules.length - 1 && ( )} )) )} {/* Products/Groups Dialog */} setDialogOpen(false)}> {dialogType === 'products' ? 'Products' : 'Groups'} index.toString()} renderItem={({ item }) => ( {item} )} showsVerticalScrollIndicator={false} style={tw`max-h-80`} ListEmptyComponent={ No {dialogType} found } /> ); }