// =========================================================================== // FILE: lib/ui/admin/admin_screen.dart // =========================================================================== import 'package:flutter/material.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:intl/intl.dart'; import 'package:provider/provider.dart'; import '../../core/theme_manager.dart'; class AdminScreen extends StatelessWidget { const AdminScreen({super.key}); @override Widget build(BuildContext context) { final theme = context.watch().currentColors; return Scaffold( backgroundColor: theme.background, appBar: AppBar( title: Text("DASHBOARD ADMIN πŸ•΅οΈβ€β™‚οΈ", style: TextStyle(color: theme.text, fontWeight: FontWeight.w900, letterSpacing: 2)), backgroundColor: theme.background, iconTheme: IconThemeData(color: theme.text), elevation: 0, ), body: StreamBuilder( stream: FirebaseFirestore.instance.collection('leaderboard').orderBy('lastActive', descending: true).snapshots(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return Center(child: CircularProgressIndicator(color: theme.playerBlue)); } if (!snapshot.hasData || snapshot.data!.docs.isEmpty) { return Center(child: Text("Nessun giocatore trovato nel database.", style: TextStyle(color: theme.text))); } final docs = snapshot.data!.docs; return ListView.builder( padding: const EdgeInsets.all(16), itemCount: docs.length, itemBuilder: (context, index) { var data = docs[index].data() as Map; String name = data['name'] ?? 'Fantasma'; int level = data['level'] ?? 1; int xp = data['xp'] ?? 0; int wins = data['wins'] ?? 0; String platform = data['platform'] ?? 'Sconosciuta'; String ip = data['ip'] ?? 'N/D'; String city = data['city'] ?? 'N/D'; String appVersion = data['appVersion'] ?? 'N/D'; String deviceModel = data['deviceModel'] ?? 'N/D'; int playtimeSec = data['playtime'] ?? 0; int hours = playtimeSec ~/ 3600; int minutes = (playtimeSec % 3600) ~/ 60; String playtimeStr = "${hours.toString().padLeft(2, '0')}:${minutes.toString().padLeft(2, '0')}"; // Recupero della data di creazione dell'account DateTime? created; if (data['accountCreated'] != null) created = (data['accountCreated'] as Timestamp).toDate(); DateTime? lastActive; if (data['lastActive'] != null) lastActive = (data['lastActive'] as Timestamp).toDate(); String createdStr = created != null ? DateFormat('dd MMM yyyy - HH:mm').format(created) : 'N/D'; String lastActiveStr = lastActive != null ? DateFormat('dd MMM yyyy - HH:mm').format(lastActive) : 'N/D'; IconData platformIcon = Icons.device_unknown; if (platform == 'iOS' || platform == 'macOS') platformIcon = Icons.apple; if (platform == 'Android') platformIcon = Icons.android; if (platform == 'Windows') platformIcon = Icons.window; return Card( color: theme.text.withOpacity(0.05), elevation: 0, margin: const EdgeInsets.only(bottom: 12), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15), side: BorderSide(color: theme.gridLine.withOpacity(0.3)) ), child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(name, style: TextStyle(color: theme.playerBlue, fontSize: 22, fontWeight: FontWeight.w900)), GestureDetector( onTap: () { showDialog( context: context, builder: (ctx) => AlertDialog( backgroundColor: theme.background, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(20), side: BorderSide(color: theme.playerBlue, width: 2), ), title: Text("Info Connessione", style: TextStyle(color: theme.text, fontWeight: FontWeight.bold)), content: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text("🌐 IP: $ip", style: TextStyle(color: theme.text, fontSize: 16)), const SizedBox(height: 10), Text("πŸ“ CittΓ : $city", style: TextStyle(color: theme.text, fontSize: 16)), const SizedBox(height: 10), Text("πŸ“± OS: $platform", style: TextStyle(color: theme.text, fontSize: 16)), const SizedBox(height: 10), Text("πŸ’» Hardware: $deviceModel", style: TextStyle(color: theme.text, fontSize: 16)), ], ), actions: [ TextButton( onPressed: () => Navigator.pop(ctx), child: Text("CHIUDI", style: TextStyle(color: theme.playerRed, fontWeight: FontWeight.bold)), ) ], ), ); }, child: Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( color: theme.text.withOpacity(0.1), shape: BoxShape.circle, ), child: Icon(platformIcon, color: theme.text.withOpacity(0.8), size: 24), ), ), ], ), const SizedBox(height: 8), Row( children: [ Text("Liv. $level", style: TextStyle(color: theme.playerRed, fontWeight: FontWeight.bold, fontSize: 14)), const SizedBox(width: 10), Text("$xp XP", style: TextStyle(color: theme.text.withOpacity(0.7), fontSize: 12)), const SizedBox(width: 10), Text("Vittorie: $wins", style: TextStyle(color: Colors.amber.shade700, fontWeight: FontWeight.bold, fontSize: 12)), const Spacer(), Icon(Icons.timer, color: theme.text.withOpacity(0.6), size: 16), const SizedBox(width: 4), Text(playtimeStr, style: TextStyle(color: theme.text, fontWeight: FontWeight.bold, fontSize: 14)), ], ), const Padding( padding: EdgeInsets.symmetric(vertical: 8.0), child: Divider(), ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ FittedBox(fit: BoxFit.scaleDown, child: Text("Registrato il:", style: TextStyle(color: theme.text.withOpacity(0.5), fontSize: 10))), FittedBox(fit: BoxFit.scaleDown, child: Text(createdStr, style: TextStyle(color: theme.text, fontSize: 12, fontWeight: FontWeight.bold))), ], ), ), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.center, children: [ FittedBox(fit: BoxFit.scaleDown, child: Text("Versione App:", style: TextStyle(color: theme.text.withOpacity(0.5), fontSize: 10))), FittedBox(fit: BoxFit.scaleDown, child: Text("v. $appVersion", style: TextStyle(color: theme.playerBlue, fontSize: 12, fontWeight: FontWeight.bold))), ], ), ), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ FittedBox(fit: BoxFit.scaleDown, child: Text("Ultimo Accesso:", style: TextStyle(color: theme.text.withOpacity(0.5), fontSize: 10))), FittedBox(fit: BoxFit.scaleDown, child: Text(lastActiveStr, style: TextStyle(color: Colors.green, fontSize: 12, fontWeight: FontWeight.bold))), ], ), ), ], ) ], ), ), ); }, ); } ), ); } }