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

This commit is contained in:
Pepe44DEV
2026-07-01 06:15:56 +02:00
parent ccaf7bd4d2
commit e2d8002bf2
29 changed files with 2776 additions and 1296 deletions

View 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,
};
}