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:
86
frontend/src/pages/Events.tsx
Normal file
86
frontend/src/pages/Events.tsx
Normal file
@@ -0,0 +1,86 @@
|
||||
import { Card, CardContent, CardHeader, Input, TextArea, Button, Chip, Separator } from '@heroui/react';
|
||||
import { CalendarDays, Trash2, Plus, Clock } from 'lucide-react';
|
||||
import { useApp } from '../context/AppContext';
|
||||
import { SectionCard } from '../components/shared/SectionCard';
|
||||
import { formatDate } from '../utils/formatters';
|
||||
|
||||
export function Events() {
|
||||
const { events, eventDraft, setEventDraft, saveEvent, deleteEvent } = useApp();
|
||||
|
||||
return (
|
||||
<SectionCard title="Events" subtitle="Bestehende Events und schneller Neu-Anlage-Flow">
|
||||
<div className="grid gap-5 xl:grid-cols-[1fr_420px]">
|
||||
<div>
|
||||
<h3 className="mb-3 text-base font-semibold">Bestehende Events ({(events || []).length})</h3>
|
||||
<div className="space-y-3">
|
||||
{(events || []).length ? (events || []).map((event) => (
|
||||
<Card key={event.id} 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 min-w-0">
|
||||
<CalendarDays size={16} className="text-primary-400 shrink-0" />
|
||||
<span className="font-semibold text-small truncate">{event.title}</span>
|
||||
</div>
|
||||
<Button color="danger" size="sm" variant="flat" startContent={<Trash2 size={14} />} onPress={() => deleteEvent(event.id)}>
|
||||
L<EFBFBD>schen
|
||||
</Button>
|
||||
</div>
|
||||
<p className="text-small text-default-400">{event.description || 'Keine Beschreibung'}</p>
|
||||
<div className="flex items-center gap-2 text-tiny text-default-500">
|
||||
<Clock size={12} />
|
||||
{formatDate(event.startsAt)}
|
||||
</div>
|
||||
</CardContent>
|
||||
</Card>
|
||||
)) : (
|
||||
<div className="flex flex-col items-center gap-2 py-8 text-center text-small text-default-400">
|
||||
<CalendarDays size={24} />
|
||||
Keine Events
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Card className="border border-default-100 bg-default-50/20">
|
||||
<CardHeader className="px-5 pt-5 pb-0">
|
||||
<h3 className="text-base font-semibold">Neues Event</h3>
|
||||
</CardHeader>
|
||||
<CardContent className="flex flex-col gap-4 p-5">
|
||||
<Input
|
||||
label="Titel"
|
||||
placeholder="Event Name"
|
||||
value={eventDraft.title}
|
||||
onValueChange={(v) => setEventDraft((s) => ({ ...s, title: v }))}
|
||||
/>
|
||||
|
||||
<TextArea
|
||||
label="Beschreibung"
|
||||
placeholder="Event Beschreibung"
|
||||
value={eventDraft.description}
|
||||
onValueChange={(v) => setEventDraft((s) => ({ ...s, description: v }))}
|
||||
/>
|
||||
|
||||
<Input
|
||||
label="Channel ID"
|
||||
placeholder="Channel f<>r Erinnerungen"
|
||||
value={eventDraft.channelId}
|
||||
onValueChange={(v) => setEventDraft((s) => ({ ...s, channelId: v }))}
|
||||
/>
|
||||
|
||||
<Input
|
||||
label="Start (ISO)"
|
||||
type="datetime-local"
|
||||
placeholder="2024-12-24T18:00"
|
||||
value={eventDraft.startsAt}
|
||||
onValueChange={(v) => setEventDraft((s) => ({ ...s, startsAt: v }))}
|
||||
/>
|
||||
|
||||
<Button color="primary" startContent={<Plus size={16} />} onPress={saveEvent}>
|
||||
Event speichern
|
||||
</Button>
|
||||
</CardContent>
|
||||
</Card>
|
||||
</div>
|
||||
</SectionCard>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user