import React, { useState } from "react"; import { View, ScrollView, TouchableOpacity, Alert, Dimensions, Share, } from "react-native"; import { theme, AppContainer, MyText, tw, useManualRefresh, useMarkDataFetchers, MyTouchableOpacity, } from "common-ui"; import { trpc, trpcClient } from "../../../src/trpc-client"; import MaterialIcons from "@expo/vector-icons/MaterialIcons"; import { Ionicons } from "@expo/vector-icons"; import dayjs from "dayjs"; import { LinearGradient } from "expo-linear-gradient"; import { useRouter } from "expo-router"; import VendorSnippetForm from "../../../components/VendorSnippetForm"; import SnippetOrdersView from "../../../components/SnippetOrdersView"; import { SnippetMenu } from "../../../components/SnippetMenu"; import { ProductListDialog } from "../../../components/ProductListDialog"; import { VendorSnippet, VendorSnippetProduct, VendorSnippetForm as VendorSnippetFormType, } from "../../../types/vendor-snippets"; const SnippetItem = ({ snippet, onEdit, onDelete, onViewOrders, onViewProducts, index, }: { snippet: VendorSnippet; onEdit: (snippet: VendorSnippet) => void; onDelete: (id: number) => void; onViewOrders: (snippetCode: string) => void; onViewProducts: (products: VendorSnippetProduct[]) => void; index: number; }) => { const isExpired = snippet.validTill && dayjs(snippet.validTill).isBefore(dayjs()); const handleCopyLink = async () => { try { if (!snippet.accessUrl) { Alert.alert("Error", "No link available"); return; } await Share.share({ message: snippet.accessUrl, }); } catch (error) { Alert.alert("Error", "Failed to share link"); } }; return ( {/* Top Header: ID & Status */} Identifier {snippet.snippetCode} {isExpired ? "Expired" : "Active"} {/* Middle: Delivery Banner */} {snippet.isPermanent ? ( <> Permanent Always Active ) : snippet.slot?.deliveryTime ? ( <> {dayjs(snippet.slot.deliveryTime).format("ddd, MMM DD")} Time: {dayjs(snippet.slot.deliveryTime).format("hh:mm A")} ) : ( <> Schedule Pending N/A )} {snippet.validTill && ( Expires {dayjs(snippet.validTill).format("MMM DD")} )} {/* Stats & Actions */} onViewProducts(snippet.products)} style={tw`flex-row items-center mr-4`} > {snippet.productIds.length} Items Share router.push(`/(drawer)/slots/slot-details?slotId=${snippet.slotId}`)} onPress={() => {}} activeOpacity={0.7} style={tw`flex-row items-center`} > View Slot ); }; export default function VendorSnippets() { // const { data: snippets, isLoading, error, refetch } = useVendorSnippets(); const { data: snippets, isLoading, error, refetch, } = trpc.admin.vendorSnippets.getAll.useQuery(); const createSnippet = trpc.admin.vendorSnippets.create.useMutation(); const updateSnippet = trpc.admin.vendorSnippets.update.useMutation(); const deleteSnippet = trpc.admin.vendorSnippets.delete.useMutation(); // const createSnippet = useCreateVendorSnippet(); // const updateSnippet = useUpdateVendorSnippet(); // const deleteSnippet = useDeleteVendorSnippet(); const router = useRouter(); const [showCreateForm, setShowCreateForm] = useState(false); const [editingSnippet, setEditingSnippet] = useState(null); const [showOrdersView, setShowOrdersView] = useState(false); const [ordersData, setOrdersData] = useState(null); const [showProductList, setShowProductList] = useState(false); const [selectedProducts, setSelectedProducts] = useState(null); useManualRefresh(refetch); useMarkDataFetchers(() => { refetch(); }); const handleCreate = () => { setShowCreateForm(true); setEditingSnippet(null); }; const handleViewProducts = (products: VendorSnippetProduct[]) => { setSelectedProducts(products); setShowProductList(true); }; const handleEdit = (snippet: VendorSnippet) => { // Convert to match the form's expected type const formSnippet: VendorSnippetFormType = { id: snippet.id, snippetCode: snippet.snippetCode, slotId: snippet.slotId || 0, // Convert null to number for form isPermanent: snippet.isPermanent, productIds: snippet.productIds, validTill: snippet.validTill, createdAt: snippet.createdAt, }; setEditingSnippet(formSnippet); setShowCreateForm(true); }; const handleDelete = (id: number) => { deleteSnippet.mutate( { id }, { onSuccess: () => { refetch(); }, }, ); }; const handleViewOrders = async (snippetCode: string) => { try { const result = await trpcClient.admin.vendorSnippets.getOrdersBySnippet.query({ snippetCode, }); if (result.success) { setOrdersData({ orders: result.data, snippetCode: snippetCode, }); setShowOrdersView(true); } else { Alert.alert("Error", "Failed to fetch orders"); } } catch (error: any) { Alert.alert("Error", error.message || "Failed to fetch orders"); } }; if (isLoading) { return ( Loading vendor snippets... ); } if (error) { return ( Error loading snippets ); } if (showOrdersView && ordersData) { return ( { setShowOrdersView(false); setOrdersData(null); }} /> ); } if (showCreateForm) { return ( { setShowCreateForm(false); setEditingSnippet(null); }} onSuccess={() => { setShowCreateForm(false); setEditingSnippet(null); refetch(); }} /> ); } return ( <> {snippets && snippets.length === 0 ? ( No Snippets Yet Start by creating your first vendor identifier using the button below. ) : ( snippets?.map((snippet, index) => ( {index < snippets.length - 1 && ( )} )) )} {/* Global Floating Action Button - Fixed Position */} setShowProductList(false)} products={selectedProducts || []} /> ); }