diff --git a/src/components/pages/dashboard/DashboardProduction.tsx b/src/components/pages/dashboard/DashboardProduction.tsx index dea66582..62f5840f 100644 --- a/src/components/pages/dashboard/DashboardProduction.tsx +++ b/src/components/pages/dashboard/DashboardProduction.tsx @@ -5,12 +5,12 @@ 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 } from 'react'; +import { useState, useEffect, useRef, useCallback, useMemo } from 'react'; import useSWR from 'swr'; import { DashboardApi } from '@/services/api/dashboard'; import { useFormik } from 'formik'; import { ProjectFlockApi } from '@/services/api/production'; -import { KandangApi, LocationApi } from '@/services/api/master-data'; +import { LocationApi } from '@/services/api/master-data'; import { generateDashboardPDF } from '@/components/pages/dashboard/export/DashboardPDF'; import { DashboardFilterType, @@ -42,6 +42,7 @@ import { cn } from '@/lib/helper'; import DashboardExportStats, { DashboardExportStatsRef, } from '@/components/pages/dashboard/export/DashboardExportStats'; +import { ProjectFlock } from '@/types/api/production/project-flock'; // Helper function to normalize values to array const normalizeToArray = ( @@ -71,6 +72,7 @@ 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); @@ -114,9 +116,17 @@ const DashboardProduction = () => { options: flockOptions, isLoadingOptions: isLoadingFlockOptions, loadMore: loadMoreFlock, - } = useSelect(ProjectFlockApi.basePath, 'id', 'flock_name', '', { - location_id: selectedLocationIds ? selectedLocationIds.toString() : '', - }); + rawData: projectFlocksRawData, + } = useSelect( + ProjectFlockApi.basePath, + 'id', + 'flock_name', + '', + { + location_id: + selectedLocationIds.length > 0 ? selectedLocationIds.toString() : '', + } + ); const { setInputValue: setInputValueLocation, @@ -125,13 +135,6 @@ const DashboardProduction = () => { loadMore: loadMoreLocation, } = useSelect(LocationApi.basePath, 'id', 'name'); - const { - setInputValue: setInputValueKandang, - options: kandangOptions, - isLoadingOptions: isLoadingKandangOptions, - loadMore: loadMoreKandang, - } = useSelect(KandangApi.basePath, 'id', 'name', ''); - const comparisonTypeOptions = [ { value: 'FARM', label: 'Farm' }, { value: 'FLOCK', label: 'Flock' }, @@ -162,11 +165,66 @@ 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 { + setInputValue: setInputValueKandang, + options: kandangOptions, + isLoadingOptions: isLoadingKandangOptions, + loadMore: loadMoreKandang, + } = kandangSelect; + const handleResetFilter = useCallback(() => { resetForm(); resetFilterValues(); // Clear stored filter values setAnalysisMode('OVERVIEW'); setSelectedLocationIds([]); + setRawKandangInputValue(''); }, [resetForm, resetFilterValues]); // ===== Formik Error List ===== @@ -461,6 +519,7 @@ const DashboardProduction = () => { formik.setFieldValue('kandang', []); formik.setFieldValue('comparisonType', ''); setSelectedLocationIds([]); + setRawKandangInputValue(''); }} color='primary' className={{ @@ -532,6 +591,7 @@ const DashboardProduction = () => { // Reset dependent fields when location changes formik.setFieldValue('flock', []); formik.setFieldValue('kandang', []); + setRawKandangInputValue(''); }} errorMessage={formik.errors.location as string} options={locationOptions} @@ -564,6 +624,7 @@ const DashboardProduction = () => { // Reset dependent fields when location changes formik.setFieldValue('flock', []); formik.setFieldValue('kandang', []); + setRawKandangInputValue(''); }} errorMessage={formik.errors.location as string} options={locationOptions} @@ -600,9 +661,11 @@ const DashboardProduction = () => { | null | undefined } - onChange={(selected) => - formik.setFieldValue('flock', selected) - } + onChange={(selected) => { + formik.setFieldValue('flock', selected); + formik.setFieldValue('kandang', []); + setInputValueKandang(''); + }} errorMessage={formik.errors.flock as string} onInputChange={setInputValueFlock} onMenuScrollToBottom={loadMoreFlock} @@ -627,9 +690,11 @@ const DashboardProduction = () => { | null | undefined } - onChange={(selected) => - formik.setFieldValue('flock', selected) - } + onChange={(selected) => { + formik.setFieldValue('flock', selected); + formik.setFieldValue('kandang', []); + setInputValueKandang(''); + }} errorMessage={formik.errors.flock as string} onInputChange={setInputValueFlock} onMenuScrollToBottom={loadMoreFlock}