feat(FE-316): Save and preview uniformity verification

This commit is contained in:
rstubryan
2025-12-27 21:00:07 +07:00
parent ec8ae7561d
commit 549a710a8d
6 changed files with 88 additions and 6 deletions
@@ -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') {
@@ -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<BodyWeightData>[] = useMemo(
() => [
{
accessorKey: 'number',
header: 'No',
cell: (props) => props.row.original.number,
},
{
accessorKey: 'weight',
header: 'Weight (g)',
cell: (props) => (
<span className='font-medium'>{props.row.original.weight}</span>
),
},
],
[]
);
return (
<section className='w-full h-full bg-white border-l border-gray-200'>
{/* Header */}
@@ -43,7 +81,29 @@ const UniformityPreviewForm = () => {
{/* Form Section */}
<div className='divider mt-3'></div>
<section className='w-full px-6'></section>
<section className='w-full px-6'>
{verifyUniformityResult ? (
<div className='flex flex-col gap-4'>
<Table<BodyWeightData>
data={tableData}
columns={columns}
pageSize={20}
className={{ containerClassName: 'mb-10' }}
/>
</div>
) : (
<div className='flex flex-col items-center justify-center py-10 text-gray-400'>
<Icon
icon='mdi:file-document-outline'
width={64}
height={64}
className='mb-4'
/>
<p className='text-lg'>No data available</p>
<p className='text-sm'>Upload a file to verify uniformity</p>
</div>
)}
</section>
</section>
);
};
+7 -3
View File
@@ -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<BaseApiResponse<Uniformity> | undefined> {
): Promise<BaseApiResponse<VerifyUniformityResponse> | 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<BaseApiResponse<Uniformity>>('/verify', {
return await this.customRequest<BaseApiResponse<VerifyUniformityResponse>>(
'/verify',
{
method: 'POST',
payload: formData as unknown as Record<string, unknown>,
});
}
);
}
}
+4
View File
@@ -48,4 +48,8 @@ export const createDrawerUISlice: StateCreator<
isNextStep: false,
setIsNextStep: (isNextStep: boolean) => set({ isNextStep }),
verifyUniformityResult: null,
setVerifyUniformityResult: (result) =>
set({ verifyUniformityResult: result }),
});
+4
View File
@@ -23,3 +23,7 @@ export type VerifyUniformityPayload = {
project_flock_kandang_id: number;
files: File;
};
export type VerifyUniformityResponse = {
body_weights: number[];
};
+3
View File
@@ -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;