diff --git a/src/components/pages/master-data/kandang/form/KandangForm.tsx b/src/components/pages/master-data/kandang/form/KandangForm.tsx new file mode 100644 index 00000000..f0d68983 --- /dev/null +++ b/src/components/pages/master-data/kandang/form/KandangForm.tsx @@ -0,0 +1,360 @@ +'use client'; + +import { useCallback, useEffect, useMemo, useState } from 'react'; +import { useRouter } from 'next/navigation'; +import { useFormik } from 'formik'; +import { toast } from 'react-hot-toast'; +import useSWR from 'swr'; + +import { Icon } from '@iconify/react'; +import Button from '@/components/Button'; +import TextInput from '@/components/input/TextInput'; +import SelectInput, { OptionType } from '@/components/input/SelectInput'; +import { useModal } from '@/components/Modal'; +import ConfirmationModal from '@/components/modal/ConfirmationModal'; + +import { + KandangFormSchema, + KandangFormValues, + UpdateKandangFormSchema, +} from '@/components/pages/master-data/kandang/form/KandangForm.schema'; +import { isResponseError, isResponseSuccess } from '@/lib/api-helper'; +import { + Kandang, + CreateKandangPayload, + UpdateKandangPayload, +} from '@/types/api/master-data/kandang'; +import { LocationApi, KandangApi } from '@/services/api/master-data'; +import { cn } from '@/lib/helper'; +import { UserApi } from '@/services/api/user'; + +interface KandangFormProps { + type?: 'add' | 'edit' | 'detail'; + initialValues?: Kandang; +} + +const KandangForm = ({ type = 'add', initialValues }: KandangFormProps) => { + const router = useRouter(); + const deleteModal = useModal(); + + const [kandangFormErrorMessage, setKandangFormErrorMessage] = useState(''); + const [isDeleteLoading, setIsDeleteLoading] = useState(false); + + const createKandangHandler = useCallback( + async (payload: CreateKandangPayload) => { + const createKandangRes = await KandangApi.create(payload); + + if (isResponseError(createKandangRes)) { + setKandangFormErrorMessage(createKandangRes.message); + return; + } + + toast.success(createKandangRes?.message as string); + router.push('/master-data/kandang'); + }, + [router] + ); + + const updateKandangHandler = useCallback( + async (kandangId: number, payload: UpdateKandangPayload) => { + const updateKandangRes = await KandangApi.update(kandangId, payload); + + if (updateKandangRes?.status === 'error') { + setKandangFormErrorMessage(updateKandangRes.message); + return; + } + + toast.success(updateKandangRes?.message as string); + router.refresh(); + router.push('/master-data/kandang'); + }, + [router] + ); + + const formikInitialValues = useMemo(() => { + return { + name: initialValues?.name ?? '', + locationId: initialValues?.location?.id ?? 0, + location: initialValues?.location + ? { + value: initialValues.location.id, + label: initialValues.location.name, + } + : null, + picId: initialValues?.pic?.id ?? 0, + pic: initialValues?.pic + ? { + value: initialValues.pic.id, + label: initialValues.pic.name, + } + : null, + }; + }, [initialValues]); + + const formik = useFormik({ + initialValues: formikInitialValues, + validationSchema: + type === 'edit' ? UpdateKandangFormSchema : KandangFormSchema, + onSubmit: async (values) => { + setKandangFormErrorMessage(''); + + const kandangPayload: CreateKandangPayload = { + name: values.name, + location_id: values.locationId, + pic_id: values.picId, + }; + + switch (type) { + case 'add': + await createKandangHandler(kandangPayload); + break; + + case 'edit': + await updateKandangHandler( + initialValues?.id as number, + kandangPayload + ); + break; + } + }, + }); + + const { setValues: formikSetValues } = formik; + + // location + const [locationSelectInputValue, setLocationSelectInputValue] = useState(''); + + const locationsUrl = `${LocationApi.basePath}?${new URLSearchParams({ + search: locationSelectInputValue ?? '', + }).toString()}`; + + const { data: locations, isLoading: isLoadingLocations } = useSWR( + locationsUrl, + LocationApi.getAllFetcher + ); + + const locationOptions = isResponseSuccess(locations) + ? locations?.data.map((location) => ({ + value: location.id, + label: location.name, + })) + : []; + + const locationChangeHandler = (val: OptionType | OptionType[] | null) => { + formik.setFieldTouched('location', true); + formik.setFieldValue('location', val); + + formik.setFieldTouched('locationId', true); + formik.setFieldValue('locationId', (val as OptionType)?.value); + }; + + // PIC + const [picSelectInputValue, setPicSelectInputValue] = useState(''); + + const picsUrl = `${UserApi.basePath}?${new URLSearchParams({ + search: picSelectInputValue ?? '', + }).toString()}`; + + const { data: pics, isLoading: isLoadingPics } = useSWR( + picsUrl, + LocationApi.getAllFetcher + ); + + const picOptions = isResponseSuccess(pics) + ? pics?.data.map((pic) => ({ + value: pic.id, + label: pic.name, + })) + : []; + + const picChangeHandler = (val: OptionType | OptionType[] | null) => { + formik.setFieldTouched('pic', true); + formik.setFieldValue('pic', val); + + formik.setFieldTouched('picId', true); + formik.setFieldValue('picId', (val as OptionType)?.value); + }; + + const deleteKandangClickHandler = () => { + deleteModal.openModal(); + }; + + const confirmationModalDeleteClickHandler = async () => { + setIsDeleteLoading(true); + + await KandangApi.delete(initialValues?.id as number); + + deleteModal.closeModal(); + toast.success('Successfully delete Kandang!'); + setIsDeleteLoading(false); + router.push('/master-data/kandang'); + }; + + useEffect(() => { + formikSetValues(formikInitialValues); + }, [formikSetValues, formikInitialValues]); + + return ( + <> +
+
+ + +

+ {type === 'add' && 'Tambah Kandang'} + {type === 'edit' && 'Edit Kandang'} + {type === 'detail' && 'Detail Kandang'} +

+
+ +
+
+ + + + + +
+ +
+ {type !== 'add' && ( +
+ + + {type !== 'edit' && ( + + )} +
+ )} + + {type !== 'detail' && ( +
+ + + +
+ )} +
+ + {kandangFormErrorMessage && ( +
+ + {kandangFormErrorMessage} +
+ )} +
+
+ + {type !== 'add' && ( + + )} + + ); +}; + +export default KandangForm;