封装 Header 和 Navbar 组件,调整用户界面
This commit is contained in:
@@ -8,14 +8,25 @@ export type PageProps = {
|
||||
export default function Page(props: ComponentProps<'main'> & PageProps) {
|
||||
return (
|
||||
<main {...props} className={merge(
|
||||
`flex-auto flex gap-4`,
|
||||
{
|
||||
full: `bg-white rounded-tl-xl p-4 flex-col overflow-auto`,
|
||||
blank: `items-stretch pb-4 pr-4 overflow-hidden`,
|
||||
}[props.mode ?? 'full'],
|
||||
props.className,
|
||||
`flex-auto rounded-tl-xl overflow-hidden relative`,
|
||||
)}>
|
||||
{props.children}
|
||||
|
||||
{/* background */}
|
||||
<div className={`absolute inset-0 overflow-hidden`}>
|
||||
<div className={`absolute w-screen h-screen bg-gray-50`}></div>
|
||||
<div className={`absolute w-[2000px] h-[2000px] -left-[1000px] -top-[1000px] bg-radial from-blue-50 from-10% to-transparent to-50%`}></div>
|
||||
<div className={`absolute w-[2000px] h-[2000px] -right-[1000px] -top-[1000px] bg-radial from-blue-50 from-10% to-transparent to-50%`}></div>
|
||||
<div className={`absolute w-[2000px] h-[2000px] left-[calc(50%-1000px)] -bottom-[1000px] bg-radial from-blue-50 from-10% to-transparent to-50%`}></div>
|
||||
</div>
|
||||
|
||||
{/* content */}
|
||||
<div className={merge(
|
||||
`relative w-full h-full`,
|
||||
`flex flex-col gap-4 p-4 overflow-auto`,
|
||||
props.className,
|
||||
)}>
|
||||
{props.children}
|
||||
</div>
|
||||
</main>
|
||||
)
|
||||
}
|
||||
|
||||
@@ -1,13 +1,15 @@
|
||||
'use client'
|
||||
import {User} from '@/lib/models'
|
||||
import {createContext, ReactNode, useContext, useRef} from 'react'
|
||||
import {createProfileStore, ProfileStore} from '@/stores/profile-store'
|
||||
import {StoreApi} from 'zustand/vanilla'
|
||||
import {useStore} from 'zustand/react'
|
||||
import {createProfileStore, ProfileStore} from '@/stores/profile'
|
||||
import {createLayoutStore, LayoutStore} from '@/stores/layout'
|
||||
|
||||
|
||||
export type StoreContextType = {
|
||||
profile: StoreApi<ProfileStore>
|
||||
layout: StoreApi<LayoutStore>
|
||||
}
|
||||
|
||||
export const StoreContext = createContext<StoreContextType | null>(null)
|
||||
@@ -18,15 +20,23 @@ export type ProfileProviderProps = {
|
||||
}
|
||||
|
||||
export default function StoreProvider(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()
|
||||
}
|
||||
|
||||
return (
|
||||
<StoreContext.Provider value={{
|
||||
profile: profile.current,
|
||||
layout: layout.current,
|
||||
}}>
|
||||
{props.children}
|
||||
</StoreContext.Provider>
|
||||
@@ -41,3 +51,11 @@ export function useProfileStore<T>(selector: (store: ProfileStore) => T) {
|
||||
}
|
||||
return useStore(ctx.profile, selector)
|
||||
}
|
||||
|
||||
export function useLayoutStore<T>(selector: (store: LayoutStore) => T) {
|
||||
const ctx = useContext(StoreContext)
|
||||
if (!ctx) {
|
||||
throw new Error('useLayoutStore must be used within a StoreProvider')
|
||||
}
|
||||
return useStore(ctx.layout, selector)
|
||||
}
|
||||
|
||||
@@ -33,7 +33,7 @@ const buttonVariants = cva(
|
||||
)
|
||||
|
||||
type ButtonProps = React.ComponentProps<'button'> & {
|
||||
theme?: 'default' | 'outline' | 'gradient' | 'error' | 'accent'
|
||||
theme?: 'default' | 'outline' | 'gradient' | 'error' | 'accent' | 'ghost'
|
||||
}
|
||||
|
||||
function Button(rawProps: ButtonProps) {
|
||||
@@ -55,6 +55,7 @@ function Button(rawProps: ButtonProps) {
|
||||
accent: 'bg-accent text-accent-foreground hover:bg-accent/90',
|
||||
error: 'bg-fail text-white hover:bg-fail/90',
|
||||
outline: 'border bg-background hover:bg-secondary hover:text-secondary-foreground dark:bg-input/30 dark:border-input dark:hover:bg-input/50',
|
||||
ghost: "text-foreground hover:bg-muted",
|
||||
}[theme ?? 'default'],
|
||||
className,
|
||||
)}
|
||||
|
||||
Reference in New Issue
Block a user