SPB Git

Repository Public

ui.ts 1.3 KB 39 lines typescript

1import { create } from 'zustand';23/** Purely local UI state. Only the sidebar width preference is persisted (localStorage, no secrets). */4interface UiState {5  sidebarCollapsed: boolean;6  paletteOpen: boolean;7  notificationsOpen: boolean;8  newMission: { open: boolean; projectId: string | null };9  set: (p: Partial<Pick<UiState, 'sidebarCollapsed' | 'paletteOpen' | 'notificationsOpen'>>) => void;10  openNewMission: (projectId?: string | null) => void;11  closeNewMission: () => void;12}13export const LAYOUT_KEY = 'aos.layout';14function loadCollapsed(): boolean {15  try {16    return typeof window !== 'undefined' && JSON.parse(localStorage.getItem(LAYOUT_KEY) ?? '{}').sidebarCollapsed === true;17  } catch {18    return false;19  }20}21export const useUi = create<UiState>((set) => ({22  sidebarCollapsed: loadCollapsed(),23  paletteOpen: false,24  notificationsOpen: false,25  newMission: { open: false, projectId: null },26  set: (p) => {27    set(p);28    if (p.sidebarCollapsed !== undefined) {29      try {30        localStorage.setItem(LAYOUT_KEY, JSON.stringify({ sidebarCollapsed: p.sidebarCollapsed }));31      } catch {32        /* storage unavailable */33      }34    }35  },36  openNewMission: (projectId = null) => set({ newMission: { open: true, projectId } }),37  closeNewMission: () => set((s) => ({ newMission: { ...s.newMission, open: false } })),38}));39
Files main
Menu

Theme