import React, { useState, useEffect, useMemo } from "react"; import { View, TouchableOpacity, Alert, ActivityIndicator, } from "react-native"; import { Image } from "expo-image"; import DraggableFlatList, { RenderItemParams, ScaleDecorator, } from "react-native-draggable-flatlist"; import { AppContainer, MyText, tw, BottomDialog, BottomDropdown, } from "common-ui"; 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: string; marketPrice: string | 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 [selectedProductId, setSelectedProductId] = useState(null); // 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 (selectedProductId) { const product = allProducts?.products.find(p => p.id === selectedProductId); if (product && !popularProducts.find(p => p.id === product.id)) { setPopularProducts(prev => [...prev, product as PopularProduct]); setHasChanges(true); setSelectedProductId(null); 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) ); const productOptions = availableProducts.map(product => ({ label: `${product.name} - ₹${product.price}`, value: 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={false} contentContainerStyle={tw`pb-8`} /> )} {/* FAB for Add Product */} setShowAddDialog(true)} style={tw`bg-blue-600 p-4 rounded-full shadow-lg`} > {/* Add Product Dialog */} setShowAddDialog(false)} > Add Popular Item Select a product to add to popular items {availableProducts.length === 0 ? ( All products are already in popular items ) : ( <> setSelectedProductId(val as number)} placeholder="Choose a product..." /> setShowAddDialog(false)} style={tw`flex-1 bg-gray-100 p-3 rounded-lg`} > Cancel Add Product )} ); }