import React, { useState } from 'react'; import { View, TouchableOpacity, Alert, ScrollView } from 'react-native'; import { useFormik } from 'formik'; import { MyText, tw, MyTextInput, MyTouchableOpacity, DateTimePickerMod } from 'common-ui'; import MaterialIcons from '@expo/vector-icons/MaterialIcons'; import ProductsSelector from './ProductsSelector'; import { trpc } from '../src/trpc-client'; interface AvailabilityScheduleFormProps { onClose: () => void; onSuccess: () => void; initialProductIds?: number[]; initialGroupIds?: number[]; } const AvailabilityScheduleForm: React.FC = ({ onClose, onSuccess, initialProductIds, initialGroupIds, }) => { const createSchedule = trpc.admin.productAvailabilitySchedules.create.useMutation(); const { data: groupsData } = trpc.admin.product.getGroups.useQuery(); // Map groups data to match ProductsSelector types (convert price from string to number) const groups = (groupsData?.groups || []).map(group => ({ ...group, products: group.products.map(product => ({ ...product, price: parseFloat(product.price as unknown as string) || 0, })), })); const formik = useFormik({ initialValues: { scheduleName: '', timeDate: null as Date | null, action: 'in' as 'in' | 'out', productIds: initialProductIds || ([] as number[]), groupIds: initialGroupIds || ([] as number[]), }, validate: (values) => { const errors: {[key: string]: string} = {}; if (!values.scheduleName.trim()) { errors.scheduleName = 'Schedule name is required'; } if (!values.timeDate) { errors.timeDate = 'Time is required'; } if (!values.action) { errors.action = 'Action is required'; } if (values.productIds.length === 0) { errors.productIds = 'At least one product must be selected'; } return errors; }, onSubmit: async (values) => { try { // Convert Date to HH:MM string const hours = values.timeDate!.getHours().toString().padStart(2, '0'); const minutes = values.timeDate!.getMinutes().toString().padStart(2, '0'); const timeString = `${hours}:${minutes}`; await createSchedule.mutateAsync({ scheduleName: values.scheduleName, time: timeString, action: values.action, productIds: values.productIds, groupIds: values.groupIds, }); Alert.alert('Success', 'Schedule created successfully'); onSuccess(); onClose(); } catch (error: any) { Alert.alert('Error', error.message || 'Failed to create schedule'); } }, }); const actionOptions = [ { label: 'In Stock', value: 'in' }, { label: 'Out of Stock', value: 'out' }, ]; return ( {/* Header */} Create Availability Schedule {/* Schedule Name */} Schedule Name {formik.touched.scheduleName && formik.errors.scheduleName && ( {formik.errors.scheduleName} )} {/* Time */} Time formik.setFieldValue('timeDate', date)} timeOnly={true} showLabels={false} /> {formik.touched.timeDate && formik.errors.timeDate && ( {formik.errors.timeDate} )} {/* Action */} Action {actionOptions.map((option) => ( formik.setFieldValue('action', option.value)} style={tw`flex-1 flex-row items-center p-4 rounded-lg border ${ formik.values.action === option.value ? 'bg-blue-50 border-blue-500' : 'bg-white border-gray-300' }`} > {formik.values.action === option.value && ( )} {option.label} ))} {/* Products and Groups */} Products & Groups formik.setFieldValue('productIds', value)} groups={groups} selectedGroupIds={formik.values.groupIds} onGroupChange={(groupIds) => formik.setFieldValue('groupIds', groupIds)} showGroups={true} label="Select Products" placeholder="Select products for this schedule" /> {formik.touched.productIds && formik.errors.productIds && ( {formik.errors.productIds} )} {/* Spacer for bottom padding */} {/* Footer Buttons */} Cancel formik.handleSubmit()} disabled={formik.isSubmitting} style={tw`flex-1 py-3 px-4 rounded-lg bg-blue-600 items-center ${ formik.isSubmitting ? 'opacity-50' : '' }`} > {formik.isSubmitting ? 'Creating...' : 'Create Schedule'} ); }; export default AvailabilityScheduleForm;