import React, { useEffect, useMemo, useState } from 'react'; import { View, Text, TouchableOpacity, ScrollView, Image, ImageBackground, } from 'react-native'; import { useNavigation, useRoute, RouteProp } from '@react-navigation/native'; import { StackNavigationProp } from '@react-navigation/stack'; import { getStyles } from './providerDetailsScreen.styles'; import { CatalogItemRow } from '@components'; import { useAppTheme } from '@theme'; import { useAppDispatch, useAppSelector } from '../../../store'; import { addItem } from '../../../store/commonreducers/cart'; import { getProviderCatalogApi, getProvidersApi } from '../../../api/deliveryApi'; import { CatalogItem, Provider } from '../../../interfaces'; import { AppStackParamList } from '../../../navigation/appStack'; type ProviderDetailsNavProp = StackNavigationProp< AppStackParamList, 'ProviderDetailsScreen' >; type ProviderDetailsRouteProp = RouteProp< AppStackParamList, 'ProviderDetailsScreen' >; const FALLBACK_CATEGORIES = ['Pizza', 'Sides', 'Beverages']; const OFFERS = [ { key: 'o1', icon: '🏷️', label: '50% OFF up to ₹100' }, { key: 'o2', icon: '🚚', label: 'Free delivery above ₹299' }, { key: 'o3', icon: '🎁', label: 'Buy 1 Get 1 on combos' }, ]; // --------------------------------------------------------------------------- // Presentational subcomponents // Kept local to this screen since none are reused elsewhere yet. Promote to // @components if a second screen needs them. // --------------------------------------------------------------------------- interface HeroSectionProps { styles: ReturnType; imageUrl?: string; onBack: () => void; } const HeroSection: React.FC = ({ styles, imageUrl, onBack, }) => ( {imageUrl ? ( ) : ( 🍽️ )} 🔗 🤍 ); interface InfoCardProps { styles: ReturnType; name: string; rating: number; deliveryTime: string; tag: string; } const InfoCard: React.FC = ({ styles, name, rating, deliveryTime, tag, }) => ( {name} {rating.toFixed(1)} {tag} • Multi-cuisine 🕐 {deliveryTime} 📍 2.4 km away Open now • Closes 11:30 PM ); interface OffersRowProps { styles: ReturnType; } const OffersRow: React.FC = ({ styles }) => ( {OFFERS.map(offer => ( {offer.icon} {offer.label} ))} ); interface CategoryTabsProps { styles: ReturnType; categories: string[]; activeCategory: string; onSelect: (category: string) => void; } const CategoryTabs: React.FC = ({ styles, categories, activeCategory, onSelect, }) => ( {categories.map(cat => { const isActive = activeCategory === cat; return ( onSelect(cat)} activeOpacity={0.75} > {cat} ); })} ); interface CartStripProps { styles: ReturnType; totalItems: number; totalPrice: number; onPress: () => void; } const CartStrip: React.FC = ({ styles, totalItems, totalPrice, onPress, }) => ( 🛍️ {totalItems} item{totalItems === 1 ? '' : 's'} ₹{totalPrice} View Cart ); // --------------------------------------------------------------------------- // Screen // --------------------------------------------------------------------------- export const ProviderDetailsScreen: React.FC = () => { const { colors } = useAppTheme(); const styles = getStyles(colors); const dispatch = useAppDispatch(); const navigation = useNavigation(); const route = useRoute(); const { providerId, providerName } = route.params; const cartItems = useAppSelector(state => state.cart.items); const [provider, setProvider] = useState(null); const [catalog, setCatalog] = useState([]); const [activeCategory, setActiveCategory] = useState(FALLBACK_CATEGORIES[0]); const resolvedProviderId = providerId || 'p1'; const resolvedProviderName = providerName || 'Pizza Planet'; useEffect(() => { getProviderCatalogApi(resolvedProviderId).then(setCatalog); }, [resolvedProviderId]); useEffect(() => { getProvidersApi().then(providers => { const match = providers.find(p => p.id === resolvedProviderId); if (match) setProvider(match); }); }, [resolvedProviderId]); const categories = useMemo(() => { const fromCatalog = Array.from(new Set(catalog.map(item => item.category))); return fromCatalog.length > 0 ? fromCatalog : FALLBACK_CATEGORIES; }, [catalog]); useEffect(() => { if (!categories.includes(activeCategory)) { setActiveCategory(categories[0]); } }, [categories, activeCategory]); const filteredItems = useMemo( () => catalog.filter(item => item.category === activeCategory), [catalog, activeCategory], ); const getItemQuantity = (itemId: string) => { const match = cartItems.find(i => i.item.id === itemId); return match ? match.quantity : 0; }; const totalItems = cartItems.reduce((sum, i) => sum + i.quantity, 0); const totalPrice = cartItems.reduce( (sum, i) => sum + i.item.price * i.quantity, 0, ); const handleAddItem = (item: CatalogItem) => { dispatch( addItem({ providerId: resolvedProviderId, providerName: resolvedProviderName, item, }), ); }; return ( navigation.goBack()} /> Menu {catalog.length} items {filteredItems.length === 0 && ( 🍽️ No items in this category yet )} {filteredItems.map(item => ( handleAddItem(item)} onRemove={() => {}} /> ))} {totalItems > 0 && ( navigation.navigate('CartScreen')} /> )} ); };