diff --git a/src/components/pages/production/recording/RecordingTable.tsx b/src/components/pages/production/recording/RecordingTable.tsx index 8d8caad1..4c83cb02 100644 --- a/src/components/pages/production/recording/RecordingTable.tsx +++ b/src/components/pages/production/recording/RecordingTable.tsx @@ -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(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) => { updateFilter('search', e.target.value); + setSearchValue(e.target.value); setPage(1); }, - [updateFilter, setPage] + [updateFilter, setSearchValue, setPage] ); const pageSizeChangeHandler = useCallback( diff --git a/src/stores/table/slices/table.slice.ts b/src/stores/table/slices/table.slice.ts new file mode 100644 index 00000000..4333e157 --- /dev/null +++ b/src/stores/table/slices/table.slice.ts @@ -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 = ( + set +) => ({ + // Initial state + searchValue: '', + + // Actions + setSearchValue: (value) => set({ searchValue: value }), + + resetSearchValue: () => { + return set({ searchValue: '' }); + }, +}); diff --git a/src/stores/table/table.store.ts b/src/stores/table/table.store.ts new file mode 100644 index 00000000..54b5d1c4 --- /dev/null +++ b/src/stores/table/table.store.ts @@ -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()( + devtools( + persist( + (...args) => ({ + ...createTableSlice(...args), + }), + { + name: 'table-cache', + partialize: (state) => ({ + searchValue: state.searchValue, + }), + } + ), + { + name: 'TableStore', + } + ) +);