diff --git a/src/components/pages/report/expense/tab/ReportDepreciationTab.tsx b/src/components/pages/report/expense/tab/ReportDepreciationTab.tsx index 403bc63b..8c6caaa3 100644 --- a/src/components/pages/report/expense/tab/ReportDepreciationTab.tsx +++ b/src/components/pages/report/expense/tab/ReportDepreciationTab.tsx @@ -1,271 +1,121 @@ 'use client'; -import React, { - useCallback, - useEffect, - useMemo, - useRef, - useState, -} from 'react'; -import { Icon } from '@iconify/react'; +import React, { useEffect, useMemo } from 'react'; +import useSWR from 'swr'; import { ColumnDef } from '@tanstack/react-table'; -import Button from '@/components/Button'; -import Dropdown from '@/components/dropdown/Dropdown'; -import Modal, { useModal } from '@/components/Modal'; + +import { Icon } from '@iconify/react'; +import Card from '@/components/Card'; import Pagination from '@/components/Pagination'; import Table from '@/components/Table'; import ButtonFilter from '@/components/helper/ButtonFilter'; -import SelectInput, { OptionType } from '@/components/input/SelectInput'; import ReportExpenseSkeleton from '@/components/pages/report/expense/skeleton/ReportExpenseSkeleton'; +import { useModal } from '@/components/Modal'; +import ReportDepreciationFilterModal from '@/components/pages/report/expense/tab/ReportDepreciationFilterModal'; + import { useTabActionsStore } from '@/stores/tab-actions/tab-actions.store'; -import { formatCurrency } from '@/lib/helper'; -import { - ReportDepreciation, - ReportDepreciationSearchParams, -} from '@/types/api/report/report-expense'; -import toast from 'react-hot-toast'; +import { ReportDepreciation } from '@/types/api/report/report-expense'; +import { DepreciationReportApi } from '@/services/api/report/expense-report'; +import { useTableFilter } from '@/services/hooks/useTableFilter'; +import { isResponseSuccess } from '@/lib/api-helper'; +import { formatCurrency, formatDate, formatNumber } from '@/lib/helper'; interface ReportDepreciationTabProps { tabId: string; } -const DUMMY_DEPRECIATION_DATA: ReportDepreciation[] = [ - { - id: 'DEP-001', - flock: 'Flock A-01', - totalCostPullet: 185000000, - totalDepresiasi: 38500000, - periode: 'Periode 1', - farm: 'Farm Sukamaju', - jumlahKandang: 4, - }, - { - id: 'DEP-002', - flock: 'Flock A-02', - totalCostPullet: 192500000, - totalDepresiasi: 40125000, - periode: 'Periode 1', - farm: 'Farm Sukamaju', - jumlahKandang: 5, - }, - { - id: 'DEP-003', - flock: 'Flock B-01', - totalCostPullet: 176800000, - totalDepresiasi: 36200000, - periode: 'Periode 2', - farm: 'Farm Cibitung', - jumlahKandang: 3, - }, - { - id: 'DEP-004', - flock: 'Flock B-02', - totalCostPullet: 201400000, - totalDepresiasi: 42250000, - periode: 'Periode 2', - farm: 'Farm Cibitung', - jumlahKandang: 4, - }, - { - id: 'DEP-005', - flock: 'Flock C-01', - totalCostPullet: 210900000, - totalDepresiasi: 43950000, - periode: 'Periode 3', - farm: 'Farm Karawang', - jumlahKandang: 6, - }, - { - id: 'DEP-006', - flock: 'Flock C-02', - totalCostPullet: 205750000, - totalDepresiasi: 43100000, - periode: 'Periode 3', - farm: 'Farm Karawang', - jumlahKandang: 5, - }, - { - id: 'DEP-007', - flock: 'Flock D-01', - totalCostPullet: 188300000, - totalDepresiasi: 39000000, - periode: 'Periode 4', - farm: 'Farm Subang', - jumlahKandang: 4, - }, - { - id: 'DEP-008', - flock: 'Flock D-02', - totalCostPullet: 197600000, - totalDepresiasi: 40875000, - periode: 'Periode 4', - farm: 'Farm Subang', - jumlahKandang: 5, - }, -]; - -const INITIAL_FILTERS: ReportDepreciationSearchParams = { - farm: null, - period: null, -}; - const ReportDepreciationTab = ({ tabId }: ReportDepreciationTabProps) => { - const [filterParams, setFilterParams] = - useState(INITIAL_FILTERS); - const [draftFilters, setDraftFilters] = - useState(INITIAL_FILTERS); - const [page, setPage] = useState(1); - const [pageSize, setPageSize] = useState(10); + const { + state: tableFilterState, + updateFilter, + setPage, + setPageSize, + toQueryString: getTableFilterQueryString, + reset: resetFilter, + } = useTableFilter({ + initial: { + area_id: '', + location_id: '', + project_flock_id: '', + period: formatDate(Date.now(), 'YYYY-MM-DD'), + }, + paramMap: { + pageSize: 'limit', + area_id: 'area_id', + location_id: 'location_id', + project_flock_id: 'project_flock_id', + period: 'period', + }, + }); + + const { data: depreciationsResponse, isLoading: isLoadingDepreciations } = + useSWR( + `${DepreciationReportApi.basePath}${getTableFilterQueryString()}`, + DepreciationReportApi.getAllFetcher + ); + + const depreciations = isResponseSuccess(depreciationsResponse) + ? depreciationsResponse.data + : []; - const handleFilterModalOpenRef = useRef(() => {}); const filterModal = useModal(); + const { ref: filterModalRef } = filterModal; + const setTabActions = useTabActionsStore((state) => state.setTabActions); const clearTabActions = useTabActionsStore((state) => state.clearTabActions); - const farmOptions = useMemo( - () => - Array.from(new Set(DUMMY_DEPRECIATION_DATA.map((item) => item.farm))).map( - (farm) => ({ - value: farm, - label: farm, - }) - ), - [] - ); - - const periodOptions = useMemo( - () => - Array.from( - new Set(DUMMY_DEPRECIATION_DATA.map((item) => item.periode)) - ).map((period) => ({ - value: period, - label: period, - })), - [] - ); - - const draftFarmValue = useMemo( - () => filterToOption(farmOptions, draftFilters.farm), - [draftFilters.farm, farmOptions] - ); - - const draftPeriodValue = useMemo( - () => filterToOption(periodOptions, draftFilters.period), - [draftFilters.period, periodOptions] - ); - - const filteredData = useMemo(() => { - return DUMMY_DEPRECIATION_DATA.filter((item) => { - const matchFarm = filterParams.farm - ? item.farm === filterParams.farm - : true; - const matchPeriod = filterParams.period - ? item.periode === filterParams.period - : true; - - return matchFarm && matchPeriod; - }); - }, [filterParams]); - - const totalPages = useMemo( - () => Math.max(1, Math.ceil(filteredData.length / pageSize)), - [filteredData.length, pageSize] - ); - - useEffect(() => { - if (page > totalPages) { - setPage(totalPages); - } - }, [page, totalPages]); - - const paginatedData = useMemo(() => { - const startIndex = (page - 1) * pageSize; - return filteredData.slice(startIndex, startIndex + pageSize); - }, [filteredData, page, pageSize]); - - handleFilterModalOpenRef.current = () => { - setDraftFilters(filterParams); - filterModal.openModal(); - }; - - const handleApplyFilters = (e: React.FormEvent) => { - e.preventDefault(); - setFilterParams(draftFilters); - setPage(1); - filterModal.closeModal(); - }; - - const handleResetFilters = () => { - setDraftFilters(INITIAL_FILTERS); - setFilterParams(INITIAL_FILTERS); - setPage(1); - filterModal.closeModal(); - }; - - const handleExport = useCallback((type: 'excel' | 'pdf') => { - toast.success( - `Export ${type.toUpperCase()} belum terhubung API. Saat ini tabel memakai dummy data.` - ); - }, []); + const depreciationKandangColumns: ColumnDef< + ReportDepreciation['components']['kandang'][0] + >[] = [ + { + accessorKey: 'kandang_name', + header: 'Kandang', + }, + { + accessorKey: 'house_type', + header: 'Tipe Kandang', + cell: ({ row }) => row.original.house_type.toUpperCase(), + }, + { + accessorKey: 'depreciation_percent', + header: 'Persentase Depresiasi', + cell: ({ row }) => row.original.depreciation_percent + '%', + }, + { + accessorKey: 'depreciation_value', + header: 'Nilai Depresiasi', + cell: ({ row }) => formatCurrency(row.original.depreciation_value), + }, + { + accessorKey: 'depreciation_source', + header: 'Asal Depresiasi', + cell: ({ row }) => row.original.depreciation_source.toUpperCase(), + }, + { + accessorKey: 'cutover_date', + header: 'Tanggal Cutover', + cell: ({ row }) => formatDate(row.original.cutover_date, 'DD MMM YYYY'), + }, + { + accessorKey: 'origin_date', + header: 'Tanggal Origin', + cell: ({ row }) => formatDate(row.original.origin_date, 'DD MMM YYYY'), + }, + ]; const tabActionsElement = useMemo( () => (
handleFilterModalOpenRef.current()} + values={tableFilterState} + excludeFields={['page', 'pageSize']} + onClick={() => filterModal.openModal()} variant='outline' className='px-3 py-2.5' /> - - -
- - Export -
- -
- - } - > - - -
), - [filterParams, handleExport] + [tableFilterState] ); useEffect(() => { @@ -278,44 +128,18 @@ const ReportDepreciationTab = ({ tabId }: ReportDepreciationTabProps) => { }; }, [clearTabActions, tabId]); - const columns = useMemo((): ColumnDef[] => { - return [ - { - header: 'Flock', - accessorKey: 'flock', - }, - { - header: 'Total Cost Pullet', - accessorKey: 'totalCostPullet', - cell: ({ row }) => formatCurrency(row.original.totalCostPullet), - }, - { - header: 'Total Depresiasi', - accessorKey: 'totalDepresiasi', - cell: ({ row }) => formatCurrency(row.original.totalDepresiasi), - }, - { - header: 'Periode', - accessorKey: 'periode', - }, - { - header: 'Farm', - accessorKey: 'farm', - }, - { - header: 'Jumlah Kandang', - accessorKey: 'jumlahKandang', - cell: ({ row }) => row.original.jumlahKandang.toLocaleString('id-ID'), - }, - ]; - }, []); - return ( <>
- {filteredData.length === 0 && ( + {isLoadingDepreciations && ( +
+ +
+ )} + + {!isLoadingDepreciations && depreciations.length === 0 && ( { /> )} - {filteredData.length > 0 && ( + {!isLoadingDepreciations && depreciations.length > 0 && ( <> - - -
- - setPage((currentPage) => - currentPage > 1 ? currentPage - 1 : currentPage - ) - } - onNextPage={() => - setPage((currentPage) => - currentPage < totalPages ? currentPage + 1 : currentPage - ) - } - onPageChange={setPage} - rowOptions={[10, 20, 50, 100]} - onRowChange={(value) => { - setPageSize(value); - setPage(1); + {depreciations.map((depreciationItem, idx) => ( + -
+ variant='bordered' + collapsible={true} + > +
+ + ))} + + setPage(tableFilterState.page - 1)} + onNextPage={() => setPage(tableFilterState.page + 1)} + onPageChange={setPage} + rowOptions={[10, 20, 50, 100]} + onRowChange={setPageSize} + /> )} - { + updateFilter('area_id', values.area_id ?? ''); + updateFilter('location_id', values.location_id ?? ''); + updateFilter('project_flock_id', values.project_flock_id ?? ''); + updateFilter( + 'period', + values.period ? formatDate(values.period, 'YYYY-MM-DD') : '' + ); + + console.log({ values }); }} - > -
-
- -

Filter Data

-
- -
- -
-
- - setDraftFilters((current) => ({ - ...current, - farm: (val as OptionType | null)?.value?.toString() || null, - })) - } - isClearable - className={{ wrapper: 'w-full' }} - /> - - - setDraftFilters((current) => ({ - ...current, - period: (val as OptionType | null)?.value?.toString() || null, - })) - } - isClearable - className={{ wrapper: 'w-full' }} - /> -
- -
- - -
- -
+ /> ); }; -const filterToOption = ( - options: OptionType[], - value: string | null -): OptionType | null => { - if (!value) return null; - return options.find((option) => option.value === value) || null; -}; - export default ReportDepreciationTab;