优化导航栏性能,完善导航栏弹出菜单的移动端适配;调整导航栏与 store 公共组件的所在目录结构
This commit is contained in:
@@ -8,7 +8,7 @@ import Image from 'next/image'
|
||||
import alipay from '@/components/composites/purchase/_assets/alipay.svg'
|
||||
import wechat from '@/components/composites/purchase/_assets/wechat.svg'
|
||||
import balance from '@/components/composites/purchase/_assets/balance.svg'
|
||||
import {useProfileStore} from '@/app/stores'
|
||||
import {useProfileStore} from '@/components/stores-provider'
|
||||
import RechargeModal from '@/components/composites/recharge'
|
||||
import Pay from '@/components/composites/purchase/pay'
|
||||
import {buttonVariants} from '@/components/ui/button'
|
||||
|
||||
@@ -6,7 +6,7 @@ import wechat from './_assets/wechat.svg'
|
||||
import balance from './_assets/balance.svg'
|
||||
import Image from 'next/image'
|
||||
import {useEffect, useRef, useState} from 'react'
|
||||
import {useProfileStore} from '@/app/stores'
|
||||
import {useProfileStore} from '@/components/stores-provider'
|
||||
import {Alert, AlertTitle} from '@/components/ui/alert'
|
||||
import {ApiResponse, ExtraResp, ExtraReq} from '@/lib/api'
|
||||
import {toast} from 'sonner'
|
||||
|
||||
@@ -8,7 +8,7 @@ import Image from 'next/image'
|
||||
import alipay from '@/components/composites/purchase/_assets/alipay.svg'
|
||||
import wechat from '@/components/composites/purchase/_assets/wechat.svg'
|
||||
import balance from '@/components/composites/purchase/_assets/balance.svg'
|
||||
import {useProfileStore} from '@/app/stores'
|
||||
import {useProfileStore} from '@/components/stores-provider'
|
||||
import RechargeModal from '@/components/composites/recharge'
|
||||
import {buttonVariants} from '@/components/ui/button'
|
||||
import Link from 'next/link'
|
||||
|
||||
@@ -19,7 +19,7 @@ import {useEffect, useMemo, useRef, useState} from 'react'
|
||||
import {Loader} from 'lucide-react'
|
||||
import {RechargeComplete, RechargePrepare} from '@/actions/user'
|
||||
import * as qrcode from 'qrcode'
|
||||
import {useProfileStore} from '@/app/stores'
|
||||
import {useProfileStore} from '@/components/stores-provider'
|
||||
import {merge} from '@/lib/utils'
|
||||
import {
|
||||
Platform,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
'use client'
|
||||
import {useProfileStore} from '@/app/stores'
|
||||
import {useProfileStore} from '@/components/stores-provider'
|
||||
import {Button} from '@/components/ui/button'
|
||||
import {Avatar, AvatarFallback, AvatarImage} from '@/components/ui/avatar'
|
||||
import {LoaderIcon, LogOutIcon, UserIcon, UserPenIcon} from 'lucide-react'
|
||||
|
||||
73
src/components/stores-provider.tsx
Normal file
73
src/components/stores-provider.tsx
Normal file
@@ -0,0 +1,73 @@
|
||||
'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>
|
||||
)
|
||||
}
|
||||
Reference in New Issue
Block a user