fix: HeroUI v3 compound API (Card.Content/Card.Header) + @heroui/styles CSS import
Some checks failed
Deploy Discord Bot / deploy (push) Has been cancelled

This commit is contained in:
Pepe44DEV
2026-07-01 04:34:39 +02:00
parent 2a116d4182
commit e9b0f25d71
3 changed files with 52 additions and 50 deletions

View File

@@ -10,6 +10,7 @@
},
"dependencies": {
"@heroui/react": "^3.2.1",
"@heroui/styles": "^3.2.1",
"framer-motion": "^12.23.24",
"lucide-react": "^0.542.0",
"react": "^19.2.0",

View File

@@ -2,8 +2,6 @@ import {
Avatar,
Button,
Card,
CardContent,
CardHeader,
Chip,
Input,
Spinner,
@@ -504,13 +502,13 @@ function App() {
className="papo-card"
onPress={() => setCurrentGuildId(guild.id)}
>
<CardContent className="flex flex-row items-center gap-4 p-5">
<Card.Content className="flex flex-row items-center gap-4 p-5">
<Avatar src={guildIconUrl(guild)} name={guild.name} radius="lg" />
<div>
<div className="text-lg font-semibold">{guild.name}</div>
<div className="text-sm text-white/50">ID: {guild.id}</div>
</div>
</CardContent>
</Card.Content>
</Card>
))}
</div>
@@ -550,7 +548,7 @@ function App() {
</div>
<Card className="papo-card mt-auto">
<CardContent className="gap-3 p-4">
<Card.Content className="gap-3 p-4">
<div className="text-xs uppercase tracking-[0.18em] text-white/45">Angemeldet als</div>
<div className="font-semibold">
{user?.username}
@@ -567,14 +565,14 @@ function App() {
>
Logout
</Button>
</CardContent>
</Card.Content>
</Card>
</aside>
<main className="px-4 py-6 md:px-8">
<div className="mx-auto max-w-[1520px]">
<Card className="papo-card mb-5">
<CardContent className="flex flex-col gap-6 p-6 md:flex-row md:items-start md:justify-between">
<Card.Content className="flex flex-col gap-6 p-6 md:flex-row md:items-start md:justify-between">
<div>
<h1 className="papo-section-title">Guild Dashboard</h1>
<p className="papo-section-subtitle">Komplettes HeroUI-Rework fuer dein Bot-Dashboard</p>
@@ -596,13 +594,13 @@ function App() {
</label>
{statusMessage ? <div className="mt-2 text-sm text-warning-300">{statusMessage}</div> : null}
</div>
</CardContent>
</Card.Content>
</Card>
{section === 'overview' && (
<div className="space-y-5">
<Card className="papo-card">
<CardContent className="flex flex-col gap-5 p-5 xl:flex-row xl:items-center xl:justify-between">
<Card.Content className="flex flex-col gap-5 p-5 xl:flex-row xl:items-center xl:justify-between">
<div className="flex min-w-0 items-center gap-4">
<Avatar className="h-20 w-20" radius="lg" src={guildIconUrl(selectedGuild)} />
<div className="min-w-0">
@@ -625,7 +623,7 @@ function App() {
>
Bot aktiv
</Chip>
</CardContent>
</Card.Content>
</Card>
<div className="grid gap-5 xl:grid-cols-[1.05fr_1.05fr_1fr]">
@@ -644,24 +642,24 @@ function App() {
/>
<Card className="papo-card">
<CardHeader className="px-5 pt-5 pb-0">
<Card.Header className="px-5 pt-5 pb-0">
<div>
<h2 className="text-2xl font-bold">Activity</h2>
<p className="mt-1 text-sm text-white/50">Live-Statistiken aus deinem Bot</p>
</div>
</CardHeader>
<CardContent className="gap-3 p-5">
</Card.Header>
<Card.Content className="gap-3 p-5">
<ActivityTile icon={<MessageSquare size={18} />} kind="messages" label="Messages (24h)" value={activity?.messages24h ?? 0} />
<ActivityTile icon={<Command size={18} />} kind="commands" label="Commands (24h)" value={activity?.commands24h ?? 0} />
<ActivityTile icon={<Shield size={18} />} kind="automod" label="Automod (24h)" value={activity?.automod24h ?? 0} />
<Button className="mt-2 justify-between" endContent={<ChevronRight size={16} />} variant="bordered" onPress={() => setSection('settings')}>
Alle Logs anzeigen
</Button>
</CardContent>
</Card.Content>
</Card>
<Card className="papo-card">
<CardHeader className="flex items-center justify-between px-5 pt-5 pb-0">
<Card.Header className="flex items-center justify-between px-5 pt-5 pb-0">
<div>
<h2 className="text-2xl font-bold">Guild Logs</h2>
<p className="mt-1 text-sm text-white/50">Neueste Ereignisse</p>
@@ -669,13 +667,13 @@ function App() {
<Button endContent={<ChevronRight size={16} />} size="sm" variant="light" onPress={() => setSection('settings')}>
Alle anzeigen
</Button>
</CardHeader>
<CardContent className="p-5">
</Card.Header>
<Card.Content className="p-5">
<div className="papo-scroll max-h-[360px] space-y-3 overflow-auto pr-2">
{logs.length ? (
logs.map((log, index) => (
<Card key={`${log.timestamp}-${index}`} className="border border-white/5 bg-white/[0.03]">
<CardContent className="gap-2 p-4">
<Card.Content className="gap-2 p-4">
<div className="flex items-center gap-2">
<Chip color={log.level === 'warn' ? 'warning' : log.level === 'error' ? 'danger' : 'default'} size="sm" variant="bordered">
{(log.level || 'info').toUpperCase()}
@@ -683,38 +681,38 @@ function App() {
<span className="text-xs text-white/45">{formatDate(log.timestamp)}</span>
</div>
<div className="text-sm text-white/80">{log.category ? `[${log.category}] ` : ''}{log.message || '-'}</div>
</CardContent>
</Card.Content>
</Card>
))
) : (
<div className="text-sm text-white/45">Keine Logs</div>
)}
</div>
</CardContent>
</Card.Content>
</Card>
</div>
<Card className="papo-card">
<CardHeader className="px-5 pt-5 pb-0">
<Card.Header className="px-5 pt-5 pb-0">
<div>
<h2 className="text-2xl font-bold">Schnellzugriff</h2>
<p className="mt-1 text-sm text-white/50">Die wichtigsten Bereiche deines Dashboards</p>
</div>
</CardHeader>
<CardContent className="grid gap-4 p-5 md:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-6">
</Card.Header>
<Card.Content className="grid gap-4 p-5 md:grid-cols-2 xl:grid-cols-3 2xl:grid-cols-6">
{navItems
.filter((item) => !['overview', 'admin'].includes(item.key))
.slice(0, 6)
.map((item) => (
<Card key={item.key} isPressable className="border border-white/6 bg-white/[0.03]" onPress={() => setSection(item.key)}>
<CardContent className="gap-3 p-4">
<Card.Content className="gap-3 p-4">
<div className="papo-icon-badge">{item.icon}</div>
<div className="font-semibold">{item.label}</div>
<div className="text-sm text-white/45">HeroUI-Komponenten fuer den Bereich {item.label}</div>
</CardContent>
</Card.Content>
</Card>
))}
</CardContent>
</Card.Content>
</Card>
</div>
)}
@@ -914,13 +912,13 @@ function App() {
<div className="grid gap-3 xl:grid-cols-2">
{modules.map((module) => (
<Card key={module.key} className="border border-white/6 bg-white/[0.03]">
<CardContent className="flex flex-row items-center justify-between gap-4 p-4">
<Card.Content className="flex flex-row items-center justify-between gap-4 p-4">
<div>
<div className="font-semibold">{module.name}</div>
<div className="text-sm text-white/45">{module.description || ''}</div>
</div>
<Switch isSelected={module.enabled} onValueChange={(value) => void toggleModule(module.key, value)} />
</CardContent>
</Card.Content>
</Card>
))}
</div>
@@ -933,14 +931,14 @@ function App() {
<div className="space-y-3">
{(events || []).map((event) => (
<Card key={event.id} className="border border-white/6 bg-white/[0.03]">
<CardContent className="gap-2 p-4">
<Card.Content className="gap-2 p-4">
<div className="flex items-center justify-between gap-3">
<div className="font-semibold">{event.title}</div>
<Button color="danger" size="sm" variant="flat" onPress={() => deleteEvent(event.id)}>Löschen</Button>
</div>
<div className="text-sm text-white/45">{event.description || 'Keine Beschreibung'}</div>
<div className="text-xs text-white/35">{formatDate(event.startsAt)}</div>
</CardContent>
</Card.Content>
</Card>
))}
</div>
@@ -973,13 +971,13 @@ function App() {
function SectionCard(props: { title: string; subtitle: string; children: React.ReactNode }) {
return (
<Card className="papo-card">
<CardHeader className="px-5 pt-5 pb-0">
<Card.Header className="px-5 pt-5 pb-0">
<div>
<h2 className="text-2xl font-bold">{props.title}</h2>
<p className="mt-1 text-sm text-white/50">{props.subtitle}</p>
</div>
</CardHeader>
<CardContent className="p-5">{props.children}</CardContent>
</Card.Header>
<Card.Content className="p-5">{props.children}</Card.Content>
</Card>
);
}
@@ -987,10 +985,10 @@ function SectionCard(props: { title: string; subtitle: string; children: React.R
function FormCard(props: { title: string; children: React.ReactNode }) {
return (
<Card className="border border-white/6 bg-white/[0.03]">
<CardHeader className="px-5 pt-5 pb-0">
<Card.Header className="px-5 pt-5 pb-0">
<div className="text-lg font-semibold">{props.title}</div>
</CardHeader>
<CardContent className="gap-4 p-5">{props.children}</CardContent>
</Card.Header>
<Card.Content className="gap-4 p-5">{props.children}</Card.Content>
</Card>
);
}
@@ -998,14 +996,14 @@ function FormCard(props: { title: string; children: React.ReactNode }) {
function ListCard(props: { title: string; items: string[] }) {
return (
<Card className="border border-white/6 bg-white/[0.03]">
<CardHeader className="px-5 pt-5 pb-0">
<Card.Header className="px-5 pt-5 pb-0">
<div className="text-lg font-semibold">{props.title}</div>
</CardHeader>
<CardContent className="p-5">
</Card.Header>
<Card.Content className="p-5">
<div className="papo-scroll max-h-[460px] space-y-3 overflow-auto pr-1">
{props.items.length ? props.items.map((item, index) => <div key={`${item}-${index}`} className="rounded-xl border border-white/6 bg-white/[0.02] px-4 py-3 text-sm text-white/75">{item}</div>) : <div className="text-sm text-white/45">Keine Daten</div>}
</div>
</CardContent>
</Card.Content>
</Card>
);
}
@@ -1013,30 +1011,30 @@ function ListCard(props: { title: string; items: string[] }) {
function InfoPanel(props: { title: string; items: Array<{ icon: React.ReactNode; label: string; value: string }>; actionLabel: string; onAction: () => void }) {
return (
<Card className="papo-card">
<CardHeader className="px-5 pt-5 pb-0">
<Card.Header className="px-5 pt-5 pb-0">
<div>
<h2 className="text-2xl font-bold">{props.title}</h2>
<p className="mt-1 text-sm text-white/50">Wichtige Guild-Daten auf einen Blick</p>
</div>
</CardHeader>
<CardContent className="gap-4 p-5">
</Card.Header>
<Card.Content className="gap-4 p-5">
<div className="grid gap-3 md:grid-cols-2">
{props.items.map((item) => (
<Card key={item.label} className="border border-white/6 bg-white/[0.03]">
<CardContent className="gap-3 p-4">
<Card.Content className="gap-3 p-4">
<div className="flex items-center gap-2 text-sm uppercase tracking-[0.14em] text-white/45">
<span className="text-warning-300">{item.icon}</span>
{item.label}
</div>
<div className="text-xl font-bold">{item.value}</div>
</CardContent>
</Card.Content>
</Card>
))}
</div>
<Button className="justify-between" endContent={<ChevronRight size={16} />} variant="bordered" onPress={props.onAction}>
{props.actionLabel}
</Button>
</CardContent>
</Card.Content>
</Card>
);
}
@@ -1044,7 +1042,7 @@ function InfoPanel(props: { title: string; items: Array<{ icon: React.ReactNode;
function ActivityTile(props: { icon: React.ReactNode; label: string; value: number; kind: 'messages' | 'commands' | 'automod' }) {
return (
<Card className="border border-white/6 bg-white/[0.03]">
<CardContent className="flex flex-row items-center justify-between gap-4 p-4">
<Card.Content className="flex flex-row items-center justify-between gap-4 p-4">
<div className="flex items-center gap-3">
<div className="papo-icon-badge">{props.icon}</div>
<div>
@@ -1055,7 +1053,7 @@ function ActivityTile(props: { icon: React.ReactNode; label: string; value: numb
<svg className="papo-chart" viewBox="0 0 120 40">
<path d={sparkPath(props.kind)} stroke={chartColor(props.kind)} />
</svg>
</CardContent>
</Card.Content>
</Card>
);
}
@@ -1072,13 +1070,13 @@ function SettingsLayout(props: { title: string; subtitle: string; children: Reac
</Button>
</FormCard>
<Card className="border border-white/6 bg-white/[0.03]">
<CardContent className="items-start gap-4 p-5">
<Card.Content className="items-start gap-4 p-5">
<div className="text-lg font-semibold">Design-Richtung</div>
<p className="text-sm text-white/55">
Dieser Bereich nutzt jetzt dieselbe HeroUI-Oberfläche wie dein Overview-Dashboard.
Die tieferen Spezial-Workflows aus dem alten Inline-Dashboard werden hier schrittweise in echte React-Komponenten überführt.
</p>
</CardContent>
</Card.Content>
</Card>
</div>
</SectionCard>

View File

@@ -1,4 +1,7 @@
@import "tailwindcss";
@import "@heroui/styles";
@custom-variant dark (&:is(.dark *));
:root {
color-scheme: dark;