migrate dashboard to real HeroUI v3 components and neutral theme
All checks were successful
Deploy Discord Bot / deploy (push) Successful in -1m4s
SonarQube / sonar (push) Successful in 1m8s

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:
Pepe44DEV
2026-07-02 12:34:53 +02:00
parent 6599158737
commit 0c47dce508
32 changed files with 537 additions and 584 deletions

View File

@@ -1,7 +1,8 @@
import { Avatar, Card, CardContent, CardDescription, CardHeader, CardTitle, Input, TextArea, Button, Chip, Switch, Separator, TextField, Label } from '@heroui/react';
import { Card, CardContent, CardDescription, CardHeader, CardTitle, Input, TextArea, Button, Chip, Switch, Separator, TextField, Label } from '@heroui/react';
import { LogIn, UserRound, Save, Send } from 'lucide-react';
import { useApp } from '../context/AppContext';
import { SectionCard } from '../components/shared/SectionCard';
import { AppAvatar } from '../components/shared/AppAvatar';
export function SupportLogin() {
const { supportLogin, setSupportLogin, saveSupportLogin } = useApp();
@@ -9,7 +10,7 @@ export function SupportLogin() {
return (
<SectionCard title="Support Login" subtitle="Login-Panel fuer Supporter konfigurieren">
<div className="grid gap-5 xl:grid-cols-[1fr_400px]">
<Card className="surface-card">
<Card>
<CardHeader>
<div>
<CardTitle>Panel-Konfiguration</CardTitle>
@@ -27,8 +28,6 @@ export function SupportLogin() {
<TextField>
<Label>Panel Channel ID</Label>
<Input
variant="bordered"
size="lg"
placeholder="Channel ID eingeben"
value={supportLogin?.config?.panelChannelId || ''}
onChange={(e) => setSupportLogin((s) => s ? { ...s, config: { ...s.config, panelChannelId: e.target.value } } : s)}
@@ -38,8 +37,6 @@ export function SupportLogin() {
<TextField>
<Label>Titel</Label>
<Input
variant="bordered"
size="lg"
value={supportLogin?.config?.title || 'Support Login'}
onChange={(e) => setSupportLogin((s) => s ? { ...s, config: { ...s.config, title: e.target.value } } : s)}
/>
@@ -48,7 +45,6 @@ export function SupportLogin() {
<TextField>
<Label>Beschreibung</Label>
<TextArea
variant="bordered"
value={supportLogin?.config?.description || ''}
onChange={(e) => setSupportLogin((s) => s ? { ...s, config: { ...s.config, description: e.target.value } } : s)}
/>
@@ -57,8 +53,6 @@ export function SupportLogin() {
<TextField>
<Label>Login Button Label</Label>
<Input
variant="bordered"
size="lg"
value={supportLogin?.config?.loginLabel || 'Ich bin jetzt im Support'}
onChange={(e) => setSupportLogin((s) => s ? { ...s, config: { ...s.config, loginLabel: e.target.value } } : s)}
/>
@@ -67,8 +61,6 @@ export function SupportLogin() {
<TextField>
<Label>Logout Button Label</Label>
<Input
variant="bordered"
size="lg"
value={supportLogin?.config?.logoutLabel || 'Ich bin nicht mehr im Support'}
onChange={(e) => setSupportLogin((s) => s ? { ...s, config: { ...s.config, logoutLabel: e.target.value } } : s)}
/>
@@ -77,18 +69,18 @@ export function SupportLogin() {
<Separator />
<div className="flex gap-2">
<Button variant="light" className="accent-button" startContent={<Save size={16} />} onPress={saveSupportLogin}>
Speichern & Panel senden
<Button variant="primary" onPress={saveSupportLogin}>
<Save size={16} /> Speichern & Panel senden
</Button>
<Button variant="light" className="ghost-button" startContent={<Send size={16} />}>
Panel manuell senden
<Button variant="ghost">
<Send size={16} /> Panel manuell senden
</Button>
</div>
</CardContent>
</Card>
<div className="space-y-4">
<Card className="surface-card">
<Card>
<CardHeader>
<div>
<CardTitle>Live Vorschau</CardTitle>
@@ -96,10 +88,10 @@ export function SupportLogin() {
</div>
</CardHeader>
<CardContent>
<Card className="surface-card-muted">
<Card className="bg-surface-tertiary">
<CardHeader>
<div className="flex items-center gap-2">
<LogIn size={16} className="accent-text" />
<LogIn size={16} className="text-accent" />
<div>
<CardTitle>{supportLogin?.config?.title || 'Support Login'}</CardTitle>
<CardDescription>{supportLogin?.config?.description || 'Melde dich als Support an/ab.'}</CardDescription>
@@ -107,14 +99,14 @@ export function SupportLogin() {
</div>
</CardHeader>
<CardContent className="flex gap-2">
<Button size="sm" variant="light" className="accent-button">{supportLogin?.config?.loginLabel || 'Login'}</Button>
<Button size="sm" variant="light" className="ghost-button">{supportLogin?.config?.logoutLabel || 'Logout'}</Button>
<Button size="sm" variant="primary">{supportLogin?.config?.loginLabel || 'Login'}</Button>
<Button size="sm" variant="ghost">{supportLogin?.config?.logoutLabel || 'Logout'}</Button>
</CardContent>
</Card>
</CardContent>
</Card>
<Card className="surface-card">
<Card>
<CardHeader>
<div>
<CardTitle>Aktive Supporter</CardTitle>
@@ -123,20 +115,20 @@ export function SupportLogin() {
</CardHeader>
<CardContent className="flex flex-col gap-2">
{supportLogin?.status?.active?.length ? supportLogin.status.active.map((s, i) => (
<Card key={i} className="surface-card-muted">
<Card key={i} className="bg-surface-tertiary">
<CardContent className="flex items-center gap-3">
<Avatar name={s.username?.[0]} size="sm" className="size-6" />
<AppAvatar name={s.username} size="sm" className="size-6" />
<span className="font-medium">{s.username || s.userId}</span>
<Chip size="sm" variant="flat" color="success" className="ml-auto">Online</Chip>
<Chip size="sm" variant="soft" color="success" className="ml-auto">Online</Chip>
</CardContent>
</Card>
)) : (
<div className="flex flex-col items-center gap-2 py-4 text-center text-tiny text-default-400">
<div className="flex flex-col items-center gap-2 py-4 text-center text-xs text-muted">
<UserRound size={20} />
Keine aktiven Supporter
</div>
)}
<p className="mt-2 text-tiny text-default-400">
<p className="mt-2 text-xs text-muted">
Support Role ID: {supportLogin?.supportRoleId || 'Nicht gesetzt'}
</p>
</CardContent>