176 lines
4.1 KiB
TypeScript
176 lines
4.1 KiB
TypeScript
import { create } from "zustand";
|
|
import { persist, createJSONStorage } from "zustand/middleware";
|
|
import { User } from "../services/types";
|
|
|
|
interface LoadingState {
|
|
users: boolean;
|
|
products: boolean;
|
|
orders: boolean;
|
|
notifications: boolean;
|
|
dashboard: boolean;
|
|
}
|
|
|
|
interface AppState {
|
|
sidebarOpen: boolean;
|
|
loading: LoadingState;
|
|
selectedItems: string[];
|
|
filters: {
|
|
search: string;
|
|
status: string;
|
|
dateRange: { start: string; end: string } | null;
|
|
};
|
|
currentUser: User | null;
|
|
|
|
// Actions
|
|
setSidebarOpen: (open: boolean) => void;
|
|
setLoading: (key: keyof LoadingState, value: boolean) => void;
|
|
setSelectedItems: (items: string[]) => void;
|
|
addSelectedItem: (item: string) => void;
|
|
removeSelectedItem: (item: string) => void;
|
|
clearSelectedItems: () => void;
|
|
setFilters: (filters: Partial<AppState["filters"]>) => void;
|
|
resetFilters: () => void;
|
|
setCurrentUser: (user: User | null) => void;
|
|
|
|
// Bulk actions
|
|
setGlobalLoading: (loading: boolean) => void;
|
|
}
|
|
|
|
const initialFilters = {
|
|
search: "",
|
|
status: "",
|
|
dateRange: null,
|
|
};
|
|
|
|
const initialLoading: LoadingState = {
|
|
users: false,
|
|
products: false,
|
|
orders: false,
|
|
notifications: false,
|
|
dashboard: false,
|
|
};
|
|
|
|
export const useAppStore = create<AppState>()(
|
|
persist(
|
|
(set) => ({
|
|
sidebarOpen: false,
|
|
loading: initialLoading,
|
|
selectedItems: [],
|
|
filters: initialFilters,
|
|
currentUser: null,
|
|
|
|
setSidebarOpen: (open) => set({ sidebarOpen: open }),
|
|
|
|
setLoading: (key, value) =>
|
|
set((state) => ({
|
|
loading: { ...state.loading, [key]: value },
|
|
})),
|
|
|
|
setSelectedItems: (items) => set({ selectedItems: items }),
|
|
|
|
addSelectedItem: (item) =>
|
|
set((state) => ({
|
|
selectedItems: state.selectedItems.includes(item)
|
|
? state.selectedItems
|
|
: [...state.selectedItems, item],
|
|
})),
|
|
|
|
removeSelectedItem: (item) =>
|
|
set((state) => ({
|
|
selectedItems: state.selectedItems.filter((i) => i !== item),
|
|
})),
|
|
|
|
clearSelectedItems: () => set({ selectedItems: [] }),
|
|
|
|
setFilters: (newFilters) =>
|
|
set((state) => ({
|
|
filters: { ...state.filters, ...newFilters },
|
|
})),
|
|
|
|
resetFilters: () => set({ filters: initialFilters }),
|
|
|
|
setCurrentUser: (user) => set({ currentUser: user }),
|
|
|
|
setGlobalLoading: (loading) =>
|
|
set((state) => ({
|
|
loading: Object.keys(state.loading).reduce(
|
|
(acc, key) => ({ ...acc, [key]: loading }),
|
|
{} as LoadingState
|
|
),
|
|
})),
|
|
}),
|
|
{
|
|
name: "app-storage",
|
|
storage: createJSONStorage(() => localStorage),
|
|
partialize: (state) => ({
|
|
sidebarOpen: state.sidebarOpen,
|
|
filters: state.filters,
|
|
currentUser: state.currentUser,
|
|
}),
|
|
}
|
|
)
|
|
);
|
|
|
|
export const useSidebar = () => {
|
|
const { sidebarOpen, setSidebarOpen } = useAppStore();
|
|
|
|
const toggleSidebar = () => setSidebarOpen(!sidebarOpen);
|
|
const closeSidebar = () => setSidebarOpen(false);
|
|
const openSidebar = () => setSidebarOpen(true);
|
|
|
|
return {
|
|
sidebarOpen,
|
|
toggleSidebar,
|
|
closeSidebar,
|
|
openSidebar,
|
|
};
|
|
};
|
|
|
|
export const useLoading = () => {
|
|
const { loading, setLoading, setGlobalLoading } = useAppStore();
|
|
|
|
return {
|
|
loading,
|
|
setLoading,
|
|
setGlobalLoading,
|
|
isAnyLoading: Object.values(loading).some(Boolean),
|
|
};
|
|
};
|
|
|
|
export const useSelection = () => {
|
|
const {
|
|
selectedItems,
|
|
setSelectedItems,
|
|
addSelectedItem,
|
|
removeSelectedItem,
|
|
clearSelectedItems,
|
|
} = useAppStore();
|
|
|
|
const isSelected = (item: string) => selectedItems.includes(item);
|
|
const hasSelection = selectedItems.length > 0;
|
|
|
|
return {
|
|
selectedItems,
|
|
setSelectedItems,
|
|
addSelectedItem,
|
|
removeSelectedItem,
|
|
clearSelectedItems,
|
|
isSelected,
|
|
hasSelection,
|
|
};
|
|
};
|
|
|
|
export const useFilters = () => {
|
|
const { filters, setFilters, resetFilters } = useAppStore();
|
|
|
|
return {
|
|
filters,
|
|
setFilters,
|
|
resetFilters,
|
|
hasActiveFilters:
|
|
filters.search !== "" ||
|
|
filters.status !== "" ||
|
|
filters.dateRange !== null,
|
|
};
|
|
};
|