feat: 炫酷的登录页
This commit is contained in:
+23
-6
@@ -1,15 +1,32 @@
|
||||
import { create } from 'zustand'
|
||||
import { persist } from 'zustand/middleware'
|
||||
|
||||
interface AppState {
|
||||
sidebarOpen: boolean
|
||||
mobileMenuOpen: boolean
|
||||
themeHue: string
|
||||
cmdKOpen: boolean
|
||||
toggleSidebar: () => void
|
||||
setMobileMenu: (open: boolean) => void
|
||||
setThemeHue: (hue: string) => void
|
||||
setCmdKOpen: (open: boolean) => void
|
||||
}
|
||||
|
||||
export const useAppStore = create<AppState>((set) => ({
|
||||
sidebarOpen: true,
|
||||
mobileMenuOpen: false,
|
||||
toggleSidebar: () => set(s => ({ sidebarOpen: !s.sidebarOpen })),
|
||||
setMobileMenu: (open) => set({ mobileMenuOpen: open }),
|
||||
}))
|
||||
export const useAppStore = create<AppState>()(
|
||||
persist(
|
||||
(set) => ({
|
||||
sidebarOpen: true,
|
||||
mobileMenuOpen: false,
|
||||
themeHue: '145', // Default emerald
|
||||
cmdKOpen: false,
|
||||
toggleSidebar: () => set(s => ({ sidebarOpen: !s.sidebarOpen })),
|
||||
setMobileMenu: (open) => set({ mobileMenuOpen: open }),
|
||||
setThemeHue: (hue) => set({ themeHue: hue }),
|
||||
setCmdKOpen: (open) => set({ cmdKOpen: open }),
|
||||
}),
|
||||
{
|
||||
name: 'app-storage',
|
||||
partialize: (state) => ({ themeHue: state.themeHue, sidebarOpen: state.sidebarOpen }),
|
||||
}
|
||||
)
|
||||
)
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
import { create } from 'zustand'
|
||||
|
||||
export interface TabItem {
|
||||
path: string
|
||||
title: string
|
||||
closable: boolean // Dashboard tab is not closable
|
||||
}
|
||||
|
||||
interface TabsState {
|
||||
tabs: TabItem[]
|
||||
activeTab: string
|
||||
|
||||
addTab: (tab: TabItem) => void
|
||||
removeTab: (path: string) => string // returns next active path
|
||||
setActiveTab: (path: string) => void
|
||||
closeOthers: (path: string) => void
|
||||
closeAll: () => string // returns home path
|
||||
closeRight: (path: string) => void
|
||||
closeLeft: (path: string) => void
|
||||
}
|
||||
|
||||
const HOME_TAB: TabItem = { path: '/dashboard', title: '仪表盘', closable: false }
|
||||
|
||||
export const useTabsStore = create<TabsState>((set, get) => ({
|
||||
tabs: [HOME_TAB],
|
||||
activeTab: '/dashboard',
|
||||
|
||||
addTab: (tab) => {
|
||||
const { tabs } = get()
|
||||
if (!tabs.find(t => t.path === tab.path)) {
|
||||
set({ tabs: [...tabs, tab], activeTab: tab.path })
|
||||
} else {
|
||||
set({ activeTab: tab.path })
|
||||
}
|
||||
},
|
||||
|
||||
removeTab: (path) => {
|
||||
const { tabs, activeTab } = get()
|
||||
const target = tabs.find(t => t.path === path)
|
||||
if (!target || !target.closable) return activeTab
|
||||
|
||||
const newTabs = tabs.filter(t => t.path !== path)
|
||||
let nextActive = activeTab
|
||||
if (activeTab === path) {
|
||||
const idx = tabs.findIndex(t => t.path === path)
|
||||
nextActive = newTabs[Math.min(idx, newTabs.length - 1)]?.path || '/dashboard'
|
||||
}
|
||||
set({ tabs: newTabs, activeTab: nextActive })
|
||||
return nextActive
|
||||
},
|
||||
|
||||
setActiveTab: (path) => set({ activeTab: path }),
|
||||
|
||||
closeOthers: (path) => {
|
||||
const { tabs } = get()
|
||||
set({
|
||||
tabs: tabs.filter(t => !t.closable || t.path === path),
|
||||
activeTab: path,
|
||||
})
|
||||
},
|
||||
|
||||
closeAll: () => {
|
||||
set({ tabs: [HOME_TAB], activeTab: '/dashboard' })
|
||||
return '/dashboard'
|
||||
},
|
||||
|
||||
closeRight: (path) => {
|
||||
const { tabs, activeTab } = get()
|
||||
const idx = tabs.findIndex(t => t.path === path)
|
||||
const newTabs = tabs.filter((t, i) => i <= idx || !t.closable)
|
||||
const stillHasActive = newTabs.find(t => t.path === activeTab)
|
||||
set({ tabs: newTabs, activeTab: stillHasActive ? activeTab : path })
|
||||
},
|
||||
|
||||
closeLeft: (path) => {
|
||||
const { tabs, activeTab } = get()
|
||||
const idx = tabs.findIndex(t => t.path === path)
|
||||
const newTabs = tabs.filter((t, i) => i >= idx || !t.closable)
|
||||
const stillHasActive = newTabs.find(t => t.path === activeTab)
|
||||
set({ tabs: newTabs, activeTab: stillHasActive ? activeTab : path })
|
||||
},
|
||||
}))
|
||||
Reference in New Issue
Block a user