feat(FE): Persist Recording search across navigation

This commit is contained in:
rstubryan
2026-01-22 15:24:04 +07:00
parent 8e48c4d7cf
commit 756701722a
3 changed files with 88 additions and 3 deletions
@@ -1,6 +1,12 @@
'use client'; 'use client';
import React, { useCallback, useState, useMemo, useEffect } from 'react'; import React, {
useCallback,
useState,
useMemo,
useEffect,
useRef,
} from 'react';
import { RefObject } from 'react'; import { RefObject } from 'react';
import useSWR from 'swr'; import useSWR from 'swr';
import { Icon } from '@iconify/react'; import { Icon } from '@iconify/react';
@@ -28,6 +34,7 @@ import { useTableFilter } from '@/services/hooks/useTableFilter';
import toast from 'react-hot-toast'; import toast from 'react-hot-toast';
import Badge from '@/components/Badge'; import Badge from '@/components/Badge';
import CheckboxInput from '@/components/input/CheckboxInput'; import CheckboxInput from '@/components/input/CheckboxInput';
import { useTableStore } from '@/stores/table/table.store';
import { BaseApproval, BaseApiResponse } from '@/types/api/api-general'; import { BaseApproval, BaseApiResponse } from '@/types/api/api-general';
const RowOptionsMenu = ({ const RowOptionsMenu = ({
@@ -344,6 +351,9 @@ const ApprovalHistoryModal = ({
}; };
const RecordingTable = () => { const RecordingTable = () => {
const { searchValue, setSearchValue, resetSearchValue } = useTableStore();
const previousPathRef = useRef<string | null>(null);
const { const {
state: tableFilterState, state: tableFilterState,
updateFilter, updateFilter,
@@ -352,7 +362,7 @@ const RecordingTable = () => {
toQueryString: getTableFilterQueryString, toQueryString: getTableFilterQueryString,
} = useTableFilter({ } = useTableFilter({
initial: { initial: {
search: '', search: searchValue,
areaFilter: '', areaFilter: '',
locationFilter: '', locationFilter: '',
kandangFilter: '', kandangFilter: '',
@@ -403,12 +413,35 @@ const RecordingTable = () => {
); );
}, []); }, []);
useEffect(() => {
// Store current path on mount
previousPathRef.current = window.location.pathname;
return () => {
const currentPath = window.location.pathname;
// if both paths are within /production/recording module
const isCurrentPathRecording = currentPath.includes(
'/production/recording'
);
const isPreviousPathRecording = previousPathRef.current?.includes(
'/production/recording'
);
// reset if we outside recording module entirely
if (isPreviousPathRecording && !isCurrentPathRecording) {
resetSearchValue();
}
};
}, [resetSearchValue]);
const searchChangeHandler = useCallback( const searchChangeHandler = useCallback(
(e: React.ChangeEvent<HTMLInputElement>) => { (e: React.ChangeEvent<HTMLInputElement>) => {
updateFilter('search', e.target.value); updateFilter('search', e.target.value);
setSearchValue(e.target.value);
setPage(1); setPage(1);
}, },
[updateFilter, setPage] [updateFilter, setSearchValue, setPage]
); );
const pageSizeChangeHandler = useCallback( const pageSizeChangeHandler = useCallback(
+25
View File
@@ -0,0 +1,25 @@
import { StateCreator } from 'zustand';
export interface TableState {
searchValue: string;
}
export interface TableSlice {
searchValue: string;
setSearchValue: (value: string) => void;
resetSearchValue: () => void;
}
export const createTableSlice: StateCreator<TableSlice, [], [], TableSlice> = (
set
) => ({
// Initial state
searchValue: '',
// Actions
setSearchValue: (value) => set({ searchValue: value }),
resetSearchValue: () => {
return set({ searchValue: '' });
},
});
+27
View File
@@ -0,0 +1,27 @@
'use client';
import { create } from 'zustand';
import { devtools, persist } from 'zustand/middleware';
import { createTableSlice } from '@/stores/table/slices/table.slice';
import type { TableSlice } from '@/stores/table/slices/table.slice';
export type TableStore = TableSlice;
export const useTableStore = create<TableStore>()(
devtools(
persist(
(...args) => ({
...createTableSlice(...args),
}),
{
name: 'table-cache',
partialize: (state) => ({
searchValue: state.searchValue,
}),
}
),
{
name: 'TableStore',
}
)
);