feat(FE-316): Add status badges and result summary tables

This commit is contained in:
rstubryan
2025-12-27 23:15:19 +07:00
parent 78486be3ea
commit c8f47c741a
2 changed files with 183 additions and 9 deletions
@@ -56,9 +56,7 @@ const UniformityPreviewForm = () => {
{
accessorKey: 'weight',
header: 'Weight (g)',
cell: (props) => (
<span className='font-medium'>{props.row.original.weight}</span>
),
cell: (props) => <span>{props.row.original.weight}</span>,
},
],
[]
@@ -14,11 +14,52 @@ import { useRouter } from 'next/navigation';
import toast from 'react-hot-toast';
import { UniformityApi } from '@/services/api/uniformity';
import { isResponseError } from '@/lib/api-helper';
import Badge from '@/components/Badge';
const weightStatusColorMap: Record<string, string> = {
ideal: 'bg-[#00D39033]',
outside: 'bg-error/10',
};
const weightStatusIndicatorColorMap: Record<string, string> = {
ideal: 'bg-[#008000]',
outside: 'bg-error',
};
const weightStatusTextMap: Record<string, string> = {
ideal: 'Ideal',
outside: 'Outside',
};
const getWeightStatusColor = (status: string): string => {
return weightStatusColorMap[status] || 'bg-info';
};
const getWeightStatusIndicatorColor = (status: string): string => {
return weightStatusIndicatorColorMap[status] || 'bg-info';
};
const getWeightStatusText = (status: string): string => {
return weightStatusTextMap[status] || status;
};
type BodyWeightData = {
id: string;
number: number;
weight: number;
status?: 'ideal' | 'outside';
};
type SamplingData = {
id: string;
label: string;
value: string;
};
type ResultData = {
id: string;
label: string;
value: string;
};
const UniformityResultForm = () => {
@@ -81,6 +122,87 @@ const UniformityResultForm = () => {
}
};
const samplingTableData: SamplingData[] = useMemo(() => {
if (!verifyUniformityResult) return [];
return [
{
id: 'sampling-size',
label: 'Sampling size',
value: `1,150 of Birds`,
},
{
id: 'mean-weight',
label: 'Mean Weight',
value: `121 g`,
},
{
id: 'min-limit',
label: 'Min Limit (-10%)',
value: `109 g`,
},
{
id: 'max-limit',
label: 'Max Limit (+10%)',
value: `133 g`,
},
];
}, [verifyUniformityResult]);
const columnsSampling: ColumnDef<SamplingData>[] = useMemo(
() => [
{
accessorKey: 'label',
header: 'Label',
cell: (props) => props.row.original.label,
},
{
accessorKey: 'value',
header: 'Value',
cell: (props) => <span>{props.row.original.value}</span>,
},
],
[]
);
const resultTableData: ResultData[] = useMemo(() => {
if (!verifyUniformityResult) return [];
return [
{
id: 'ideal-birds',
label: 'Ideal Birds',
value: `851 of Birds`,
},
{
id: 'outside-range',
label: 'Outside Range',
value: `299 of Birds`,
},
{
id: 'uniformity',
label: 'Uniformity',
value: `74 %`,
},
];
}, [verifyUniformityResult]);
const resultColumns: ColumnDef<ResultData>[] = useMemo(
() => [
{
accessorKey: 'label',
header: 'Label',
cell: (props) => props.row.original.label,
},
{
accessorKey: 'value',
header: 'Value',
cell: (props) => <span>{props.row.original.value}</span>,
},
],
[]
);
const tableData = useMemo(() => {
if (!verifyUniformityResult) return [];
@@ -91,7 +213,7 @@ const UniformityResultForm = () => {
}));
}, [verifyUniformityResult]);
const columns: ColumnDef<BodyWeightData>[] = useMemo(
const columnsUniformity: ColumnDef<BodyWeightData>[] = useMemo(
() => [
{
accessorKey: 'number',
@@ -101,9 +223,39 @@ const UniformityResultForm = () => {
{
accessorKey: 'weight',
header: 'Weight (g)',
cell: (props) => (
<span className='font-medium'>{props.row.original.weight}</span>
),
cell: (props) => <span>{props.row.original.weight}</span>,
},
{
accessorKey: 'status',
header: 'Status',
cell: (props) => {
const status = props.row.original.status;
return status ? (
<div className='w-full'>
<Badge
statusIndicator={true}
variant='soft'
className={{
badge: `rounded-xl w-full justify-start border border-gray-200 text-black ${getWeightStatusColor(status)}`,
status: getWeightStatusIndicatorColor(status),
}}
>
{getWeightStatusText(status)}
</Badge>
</div>
) : (
<Badge
statusIndicator={true}
variant='soft'
className={{
badge: `rounded-xl w-full justify-start border border-gray-200 text-black bg-[#00D39033]`,
status: 'bg-[#008000]',
}}
>
Ideal
</Badge>
);
},
},
],
[]
@@ -130,15 +282,39 @@ const UniformityResultForm = () => {
<section className='w-full px-6'>
{verifyUniformityResult ? (
<div className='flex flex-col gap-4'>
<div className=''>
<p className='text-sm font-medium mb-5'>Sampling and Range</p>
<Table<SamplingData>
data={samplingTableData}
columns={columnsSampling}
pageSize={4}
className={{
containerClassName: 'mb-0',
paginationClassName: 'hidden',
}}
/>
</div>
<div className=''>
<p className='text-sm font-medium mb-5'>Result</p>
<Table<ResultData>
data={resultTableData}
columns={resultColumns}
pageSize={3}
className={{
containerClassName: 'mb-0',
paginationClassName: 'hidden',
}}
/>
</div>
<div className='mt-4'>
<Table<BodyWeightData>
data={tableData}
columns={columns}
columns={columnsUniformity}
pageSize={15}
className={{ containerClassName: 'mb-5' }}
/>
</div>
{/* Action Buttons */}
<RequirePermission permissions='lti.production.uniformity.create'>
<Button