fix: migrate stores/index.ts from Zustand to Signals

- Migrate stores/index.ts to use @preact/signals
- Update Counter.tsx to reference Signals (not Zustand)
- All stores now use Signals: UI, User, Template, Content
- Maintains same API for backward compatibility

 Fixes: Import "zustand" not a dependency error
This commit is contained in:
Haitao Pan 2025-11-05 18:00:38 +08:00
parent fec7641d78
commit f43448de5f
2 changed files with 55 additions and 56 deletions

View File

@ -4,7 +4,7 @@
* Islands in Fresh are interactive components that run on the client.
* This is a simple example demonstrating:
* - Preact hooks (useState)
* - Zustand state management integration
* - Signals state management integration
* - Client-side interactivity
*/

View File

@ -1,84 +1,83 @@
/**
* Zustand stores for dashboard state management
* Signals-based stores for dashboard state management
*
* This module provides global state management using Zustand.
* This module provides global state management using Preact Signals.
* Stores are designed to work with both Fresh SSR and client-side islands.
*/
import { create } from 'zustand'
import { signal } from '@preact/signals'
/**
* UI State Store
* Manages global UI state like sidebar, theme, etc.
*/
interface UIState {
sidebarOpen: boolean
theme: 'light' | 'dark' | 'auto'
toggleSidebar: () => void
setTheme: (theme: 'light' | 'dark' | 'auto') => void
}
const sidebarOpenSignal = signal(false)
const themeSignal = signal<'light' | 'dark' | 'auto'>('auto')
export const useUIStore = create<UIState>((set) => ({
sidebarOpen: false,
theme: 'auto',
toggleSidebar: () => set((state) => ({ sidebarOpen: !state.sidebarOpen })),
setTheme: (theme) => set({ theme }),
}))
export const useUIStore = () => ({
sidebarOpen: sidebarOpenSignal.value,
theme: themeSignal.value,
toggleSidebar: () => {
sidebarOpenSignal.value = !sidebarOpenSignal.value
},
setTheme: (theme: 'light' | 'dark' | 'auto') => {
themeSignal.value = theme
},
})
/**
* User State Store
* Manages user authentication and profile data
*/
interface UserState {
user: {
id?: string
email?: string
name?: string
} | null
isAuthenticated: boolean
setUser: (user: UserState['user']) => void
logout: () => void
}
const userSignal = signal<{
id?: string
email?: string
name?: string
} | null>(null)
export const useUserStore = create<UserState>((set) => ({
user: null,
isAuthenticated: false,
setUser: (user) => set({ user, isAuthenticated: !!user }),
logout: () => set({ user: null, isAuthenticated: false }),
}))
export const useUserStore = () => ({
user: userSignal.value,
isAuthenticated: !!userSignal.value,
setUser: (user: typeof userSignal.value) => {
userSignal.value = user
},
logout: () => {
userSignal.value = null
},
})
/**
* Template State Store
* Manages template selection and metadata
*/
interface TemplateState {
selectedTemplateId: string | null
templates: Array<{ id: string; name: string; category: string }>
setSelectedTemplate: (id: string | null) => void
setTemplates: (templates: TemplateState['templates']) => void
}
const selectedTemplateIdSignal = signal<string | null>(null)
const templatesSignal = signal<Array<{ id: string; name: string; category: string }>>([])
export const useTemplateStore = create<TemplateState>((set) => ({
selectedTemplateId: null,
templates: [],
setSelectedTemplate: (id) => set({ selectedTemplateId: id }),
setTemplates: (templates) => set({ templates }),
}))
export const useTemplateStore = () => ({
selectedTemplateId: selectedTemplateIdSignal.value,
templates: templatesSignal.value,
setSelectedTemplate: (id: string | null) => {
selectedTemplateIdSignal.value = id
},
setTemplates: (templates: typeof templatesSignal.value) => {
templatesSignal.value = templates
},
})
/**
* Content State Store
* Manages content/document state
*/
interface ContentState {
currentDocSlug: string | null
searchQuery: string
setCurrentDocSlug: (slug: string | null) => void
setSearchQuery: (query: string) => void
}
const currentDocSlugSignal = signal<string | null>(null)
const searchQuerySignal = signal('')
export const useContentStore = create<ContentState>((set) => ({
currentDocSlug: null,
searchQuery: '',
setCurrentDocSlug: (slug) => set({ currentDocSlug: slug }),
setSearchQuery: (query) => set({ searchQuery: query }),
}))
export const useContentStore = () => ({
currentDocSlug: currentDocSlugSignal.value,
searchQuery: searchQuerySignal.value,
setCurrentDocSlug: (slug: string | null) => {
currentDocSlugSignal.value = slug
},
setSearchQuery: (query: string) => {
searchQuerySignal.value = query
},
})