refactor(FE): Integrate UI store and pathname sync in master-data tables

This commit is contained in:
rstubryan
2026-03-03 10:59:26 +07:00
parent 3d2e40518b
commit 4e278c5687
13 changed files with 195 additions and 45 deletions
@@ -1,6 +1,6 @@
'use client';
import { ChangeEventHandler, useMemo, useState } from 'react';
import { ChangeEventHandler, useEffect, useMemo, useState } from 'react';
import useSWR from 'swr';
import { CellContext, ColumnDef, SortingState } from '@tanstack/react-table';
import toast from 'react-hot-toast';
@@ -20,6 +20,8 @@ import { Area } from '@/types/api/master-data/area';
import { AreaApi } from '@/services/api/master-data';
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
import { useTableFilter } from '@/services/hooks/useTableFilter';
import { usePathname } from 'next/navigation';
import { useUiStore } from '@/stores/ui/ui.store';
const RowOptionsMenu = ({
popoverPosition = 'bottom',
@@ -101,6 +103,9 @@ const RowOptionsMenu = ({
};
const AreasTable = () => {
const { searchValue, setSearchValue, setTableState } = useUiStore();
const pathname = usePathname();
const {
state: tableFilterState,
updateFilter,
@@ -109,7 +114,7 @@ const AreasTable = () => {
toQueryString: getTableFilterQueryString,
} = useTableFilter({
initial: {
search: '',
search: searchValue,
},
paramMap: {
page: 'page',
@@ -132,7 +137,16 @@ const AreasTable = () => {
const [selectedArea, setSelectedArea] = useState<Area | undefined>(undefined);
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
useEffect(() => {
updateFilter('search', searchValue);
}, [searchValue, updateFilter]);
useEffect(() => {
setTableState('areas-table', pathname);
}, [pathname]);
const searchChangeHandler: ChangeEventHandler<HTMLInputElement> = (e) => {
setSearchValue(e.target.value);
updateFilter('search', e.target.value);
};
@@ -1,6 +1,6 @@
'use client';
import { ChangeEventHandler, useMemo, useState } from 'react';
import { ChangeEventHandler, useEffect, useMemo, useState } from 'react';
import useSWR from 'swr';
import { CellContext, ColumnDef, SortingState } from '@tanstack/react-table';
import toast from 'react-hot-toast';
@@ -20,6 +20,8 @@ import { Bank } from '@/types/api/master-data/bank';
import { BankApi } from '@/services/api/master-data';
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
import { useTableFilter } from '@/services/hooks/useTableFilter';
import { usePathname } from 'next/navigation';
import { useUiStore } from '@/stores/ui/ui.store';
const RowOptionsMenu = ({
popoverPosition = 'bottom',
@@ -101,6 +103,9 @@ const RowOptionsMenu = ({
};
const BanksTable = () => {
const { searchValue, setSearchValue, setTableState } = useUiStore();
const pathname = usePathname();
const {
state: tableFilterState,
updateFilter,
@@ -109,7 +114,7 @@ const BanksTable = () => {
toQueryString: getTableFilterQueryString,
} = useTableFilter({
initial: {
search: '',
search: searchValue,
},
paramMap: {
page: 'page',
@@ -132,7 +137,16 @@ const BanksTable = () => {
const [selectedBank, setSelectedBank] = useState<Bank | undefined>(undefined);
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
useEffect(() => {
updateFilter('search', searchValue);
}, [searchValue, updateFilter]);
useEffect(() => {
setTableState('banks-table', pathname);
}, [pathname]);
const searchChangeHandler: ChangeEventHandler<HTMLInputElement> = (e) => {
setSearchValue(e.target.value);
updateFilter('search', e.target.value);
};
@@ -1,6 +1,6 @@
'use client';
import { ChangeEventHandler, useMemo, useState } from 'react';
import { ChangeEventHandler, useEffect, useMemo, useState } from 'react';
import useSWR from 'swr';
import { CellContext, ColumnDef, SortingState } from '@tanstack/react-table';
import toast from 'react-hot-toast';
@@ -20,6 +20,8 @@ import { Customer } from '@/types/api/master-data/customer';
import { CustomerApi } from '@/services/api/master-data';
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
import { useTableFilter } from '@/services/hooks/useTableFilter';
import { usePathname } from 'next/navigation';
import { useUiStore } from '@/stores/ui/ui.store';
const RowOptionsMenu = ({
popoverPosition = 'bottom',
@@ -101,6 +103,9 @@ const RowOptionsMenu = ({
};
const CustomersTable = () => {
const { searchValue, setSearchValue, setTableState } = useUiStore();
const pathname = usePathname();
const {
state: tableFilterState,
updateFilter,
@@ -109,7 +114,7 @@ const CustomersTable = () => {
toQueryString: getTableFilterQueryString,
} = useTableFilter({
initial: {
search: '',
search: searchValue,
},
paramMap: {
page: 'page',
@@ -134,7 +139,16 @@ const CustomersTable = () => {
>(undefined);
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
useEffect(() => {
updateFilter('search', searchValue);
}, [searchValue, updateFilter]);
useEffect(() => {
setTableState('customers-table', pathname);
}, [pathname]);
const searchChangeHandler: ChangeEventHandler<HTMLInputElement> = (e) => {
setSearchValue(e.target.value);
updateFilter('search', e.target.value);
};
@@ -1,6 +1,6 @@
'use client';
import { ChangeEventHandler, useMemo, useState } from 'react';
import { ChangeEventHandler, useEffect, useMemo, useState } from 'react';
import useSWR from 'swr';
import { CellContext, ColumnDef, SortingState } from '@tanstack/react-table';
import toast from 'react-hot-toast';
@@ -20,6 +20,8 @@ import { Flock } from '@/types/api/master-data/flock';
import { FlockApi } from '@/services/api/master-data';
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
import { useTableFilter } from '@/services/hooks/useTableFilter';
import { usePathname } from 'next/navigation';
import { useUiStore } from '@/stores/ui/ui.store';
const RowOptionsMenu = ({
popoverPosition = 'bottom',
@@ -101,6 +103,9 @@ const RowOptionsMenu = ({
};
const FlockTable = () => {
const { searchValue, setSearchValue, setTableState } = useUiStore();
const pathname = usePathname();
const {
state: tableFilterState,
updateFilter,
@@ -109,7 +114,7 @@ const FlockTable = () => {
toQueryString: getTableFilterQueryString,
} = useTableFilter({
initial: {
search: '',
search: searchValue,
},
paramMap: {
page: 'page',
@@ -134,7 +139,16 @@ const FlockTable = () => {
);
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
useEffect(() => {
updateFilter('search', searchValue);
}, [searchValue, updateFilter]);
useEffect(() => {
setTableState('flocks-table', pathname);
}, [pathname]);
const searchChangeHandler: ChangeEventHandler<HTMLInputElement> = (e) => {
setSearchValue(e.target.value);
updateFilter('search', e.target.value);
};
@@ -1,6 +1,6 @@
'use client';
import { ChangeEventHandler, useMemo, useState } from 'react';
import { ChangeEventHandler, useEffect, useMemo, useState } from 'react';
import useSWR from 'swr';
import { CellContext, ColumnDef, SortingState } from '@tanstack/react-table';
import toast from 'react-hot-toast';
@@ -21,6 +21,8 @@ import { KandangApi } from '@/services/api/master-data';
import { formatNumber } from '@/lib/helper';
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
import { useTableFilter } from '@/services/hooks/useTableFilter';
import { usePathname } from 'next/navigation';
import { useUiStore } from '@/stores/ui/ui.store';
const RowOptionsMenu = ({
popoverPosition = 'bottom',
@@ -102,6 +104,9 @@ const RowOptionsMenu = ({
};
const KandangsTable = () => {
const { searchValue, setSearchValue, setTableState } = useUiStore();
const pathname = usePathname();
const {
state: tableFilterState,
updateFilter,
@@ -110,7 +115,7 @@ const KandangsTable = () => {
toQueryString: getTableFilterQueryString,
} = useTableFilter({
initial: {
search: '',
search: searchValue,
},
paramMap: {
page: 'page',
@@ -135,7 +140,16 @@ const KandangsTable = () => {
);
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
useEffect(() => {
updateFilter('search', searchValue);
}, [searchValue, updateFilter]);
useEffect(() => {
setTableState('kandangs-table', pathname);
}, [pathname]);
const searchChangeHandler: ChangeEventHandler<HTMLInputElement> = (e) => {
setSearchValue(e.target.value);
updateFilter('search', e.target.value);
};
@@ -1,6 +1,6 @@
'use client';
import { ChangeEventHandler, useMemo, useState } from 'react';
import { ChangeEventHandler, useEffect, useMemo, useState } from 'react';
import useSWR from 'swr';
import { CellContext, ColumnDef, SortingState } from '@tanstack/react-table';
import toast from 'react-hot-toast';
@@ -20,6 +20,8 @@ import { Location } from '@/types/api/master-data/location';
import { LocationApi } from '@/services/api/master-data';
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
import { useTableFilter } from '@/services/hooks/useTableFilter';
import { usePathname } from 'next/navigation';
import { useUiStore } from '@/stores/ui/ui.store';
const RowOptionsMenu = ({
popoverPosition = 'bottom',
@@ -101,6 +103,9 @@ const RowOptionsMenu = ({
};
const LocationsTable = () => {
const { searchValue, setSearchValue, setTableState } = useUiStore();
const pathname = usePathname();
const {
state: tableFilterState,
updateFilter,
@@ -109,7 +114,7 @@ const LocationsTable = () => {
toQueryString: getTableFilterQueryString,
} = useTableFilter({
initial: {
search: '',
search: searchValue,
},
paramMap: {
page: 'page',
@@ -134,7 +139,16 @@ const LocationsTable = () => {
>(undefined);
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
useEffect(() => {
updateFilter('search', searchValue);
}, [searchValue, updateFilter]);
useEffect(() => {
setTableState('locations-table', pathname);
}, [pathname]);
const searchChangeHandler: ChangeEventHandler<HTMLInputElement> = (e) => {
setSearchValue(e.target.value);
updateFilter('search', e.target.value);
};
@@ -1,6 +1,6 @@
'use client';
import { ChangeEventHandler, useMemo, useState } from 'react';
import { ChangeEventHandler, useEffect, useMemo, useState } from 'react';
import useSWR from 'swr';
import { CellContext, ColumnDef, SortingState } from '@tanstack/react-table';
import toast from 'react-hot-toast';
@@ -20,6 +20,8 @@ import { Nonstock } from '@/types/api/master-data/nonstock';
import { NonstockApi } from '@/services/api/master-data';
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
import { useTableFilter } from '@/services/hooks/useTableFilter';
import { usePathname } from 'next/navigation';
import { useUiStore } from '@/stores/ui/ui.store';
const RowOptionsMenu = ({
popoverPosition = 'bottom',
@@ -101,6 +103,9 @@ const RowOptionsMenu = ({
};
const NonstocksTable = () => {
const { searchValue, setSearchValue, setTableState } = useUiStore();
const pathname = usePathname();
const {
state: tableFilterState,
updateFilter,
@@ -109,7 +114,7 @@ const NonstocksTable = () => {
toQueryString: getTableFilterQueryString,
} = useTableFilter({
initial: {
search: '',
search: searchValue,
},
paramMap: {
page: 'page',
@@ -117,6 +122,14 @@ const NonstocksTable = () => {
},
});
useEffect(() => {
updateFilter('search', searchValue);
}, [searchValue, updateFilter]);
useEffect(() => {
setTableState('nonstocks-table', pathname);
}, [pathname]);
const [sorting, setSorting] = useState<SortingState>([]);
const {
@@ -135,6 +148,7 @@ const NonstocksTable = () => {
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
const searchChangeHandler: ChangeEventHandler<HTMLInputElement> = (e) => {
setSearchValue(e.target.value);
updateFilter('search', e.target.value);
};
@@ -7,6 +7,7 @@ import {
useRef,
useState,
} from 'react';
import { usePathname } from 'next/navigation';
import useSWR from 'swr';
import { CellContext, ColumnDef, SortingState } from '@tanstack/react-table';
import toast from 'react-hot-toast';
@@ -108,8 +109,8 @@ const RowOptionsMenu = ({
};
const ProductCategoryTable = () => {
const { searchValue, setSearchValue, resetSearchValue } = useUiStore();
const previousPathRef = useRef<string | null>(null);
const { searchValue, setSearchValue, setTableState } = useUiStore();
const pathname = usePathname();
const {
state: tableFilterState,
@@ -119,7 +120,7 @@ const ProductCategoryTable = () => {
toQueryString: getTableFilterQueryString,
} = useTableFilter({
initial: {
search: searchValue,
search: '',
},
paramMap: {
page: 'page',
@@ -127,6 +128,10 @@ const ProductCategoryTable = () => {
},
});
useEffect(() => {
updateFilter('search', searchValue);
}, [searchValue, updateFilter]);
const [sorting, setSorting] = useState<SortingState>([]);
const {
@@ -216,26 +221,8 @@ const ProductCategoryTable = () => {
);
useEffect(() => {
// Store current path on mount
previousPathRef.current = window.location.pathname;
return () => {
const currentPath = window.location.pathname;
// if both paths are within /master-data/product-category module
const isCurrentPathProductCategory = currentPath.includes(
'/master-data/product-category'
);
const isPreviousPathProductCategory = previousPathRef.current?.includes(
'/master-data/product-category'
);
// reset if we outside product category module entirely
if (isPreviousPathProductCategory && !isCurrentPathProductCategory) {
resetSearchValue();
}
};
}, [resetSearchValue]);
setTableState('product-category-table', pathname);
}, [pathname]);
return (
<>
@@ -1,6 +1,7 @@
'use client';
import { ChangeEventHandler, useMemo, useState } from 'react';
import { ChangeEventHandler, useEffect, useMemo, useState } from 'react';
import { usePathname } from 'next/navigation';
import useSWR from 'swr';
import { CellContext, ColumnDef, SortingState } from '@tanstack/react-table';
import toast from 'react-hot-toast';
@@ -21,6 +22,7 @@ import { ProductApi } from '@/services/api/master-data';
import { formatCurrency } from '@/lib/helper';
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
import { useTableFilter } from '@/services/hooks/useTableFilter';
import { useUiStore } from '@/stores/ui/ui.store';
const RowOptionsMenu = ({
popoverPosition = 'bottom',
@@ -102,6 +104,9 @@ const RowOptionsMenu = ({
};
const ProductsTable = () => {
const { searchValue, setSearchValue, setTableState } = useUiStore();
const pathname = usePathname();
const {
state: tableFilterState,
updateFilter,
@@ -118,6 +123,10 @@ const ProductsTable = () => {
},
});
useEffect(() => {
updateFilter('search', searchValue);
}, [searchValue, updateFilter]);
const [sorting, setSorting] = useState<SortingState>([]);
const {
@@ -135,7 +144,12 @@ const ProductsTable = () => {
);
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
useEffect(() => {
setTableState('product-table', pathname);
}, [pathname]);
const searchChangeHandler: ChangeEventHandler<HTMLInputElement> = (e) => {
setSearchValue(e.target.value);
updateFilter('search', e.target.value);
};
@@ -1,6 +1,6 @@
'use client';
import { useMemo, useState } from 'react';
import { useEffect, useMemo, useState } from 'react';
import useSWR from 'swr';
import { CellContext, ColumnDef, SortingState } from '@tanstack/react-table';
import toast from 'react-hot-toast';
@@ -18,6 +18,8 @@ import ProductionStandardTableSkeleton from '@/components/pages/master-data/prod
import { ProductionStandard } from '@/types/api/master-data/production-standard';
import { ProductionStandardApi } from '@/services/api/master-data';
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
import { usePathname } from 'next/navigation';
import { useUiStore } from '@/stores/ui/ui.store';
const RowOptionsMenu = ({
popoverPosition = 'bottom',
@@ -99,6 +101,13 @@ const RowOptionsMenu = ({
};
const ProductionStandardTable = () => {
const { setTableState } = useUiStore();
const pathname = usePathname();
useEffect(() => {
setTableState('production-standard-table', pathname);
}, [pathname]);
const [sorting, setSorting] = useState<SortingState>([]);
const {
@@ -1,6 +1,6 @@
'use client';
import { ChangeEventHandler, useMemo, useState } from 'react';
import { ChangeEventHandler, useEffect, useMemo, useState } from 'react';
import useSWR from 'swr';
import { CellContext, ColumnDef, SortingState } from '@tanstack/react-table';
import toast from 'react-hot-toast';
@@ -20,6 +20,8 @@ import { Supplier } from '@/types/api/master-data/supplier';
import { SupplierApi } from '@/services/api/master-data';
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
import { useTableFilter } from '@/services/hooks/useTableFilter';
import { usePathname } from 'next/navigation';
import { useUiStore } from '@/stores/ui/ui.store';
const RowOptionsMenu = ({
popoverPosition = 'bottom',
@@ -101,6 +103,9 @@ const RowOptionsMenu = ({
};
const SuppliersTable = () => {
const { searchValue, setSearchValue, setTableState } = useUiStore();
const pathname = usePathname();
const {
state: tableFilterState,
updateFilter,
@@ -109,7 +114,7 @@ const SuppliersTable = () => {
toQueryString: getTableFilterQueryString,
} = useTableFilter({
initial: {
search: '',
search: searchValue,
},
paramMap: {
page: 'page',
@@ -117,6 +122,14 @@ const SuppliersTable = () => {
},
});
useEffect(() => {
updateFilter('search', searchValue);
}, [searchValue, updateFilter]);
useEffect(() => {
setTableState('suppliers-table', pathname);
}, [pathname]);
const [sorting, setSorting] = useState<SortingState>([]);
const {
@@ -135,6 +148,7 @@ const SuppliersTable = () => {
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
const searchChangeHandler: ChangeEventHandler<HTMLInputElement> = (e) => {
setSearchValue(e.target.value);
updateFilter('search', e.target.value);
};
@@ -1,6 +1,6 @@
'use client';
import { ChangeEventHandler, useMemo, useState } from 'react';
import { ChangeEventHandler, useEffect, useMemo, useState } from 'react';
import useSWR from 'swr';
import { CellContext, ColumnDef, SortingState } from '@tanstack/react-table';
import toast from 'react-hot-toast';
@@ -20,6 +20,8 @@ import { Uom } from '@/types/api/master-data/uom';
import { UomApi } from '@/services/api/master-data';
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
import { useTableFilter } from '@/services/hooks/useTableFilter';
import { usePathname } from 'next/navigation';
import { useUiStore } from '@/stores/ui/ui.store';
const RowOptionsMenu = ({
popoverPosition = 'bottom',
@@ -101,6 +103,9 @@ const RowOptionsMenu = ({
};
const UomsTable = () => {
const { searchValue, setSearchValue, setTableState } = useUiStore();
const pathname = usePathname();
const {
state: tableFilterState,
updateFilter,
@@ -109,7 +114,7 @@ const UomsTable = () => {
toQueryString: getTableFilterQueryString,
} = useTableFilter({
initial: {
search: '',
search: searchValue,
},
paramMap: {
page: 'page',
@@ -117,6 +122,14 @@ const UomsTable = () => {
},
});
useEffect(() => {
updateFilter('search', searchValue);
}, [searchValue, updateFilter]);
useEffect(() => {
setTableState('uoms-table', pathname);
}, [pathname]);
const [sorting, setSorting] = useState<SortingState>([]);
const {
@@ -133,6 +146,7 @@ const UomsTable = () => {
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
const searchChangeHandler: ChangeEventHandler<HTMLInputElement> = (e) => {
setSearchValue(e.target.value);
updateFilter('search', e.target.value);
};
@@ -1,6 +1,6 @@
'use client';
import { ChangeEventHandler, useMemo, useState } from 'react';
import { ChangeEventHandler, useEffect, useMemo, useState } from 'react';
import useSWR from 'swr';
import { CellContext, ColumnDef, SortingState } from '@tanstack/react-table';
import toast from 'react-hot-toast';
@@ -20,6 +20,8 @@ import { Warehouse } from '@/types/api/master-data/warehouse';
import { WarehouseApi } from '@/services/api/master-data';
import { isResponseError, isResponseSuccess } from '@/lib/api-helper';
import { useTableFilter } from '@/services/hooks/useTableFilter';
import { usePathname } from 'next/navigation';
import { useUiStore } from '@/stores/ui/ui.store';
const RowOptionsMenu = ({
popoverPosition = 'bottom',
@@ -101,6 +103,9 @@ const RowOptionsMenu = ({
};
const WarehousesTable = () => {
const { searchValue, setSearchValue, setTableState } = useUiStore();
const pathname = usePathname();
const {
state: tableFilterState,
updateFilter,
@@ -109,7 +114,7 @@ const WarehousesTable = () => {
toQueryString: getTableFilterQueryString,
} = useTableFilter({
initial: {
search: '',
search: searchValue,
},
paramMap: {
page: 'page',
@@ -117,6 +122,14 @@ const WarehousesTable = () => {
},
});
useEffect(() => {
updateFilter('search', searchValue);
}, [searchValue, updateFilter]);
useEffect(() => {
setTableState('warehouses-table', pathname);
}, [pathname]);
const [sorting, setSorting] = useState<SortingState>([]);
const {
@@ -135,6 +148,7 @@ const WarehousesTable = () => {
const [isDeleteLoading, setIsDeleteLoading] = useState(false);
const searchChangeHandler: ChangeEventHandler<HTMLInputElement> = (e) => {
setSearchValue(e.target.value);
updateFilter('search', e.target.value);
};