74 lines
2.2 KiB
TypeScript
74 lines
2.2 KiB
TypeScript
'use client'
|
|
import {User} from '@/lib/models'
|
|
import {createContext, ReactNode, useContext, useEffect, useRef} from 'react'
|
|
import {StoreApi} from 'zustand/vanilla'
|
|
import {useStore} from 'zustand/react'
|
|
import {createProfileStore, ProfileStore} from '@/lib/stores/profile'
|
|
import {createLayoutStore, LayoutStore} from '@/lib/stores/layout'
|
|
import {ClientStore, createClientStore} from '@/lib/stores/client'
|
|
|
|
const StoreContext = createContext<{
|
|
profile?: StoreApi<ProfileStore>
|
|
layout?: StoreApi<LayoutStore>
|
|
client?: StoreApi<ClientStore>
|
|
}>({})
|
|
|
|
export function useProfileStore<T>(selector: (store: ProfileStore) => T) {
|
|
const profile = useContext(StoreContext).profile
|
|
if (!profile) {
|
|
throw new Error('useProfileStore must be used within a StoreProvider')
|
|
}
|
|
return useStore(profile, selector)
|
|
}
|
|
|
|
export function useLayoutStore<T>(selector: (store: LayoutStore) => T) {
|
|
const layout = useContext(StoreContext).layout
|
|
if (!layout) {
|
|
throw new Error('useLayoutStore must be used within a StoreProvider')
|
|
}
|
|
return useStore(layout, selector)
|
|
}
|
|
|
|
export function useClientStore<T>(selector: (store: ClientStore) => T) {
|
|
const client = useContext(StoreContext).client
|
|
if (!client) {
|
|
throw new Error('useClientStore must be used within a StoreProvider')
|
|
}
|
|
return useStore(client, selector)
|
|
}
|
|
|
|
export type ProfileProviderProps = {
|
|
user: User | null
|
|
children: ReactNode
|
|
}
|
|
|
|
export default function StoresProvider(props: ProfileProviderProps) {
|
|
const profile = useRef<StoreApi<ProfileStore>>(null)
|
|
if (!profile.current) {
|
|
console.log('📦 create profile store')
|
|
profile.current = createProfileStore(props.user)
|
|
}
|
|
|
|
const layout = useRef<StoreApi<LayoutStore>>(null)
|
|
if (!layout.current) {
|
|
console.log('📦 create layout store')
|
|
layout.current = createLayoutStore()
|
|
}
|
|
|
|
const client = useRef<StoreApi<ClientStore>>(null)
|
|
if (!client.current) {
|
|
console.log('📦 create client store')
|
|
client.current = createClientStore()
|
|
}
|
|
|
|
return (
|
|
<StoreContext.Provider value={{
|
|
profile: profile.current,
|
|
layout: layout.current,
|
|
client: client.current,
|
|
}}>
|
|
{props.children}
|
|
</StoreContext.Provider>
|
|
)
|
|
}
|