From 549a710a8d02b3ad8fd12fbd4ee34c9326ccce2f Mon Sep 17 00:00:00 2001 From: rstubryan Date: Sat, 27 Dec 2025 21:00:07 +0700 Subject: [PATCH] feat(FE-316): Save and preview uniformity verification --- .../pages/uniformity/form/UniformityForm.tsx | 7 +++ .../uniformity/form/UniformityPreviewForm.tsx | 62 ++++++++++++++++++- src/services/api/uniformity.ts | 14 +++-- src/stores/ui/slices/drawer.slice.ts | 4 ++ src/types/api/uniformity/uniformity.d.ts | 4 ++ src/types/stores.d.ts | 3 + 6 files changed, 88 insertions(+), 6 deletions(-) diff --git a/src/components/pages/uniformity/form/UniformityForm.tsx b/src/components/pages/uniformity/form/UniformityForm.tsx index ec8314c3..d8c1bda4 100644 --- a/src/components/pages/uniformity/form/UniformityForm.tsx +++ b/src/components/pages/uniformity/form/UniformityForm.tsx @@ -60,6 +60,9 @@ const UniformityForm = ({ ); const isNextStep = useUiStore((s) => s.isNextStep); const setIsNextStep = useUiStore((s) => s.setIsNextStep); + const setVerifyUniformityResult = useUiStore( + (s) => s.setVerifyUniformityResult + ); const [uniformityFormErrorMessage, setUniformityFormErrorMessage] = useState(''); @@ -239,6 +242,10 @@ const UniformityForm = ({ return; } + if (isResponseSuccess(res) && res.data) { + setVerifyUniformityResult(res.data); + } + toast.success(res?.message as string); if (formType === 'add') { diff --git a/src/components/pages/uniformity/form/UniformityPreviewForm.tsx b/src/components/pages/uniformity/form/UniformityPreviewForm.tsx index 7cbd86b9..2e239fbf 100644 --- a/src/components/pages/uniformity/form/UniformityPreviewForm.tsx +++ b/src/components/pages/uniformity/form/UniformityPreviewForm.tsx @@ -1,21 +1,59 @@ 'use client'; +import { useMemo } from 'react'; import { Icon } from '@iconify/react'; +import { ColumnDef } from '@tanstack/react-table'; import Button from '@/components/Button'; import Tooltip from '@/components/Tooltip'; import DrawerHeader from '@/components/helper/drawer/DrawerHeader'; import { useUiStore } from '@/stores/ui/ui.store'; import RequirePermission from '@/components/helper/RequirePermission'; +import Table from '@/components/Table'; + +type BodyWeightData = { + id: string; + number: number; + weight: number; +}; const UniformityPreviewForm = () => { const setExpandedDrawerOpen = useUiStore((s) => s.setExpandedDrawerOpen); const setIsNextStep = useUiStore((s) => s.setIsNextStep); + const verifyUniformityResult = useUiStore((s) => s.verifyUniformityResult); const handleClose = () => { setExpandedDrawerOpen(false); setIsNextStep(false); }; + const tableData = useMemo(() => { + if (!verifyUniformityResult) return []; + + return verifyUniformityResult.body_weights.map((weight, index) => ({ + id: `weight-${index}`, + number: index + 1, + weight: weight, + })); + }, [verifyUniformityResult]); + + const columns: ColumnDef[] = useMemo( + () => [ + { + accessorKey: 'number', + header: 'No', + cell: (props) => props.row.original.number, + }, + { + accessorKey: 'weight', + header: 'Weight (g)', + cell: (props) => ( + {props.row.original.weight} + ), + }, + ], + [] + ); + return (
{/* Header */} @@ -43,7 +81,29 @@ const UniformityPreviewForm = () => { {/* Form Section */}
-
+
+ {verifyUniformityResult ? ( +
+ + data={tableData} + columns={columns} + pageSize={20} + className={{ containerClassName: 'mb-10' }} + /> +
+ ) : ( +
+ +

No data available

+

Upload a file to verify uniformity

+
+ )} +
); }; diff --git a/src/services/api/uniformity.ts b/src/services/api/uniformity.ts index 386c1814..2ccd38fd 100644 --- a/src/services/api/uniformity.ts +++ b/src/services/api/uniformity.ts @@ -2,6 +2,7 @@ import { BaseApiService } from '@/services/api/base'; import { BaseApiResponse } from '@/types/api/api-general'; import { VerifyUniformityPayload, + VerifyUniformityResponse, Uniformity, CreateUniformityPayload, } from '@/types/api/uniformity/uniformity'; @@ -38,7 +39,7 @@ export class UniformityApiService extends BaseApiService< async verifyUniformity( payload: VerifyUniformityPayload - ): Promise | undefined> { + ): Promise | undefined> { const formData = new FormData(); formData.append( 'project_flock_kandang_id', @@ -49,10 +50,13 @@ export class UniformityApiService extends BaseApiService< formData.append('file', payload.files); } - return await this.customRequest>('/verify', { - method: 'POST', - payload: formData as unknown as Record, - }); + return await this.customRequest>( + '/verify', + { + method: 'POST', + payload: formData as unknown as Record, + } + ); } } diff --git a/src/stores/ui/slices/drawer.slice.ts b/src/stores/ui/slices/drawer.slice.ts index 382eaff2..c8eb3c8b 100644 --- a/src/stores/ui/slices/drawer.slice.ts +++ b/src/stores/ui/slices/drawer.slice.ts @@ -48,4 +48,8 @@ export const createDrawerUISlice: StateCreator< isNextStep: false, setIsNextStep: (isNextStep: boolean) => set({ isNextStep }), + + verifyUniformityResult: null, + setVerifyUniformityResult: (result) => + set({ verifyUniformityResult: result }), }); diff --git a/src/types/api/uniformity/uniformity.d.ts b/src/types/api/uniformity/uniformity.d.ts index 5f889dda..b8d1b144 100644 --- a/src/types/api/uniformity/uniformity.d.ts +++ b/src/types/api/uniformity/uniformity.d.ts @@ -23,3 +23,7 @@ export type VerifyUniformityPayload = { project_flock_kandang_id: number; files: File; }; + +export type VerifyUniformityResponse = { + body_weights: number[]; +}; diff --git a/src/types/stores.d.ts b/src/types/stores.d.ts index 7bfa63cd..ff18d06a 100644 --- a/src/types/stores.d.ts +++ b/src/types/stores.d.ts @@ -1,4 +1,5 @@ import type { ReactNode } from 'react'; +import type { VerifyUniformityResponse } from '@/types/api/uniformity/uniformity'; type MainUiSlice = { mainDrawerOpen: boolean; @@ -18,6 +19,8 @@ type DrawerUISlice = { setExpandedDrawerContent: (content: ReactNode) => void; isNextStep: boolean; setIsNextStep: (v: boolean) => void; + verifyUniformityResult: VerifyUniformityResponse | null; + setVerifyUniformityResult: (result: VerifyUniformityResponse | null) => void; }; export type UIStore = MainUiSlice & DrawerUISlice;