/// Widget: Member Card Widget /// /// Displays a user's membership card with tier-specific styling. /// Shows member information, points, QR code, and tier badge. /// /// Supports three tiers: Diamond, Platinum, Gold library; import 'package:flutter/material.dart'; import 'package:qr_flutter/qr_flutter.dart'; import 'package:worker/core/theme/colors.dart'; import 'package:worker/features/home/domain/entities/member_card.dart'; /// Member Card Widget /// /// Renders a beautiful gradient card displaying member information. /// The gradient and styling changes based on the membership tier. class MemberCardWidget extends StatelessWidget { /// Member card data final MemberCard memberCard; const MemberCardWidget({ super.key, required this.memberCard, }); @override Widget build(BuildContext context) { return Container( margin: const EdgeInsets.all(16), height: 200, decoration: BoxDecoration( gradient: _getGradientForTier(memberCard.tier), borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.2), blurRadius: 10, offset: const Offset(0, 4), ), ], ), child: Padding( padding: const EdgeInsets.all(20), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Header Row: Branding and Valid Until Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ // Branding Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'EUROTILE', style: TextStyle( color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold, letterSpacing: 1.2, ), ), const SizedBox(height: 4), Text( memberCard.memberType.displayName, style: TextStyle( color: Colors.white.withOpacity(0.9), fontSize: 11, fontWeight: FontWeight.w500, letterSpacing: 0.8, ), ), ], ), // Valid Until Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ Text( 'Valid through', style: TextStyle( color: Colors.white.withOpacity(0.8), fontSize: 11, ), ), const SizedBox(height: 2), Text( _formatDate(memberCard.validUntil), style: const TextStyle( color: Colors.white, fontSize: 14, fontWeight: FontWeight.w500, ), ), ], ), ], ), const Spacer(), // Footer Row: Member Info and QR Code Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.end, children: [ // Member Info Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( memberCard.name, style: const TextStyle( color: Colors.white, fontSize: 18, fontWeight: FontWeight.w600, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), const SizedBox(height: 4), Text( 'CLASS: ${memberCard.tier.displayName}', style: TextStyle( color: Colors.white.withOpacity(0.9), fontSize: 12, fontWeight: FontWeight.w600, ), ), const SizedBox(height: 2), Text( 'Points: ${_formatPoints(memberCard.points)}', style: TextStyle( color: Colors.white.withOpacity(0.9), fontSize: 12, fontWeight: FontWeight.w600, ), ), ], ), ), // QR Code Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(8), ), child: QrImageView( data: memberCard.qrData, version: QrVersions.auto, size: 60, backgroundColor: Colors.white, ), ), ], ), ], ), ), ); } /// Get gradient for tier LinearGradient _getGradientForTier(MemberTier tier) { switch (tier) { case MemberTier.diamond: return AppColors.diamondGradient; case MemberTier.platinum: return AppColors.platinumGradient; case MemberTier.gold: return AppColors.goldGradient; } } /// Format date to DD/MM/YYYY String _formatDate(DateTime date) { return '${date.day.toString().padLeft(2, '0')}/${date.month.toString().padLeft(2, '0')}/${date.year}'; } /// Format points with thousands separator String _formatPoints(int points) { return points.toString().replaceAllMapped( RegExp(r'(\d{1,3})(?=(\d{3})+(?!\d))'), (Match m) => '${m[1]},', ); } }