import React, { useState, useEffect, useMemo } from "react"; import { View, Alert, ActivityIndicator, ScrollView, } from "react-native"; import { TouchableOpacity } from "react-native-gesture-handler"; import { Image } from "expo-image"; import DraggableFlatList, { RenderItemParams, ScaleDecorator, } from "react-native-draggable-flatlist"; import { AppContainer, MyText, tw, BottomDialog, BottomDropdown, MyTouchableOpacity, } from "common-ui"; import ProductsSelector from "../../../components/ProductsSelector"; import { useRouter } from "expo-router"; import { trpc } from "../../../src/trpc-client"; import MaterialIcons from "@expo/vector-icons/MaterialIcons"; import { useQueryClient } from "@tanstack/react-query"; interface PopularProduct { id: number; name: string; shortDescription: string | null; price: number; marketPrice: number | null; unit: string; incrementStep: number; productQuantity: number; storeId: number | null; isOutOfStock: boolean; nextDeliveryDate: string | null; images: string[]; } interface ProductItemProps { item: PopularProduct; drag: () => void; isActive: boolean; onDelete: (id: number) => void; } const ProductItem: React.FC = ({ item, drag, isActive, onDelete, }) => { return ( {/* Drag Handle */} {/* Product Image */} {item.images?.[0] ? ( ) : ( )} {/* Product Info */} {item.name} ₹{item.price} {/* Delete Button */} onDelete(item.id)} style={tw`p-2 ml-2`} > ); }; export default function CustomizePopularItems() { const router = useRouter(); const queryClient = useQueryClient(); const [popularProducts, setPopularProducts] = useState([]); const [hasChanges, setHasChanges] = useState(false); const [showAddDialog, setShowAddDialog] = useState(false); const [selectedProductIds, setSelectedProductIds] = useState([]); // Get current popular items from constants const { data: constants, isLoading: isLoadingConstants, error: constantsError } = trpc.admin.const.getConstants.useQuery(); const { data: allProducts, isLoading: isLoadingProducts, error: productsError } = trpc.common.product.getAllProductsSummary.useQuery({}); const updateConstants = trpc.admin.const.updateConstants.useMutation(); // Initialize popular products from constants useEffect(() => { if (constants && allProducts?.products) { const popularItemsConstant = constants.find(c => c.key === 'popularItems'); let popularIds: number[] = []; if (popularItemsConstant) { const value = popularItemsConstant.value; if (Array.isArray(value)) { // Already an array of IDs popularIds = value.map((id: any) => parseInt(id)); } else if (typeof value === 'string') { // Comma-separated string popularIds = value.split(',').map((id: string) => parseInt(id.trim())).filter(id => !isNaN(id)); } const popularProds: PopularProduct[] = []; for (const id of popularIds) { const product = allProducts.products.find(p => p.id === id); if (product) { popularProds.push(product); } } setPopularProducts(popularProds); } } }, [constants, allProducts]); const handleDragEnd = ({ data }: { data: PopularProduct[] }) => { setPopularProducts(data); setHasChanges(true); }; const handleDelete = (productId: number) => { Alert.alert( "Remove Product", "Are you sure you want to remove this product from popular items?", [ { text: "Cancel", style: "cancel" }, { text: "Remove", style: "destructive", onPress: () => { setPopularProducts(prev => prev.filter(p => p.id !== productId)); setHasChanges(true); } } ] ); }; const handleAddProduct = () => { if (selectedProductIds.length > 0) { const newProducts = selectedProductIds .map(id => allProducts?.products.find(p => p.id === id)) .filter((product): product is NonNullable => product !== undefined && !popularProducts.find(p => p.id === product.id) ); if (newProducts.length > 0) { setPopularProducts(prev => [...prev, ...newProducts as PopularProduct[]]); setHasChanges(true); } setSelectedProductIds([]); setShowAddDialog(false); } }; const handleSave = () => { const popularIds = popularProducts.map(p => p.id); updateConstants.mutate( { constants: [{ key: 'popularItems', value: popularIds }] }, { onSuccess: () => { setHasChanges(false); Alert.alert('Success', 'Popular items updated successfully!'); queryClient.invalidateQueries({ queryKey: ['const.getConstants'] }); }, onError: (error) => { Alert.alert('Error', 'Failed to update popular items. Please try again.'); console.error('Update popular items error:', error); } } ); }; const availableProducts = (allProducts?.products || []).filter( product => !popularProducts.find(p => p.id === product.id) ); // Show loading state while data is being fetched if (isLoadingConstants || isLoadingProducts) { return ( {/* Header */} router.back()} style={tw`p-2 -ml-4`} > Popular Items {/* Spacer for centering */} {/* Loading Content */} {isLoadingConstants ? 'Loading constants...' : 'Loading products...'} ); } // Show error state if queries failed if (constantsError || productsError) { return ( {/* Header */} router.back()} style={tw`p-2 -ml-4`} > Popular Items {/* Spacer for centering */} {/* Error Content */} Error {constantsError ? 'Failed to load constants' : 'Failed to load products'} router.back()} style={tw`mt-6 bg-blue-600 px-6 py-3 rounded-full`} > Go Back ); } return ( {/* Header */} router.back()} style={tw`p-2 -ml-4`} > Popular Items {updateConstants.isPending ? 'Saving...' : 'Save'} {/* Content */} {popularProducts.length === 0 ? ( No popular items configured Add products to display as popular items ) : ( Long press an item to drag and reorder ( )} keyExtractor={(item) => item.id.toString()} onDragEnd={handleDragEnd} showsVerticalScrollIndicator={true} scrollEnabled={true} contentContainerStyle={{ paddingBottom: 80 }} containerStyle={tw`flex-1`} keyboardShouldPersistTaps="handled" /> )} {/* FAB for Add Product - Fixed position */} setShowAddDialog(true)} style={tw`bg-blue-600 p-4 rounded-full shadow-lg elevation-5`} > {/* Add Product Dialog */} { setShowAddDialog(false); setSelectedProductIds([]); }} > Add Popular Items Select products to add to popular items {availableProducts.length === 0 ? ( All products are already in popular items ) : ( <> setSelectedProductIds(val as number[])} multiple={true} label="Select Products" placeholder="Choose products..." labelFormat={(product) => `${product.name} - ₹${product.price}`} /> setShowAddDialog(false)} style={tw`flex-1 bg-gray-100 p-3 rounded-lg`} > Cancel 0 ? 'bg-blue-600' : 'bg-gray-300' } p-3 rounded-lg`} > {selectedProductIds.length > 0 ? `Add ${selectedProductIds.length} Product${selectedProductIds.length > 1 ? 's' : ''}` : 'Add Products'} )} ); }