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';
import React, { useCallback, useState, useMemo, useEffect } from 'react';
import React, {
useCallback,
useState,
useMemo,
useEffect,
useRef,
} from 'react';
import { RefObject } from 'react';
import useSWR from 'swr';
import { Icon } from '@iconify/react';
@@ -28,6 +34,7 @@ import { useTableFilter } from '@/services/hooks/useTableFilter';
import toast from 'react-hot-toast';
import Badge from '@/components/Badge';
import CheckboxInput from '@/components/input/CheckboxInput';
import { useTableStore } from '@/stores/table/table.store';
import { BaseApproval, BaseApiResponse } from '@/types/api/api-general';
const RowOptionsMenu = ({
@@ -344,6 +351,9 @@ const ApprovalHistoryModal = ({
};
const RecordingTable = () => {
const { searchValue, setSearchValue, resetSearchValue } = useTableStore();
const previousPathRef = useRef<string | null>(null);
const {
state: tableFilterState,
updateFilter,
@@ -352,7 +362,7 @@ const RecordingTable = () => {
toQueryString: getTableFilterQueryString,
} = useTableFilter({
initial: {
search: '',
search: searchValue,
areaFilter: '',
locationFilter: '',
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(
(e: React.ChangeEvent<HTMLInputElement>) => {
updateFilter('search', e.target.value);
setSearchValue(e.target.value);
setPage(1);
},
[updateFilter, setPage]
[updateFilter, setSearchValue, setPage]
);
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',
}
)
);