From bbbd767cf2ae63d8318dde05002db6f9c7d5c965 Mon Sep 17 00:00:00 2001 From: rstubryan Date: Fri, 20 Feb 2026 09:21:42 +0700 Subject: [PATCH 1/8] refactor(FE): Fix week calculation logic in UniformityForm --- .../uniformity/form/UniformityForm.tsx | 79 +++++++++---------- 1 file changed, 39 insertions(+), 40 deletions(-) diff --git a/src/components/pages/production/uniformity/form/UniformityForm.tsx b/src/components/pages/production/uniformity/form/UniformityForm.tsx index 33b649c4..724f7b81 100644 --- a/src/components/pages/production/uniformity/form/UniformityForm.tsx +++ b/src/components/pages/production/uniformity/form/UniformityForm.tsx @@ -203,16 +203,19 @@ const UniformityForm = ({ // ===== RECORDINGS DATA (FOR WEEK CALCULATION) ===== const recordingsUrl = useMemo(() => { + if (!projectFlockKandangLookup?.project_flock_kandang_id) return null; const params = new URLSearchParams({ page: '1', limit: '100', + project_flock_kandang_id: + projectFlockKandangLookup.project_flock_kandang_id.toString(), }); return `${RecordingApi.basePath}?${params.toString()}`; - }, []); + }, [projectFlockKandangLookup?.project_flock_kandang_id]); const { data: recordingsData } = useSWR( recordingsUrl, - RecordingApi.getAllFetcher + recordingsUrl ? RecordingApi.getAllFetcher : null ); // ===== FORM CONFIGURATION ===== @@ -400,50 +403,46 @@ const UniformityForm = ({ useEffect(() => { if ( projectFlockKandangLookup?.chick_in_date && - projectFlockKandangLookup?.project_flock_kandang_id && - isResponseSuccess(recordingsData) && - recordingsData.data + projectFlockKandangLookup?.project_flock_kandang_id ) { - const matchingRecordings = recordingsData.data.filter( - (recording: Recording) => - recording.project_flock?.project_flock_kandang_id === - projectFlockKandangLookup.project_flock_kandang_id - ); + const chickInDate = new Date(projectFlockKandangLookup.chick_in_date); + chickInDate.setHours(0, 0, 0, 0); - matchingRecordings.sort( - (a: Recording, b: Recording) => - new Date(a.record_datetime).getTime() - - new Date(b.record_datetime).getTime() - ); + let initialWeek = 18; - const earliestRecording = matchingRecordings[0]; + if ( + isResponseSuccess(recordingsData) && + recordingsData.data && + recordingsData.data.length > 0 + ) { + const sortedRecordings = [...recordingsData.data].sort( + (a: Recording, b: Recording) => + new Date(a.record_datetime).getTime() - + new Date(b.record_datetime).getTime() + ); - if (earliestRecording) { - const chickInDate = new Date(projectFlockKandangLookup.chick_in_date); - chickInDate.setHours(0, 0, 0, 0); - - const earliestRecordDate = new Date(earliestRecording.record_datetime); - earliestRecordDate.setHours(0, 0, 0, 0); - - const initialWeek = - earliestRecording.project_flock?.production_standart?.week || 18; - - if (formik.values.date) { - const selectedDate = new Date(formik.values.date); - selectedDate.setHours(0, 0, 0, 0); - - const daysDiff = Math.floor( - (selectedDate.getTime() - chickInDate.getTime()) / - (1000 * 60 * 60 * 24) - ); - - const weeksDiff = Math.floor(daysDiff / 7); - - formik.setFieldValue('week', initialWeek + weeksDiff); - } else { - formik.setFieldValue('week', initialWeek); + const earliestRecording = sortedRecordings[0]; + if (earliestRecording?.project_flock?.production_standart?.week) { + initialWeek = + earliestRecording.project_flock.production_standart.week; } } + + if (formik.values.date) { + const selectedDate = new Date(formik.values.date); + selectedDate.setHours(0, 0, 0, 0); + + const daysDiff = Math.floor( + (selectedDate.getTime() - chickInDate.getTime()) / + (1000 * 60 * 60 * 24) + ); + + const weeksDiff = Math.floor(daysDiff / 7); + + formik.setFieldValue('week', initialWeek + weeksDiff); + } else { + formik.setFieldValue('week', initialWeek); + } } }, [ projectFlockKandangLookup?.chick_in_date, From b35b6c2ab8fd536d517fb32c6ad8da3de38b8c35 Mon Sep 17 00:00:00 2001 From: rstubryan Date: Fri, 20 Feb 2026 10:11:16 +0700 Subject: [PATCH 2/8] feat(FE): Add submittedActionType state to track modal action type --- .../TransferToLayingFormModal.tsx | 17 ++++++++++++++--- .../TransferToLayingsTable.tsx | 3 +++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/src/components/pages/production/transfer-to-laying/TransferToLayingFormModal.tsx b/src/components/pages/production/transfer-to-laying/TransferToLayingFormModal.tsx index 78de70e1..cf80be89 100644 --- a/src/components/pages/production/transfer-to-laying/TransferToLayingFormModal.tsx +++ b/src/components/pages/production/transfer-to-laying/TransferToLayingFormModal.tsx @@ -83,6 +83,9 @@ const TransferToLayingFormModal = () => { TransferToLayingFormValues | undefined >(undefined); const [formErrorMessage, setFormErrorMessage] = useState(null); + const [submittedActionType, setSubmittedActionType] = useState< + 'add' | 'edit' | null + >(null); // Flock Source const { @@ -203,6 +206,7 @@ const TransferToLayingFormModal = () => { }; setFormikLastValues(values); + setSubmittedActionType(modalAction as 'add' | 'edit'); switch (modalAction) { case 'add': @@ -1059,10 +1063,17 @@ const TransferToLayingFormModal = () => { setFormikLastValues(undefined)} + onClose={() => { + setFormikLastValues(undefined); + setSubmittedActionType(null); + }} secondaryButton={undefined} /> diff --git a/src/components/pages/production/transfer-to-laying/TransferToLayingsTable.tsx b/src/components/pages/production/transfer-to-laying/TransferToLayingsTable.tsx index 438c529c..bf4c31e3 100644 --- a/src/components/pages/production/transfer-to-laying/TransferToLayingsTable.tsx +++ b/src/components/pages/production/transfer-to-laying/TransferToLayingsTable.tsx @@ -680,6 +680,7 @@ const TransferToLayingsTable = () => { subtitleText='Are you sure you want to delete this data? ' transferToLayingIds={selectedRowIds} primaryButton={{ + text: 'Delete', isLoading: isDeleteLoading, color: 'error', onClick: confirmationModalDeleteClickHandler, @@ -704,6 +705,7 @@ const TransferToLayingsTable = () => { withNote noteLabel='Notes Approval' primaryButton={{ + text: 'Approve', isLoading: isApproveLoading, onClick: confirmationModalApproveClickHandler, }} @@ -735,6 +737,7 @@ const TransferToLayingsTable = () => { }, }} primaryButton={{ + text: 'Reject', isLoading: isRejectLoading, color: 'error', onClick: confirmationModalRejectClickHandler, From 4c3e7c615fc80abde3c566707b1a68a183e47444 Mon Sep 17 00:00:00 2001 From: rstubryan Date: Fri, 20 Feb 2026 10:12:06 +0700 Subject: [PATCH 3/8] refactor(FE): Refactor conditional text formatting in modal component --- .../transfer-to-laying/TransferToLayingFormModal.tsx | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/src/components/pages/production/transfer-to-laying/TransferToLayingFormModal.tsx b/src/components/pages/production/transfer-to-laying/TransferToLayingFormModal.tsx index cf80be89..84e67a5b 100644 --- a/src/components/pages/production/transfer-to-laying/TransferToLayingFormModal.tsx +++ b/src/components/pages/production/transfer-to-laying/TransferToLayingFormModal.tsx @@ -1063,7 +1063,11 @@ const TransferToLayingFormModal = () => { Date: Fri, 20 Feb 2026 10:23:47 +0700 Subject: [PATCH 4/8] feat(FE): Add project flock closing modal and zustand store --- .../project-flock/ProjectFlockTable.tsx | 58 ++++++++++++++ .../closing/ProjectFlockClosingForm.tsx | 78 ++++++++----------- .../project-flock-closing.store.ts | 19 +++++ .../slices/project-flock-closing.slice.ts | 70 +++++++++++++++++ 4 files changed, 178 insertions(+), 47 deletions(-) create mode 100644 src/stores/production/project-flock-closing/project-flock-closing.store.ts create mode 100644 src/stores/production/project-flock-closing/slices/project-flock-closing.slice.ts diff --git a/src/components/pages/production/project-flock/ProjectFlockTable.tsx b/src/components/pages/production/project-flock/ProjectFlockTable.tsx index 040948ff..040771a8 100644 --- a/src/components/pages/production/project-flock/ProjectFlockTable.tsx +++ b/src/components/pages/production/project-flock/ProjectFlockTable.tsx @@ -37,6 +37,7 @@ import ProjectFlockConfirmationModal from './ProjectFlockConfirmationModal'; import { useProjectFlockStore } from '@/stores/production/project-flock/project-flock.store'; import { ProjectFlockFormValues } from './form/ProjectFlockForm.schema'; import { useChickinStore } from '@/stores/production/chickin/chickin.store'; +import { useProjectFlockClosingStore } from '@/stores/production/project-flock-closing/project-flock-closing.store'; const RowOptionsMenu = ({ props, @@ -195,6 +196,7 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => { const confirmModal = useModal(); const successModal = useModal(); const chickinApproveModal = useModal(); + const closingModal = useModal(); const [approvalAction, setApprovalAction] = useState<'APPROVED' | 'REJECTED'>( 'APPROVED' ); @@ -210,6 +212,15 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => { setChickinApproveLoading, } = useChickinStore(); + const { + isClosingModalOpen, + isKandangClosed, + isClosingLoading, + closingCallback, + closeClosingModal, + setClosingLoading, + } = useProjectFlockClosingStore(); + // ===== Fetch Data ===== const { data: projectFlocks, @@ -309,6 +320,14 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => { } }, [isChickinApproveModalOpen, chickinApproveModal]); + useEffect(() => { + if (isClosingModalOpen) { + closingModal.openModal(); + } else { + closingModal.closeModal(); + } + }, [isClosingModalOpen, closingModal]); + useEffect(() => { if (isSuccess) { successModal.openModal(); @@ -1025,6 +1044,45 @@ const ProjectFlockTable = ({ refresh }: { refresh?: () => void }) => { isLoading: isChickinApproveLoading, }} /> + + {/* Project Flock Closing Modal */} + { + closeClosingModal(); + closingModal.closeModal(); + }, + }} + primaryButton={{ + text: 'Ya', + color: 'error', + isLoading: isClosingLoading, + onClick: async () => { + if (closingCallback) { + setClosingLoading(true); + try { + await closingCallback(!isKandangClosed ? 'close' : 'unclose'); + } finally { + setClosingLoading(false); + closeClosingModal(); + closingModal.closeModal(); + refreshProjectFlocks(); + } + } + }, + }} + /> ); }; diff --git a/src/components/pages/production/project-flock/closing/ProjectFlockClosingForm.tsx b/src/components/pages/production/project-flock/closing/ProjectFlockClosingForm.tsx index f963a793..e73a157a 100644 --- a/src/components/pages/production/project-flock/closing/ProjectFlockClosingForm.tsx +++ b/src/components/pages/production/project-flock/closing/ProjectFlockClosingForm.tsx @@ -17,9 +17,8 @@ import { Icon } from '@iconify/react'; import useSWR from 'swr'; import { ProjectFlockKandangApi } from '@/services/api/production/project-flock-kandang'; import { isResponseError, isResponseSuccess } from '@/lib/api-helper'; -import { useModal } from '@/components/Modal'; -import ConfirmationModal from '@/components/modal/ConfirmationModal'; -import { useMemo, useState } from 'react'; +import { useProjectFlockClosingStore } from '@/stores/production/project-flock-closing/project-flock-closing.store'; +import { useMemo } from 'react'; import toast from 'react-hot-toast'; import { useRouter } from 'next/navigation'; import { ApprovalApi } from '@/services/api/approval'; @@ -53,9 +52,8 @@ const ProjectFlockClosingForm = ({ projectFlockKandang: ProjectFlockKandang; }) => { const router = useRouter(); - const closeModal = useModal(); - const [isClosingLoading, setIsClosingLoading] = useState(false); + const { openClosingModal } = useProjectFlockClosingStore(); const { data: closingData, isLoading } = useSWR( `${ProjectFlockKandangApi.basePath}/${projectFlockKandang.id}/closing`, @@ -80,29 +78,34 @@ const ProjectFlockClosingForm = ({ : true; }, [projectFlockKandangApprovals]); - const confirmationModalCloseClickHandler = async () => { - setIsClosingLoading(true); - const deleteProjectFlockRes = await ProjectFlockKandangApi.closing( - projectFlockKandang?.id as number, - { - closed_date: !isKandangClosed - ? formatDate(new Date(), 'YYYY-MM-DD') - : '', - action: !isKandangClosed ? 'close' : 'unclose', - } - ); - - if (isResponseSuccess(deleteProjectFlockRes)) { - toast.success(deleteProjectFlockRes?.message as string); - router.push( - `/production/project-flock/detail?projectFlockId=${projectFlock.id}` + const handleCloseClick = () => { + const closingCallback = async (action: 'close' | 'unclose') => { + const deleteProjectFlockRes = await ProjectFlockKandangApi.closing( + projectFlockKandang?.id as number, + { + closed_date: + action === 'close' ? formatDate(new Date(), 'YYYY-MM-DD') : '', + action, + } ); - } - if (isResponseError(deleteProjectFlockRes)) { - toast.error(deleteProjectFlockRes?.message as string); - } - setIsClosingLoading(false); - closeModal.closeModal(); + + if (isResponseSuccess(deleteProjectFlockRes)) { + toast.success(deleteProjectFlockRes?.message as string); + router.push( + `/production/project-flock/detail?projectFlockId=${projectFlock.id}` + ); + } + if (isResponseError(deleteProjectFlockRes)) { + toast.error(deleteProjectFlockRes?.message as string); + } + }; + + openClosingModal( + projectFlockKandang, + projectFlock.id, + isKandangClosed, + closingCallback + ); }; // const errorStock = useMemo(() => { @@ -334,7 +337,7 @@ const ProjectFlockClosingForm = ({ color='error' isLoading={isLoading} disabled={!isCanCloseValid} - onClick={() => closeModal.openModal()} + onClick={handleCloseClick} > - - ); diff --git a/src/stores/production/project-flock-closing/project-flock-closing.store.ts b/src/stores/production/project-flock-closing/project-flock-closing.store.ts new file mode 100644 index 00000000..b6543b97 --- /dev/null +++ b/src/stores/production/project-flock-closing/project-flock-closing.store.ts @@ -0,0 +1,19 @@ +'use client'; + +import { create } from 'zustand'; +import { devtools } from 'zustand/middleware'; +import { createProjectFlockClosingSlice } from '@/stores/production/project-flock-closing/slices/project-flock-closing.slice'; +import { ProjectFlockClosingSlice } from '@/stores/production/project-flock-closing/slices/project-flock-closing.slice'; + +export type ProjectFlockClosingStore = ProjectFlockClosingSlice; + +export const useProjectFlockClosingStore = create()( + devtools( + (...args) => ({ + ...createProjectFlockClosingSlice(...args), + }), + { + name: 'ProjectFlockClosingStore', + } + ) +); diff --git a/src/stores/production/project-flock-closing/slices/project-flock-closing.slice.ts b/src/stores/production/project-flock-closing/slices/project-flock-closing.slice.ts new file mode 100644 index 00000000..faff8816 --- /dev/null +++ b/src/stores/production/project-flock-closing/slices/project-flock-closing.slice.ts @@ -0,0 +1,70 @@ +import { StateCreator } from 'zustand'; +import { ProjectFlockKandang } from '@/types/api/production/project-flock-kandang'; + +export type ProjectFlockClosingSlice = { + // State + isClosingModalOpen: boolean; + selectedProjectFlockKandang: ProjectFlockKandang | null; + projectFlockId: number | null; + isKandangClosed: boolean; + isClosingLoading: boolean; + closingCallback: ((action: 'close' | 'unclose') => Promise) | null; + + // Actions + openClosingModal: ( + data: ProjectFlockKandang, + projectFlockId: number, + isClosed: boolean, + callback: (action: 'close' | 'unclose') => Promise + ) => void; + closeClosingModal: () => void; + setClosingLoading: (loading: boolean) => void; + resetClosing: () => void; +}; + +export const createProjectFlockClosingSlice: StateCreator< + ProjectFlockClosingSlice, + [], + [], + ProjectFlockClosingSlice +> = (set) => ({ + // Initial state + isClosingModalOpen: false, + selectedProjectFlockKandang: null, + projectFlockId: null, + isKandangClosed: false, + isClosingLoading: false, + closingCallback: null, + + // Actions + openClosingModal: (data, projectFlockId, isClosed, callback) => + set({ + isClosingModalOpen: true, + selectedProjectFlockKandang: data, + projectFlockId, + isKandangClosed: isClosed, + closingCallback: callback, + }), + + closeClosingModal: () => + set({ + isClosingModalOpen: false, + selectedProjectFlockKandang: null, + projectFlockId: null, + isKandangClosed: false, + closingCallback: null, + }), + + setClosingLoading: (loading) => + set({ isClosingLoading: loading }), + + resetClosing: () => + set({ + isClosingModalOpen: false, + selectedProjectFlockKandang: null, + projectFlockId: null, + isKandangClosed: false, + isClosingLoading: false, + closingCallback: null, + }), +}); From a0e79168b28df0e7558b61f5ca8e507682038c60 Mon Sep 17 00:00:00 2001 From: rstubryan Date: Fri, 20 Feb 2026 10:25:30 +0700 Subject: [PATCH 5/8] refactor(FE): Refactor setClosingLoading to use single-line syntax --- .../slices/project-flock-closing.slice.ts | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/stores/production/project-flock-closing/slices/project-flock-closing.slice.ts b/src/stores/production/project-flock-closing/slices/project-flock-closing.slice.ts index faff8816..ccffd387 100644 --- a/src/stores/production/project-flock-closing/slices/project-flock-closing.slice.ts +++ b/src/stores/production/project-flock-closing/slices/project-flock-closing.slice.ts @@ -55,8 +55,7 @@ export const createProjectFlockClosingSlice: StateCreator< closingCallback: null, }), - setClosingLoading: (loading) => - set({ isClosingLoading: loading }), + setClosingLoading: (loading) => set({ isClosingLoading: loading }), resetClosing: () => set({ From 1f2f3acebb4e464812da5434988574678f9ca77c Mon Sep 17 00:00:00 2001 From: rstubryan Date: Fri, 20 Feb 2026 14:17:26 +0700 Subject: [PATCH 6/8] refactor(FE): Remove unused imports and redundant code --- src/app/closing/detail/page.tsx | 1 - src/app/finance/detail/edit/page.tsx | 1 - src/app/finance/detail/page.tsx | 2 +- src/app/page.tsx | 3 +- src/app/production/project-flock/add/page.tsx | 4 +- .../project-flock/detail/edit/page.tsx | 9 ++- .../production/project-flock/detail/page.tsx | 10 ++-- src/components/MainDrawer.tsx | 2 - src/components/Tabs.tsx | 2 +- .../helper/skeleton/DataStateSkeleton.tsx | 1 - src/components/input/PatternInput.tsx | 1 - .../modal/ConfirmationModalWithNotes.tsx | 2 +- .../closing/table/OverheadClosingTable.tsx | 4 +- .../pages/dashboard/export/DashboardPDF.ts | 2 +- src/components/pages/finance/FinanceTable.tsx | 1 - .../FormFinanceAddInitialBalance.tsx | 8 +-- .../add/injection/FormFinanceInjection.tsx | 5 +- .../adjustment/InventoryAdjustmentTable.tsx | 1 - .../form/InventoryAdjustmentForm.tsx | 1 - .../inventory/movement/form/MovementForm.tsx | 1 - .../product/InventoryProductTable.tsx | 7 +-- .../detail/StockProductWarehouseTable.tsx | 5 +- .../marketing/DeliveryOrderFormModal.tsx | 58 +++++-------------- .../pages/marketing/MarketingTable.tsx | 10 +--- .../pages/marketing/SalesOrderFormModal.tsx | 4 +- .../delivery-order/DeliverOrderProduct.tsx | 13 ++--- .../sales-order/SalesOrderProductForm.tsx | 12 ++-- .../marketing/pdf/DeliveryOrderExport.tsx | 2 +- .../pages/marketing/pdf/SalesOrderExport.tsx | 6 +- .../customer/form/CustomerForm.tsx | 3 +- .../master-data/kandang/form/KandangForm.tsx | 3 +- .../location/form/LocationForm.tsx | 3 +- .../nonstock/form/NonstockForm.tsx | 3 +- .../ProductionStandardTable.tsx | 14 ++--- .../warehouse/form/WarehouseForm.tsx | 3 +- .../production/chickin/form/ChickinForm.tsx | 5 -- .../chickin/form/tabs/ChickinFormView.tsx | 2 - .../ProjectFlockConfirmationModal.tsx | 8 +-- .../project-flock/ProjectFlockTable.tsx | 38 +----------- .../closing/ProjectFlockClosingForm.tsx | 16 ----- .../detail/ProjectFlockDetail.tsx | 14 ----- .../project-flock/form/ProjectFlockForm.tsx | 16 +++-- .../form/ProjectFlockKandangTable.tsx | 9 +-- .../TransferToLayingConfirmationModal.tsx | 4 +- .../TransferToLayingDetailModal.tsx | 5 +- .../TransferToLayingFormModal.tsx | 25 +++----- .../form/TransferToLayingForm.schema.ts | 3 - .../order/PurchaseOrderAcceptApprovalForm.tsx | 15 ----- .../form/request/PurchaseRequestForm.tsx | 8 +-- .../purchase/order/PurchaseOrderDetail.tsx | 9 ++- .../export/ReportExpenseExportXLSX.tsx | 2 +- .../export/CustomerPaymentExportPDF.tsx | 2 +- .../finance/export/DebtSupllierExportPDF.tsx | 2 +- .../finance/export/DebtSupplierExportXLSX.tsx | 2 +- .../finance/skeleton/DebtSupplierSkeleton.tsx | 1 - .../report/finance/tab/DebtSupplierTab.tsx | 6 +- .../export/PurchasesPerSupplierExportPDF.tsx | 2 +- .../tab/PurchasesPerSupplierTab.tsx | 5 -- .../export/DailyMarketingExportPDF.tsx | 2 +- .../export/HppPerkandangExportPDF.tsx | 2 +- .../report/marketing/tab/HppPerKandangTab.tsx | 5 -- ...oductionResultProjectFlockKandangTable.tsx | 1 - .../components/base/date-picker.tsx | 18 +++--- .../components/base/date-range-picker.tsx | 5 -- .../daily-checklist/DailyChecklistContent.tsx | 23 ++++---- .../components/pages/dashboard/Dashboard.tsx | 24 ++++---- .../ListDailyChecklistContent.tsx | 16 ++--- .../detail/DetailDailyChecklistContent.tsx | 31 +++++----- .../activity/MasterAktivitasContent.tsx | 14 +---- .../MasterConfigurationContent.tsx | 6 +- .../employee/MasterEmployeeContent.tsx | 23 ++++---- .../reports/DailyChecklistReportsContent.tsx | 58 +++++++++++-------- .../api/daily-checklist/daily-checklist.ts | 3 +- src/services/api/expense.ts | 1 - src/services/api/marketing/marketing.ts | 8 +-- .../api/production/transfer-to-laying.ts | 6 +- src/services/api/report.ts | 3 +- src/services/api/report/marketing-report.ts | 4 +- src/types/api/closing.d.ts | 3 - src/types/api/daily-checklist/employee.d.ts | 2 - src/types/api/dashboard/dashboard.d.ts | 2 - src/types/api/expense.d.ts | 8 +-- src/types/api/inventory/product.d.ts | 1 - src/types/api/marketing/marketing.d.ts | 1 - src/types/api/master-data/nonstock.d.ts | 2 +- src/types/api/master-data/product.d.ts | 2 +- .../api/production/project-flock-kandang.d.ts | 1 - .../api/production/transfer-to-laying.d.ts | 9 +-- src/types/api/report/marketing.d.ts | 5 +- src/types/api/report/report-expense.d.ts | 1 - 90 files changed, 222 insertions(+), 474 deletions(-) diff --git a/src/app/closing/detail/page.tsx b/src/app/closing/detail/page.tsx index 96487258..d83b7608 100644 --- a/src/app/closing/detail/page.tsx +++ b/src/app/closing/detail/page.tsx @@ -7,7 +7,6 @@ import ClosingDetail from '@/components/pages/closing/ClosingDetailTabs'; import { ClosingApi } from '@/services/api/closing'; import { isResponseError, isResponseSuccess } from '@/lib/api-helper'; -import { FlockApi } from '@/services/api/master-data'; import { ProjectFlockApi } from '@/services/api/production/project-flock'; import { ProjectFlockKandangApi } from '@/services/api/production'; diff --git a/src/app/finance/detail/edit/page.tsx b/src/app/finance/detail/edit/page.tsx index 93a0daea..331f4101 100644 --- a/src/app/finance/detail/edit/page.tsx +++ b/src/app/finance/detail/edit/page.tsx @@ -5,7 +5,6 @@ import useSWR from 'swr'; import { FinanceApi } from '@/services/api/finance'; import { isResponseError, isResponseSuccess } from '@/lib/api-helper'; import FormFinanceAdd from '@/components/pages/finance/add/FormFinanceAdd'; -import FormFinanceAddInitialBalance from '@/components/pages/finance/add/initial-balance/FormFinanceAddInitialBalance'; const EditFinanceTransactionPage = () => { const router = useRouter(); diff --git a/src/app/finance/detail/page.tsx b/src/app/finance/detail/page.tsx index b80e8acb..f23d7770 100644 --- a/src/app/finance/detail/page.tsx +++ b/src/app/finance/detail/page.tsx @@ -4,7 +4,7 @@ import FinanceDetail from '@/components/pages/finance/FinanceDetail'; import useSWR from 'swr'; import { useRouter, useSearchParams } from 'next/navigation'; import { FinanceApi } from '@/services/api/finance'; -import { isResponseError, isResponseSuccess } from '@/lib/api-helper'; +import { isResponseSuccess } from '@/lib/api-helper'; const FinanceDetailPage = () => { const router = useRouter(); diff --git a/src/app/page.tsx b/src/app/page.tsx index 33d01de7..8c10b702 100644 --- a/src/app/page.tsx +++ b/src/app/page.tsx @@ -3,10 +3,9 @@ import { useEffect } from 'react'; import { usePathname, useRouter } from 'next/navigation'; import { useAuth } from '@/services/hooks/useAuth'; -import { redirectToSSO } from '@/lib/auth-helper'; export default function Home() { - const { user, isLoadingUser } = useAuth(); + const { isLoadingUser } = useAuth(); const router = useRouter(); const pathname = usePathname(); diff --git a/src/app/production/project-flock/add/page.tsx b/src/app/production/project-flock/add/page.tsx index 2eb2c090..eb2b6dd1 100644 --- a/src/app/production/project-flock/add/page.tsx +++ b/src/app/production/project-flock/add/page.tsx @@ -1,8 +1,8 @@ 'use client'; import ProjectFlockForm from '@/components/pages/production/project-flock/form/ProjectFlockForm'; -import React, { useImperativeHandle } from 'react'; -import toast from 'react-hot-toast'; +import React from 'react'; +// import React, { useImperativeHandle } from 'react'; const AddProjectFlock = () => { // useImperativeHandle(ref, () => ({ diff --git a/src/app/production/project-flock/detail/edit/page.tsx b/src/app/production/project-flock/detail/edit/page.tsx index e5f88f19..4551dd85 100644 --- a/src/app/production/project-flock/detail/edit/page.tsx +++ b/src/app/production/project-flock/detail/edit/page.tsx @@ -12,11 +12,10 @@ const ProjectFlockEdit = () => { const projectFlockId = searchParams.get('projectFlockId'); - const { - data: projectFlock, - isLoading: isLoadingProjectFlock, - mutate: refreshProjectFlocks, - } = useSWR(projectFlockId, (id: number) => ProjectFlockApi.getSingle(id)); + const { data: projectFlock, isLoading: isLoadingProjectFlock } = useSWR( + projectFlockId, + (id: number) => ProjectFlockApi.getSingle(id) + ); if (!projectFlockId) { router.back(); diff --git a/src/app/production/project-flock/detail/page.tsx b/src/app/production/project-flock/detail/page.tsx index 6187898e..f4d58f9a 100644 --- a/src/app/production/project-flock/detail/page.tsx +++ b/src/app/production/project-flock/detail/page.tsx @@ -1,7 +1,6 @@ 'use client'; import ProjectFlockDetail from '@/components/pages/production/project-flock/detail/ProjectFlockDetail'; -import ProjectFlockForm from '@/components/pages/production/project-flock/form/ProjectFlockForm'; import { isResponseError, isResponseSuccess } from '@/lib/api-helper'; import { ProjectFlockApi } from '@/services/api/production/project-flock'; import { useRouter, useSearchParams } from 'next/navigation'; @@ -13,11 +12,10 @@ const ProjectFlockDetailPage = () => { const projectFlockId = searchParams.get('projectFlockId'); - const { - data: projectFlock, - isLoading: isLoadingProjectFlock, - mutate: refreshProjectFlock, - } = useSWR(projectFlockId, (id: number) => ProjectFlockApi.getSingle(id)); + const { data: projectFlock, isLoading: isLoadingProjectFlock } = useSWR( + projectFlockId, + (id: number) => ProjectFlockApi.getSingle(id) + ); if (!projectFlockId) { router.back(); diff --git a/src/components/MainDrawer.tsx b/src/components/MainDrawer.tsx index 71da0789..724e4b0a 100644 --- a/src/components/MainDrawer.tsx +++ b/src/components/MainDrawer.tsx @@ -1,6 +1,5 @@ 'use client'; -import { useCallback } from 'react'; import { usePathname } from 'next/navigation'; import Image from 'next/image'; @@ -13,7 +12,6 @@ import PermissionNotFound from '@/components/helper/PermissionNotFound'; import { useUiStore } from '@/stores/ui/ui.store'; import { MAIN_DRAWER_LINKS } from '@/config/constant'; -import { isPathActive } from '@/lib/helper'; import { ROUTE_PERMISSIONS } from '@/config/route-permission'; import { useAuth } from '@/services/hooks/useAuth'; diff --git a/src/components/Tabs.tsx b/src/components/Tabs.tsx index 8a06f9ed..52047d8b 100644 --- a/src/components/Tabs.tsx +++ b/src/components/Tabs.tsx @@ -1,4 +1,4 @@ -import { HTMLAttributes, ReactNode, useEffect, useState } from 'react'; +import { HTMLAttributes, ReactNode, useState } from 'react'; import { cn } from '@/lib/helper'; export interface TabItem { diff --git a/src/components/helper/skeleton/DataStateSkeleton.tsx b/src/components/helper/skeleton/DataStateSkeleton.tsx index cd5474e0..f3e9fdef 100644 --- a/src/components/helper/skeleton/DataStateSkeleton.tsx +++ b/src/components/helper/skeleton/DataStateSkeleton.tsx @@ -1,5 +1,4 @@ import IconSkeleton from '@/components/helper/skeleton/IconSkeleton'; -import { Icon } from '@iconify/react'; const DataStateSkeleton = ({ icon, diff --git a/src/components/input/PatternInput.tsx b/src/components/input/PatternInput.tsx index 9af1b68e..290614c7 100644 --- a/src/components/input/PatternInput.tsx +++ b/src/components/input/PatternInput.tsx @@ -4,7 +4,6 @@ import { ChangeEvent } from 'react'; import { PatternFormat, NumberFormatBase, - NumberFormatBaseProps, OnValueChange, } from 'react-number-format'; import TextInput, { TextInputProps } from '@/components/input/TextInput'; diff --git a/src/components/modal/ConfirmationModalWithNotes.tsx b/src/components/modal/ConfirmationModalWithNotes.tsx index e862dffc..20f63019 100644 --- a/src/components/modal/ConfirmationModalWithNotes.tsx +++ b/src/components/modal/ConfirmationModalWithNotes.tsx @@ -56,7 +56,7 @@ const ConfirmationModalWithNotes: React.FC = ({ closeOnBackdrop={closeOnBackdrop} primaryButton={{ ...primaryButton, - onClick: (e) => { + onClick: () => { if (primaryButton && primaryButton?.onClick) { primaryButton?.onClick?.(notes); } else { diff --git a/src/components/pages/closing/table/OverheadClosingTable.tsx b/src/components/pages/closing/table/OverheadClosingTable.tsx index a6c31e6c..421817f9 100644 --- a/src/components/pages/closing/table/OverheadClosingTable.tsx +++ b/src/components/pages/closing/table/OverheadClosingTable.tsx @@ -1,5 +1,5 @@ import Card from '@/components/Card'; -import Table, { TABLE_DEFAULT_STYLING } from '@/components/Table'; +import Table from '@/components/Table'; import { isResponseSuccess } from '@/lib/api-helper'; import { cn, formatCurrency, formatDate, formatNumber } from '@/lib/helper'; import { ClosingApi } from '@/services/api/closing'; @@ -38,7 +38,7 @@ const OverheadClosingTable = ({ } ); - const { data: overheadKandang, isLoading: isLoadingOverheadKandang } = useSWR( + const { data: overheadKandang } = useSWR( kandangId ? `${ClosingApi.basePath}/${projectFlockId}/${kandangId}/overhead` : undefined, diff --git a/src/components/pages/dashboard/export/DashboardPDF.ts b/src/components/pages/dashboard/export/DashboardPDF.ts index 8b4c7e6a..340abcbc 100644 --- a/src/components/pages/dashboard/export/DashboardPDF.ts +++ b/src/components/pages/dashboard/export/DashboardPDF.ts @@ -256,7 +256,7 @@ export const generateDashboardPDF = async ({ pdf.save(fileName); toast.success('PDF exported successfully!', { id: 'export-pdf' }); - } catch (error) { + } catch { toast.error('Failed to export PDF. Please try again.', { id: 'export-pdf', }); diff --git a/src/components/pages/finance/FinanceTable.tsx b/src/components/pages/finance/FinanceTable.tsx index 6f422753..f83fa469 100644 --- a/src/components/pages/finance/FinanceTable.tsx +++ b/src/components/pages/finance/FinanceTable.tsx @@ -1,6 +1,5 @@ import { useEffect, useMemo, useRef, useState } from 'react'; import { CellContext } from '@tanstack/react-table'; -import { useSearchParams } from 'next/navigation'; import useSWR from 'swr'; import { useFormik } from 'formik'; diff --git a/src/components/pages/finance/add/initial-balance/FormFinanceAddInitialBalance.tsx b/src/components/pages/finance/add/initial-balance/FormFinanceAddInitialBalance.tsx index a63caa94..621557b2 100644 --- a/src/components/pages/finance/add/initial-balance/FormFinanceAddInitialBalance.tsx +++ b/src/components/pages/finance/add/initial-balance/FormFinanceAddInitialBalance.tsx @@ -48,9 +48,9 @@ const FormFinanceAddInitialBalance = ({ // ===== Formik ===== const formikInitialValues = useMemo((): InitialBalanceFormValues => { // Type assertion to handle potential initial_balance_type field - const extendedInitialValues = initialValues as Finance & { - initial_balance_type?: string; - }; + // const extendedInitialValues = initialValues as Finance & { + // initial_balance_type?: string; + // }; return { party_type_option: @@ -122,8 +122,6 @@ const FormFinanceAddInitialBalance = ({ options: bankOptions, rawData: bankRawData, isLoadingOptions: isLoadingBankOptions, - setInputValue: setBankInputValue, - loadMore: loadMoreBankOptions, } = useSelect(BankApi.basePath, 'id', 'name'); // ===== Helper Functions ===== diff --git a/src/components/pages/finance/add/injection/FormFinanceInjection.tsx b/src/components/pages/finance/add/injection/FormFinanceInjection.tsx index a4b77baf..b729ce11 100644 --- a/src/components/pages/finance/add/injection/FormFinanceInjection.tsx +++ b/src/components/pages/finance/add/injection/FormFinanceInjection.tsx @@ -28,10 +28,7 @@ import { useCallback, useMemo, useState } from 'react'; import toast from 'react-hot-toast'; import Alert from '@/components/Alert'; import { Icon } from '@iconify/react'; -import { - FINANCE_INJECTION_STATUS, - FINANCE_INJECTION_TYPE_OPTIONS, -} from '@/config/constant'; +import { FINANCE_INJECTION_TYPE_OPTIONS } from '@/config/constant'; interface FormFinanceInjectionProps { type?: 'add' | 'edit'; diff --git a/src/components/pages/inventory/adjustment/InventoryAdjustmentTable.tsx b/src/components/pages/inventory/adjustment/InventoryAdjustmentTable.tsx index 8da2abf8..1bd47caf 100644 --- a/src/components/pages/inventory/adjustment/InventoryAdjustmentTable.tsx +++ b/src/components/pages/inventory/adjustment/InventoryAdjustmentTable.tsx @@ -15,7 +15,6 @@ import { Icon } from '@iconify/react'; import { ColumnDef, ColumnSort, SortingState } from '@tanstack/react-table'; import { useCallback, useEffect, useState } from 'react'; import useSWR from 'swr'; -import { useFormikErrorList } from '@/services/hooks/useFormikErrorList'; const InventoryAdjustmentTable = () => { const { diff --git a/src/components/pages/inventory/adjustment/form/InventoryAdjustmentForm.tsx b/src/components/pages/inventory/adjustment/form/InventoryAdjustmentForm.tsx index 3bae393d..612fbb20 100644 --- a/src/components/pages/inventory/adjustment/form/InventoryAdjustmentForm.tsx +++ b/src/components/pages/inventory/adjustment/form/InventoryAdjustmentForm.tsx @@ -14,7 +14,6 @@ import { InventoryAdjustmentFormSchema, InventoryAdjustmentFormValues, } from '@/components/pages/inventory/adjustment/form/InventoryAdjustmentForm.schema'; -import useSWR from 'swr'; import { ProductApi, ProductCategoryApi, diff --git a/src/components/pages/inventory/movement/form/MovementForm.tsx b/src/components/pages/inventory/movement/form/MovementForm.tsx index dbb30314..f723e763 100644 --- a/src/components/pages/inventory/movement/form/MovementForm.tsx +++ b/src/components/pages/inventory/movement/form/MovementForm.tsx @@ -33,7 +33,6 @@ import { toast } from 'react-hot-toast'; import { MovementApi } from '@/services/api/inventory'; import FileInput from '@/components/input/FileInput'; import CheckboxInput from '@/components/input/CheckboxInput'; -import Badge from '@/components/Badge'; import Card from '@/components/Card'; import { S3_PUBLIC_BASE_URL } from '@/config/constant'; import { getUniqueFormikErrors } from '@/lib/formik-helper'; diff --git a/src/components/pages/inventory/product/InventoryProductTable.tsx b/src/components/pages/inventory/product/InventoryProductTable.tsx index fce21b2c..316bd103 100644 --- a/src/components/pages/inventory/product/InventoryProductTable.tsx +++ b/src/components/pages/inventory/product/InventoryProductTable.tsx @@ -15,12 +15,7 @@ import { InventoryProductApi } from '@/services/api/inventory'; import { useTableFilter } from '@/services/hooks/useTableFilter'; import { InventoryProduct } from '@/types/api/inventory/product'; import { Icon } from '@iconify/react'; -import { - CellContext, - ColumnDef, - Row, - SortingState, -} from '@tanstack/react-table'; +import { CellContext, ColumnDef, SortingState } from '@tanstack/react-table'; import { ChangeEventHandler, useMemo, useState } from 'react'; import useSWR from 'swr'; diff --git a/src/components/pages/inventory/product/detail/StockProductWarehouseTable.tsx b/src/components/pages/inventory/product/detail/StockProductWarehouseTable.tsx index 6f48f7cd..aa375bdc 100644 --- a/src/components/pages/inventory/product/detail/StockProductWarehouseTable.tsx +++ b/src/components/pages/inventory/product/detail/StockProductWarehouseTable.tsx @@ -1,10 +1,7 @@ import Card from '@/components/Card'; import Table from '@/components/Table'; import { formatNumber } from '@/lib/helper'; -import { - InventoryProduct, - ProductWarehouseStock, -} from '@/types/api/inventory/product'; +import { ProductWarehouseStock } from '@/types/api/inventory/product'; const StockProductWarehouseTable = ({ productWarehouseStock, diff --git a/src/components/pages/marketing/DeliveryOrderFormModal.tsx b/src/components/pages/marketing/DeliveryOrderFormModal.tsx index f1d5e3cc..ae559328 100644 --- a/src/components/pages/marketing/DeliveryOrderFormModal.tsx +++ b/src/components/pages/marketing/DeliveryOrderFormModal.tsx @@ -48,11 +48,7 @@ import RequirePermission from '@/components/helper/RequirePermission'; const MemoizedDeliveryOrderProductTable = memo(DeliveryOrderProductTable); const MemoizedDeliveryOrderProductForm = memo(DeliveryOrderProductForm); -const DeliveryOrderFormModal = ({ - initialValues, -}: { - initialValues?: Marketing; -}) => { +const DeliveryOrderFormModal = ({}: { initialValues?: Marketing }) => { const router = useRouter(); const searchParams = useSearchParams(); @@ -76,19 +72,14 @@ const DeliveryOrderFormModal = ({ ); }; - const { data: marketing, isLoading: isLoadingMarketing } = useSWR( + const { data: marketing } = useSWR( isModalActionForForm && marketingId ? `detail-marketing-${marketingId}` : undefined, () => MarketingApi.getSingle(Number(marketingId)) ); - const { - approvals, - rawDataApprovals, - isLoading: isLoadingApproval, - refresh: refreshApproval, - } = useApprovalSteps({ + const { rawDataApprovals, refresh: refreshApproval } = useApprovalSteps({ latestApproval: isResponseSuccess(marketing) ? marketing?.data.latest_approval : undefined, @@ -284,29 +275,10 @@ const DeliveryOrderFormModal = ({ setIsLoading(false); }; - const memoSalesOrder = formik.values.sales_order; - // ================== HANDLER ================== - const nextButtonHandler = () => { - setStep(step + 1); - }; const prevButtonHandler = () => { setStep(step - 1); }; - const handleChangeCustomer = useCallback( - (val: OptionType | OptionType[] | null) => { - formik.setFieldValue('customer_id', (val as OptionType)?.value); - formik.setFieldValue('customer', val as OptionType); - }, - [] - ); - const handleChangeSalesPerson = useCallback( - (val: OptionType | OptionType[] | null) => { - formik.setFieldValue('sales_person_id', (val as OptionType)?.value); - formik.setFieldValue('sales_person', val as OptionType); - }, - [] - ); const rejectMarketingHandler = async (notes: string) => { if (!marketingId) { toast.error(`Tidak ada data yang valid untuk di reject.`); @@ -507,18 +479,18 @@ const DeliveryOrderFormModal = ({ }, []); // ================== MEMOIZED ================== - const isNextButtonDisabled = useMemo(() => { - if (step === 1) { - return Boolean( - !formik.values.customer_id || - !formik.values.sales_person_id || - !formik.values.so_date || - !formik.values.notes - ); - } + // const isNextButtonDisabled = useMemo(() => { + // if (step === 1) { + // return Boolean( + // !formik.values.customer_id || + // !formik.values.sales_person_id || + // !formik.values.so_date || + // !formik.values.notes + // ); + // } - return true; - }, [step, formik.values]); + // return true; + // }, [step, formik.values]); const deliveryRejected = useMemo(() => { return ( isResponseSuccess(marketing) && @@ -877,7 +849,7 @@ const DeliveryOrderFormModal = ({ text: 'Oke', color: 'primary', className: 'rounded-lg', - onClick: (e) => { + onClick: () => { closeModalHandler(); }, }} diff --git a/src/components/pages/marketing/MarketingTable.tsx b/src/components/pages/marketing/MarketingTable.tsx index 6368df11..994e8b4c 100644 --- a/src/components/pages/marketing/MarketingTable.tsx +++ b/src/components/pages/marketing/MarketingTable.tsx @@ -25,7 +25,6 @@ import { useMemo, useState } from 'react'; import toast from 'react-hot-toast'; import useSWR from 'swr'; import RequirePermission from '@/components/helper/RequirePermission'; -import { useAuth } from '@/services/hooks/useAuth'; import ButtonFilter from '@/components/helper/ButtonFilter'; import Dropdown from '@/components/Dropdown'; import PopoverButton from '@/components/popover/PopoverButton'; @@ -136,7 +135,7 @@ const RowsOptionsMenu = ({ onClick={deleteClickHandler} variant='ghost' color='none' - className='relative p-3 overflow-hidden justify-start text-sm font-semibold w-full text-error before:content-[""] before:absolute before:h-0.25 before:p-3 before:top-0 before:left-0 before:right-0 before:border-t before:border-base-content/5' + className='relative p-3 overflow-hidden justify-start text-sm font-semibold w-full text-error before:content-[""] before:absolute before:h-px before:p-3 before:top-0 before:left-0 before:right-0 before:border-t before:border-base-content/5' > Delete Item @@ -149,14 +148,11 @@ const RowsOptionsMenu = ({ }; const MarketingTable = () => { - const [search, setSearch] = useState(''); - const [approveAction, setApproveAction] = useState<'APPROVED' | 'REJECTED'>( 'APPROVED' ); const [selectedItem, setSelectedItem] = useState(null); const [rowSelection, setRowSelection] = useState>({}); - const { permissionCheck } = useAuth(); const router = useRouter(); const deleteModal = useModal(); @@ -530,7 +526,7 @@ const MarketingTable = () => { {idsToProcess.length > 0 && ( <> -
+
Date: Fri, 20 Feb 2026 14:42:46 +0700 Subject: [PATCH 8/8] refactor(FE): Fix formatting for array dependencies and className conditions --- src/components/pages/marketing/MarketingTable.tsx | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/components/pages/marketing/MarketingTable.tsx b/src/components/pages/marketing/MarketingTable.tsx index 629ddcf7..0bf00833 100644 --- a/src/components/pages/marketing/MarketingTable.tsx +++ b/src/components/pages/marketing/MarketingTable.tsx @@ -234,7 +234,11 @@ const MarketingTable = () => { } return count; - }, [tableFilterState.product_ids, tableFilterState.status, tableFilterState.customer_id]); + }, [ + tableFilterState.product_ids, + tableFilterState.status, + tableFilterState.customer_id, + ]); const approveClickHandler = () => { setApproveAction('APPROVED'); @@ -593,7 +597,8 @@ const MarketingTable = () => { className={cn( 'px-3 py-2.5 gap-1.5 text-sm text-base-content/50 border border-base-content/10 rounded-xl shadow-button-soft transition-all', { - 'border-primary-gradient text-primary': activeFiltersCount > 0, + 'border-primary-gradient text-primary': + activeFiltersCount > 0, } )} >