import 'package:siro_driver/constant/currency.dart'; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import '../../constant/colors.dart'; import '../../../controller/gamification/leaderboard_controller.dart'; import '../widgets/ui/siro_ui.dart'; class LeaderboardPage extends StatelessWidget { LeaderboardPage({super.key}); final LeaderboardController controller = Get.put(LeaderboardController()); @override Widget build(BuildContext context) { return Scaffold( body: GetBuilder(builder: (lc) { if (lc.isLoading) { return const SiroLoading(); } if (lc.currentLeaderboard.isEmpty) { return SiroEmptyState( icon: Icons.leaderboard_rounded, title: 'Leaderboard'.tr, message: 'No data yet'.tr, ); } return CustomScrollView( physics: const BouncingScrollPhysics(), slivers: [ SliverAppBar( expandedHeight: 200, pinned: true, foregroundColor: Colors.white, backgroundColor: AppColor.primaryColor, flexibleSpace: FlexibleSpaceBar( centerTitle: true, titlePadding: const EdgeInsets.symmetric( horizontal: 48, vertical: 14), title: Text('Leaderboard'.tr, overflow: TextOverflow.ellipsis, style: const TextStyle( color: Colors.white, fontWeight: FontWeight.bold, fontSize: 17)), background: Stack(fit: StackFit.expand, children: [ // كان التدرّج نيفي ← أحمر قانٍ، وهو لون لا يوجد في // هوية سيرو ويقرأه المستخدم إشارةَ خطر لا إنجاز. Container( decoration: BoxDecoration( gradient: SiroUi.brandGradient(context))), PositionedDirectional( end: -40, top: -20, child: Icon(Icons.leaderboard_rounded, size: 180, color: Colors.white.withValues(alpha: 0.05))), // Top 3 podium if (lc.currentLeaderboard.length >= 3) Positioned( bottom: 50, left: 0, right: 0, child: _buildPodium(lc)), ]), ), ), // Tab bar SliverToBoxAdapter( child: Container( margin: const EdgeInsets.fromLTRB(16, 14, 16, 0), padding: const EdgeInsets.all(4), decoration: BoxDecoration( color: SiroUi.border(context).withValues(alpha: 0.5), borderRadius: BorderRadius.circular(14)), child: Row(children: [ _tab(context, 'Trips'.tr, Icons.local_taxi_rounded, 0, lc), _tab(context, 'Earnings'.tr, Icons.monetization_on_rounded, 1, lc), ]), )), // List SliverPadding( padding: const EdgeInsets.fromLTRB(16, 14, 16, 32), sliver: SliverList( delegate: SliverChildBuilderDelegate( (ctx, i) { if (i >= lc.currentLeaderboard.length) return null; return _buildRow( ctx, lc.currentLeaderboard[i], lc.selectedTab == 1); }, childCount: lc.currentLeaderboard.length, ), )), ]); }), ); } Widget _buildPodium(LeaderboardController lc) { final top3 = lc.currentLeaderboard.take(3).toList(); return Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.end, children: [ if (top3.length > 1) _podiumItem(top3[1], 2, const Color(0xFFC0C0C0)), if (top3.isNotEmpty) _podiumItem(top3[0], 1, AppColor.gold), if (top3.length > 2) _podiumItem(top3[2], 3, AppColor.bronze), ]); } Widget _podiumItem(LeaderboardEntry e, int rank, Color color) { return Padding( padding: const EdgeInsets.symmetric(horizontal: 8), child: Column(mainAxisSize: MainAxisSize.min, children: [ CircleAvatar( radius: rank == 1 ? 22 : 18, backgroundColor: color.withValues(alpha: 0.3), child: Text(_getRankEmoji(rank), style: TextStyle(fontSize: rank == 1 ? 22 : 16))), const SizedBox(height: 4), Text(e.name.length > 8 ? '${e.name.substring(0, 8)}...' : e.name, style: TextStyle( color: Colors.white, fontSize: 10, fontWeight: e.isCurrentUser ? FontWeight.bold : FontWeight.normal)), ])); } Widget _tab(BuildContext context, String label, IconData icon, int idx, LeaderboardController lc) { final selected = lc.selectedTab == idx; final accent = SiroUi.interactive(context); return Expanded( child: GestureDetector( onTap: () => lc.changeTab(idx), child: AnimatedContainer( duration: const Duration(milliseconds: 200), padding: const EdgeInsets.symmetric(vertical: 10), decoration: BoxDecoration( color: selected ? SiroUi.surface(context) : Colors.transparent, borderRadius: BorderRadius.circular(10), border: selected ? Border.all(color: accent.withValues(alpha: 0.35)) : null), child: Row(mainAxisAlignment: MainAxisAlignment.center, children: [ Icon(icon, size: 16, color: selected ? accent : SiroUi.subtle(context)), const SizedBox(width: 6), Flexible( child: Text(label, overflow: TextOverflow.ellipsis, style: TextStyle( fontSize: 13, fontWeight: FontWeight.w600, color: selected ? accent : SiroUi.subtle(context))), ), ]), ), )); } Widget _buildRow(BuildContext context, LeaderboardEntry e, bool isEarnings) { final accent = SiroUi.interactive(context); final rankColor = e.rank == 1 ? AppColor.gold : e.rank == 2 ? const Color(0xFFC0C0C0) : e.rank == 3 ? AppColor.bronze : SiroUi.subtle(context); return SiroCard( margin: const EdgeInsets.only(bottom: 8), padding: const EdgeInsets.all(12), accent: e.isCurrentUser ? accent : null, child: Row(children: [ // Rank Container( width: 32, height: 32, decoration: BoxDecoration( color: rankColor.withValues(alpha: 0.15), borderRadius: BorderRadius.circular(8)), child: Center( child: e.rank <= 3 ? Text(_getRankEmoji(e.rank), style: const TextStyle(fontSize: 16)) : Text('${e.rank}', style: TextStyle( fontSize: 12, fontWeight: FontWeight.bold, color: rankColor)))), const SizedBox(width: 12), // Avatar CircleAvatar( radius: 17, backgroundColor: accent.withValues(alpha: 0.12), child: Text(e.name.isNotEmpty ? e.name[0] : '?', style: TextStyle( fontWeight: FontWeight.bold, color: accent))), const SizedBox(width: 12), // Name Expanded( child: Column(crossAxisAlignment: CrossAxisAlignment.start, children: [ Row(children: [ Flexible( child: Text(e.name, overflow: TextOverflow.ellipsis, style: Theme.of(context).textTheme.bodyMedium?.copyWith( fontWeight: e.isCurrentUser ? FontWeight.bold : FontWeight.w500)), ), if (e.isCurrentUser) ...[ const SizedBox(width: 6), SiroTag('You'.tr, color: accent), ], ]), ])), const SizedBox(width: 8), // Value Text( isEarnings ? '${e.value.toStringAsFixed(0)} ${CurrencyHelper.currency}' : '${e.value.toInt()} ${'Rides'.tr}', style: Theme.of(context) .textTheme .bodyMedium ?.copyWith(fontWeight: FontWeight.w800)), ]), ); } String _getRankEmoji(int rank) => rank == 1 ? '🥇' : rank == 2 ? '🥈' : '🥉'; }