diff --git a/src/components/pages/dashboard/DashboardProduction.tsx b/src/components/pages/dashboard/DashboardProduction.tsx index 81254442..6b3dabbd 100644 --- a/src/components/pages/dashboard/DashboardProduction.tsx +++ b/src/components/pages/dashboard/DashboardProduction.tsx @@ -5,11 +5,14 @@ import { Icon } from '@iconify/react'; import Modal, { useModal } from '@/components/Modal'; import DateInput from '@/components/input/DateInput'; import { OptionType, useSelect } from '@/components/input/SelectInput'; -import { useState, useEffect, useRef, useCallback, useMemo } from 'react'; +import { useState, useEffect, useRef, useCallback } from 'react'; import useSWR from 'swr'; import { DashboardApi } from '@/services/api/dashboard'; import { useFormik } from 'formik'; -import { ProjectFlockApi } from '@/services/api/production'; +import { + ProjectFlockApi, + ProjectFlockKandangApi, +} from '@/services/api/production'; import { LocationApi } from '@/services/api/master-data'; import { generateDashboardPDF } from '@/components/pages/dashboard/export/DashboardPDF'; import { @@ -22,10 +25,7 @@ import DashboardExportCharts, { DashboardExportChartsRef, } from '@/components/pages/dashboard/export/DashboardExportCharts'; import { RadioGroup, RadioGroupItem } from '@/components/input/RadioInput'; -import { - DashboardFilter, - DashboardMeta, -} from '@/types/api/dashboard/dashboard'; +import { DashboardMeta } from '@/types/api/dashboard/dashboard'; import DashboardStats from '@/components/pages/dashboard/chart/DashboardStats'; import { isResponseSuccess } from '@/lib/api-helper'; import AlertErrorList from '@/components/helper/form/FormErrors'; @@ -43,6 +43,7 @@ import DashboardExportStats, { DashboardExportStatsRef, } from '@/components/pages/dashboard/export/DashboardExportStats'; import { ProjectFlock } from '@/types/api/production/project-flock'; +import { ProjectFlockKandang } from '@/types/api/production/project-flock-kandang'; // Helper function to normalize values to array const normalizeToArray = ( @@ -72,7 +73,6 @@ const DashboardProduction = () => { const [selectedLocationIds, setSelectedLocationIds] = useState( normalizeToArray(filterValues.location) ); - const [kandangInputValue, setRawKandangInputValue] = useState(''); const [exporting, setExporting] = useState(false); const allChartsRef = useRef(null); const allStatsRef = useRef(null); @@ -116,15 +116,13 @@ const DashboardProduction = () => { options: flockOptions, isLoadingOptions: isLoadingFlockOptions, loadMore: loadMoreFlock, - rawData: projectFlocksRawData, } = useSelect( ProjectFlockApi.basePath, 'id', 'flock_name', - '', + 'search', { - location_id: - selectedLocationIds.length > 0 ? selectedLocationIds.toString() : '', + location_id: selectedLocationIds ? selectedLocationIds.toString() : '', } ); @@ -165,66 +163,34 @@ const DashboardProduction = () => { const { resetForm } = formik; - const selectedFlockIds = useMemo( - () => normalizeToArray(formik.values.flock), - [formik.values.flock] - ); - - const derivedKandangOptions = useMemo(() => { - if (!isResponseSuccess(projectFlocksRawData)) return []; - - const availableProjectFlocks = projectFlocksRawData.data.filter( - (projectFlock) => - selectedFlockIds.length === 0 || - selectedFlockIds.includes(projectFlock.id) - ); - - const kandangMap = new Map>(); - - availableProjectFlocks.forEach((projectFlock) => { - projectFlock.kandangs?.forEach((kandang) => { - if (!kandangMap.has(kandang.id)) { - kandangMap.set(kandang.id, { - value: kandang.id, - label: kandang.name, - }); - } - }); - }); - - const normalizedSearch = kandangInputValue.trim().toLowerCase(); - const allOptions = Array.from(kandangMap.values()); - - if (!normalizedSearch) return allOptions; - - return allOptions.filter((option) => - option.label.toLowerCase().includes(normalizedSearch) - ); - }, [projectFlocksRawData, selectedFlockIds, kandangInputValue]); - - const kandangSelect = useMemo( - () => ({ - setInputValue: setRawKandangInputValue, - options: derivedKandangOptions, - isLoadingOptions: isLoadingFlockOptions, - loadMore: loadMoreFlock, - }), - [derivedKandangOptions, isLoadingFlockOptions, loadMoreFlock] - ); + const selectedLocationValues = normalizeToArray(formik.values.location); + const selectedFlockValues = normalizeToArray(formik.values.flock); const { setInputValue: setInputValueKandang, options: kandangOptions, isLoadingOptions: isLoadingKandangOptions, loadMore: loadMoreKandang, - } = kandangSelect; + } = useSelect( + ProjectFlockKandangApi.basePath, + 'kandang_id', + 'kandang.name', + 'search', + { + location_id: + selectedLocationValues.length > 0 + ? selectedLocationValues.toString() + : '', + project_flock_id: + selectedFlockValues.length > 0 ? selectedFlockValues.toString() : '', + } + ); const handleResetFilter = useCallback(() => { resetForm(); resetFilterValues(); // Clear stored filter values setAnalysisMode('OVERVIEW'); setSelectedLocationIds([]); - setRawKandangInputValue(''); filterModal.closeModal(); }, [filterModal, resetForm, resetFilterValues]); @@ -520,7 +486,6 @@ const DashboardProduction = () => { formik.setFieldValue('kandang', []); formik.setFieldValue('comparisonType', ''); setSelectedLocationIds([]); - setRawKandangInputValue(''); }} color='primary' className={{ @@ -592,7 +557,6 @@ const DashboardProduction = () => { // Reset dependent fields when location changes formik.setFieldValue('flock', []); formik.setFieldValue('kandang', []); - setRawKandangInputValue(''); }} errorMessage={formik.errors.location as string} options={locationOptions} @@ -625,7 +589,6 @@ const DashboardProduction = () => { // Reset dependent fields when location changes formik.setFieldValue('flock', []); formik.setFieldValue('kandang', []); - setRawKandangInputValue(''); }} errorMessage={formik.errors.location as string} options={locationOptions} @@ -662,11 +625,9 @@ const DashboardProduction = () => { | null | undefined } - onChange={(selected) => { - formik.setFieldValue('flock', selected); - formik.setFieldValue('kandang', []); - setInputValueKandang(''); - }} + onChange={(selected) => + formik.setFieldValue('flock', selected) + } errorMessage={formik.errors.flock as string} onInputChange={setInputValueFlock} onMenuScrollToBottom={loadMoreFlock} @@ -691,11 +652,9 @@ const DashboardProduction = () => { | null | undefined } - onChange={(selected) => { - formik.setFieldValue('flock', selected); - formik.setFieldValue('kandang', []); - setInputValueKandang(''); - }} + onChange={(selected) => + formik.setFieldValue('flock', selected) + } errorMessage={formik.errors.flock as string} onInputChange={setInputValueFlock} onMenuScrollToBottom={loadMoreFlock} diff --git a/src/components/pages/marketing/MarketingFilter.tsx b/src/components/pages/marketing/MarketingFilter.tsx index 624c573c..823d2dd2 100644 --- a/src/components/pages/marketing/MarketingFilter.tsx +++ b/src/components/pages/marketing/MarketingFilter.tsx @@ -17,6 +17,7 @@ import { import { MarketingFilter } from '@/types/api/marketing/marketing'; import SelectInputCheckbox from '@/components/input/SelectInputCheckbox'; import { MarketingApi } from '@/services/api/marketing/marketing'; +import { CustomerApi } from '@/services/api/master-data'; import { isResponseSuccess } from '@/lib/api-helper'; import { BaseMarketing, BaseSalesOrder } from '@/types/api/marketing/marketing'; @@ -41,9 +42,12 @@ const MarketingFilterModal = ({ isLoadingOptions: isLoadingProductsOptions, setInputValue: setProductsInputValue, loadMore: loadMoreProducts, - } = useSelect(MarketingApi.basePath, 'id', 'so_number', '', { - limit: 'limit', - }); + } = useSelect( + MarketingApi.basePath, + 'id', + 'so_number', + 'search' + ); const productsOptions = useMemo(() => { if (!productsRawData || !isResponseSuccess(productsRawData)) return []; @@ -70,19 +74,10 @@ const MarketingFilterModal = ({ isLoadingOptions: isLoadingCustomersOptions, setInputValue: setCustomersInputValue, loadMore: loadMoreCustomers, - } = useSelect(MarketingApi.basePath, 'customer.id', 'customer.name', '', { - limit: 'limit', + } = useSelect(CustomerApi.basePath, 'id', 'name', 'search', { + has_marketing: 'true', }); - const salesCustomerOptions = useMemo(() => { - const seen = new Set(); - return customersOptions.filter((customer) => { - if (seen.has(customer.value)) return false; - seen.add(customer.value); - return true; - }); - }, [customersOptions]); - const statusOptions = [ ...MARKETING_APPROVAL_LINE.map((item) => ({ value: item.step_name.split(' ').join('_').toUpperCase(), @@ -190,7 +185,7 @@ const MarketingFilterModal = ({ label='Customer' isClearable placeholder='Pilih customer' - options={salesCustomerOptions} + options={customersOptions} isLoading={isLoadingCustomersOptions} value={formik.values.customer} onChange={customerChangeHandler}