feat(FE-438): Add approve/reject flows to UniformityTable

This commit is contained in:
rstubryan
2025-12-28 16:58:29 +07:00
parent b1ccad081d
commit 6e4462e217
@@ -86,6 +86,10 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
const singleDeleteModal = useModal();
const bulkDeleteModal = useModal();
const successModal = useModal();
const singleApproveModal = useModal();
const singleRejectModal = useModal();
const bulkApproveModal = useModal();
const bulkRejectModal = useModal();
const {
data: uniformities,
@@ -136,6 +140,38 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
setIsDeleteLoading(false);
}, [selectedUniformity?.id, refreshUniformities, singleDeleteModal]);
const singleApproveHandler = useCallback(async () => {
setIsDeleteLoading(true);
try {
await UniformityApi.approve([selectedUniformity?.id as number]);
refreshUniformities();
singleApproveModal.closeModal();
toast.success('Successfully approved Uniformity!');
} catch {
toast.error('Failed to approve Uniformity');
} finally {
setIsDeleteLoading(false);
}
}, [selectedUniformity?.id, refreshUniformities, singleApproveModal]);
const singleRejectHandler = useCallback(async () => {
setIsDeleteLoading(true);
try {
await UniformityApi.reject([selectedUniformity?.id as number]);
refreshUniformities();
singleRejectModal.closeModal();
toast.success('Successfully rejected Uniformity!');
} catch {
toast.error('Failed to reject Uniformity');
} finally {
setIsDeleteLoading(false);
}
}, [selectedUniformity?.id, refreshUniformities, singleRejectModal]);
const handleBulkDelete = useCallback(() => {
bulkDeleteModal.openModal();
}, [bulkDeleteModal]);
@@ -164,7 +200,15 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
setRowSelection({});
}, []);
const handleBulkApprove = useCallback(async () => {
const handleBulkApprove = useCallback(() => {
bulkApproveModal.openModal();
}, [bulkApproveModal]);
const handleBulkReject = useCallback(() => {
bulkRejectModal.openModal();
}, [bulkRejectModal]);
const bulkApproveHandler = useCallback(async () => {
setIsBulkActionLoading(true);
try {
@@ -173,6 +217,7 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
setRowSelection({});
refreshUniformities();
bulkApproveModal.closeModal();
toast.success(
`Successfully approved ${selectedRowIds.length} Uniformity data!`
);
@@ -181,9 +226,9 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
} finally {
setIsBulkActionLoading(false);
}
}, [selectedRowIds, refreshUniformities]);
}, [selectedRowIds, refreshUniformities, bulkApproveModal]);
const handleBulkReject = useCallback(async () => {
const bulkRejectHandler = useCallback(async () => {
setIsBulkActionLoading(true);
try {
@@ -192,6 +237,7 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
setRowSelection({});
refreshUniformities();
bulkRejectModal.closeModal();
toast.success(
`Successfully rejected ${selectedRowIds.length} Uniformity data!`
);
@@ -200,7 +246,7 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
} finally {
setIsBulkActionLoading(false);
}
}, [selectedRowIds, refreshUniformities]);
}, [selectedRowIds, refreshUniformities, bulkRejectModal]);
useEffect(() => {
if (isResponseSuccess(uniformities) && uniformities.data) {
@@ -638,6 +684,252 @@ const UniformityTable = ({ refresh }: { refresh?: () => void }) => {
</div>
</ConfirmationModal>
<ConfirmationModal
ref={singleApproveModal.ref}
type='success'
iconPosition='left'
iconSize={32}
text='Apakah anda yakin ingin menyetujui data Uniformity ini?'
secondaryButton={{
text: 'Tidak',
}}
primaryButton={{
text: 'Ya',
color: 'success',
isLoading: isDeleteLoading,
onClick: singleApproveHandler,
}}
className={{
modalBox: 'rounded-2xl',
}}
>
<div className='flex flex-col gap-4 mt-4'>
<Table
data={[
{
id: 'tanggal',
label: 'Tanggal',
value: selectedUniformity
? formatDate(selectedUniformity.applied_at, 'DD MMM YYYY')
: '-',
},
{
id: 'lokasi-farm',
label: 'Lokasi Farm',
value: selectedUniformity?.location_name || '-',
},
{
id: 'project-flock',
label: 'Project Flock',
value: selectedUniformity?.flock_name || '-',
},
{
id: 'kandang',
label: 'Kandang',
value: selectedUniformity?.kandang_name || '-',
},
{
id: 'uniformity',
label: 'Uniformity',
value: `${selectedUniformity?.uniformity || 0}%`,
},
{
id: 'status',
label: 'Status',
value: getStatusText(selectedUniformity?.status || 'CREATED'),
},
]}
columns={[
{
accessorKey: 'label',
header: 'Label',
cell: (props) => props.row.original.label,
},
{
accessorKey: 'value',
header: 'Value',
cell: (props) => <span>{props.row.original.value}</span>,
},
]}
pageSize={6}
className={{
containerClassName: 'mb-0',
paginationClassName: 'hidden',
}}
/>
</div>
</ConfirmationModal>
<ConfirmationModal
ref={singleRejectModal.ref}
type='error'
iconPosition='left'
iconSize={32}
text='Apakah anda yakin ingin menolak data Uniformity ini?'
secondaryButton={{
text: 'Tidak',
}}
primaryButton={{
text: 'Ya',
color: 'error',
isLoading: isDeleteLoading,
onClick: singleRejectHandler,
}}
className={{
modalBox: 'rounded-2xl',
}}
>
<div className='flex flex-col gap-4 mt-4'>
<Table
data={[
{
id: 'tanggal',
label: 'Tanggal',
value: selectedUniformity
? formatDate(selectedUniformity.applied_at, 'DD MMM YYYY')
: '-',
},
{
id: 'lokasi-farm',
label: 'Lokasi Farm',
value: selectedUniformity?.location_name || '-',
},
{
id: 'project-flock',
label: 'Project Flock',
value: selectedUniformity?.flock_name || '-',
},
{
id: 'kandang',
label: 'Kandang',
value: selectedUniformity?.kandang_name || '-',
},
{
id: 'uniformity',
label: 'Uniformity',
value: `${selectedUniformity?.uniformity || 0}%`,
},
{
id: 'status',
label: 'Status',
value: getStatusText(selectedUniformity?.status || 'CREATED'),
},
]}
columns={[
{
accessorKey: 'label',
header: 'Label',
cell: (props) => props.row.original.label,
},
{
accessorKey: 'value',
header: 'Value',
cell: (props) => <span>{props.row.original.value}</span>,
},
]}
pageSize={6}
className={{
containerClassName: 'mb-0',
paginationClassName: 'hidden',
}}
/>
</div>
</ConfirmationModal>
<ConfirmationModal
ref={bulkApproveModal.ref}
type='success'
iconPosition='left'
iconSize={32}
text={`Apakah anda yakin ingin menyetujui ${selectedRowIds.length} data Uniformity yang dipilih?`}
secondaryButton={{
text: 'Tidak',
}}
primaryButton={{
text: 'Ya',
color: 'success',
isLoading: isBulkActionLoading,
onClick: bulkApproveHandler,
}}
className={{
modalBox: 'rounded-2xl',
}}
>
<div className='flex flex-col gap-4 mt-4'>
<Table
data={selectedUniformities.map((u, index) => ({
id: `bulk-approve-${index}`,
label: `${index + 1}. ${u.location_name}`,
value: `${u.flock_name} - ${u.kandang_name}`,
}))}
columns={[
{
accessorKey: 'label',
header: 'Label',
cell: (props) => props.row.original.label,
},
{
accessorKey: 'value',
header: 'Value',
cell: (props) => <span>{props.row.original.value}</span>,
},
]}
pageSize={selectedUniformities.length}
className={{
containerClassName: 'mb-0',
paginationClassName: 'hidden',
}}
/>
</div>
</ConfirmationModal>
<ConfirmationModal
ref={bulkRejectModal.ref}
type='error'
iconPosition='left'
iconSize={32}
text={`Apakah anda yakin ingin menolak ${selectedRowIds.length} data Uniformity yang dipilih?`}
secondaryButton={{
text: 'Tidak',
}}
primaryButton={{
text: 'Ya',
color: 'error',
isLoading: isBulkActionLoading,
onClick: bulkRejectHandler,
}}
className={{
modalBox: 'rounded-2xl',
}}
>
<div className='flex flex-col gap-4 mt-4'>
<Table
data={selectedUniformities.map((u, index) => ({
id: `bulk-reject-${index}`,
label: `${index + 1}. ${u.location_name}`,
value: `${u.flock_name} - ${u.kandang_name}`,
}))}
columns={[
{
accessorKey: 'label',
header: 'Label',
cell: (props) => props.row.original.label,
},
{
accessorKey: 'value',
header: 'Value',
cell: (props) => <span>{props.row.original.value}</span>,
},
]}
pageSize={selectedUniformities.length}
className={{
containerClassName: 'mb-0',
paginationClassName: 'hidden',
}}
/>
</div>
</ConfirmationModal>
{/* Floating Actions Button */}
<FloatingActionsButton
actions={[