import 'package:flutter/material.dart'; import 'package:firebase_database/firebase_database.dart'; class CardDetailPage extends StatefulWidget { final String uid; final String name; const CardDetailPage({super.key, required this.uid, required this.name}); @override State createState() => _CardDetailPageState(); } class _CardDetailPageState extends State { // 🎨 THEME WARNA GLOBAL static const Color primaryColor = Color(0xff4E7C34); static const Color secondaryColor = Color(0xff6A994E); static const Color backgroundColor = Color(0xffFFF8E8); final List steps = [ 'Membaca doa wudhu', 'Berkumur-kumur', 'Membersihkan hidung', 'Membasuh muka', 'Membasuh tangan kanan & kiri', 'Mengusap kepala', 'Mengusap telinga', 'Membasuh kaki kanan & kiri', ]; final Map values = {}; int lastSavedScore = -1; @override void initState() { super.initState(); for (final step in steps) { values[step] = null; } FirebaseDatabase.instance.ref("hasil/${widget.uid}").onValue.listen(( event, ) { final data = event.snapshot.value as Map?; if (data != null) { for (int i = 0; i < steps.length; i++) { values[steps[i]] = data["step${i + 1}"]; } setState(() {}); int correct = values.values.where((v) => v == true).length; int total = values.length; int newScore = ((correct / total) * 100).round(); if (newScore != lastSavedScore) { lastSavedScore = newScore; FirebaseDatabase.instance.ref("cards/${widget.uid}").update({ "nilai": newScore, }); FirebaseDatabase.instance.ref("history/${widget.uid}").push().set({ "nilai": newScore, "timestamp": DateTime.now().millisecondsSinceEpoch, }); } } }); } Future _resetData() async { final confirm = await showDialog( context: context, builder: (context) => AlertDialog( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(16)), title: const Text("Reset Data"), content: const Text("Yakin ingin mengulang penilaian dari awal?"), actions: [ TextButton( onPressed: () => Navigator.pop(context, false), child: const Text("Batal"), ), TextButton( onPressed: () => Navigator.pop(context, true), child: const Text("Reset", style: TextStyle(color: Colors.red)), ), ], ), ); if (confirm == true) { await FirebaseDatabase.instance.ref("hasil/${widget.uid}").remove(); await FirebaseDatabase.instance.ref("cards/${widget.uid}").update({ "nilai": 0, }); setState(() { for (final step in steps) { values[step] = null; } lastSavedScore = -1; }); ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text("Data berhasil direset"), backgroundColor: primaryColor, ), ); } } int get correctCount => values.values.where((v) => v == true).length; int get wrongCount => values.values.where((v) => v == false).length; int get score { final total = values.length; if (total == 0) return 0; return ((correctCount / total) * 100).round(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: backgroundColor, // 🔥 APPBAR appBar: AppBar( title: const Text("Nilai Praktik Wudhu"), backgroundColor: primaryColor, foregroundColor: Colors.white, centerTitle: true, ), // 🔽 RESET BUTTON bottomNavigationBar: Padding( padding: const EdgeInsets.all(16), child: Container( decoration: BoxDecoration( gradient: const LinearGradient( colors: [primaryColor, secondaryColor], ), borderRadius: BorderRadius.circular(14), ), child: ElevatedButton.icon( onPressed: _resetData, icon: const Icon(Icons.refresh, color: Colors.white), label: const Text( "Reset Penilaian", style: TextStyle(color: Colors.white), ), style: ElevatedButton.styleFrom( backgroundColor: Colors.transparent, shadowColor: Colors.transparent, padding: const EdgeInsets.symmetric(vertical: 14), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(14), ), ), ), ), ), body: Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 20), child: Column( children: [ // 🔥 HEADER Container( width: double.infinity, padding: const EdgeInsets.all(16), decoration: BoxDecoration( gradient: LinearGradient( colors: [backgroundColor, secondaryColor.withOpacity(0.2)], ), borderRadius: BorderRadius.circular(16), ), child: Row( children: [ Container( width: 50, height: 50, decoration: const BoxDecoration( shape: BoxShape.circle, color: primaryColor, ), child: const Icon(Icons.person, color: Colors.white), ), const SizedBox(width: 12), Expanded( child: Text( widget.name, style: const TextStyle( fontSize: 18, fontWeight: FontWeight.bold, color: primaryColor, ), ), ), ], ), ), const SizedBox(height: 20), // 🔥 LIST STEP Expanded( child: ListView.separated( itemCount: steps.length, separatorBuilder: (_, __) => const SizedBox(height: 12), itemBuilder: (context, index) { final step = steps[index]; final value = values[step]; final statusText = value == null ? 'Belum' : value ? 'Benar' : 'Salah'; final statusColor = value == null ? Colors.black54 : value ? primaryColor : Colors.red; final icon = value == null ? Icons.circle_outlined : value ? Icons.check_circle : Icons.cancel; final iconColor = value == null ? Colors.black26 : value ? primaryColor : Colors.red; final iconBg = value == null ? const Color(0xffe5e7eb) : value ? const Color(0xffdff5e1) : const Color(0xffffe2e2); return Container( padding: const EdgeInsets.symmetric( horizontal: 16, vertical: 14, ), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), ), child: Row( children: [ Container( width: 32, height: 32, decoration: BoxDecoration( shape: BoxShape.circle, color: iconBg, ), child: Icon(icon, color: iconColor, size: 18), ), const SizedBox(width: 12), Expanded( child: Text( step, style: const TextStyle( fontSize: 15, fontWeight: FontWeight.w600, ), ), ), Text( statusText, style: TextStyle( fontWeight: FontWeight.bold, color: statusColor, ), ), ], ), ); }, ), ), const SizedBox(height: 16), // 🔥 SCORE CARD Container( padding: const EdgeInsets.all(20), decoration: BoxDecoration( gradient: const LinearGradient( colors: [primaryColor, secondaryColor], ), borderRadius: BorderRadius.circular(16), ), child: Column( children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text( 'Benar', style: TextStyle(color: Colors.white70), ), Text( '$correctCount', style: const TextStyle(color: Colors.white), ), ], ), const SizedBox(height: 8), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ const Text( 'Salah', style: TextStyle(color: Colors.white70), ), Text( '$wrongCount', style: const TextStyle(color: Colors.white), ), ], ), const SizedBox(height: 16), const Divider(color: Colors.white24), const SizedBox(height: 16), Text( 'Nilai: $score', style: const TextStyle( color: Colors.white, fontSize: 24, fontWeight: FontWeight.bold, ), ), ], ), ), ], ), ), ); } }