import { useEffect, type FC } from 'react' import { useFormik } from 'formik' import { p as P, Dropdown, pInput as PInput, Checkbox } from 'web-components' import ProductsSelector from './ProductsSelector' import DateInput from './DateInput' import { trpc } from '@/lib/trpc-client' import type { VendorSnippetForm as VendorSnippetFormType } from '@/types/vendor-snippets' interface VendorSnippetFormProps { snippet?: VendorSnippetFormType | null onClose: () => void onSuccess: () => void showIsPermanentCheckbox?: boolean } const VendorSnippetForm: FC = ({ snippet, onClose, onSuccess, showIsPermanentCheckbox = false, }) => { // Fetch slots const { data: slotsData } = trpc.user.slots.getSlots.useQuery() const createSnippet = trpc.admin.vendorSnippets.create.useMutation() const updateSnippet = trpc.admin.vendorSnippets.update.useMutation() const isEditing = !!snippet const formik = useFormik({ initialValues: { snippetCode: snippet?.snippetCode || '', slotId: snippet?.slotId?.toString() || '', isPermanent: snippet?.isPermanent || false, skuIds: snippet?.skuIds?.map(id => id.toString()) || [], validTill: snippet?.validTill ? new Date(snippet.validTill) : null, }, validate: (values) => { const errors: {[key: string]: string} = {} if (!values.snippetCode.trim()) { errors.snippetCode = 'Snippet code is required' } // Validate snippet code only contains alphanumeric characters and underscore const snippetCodeRegex = /^[a-zA-Z0-9_]+$/ if (values.snippetCode && !snippetCodeRegex.test(values.snippetCode)) { errors.snippetCode = 'Snippet code can only contain letters, numbers, and underscores' } // Only require slotId if isPermanent is false if (!values.isPermanent && !values.slotId) { errors.slotId = 'Slot selection is required' } if (values.skuIds.length === 0) { errors.skuIds = 'At least one product must be selected' } return errors }, onSubmit: async (values) => { try { const submitData = { snippetCode: values.snippetCode, slotId: values.isPermanent ? undefined : parseInt(values.slotId || '0'), isPermanent: values.isPermanent, skuIds: values.skuIds.map(id => parseInt(id)), validTill: values.validTill ? values.validTill.toISOString() : undefined, } if (isEditing && snippet) { await updateSnippet.mutateAsync({ id: snippet.id, updates: submitData, }) window.alert('Success: Vendor snippet updated successfully') } else { await createSnippet.mutateAsync(submitData) window.alert('Success: Vendor snippet created successfully') } onSuccess() onClose() } catch (error: any) { window.alert(`Error: ${error.message || 'Failed to save vendor snippet'}`) } }, }) // Generate unique snippet code if creating new (only on mount) useEffect(() => { if (!isEditing && !formik.values.snippetCode) { const timestamp = Date.now() const random = Math.random().toString(36).substring(2, 8) formik.setFieldValue('snippetCode', `VS_${timestamp}_${random}`) } }, [isEditing]) // Removed formik.values.snippetCode from deps const slotOptions = slotsData?.slots.map(slot => ({ label: new Date(slot.deliveryTime).toLocaleString(), value: slot.id.toString(), })) || [] return (

{isEditing ? 'Edit Vendor Snippet' : 'Create Vendor Snippet'}

{/* Snippet Code */}
{formik.errors.snippetCode && formik.touched.snippetCode && (

{formik.errors.snippetCode}

)}
{/* Is Permanent Checkbox */}

Check if this snippet is permanent and not tied to a specific delivery slot

{/* Slot Selection - Only show if not permanent */} {!formik.values.isPermanent && (

Delivery Slot

formik.setFieldValue('slotId', String(value))} className="w-full" /> {formik.errors.slotId && formik.touched.slotId && (

{formik.errors.slotId}

)}
)} {/* Product Selection */}
parseInt(id))} onChange={(selectedProductIds) => formik.setFieldValue('skuIds', (selectedProductIds as number[]).map(id => id.toString()))} multiple={true} label="Select Products" placeholder="Select products" labelFormat={(product) => product.label} /> {formik.errors.skuIds && formik.touched.skuIds && (

{formik.errors.skuIds}

)}
{/* Valid Till Date */}

Valid Till (Optional)

formik.setFieldValue('validTill', date)} placeholder="Select expiry date" showLabel={false} />

Leave empty for no expiry

{/* Submit Button */}
) } export default VendorSnippetForm