Files
blackcanyontickets/src/components/calendar/EventList.tsx
dzinesco 0956873381 feat: Enhance calendar component with glassmorphism design and modular architecture
- Refactored Calendar.tsx into modular component structure
- Added glassmorphism theming with CSS custom properties
- Implemented reusable calendar subcomponents:
  - CalendarGrid: Month view with improved day/event display
  - CalendarHeader: Navigation and view controls
  - EventList: List view for events
  - TrendingEvents: Location-based trending events
  - UpcomingEvents: Quick upcoming events preview
- Enhanced responsive design for mobile devices
- Added Playwright testing framework for automated testing
- Updated Docker development commands in CLAUDE.md
- Improved accessibility and user experience

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-07-13 12:07:33 -06:00

78 lines
2.9 KiB
TypeScript

import React from 'react';
import { EventListProps } from './types';
import { groupEventsByDate, sortEventsByDate, getFutureEvents, getRelativeDateText } from './utils';
import { EventCard } from './EventCard';
/**
* Event list component showing events grouped by date
*/
export const EventList: React.FC<EventListProps> = ({
events,
onEventClick,
showDistance = false
}) => {
const futureEvents = getFutureEvents(events);
const sortedEvents = sortEventsByDate(futureEvents);
const groupedEvents = groupEventsByDate(sortedEvents);
const sortedDates = Object.keys(groupedEvents).sort((a, b) => new Date(a).getTime() - new Date(b).getTime());
if (sortedEvents.length === 0) {
return (
<div className="p-3 md:p-6">
<div className="text-center py-16">
<div className="w-24 h-24 mx-auto mb-6 rounded-full flex items-center justify-center"
style={{ background: 'linear-gradient(to bottom right, var(--ui-bg-secondary), var(--ui-bg-elevated))' }}>
<svg className="w-12 h-12" style={{ color: 'var(--ui-text-muted)' }} fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="1.5" d="M8 7V3m8 4V3m-9 8h10M5 21h14a2 2 0 002-2V7a2 2 0 00-2-2H5a2 2 0 00-2 2v12a2 2 0 002 2z"></path>
</svg>
</div>
<h3 className="text-xl font-semibold mb-2" style={{ color: 'var(--ui-text-primary)' }}>
No Upcoming Events
</h3>
<p style={{ color: 'var(--ui-text-secondary)' }}>
Check back later for new events or adjust your filters.
</p>
</div>
</div>
);
}
return (
<div className="p-3 md:p-6">
<div className="space-y-6">
{sortedDates.map(dateKey => {
const date = new Date(dateKey);
const dateEvents = groupedEvents[dateKey];
const dateText = getRelativeDateText(date);
return (
<div key={dateKey} className="animate-fade-in-up">
{/* Date Header */}
<div className="mb-4">
<h3 className="text-lg font-semibold mb-1" style={{ color: 'var(--ui-text-primary)' }}>
{dateText}
</h3>
<div className="w-16 h-1 rounded-full"
style={{ background: 'linear-gradient(to right, rgb(37, 99, 235), rgb(147, 51, 234))' }}>
</div>
</div>
{/* Events for this date */}
<div className="grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
{dateEvents.map(event => (
<EventCard
key={event.id}
event={event}
onClick={onEventClick}
variant="list"
showDistance={showDistance}
/>
))}
</div>
</div>
);
})}
</div>
</div>
);
};