Merge branch 'development' into 'production'

Development

See merge request mbugroup/lti-web-client!393
This commit is contained in:
Adnan Zahir
2026-04-13 11:17:24 +07:00
12 changed files with 203 additions and 235 deletions
+3 -3
View File
@@ -51,7 +51,7 @@ const Button = ({
return ( return (
<> <>
{!href && ( {(!href || (href && disabled)) && (
<button <button
{...props} {...props}
type={type} type={type}
@@ -68,9 +68,9 @@ const Button = ({
</button> </button>
)} )}
{href && ( {href && !disabled && (
<Link <Link
href={disabled ? '#' : href} href={href}
target={target} target={target}
rel={rel} rel={rel}
aria-disabled={disabled} aria-disabled={disabled}
@@ -112,12 +112,11 @@ const ClosingDetail: React.FC<ClosingDetailProps> = ({
kandangData={kandangData} kandangData={kandangData}
/> />
{!kandangData && ( <ClosingKandangList
<ClosingKandangList initialValue={initialValue}
initialValue={initialValue} projectData={projectData}
projectData={projectData} selectedKandangId={kandangData?.id}
/> />
)}
<Tabs <Tabs
activeTabId={activeTabId} activeTabId={activeTabId}
@@ -5,9 +5,11 @@ import { ProjectFlock } from '@/types/api/production/project-flock';
const ClosingKandangList = ({ const ClosingKandangList = ({
initialValue, initialValue,
projectData, projectData,
selectedKandangId,
}: { }: {
initialValue?: ClosingGeneralInformation; initialValue?: ClosingGeneralInformation;
projectData?: ProjectFlock; projectData?: ProjectFlock;
selectedKandangId?: number;
}) => { }) => {
return ( return (
<div className='w-full py-3 @container relative before:absolute before:top-0 before:left-0 before:right-0 before:-mx-4 before:border-t before:border-base-content/10'> <div className='w-full py-3 @container relative before:absolute before:top-0 before:left-0 before:right-0 before:-mx-4 before:border-t before:border-base-content/10'>
@@ -22,6 +24,9 @@ const ClosingKandangList = ({
variant='outline' variant='outline'
className='px-3 py-2.5 w-fit text-sm rounded-lg shadow-sm' className='px-3 py-2.5 w-fit text-sm rounded-lg shadow-sm'
href={`/closing/detail/?closingId=${initialValue?.flock_id}&kandangId=${kandang.project_flock_kandang_id}`} href={`/closing/detail/?closingId=${initialValue?.flock_id}&kandangId=${kandang.project_flock_kandang_id}`}
disabled={
selectedKandangId === kandang.project_flock_kandang_id
}
> >
{kandang.name} {kandang.name}
</Button> </Button>
@@ -279,8 +279,6 @@ const ExpenseRequestContent = ({
)} )}
<div className='w-full mt-4 flex flex-col gap-4'> <div className='w-full mt-4 flex flex-col gap-4'>
{/* TODO: apply RBAC */}
<div className='w-full mx-auto flex flex-col sm:flex-row justify-end gap-2'> <div className='w-full mx-auto flex flex-col sm:flex-row justify-end gap-2'>
{isCurrentApprovalOnHeadArea && ( {isCurrentApprovalOnHeadArea && (
<RequirePermission permissions='lti.expense.approve.head_area'> <RequirePermission permissions='lti.expense.approve.head_area'>
@@ -59,8 +59,7 @@ const RowOptionsMenu = ({
detailClickHandler: (id: number) => void; detailClickHandler: (id: number) => void;
deleteClickHandler: () => void; deleteClickHandler: () => void;
}) => { }) => {
// TODO: change this to real condition const showEditButton = props.row.original.approval?.step_number !== 2;
const showEditButton = true;
const showDeleteButton = showEditButton; const showDeleteButton = showEditButton;
@@ -67,7 +67,6 @@ const ReportExpenseTab = ({ tabId }: ReportExpenseTabProps) => {
const isAnyExportLoading = isPdfExportLoading || isExcelExportLoading; const isAnyExportLoading = isPdfExportLoading || isExcelExportLoading;
// ===== SUBMISSION STATE ===== // ===== SUBMISSION STATE =====
const [isSubmitted, setIsSubmitted] = useState(false);
const [filterParams, setFilterParams] = useState<FilterParams>({}); const [filterParams, setFilterParams] = useState<FilterParams>({});
// ===== PAGINATION STATE ===== // ===== PAGINATION STATE =====
@@ -117,12 +116,10 @@ const ReportExpenseTab = ({ tabId }: ReportExpenseTabProps) => {
: undefined, : undefined,
}); });
filterModal.closeModal(); filterModal.closeModal();
setIsSubmitted(true);
setPage(1); setPage(1);
}, },
onReset: () => { onReset: () => {
setFilterParams({}); setFilterParams({});
setIsSubmitted(false);
setPage(1); setPage(1);
filterModal.closeModal(); filterModal.closeModal();
}, },
@@ -194,27 +191,25 @@ const ReportExpenseTab = ({ tabId }: ReportExpenseTabProps) => {
// ===== DATA FETCHING ===== // ===== DATA FETCHING =====
const { data: reportExpenseResponse, isLoading } = useSWR( const { data: reportExpenseResponse, isLoading } = useSWR(
isSubmitted () => {
? () => { const params = new URLSearchParams();
const params = new URLSearchParams(); if (filterParams.location_id)
if (filterParams.location_id) params.append('location_id', filterParams.location_id);
params.append('location_id', filterParams.location_id); if (filterParams.supplier_id)
if (filterParams.supplier_id) params.append('supplier_id', filterParams.supplier_id);
params.append('supplier_id', filterParams.supplier_id); if (filterParams.kandang_id)
if (filterParams.kandang_id) params.append('kandang_id', filterParams.kandang_id);
params.append('kandang_id', filterParams.kandang_id); if (filterParams.nonstock_id)
if (filterParams.nonstock_id) params.append('nonstock_id', filterParams.nonstock_id);
params.append('nonstock_id', filterParams.nonstock_id); if (filterParams.realization_date)
if (filterParams.realization_date) params.append('realization_date', filterParams.realization_date);
params.append('realization_date', filterParams.realization_date); if (filterParams.category)
if (filterParams.category) params.append('category', filterParams.category);
params.append('category', filterParams.category); params.append('page', String(page));
params.append('page', String(page)); params.append('limit', String(pageSize));
params.append('limit', String(pageSize));
return [`${ReportExpenseApi.basePath}?${params.toString()}`]; return [`${ReportExpenseApi.basePath}?${params.toString()}`];
} },
: null,
([url]: string[]) => httpClient<BaseApiResponse<ReportExpense[]>>(url) ([url]: string[]) => httpClient<BaseApiResponse<ReportExpense[]>>(url)
); );
@@ -529,25 +524,13 @@ const ReportExpenseTab = ({ tabId }: ReportExpenseTabProps) => {
<> <>
{TabActionsElement} {TabActionsElement}
<div className='w-full p-0 sm:p-3 flex flex-col gap-3'> <div className='w-full p-0 sm:p-3 flex flex-col gap-3'>
{!isSubmitted ? ( {isLoading && (
<ReportExpenseSkeleton
columns={columns}
icon={
<Icon
icon='heroicons:funnel'
className='text-white'
width={20}
height={20}
/>
}
title='No Filters Selected'
subtitle='Please choose filters to narrow down your results and make your search easier.'
/>
) : isLoading ? (
<div className='w-full flex flex-row justify-center items-center p-4'> <div className='w-full flex flex-row justify-center items-center p-4'>
<span className='loading loading-spinner loading-xl' /> <span className='loading loading-spinner loading-xl' />
</div> </div>
) : !data || data.length === 0 ? ( )}
{!isLoading && (!data || data.length === 0) && (
<ReportExpenseSkeleton <ReportExpenseSkeleton
columns={columns} columns={columns}
icon={ icon={
@@ -561,7 +544,9 @@ const ReportExpenseTab = ({ tabId }: ReportExpenseTabProps) => {
title='Data Not Yet Available' title='Data Not Yet Available'
subtitle='Please change your filters to get the data.' subtitle='Please change your filters to get the data.'
/> />
) : ( )}
{!isLoading && data.length > 0 && (
<> <>
<Table <Table
data={data} data={data}
@@ -61,7 +61,6 @@ const CustomerPaymentTab = ({ tabId }: CustomerPaymentTabProps) => {
const [pageSize] = useState(10); const [pageSize] = useState(10);
// ===== SUBMISSION STATE ===== // ===== SUBMISSION STATE =====
const [isSubmitted, setIsSubmitted] = useState(false);
const [filterParams, setFilterParams] = useState<FilterParams>({}); const [filterParams, setFilterParams] = useState<FilterParams>({});
const [dateErrorShown, setDateErrorShown] = useState(false); const [dateErrorShown, setDateErrorShown] = useState(false);
const [hasDateError, setHasDateError] = useState(false); const [hasDateError, setHasDateError] = useState(false);
@@ -102,13 +101,11 @@ const CustomerPaymentTab = ({ tabId }: CustomerPaymentTabProps) => {
filter_by: values.filter_by || undefined, filter_by: values.filter_by || undefined,
}); });
filterModal.closeModal(); filterModal.closeModal();
setIsSubmitted(true);
setCurrentPage(1); setCurrentPage(1);
setSubmitting(false); setSubmitting(false);
}, },
onReset: () => { onReset: () => {
setFilterParams({}); setFilterParams({});
setIsSubmitted(false);
setCurrentPage(1); setCurrentPage(1);
setHasDateError(false); setHasDateError(false);
if (dateErrorShown) { if (dateErrorShown) {
@@ -218,23 +215,21 @@ const CustomerPaymentTab = ({ tabId }: CustomerPaymentTabProps) => {
// ===== DATA FETCHING ===== // ===== DATA FETCHING =====
const { data: customerPayment, isLoading } = useSWR( const { data: customerPayment, isLoading } = useSWR(
isSubmitted () => {
? () => { const params = {
const params = { customer_ids: filterParams.customer_ids,
customer_ids: filterParams.customer_ids, filter_by: filterParams.filter_by as
filter_by: filterParams.filter_by as | 'trans_date'
| 'trans_date' | 'realization_date'
| 'realization_date' | undefined,
| undefined, start_date: filterParams.start_date,
start_date: filterParams.start_date, end_date: filterParams.end_date,
end_date: filterParams.end_date, page: currentPage,
page: currentPage, limit: pageSize,
limit: pageSize, };
};
return ['customer-payment-report', params]; return ['customer-payment-report', params];
} },
: null,
([, params]) => ([, params]) =>
FinanceApi.getCustomerPaymentReport( FinanceApi.getCustomerPaymentReport(
params.customer_ids, params.customer_ids,
@@ -700,25 +695,13 @@ const CustomerPaymentTab = ({ tabId }: CustomerPaymentTabProps) => {
<> <>
{TabActionsElement} {TabActionsElement}
<div className='w-full p-0 sm:p-3 flex flex-col gap-3'> <div className='w-full p-0 sm:p-3 flex flex-col gap-3'>
{!isSubmitted ? ( {isLoading && (
<CustomerSupplierSkeleton
columns={getTableColumns({} as CustomerPaymentSummary)}
icon={
<Icon
icon='heroicons:funnel'
className='text-white'
width={20}
height={20}
/>
}
title='No Filters Selected'
subtitle='Please choose filters to narrow down your results and make your search easier.'
/>
) : isLoading ? (
<div className='w-full flex flex-row justify-center items-center p-4'> <div className='w-full flex flex-row justify-center items-center p-4'>
<span className='loading loading-spinner loading-xl' /> <span className='loading loading-spinner loading-xl' />
</div> </div>
) : data.length === 0 ? ( )}
{!isLoading && data.length === 0 && (
<CustomerSupplierSkeleton <CustomerSupplierSkeleton
columns={getTableColumns({} as CustomerPaymentSummary)} columns={getTableColumns({} as CustomerPaymentSummary)}
icon={ icon={
@@ -732,7 +715,10 @@ const CustomerPaymentTab = ({ tabId }: CustomerPaymentTabProps) => {
title='Data Not Yet Available' title='Data Not Yet Available'
subtitle='Please change your filters to get the data.' subtitle='Please change your filters to get the data.'
/> />
) : ( )}
{!isLoading &&
data.length > 0 &&
data.map((customerReport) => { data.map((customerReport) => {
const summary = customerReport.summary || { const summary = customerReport.summary || {
total_qty: 0, total_qty: 0,
@@ -761,7 +747,6 @@ const CustomerPaymentTab = ({ tabId }: CustomerPaymentTabProps) => {
}} }}
variant='bordered' variant='bordered'
collapsible={true} collapsible={true}
defaultCollapsed={true}
> >
<Table <Table
data={[ data={[
@@ -825,8 +810,7 @@ const CustomerPaymentTab = ({ tabId }: CustomerPaymentTabProps) => {
/> />
</Card> </Card>
); );
}) })}
)}
</div> </div>
{/* Filter Modal */} {/* Filter Modal */}
@@ -85,7 +85,6 @@ const DebtSupplierTab = ({ tabId }: DebtSupplierTabProps) => {
supplier_ids: undefined, supplier_ids: undefined,
filter_by: undefined, filter_by: undefined,
}); });
const [isSubmitted, setIsSubmitted] = useState(false);
// ===== DATE ERROR STATE ===== // ===== DATE ERROR STATE =====
const [dateErrorShown, setDateErrorShown] = useState(false); const [dateErrorShown, setDateErrorShown] = useState(false);
@@ -129,7 +128,7 @@ const DebtSupplierTab = ({ tabId }: DebtSupplierTabProps) => {
filter_by: values.filterBy?.value?.toString() || undefined, filter_by: values.filterBy?.value?.toString() || undefined,
}); });
filterModal.closeModal(); filterModal.closeModal();
setIsSubmitted(true); // setIsSubmitted(true);
}, },
onReset: () => { onReset: () => {
setFilterParams({ setFilterParams({
@@ -138,7 +137,7 @@ const DebtSupplierTab = ({ tabId }: DebtSupplierTabProps) => {
supplier_ids: undefined, supplier_ids: undefined,
filter_by: undefined, filter_by: undefined,
}); });
setIsSubmitted(false); // setIsSubmitted(false);
filterModal.closeModal(); filterModal.closeModal();
}, },
}); });
@@ -150,18 +149,16 @@ const DebtSupplierTab = ({ tabId }: DebtSupplierTabProps) => {
// ===== DATA FETCHING ===== // ===== DATA FETCHING =====
const { data: debtSupplier, isLoading } = useSWR( const { data: debtSupplier, isLoading } = useSWR(
isSubmitted () => {
? () => { const params = {
const params = { supplier_ids: filterParams.supplier_ids,
supplier_ids: filterParams.supplier_ids, filter_by: filterParams.filter_by,
filter_by: filterParams.filter_by, start_date: filterParams.start_date,
start_date: filterParams.start_date, end_date: filterParams.end_date,
end_date: filterParams.end_date, };
};
return ['debt-supplier-report', params]; return ['debt-supplier-report', params];
} },
: null,
([, params]) => ([, params]) =>
DebtSupplierApi.getDebtSupplierReport( DebtSupplierApi.getDebtSupplierReport(
params.supplier_ids, params.supplier_ids,
@@ -611,25 +608,13 @@ const DebtSupplierTab = ({ tabId }: DebtSupplierTabProps) => {
<> <>
{TabActionsElement} {TabActionsElement}
<div className='w-full p-0 sm:p-3 flex flex-col gap-3'> <div className='w-full p-0 sm:p-3 flex flex-col gap-3'>
{!isSubmitted ? ( {isLoading && (
<DebtSupplierSkeleton
columns={getTableColumns()}
icon={
<Icon
icon='heroicons:funnel'
className='text-white'
width={20}
height={20}
/>
}
title='No Filters Selected'
subtitle='Please choose filters to narrow down your results and make your search easier.'
/>
) : isLoading ? (
<div className='w-full flex flex-row justify-center items-center p-4'> <div className='w-full flex flex-row justify-center items-center p-4'>
<span className='loading loading-spinner loading-xl' /> <span className='loading loading-spinner loading-xl' />
</div> </div>
) : data.length === 0 ? ( )}
{!isLoading && data.length === 0 && (
<DebtSupplierSkeleton <DebtSupplierSkeleton
columns={getTableColumns()} columns={getTableColumns()}
icon={ icon={
@@ -643,7 +628,10 @@ const DebtSupplierTab = ({ tabId }: DebtSupplierTabProps) => {
title='Data Not Yet Available' title='Data Not Yet Available'
subtitle='Please change your filters to get the data.' subtitle='Please change your filters to get the data.'
/> />
) : ( )}
{!isLoading &&
data.length > 0 &&
data.map((supplierReport) => { data.map((supplierReport) => {
return ( return (
<Card <Card
@@ -658,7 +646,6 @@ const DebtSupplierTab = ({ tabId }: DebtSupplierTabProps) => {
}} }}
variant='bordered' variant='bordered'
collapsible={true} collapsible={true}
defaultCollapsed={true}
> >
<Table <Table
data={[ data={[
@@ -729,8 +716,7 @@ const DebtSupplierTab = ({ tabId }: DebtSupplierTabProps) => {
/> />
</Card> </Card>
); );
}) })}
)}
</div> </div>
{/* Filter Modal */} {/* Filter Modal */}
@@ -61,7 +61,6 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
// ===== SUBMISSION STATE ===== // ===== SUBMISSION STATE =====
const [filterParams, setFilterParams] = useState<FilterParams>({}); const [filterParams, setFilterParams] = useState<FilterParams>({});
const [isSubmitted, setIsSubmitted] = useState(false);
const [dateErrorShown, setDateErrorShown] = useState(false); const [dateErrorShown, setDateErrorShown] = useState(false);
const [hasDateError, setHasDateError] = useState(false); const [hasDateError, setHasDateError] = useState(false);
@@ -70,24 +69,34 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
const filterModal = useModal(); const filterModal = useModal();
// ===== OPTIONS ===== // ===== OPTIONS =====
const { options: areaOptions, isLoadingOptions: isLoadingAreas } = useSelect( const {
AreaApi.basePath, options: areaOptions,
'id', isLoadingOptions: isLoadingAreas,
'name', setInputValue: setAreaInputValue,
'search' loadMore: loadMoreArea,
); } = useSelect(AreaApi.basePath, 'id', 'name', 'search');
const { options: supplierOptions, isLoadingOptions: isLoadingSuppliers } = const {
useSelect(SupplierApi.basePath, 'id', 'name', 'search', { options: supplierOptions,
category: 'SAPRONAK', isLoadingOptions: isLoadingSuppliers,
}); setInputValue: setSupplierInputValue,
loadMore: loadMoreSupplier,
} = useSelect(SupplierApi.basePath, 'id', 'name', 'search', {
category: 'SAPRONAK',
});
const { options: productOptions, isLoadingOptions: isLoadingProducts } = const {
useSelect(ProductApi.basePath, 'id', 'name', 'search'); options: productOptions,
isLoadingOptions: isLoadingProducts,
setInputValue: setProductInputValue,
loadMore: loadMoreProduct,
} = useSelect(ProductApi.basePath, 'id', 'name', 'search');
const { const {
options: productCategoryOptions, options: productCategoryOptions,
isLoadingOptions: isLoadingProductCategories, isLoadingOptions: isLoadingProductCategories,
setInputValue: setProductCategoryInputValue,
loadMore: loadMoreProductCategory,
} = useSelect(ProductCategoryApi.basePath, 'id', 'name', 'search'); } = useSelect(ProductCategoryApi.basePath, 'id', 'name', 'search');
const dataTypeOptions = useMemo( const dataTypeOptions = useMemo(
@@ -131,13 +140,11 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
sort_by: values.sort_by || undefined, sort_by: values.sort_by || undefined,
}); });
filterModal.closeModal(); filterModal.closeModal();
setIsSubmitted(true);
setCurrentPage(1); setCurrentPage(1);
setSubmitting(false); setSubmitting(false);
}, },
onReset: () => { onReset: () => {
setFilterParams({}); setFilterParams({});
setIsSubmitted(false);
setCurrentPage(1); setCurrentPage(1);
setHasDateError(false); setHasDateError(false);
if (dateErrorShown) { if (dateErrorShown) {
@@ -261,24 +268,22 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
// ===== DATA FETCHING ===== // ===== DATA FETCHING =====
const { data: purchasePerSupplier, isLoading } = useSWR( const { data: purchasePerSupplier, isLoading } = useSWR(
isSubmitted () => {
? () => { const params = {
const params = { area_id: filterParams.area_id,
area_id: filterParams.area_id, supplier_id: filterParams.supplier_id,
supplier_id: filterParams.supplier_id, product_id: filterParams.product_id,
product_id: filterParams.product_id, product_category_id: filterParams.product_category_id,
product_category_id: filterParams.product_category_id, start_date: filterParams.start_date,
start_date: filterParams.start_date, end_date: filterParams.end_date,
end_date: filterParams.end_date, sort_by: filterParams.sort_by,
sort_by: filterParams.sort_by, filter_by: filterParams.filter_by,
filter_by: filterParams.filter_by, page: currentPage,
page: currentPage, limit: pageSize,
limit: pageSize, };
};
return ['logistic-purchase-report', params]; return ['logistic-purchase-report', params];
} },
: null,
([, params]) => ([, params]) =>
LogisticApi.getLogisticPurchasePerSupplierReport( LogisticApi.getLogisticPurchasePerSupplierReport(
params.area_id, params.area_id,
@@ -726,21 +731,7 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
<> <>
{TabActionsElement} {TabActionsElement}
<div className='w-full p-0 sm:p-3 flex flex-col gap-3'> <div className='w-full p-0 sm:p-3 flex flex-col gap-3'>
{!isSubmitted ? ( {isLoading && (
<PurchasePerSupplierSkeleton
columns={getTableColumns({} as LogisticPurchasePerSupplierSummary)}
icon={
<Icon
icon='heroicons:funnel'
className='text-white'
width={20}
height={20}
/>
}
title='No Filters Selected'
subtitle='Please choose filters to narrow down your results and make your search easier.'
/>
) : isLoading ? (
<PurchasePerSupplierSkeleton <PurchasePerSupplierSkeleton
columns={getTableColumns({} as LogisticPurchasePerSupplierSummary)} columns={getTableColumns({} as LogisticPurchasePerSupplierSummary)}
icon={ icon={
@@ -754,7 +745,9 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
title='Memuat Data Pembelian Per Supplier' title='Memuat Data Pembelian Per Supplier'
subtitle='Silakan tunggu sebentar...' subtitle='Silakan tunggu sebentar...'
/> />
) : data.length === 0 ? ( )}
{!isLoading && data.length === 0 && (
<PurchasePerSupplierSkeleton <PurchasePerSupplierSkeleton
columns={getTableColumns({} as LogisticPurchasePerSupplierSummary)} columns={getTableColumns({} as LogisticPurchasePerSupplierSummary)}
icon={ icon={
@@ -768,7 +761,10 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
title='Data Not Yet Available' title='Data Not Yet Available'
subtitle='Please change your filters to get the data.' subtitle='Please change your filters to get the data.'
/> />
) : ( )}
{!isLoading &&
data.length > 0 &&
data.map((supplierReport) => { data.map((supplierReport) => {
const summary = supplierReport.summary || { const summary = supplierReport.summary || {
total_qty: 0, total_qty: 0,
@@ -798,7 +794,6 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
}} }}
variant='bordered' variant='bordered'
collapsible={true} collapsible={true}
defaultCollapsed={true}
> >
<Table <Table
data={supplierReport.rows} data={supplierReport.rows}
@@ -827,8 +822,7 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
/> />
</Card> </Card>
); );
}) })}
)}
</div> </div>
{/* Filter Modal */} {/* Filter Modal */}
@@ -907,6 +901,8 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
isLoading={isLoadingAreas} isLoading={isLoadingAreas}
isClearable isClearable
className={{ wrapper: 'w-full' }} className={{ wrapper: 'w-full' }}
onInputChange={setAreaInputValue}
onMenuScrollToBottom={loadMoreArea}
/> />
{/* Supplier Filter */} {/* Supplier Filter */}
@@ -926,6 +922,8 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
isLoading={isLoadingSuppliers} isLoading={isLoadingSuppliers}
isClearable isClearable
className={{ wrapper: 'w-full' }} className={{ wrapper: 'w-full' }}
onInputChange={setSupplierInputValue}
onMenuScrollToBottom={loadMoreSupplier}
/> />
{/* Product Filter */} {/* Product Filter */}
@@ -945,6 +943,8 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
isLoading={isLoadingProducts} isLoading={isLoadingProducts}
isClearable isClearable
className={{ wrapper: 'w-full' }} className={{ wrapper: 'w-full' }}
onInputChange={setProductInputValue}
onMenuScrollToBottom={loadMoreProduct}
/> />
{/* Product Category Filter */} {/* Product Category Filter */}
@@ -964,6 +964,8 @@ const PurchasesPerSupplierTab = ({ tabId }: PurchasesPerSupplierTabProps) => {
isLoading={isLoadingProductCategories} isLoading={isLoadingProductCategories}
isClearable isClearable
className={{ wrapper: 'w-full' }} className={{ wrapper: 'w-full' }}
onInputChange={setProductCategoryInputValue}
onMenuScrollToBottom={loadMoreProductCategory}
/> />
{/* Filter By Type */} {/* Filter By Type */}
@@ -70,9 +70,6 @@ const DailyMarketingTab = ({ tabId }: DailyMarketingTabProps) => {
const [isExcelExportLoading, setIsExcelExportLoading] = useState(false); const [isExcelExportLoading, setIsExcelExportLoading] = useState(false);
const isAnyExportLoading = isPdfExportLoading || isExcelExportLoading; const isAnyExportLoading = isPdfExportLoading || isExcelExportLoading;
// ===== SUBMISSION STATE =====
const [isSubmitted, setIsSubmitted] = useState(false);
// ===== SEARCH STATE ===== // ===== SEARCH STATE =====
const [searchValue, setSearchValue] = useState<string>(''); const [searchValue, setSearchValue] = useState<string>('');
@@ -88,21 +85,33 @@ const DailyMarketingTab = ({ tabId }: DailyMarketingTabProps) => {
const filterModal = useModal(); const filterModal = useModal();
// ===== OPTIONS ===== // ===== OPTIONS =====
const { options: areaOptions, isLoadingOptions: isLoadingAreas } = useSelect( const {
AreaApi.basePath, options: areaOptions,
'id', isLoadingOptions: isLoadingAreas,
'name', setInputValue: setAreaInputValue,
'search' loadMore: loadMoreArea,
); } = useSelect(AreaApi.basePath, 'id', 'name', 'search');
const { options: locationOptions, isLoadingOptions: isLoadingLocations } = const {
useSelect(LocationApi.basePath, 'id', 'name', 'search'); options: locationOptions,
isLoadingOptions: isLoadingLocations,
setInputValue: setLocationInputValue,
loadMore: loadMoreLocation,
} = useSelect(LocationApi.basePath, 'id', 'name', 'search');
const { options: warehouseOptions, isLoadingOptions: isLoadingWarehouses } = const {
useSelect(WarehouseApi.basePath, 'id', 'name', 'search'); options: warehouseOptions,
isLoadingOptions: isLoadingWarehouses,
setInputValue: setWarehouseInputValue,
loadMore: loadMoreWarehouse,
} = useSelect(WarehouseApi.basePath, 'id', 'name', 'search');
const { options: customerOptions, isLoadingOptions: isLoadingCustomers } = const {
useSelect(CustomerApi.basePath, 'id', 'name', 'search'); options: customerOptions,
isLoadingOptions: isLoadingCustomers,
setInputValue: setCustomerInputValue,
loadMore: loadMoreCustomer,
} = useSelect(CustomerApi.basePath, 'id', 'name', 'search');
// ===== FORMIK SETUP ===== // ===== FORMIK SETUP =====
const formik = useFormik<DailyMarketingReportFilterType>({ const formik = useFormik<DailyMarketingReportFilterType>({
@@ -132,12 +141,10 @@ const DailyMarketingTab = ({ tabId }: DailyMarketingTabProps) => {
sort_by: values.sort_by || undefined, sort_by: values.sort_by || undefined,
}); });
filterModal.closeModal(); filterModal.closeModal();
setIsSubmitted(true);
setSubmitting(false); setSubmitting(false);
}, },
onReset: () => { onReset: () => {
setFilterParams({}); setFilterParams({});
setIsSubmitted(false);
filterModal.closeModal(); filterModal.closeModal();
}, },
}); });
@@ -211,31 +218,28 @@ const DailyMarketingTab = ({ tabId }: DailyMarketingTabProps) => {
// ===== DATA FETCHING ===== // ===== DATA FETCHING =====
const { data: dailyMarketings, isLoading } = useSWR( const { data: dailyMarketings, isLoading } = useSWR(
isSubmitted () => {
? () => { const params = new URLSearchParams();
const params = new URLSearchParams();
if (searchValue) params.set('search', searchValue); if (searchValue) params.set('search', searchValue);
if (filterParams.area_id) params.set('area_id', filterParams.area_id); if (filterParams.area_id) params.set('area_id', filterParams.area_id);
if (filterParams.location_id) if (filterParams.location_id)
params.set('location_id', filterParams.location_id); params.set('location_id', filterParams.location_id);
if (filterParams.warehouse_id) if (filterParams.warehouse_id)
params.set('warehouse_id', filterParams.warehouse_id); params.set('warehouse_id', filterParams.warehouse_id);
if (filterParams.customer_id) if (filterParams.customer_id)
params.set('customer_id', filterParams.customer_id); params.set('customer_id', filterParams.customer_id);
if (filterParams.start_date) if (filterParams.start_date)
params.set('start_date', filterParams.start_date); params.set('start_date', filterParams.start_date);
if (filterParams.end_date) if (filterParams.end_date) params.set('end_date', filterParams.end_date);
params.set('end_date', filterParams.end_date); if (filterParams.filter_by)
if (filterParams.filter_by) params.set('filter_by', filterParams.filter_by);
params.set('filter_by', filterParams.filter_by); if (filterParams.marketing_type)
if (filterParams.marketing_type) params.set('marketing_type', filterParams.marketing_type);
params.set('marketing_type', filterParams.marketing_type); if (filterParams.sort_by) params.set('sort_by', filterParams.sort_by);
if (filterParams.sort_by) params.set('sort_by', filterParams.sort_by);
return ['daily-marketing-report', params.toString()]; return ['daily-marketing-report', params.toString()];
} },
: null,
([, params]) => ([, params]) =>
MarketingReportApi.getAllDailyMarketingFetcher( MarketingReportApi.getAllDailyMarketingFetcher(
`${MarketingReportApi.basePath}?${params}` `${MarketingReportApi.basePath}?${params}`
@@ -648,21 +652,7 @@ const DailyMarketingTab = ({ tabId }: DailyMarketingTabProps) => {
<> <>
{TabActionsElement} {TabActionsElement}
<div className='w-full p-0 sm:p-3 flex flex-col gap-3'> <div className='w-full p-0 sm:p-3 flex flex-col gap-3'>
{!isSubmitted ? ( {isLoading && (
<DailyMarketingReportSkeleton
columns={getTableColumns()}
icon={
<Icon
icon='heroicons:funnel'
className='text-white'
width={20}
height={20}
/>
}
title='No Filters Selected'
subtitle='Please choose filters to narrow down your results and make your search easier.'
/>
) : isLoading ? (
<DailyMarketingReportSkeleton <DailyMarketingReportSkeleton
columns={getTableColumns()} columns={getTableColumns()}
icon={ icon={
@@ -676,7 +666,9 @@ const DailyMarketingTab = ({ tabId }: DailyMarketingTabProps) => {
title='Memuat Data Penjualan Harian' title='Memuat Data Penjualan Harian'
subtitle='Silakan tunggu sebentar...' subtitle='Silakan tunggu sebentar...'
/> />
) : data.length === 0 ? ( )}
{!isLoading && data.length === 0 && (
<DailyMarketingReportSkeleton <DailyMarketingReportSkeleton
columns={getTableColumns()} columns={getTableColumns()}
icon={ icon={
@@ -690,7 +682,9 @@ const DailyMarketingTab = ({ tabId }: DailyMarketingTabProps) => {
title='Data Not Yet Available' title='Data Not Yet Available'
subtitle='Please change your filters to get the data.' subtitle='Please change your filters to get the data.'
/> />
) : ( )}
{!isLoading && data.length > 0 && (
<Table <Table
data={data} data={data}
columns={getTableColumns()} columns={getTableColumns()}
@@ -837,6 +831,8 @@ const DailyMarketingTab = ({ tabId }: DailyMarketingTabProps) => {
}} }}
isClearable isClearable
className={{ wrapper: 'w-full' }} className={{ wrapper: 'w-full' }}
onInputChange={setAreaInputValue}
onMenuScrollToBottom={loadMoreArea}
/> />
{/* Location Filter */} {/* Location Filter */}
@@ -854,6 +850,8 @@ const DailyMarketingTab = ({ tabId }: DailyMarketingTabProps) => {
}} }}
isClearable isClearable
className={{ wrapper: 'w-full' }} className={{ wrapper: 'w-full' }}
onInputChange={setLocationInputValue}
onMenuScrollToBottom={loadMoreLocation}
/> />
{/* Warehouse Filter */} {/* Warehouse Filter */}
@@ -871,6 +869,8 @@ const DailyMarketingTab = ({ tabId }: DailyMarketingTabProps) => {
}} }}
isClearable isClearable
className={{ wrapper: 'w-full' }} className={{ wrapper: 'w-full' }}
onInputChange={setWarehouseInputValue}
onMenuScrollToBottom={loadMoreWarehouse}
/> />
{/* Customer Filter */} {/* Customer Filter */}
@@ -888,6 +888,8 @@ const DailyMarketingTab = ({ tabId }: DailyMarketingTabProps) => {
}} }}
isClearable isClearable
className={{ wrapper: 'w-full' }} className={{ wrapper: 'w-full' }}
onInputChange={setCustomerInputValue}
onMenuScrollToBottom={loadMoreCustomer}
/> />
{/* Filter By Date Type */} {/* Filter By Date Type */}
@@ -791,6 +791,10 @@ const HppPerKandangTab = ({ tabId }: HppPerKandangTabProps) => {
[data, perWeightRangeSummary] [data, perWeightRangeSummary]
); );
useEffectHook(() => {
filterModal.openModal();
}, []);
return ( return (
<> <>
{TabActionsElement} {TabActionsElement}
@@ -631,6 +631,10 @@ const ProductionResultContent = ({ tabId }: ProductionResultTabProps) => {
// Render the TabActions component // Render the TabActions component
const TabActionsElement = useMemo(() => <TabActions />, [TabActions]); const TabActionsElement = useMemo(() => <TabActions />, [TabActions]);
useEffect(() => {
filterModal.openModal();
}, []);
return ( return (
<> <>
{TabActionsElement} {TabActionsElement}