import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../../core/responsive/responsive_layout.dart'; import '../../../core/theme/app_typography.dart'; import '../../../core/theme/theme_extensions.dart'; import '../../../services/clubs/club_models.dart'; import '../../../services/clubs/club_providers.dart'; import 'widgets/club_monogram.dart'; /// Read-only preview destination for a MotorSignal Club. /// Displays authoritative identity and metadata without CLUB-2C membership mutations. class ClubPreviewScreen extends ConsumerWidget { final String clubId; const ClubPreviewScreen({ super.key, required this.clubId, }); @override Widget build(BuildContext context, WidgetRef ref) { final colors = context.motorColors; final theme = Theme.of(context); final clubAsync = ref.watch(clubDetailProvider(clubId)); final memberAsync = ref.watch(currentMemberProvider(clubId)); return Scaffold( appBar: AppBar( title: const Text( 'Club', style: TextStyle( fontFamily: AppTypography.fontHeadline, fontWeight: FontWeight.w700, ), ), ), body: SafeArea( child: clubAsync.when( data: (club) { if (club == null) { return Center( child: Padding( padding: const EdgeInsets.all(24.0), child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.shield_outlined, size: 48, color: colors.warningAmber), const SizedBox(height: 16), const Text( 'Club Not Found', style: TextStyle( fontFamily: AppTypography.fontHeadline, fontSize: 18, fontWeight: FontWeight.w700, ), ), const SizedBox(height: 8), Text( 'This club may have been archived or does not exist.', textAlign: TextAlign.center, style: TextStyle( fontFamily: AppTypography.fontBody, fontSize: 13, color: theme.colorScheme.onSurfaceVariant, ), ), ], ), ), ); } if (club.isArchived) { return Center( child: Padding( padding: const EdgeInsets.all(24.0), child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.archive_outlined, size: 48, color: colors.warningAmber), const SizedBox(height: 16), const Text( 'Club Archived', style: TextStyle( fontFamily: AppTypography.fontHeadline, fontSize: 18, fontWeight: FontWeight.w700, ), ), const SizedBox(height: 8), Text( 'This club has been archived by leadership and is no longer active.', textAlign: TextAlign.center, style: TextStyle( fontFamily: AppTypography.fontBody, fontSize: 13, color: theme.colorScheme.onSurfaceVariant, ), ), ], ), ), ); } final myMembership = memberAsync.value; return ResponsiveLayout( builder: (context, responsive) { return Center( child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 750), child: SingleChildScrollView( padding: const EdgeInsets.all(18.0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // Club Hero Identity Card _buildHeroCard(context, club, myMembership, colors, theme), const SizedBox(height: 18), // Description Card _buildDescriptionCard(context, club, colors, theme), const SizedBox(height: 18), // Metadata Card (Region, Focus, Dates) _buildMetadataCard(context, club, colors, theme), ], ), ), ), ); }, ); }, loading: () => Center( child: CircularProgressIndicator( valueColor: AlwaysStoppedAnimation(colors.cyberCyan), ), ), error: (err, _) => Center( child: Padding( padding: const EdgeInsets.all(24.0), child: Column( mainAxisSize: MainAxisSize.min, children: [ Icon(Icons.shield_outlined, size: 36, color: colors.warningAmber), const SizedBox(height: 12), const Text( 'Club Unavailable', style: TextStyle( fontFamily: AppTypography.fontHeadline, fontWeight: FontWeight.w700, ), ), const SizedBox(height: 8), Text( 'Unable to display this club at this time.', textAlign: TextAlign.center, style: TextStyle( fontFamily: AppTypography.fontBody, fontSize: 13, color: theme.colorScheme.onSurfaceVariant, ), ), ], ), ), ), ), ), ); } Widget _buildHeroCard( BuildContext context, Club club, ClubMember? member, MotorSignalThemeColors colors, ThemeData theme, ) { return Container( padding: const EdgeInsets.all(20.0), decoration: BoxDecoration( color: colors.surfaceContainer, borderRadius: BorderRadius.circular(16), border: Border.all(color: colors.outlineVariant, width: 0.8), ), child: Column( children: [ ClubMonogram(name: club.name, size: 68, fontSize: 26), const SizedBox(height: 14), Text( club.name, textAlign: TextAlign.center, style: const TextStyle( fontFamily: AppTypography.fontHeadline, fontSize: 20, fontWeight: FontWeight.w800, ), ), const SizedBox(height: 4), Text( '@${club.slug}', style: TextStyle( fontFamily: AppTypography.fontTelemetry, fontSize: 14, fontWeight: FontWeight.w600, color: colors.cyberCyan, ), ), const SizedBox(height: 14), Wrap( spacing: 8, runSpacing: 6, alignment: WrapAlignment.center, children: [ _buildPill( icon: Icons.people_outline, label: '${club.memberCount} ${club.memberCount == 1 ? 'member' : 'members'}', colors: colors, theme: theme, ), _buildPill( icon: club.admissionPolicy == ClubAdmissionPolicy.open ? Icons.lock_open_outlined : Icons.how_to_reg_outlined, label: club.admissionPolicy.label, colors: colors, theme: theme, tintColor: colors.cyberCyan, ), _buildPill( icon: club.visibility == ClubVisibility.public ? Icons.public : Icons.visibility_off_outlined, label: club.visibility.label, colors: colors, theme: theme, ), if (member != null && member.isActive && (member.role == ClubRole.owner || member.role == ClubRole.admin)) _buildPill( icon: Icons.verified_user_outlined, label: 'ROLE: ${member.role.label.toUpperCase()}', colors: colors, theme: theme, tintColor: colors.launchGreen, ), ], ), ], ), ); } Widget _buildDescriptionCard( BuildContext context, Club club, MotorSignalThemeColors colors, ThemeData theme, ) { return Container( padding: const EdgeInsets.all(18.0), decoration: BoxDecoration( color: colors.surfaceContainer, borderRadius: BorderRadius.circular(14), border: Border.all(color: colors.outlineVariant, width: 0.8), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'About the Club', style: TextStyle( fontFamily: AppTypography.fontHeadline, fontSize: 13, fontWeight: FontWeight.w700, letterSpacing: 0.2, color: colors.cyberCyan, ), ), const SizedBox(height: 10), Text( club.description.isNotEmpty ? club.description : 'No club description provided by leadership.', style: TextStyle( fontFamily: AppTypography.fontBody, fontSize: 13.5, color: club.description.isNotEmpty ? theme.colorScheme.onSurface : theme.colorScheme.onSurfaceVariant, height: 1.4, ), ), ], ), ); } Widget _buildMetadataCard( BuildContext context, Club club, MotorSignalThemeColors colors, ThemeData theme, ) { return Container( padding: const EdgeInsets.all(18.0), decoration: BoxDecoration( color: colors.surfaceContainer, borderRadius: BorderRadius.circular(14), border: Border.all(color: colors.outlineVariant, width: 0.8), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Club Details', style: TextStyle( fontFamily: AppTypography.fontHeadline, fontSize: 13, fontWeight: FontWeight.w700, letterSpacing: 0.2, color: colors.cyberCyan, ), ), const SizedBox(height: 12), _buildDetailRow( icon: Icons.location_on_outlined, title: 'Home Region', value: club.homeRegion?.trim().isNotEmpty == true ? club.homeRegion! : 'Global / Not Specified', colors: colors, theme: theme, ), const Divider(height: 18), _buildDetailRow( icon: Icons.two_wheeler_outlined, title: 'Motorcycle Focus', value: club.motorcycleFocus?.trim().isNotEmpty == true ? club.motorcycleFocus! : 'All Motorcycles & Disciplines', colors: colors, theme: theme, ), const Divider(height: 18), _buildDetailRow( icon: Icons.calendar_today_outlined, title: 'Established', value: '${club.createdAt.year}-${club.createdAt.month.toString().padLeft(2, '0')}-${club.createdAt.day.toString().padLeft(2, '0')}', colors: colors, theme: theme, ), ], ), ); } Widget _buildDetailRow({ required IconData icon, required String title, required String value, required MotorSignalThemeColors colors, required ThemeData theme, }) { return Row( children: [ Icon(icon, size: 18, color: colors.cyberCyan), const SizedBox(width: 12), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: TextStyle( fontFamily: AppTypography.fontBody, fontSize: 11.5, color: theme.colorScheme.onSurfaceVariant, ), ), const SizedBox(height: 2), Text( value, style: const TextStyle( fontFamily: AppTypography.fontHeadline, fontSize: 13.5, fontWeight: FontWeight.w600, ), ), ], ), ), ], ); } Widget _buildPill({ required IconData icon, required String label, required MotorSignalThemeColors colors, required ThemeData theme, Color? tintColor, }) { final effectiveColor = tintColor ?? theme.colorScheme.onSurfaceVariant; return Container( padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 5), decoration: BoxDecoration( color: colors.surfaceContainerHighest.withValues(alpha: 0.6), borderRadius: BorderRadius.circular(8), border: Border.all(color: colors.outlineVariant.withValues(alpha: 0.6), width: 0.6), ), child: Row( mainAxisSize: MainAxisSize.min, children: [ Icon(icon, size: 13, color: effectiveColor), const SizedBox(width: 5), Text( label, style: TextStyle( fontFamily: AppTypography.fontHeadline, fontSize: 11.5, fontWeight: FontWeight.w600, color: effectiveColor, ), ), ], ), ); } }