feat: Implement new settings pages and refactor application layout and navigation with new components and hooks.

This commit is contained in:
syntaxbullet
2026-01-16 12:49:17 +01:00
parent 2f73f38877
commit 2a72beb0ef
33 changed files with 2584 additions and 1863 deletions

View File

@@ -0,0 +1,146 @@
import * as React from "react"
import { useLocation, type Location } from "react-router-dom"
import { Home, Palette, ShieldCheck, Users, Settings, BarChart3, Scroll, type LucideIcon } from "lucide-react"
export interface NavSubItem {
title: string
url: string
isActive?: boolean
}
export interface NavItem {
title: string
url: string
icon: LucideIcon
isActive?: boolean
subItems?: NavSubItem[]
}
export interface Breadcrumb {
title: string
url: string
}
interface NavigationContextProps {
navItems: NavItem[]
breadcrumbs: Breadcrumb[]
currentPath: string
currentTitle: string
}
const NavigationContext = React.createContext<NavigationContextProps | null>(null)
interface NavConfigItem extends Omit<NavItem, "isActive" | "subItems"> {
subItems?: Omit<NavSubItem, "isActive">[]
}
const NAV_CONFIG: NavConfigItem[] = [
{ title: "Home", url: "/", icon: Home },
{ title: "Design System", url: "/design-system", icon: Palette },
{
title: "Admin",
url: "/admin",
icon: ShieldCheck,
subItems: [
{ title: "Overview", url: "/admin/overview" },
{ title: "Quests", url: "/admin/quests" },
]
},
{
title: "Settings",
url: "/settings",
icon: Settings,
subItems: [
{ title: "General", url: "/settings/general" },
{ title: "Economy", url: "/settings/economy" },
{ title: "Systems", url: "/settings/systems" },
{ title: "Roles", url: "/settings/roles" },
]
},
]
function generateBreadcrumbs(location: Location): Breadcrumb[] {
const pathParts = location.pathname.split("/").filter(Boolean)
const breadcrumbs: Breadcrumb[] = []
let currentPath = ""
for (const part of pathParts) {
currentPath += `/${part}`
// Capitalize and clean up the part for display
const title = part
.split("-")
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join(" ")
breadcrumbs.push({ title, url: currentPath })
}
return breadcrumbs
}
function getPageTitle(pathname: string): string {
// Check top-level items first
for (const item of NAV_CONFIG) {
if (item.url === pathname) return item.title
// Check sub-items
if (item.subItems) {
const subItem = item.subItems.find((sub) => sub.url === pathname)
if (subItem) return subItem.title
}
}
// Handle nested routes
const parts = pathname.split("/").filter(Boolean)
const lastPart = parts[parts.length - 1]
if (lastPart) {
return lastPart
.split("-")
.map((word) => word.charAt(0).toUpperCase() + word.slice(1))
.join(" ")
}
return "Aurora"
}
export function NavigationProvider({ children }: { children: React.ReactNode }) {
const location = useLocation()
const value = React.useMemo<NavigationContextProps>(() => {
const navItems = NAV_CONFIG.map((item) => {
const isParentActive = item.subItems
? location.pathname.startsWith(item.url)
: location.pathname === item.url
return {
...item,
isActive: isParentActive,
subItems: item.subItems?.map((subItem) => ({
...subItem,
isActive: location.pathname === subItem.url,
})),
}
})
return {
navItems,
breadcrumbs: generateBreadcrumbs(location),
currentPath: location.pathname,
currentTitle: getPageTitle(location.pathname),
}
}, [location.pathname])
return (
<NavigationContext.Provider value={value}>
{children}
</NavigationContext.Provider>
)
}
export function useNavigation() {
const context = React.useContext(NavigationContext)
if (!context) {
throw new Error("useNavigation must be used within a NavigationProvider")
}
return context
}