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:
62
frontend/src/pages/Music.tsx
Normal file
62
frontend/src/pages/Music.tsx
Normal file
@@ -0,0 +1,62 @@
|
||||
import { Card, CardContent, CardHeader, Chip, Button } from '@heroui/react';
|
||||
import { Music, Play, List, Repeat, ExternalLink } from 'lucide-react';
|
||||
import { useApp } from '../context/AppContext';
|
||||
import { SectionCard } from '../components/shared/SectionCard';
|
||||
import { StatCard } from '../components/shared/StatCard';
|
||||
|
||||
export function MusicPage() {
|
||||
const { musicStatus } = useApp();
|
||||
|
||||
return (
|
||||
<SectionCard title="Musik-Status" subtitle="Aktuelle Wiedergabe und Queues pro Guild.">
|
||||
<div className="space-y-5">
|
||||
<div className="grid gap-4 sm:grid-cols-3">
|
||||
<StatCard icon={<Music size={18} />} label="Aktive Guilds" value={musicStatus.activeGuilds} color="primary" />
|
||||
<StatCard icon={<Play size={18} />} label="Aktive Sessions" value={musicStatus.sessions.length} color="success" />
|
||||
</div>
|
||||
|
||||
<div className="space-y-3">
|
||||
<h3 className="text-base font-semibold">Sessions ({musicStatus.sessions.length})</h3>
|
||||
{musicStatus.sessions.length ? musicStatus.sessions.map((session) => (
|
||||
<Card key={session.guildId} className="border border-default-100 bg-default-50/20">
|
||||
<CardContent className="flex flex-col gap-3 p-4">
|
||||
<div className="flex items-center justify-between">
|
||||
<div className="flex items-center gap-2">
|
||||
<Music size={16} className="text-primary-400" />
|
||||
<span className="font-semibold text-small">{session.guildId}</span>
|
||||
</div>
|
||||
<div className="flex gap-2">
|
||||
<Chip size="sm" variant="flat" startContent={<Repeat size={12} />}>
|
||||
{session.loop}
|
||||
</Chip>
|
||||
<Chip size="sm" variant="flat" startContent={<List size={12} />}>
|
||||
{session.queueLength} in Queue
|
||||
</Chip>
|
||||
</div>
|
||||
</div>
|
||||
{session.nowPlaying ? (
|
||||
<div className="rounded-xl bg-default-100/50 px-4 py-3 text-small">
|
||||
<span className="text-default-500">Jetzt l<EFBFBD>uft: </span>
|
||||
<a href={session.nowPlaying.url} target="_blank" rel="noopener noreferrer" className="inline-flex items-center gap-1 text-primary-400 hover:underline">
|
||||
{session.nowPlaying.title}
|
||||
<ExternalLink size={12} />
|
||||
</a>
|
||||
</div>
|
||||
) : (
|
||||
<div className="rounded-xl bg-default-100/30 px-4 py-3 text-small text-default-400">
|
||||
Keine aktive Wiedergabe
|
||||
</div>
|
||||
)}
|
||||
</CardContent>
|
||||
</Card>
|
||||
)) : (
|
||||
<div className="flex flex-col items-center gap-2 py-8 text-center text-small text-default-400">
|
||||
<Music size={24} />
|
||||
Keine aktiven Musik-Sessions
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</SectionCard>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user