import 'package:flutter/material.dart'; import 'package:flame/game.dart'; import 'utils/audio_manager.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_database/firebase_database.dart'; class StatsPage extends StatefulWidget { const StatsPage({Key? key}) : super(key: key); @override State createState() => _StatsPageState(); } class _StatsPageState extends State { Future>> _getScores() async { final user = FirebaseAuth.instance.currentUser; if (user == null) { print('No user logged in'); return []; } try { final ref = FirebaseDatabase.instance.ref(); final snapshot = await ref.child('scores').get(); print('Raw Firebase response: ${snapshot.value}'); if (snapshot.exists && snapshot.value != null) { List> scores = []; final values = snapshot.value as Map; values.forEach((key, value) { if (value is Map && value['userId'] == user.uid) { scores.add({ 'level': value['level'] ?? '-', 'category': value['category'] ?? '-', 'time': value['time'] ?? '-', 'score': value['score'] ?? 0, 'timestamp': value['timestamp'] ?? '', }); } }); print('Processed scores: $scores'); // Sort by timestamp descending scores.sort( (a, b) => (b['timestamp'] ?? '').compareTo(a['timestamp'] ?? '')); return scores; } print('No data found in snapshot'); return []; } catch (e) { print('Error fetching scores: $e'); return []; } } @override void initState() { super.initState(); } @override Widget build(BuildContext context) { return Scaffold( body: Container( decoration: const BoxDecoration( image: DecorationImage( image: AssetImage('assets/images/background.jpg'), fit: BoxFit.cover, ), ), child: Stack( children: [ // Tombol X untuk kembali Positioned( top: 10, right: 10, child: IconButton( icon: Image.asset( 'assets/icons/exit.png', width: 40, height: 40, ), onPressed: () { AudioManager.playClickSound(); Navigator.pop(context); }, ), ), // Konten Utama Center( child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ Container( decoration: BoxDecoration( image: DecorationImage( image: AssetImage('assets/icons/title.png'), fit: BoxFit.cover, ), borderRadius: BorderRadius.circular(10), ), padding: const EdgeInsets.symmetric( horizontal: 24, vertical: 15), child: const Text( 'STATISTIK', style: TextStyle( fontSize: 25, fontFamily: 'Bestime', color: Color.fromARGB(225, 193, 138, 83), ), ), ), const SizedBox(height: 40), // Tabel Statistik Container( margin: const EdgeInsets.symmetric(horizontal: 20), padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: Color.fromARGB(255, 182, 134, 86).withOpacity(0.9), borderRadius: BorderRadius.circular(10), border: Border.all( color: Color.fromARGB(255, 65, 44, 23), width: 2, ), ), child: FutureBuilder>>( future: _getScores(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return Center( child: CircularProgressIndicator( color: Color.fromARGB(255, 65, 44, 23), ), ); } if (snapshot.hasError) { print('Error in FutureBuilder: ${snapshot.error}'); return Center( child: Text( 'Terjadi kesalahan saat memuat data', style: TextStyle( fontFamily: 'Bestime', fontSize: 14, color: Color.fromARGB(255, 65, 44, 23), ), ), ); } final List> data = snapshot.data ?? []; print('Data in builder: $data'); // Debug print // Daftar atribut yang akan jadi baris (header vertikal) final List attributes = [ 'Level', 'Kategori', 'Waktu', 'Skor' ]; // Key mapping ke data final List keys = [ 'level', 'category', 'time', 'score' ]; // Jika tidak ada data, tampilkan pesan kosong if (data.isEmpty) { return Center( child: Text( 'Tidak ada data', style: TextStyle( fontFamily: 'Bestime', fontSize: 14, color: Color.fromARGB(255, 103, 75, 47), ), ), ); } // Responsive width double cellWidth = 110; double headerWidth = 90; double tableWidth = headerWidth + (data.length * cellWidth); double maxWidth = MediaQuery.of(context).size.width - 32; // padding if (tableWidth < maxWidth) tableWidth = maxWidth; return SingleChildScrollView( scrollDirection: Axis.horizontal, child: Container( width: tableWidth, child: Table( border: TableBorder.all( color: Color.fromARGB(255, 65, 44, 23), width: 1, ), defaultVerticalAlignment: TableCellVerticalAlignment.middle, columnWidths: { 0: FixedColumnWidth(headerWidth), for (int i = 1; i <= data.length; i++) i: FixedColumnWidth(cellWidth), }, children: [ // Baris judul (No, User 1, User 2, ...) TableRow( decoration: BoxDecoration( color: Color.fromARGB(255, 65, 44, 23), ), children: [ TableCell( child: Padding( padding: EdgeInsets.all(8.0), child: Text( '', style: TextStyle( color: Colors.white, fontFamily: 'Bestime', fontSize: 14, ), ), ), ), ...List.generate( data.length, (i) => TableCell( child: Padding( padding: EdgeInsets.all(8.0), child: Text( '${i + 1}', textAlign: TextAlign.center, style: TextStyle( color: Colors.white, fontFamily: 'Bestime', fontSize: 14, ), ), ), ), ), ], ), // Baris-baris atribut ...List.generate( attributes.length, (rowIdx) => TableRow( children: [ // Header baris (atribut) TableCell( child: Padding( padding: EdgeInsets.all(8.0), child: Text( attributes[rowIdx], style: TextStyle( fontFamily: 'Bestime', fontSize: 14, color: Color.fromARGB( 255, 65, 44, 23), ), ), ), ), // Data user untuk atribut ini ...List.generate(data.length, (colIdx) { final value = data[colIdx][keys[rowIdx]] ?? '-'; return TableCell( child: Padding( padding: EdgeInsets.all(8.0), child: Text( value.toString(), textAlign: TextAlign.center, style: TextStyle( fontFamily: 'Bestime', fontSize: 14, color: Color.fromARGB( 255, 103, 75, 47), ), ), ), ); }), ], ), ), ], ), ), ); }, ), ), ], ), ), ], ), ), ); } } // Game kosong sebagai background class BackgroundGame extends FlameGame { @override Color backgroundColor() => Color.fromARGB(255, 255, 255, 255); @override Future onLoad() async { // Bisa ditambahkan komponen lain jika diperlukan } }