From 71df86c8df4998984b5904cfce135b9568624c46 Mon Sep 17 00:00:00 2001 From: rstubryan Date: Thu, 23 Oct 2025 21:34:40 +0700 Subject: [PATCH] feat(FE-114): integrate location and project flock selection in RecordingForm --- .../recording/form/RecordingForm.tsx | 142 ++++++++++++++---- 1 file changed, 109 insertions(+), 33 deletions(-) diff --git a/src/components/pages/production/recording/form/RecordingForm.tsx b/src/components/pages/production/recording/form/RecordingForm.tsx index 26879c91..944b979a 100644 --- a/src/components/pages/production/recording/form/RecordingForm.tsx +++ b/src/components/pages/production/recording/form/RecordingForm.tsx @@ -2,10 +2,12 @@ import { useMemo, useState, useEffect } from 'react'; import { useFormik } from 'formik'; +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 CheckboxInput from '@/components/input/CheckboxInput'; import ConfirmationModal from '@/components/modal/ConfirmationModal'; import { FormHeader } from '@/components/helper/form/FormHeader'; @@ -21,6 +23,9 @@ import { UpdateRecordingFormSchema, } from './RecordingForm.schema'; import { useRecordingFormHandlers } from './useRecordingFormHandlers'; +import { ProjectFlockApi } from '@/services/api/production'; +import { LocationApi } from '@/services/api/master-data'; +import { isResponseSuccess } from '@/lib/api-helper'; import Card from '@/components/Card'; @@ -34,6 +39,62 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { const [selectedStocks, setSelectedStocks] = useState([]); const [selectedDepletions, setSelectedDepletions] = useState([]); + // State for Location search and selection + const [locationSearchValue, setLocationSearchValue] = useState(''); + const [selectedLocation, setSelectedLocation] = useState(null); + + // State for Project Flock search + const [projectFlockSearchValue, setProjectFlockSearchValue] = useState(''); + + // Fetch Locations data + const locationsUrl = `${LocationApi.basePath}?${new URLSearchParams({ + search: locationSearchValue || '', + }).toString()}`; + + const { data: locations, isLoading: isLoadingLocations } = useSWR( + locationsUrl, + LocationApi.getAllFetcher + ); + + // Fetch Project Flocks data with location filter + const projectFlocksUrl = `${ProjectFlockApi.basePath}?${new URLSearchParams({ + search: projectFlockSearchValue || '', + ...(selectedLocation ? { location_id: selectedLocation.value.toString() } : {}), + }).toString()}`; + + const { data: projectFlocks, isLoading: isLoadingProjectFlocks } = useSWR( + projectFlocksUrl, + ProjectFlockApi.getAllFetcher + ); + + // Extract location options from locations data + const locationOptions = useMemo(() => { + if (!isResponseSuccess(locations)) return []; + + return locations?.data.map((location) => ({ + value: location.id, + label: location.name, + })) || []; + }, [locations]); + + // Extract kandang options from project_flocks data + const projectFlockKandangOptions = useMemo(() => { + if (!isResponseSuccess(projectFlocks)) return []; + + const options: OptionType[] = []; + + projectFlocks?.data.forEach((projectFlock) => { + projectFlock.kandangs.forEach((kandang) => { + options.push({ + value: kandang.id, + label: `${projectFlock.flock.name} - ${projectFlock.area.name} - ${kandang.name}`, + }); + }); + }); + + return options; + }, [projectFlocks]); + const { deleteModal, recordingFormErrorMessage, @@ -114,9 +175,19 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { }); // EVENT HANDLERS - Select Inputs - const projectFlockChangeHandler = (value: string) => { - const projectFlockId = parseInt(value) || 0; - formik.setFieldValue('project_flock_kandang_id', projectFlockId, false); + const locationChangeHandler = (val: OptionType | OptionType[] | null) => { + setSelectedLocation(val as OptionType); + + // Reset project flock selection when location changes + formik.setFieldValue('project_flock_kandang', null); + formik.setFieldValue('project_flock_kandang_id', 0); + }; + + const projectFlockKandangChangeHandler = (val: OptionType | OptionType[] | null) => { + formik.setFieldTouched('project_flock_kandang', true); + formik.setFieldValue('project_flock_kandang', val); + formik.setFieldTouched('project_flock_kandang_id', true); + formik.setFieldValue('project_flock_kandang_id', (val as OptionType)?.value || 0); }; // EVENT HANDLERS - Date Time @@ -303,28 +374,41 @@ const RecordingForm = ({ type = 'add', initialValues }: RecordingFormProps) => { }} >
- { - const value = e.target.value; - formik.setFieldValue( - 'project_flock_kandang_id', - parseInt(value) || 0 - ); - projectFlockChangeHandler(value); - }} - onBlur={formik.handleBlur} + label='Lokasi' + value={selectedLocation} + onChange={locationChangeHandler} + options={locationOptions} + onInputChange={setLocationSearchValue} + isLoading={isLoadingLocations} + isDisabled={type === 'detail'} + placeholder='Pilih Lokasi' + isClearable + isSearchable + /> + + { readOnly={type === 'detail'} placeholder='Masukkan status (0-3)' /> - -
+ + {/* Body Weights Table */} { {/* Stocks Table */} { )} - Product Warehouse ID + Persediaan { {/* Depletions Table */}