import React, { useState } from 'react'; import { MaterialCommunityIcons, Entypo } from '@expo/vector-icons'; import { View, TouchableOpacity, FlatList, Alert, ActivityIndicator } from 'react-native'; import { AppContainer, MyText, tw, MyFlatList , BottomDialog, MyTouchableOpacity, Checkbox } from 'common-ui'; import { trpc } from '@/src/trpc-client'; import { useRouter } from 'expo-router'; import dayjs from 'dayjs'; import { LinearGradient } from 'expo-linear-gradient'; interface SlotItemProps { item: any; router: any; setDialogProducts: React.Dispatch>; setDialogOpen: React.Dispatch>; refetch: () => void; } const SlotItemComponent: React.FC = ({ item: slot, router, setDialogProducts, setDialogOpen, refetch, }) => { const [menuOpen, setMenuOpen] = useState(false); const slotProducts = slot.products?.map((p: any) => p.name).filter(Boolean) || []; const displayProducts = slotProducts.slice(0, 2).join(', '); const isActive = slot.isActive; const statusColor = isActive ? 'bg-green-100 text-green-700' : 'bg-red-100 text-red-700'; const statusText = isActive ? 'Active' : 'Inactive'; const updateSlotCapacity = trpc.admin.slots.updateSlotCapacity.useMutation(); const handleCapacityToggle = () => { updateSlotCapacity.mutate( { slotId: slot.id, isCapacityFull: !slot.isCapacityFull }, { onSuccess: () => { setMenuOpen(false); refetch(); Alert.alert( 'Success', slot.isCapacityFull ? 'Slot capacity reset. It will now be visible to users.' : 'Slot marked as full capacity. It will be hidden from users.' ); }, onError: (error: any) => { Alert.alert('Error', error.message || 'Failed to update slot capacity'); }, } ); }; return ( router.push(`/(drawer)/slots/slot-details?slotId=${slot.id}`)} activeOpacity={0.7} > {/* Header: ID and Status */} Slot #{slot.id} ID: {slot.id} router.push(`/slots/edit/${slot.id}` as any)} style={tw`px-3 py-1 rounded-full bg-pink2 mr-2`} > Edit {statusText} {slot.isCapacityFull && ( FULL )} setMenuOpen(true)} style={tw`ml-2 p-1`} hitSlop={{ top: 10, bottom: 10, left: 10, right: 10 }} > {/* Replicate Menu Dialog */} setMenuOpen(false)}> Slot #{slot.id} Actions {/* Capacity Toggle */} {updateSlotCapacity.isPending ? ( ) : ( )} Mark as Full Capacity {slot.isCapacityFull ? "Slot is hidden from users" : "Hidden from users when full"} {updateSlotCapacity.isPending ? ( ) : ( )} { setMenuOpen(false); router.push(`/slots/add?baseslot=${slot.id}` as any); }} style={tw`py-4 border-b border-gray-200`} > Replicate Slot setMenuOpen(false)} style={tw`py-4 mt-2`} > Cancel {/* Divider */} {/* Details Grid */} {/* Delivery Time */} Delivery {dayjs(slot.deliveryTime).format('DD MMM, h:mm A')} {/* Freeze Time */} Freeze {dayjs(slot.freezeTime).format('DD MMM, h:mm A')} {/* Products */} {slotProducts.length > 0 ? ( Products {displayProducts} {slotProducts.length > 2 && ( { setDialogProducts(slotProducts); setDialogOpen(true); }} > +{slotProducts.length - 2} more )} ) : null} ); }; export default function Slots() { const router = useRouter(); const { data: slotsData, isLoading, refetch } = trpc.admin.slots.getAll.useQuery(); const slots = slotsData?.slots || []; // Dialog state const [dialogOpen, setDialogOpen] = useState(false); const [dialogProducts, setDialogProducts] = useState([]); const [refreshing, setRefreshing] = useState(false); const handleRefresh = async () => { setRefreshing(true); await refetch(); setRefreshing(false); }; if (isLoading) { return ( Loading slots... ); } return ( item.id.toString()} renderItem={({ item }) => ( )} contentContainerStyle={tw`p-4`} onRefresh={handleRefresh} refreshing={refreshing} /> {/* FAB for Add New Slot */} router.push('/slots/add' as any)} activeOpacity={0.95} style={{ position: 'absolute', bottom: 32, right: 24, zIndex: 100 }} > {/* Products Dialog */} setDialogOpen(false)}> All Products index.toString()} renderItem={({ item }) => ( {item} )} showsVerticalScrollIndicator={false} style={tw`max-h-80`} /> ); }