import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:intl/intl.dart'; import '../../domain/event.dart'; import 'countdown_timer.dart'; /// Material 3 card representing a single [Event] in the events list. /// /// Tap navigates to `/events/:id`. Visual emphasis is given to the title, /// the countdown chip, and the registration headcount. class EventCard extends StatelessWidget { const EventCard({super.key, required this.event}); final Event event; @override Widget build(BuildContext context) { final theme = Theme.of(context); final scheme = theme.colorScheme; final dateLabel = DateFormat('EEE, MMM d ยท h:mm a').format(event.date); final isFull = event.teamsRegistered >= event.maxTeams && event.maxTeams > 0; return Card( clipBehavior: Clip.antiAlias, margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 8), child: InkWell( onTap: () => context.go('/events/${event.id}'), child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: Text( event.title, style: theme.textTheme.titleLarge?.copyWith( fontWeight: FontWeight.w700, ), ), ), const SizedBox(width: 12), CountdownTimer(target: event.date), ], ), const SizedBox(height: 8), Row( children: [ _CategoryChip(category: event.category), if (event.isCancelled) ...[ const SizedBox(width: 8), _CancelledChip(scheme: scheme), ], ], ), const SizedBox(height: 12), _IconRow( icon: Icons.calendar_today_outlined, color: scheme.onSurfaceVariant, child: Text( dateLabel, style: theme.textTheme.bodyMedium?.copyWith( color: scheme.onSurfaceVariant, ), ), ), const SizedBox(height: 6), _IconRow( icon: Icons.place_outlined, color: scheme.onSurfaceVariant, child: Text( event.location, style: theme.textTheme.bodyMedium?.copyWith( color: scheme.onSurfaceVariant, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), ), const SizedBox(height: 12), Row( children: [ Icon(Icons.groups_outlined, size: 18, color: scheme.primary), const SizedBox(width: 6), Text( '${event.teamsRegistered} / ${event.maxTeams} teams', style: theme.textTheme.titleSmall?.copyWith( color: scheme.primary, fontWeight: FontWeight.w600, ), ), const Spacer(), if (isFull) Text( 'Preferred count reached', style: theme.textTheme.labelSmall?.copyWith( color: scheme.tertiary, ), ), ], ), ], ), ), ), ); } } class _IconRow extends StatelessWidget { const _IconRow({ required this.icon, required this.color, required this.child, }); final IconData icon; final Color color; final Widget child; @override Widget build(BuildContext context) { return Row( crossAxisAlignment: CrossAxisAlignment.center, children: [ Icon(icon, size: 16, color: color), const SizedBox(width: 6), Expanded(child: child), ], ); } } class _CancelledChip extends StatelessWidget { const _CancelledChip({required this.scheme}); final ColorScheme scheme; @override Widget build(BuildContext context) { return Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), decoration: BoxDecoration( color: scheme.errorContainer, borderRadius: BorderRadius.circular(999), ), child: Text( 'Cancelled', style: Theme.of(context).textTheme.labelSmall?.copyWith( color: scheme.onErrorContainer, fontWeight: FontWeight.w700, ), ), ); } } class _CategoryChip extends StatelessWidget { const _CategoryChip({required this.category}); final EventCategory category; static const Color _tournamentColor = Color(0xFF8B30C8); static const Color _pickupColor = Color(0xFF26A69A); @override Widget build(BuildContext context) { final isTournament = category == EventCategory.tournament; final color = isTournament ? _tournamentColor : _pickupColor; final label = isTournament ? 'TOURNAMENT' : 'PICK-UP'; final icon = isTournament ? Icons.emoji_events_outlined : Icons.sports_soccer; return Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), decoration: BoxDecoration( color: color.withValues(alpha: 0.18), borderRadius: BorderRadius.circular(999), border: Border.all(color: color.withValues(alpha: 0.55)), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon(icon, size: 13, color: color), const SizedBox(width: 4), Text( label, style: Theme.of(context).textTheme.labelSmall?.copyWith( color: color, fontWeight: FontWeight.w800, letterSpacing: 0.8, ), ), ], ), ); } }