From 19afb80597ef928033ce25ab4f329ef013bbde70 Mon Sep 17 00:00:00 2001 From: rstubryan Date: Fri, 31 Oct 2025 17:26:56 +0700 Subject: [PATCH] feat(FE-170,174): refactor GradingForm to use grading form handlers and remove approval logic --- .../production/recording/grading/add/page.tsx | 2 +- .../recording/grading/detail/edit/page.tsx | 5 +- .../recording/grading/detail/page.tsx | 7 +- .../recording/grading/{detail => }/layout.tsx | 0 .../recording/grading/form/GradingForm.tsx | 220 +++--------------- 5 files changed, 43 insertions(+), 191 deletions(-) rename src/app/production/recording/grading/{detail => }/layout.tsx (100%) diff --git a/src/app/production/recording/grading/add/page.tsx b/src/app/production/recording/grading/add/page.tsx index c09a816b..2c1859cb 100644 --- a/src/app/production/recording/grading/add/page.tsx +++ b/src/app/production/recording/grading/add/page.tsx @@ -35,7 +35,7 @@ const AddGrading = () => { {(!recordingId || recordingId === 'new' || (!isLoadingRecording && recording && isResponseSuccess(recording))) && ( - + )} ); diff --git a/src/app/production/recording/grading/detail/edit/page.tsx b/src/app/production/recording/grading/detail/edit/page.tsx index bab82777..4403e04a 100644 --- a/src/app/production/recording/grading/detail/edit/page.tsx +++ b/src/app/production/recording/grading/detail/edit/page.tsx @@ -41,8 +41,9 @@ const EditGrading = () => { {!isLoadingRecording && recording && isResponseSuccess(recording) && ( egg.id === parseInt(gradingId || '0'))} - recordingData={recording.data} + initialValues={recording.data.recording_eggs?.find( + (egg) => egg.id === parseInt(gradingId || '0') + )} /> )} diff --git a/src/app/production/recording/grading/detail/page.tsx b/src/app/production/recording/grading/detail/page.tsx index 05901dec..afe1a5bc 100644 --- a/src/app/production/recording/grading/detail/page.tsx +++ b/src/app/production/recording/grading/detail/page.tsx @@ -40,12 +40,13 @@ const DetailGrading = () => { {!isLoadingGrading && grading && isResponseSuccess(grading) && ( egg.id === parseInt(gradingId))} - recordingData={grading.data} + initialValues={grading.data.recording_eggs?.find( + (egg) => egg.id === parseInt(gradingId) + )} /> )} ); }; -export default DetailGrading; \ No newline at end of file +export default DetailGrading; diff --git a/src/app/production/recording/grading/detail/layout.tsx b/src/app/production/recording/grading/layout.tsx similarity index 100% rename from src/app/production/recording/grading/detail/layout.tsx rename to src/app/production/recording/grading/layout.tsx diff --git a/src/components/pages/production/recording/grading/form/GradingForm.tsx b/src/components/pages/production/recording/grading/form/GradingForm.tsx index 2cad7bdb..d07e61b1 100644 --- a/src/components/pages/production/recording/grading/form/GradingForm.tsx +++ b/src/components/pages/production/recording/grading/form/GradingForm.tsx @@ -15,39 +15,31 @@ import { FormHeader } from '@/components/helper/form/FormHeader'; import { RecordingApi } from '@/services/api/production'; import { CreateGradingPayload, - Recording, + UpdateGradingPayload, RecordingEgg, GradingEgg, } from '@/types/api/production/recording'; -import { type BaseApiResponse, FormStepStatus } from '@/types/api/api-general'; +import { type FormStepStatus } from '@/types/api/api-general'; import { RecordingGradingFormSchema, RecordingGradingFormValues, UpdateRecordingGradingFormSchema, getRecordingGradingFormInitialValues, } from '../../form/RecordingForm.schema'; -import { useRecordingFormHandlers } from '../../form/useRecordingFormHandlers'; -import { ProductWarehouseApi } from '@/services/api/inventory'; -import { isResponseSuccess } from '@/lib/api-helper'; import { cn } from '@/lib/helper'; -import { useModal } from '@/components/Modal'; import toast from 'react-hot-toast'; import Card from '@/components/Card'; -import Badge from '@/components/Badge'; import StepItem from '@/components/steps/StepItem'; +import { useModal } from '@/components/Modal'; +import { useGradingFormHandlers } from './useGradingFormHandlers'; interface GradingFormProps { type?: 'add' | 'edit' | 'detail'; initialValues?: RecordingEgg & { grading_eggs?: GradingEgg[] }; - recordingData?: Recording; } -const GradingForm = ({ - type = 'add', - initialValues, - recordingData, -}: GradingFormProps) => { +const GradingForm = ({ type = 'add', initialValues }: GradingFormProps) => { const router = useRouter(); const searchParams = useSearchParams(); const recordingId = searchParams.get('recording_id'); @@ -55,64 +47,45 @@ const GradingForm = ({ [] ); - const [isApproveLoading, setIsApproveLoading] = useState(false); - const [isRejectLoading, setIsRejectLoading] = useState(false); const [formSteps, setFormSteps] = useState(null); - const approveModal = useModal(); - const rejectModal = useModal(); - // ===== API DATA FETCHING ===== - const eggProductsUrl = useMemo(() => { - if (!recordingData?.project_flock_kandangs_id) return null; - const params = new URLSearchParams({ - search: '', - location_id: recordingData.project_flock_kandangs_id.toString(), - }); - return `${ProductWarehouseApi.basePath}?${params.toString()}`; - }, [recordingData]); + // Fetch existing gradings for the recording egg to show recorded data + // Optional: Fetch existing gradings if needed for display purposes + // const existingGradingsUrl = useMemo(() => { + // const recordingEggIdToUse = recordingId || initialValues?.id?.toString(); + // if (!recordingEggIdToUse) return null; + // return `${RecordingApi.basePath}/gradings?recording_egg_id=${recordingEggIdToUse}`; + // }, [recordingId, initialValues]); - const { data: eggProductsData, isLoading: isLoadingEggProducts } = useSWR( - eggProductsUrl, - ProductWarehouseApi.getAllFetcher - ); + // const { data: existingGradings } = useSWR( + // existingGradingsUrl, + // existingGradingsUrl ? RecordingApi.getAllFetcher : null + // ); // ===== DATA PROCESSING ===== - const eggProducts = useMemo(() => { - const options: OptionType[] = []; - if (isResponseSuccess(eggProductsData)) { - eggProductsData.data.forEach((product) => { - const productName = product.product.name; - - if ( - productName.toLowerCase().includes('telur') || - productName.toLowerCase().includes('egg') - ) { - options.push({ - value: product.id, - label: product.product.name, - }); - } - }); - } - - return options; - }, [eggProductsData]); + // No data processing needed - grading form only needs recording_egg_id and grading data // ===== FORM HANDLERS ===== const { deleteModal, recordingFormErrorMessage, isDeleteLoading, - createRecordingHandler, - updateRecordingHandler, + createGradingHandler, + updateGradingHandler, deleteRecordingClickHandler, confirmationModalDeleteClickHandler, - } = useRecordingFormHandlers(initialValues?.id); + } = useGradingFormHandlers(initialValues?.id); const formikInitialValues = useMemo(() => { + let recordingEggId: number | undefined = initialValues?.id; + + if (!recordingEggId) { + recordingEggId = parseInt(recordingId || '0') || 0; + } + return getRecordingGradingFormInitialValues({ - recording_egg_id: initialValues?.id || parseInt(recordingId || '0') || 0, + recording_egg_id: recordingEggId, eggs_grading: initialValues?.grading_eggs?.map((grading: GradingEgg) => ({ grade: grading.grade, @@ -141,74 +114,19 @@ const GradingForm = ({ switch (type) { case 'add': - await createRecordingHandler(gradingPayload as CreateGradingPayload); + await createGradingHandler(gradingPayload as CreateGradingPayload); break; case 'edit': - await updateRecordingHandler( + await updateGradingHandler( initialValues?.id as number, - gradingPayload as CreateGradingPayload + gradingPayload as UpdateGradingPayload ); break; } }, }); - // ===== EVENT HANDLERS ===== - const approveHandler = async () => { - setIsApproveLoading(true); - - const approveResponse = await RecordingApi.customRequest< - BaseApiResponse - >('approvals', { - method: 'POST', - payload: { - action: 'APPROVED', - approvable_ids: [initialValues?.id as number], - notes: 'Approved via Grading Form', - }, - }); - - if (isResponseSuccess(approveResponse)) { - toast.success('Grading berhasil disetujui!'); - approveModal.closeModal(); - router.push('/production/recording'); - } else { - toast.error( - (approveResponse?.message as string) || 'Gagal menyetujui grading' - ); - approveModal.closeModal(); - } - - setIsApproveLoading(false); - }; - - const rejectHandler = async () => { - setIsRejectLoading(true); - - const rejectResponse = await RecordingApi.customRequest< - BaseApiResponse - >('approvals', { - method: 'POST', - payload: { - action: 'REJECTED', - approvable_ids: [initialValues?.id as number], - notes: 'Rejected via Grading Form', - }, - }); - - if (isResponseSuccess(rejectResponse)) { - toast.success('Grading berhasil ditolak!'); - rejectModal.closeModal(); - router.push('/production/recording'); - } else { - toast.error( - (rejectResponse?.message as string) || 'Gagal menolak grading' - ); - rejectModal.closeModal(); - } - - setIsRejectLoading(false); - }; + // Grading form doesn't need approval/reject handlers // Grading Handlers const addGrading = () => { @@ -309,6 +227,8 @@ const GradingForm = ({ } }, [formik]); + // Grading form doesn't need loading state since it only depends on recording_egg_id + return ( <>
@@ -394,9 +314,9 @@ const GradingForm = ({ : 'grid grid-cols-3 gap-4' } > - {type === 'detail' && recordingData ? ( + {type === 'detail' && initialValues ? ( <> - Recording ID#{recordingData.id} + Recording Egg ID#{initialValues.id} ) : ( <> @@ -641,40 +561,6 @@ const GradingForm = ({ Edit )} - {type === 'detail' && ( - <> - - - - )} )} {type !== 'detail' && ( @@ -735,42 +621,6 @@ const GradingForm = ({ onClick: confirmationModalDeleteClickHandler, }} /> - - {/* Approve Confirmation Modal */} - {type === 'detail' && ( - - )} - - {/* Reject Confirmation Modal */} - {type === 'detail' && ( - - )} )}