import React, { useState, useMemo } from 'react'; import { View, ScrollView } from 'react-native'; import { useLocalSearchParams, useRouter } from 'expo-router'; import { tw, useMarkDataFetchers , BottomDialog, MyText, MyTouchableOpacity } from 'common-ui'; import MaterialIcons from '@expo/vector-icons/MaterialIcons'; import { useQueryClient } from '@tanstack/react-query'; import AddressForm from '@/src/components/AddressForm'; import { useAuthenticatedRoute } from '@/hooks/useAuthenticatedRoute'; import { trpc } from '@/src/trpc-client'; import { useGetCart } from '@/hooks/cart-query-hooks'; import { useGetEssentialConsts } from '@/src/api-hooks/essential-consts.api'; import PaymentAndOrderComponent from '@/components/PaymentAndOrderComponent'; import CheckoutAddressSelector from '@/components/CheckoutAddressSelector'; import { useAddressStore } from '@/src/store/addressStore'; interface CheckoutPageProps { isFlashDelivery?: boolean; } const CheckoutPage: React.FC = ({ isFlashDelivery = false }) => { const params = useLocalSearchParams(); const queryClient = useQueryClient(); const router = useRouter(); // Protect checkout route and preserve query params useAuthenticatedRoute({ targetUrl: isFlashDelivery ? '/(drawer)/(tabs)/flash-delivery/checkout' : '/(drawer)/(tabs)/home/checkout', queryParams: params }); const cartType: "regular" | "flash" = isFlashDelivery ? "flash" : "regular"; const { data: cartData, refetch: refetchCart } = useGetCart({}, cartType); console.log({cartType}) const { data: addresses, refetch: refetchAddresses } = trpc.user.address.getUserAddresses.useQuery(); const { data: slotsData, refetch: refetchSlots } = trpc.user.slots.getSlots.useQuery(); const { data: constsData } = useGetEssentialConsts(); const { data: productsData } = trpc.user.product.getAllProductsSummary.useQuery(); useMarkDataFetchers(() => { refetchCart(); refetchAddresses(); refetchSlots(); }); const { selectedAddressId, setSelectedAddressId } = useAddressStore(); const [showAddAddress, setShowAddAddress] = useState(false); const [selectedCouponId, setSelectedCouponId] = useState(null); const cartItems = cartData?.items || []; // Memoized flash-eligible product IDs const flashEligibleProductIds = useMemo(() => { if (!productsData) return new Set(); return new Set( productsData .filter((product: any) => product.isFlashAvailable) .map((product: any) => product.id) ); }, [productsData]); // Parse slots parameter from URL (format: "1:1,2,3;2:4,5") const selectedSlots = useMemo(() => { const slots: Record = {}; if (params.slots) { const slotGroups = (params.slots as string).split(';'); slotGroups.forEach(group => { const [slotIdStr, itemIdsStr] = group.split(':'); const slotId = Number(slotIdStr); const itemIds = itemIdsStr.split(',').map(Number); itemIds.forEach(itemId => { slots[itemId] = slotId; }); }); } return slots; }, [params.slots]); const selectedItems = cartItems.filter(item => { // For flash delivery, check if product supports flash delivery if (isFlashDelivery) { return flashEligibleProductIds.has(item.productId); } // For regular delivery, only include items with assigned slots return selectedSlots[item.id]; }); React.useEffect(() => { if (params.coupons) { const couponId = Number(params.coupons as string); setSelectedCouponId(couponId); } }, [params.coupons]); // Handle empty cart case if (selectedItems.length === 0) { return ( {cartItems.length === 0 ? "Your cart is empty" : "No items to checkout"} {cartItems.length === 0 ? "Add some delicious items to your cart before checking out" : isFlashDelivery ? "None of your cart items are available for flash delivery" : "Please select delivery slots for your items" } router.back()} > Back to Shopping ); } const totalPrice = selectedItems .filter((item) => !item.product?.isOutOfStock) .reduce( (sum, item) => { const price = isFlashDelivery ? (item.product?.flashPrice ?? item.product?.price ?? 0) : (item.product?.price || 0); return sum + price * item.quantity; }, 0 ); const { data: couponsRaw } = trpc.user.coupon.getEligible.useQuery(); const eligibleCoupons = useMemo(() => { if (!couponsRaw?.data) return []; return couponsRaw.data.map(coupon => { let isEligible = true; let ineligibilityReason = ''; if (coupon.maxLimitForUser && coupon.usages.length >= coupon.maxLimitForUser) { isEligible = false; ineligibilityReason = 'Usage limit exceeded'; } if (coupon.minOrder && parseFloat(coupon.minOrder) > totalPrice) { isEligible = false; ineligibilityReason = `Min order ₹${coupon.minOrder}`; } return { id: coupon.id, code: coupon.couponCode, discountType: coupon.discountPercent ? 'percentage' : 'flat', discountValue: parseFloat(coupon.discountPercent || coupon.flatDiscount || '0'), maxValue: coupon.maxValue ? parseFloat(coupon.maxValue) : undefined, minOrder: coupon.minOrder ? parseFloat(coupon.minOrder) : undefined, description: '', exclusiveApply: coupon.exclusiveApply, isEligible, ineligibilityReason: isEligible ? undefined : ineligibilityReason, }; }).filter(coupon => coupon.ineligibilityReason !== 'Usage limit exceeded'); }, [couponsRaw, totalPrice]); const selectedCoupons = useMemo( () => selectedCouponId ? eligibleCoupons?.filter((coupon) => coupon.id === selectedCouponId) : [], [eligibleCoupons, selectedCouponId] ); const discountAmount = useMemo( () => selectedCoupons?.reduce( (sum, coupon) => sum + (coupon.discountType === "percentage" ? Math.min( (totalPrice * coupon.discountValue) / 100, coupon.maxValue || Infinity ) : Math.min(coupon.discountValue, coupon.maxValue || totalPrice)), 0 ) || 0, [selectedCoupons, totalPrice] ); const finalTotal = totalPrice - discountAmount; const deliveryCharge = useMemo(() => { const threshold = isFlashDelivery ? constsData?.flashFreeDeliveryThreshold : constsData?.freeDeliveryThreshold; const charge = isFlashDelivery ? constsData?.flashDeliveryCharge : constsData?.deliveryCharge; return finalTotal < threshold ? charge : 0; }, [finalTotal, constsData, isFlashDelivery]); const finalTotalWithDelivery = finalTotal + deliveryCharge; return ( {/* Checkout Type Header */} router.back()} style={tw`p-2 -ml-2 mr-1`} activeOpacity={0.7} > {isFlashDelivery ? "Flash Delivery Checkout" : "Scheduled Delivery Checkout"} setShowAddAddress(false)}> { setShowAddAddress(false); queryClient.invalidateQueries(); }} /> ); }; export default CheckoutPage;