File size: 1,337 Bytes
9dfccd9
 
 
 
 
 
 
 
 
 
9bb34f8
 
 
 
 
 
 
9dfccd9
 
 
 
 
 
 
9bb34f8
 
 
 
9dfccd9
 
 
 
 
 
 
9bb34f8
 
 
9dfccd9
 
 
 
 
 
 
 
9bb34f8
9dfccd9
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
import { create } from 'zustand'
import { persist } from 'zustand/middleware'

export interface Toast {
  id:      string
  message: string
  type:    'info' | 'success' | 'warning' | 'error'
}

interface UIState {
  theme:          'light' | 'dark'
  sidebarOpen:    boolean
  graphCollapsed: boolean
  toasts:         Toast[]
  toggleTheme:         () => void
  toggleSidebar:       () => void
  toggleGraphCollapsed: () => void
  addToast:    (toast: Omit<Toast, 'id'>) => void
  removeToast: (id: string) => void
}

export const useUIStore = create<UIState>()(
  persist(
    (set) => ({
      theme:          'light',
      sidebarOpen:    true,
      graphCollapsed: false,
      toasts:         [],

      toggleTheme: () =>
        set((s) => ({ theme: s.theme === 'light' ? 'dark' : 'light' })),

      toggleSidebar: () =>
        set((s) => ({ sidebarOpen: !s.sidebarOpen })),

      toggleGraphCollapsed: () =>
        set((s) => ({ graphCollapsed: !s.graphCollapsed })),

      addToast: (toast) =>
        set((s) => ({
          toasts: [...s.toasts, { ...toast, id: crypto.randomUUID() }],
        })),

      removeToast: (id) =>
        set((s) => ({ toasts: s.toasts.filter((t) => t.id !== id) })),
    }),
    { name: 'godspeed-ui', partialize: (s) => ({ theme: s.theme, graphCollapsed: s.graphCollapsed }) },
  ),
)