import React, { useState, useEffect } from "react"; import { View, ScrollView, Dimensions, Alert } from "react-native"; import { Image } from 'expo-image'; import { useRouter } from "expo-router"; import MaterialIcons from "@expo/vector-icons/MaterialIcons"; import { StorageServiceCasual, tw, MyText, MyTouchableOpacity, MiniQuantifier, BottomDropdown, BottomDialog, theme, updateStatusBarColor, } from "common-ui"; import { trpc } from "@/src/trpc-client"; import { useGetCart, useUpdateCartItem, useRemoveFromCart, useAddToCart, type CartType, } from "@/hooks/cart-query-hooks"; import { useGetEssentialConsts } from "@/src/api-hooks/essential-consts.api"; import { useProductSlotIdentifier } from "@/hooks/useProductSlotIdentifier"; import dayjs from "dayjs"; import { LinearGradient } from "expo-linear-gradient"; const { height: screenHeight } = Dimensions.get("window"); interface FloatingCartBarProps { isFlashDelivery?: boolean; isExpanded?: boolean; setIsExpanded?: (value: boolean) => void; } const FloatingCartBar: React.FC = ({ isFlashDelivery = false, isExpanded: controlledIsExpanded, setIsExpanded: controlledSetIsExpanded, }) => { const cartBarColor = isFlashDelivery ? '#f81260' : theme.colors.brand600; const cartBarBorderColor = isFlashDelivery ? '#e11d48' : theme.colors.brand500; const router = useRouter(); const [localIsExpanded, setLocalIsExpanded] = useState(false); const [quantities, setQuantities] = useState>({}); const cartType: CartType = isFlashDelivery ? "flash" : "regular"; const isExpanded = controlledIsExpanded ?? localIsExpanded; const setIsExpanded = controlledSetIsExpanded ?? setLocalIsExpanded; const { data: cartData, refetch: refetchCart } = useGetCart({}, cartType); const { data: constsData } = useGetEssentialConsts(); const { data: slotsData } = trpc.user.slots.getSlotsWithProducts.useQuery(); const { productSlotsMap } = useProductSlotIdentifier(); const cartItems = cartData?.items || []; const itemCount = cartItems.length; const updateCartItem = useUpdateCartItem({ showSuccessAlert: false, showErrorAlert: false, refetchCart: true, }, cartType); const removeFromCart = useRemoveFromCart({ showSuccessAlert: false, showErrorAlert: false, refetchCart: true, }, cartType); const { addToCart = () => { } } = useAddToCart({ showSuccessAlert: false, showErrorAlert: false, refetchCart: true, }, cartType) || {}; useEffect(() => { const initial: Record = {}; cartItems.forEach((item) => { initial[item.id] = item.quantity; }); setQuantities(initial); }, [cartData]); useEffect(() => { if (!cartItems.length || !slotsData?.slots || !productSlotsMap) return; const itemsToUpdate = cartItems.filter(item => { if (!item.slotId) return true; // No slotId const slotExists = slotsData.slots.some(slot => slot.id === item.slotId); return !slotExists; // Slot doesn't exist }); itemsToUpdate.forEach((item) => { const availableSlots = productSlotsMap.get(item.productId) || []; if (availableSlots.length > 0 && !isFlashDelivery) { // don't bother updating slot for flash delivery const nearestSlotId = availableSlots[0]; removeFromCart.mutate({ itemId: item.id }); addToCart(item.productId, item.quantity, nearestSlotId); } }); }, []); const firstItem = cartItems[0]; const expandedHeight = screenHeight * 0.7; // Calculate total cart value and free delivery info const totalCartValue = cartItems.reduce( (sum, item) => { const price = isFlashDelivery ? (item.product.flashPrice ?? item.product.price) : item.product.price; return sum + price * item.quantity; }, 0 ); const freeDeliveryThreshold = isFlashDelivery ? constsData?.flashFreeDeliveryThreshold : constsData?.freeDeliveryThreshold; const remainingForFreeDelivery = Math.max( 0, freeDeliveryThreshold - totalCartValue ); return ( <> {!isExpanded && ( // --- Collapsed View --- itemCount > 0 && setIsExpanded(true)} activeOpacity={0.9} > {itemCount === 0 ? (isFlashDelivery ? "No Flash Items" : "No Items In Cart") : ( <> ₹{totalCartValue} {` • ${itemCount} ${itemCount === 1 ? "Item" : "Items"}`} )} {itemCount > 0 && } {remainingForFreeDelivery > 0 ? ( ₹{remainingForFreeDelivery} more for FREE Delivery ) : itemCount > 0 ? ( Free Delivery Unlocked ) : ( Shop for ₹{freeDeliveryThreshold}+ for free shipping )} router.push( isFlashDelivery ? "/(drawer)/(tabs)/flash-delivery/(cart)/cart" : "/(drawer)/(tabs)/home/cart" )} > Go to Cart )} setIsExpanded(false)} enableDismiss={true}> {/* Header */} Your Cart {itemCount} Items setIsExpanded(false)} > {/* Progress Bar Header */} {remainingForFreeDelivery > 0 && ( Free Delivery Progress {Math.round((totalCartValue / freeDeliveryThreshold) * 100)}% Needed +₹{remainingForFreeDelivery} )} {/* Items List */} {cartItems.map((item, index) => ( {item.product.name.length > 30 ? item.product.name.substring(0, 30) + '...' : item.product.name} { if (value === 0) { removeFromCart.mutate({ itemId: item.id }); } else { setQuantities((prev) => ({ ...prev, [item.id]: value })); updateCartItem.mutate({ itemId: item.id, quantity: value }); } }} step={item.product.incrementStep} showUnits={true} unit={item.product?.unitNotation} /> {item.slotId && slotsData && productSlotsMap.has(item.productId) && ( { const slot = slotsData.slots.find(s => s.id === slotId); return { label: slot ? dayjs(slot.deliveryTime).format("ddd, MMM DD • h:mm A") : "N/A", value: slotId, }; })} onValueChange={(val) => { const newSlot = slotsData.slots.find(s => s.id === val); Alert.alert("Delivery Updated", `Scheduled for ${dayjs(newSlot?.deliveryTime).format("MMM DD, h:mm A")}`); }} triggerComponent={({ onPress, displayText }) => ( {displayText} )} /> )} ₹{(isFlashDelivery ? (item.product.flashPrice ?? item.product.price) : item.product.price) * item.quantity} {index < cartItems.length - 1 && ( )} ))} {/* Fancy Footer */} Subtotal ₹{totalCartValue} {remainingForFreeDelivery === 0 && ( Free Delivery )} router.push( isFlashDelivery ? "/(drawer)/(tabs)/flash-delivery/(cart)/cart" : "/(drawer)/(tabs)/home/cart" )} activeOpacity={0.9} > Go to cart ); }; export default FloatingCartBar;