import React, { useState } from 'react'; import { Drawer } from 'expo-router/drawer'; import { DrawerContentComponentProps } from '@react-navigation/drawer'; import { View, ScrollView, Alert, Dimensions } from 'react-native'; import { Image } from 'expo-image'; import { useRouter, usePathname } from 'expo-router'; import MaterialIcons from '@expo/vector-icons/MaterialIcons'; import { tw, theme, MyText, MyTouchableOpacity, MyFlatList, AppContainer, MiniQuantifier } from 'common-ui'; import { trpc } from '@/src/trpc-client'; import { useQuickDeliveryStore } from '@/src/store/quickDeliveryStore'; import { useAddToCart, useGetCart, useUpdateCartItem, useRemoveFromCart } from '@/hooks/cart-query-hooks'; import { useHideTabNav } from '@/src/hooks/useHideTabNav'; import CartIcon from '@/components/icons/CartIcon'; import { useSlotStore } from '@/components/stores/slotStore'; import { LinearGradient } from 'expo-linear-gradient'; import FloatingCartBar from '@/components/floating-cart-bar'; import QuickDeliveryAddressSelector from '@/components/QuickDeliveryAddressSelector'; import dayjs from 'dayjs'; const { width: screenWidth } = Dimensions.get("window"); const drawerWidth = 85; // From layout drawerStyle const itemWidth = (screenWidth - drawerWidth - 48) / 2; // Account for drawer width interface SlotLayoutProps { slotId?: number; storeId?: number; baseUrl: string; isForFlashDelivery?: boolean; } function CustomDrawerContent(baseUrl: string, drawerProps: DrawerContentComponentProps, slotIdParent?: number, storeIdParent?: number) { const router = useRouter(); const pathname = usePathname(); const { data: storesData } = trpc.user.stores.getStores.useQuery(); const setStoreId = useSlotStore(state => state.setStoreId); const { slotId, storeId } = useSlotStore(); // Get current pathname to determine active item const currentPath = pathname; // Check if we are on the main 'quick-delivery' page (All products) // const isAllActive = !currentPath.includes('/store/'); const isAllActive = isNaN(storeId as number); const allSlotsUrl = `${baseUrl}${slotId ? `?slotId=${slotId}` : ''}`; return ( {/* All Products Item */} { router.replace(allSlotsUrl as any); }} activeOpacity={0.8} > {isAllActive ? ( ALL ) : ( ALL )} {/* Store Items */} {storesData?.stores?.map(store => { // Check if this specific store is active const isStoreActive = storeId === store.id; // const isStoreActive = currentPath.includes(`/store/${store.id}`); return ( { setStoreId(store.id); const targetUrl = `${baseUrl}${slotId ? `?slotId=${slotId}&storeId=${store.id}` : `?storeId=${store.id}`}`; router.replace(targetUrl as any); }} activeOpacity={0.8} > {isStoreActive ? ( {store.signedImageUrl ? ( ) : ( )} {store.name.replace(/^The\s+/i, '')} {/* Active Pip/Indicator */} ) : ( {store.signedImageUrl ? ( ) : ( )} {store.name.replace(/^The\s+/i, '')} )} ); }) || ( Loading... )} ); } export function SlotLayout({ slotId, storeId, baseUrl, isForFlashDelivery }: SlotLayoutProps) { const router = useRouter(); // const { slotId: paramsSlotId } = useLocalSearchParams(); const isDrawerHidden = useQuickDeliveryStore(state => state.isDrawerHidden); const setSelectedSlotId = useQuickDeliveryStore(state => state.setSelectedSlotId); const setSlotId = useSlotStore(state => state.setSlotId); const handleSlotChange = (newSlotId: number) => { setSelectedSlotId(newSlotId); setSlotId(newSlotId); router.replace(`${baseUrl}?slotId=${newSlotId}` as any); }; const slotQuery = slotId ? trpc.user.slots.getSlotById.useQuery({ slotId: Number(slotId) }) : trpc.user.slots.nextMajorDelivery.useQuery(); const deliveryTime = dayjs(slotQuery.data?.deliveryTime).format('DD MMM hh:mm A'); return ( <> CustomDrawerContent(baseUrl, props, slotId, storeId)} screenOptions={{ headerShown: false, drawerType: 'permanent', drawerStyle: { width: 85, ...(isDrawerHidden && { display: 'none' }), }, headerStyle: { // width: 220, backgroundColor: 'white', }, headerShadowVisible: false, }} > {/* */} {/* */} ); } const formatQuantity = (quantity: number, unit: string): { value: string; display: string } => { if (unit?.toLowerCase() === 'kg' && quantity < 1) { return { value: `${Math.round(quantity * 1000)} g`, display: `${Math.round(quantity * 1000)}g` }; } return { value: `${quantity} ${unit}(s)`, display: `${quantity}${unit}` }; }; const CompactProductCard = ({ item, handleAddToCart, onPress, cartType = "regular", }: { item: any; handleAddToCart: (productId: number) => void; onPress?: () => void; cartType?: "regular" | "flash"; }) => { // Cart management for miniView const { data: cartData } = useGetCart({}, cartType); const updateCartItem = useUpdateCartItem({ showSuccessAlert: false, showErrorAlert: false, refetchCart: true, }, cartType); const removeFromCart = useRemoveFromCart({ showSuccessAlert: false, showErrorAlert: false, refetchCart: true, }, cartType); const cartItem = cartData?.items?.find((cartItem: any) => cartItem.productId === item.id); const quantity = cartItem?.quantity || 0; const handleQuantityChange = (newQuantity: number) => { if (newQuantity === 0 && cartItem) { removeFromCart.mutate({ itemId: cartItem.id }); } else if (newQuantity === 1 && !cartItem) { handleAddToCart(item.id); } else if (cartItem) { updateCartItem.mutate({ itemId: cartItem.id, quantity: newQuantity }); } }; return ( {item.isOutOfStock && ( Out of Stock )} {quantity > 0 ? ( ) : ( handleQuantityChange(1)} activeOpacity={0.8} > )} {item.name} ₹{cartType === "flash" ? (item.flashPrice ?? item.price) : item.price} {item.marketPrice && Number(item.marketPrice) > Number(item.price) && ( ₹{item.marketPrice} )} Quantity: {formatQuantity(item.productQuantity || 1, item.unit).display} ); }; interface SlotProductsProps { slotId?: number; storeId?: number; baseUrl: string; } export function SlotProducts({ slotId:slotIdParent, storeId:storeIdParent, baseUrl, }: SlotProductsProps) { useHideTabNav('quick_delivery'); const [isLoadingDialogOpen, setIsLoadingDialogOpen] = React.useState(false); const router = useRouter(); const slotId = slotIdParent; const storeId = storeIdParent; const storeIdNum = storeId; // const { storeId, slotId: slotIdRaw } = useLocalSearchParams(); // const slotId = Number(slotIdRaw); // const storeIdNum = storeId ? Number(storeId) : undefined; const slotQuery = trpc.user.slots.getSlotById.useQuery({ slotId: slotId! }, { enabled: !!slotId }); const productsQuery = trpc.user.product.getAllProductsSummary.useQuery(); const { addToCart = () => { } } = useAddToCart({ showSuccessAlert: false, showErrorAlert: false, refetchCart: true }, "flash") || {}; const handleAddToCart = (productId: number) => { setIsLoadingDialogOpen(true); addToCart(productId, 1, slotId || 0, () => setIsLoadingDialogOpen(false)); }; if (slotQuery.isLoading || (storeIdNum && productsQuery?.isLoading)) { return ( Loading slot delivery... ); } if (slotQuery.error || (storeIdNum && productsQuery?.error)) { return ( Oops! Failed to load slot delivery ); } if (!slotQuery.data) { return ( Quick Delivery No delivery slot available. ); } const filteredProducts: any[] = storeIdNum ? productsQuery?.data?.filter(p => p.storeId === storeIdNum) || [] : slotQuery.data.products; return ( ( router.push(`/(drawer)/(tabs)/home/product-detail/${item.id}`)} cartType="regular" /> )} keyExtractor={(item, index) => index.toString()} columnWrapperStyle={{ gap: 16, justifyContent: 'flex-start' }} contentContainerStyle={[tw`pb-24 px-4`, { gap: 16 }]} onRefresh={() => slotQuery.refetch()} ListEmptyComponent={ storeIdNum ? ( No products from this store in this slot. ) : null } /> ); } interface FlashDeliveryProductsProps { storeId?: number; baseUrl: string; onProductPress?: (productId: number) => void; } export function FlashDeliveryProducts({ storeId:storeIdParent, baseUrl, onProductPress }: FlashDeliveryProductsProps) { useHideTabNav('quick_delivery'); const [isLoadingDialogOpen, setIsLoadingDialogOpen] = React.useState(false); const router = useRouter(); const storeId = storeIdParent; const storeIdNum = storeId; const productsQuery = trpc.user.product.getAllProductsSummary.useQuery(); const { addToCart = () => { } } = useAddToCart({ showSuccessAlert: false, showErrorAlert: false, refetchCart: true }, "flash") || {}; const handleAddToCart = (productId: number) => { setIsLoadingDialogOpen(true); addToCart(productId, 1, 0, () => setIsLoadingDialogOpen(false)); }; if (storeIdNum && productsQuery?.isLoading) { return ( Loading Flash Delivery... ); } if (storeIdNum && productsQuery?.error) { return ( Oops! Failed to load Flash Delivery ); } // Filter products to only include those eligible for flash delivery let flashProducts: any[] = []; if (storeIdNum) { // Filter by store and flash availability flashProducts = productsQuery?.data?.filter(p => p.storeId === storeIdNum && p.isFlashAvailable) || []; } else { // Show all flash-available products (no slot filtering) flashProducts = productsQuery?.data?.filter(p => p.isFlashAvailable) || []; } return ( ( { if (onProductPress) { onProductPress(item.id); } else { router.push(`/(drawer)/(tabs)/flash-delivery/product-detail/${item.id}`); } }} cartType="flash" /> )} keyExtractor={(item, index) => index.toString()} columnWrapperStyle={{ gap: 16, justifyContent: 'flex-start' }} contentContainerStyle={[tw`pb-24 px-4`, { gap: 16 }]} onRefresh={() => productsQuery.refetch()} ListEmptyComponent={ No Flash Delivery products available. } /> ); }