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>
141 lines
5.8 KiB
TypeScript
141 lines
5.8 KiB
TypeScript
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();
|
|
|
|
return (
|
|
<SectionCard title="Support Login" subtitle="Login-Panel fuer Supporter konfigurieren">
|
|
<div className="grid gap-5 xl:grid-cols-[1fr_400px]">
|
|
<Card>
|
|
<CardHeader>
|
|
<div>
|
|
<CardTitle>Panel-Konfiguration</CardTitle>
|
|
<CardDescription>Texte und Zielkanal mit normalen HeroUI-Feldern pflegen.</CardDescription>
|
|
</div>
|
|
</CardHeader>
|
|
<CardContent className="flex flex-col gap-4">
|
|
<Switch
|
|
isSelected={supportLogin?.config?.autoRefresh !== false}
|
|
onChange={(v) => setSupportLogin((s) => s ? { ...s, config: { ...s.config, autoRefresh: v } } : s)}
|
|
>
|
|
Auto-Refresh aktiv
|
|
</Switch>
|
|
|
|
<TextField>
|
|
<Label>Panel Channel ID</Label>
|
|
<Input
|
|
placeholder="Channel ID eingeben"
|
|
value={supportLogin?.config?.panelChannelId || ''}
|
|
onChange={(e) => setSupportLogin((s) => s ? { ...s, config: { ...s.config, panelChannelId: e.target.value } } : s)}
|
|
/>
|
|
</TextField>
|
|
|
|
<TextField>
|
|
<Label>Titel</Label>
|
|
<Input
|
|
value={supportLogin?.config?.title || 'Support Login'}
|
|
onChange={(e) => setSupportLogin((s) => s ? { ...s, config: { ...s.config, title: e.target.value } } : s)}
|
|
/>
|
|
</TextField>
|
|
|
|
<TextField>
|
|
<Label>Beschreibung</Label>
|
|
<TextArea
|
|
value={supportLogin?.config?.description || ''}
|
|
onChange={(e) => setSupportLogin((s) => s ? { ...s, config: { ...s.config, description: e.target.value } } : s)}
|
|
/>
|
|
</TextField>
|
|
|
|
<TextField>
|
|
<Label>Login Button Label</Label>
|
|
<Input
|
|
value={supportLogin?.config?.loginLabel || 'Ich bin jetzt im Support'}
|
|
onChange={(e) => setSupportLogin((s) => s ? { ...s, config: { ...s.config, loginLabel: e.target.value } } : s)}
|
|
/>
|
|
</TextField>
|
|
|
|
<TextField>
|
|
<Label>Logout Button Label</Label>
|
|
<Input
|
|
value={supportLogin?.config?.logoutLabel || 'Ich bin nicht mehr im Support'}
|
|
onChange={(e) => setSupportLogin((s) => s ? { ...s, config: { ...s.config, logoutLabel: e.target.value } } : s)}
|
|
/>
|
|
</TextField>
|
|
|
|
<Separator />
|
|
|
|
<div className="flex gap-2">
|
|
<Button variant="primary" onPress={saveSupportLogin}>
|
|
<Save size={16} /> Speichern & Panel senden
|
|
</Button>
|
|
<Button variant="ghost">
|
|
<Send size={16} /> Panel manuell senden
|
|
</Button>
|
|
</div>
|
|
</CardContent>
|
|
</Card>
|
|
|
|
<div className="space-y-4">
|
|
<Card>
|
|
<CardHeader>
|
|
<div>
|
|
<CardTitle>Live Vorschau</CardTitle>
|
|
<CardDescription>Panel in einer normalen HeroUI-Karte.</CardDescription>
|
|
</div>
|
|
</CardHeader>
|
|
<CardContent>
|
|
<Card className="bg-surface-tertiary">
|
|
<CardHeader>
|
|
<div className="flex items-center gap-2">
|
|
<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>
|
|
</div>
|
|
</div>
|
|
</CardHeader>
|
|
<CardContent className="flex gap-2">
|
|
<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>
|
|
<CardHeader>
|
|
<div>
|
|
<CardTitle>Aktive Supporter</CardTitle>
|
|
<CardDescription>Aktueller Status aus der Guild.</CardDescription>
|
|
</div>
|
|
</CardHeader>
|
|
<CardContent className="flex flex-col gap-2">
|
|
{supportLogin?.status?.active?.length ? supportLogin.status.active.map((s, i) => (
|
|
<Card key={i} className="bg-surface-tertiary">
|
|
<CardContent className="flex items-center gap-3">
|
|
<AppAvatar name={s.username} size="sm" className="size-6" />
|
|
<span className="font-medium">{s.username || s.userId}</span>
|
|
<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-xs text-muted">
|
|
<UserRound size={20} />
|
|
Keine aktiven Supporter
|
|
</div>
|
|
)}
|
|
<p className="mt-2 text-xs text-muted">
|
|
Support Role ID: {supportLogin?.supportRoleId || 'Nicht gesetzt'}
|
|
</p>
|
|
</CardContent>
|
|
</Card>
|
|
</div>
|
|
</div>
|
|
</SectionCard>
|
|
);
|
|
}
|