mirror of
https://gitlab.com/mbugroup/lti-web-client.git
synced 2026-05-20 13:32:00 +00:00
feat(FE-442): create ProductionResultProjectFlockKandangTable component
This commit is contained in:
+364
@@ -0,0 +1,364 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
import { useEffect, useState } from 'react';
|
||||||
|
import useSWR from 'swr';
|
||||||
|
import { ColumnDef, SortingState } from '@tanstack/react-table';
|
||||||
|
|
||||||
|
import { Icon } from '@iconify/react';
|
||||||
|
import Table from '@/components/Table';
|
||||||
|
import Card from '@/components/Card';
|
||||||
|
import Collapse from '@/components/Collapse';
|
||||||
|
|
||||||
|
import { cn, formatNumber } from '@/lib/helper';
|
||||||
|
import { isResponseSuccess } from '@/lib/api-helper';
|
||||||
|
import { ProductionResult } from '@/types/api/report/production-result';
|
||||||
|
import { useTableFilter } from '@/services/hooks/useTableFilter';
|
||||||
|
import { ProductionResultReportApi } from '@/services/api/report/production-result';
|
||||||
|
|
||||||
|
interface ProductionResultProjectFlockKandangTableProps {
|
||||||
|
projectFlockKandangId?: number;
|
||||||
|
kandangName?: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
const ProductionResultProjectFlockKandangTable = ({
|
||||||
|
projectFlockKandangId,
|
||||||
|
kandangName,
|
||||||
|
}: ProductionResultProjectFlockKandangTableProps) => {
|
||||||
|
const {
|
||||||
|
state: tableFilterState,
|
||||||
|
updateFilter,
|
||||||
|
setPage,
|
||||||
|
setPageSize,
|
||||||
|
toQueryString: getTableFilterQueryString,
|
||||||
|
reset: resetFilter,
|
||||||
|
} = useTableFilter({
|
||||||
|
initial: {
|
||||||
|
filter_by: '',
|
||||||
|
sort_by: '',
|
||||||
|
},
|
||||||
|
paramMap: {
|
||||||
|
pageSize: 'limit',
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
const { data: productionResults, isLoading: isLoadingProductionResults } =
|
||||||
|
useSWR(
|
||||||
|
projectFlockKandangId
|
||||||
|
? `/reports/production-result/${projectFlockKandangId}${getTableFilterQueryString()}`
|
||||||
|
: null,
|
||||||
|
ProductionResultReportApi.getAllProductionResultFetcher,
|
||||||
|
{
|
||||||
|
keepPreviousData: true,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
const [open, setOpen] = useState(false);
|
||||||
|
|
||||||
|
const [sorting, setSorting] = useState<SortingState>([]);
|
||||||
|
|
||||||
|
const productionResultColumns: ColumnDef<ProductionResult>[] = [
|
||||||
|
{
|
||||||
|
header: 'No',
|
||||||
|
cell: (props) => props.row.index + 1,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'woa',
|
||||||
|
header: 'WOA',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'bw',
|
||||||
|
header: 'BW',
|
||||||
|
cell: (props) => formatNumber(props.row.original.bw),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'std_bw',
|
||||||
|
header: 'STD BW',
|
||||||
|
cell: (props) => formatNumber(props.row.original.std_bw),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'uniformity',
|
||||||
|
header: 'Uniformity',
|
||||||
|
cell: (props) => formatNumber(props.row.original.uniformity),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'std_uniformity',
|
||||||
|
header: 'STD Uniformity',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'dep_kum',
|
||||||
|
header: 'Dep Kum',
|
||||||
|
cell: (props) => formatNumber(props.row.original.dep_kum),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'dep_std',
|
||||||
|
header: 'Dep STD',
|
||||||
|
cell: (props) => formatNumber(props.row.original.dep_std),
|
||||||
|
},
|
||||||
|
// Butiran
|
||||||
|
{
|
||||||
|
header: 'Butiran',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
accessorKey: 'butiran_utuh',
|
||||||
|
header: 'Utuh',
|
||||||
|
cell: (props) => formatNumber(props.row.original.butiran_utuh),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'butiran_putih',
|
||||||
|
header: 'Putih',
|
||||||
|
cell: (props) => formatNumber(props.row.original.butiran_putih),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'butiran_retak',
|
||||||
|
header: 'Retak',
|
||||||
|
cell: (props) => formatNumber(props.row.original.butiran_retak),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'butiran_pecah',
|
||||||
|
header: 'Pecah',
|
||||||
|
cell: (props) => formatNumber(props.row.original.butiran_pecah),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'butiran_jumlah',
|
||||||
|
header: 'Jumlah (Butir)',
|
||||||
|
cell: (props) => formatNumber(props.row.original.butiran_jumlah),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'total_butir',
|
||||||
|
header: 'Total Butir',
|
||||||
|
cell: (props) => formatNumber(props.row.original.total_butir),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// Kg
|
||||||
|
{
|
||||||
|
header: 'Kg',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
accessorKey: 'kg_utuh',
|
||||||
|
header: 'Utuh (Kg)',
|
||||||
|
cell: (props) => formatNumber(props.row.original.kg_utuh),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'kg_putih',
|
||||||
|
header: 'Putih (Kg)',
|
||||||
|
cell: (props) => formatNumber(props.row.original.kg_putih),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'kg_retak',
|
||||||
|
header: 'Retak (Kg)',
|
||||||
|
cell: (props) => formatNumber(props.row.original.kg_retak),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'kg_pecah',
|
||||||
|
header: 'Pecah (Kg)',
|
||||||
|
cell: (props) => formatNumber(props.row.original.kg_pecah),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'kg_jumlah',
|
||||||
|
header: 'Jumlah (Kg)',
|
||||||
|
cell: (props) => formatNumber(props.row.original.kg_jumlah),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'total_kg',
|
||||||
|
header: 'Total Kg',
|
||||||
|
cell: (props) => formatNumber(props.row.original.total_kg),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// Persen
|
||||||
|
{
|
||||||
|
header: '%',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
accessorKey: 'persen_utuh',
|
||||||
|
header: 'Utuh',
|
||||||
|
cell: (props) => formatNumber(props.row.original.persen_utuh),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'persen_putih',
|
||||||
|
header: 'Putih',
|
||||||
|
cell: (props) => formatNumber(props.row.original.persen_putih),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'persen_retak',
|
||||||
|
header: 'Retak',
|
||||||
|
cell: (props) => formatNumber(props.row.original.persen_retak),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'persen_pecah',
|
||||||
|
header: 'Pecah',
|
||||||
|
cell: (props) => formatNumber(props.row.original.persen_pecah),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
// Produksi
|
||||||
|
{
|
||||||
|
header: 'Produksi',
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
accessorKey: 'hd',
|
||||||
|
header: 'HD',
|
||||||
|
cell: (props) => formatNumber(props.row.original.hd),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'hd_std',
|
||||||
|
header: 'HD STD',
|
||||||
|
cell: (props) => formatNumber(props.row.original.hd_std),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'fi',
|
||||||
|
header: 'FI',
|
||||||
|
cell: (props) => formatNumber(props.row.original.fi),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'fi_std',
|
||||||
|
header: 'FI STD',
|
||||||
|
cell: (props) => formatNumber(props.row.original.fi_std),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'em',
|
||||||
|
header: 'EM',
|
||||||
|
cell: (props) => formatNumber(props.row.original.em),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'em_std',
|
||||||
|
header: 'EM STD',
|
||||||
|
cell: (props) => formatNumber(props.row.original.em_std),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'ew',
|
||||||
|
header: 'EW',
|
||||||
|
cell: (props) => formatNumber(props.row.original.ew),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'ew_std',
|
||||||
|
header: 'EW STD',
|
||||||
|
cell: (props) => formatNumber(props.row.original.ew_std),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'fcr',
|
||||||
|
header: 'FCR',
|
||||||
|
cell: (props) => formatNumber(props.row.original.fcr),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'fcr_std',
|
||||||
|
header: 'FCR STD',
|
||||||
|
cell: (props) => formatNumber(props.row.original.fcr_std),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'hh',
|
||||||
|
header: 'HH',
|
||||||
|
cell: (props) => formatNumber(props.row.original.hh),
|
||||||
|
},
|
||||||
|
{
|
||||||
|
accessorKey: 'hh_std',
|
||||||
|
header: 'HH STD',
|
||||||
|
cell: (props) => formatNumber(props.row.original.hh_std),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (sorting.length === 1) {
|
||||||
|
updateFilter('filter_by', sorting[0].id);
|
||||||
|
updateFilter('sort_by', sorting[0].desc ? 'desc' : 'asc');
|
||||||
|
} else {
|
||||||
|
updateFilter('filter_by', '');
|
||||||
|
updateFilter('sort_by', '');
|
||||||
|
}
|
||||||
|
}, [sorting]);
|
||||||
|
|
||||||
|
useEffect(() => {
|
||||||
|
if (!open) {
|
||||||
|
setOpen(
|
||||||
|
isResponseSuccess(productionResults)
|
||||||
|
? productionResults.data.length > 0
|
||||||
|
: false
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}, [productionResults, isResponseSuccess]);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Card
|
||||||
|
className={{
|
||||||
|
wrapper: 'w-full',
|
||||||
|
body: 'p-4 shadow',
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<Collapse
|
||||||
|
open={open}
|
||||||
|
onOpenChange={setOpen}
|
||||||
|
title={
|
||||||
|
<div className='card-actions p-4 justify-between items-center w-full'>
|
||||||
|
<div className='card-title'>{kandangName}</div>
|
||||||
|
|
||||||
|
<Icon
|
||||||
|
icon='material-symbols:keyboard-arrow-down'
|
||||||
|
width={24}
|
||||||
|
height={24}
|
||||||
|
className={cn('text-primary transition-transform', {
|
||||||
|
'-rotate-180': open,
|
||||||
|
})}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
}
|
||||||
|
className='w-full!'
|
||||||
|
titleClassName='w-full p-0!'
|
||||||
|
>
|
||||||
|
<div className='w-full p-0'>
|
||||||
|
{/* <div className='flex flex-col gap-2 mb-4'>
|
||||||
|
<div className='w-full flex flex-col sm:flex-row justify-start items-end sm:items-center gap-4'>
|
||||||
|
<DebouncedTextInput
|
||||||
|
name='search'
|
||||||
|
placeholder='Cari Record'
|
||||||
|
value={tableFilterState.search}
|
||||||
|
onChange={searchChangeHandler}
|
||||||
|
className={{ wrapper: 'sm:max-w-3xs' }}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div> */}
|
||||||
|
|
||||||
|
<Table<ProductionResult>
|
||||||
|
data={
|
||||||
|
isResponseSuccess(productionResults)
|
||||||
|
? productionResults?.data
|
||||||
|
: []
|
||||||
|
}
|
||||||
|
columns={productionResultColumns}
|
||||||
|
pageSize={tableFilterState.pageSize}
|
||||||
|
onPageSizeChange={setPageSize}
|
||||||
|
rowOptions={[10, 20, 50, 100]}
|
||||||
|
page={
|
||||||
|
isResponseSuccess(productionResults)
|
||||||
|
? productionResults?.meta?.page
|
||||||
|
: 0
|
||||||
|
}
|
||||||
|
totalItems={
|
||||||
|
isResponseSuccess(productionResults)
|
||||||
|
? productionResults?.meta?.total_results
|
||||||
|
: 0
|
||||||
|
}
|
||||||
|
onPageChange={setPage}
|
||||||
|
isLoading={isLoadingProductionResults}
|
||||||
|
sorting={sorting}
|
||||||
|
setSorting={setSorting}
|
||||||
|
renderFooter={false}
|
||||||
|
className={{
|
||||||
|
containerClassName: cn({
|
||||||
|
'w-full mb-20':
|
||||||
|
isResponseSuccess(productionResults) &&
|
||||||
|
productionResults?.data?.length === 0,
|
||||||
|
}),
|
||||||
|
headerColumnClassName:
|
||||||
|
'px-4 py-3 border-base-content/10 text-base-content/50',
|
||||||
|
}}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</Collapse>
|
||||||
|
</Card>
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
export default ProductionResultProjectFlockKandangTable;
|
||||||
Reference in New Issue
Block a user