migrate dashboard to real HeroUI v3 components and neutral theme
The frontend was built against HeroUI v2 props/classes (variant="light"/"flat", color="primary", startContent, text-tiny, <Avatar src=/name=>) while @heroui/react ^3.2.1 is installed, so most styling was silently ignored. Rewrites every page/component onto the actual v3 API (variant/color enums, Tooltip/Dropdown trigger-content structure, Avatar.Image/Fallback via a new AppAvatar helper) and replaces the custom orange branding with HeroUI's neutral default theme tokens. Also compacts the dashboard stat tiles, narrows the sidebar, and swaps the activity stat grid for a single-hue comparison bar chart. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,7 +1,8 @@
|
||||
import { Button, Chip, Tooltip, Dropdown, DropdownTrigger, DropdownMenu, DropdownItem, Avatar } from '@heroui/react';
|
||||
import { Button, Chip, Tooltip, Dropdown, DropdownTrigger, DropdownPopover, DropdownMenu, DropdownItem } from '@heroui/react';
|
||||
import { Moon, Sun, ChevronDown, LogOut, Settings } from 'lucide-react';
|
||||
import { useTheme } from '../../hooks/useTheme';
|
||||
import { useApp } from '../../context/AppContext';
|
||||
import { AppAvatar } from '../shared/AppAvatar';
|
||||
|
||||
const navLabels: Record<string, string> = {
|
||||
overview: 'Übersicht',
|
||||
@@ -30,14 +31,14 @@ export function Header() {
|
||||
return (
|
||||
<div className="mb-6 flex flex-col gap-3 sm:flex-row sm:items-center sm:justify-between">
|
||||
<div className="flex items-center gap-3 min-w-0">
|
||||
<div className="flex items-center gap-1.5 text-sm section-subtle min-w-0">
|
||||
<button className="hover:text-white transition-colors" onClick={() => setSection('overview')}>
|
||||
<div className="flex items-center gap-1.5 text-sm text-muted min-w-0">
|
||||
<button className="hover:text-foreground transition-colors" onClick={() => setSection('overview')}>
|
||||
Dashboard
|
||||
</button>
|
||||
{section !== 'overview' && (
|
||||
<>
|
||||
<span>/</span>
|
||||
<span className="accent-text font-semibold truncate">{navLabels[section] || section}</span>
|
||||
<span className="text-accent font-semibold truncate">{navLabels[section] || section}</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
@@ -45,33 +46,36 @@ export function Header() {
|
||||
|
||||
<div className="flex items-center gap-2 shrink-0">
|
||||
{statusMessage && (
|
||||
<Chip size="sm" variant="flat" className="accent-chip max-w-[220px]">
|
||||
<Chip size="sm" variant="soft" color="accent" className="max-w-[220px]">
|
||||
<span className="truncate">{statusMessage}</span>
|
||||
</Chip>
|
||||
)}
|
||||
|
||||
<Tooltip content={dark ? 'Helles Design' : 'Dunkles Design'} placement="bottom">
|
||||
<Button isIconOnly radius="lg" size="sm" variant="light" className="ghost-button" onPress={toggle}>
|
||||
{dark ? <Sun size={16} /> : <Moon size={16} />}
|
||||
</Button>
|
||||
<Tooltip>
|
||||
<Tooltip.Trigger>
|
||||
<Button isIconOnly size="sm" variant="ghost" onPress={toggle}>
|
||||
{dark ? <Sun size={16} /> : <Moon size={16} />}
|
||||
</Button>
|
||||
</Tooltip.Trigger>
|
||||
<Tooltip.Content placement="bottom">{dark ? 'Helles Design' : 'Dunkles Design'}</Tooltip.Content>
|
||||
</Tooltip>
|
||||
|
||||
<Dropdown placement="bottom-end">
|
||||
<DropdownTrigger>
|
||||
<Button className="ghost-button gap-2" radius="lg" size="sm" variant="light">
|
||||
<Avatar name={user?.username} size="sm" className="size-6" />
|
||||
<span className="hidden sm:inline text-sm">{user?.username}</span>
|
||||
<ChevronDown size={14} />
|
||||
</Button>
|
||||
<Dropdown>
|
||||
<DropdownTrigger className="inline-flex h-9 items-center gap-2 rounded-3xl px-3 text-sm font-medium hover:bg-default-hover">
|
||||
<AppAvatar name={user?.username} size="sm" className="size-6" />
|
||||
<span className="hidden sm:inline text-sm">{user?.username}</span>
|
||||
<ChevronDown size={14} />
|
||||
</DropdownTrigger>
|
||||
<DropdownMenu aria-label="User Menu">
|
||||
<DropdownItem key="settings" startContent={<Settings size={14} />} onPress={() => setSection('settings')}>
|
||||
Einstellungen
|
||||
</DropdownItem>
|
||||
<DropdownItem key="logout" startContent={<LogOut size={14} />} color="danger" onPress={handleLogout}>
|
||||
Abmelden
|
||||
</DropdownItem>
|
||||
</DropdownMenu>
|
||||
<DropdownPopover placement="bottom end">
|
||||
<DropdownMenu aria-label="User Menu">
|
||||
<DropdownItem key="settings" onAction={() => setSection('settings')}>
|
||||
<Settings size={14} /> Einstellungen
|
||||
</DropdownItem>
|
||||
<DropdownItem key="logout" variant="danger" onAction={handleLogout}>
|
||||
<LogOut size={14} /> Abmelden
|
||||
</DropdownItem>
|
||||
</DropdownMenu>
|
||||
</DropdownPopover>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Reference in New Issue
Block a user