This commit is contained in:
2026-01-12 20:37:38 -06:00
parent 7694532d53
commit 9c2d516f9d
74 changed files with 1842 additions and 1842 deletions

View File

@@ -213,7 +213,7 @@ const AdminEventAttendance = () => {
if (loading) {
return (
<div className="flex items-center justify-center h-64">
<div className="text-var(--purple-lavender)">Loading event data...</div>
<div className="text-[var(--purple-lavender)]">Loading event data...</div>
</div>
);
}
@@ -221,8 +221,8 @@ const AdminEventAttendance = () => {
if (!event) {
return (
<div className="text-center py-12">
<p className="text-var(--purple-lavender) mb-4">Event not found</p>
<Button onClick={() => navigate('/admin/events')} className="bg-var(--purple-lavender) hover:bg-var(--purple-ink) text-white rounded-xl">
<p className="text-[var(--purple-lavender)] mb-4">Event not found</p>
<Button onClick={() => navigate('/admin/events')} className="bg-[var(--purple-lavender)] hover:bg-[var(--purple-ink)] text-white rounded-xl">
Back to Events
</Button>
</div>
@@ -237,24 +237,24 @@ const AdminEventAttendance = () => {
<Button
onClick={() => navigate('/admin/events')}
variant="outline"
className="border-var(--neutral-800) text-var(--purple-lavender) rounded-xl"
className="border-[var(--neutral-800)] text-[var(--purple-lavender)] rounded-xl"
style={{ fontFamily: "'Inter', sans-serif" }}
>
<ArrowLeft className="h-4 w-4 mr-2" />
Back to Events
</Button>
<div>
<h1 className="text-3xl font-semibold text-var(--purple-ink)" style={{ fontFamily: "'Inter', sans-serif" }}>
<h1 className="text-3xl font-semibold text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>
Event Attendance
</h1>
<p className="text-var(--purple-lavender) mt-1" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
<p className="text-[var(--purple-lavender)] mt-1" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
Manage RSVPs and track attendance for this event
</p>
</div>
</div>
<Button
onClick={exportToCSV}
className="bg-var(--green-light) hover:bg-var(--green-eucalyptus) text-white rounded-xl"
className="bg-[var(--green-light)] hover:bg-[var(--green-eucalyptus)] text-white rounded-xl"
style={{ fontFamily: "'Inter', sans-serif" }}
>
<Download className="h-4 w-4 mr-2" />
@@ -263,13 +263,13 @@ const AdminEventAttendance = () => {
</div>
{/* Event Details Card */}
<Card className="p-6 bg-background border-var(--neutral-800) rounded-xl">
<Card className="p-6 bg-background border-[var(--neutral-800)] rounded-xl">
<div className="flex items-start justify-between">
<div>
<h2 className="text-2xl font-semibold text-var(--purple-ink) mb-2" style={{ fontFamily: "'Inter', sans-serif" }}>
<h2 className="text-2xl font-semibold text-[var(--purple-ink)] mb-2" style={{ fontFamily: "'Inter', sans-serif" }}>
{event.title}
</h2>
<div className="flex flex-wrap gap-4 text-var(--purple-lavender)" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
<div className="flex flex-wrap gap-4 text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
<div className="flex items-center gap-2">
<Calendar className="h-4 w-4" />
<span>{moment(event.start_at).format('MMMM D, YYYY [at] h:mm A')}</span>
@@ -282,7 +282,7 @@ const AdminEventAttendance = () => {
)}
</div>
</div>
<Badge className={`${event.published ? 'bg-var(--green-light)' : 'bg-var(--neutral-800)'} text-white px-3 py-1`}>
<Badge className={`${event.published ? 'bg-[var(--green-light)]' : 'bg-[var(--neutral-800)]'} text-white px-3 py-1`}>
{event.published ? 'Published' : 'Draft'}
</Badge>
</div>
@@ -290,59 +290,59 @@ const AdminEventAttendance = () => {
{/* Statistics Cards */}
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-5 gap-4">
<Card className="p-4 bg-background border-var(--neutral-800) rounded-xl">
<Card className="p-4 bg-background border-[var(--neutral-800)] rounded-xl">
<div className="flex items-center gap-3">
<Users className="h-8 w-8 text-var(--purple-lavender)" />
<Users className="h-8 w-8 text-[var(--purple-lavender)]" />
<div>
<p className="text-sm text-var(--purple-lavender)" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>Total RSVPs</p>
<p className="text-2xl font-semibold text-var(--purple-ink)" style={{ fontFamily: "'Inter', sans-serif" }}>{stats.total}</p>
<p className="text-sm text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>Total RSVPs</p>
<p className="text-2xl font-semibold text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>{stats.total}</p>
</div>
</div>
</Card>
<Card className="p-4 bg-background border-var(--neutral-800) rounded-xl">
<Card className="p-4 bg-background border-[var(--neutral-800)] rounded-xl">
<div className="flex items-center gap-3">
<UserCheck className="h-8 w-8 text-var(--green-light)" />
<UserCheck className="h-8 w-8 text-[var(--green-light)]" />
<div>
<p className="text-sm text-var(--purple-lavender)" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>Yes</p>
<p className="text-2xl font-semibold text-var(--purple-ink)" style={{ fontFamily: "'Inter', sans-serif" }}>{stats.yesCount}</p>
<p className="text-sm text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>Yes</p>
<p className="text-2xl font-semibold text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>{stats.yesCount}</p>
</div>
</div>
</Card>
<Card className="p-4 bg-background border-var(--neutral-800) rounded-xl">
<Card className="p-4 bg-background border-[var(--neutral-800)] rounded-xl">
<div className="flex items-center gap-3">
<UserX className="h-8 w-8 text-var(--orange-soft)" />
<UserX className="h-8 w-8 text-[var(--orange-soft)]" />
<div>
<p className="text-sm text-var(--purple-lavender)" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>No</p>
<p className="text-2xl font-semibold text-var(--purple-ink)" style={{ fontFamily: "'Inter', sans-serif" }}>{stats.noCount}</p>
<p className="text-sm text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>No</p>
<p className="text-2xl font-semibold text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>{stats.noCount}</p>
</div>
</div>
</Card>
<Card className="p-4 bg-background border-var(--neutral-800) rounded-xl">
<Card className="p-4 bg-background border-[var(--neutral-800)] rounded-xl">
<div className="flex items-center gap-3">
<HelpCircle className="h-8 w-8 text-var(--gold-warm)" />
<HelpCircle className="h-8 w-8 text-[var(--gold-warm)]" />
<div>
<p className="text-sm text-var(--purple-lavender)" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>Maybe</p>
<p className="text-2xl font-semibold text-var(--purple-ink)" style={{ fontFamily: "'Inter', sans-serif" }}>{stats.maybeCount}</p>
<p className="text-sm text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>Maybe</p>
<p className="text-2xl font-semibold text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>{stats.maybeCount}</p>
</div>
</div>
</Card>
<Card className="p-4 bg-background border-var(--neutral-800) rounded-xl">
<Card className="p-4 bg-background border-[var(--neutral-800)] rounded-xl">
<div className="flex items-center gap-3">
<Check className="h-8 w-8 text-var(--purple-lavender)" />
<Check className="h-8 w-8 text-[var(--purple-lavender)]" />
<div>
<p className="text-sm text-var(--purple-lavender)" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>Attended</p>
<p className="text-2xl font-semibold text-var(--purple-ink)" style={{ fontFamily: "'Inter', sans-serif" }}>{stats.attendedCount}</p>
<p className="text-sm text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>Attended</p>
<p className="text-2xl font-semibold text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>{stats.attendedCount}</p>
</div>
</div>
</Card>
</div>
{/* Filters and Actions */}
<Card className="p-6 bg-background border-var(--neutral-800) rounded-xl">
<Card className="p-6 bg-background border-[var(--neutral-800)] rounded-xl">
<div className="space-y-4">
{/* Tab Filters */}
<div className="flex flex-wrap gap-2">
@@ -350,8 +350,8 @@ const AdminEventAttendance = () => {
onClick={() => setActiveTab('all')}
variant={activeTab === 'all' ? 'default' : 'outline'}
className={`rounded-xl ${activeTab === 'all'
? 'bg-var(--purple-lavender) hover:bg-var(--purple-ink) text-white'
: 'border-var(--neutral-800) text-var(--purple-lavender) hover:bg-var(--lavender-500)'
? 'bg-[var(--purple-lavender)] hover:bg-[var(--purple-ink)] text-white'
: 'border-[var(--neutral-800)] text-[var(--purple-lavender)] hover:bg-[var(--lavender-500)]'
}`}
style={{ fontFamily: "'Inter', sans-serif" }}
>
@@ -361,8 +361,8 @@ const AdminEventAttendance = () => {
onClick={() => setActiveTab('yes')}
variant={activeTab === 'yes' ? 'default' : 'outline'}
className={`rounded-xl ${activeTab === 'yes'
? 'bg-var(--green-light) hover:bg-var(--green-eucalyptus) text-white'
: 'border-var(--neutral-800) text-var(--purple-lavender) hover:bg-var(--lavender-500)'
? 'bg-[var(--green-light)] hover:bg-[var(--green-eucalyptus)] text-white'
: 'border-[var(--neutral-800)] text-[var(--purple-lavender)] hover:bg-[var(--lavender-500)]'
}`}
style={{ fontFamily: "'Inter', sans-serif" }}
>
@@ -372,8 +372,8 @@ const AdminEventAttendance = () => {
onClick={() => setActiveTab('no')}
variant={activeTab === 'no' ? 'default' : 'outline'}
className={`rounded-xl ${activeTab === 'no'
? 'bg-var(--orange-soft) hover:bg-var(--orange-rust) text-white'
: 'border-var(--neutral-800) text-var(--purple-lavender) hover:bg-var(--lavender-500)'
? 'bg-[var(--orange-soft)] hover:bg-[var(--orange-rust)] text-white'
: 'border-[var(--neutral-800)] text-[var(--purple-lavender)] hover:bg-[var(--lavender-500)]'
}`}
style={{ fontFamily: "'Inter', sans-serif" }}
>
@@ -383,8 +383,8 @@ const AdminEventAttendance = () => {
onClick={() => setActiveTab('maybe')}
variant={activeTab === 'maybe' ? 'default' : 'outline'}
className={`rounded-xl ${activeTab === 'maybe'
? 'bg-var(--gold-warm) hover:bg-var(--gold-soft) text-var(--purple-ink)'
: 'border-var(--neutral-800) text-var(--purple-lavender) hover:bg-var(--lavender-500)'
? 'bg-[var(--gold-warm)] hover:bg-[var(--gold-soft)] text-[var(--purple-ink)]'
: 'border-[var(--neutral-800)] text-[var(--purple-lavender)] hover:bg-[var(--lavender-500)]'
}`}
style={{ fontFamily: "'Inter', sans-serif" }}
>
@@ -395,26 +395,26 @@ const AdminEventAttendance = () => {
{/* Search and Bulk Actions */}
<div className="flex flex-wrap gap-3 items-center justify-between">
<div className="flex-1 min-w-[200px] max-w-md relative">
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-var(--purple-lavender)" />
<Search className="absolute left-3 top-1/2 -translate-y-1/2 h-4 w-4 text-[var(--purple-lavender)]" />
<Input
type="text"
placeholder="Search by name or email..."
value={searchQuery}
onChange={(e) => setSearchQuery(e.target.value)}
className="pl-10 border-var(--neutral-800) rounded-xl"
className="pl-10 border-[var(--neutral-800)] rounded-xl"
style={{ fontFamily: "'Nunito Sans', sans-serif" }}
/>
</div>
{selectedRsvps.size > 0 && (
<div className="flex gap-2">
<Badge className="bg-var(--purple-lavender) text-white px-3 py-1">
<Badge className="bg-[var(--purple-lavender)] text-white px-3 py-1">
{selectedRsvps.size} selected
</Badge>
<Button
onClick={() => handleBulkAttendance(true)}
disabled={saving}
className="bg-var(--green-light) hover:bg-var(--green-eucalyptus) text-white rounded-xl"
className="bg-[var(--green-light)] hover:bg-[var(--green-eucalyptus)] text-white rounded-xl"
style={{ fontFamily: "'Inter', sans-serif" }}
>
<Check className="h-4 w-4 mr-1" />
@@ -423,7 +423,7 @@ const AdminEventAttendance = () => {
<Button
onClick={() => handleBulkAttendance(false)}
disabled={saving}
className="bg-var(--orange-soft) hover:bg-var(--orange-rust) text-white rounded-xl"
className="bg-[var(--orange-soft)] hover:bg-[var(--orange-rust)] text-white rounded-xl"
style={{ fontFamily: "'Inter', sans-serif" }}
>
<X className="h-4 w-4 mr-1" />
@@ -436,10 +436,10 @@ const AdminEventAttendance = () => {
</Card>
{/* RSVP Table */}
<Card className="bg-background border-var(--neutral-800) rounded-xl overflow-hidden">
<Card className="bg-background border-[var(--neutral-800)] rounded-xl overflow-hidden">
<div className="overflow-x-auto">
<table className="w-full">
<thead className="bg-var(--lavender-500) border-b border-var(--neutral-800)">
<thead className="bg-[var(--lavender-500)] border-b border-[var(--neutral-800)]">
<tr>
<th className="px-4 py-3 text-left">
<Checkbox
@@ -447,19 +447,19 @@ const AdminEventAttendance = () => {
onCheckedChange={handleSelectAll}
/>
</th>
<th className="px-4 py-3 text-left text-sm font-semibold text-var(--purple-ink)" style={{ fontFamily: "'Inter', sans-serif" }}>
<th className="px-4 py-3 text-left text-sm font-semibold text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>
Name
</th>
<th className="px-4 py-3 text-left text-sm font-semibold text-var(--purple-ink)" style={{ fontFamily: "'Inter', sans-serif" }}>
<th className="px-4 py-3 text-left text-sm font-semibold text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>
Email
</th>
<th className="px-4 py-3 text-left text-sm font-semibold text-var(--purple-ink)" style={{ fontFamily: "'Inter', sans-serif" }}>
<th className="px-4 py-3 text-left text-sm font-semibold text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>
RSVP Status
</th>
<th className="px-4 py-3 text-center text-sm font-semibold text-var(--purple-ink)" style={{ fontFamily: "'Inter', sans-serif" }}>
<th className="px-4 py-3 text-center text-sm font-semibold text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>
Attendance
</th>
<th className="px-4 py-3 text-left text-sm font-semibold text-var(--purple-ink)" style={{ fontFamily: "'Inter', sans-serif" }}>
<th className="px-4 py-3 text-left text-sm font-semibold text-[var(--purple-ink)]" style={{ fontFamily: "'Inter', sans-serif" }}>
Attended At
</th>
</tr>
@@ -467,26 +467,26 @@ const AdminEventAttendance = () => {
<tbody>
{filteredRsvps.length > 0 ? (
filteredRsvps.map((rsvp) => (
<tr key={rsvp.user_id} className="border-b border-var(--neutral-800) hover:bg-var(--lavender-500) transition-colors">
<tr key={rsvp.user_id} className="border-b border-[var(--neutral-800)] hover:bg-[var(--lavender-500)] transition-colors">
<td className="px-4 py-3">
<Checkbox
checked={selectedRsvps.has(rsvp.user_id)}
onCheckedChange={() => handleSelectRsvp(rsvp.user_id)}
/>
</td>
<td className="px-4 py-3 text-sm text-var(--purple-ink)" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
<td className="px-4 py-3 text-sm text-[var(--purple-ink)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
{rsvp.user_name}
</td>
<td className="px-4 py-3 text-sm text-var(--purple-lavender)" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
<td className="px-4 py-3 text-sm text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
{rsvp.user_email}
</td>
<td className="px-4 py-3">
<Badge
className={`${rsvp.rsvp_status === 'yes'
? 'bg-var(--green-light)'
? 'bg-[var(--green-light)]'
: rsvp.rsvp_status === 'no'
? 'bg-var(--orange-soft)'
: 'bg-var(--gold-warm) text-var(--purple-ink)'
? 'bg-[var(--orange-soft)]'
: 'bg-[var(--gold-warm)] text-[var(--purple-ink)]'
} text-white text-xs px-2 py-1`}
>
{rsvp.rsvp_status.toUpperCase()}
@@ -498,7 +498,7 @@ const AdminEventAttendance = () => {
onClick={() => handleIndividualAttendance(rsvp.user_id, false)}
disabled={saving}
size="sm"
className="bg-var(--green-light) hover:bg-var(--green-eucalyptus) text-white rounded-lg min-w-[120px]"
className="bg-[var(--green-light)] hover:bg-[var(--green-eucalyptus)] text-white rounded-lg min-w-[120px]"
style={{ fontFamily: "'Inter', sans-serif" }}
>
<Check className="h-3 w-3 mr-1" />
@@ -510,7 +510,7 @@ const AdminEventAttendance = () => {
disabled={saving}
size="sm"
variant="outline"
className="border-var(--neutral-800) text-var(--purple-lavender) hover:bg-var(--green-light) hover:text-white hover:border-var(--green-light) rounded-lg min-w-[120px]"
className="border-[var(--neutral-800)] text-[var(--purple-lavender)] hover:bg-[var(--green-light)] hover:text-white hover:border-[var(--green-light)] rounded-lg min-w-[120px]"
style={{ fontFamily: "'Inter', sans-serif" }}
>
<X className="h-3 w-3 mr-1" />
@@ -518,7 +518,7 @@ const AdminEventAttendance = () => {
</Button>
)}
</td>
<td className="px-4 py-3 text-sm text-var(--purple-lavender)" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
<td className="px-4 py-3 text-sm text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
{rsvp.attended_at ? moment(rsvp.attended_at).format('MMM D, YYYY h:mm A') : '-'}
</td>
</tr>
@@ -526,7 +526,7 @@ const AdminEventAttendance = () => {
) : (
<tr>
<td colSpan="6" className="px-4 py-12 text-center">
<p className="text-var(--purple-lavender)" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
<p className="text-[var(--purple-lavender)]" style={{ fontFamily: "'Nunito Sans', sans-serif" }}>
{searchQuery ? 'No RSVPs match your search' : 'No RSVPs for this filter'}
</p>
</td>