interacmanagernew / packages /web /src /stores /transactionStore.ts
MichaelEdou
feat: add Excel export, filters, search, match accuracy, journal page, and email viewer improvements
e85d815
import { create } from 'zustand';
interface TransactionFilters {
page: number;
limit: number;
search: string;
branch: string;
status: string;
reviewed: string;
from: string;
to: string;
sortBy: string;
sortOrder: 'asc' | 'desc';
}
interface TransactionState {
filters: TransactionFilters;
selectedIds: Set<string>;
setFilter: <K extends keyof TransactionFilters>(key: K, value: TransactionFilters[K]) => void;
setFilters: (filters: Partial<TransactionFilters>) => void;
resetFilters: () => void;
toggleSelected: (id: string) => void;
selectAll: (ids: string[]) => void;
clearSelection: () => void;
}
const defaultFilters: TransactionFilters = {
page: 1,
limit: 500,
search: '',
branch: '',
status: '',
reviewed: '',
from: '',
to: '',
sortBy: 'date',
sortOrder: 'desc',
};
export const useTransactionStore = create<TransactionState>((set) => ({
filters: { ...defaultFilters },
selectedIds: new Set(),
setFilter: (key, value) =>
set((state) => ({
filters: { ...state.filters, [key]: value, ...(key !== 'page' ? { page: 1 } : {}) },
})),
setFilters: (partial) =>
set((state) => ({
filters: { ...state.filters, ...partial, ...('page' in partial ? {} : { page: 1 }) },
})),
resetFilters: () => set({ filters: { ...defaultFilters }, selectedIds: new Set() }),
toggleSelected: (id) =>
set((state) => {
const next = new Set(state.selectedIds);
if (next.has(id)) next.delete(id);
else next.add(id);
return { selectedIds: next };
}),
selectAll: (ids) => set({ selectedIds: new Set(ids) }),
clearSelection: () => set({ selectedIds: new Set() }),
}));