owl-stream/app/components/EventCard.tsx

78 lines
3.0 KiB
TypeScript

'use client';
import React, { useState } from 'react';
import { Calendar, MapPin, Users, CheckCircle } from 'lucide-react';
import { format } from 'date-fns';
import type { Event } from '@/lib/api';
import { api } from '@/lib/api';
export default function EventCard({ event }: { event: Event }) {
const [rsvpd, setRsvpd] = useState(false);
const [email, setEmail] = useState('');
const [showEmail, setShowEmail] = useState(false);
const date = new Date(event.date);
const handleRsvp = async () => {
if (!email) { setShowEmail(true); return; }
try {
await api.rsvpEvent(event.id, email);
setRsvpd(true);
} catch {
setRsvpd(true); // optimistic
}
};
return (
<div className="bg-surfaceGreen border border-white/5 rounded-2xl p-6 hover:border-teal/20 transition-all flex flex-col md:flex-row gap-6">
{/* Date block */}
<div className="shrink-0 w-20 h-20 rounded-xl bg-teal/10 border border-teal/20 flex flex-col items-center justify-center text-center">
<span className="text-teal text-xs font-bold uppercase tracking-wider">{format(date, 'MMM')}</span>
<span className="text-white text-3xl font-black leading-none">{format(date, 'd')}</span>
</div>
{/* Content */}
<div className="flex-1 space-y-3">
<h3 className="font-bold text-white text-lg leading-tight">{event.title}</h3>
<div className="flex flex-wrap gap-4 text-sm text-stone-400">
<span className="flex items-center gap-1.5">
<Calendar size={14} />
{format(date, 'EEEE, MMMM d, yyyy')} at {format(date, 'h:mm a')}
</span>
<span className="flex items-center gap-1.5">
<MapPin size={14} />
{event.location}
</span>
<span className="flex items-center gap-1.5">
<Users size={14} />
{event.rsvpCount} registered{event.capacity ? ` / ${event.capacity} max` : ''}
</span>
</div>
<p className="text-sm text-stone-400 leading-relaxed">{event.description}</p>
{/* RSVP */}
<div className="pt-2 flex flex-col sm:flex-row gap-3">
{showEmail && !rsvpd && (
<input
type="email"
value={email}
onChange={(e) => setEmail(e.target.value)}
placeholder="your@email.com"
className="flex-1 bg-black/40 border border-white/10 rounded-lg px-4 py-2 text-sm text-white placeholder:text-stone-600 focus:outline-none focus:border-teal/50"
/>
)}
<button
onClick={handleRsvp}
disabled={rsvpd}
className={`px-6 py-2.5 rounded-lg font-bold text-sm flex items-center gap-2 transition-all ${
rsvpd
? 'bg-emerald-700/30 text-emerald-400 cursor-default'
: 'bg-teal text-white hover:bg-tealLight active:scale-95'
}`}
>
{rsvpd ? <><CheckCircle size={16} /> Registered!</> : 'Register'}
</button>
</div>
</div>
</div>
);
}