ifixkart-admin/store/uiStore.ts

135 lines
3.5 KiB
TypeScript

import { create } from 'zustand';
export interface NotificationItem {
id: string;
title: string;
message: string;
type: 'info' | 'success' | 'warning' | 'error';
read: boolean;
createdAt: Date;
}
export interface OfflineAction {
id: string;
url: string;
method: 'POST' | 'PUT' | 'DELETE';
payload: any;
timestamp: number;
}
interface UIState {
// Sidebar State
sidebarCollapsed: boolean;
toggleSidebar: () => void;
setSidebarCollapsed: (collapsed: boolean) => void;
// Command Palette State
commandPaletteOpen: boolean;
setCommandPaletteOpen: (open: boolean) => void;
// Notifications State
notifications: NotificationItem[];
unreadCount: number;
addNotification: (notification: Omit<NotificationItem, 'id' | 'read' | 'createdAt'>) => void;
markAsRead: (id: string) => void;
markAllAsRead: () => void;
clearNotifications: () => void;
// Network/Offline State
isOnline: boolean;
setIsOnline: (online: boolean) => void;
offlineQueue: OfflineAction[];
enqueueOfflineAction: (action: Omit<OfflineAction, 'id' | 'timestamp'>) => void;
clearOfflineQueue: () => void;
}
export const useUIStore = create<UIState>((set) => ({
// Sidebar defaults
sidebarCollapsed: false,
toggleSidebar: () => set((state) => ({ sidebarCollapsed: !state.sidebarCollapsed })),
setSidebarCollapsed: (collapsed) => set({ sidebarCollapsed: collapsed }),
// Command palette defaults
commandPaletteOpen: false,
setCommandPaletteOpen: (open) => set({ commandPaletteOpen: open }),
// Mock Notifications for design alignment
notifications: [
{
id: '1',
title: 'New Repair Job Assigned',
message: 'Repair ticket #REP0089 assigned to Technician John Doe',
type: 'info',
read: false,
createdAt: new Date(),
},
{
id: '2',
title: 'Low Stock Alert',
message: 'iPhone 15 Screen replacement modules are below safety levels (2 units remaining)',
type: 'warning',
read: false,
createdAt: new Date(Date.now() - 3600000),
},
{
id: '3',
title: 'Invoice Paid',
message: 'Payment received for Invoice #INV10452 ($450.00)',
type: 'success',
read: true,
createdAt: new Date(Date.now() - 7200000),
}
],
unreadCount: 2,
addNotification: (n) =>
set((state) => {
const item: NotificationItem = {
...n,
id: Math.random().toString(36).substr(2, 9),
read: false,
createdAt: new Date(),
};
const updated = [item, ...state.notifications];
return {
notifications: updated,
unreadCount: updated.filter((x) => !x.read).length,
};
}),
markAsRead: (id) =>
set((state) => {
const updated = state.notifications.map((n) =>
n.id === id ? { ...n, read: true } : n
);
return {
notifications: updated,
unreadCount: updated.filter((x) => !x.read).length,
};
}),
markAllAsRead: () =>
set((state) => ({
notifications: state.notifications.map((n) => ({ ...n, read: true })),
unreadCount: 0,
})),
clearNotifications: () => set({ notifications: [], unreadCount: 0 }),
// Network states
isOnline: true,
setIsOnline: (online) => set({ isOnline: online }),
offlineQueue: [],
enqueueOfflineAction: (action) =>
set((state) => ({
offlineQueue: [
...state.offlineQueue,
{
...action,
id: Math.random().toString(36).substr(2, 9),
timestamp: Date.now(),
},
],
})),
clearOfflineQueue: () => set({ offlineQueue: [] }),
}));