import React, { useState, useEffect, useMemo } from 'react'; import { View, Text, TouchableOpacity, Alert } from 'react-native'; import { Formik, FieldArray } from 'formik'; import DateTimePickerMod from 'common-ui/src/components/date-time-picker'; import { tw, MyTextInput } from 'common-ui'; import { trpc } from '../src/trpc-client'; import BottomDropdown, { DropdownOption } from 'common-ui/src/components/bottom-dropdown'; interface VendorSnippet { name: string; groupIds: number[]; productIds: number[]; validTill?: string; } interface SlotFormProps { onSlotAdded?: () => void; initialDeliveryTime?: Date | null; initialFreezeTime?: Date | null; initialIsActive?: boolean; slotId?: number; initialProductIds?: number[]; } export default function SlotForm({ onSlotAdded, initialDeliveryTime, initialFreezeTime, initialIsActive = true, slotId, initialProductIds = [], }: SlotFormProps) { const initialValues = { deliveryTime: initialDeliveryTime || null, freezeTime: initialFreezeTime || null, selectedGroupIds: [] as number[], selectedProductIds: initialProductIds, vendorSnippetList: [] as VendorSnippet[], }; const { mutate: createSlot, isPending: isCreating } = trpc.admin.slots.createSlot.useMutation(); const { mutate: updateSlot, isPending: isUpdating } = trpc.admin.slots.updateSlot.useMutation(); const isEditMode = !!slotId; const isPending = isCreating || isUpdating; // Fetch products and groups const { data: productsData } = trpc.common.product.getAllProductsSummary.useQuery({}); const { data: groupsData } = trpc.admin.product.getGroups.useQuery(); const products = productsData?.products || []; const handleFormSubmit = (values: typeof initialValues) => { if (!values.deliveryTime || !values.freezeTime) { Alert.alert('Error', 'Please fill all fields'); return; } const slotData = { deliveryTime: values.deliveryTime.toISOString(), freezeTime: values.freezeTime.toISOString(), isActive: initialIsActive, productIds: values.selectedProductIds, vendorSnippets: values.vendorSnippetList.map(snippet => ({ name: snippet.name, productIds: snippet.productIds, validTill: snippet.validTill, })), }; console.log({snippetList: values.vendorSnippetList}) values.vendorSnippetList.forEach((snippet, index) => { console.log({snippet}) }); if (isEditMode && slotId) { updateSlot( { id: slotId, ...slotData }, { onSuccess: () => { Alert.alert('Success', 'Slot updated successfully!'); onSlotAdded?.(); }, onError: (error: any) => { console.log({msg: JSON.stringify(error.message)}) Alert.alert('Error', error.message || 'Failed to update slot'); }, } ); } else { createSlot( slotData, { onSuccess: () => { Alert.alert('Success', 'Slot created successfully!'); // Reset form // Formik will handle reset onSlotAdded?.(); }, onError: (error: any) => { Alert.alert('Error', error.message || 'Failed to create slot'); }, } ); } }; return ( {({ handleSubmit, values, setFieldValue }) => { // Collect all product IDs from selected groups const allGroupProductIds = (values?.selectedGroupIds || []).flatMap(groupId => { const group = (groupsData?.groups || []).find(g => g.id === groupId); return group?.products.map(p => p.id) || []; }); // Remove duplicates const groupProductIds = [...new Set(allGroupProductIds)]; const productOptions: DropdownOption[] = products.map(product => ({ label: `${product.name}${groupProductIds.includes(product.id) ? ' (from group)' : ''}`, value: product.id.toString(), disabled: groupProductIds.includes(product.id), })); const groupOptions: DropdownOption[] = (groupsData?.groups || []).map(group => ({ label: group.groupName, value: group.id.toString(), })); return ( {isEditMode ? 'Edit Slot' : 'Create New Slot'} Delivery Date & Time setFieldValue('deliveryTime', value)} /> Freeze Date & Time setFieldValue('freezeTime', value)} /> Select Product Groups (Optional) id.toString())} onValueChange={(value) => { const selectedValues = Array.isArray(value) ? value : typeof value === 'string' ? [value] : []; const groupIds = selectedValues.map(v => parseInt(v as string)); setFieldValue('selectedGroupIds', groupIds); // Collect all products from selected groups const allGroupProducts = groupIds.flatMap(groupId => { const group = (groupsData?.groups || []).find(g => g.id === groupId); return group?.products.map(p => p.id) || []; }); // Remove duplicates const uniqueProducts = [...new Set(allGroupProducts)]; setFieldValue('selectedProductIds', uniqueProducts); }} placeholder="Select product groups" multiple={true} /> Select Products (Optional) id.toString())} onValueChange={(value) => { const selectedValues = Array.isArray(value) ? value : typeof value === 'string' ? [value] : []; setFieldValue('selectedProductIds', selectedValues.map(v => Number(v))); }} placeholder="Select products for this slot" multiple={true} /> {/* Vendor Snippets */} {({ push, remove }) => ( Vendor Snippets {values.vendorSnippetList.map((snippet, index) => ( setFieldValue(`vendorSnippetList.${index}.name`, text)} /> values.selectedGroupIds.includes(Number(option.value)) )} value={snippet.groupIds?.map(id => id.toString()) || []} onValueChange={(value) => { const selectedValues = Array.isArray(value) ? value : [value]; const selectedGroupIds = selectedValues.map(v => parseInt(v as string)); setFieldValue(`vendorSnippetList.${index}.groupIds`, selectedGroupIds); // Auto-populate products from selected groups const allSnippetProducts = selectedGroupIds.flatMap(groupId => { const group = (groupsData?.groups || []).find(g => g.id === groupId); return group?.products.map(p => p.id) || []; }); // Remove duplicates const uniqueSnippetProducts = [...new Set(allSnippetProducts)]; setFieldValue(`vendorSnippetList.${index}.productIds`, uniqueSnippetProducts); }} placeholder="Select groups for snippet" multiple={true} /> values.selectedProductIds.includes(Number(option.value)) )} value={snippet.productIds?.map(id => id.toString()) || []} onValueChange={(value) => { const selectedValues = Array.isArray(value) ? value : [value]; setFieldValue(`vendorSnippetList.${index}.productIds`, selectedValues.map(v => parseInt(v as string))); }} placeholder="Select products for snippet" multiple={true} /> remove(index)} style={tw`bg-red-500 px-4 py-2 rounded-lg self-end`} > Remove Snippet ))} push({ name: '', groupIds: [], productIds: [], validTill: '' })} style={tw`bg-blue-500 px-4 py-3 rounded-lg items-center`} > Add Vendor Snippet )} handleSubmit()} disabled={isPending} style={tw`${isPending ? 'bg-pink2' : 'bg-pink1'} p-3 rounded-lg items-center mt-6 pb-4`} > {isPending ? (isEditMode ? 'Updating...' : 'Creating...') : (isEditMode ? 'Update Slot' : 'Create Slot')} )}} ); }