feat: vollständiges Dashboard-Redesign mit HeroUI - monolithische App.tsx aufgelöst, 16 Seiten, Context-API, collapsible Sidebar, neues Dashboard-Layout
Some checks failed
Deploy Discord Bot / deploy (push) Has been cancelled
Some checks failed
Deploy Discord Bot / deploy (push) Has been cancelled
This commit is contained in:
88
frontend/src/components/layout/Header.tsx
Normal file
88
frontend/src/components/layout/Header.tsx
Normal file
@@ -0,0 +1,88 @@
|
||||
import { Button, Chip, Tooltip, Dropdown, DropdownTrigger, DropdownMenu, DropdownItem, Avatar } from '@heroui/react';
|
||||
import { Moon, Sun, Bell, ChevronDown, LogOut, Settings } from 'lucide-react';
|
||||
import { useTheme } from '../../hooks/useTheme';
|
||||
import { useApp } from '../../context/AppContext';
|
||||
|
||||
const navLabels: Record<string, string> = {
|
||||
overview: 'Übersicht',
|
||||
tickets: 'Ticketsystem',
|
||||
supportlogin: 'Support Login',
|
||||
automod: 'Automod',
|
||||
welcome: 'Willkommen',
|
||||
dynamicvoice: 'Dynamic Voice',
|
||||
birthday: 'Birthday',
|
||||
reactionroles: 'Reaction Roles',
|
||||
statuspage: 'Statuspage',
|
||||
serverstats: 'Server Stats',
|
||||
register: 'Registrierung',
|
||||
music: 'Musik',
|
||||
settings: 'Einstellungen',
|
||||
modules: 'Module',
|
||||
events: 'Events',
|
||||
admin: 'Admin',
|
||||
};
|
||||
|
||||
export function Header() {
|
||||
const { dark, toggle } = useTheme();
|
||||
const { guildName, statusMessage } = useHeaderData();
|
||||
const { user, handleLogout, setSection, section } = useApp();
|
||||
|
||||
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 text-default-400 min-w-0">
|
||||
<button className="hover:text-foreground transition-colors" onClick={() => setSection('overview')}>
|
||||
Dashboard
|
||||
</button>
|
||||
{section !== 'overview' && (
|
||||
<>
|
||||
<span>/</span>
|
||||
<span className="text-foreground font-medium truncate">{navLabels[section] || section}</span>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div className="flex items-center gap-2 shrink-0">
|
||||
{statusMessage && (
|
||||
<Chip color="warning" size="sm" variant="flat" className="max-w-[200px]">
|
||||
<span className="truncate">{statusMessage}</span>
|
||||
</Chip>
|
||||
)}
|
||||
|
||||
<Tooltip content={dark ? 'Helles Design' : 'Dunkles Design'} placement="bottom">
|
||||
<Button isIconOnly radius="lg" size="sm" variant="light" onPress={toggle}>
|
||||
{dark ? <Sun size={16} /> : <Moon size={16} />}
|
||||
</Button>
|
||||
</Tooltip>
|
||||
|
||||
<Dropdown placement="bottom-end">
|
||||
<DropdownTrigger>
|
||||
<Button className="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>
|
||||
</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>
|
||||
</Dropdown>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
function useHeaderData() {
|
||||
const { guildInfo, guilds, currentGuildId } = useApp();
|
||||
const selectedGuild = guilds.find((g) => g.id === currentGuildId);
|
||||
return {
|
||||
guildName: guildInfo?.name || selectedGuild?.name || 'Dashboard',
|
||||
statusMessage: null,
|
||||
};
|
||||
}
|
||||
Reference in New Issue
Block a user