TKK_E32230502/lib/screen/akun.dart

444 lines
18 KiB
Dart

import 'package:flutter/material.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'dashboard.dart';
import 'history.dart';
import 'notifikasi.dart';
import '../widgets/whatsapp_notification.dart';
import '../widgets/fade_in_up.dart'; // Import animasi
import 'package:firebase_database/firebase_database.dart';
class AkunPage extends StatelessWidget {
const AkunPage({super.key});
@override
Widget build(BuildContext context) {
final user = FirebaseAuth.instance.currentUser;
// Gunakan displayName jika ada, jika tidak gunakan bagian depan email, jika tidak ada gunakan default
String displayName = user?.displayName ?? "Pengguna SafeBite";
if (user?.displayName == null && user?.email != null) {
displayName = user!.email!.split('@')[0];
}
String emailOrPhone = user?.email ?? "0812xxxxxx";
return Scaffold(
body: Container(
width: double.infinity,
height: double.infinity,
decoration: const BoxDecoration(
gradient: LinearGradient(
colors: [
Colors.white,
Color(0xFFE3F2FD),
Color(0xFF42A5F5),
Color(0xFF1565C0),
],
begin: Alignment.topCenter,
end: Alignment.bottomCenter,
),
),
child: SafeArea(
child: Column(
children: [
const SizedBox(height: 10),
// 1. PROFILE INFO SECTION (Animated & Centered)
Padding(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 20),
child: FadeInUp(
delay: 150,
child: Container(
width: double.infinity,
decoration: const BoxDecoration(
color: Colors.transparent,
),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
// Animated Icon
TweenAnimationBuilder(
tween: Tween<double>(begin: 0.9, end: 1.0),
duration: const Duration(seconds: 2),
curve: Curves.easeInOut,
onEnd: () {}, // No-op to allow repeat if wrapped
builder: (context, double value, child) {
return Transform.scale(
scale: value,
child: child,
);
},
child: Container(
padding: const EdgeInsets.all(15),
decoration: BoxDecoration(
color: const Color(0xFF1565C0).withOpacity(0.1),
shape: BoxShape.circle,
),
child: const Icon(
Icons.account_circle_rounded,
size: 80,
color: Color(0xFF1565C0),
),
),
),
const SizedBox(height: 15),
const Text(
"Account",
style: TextStyle(
fontSize: 22,
fontWeight: FontWeight.bold,
color: Color(0xFF1565C0),
letterSpacing: 1.2,
),
),
const Text(
"SafeBite User Profile",
style: TextStyle(
fontSize: 13,
color: Colors.grey,
),
),
],
),
),
),
),
// INFORMASI PROJECT DAN AKUN DENGAN ANIMASI
Expanded(
child: SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 20, vertical: 25),
child: Column(
children: [
// KARTU INFORMASI PROJECT
FadeInUp(
delay: 200,
child: Container(
width: double.infinity,
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.04),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: Column(
children: [
Container(
padding: const EdgeInsets.all(12),
decoration: BoxDecoration(
color: const Color(0xFFE3F2FD),
shape: BoxShape.circle,
),
child: const Icon(Icons.verified_user_rounded, color: Color(0xFF1565C0), size: 35),
),
const SizedBox(height: 15),
const Text(
"SafeBite Project",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Color(0xFF1565C0),
),
),
const SizedBox(height: 5),
Text(
"Alat Pendeteksi Kandungan Formalin\npada Makanan secara Real-Time",
textAlign: TextAlign.center,
style: TextStyle(
fontSize: 13,
color: Colors.grey.shade600,
height: 1.4,
),
),
],
),
),
),
const SizedBox(height: 20),
// KARTU DETAIL AKUN
FadeInUp(
delay: 300,
child: Container(
width: double.infinity,
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
color: Colors.black.withOpacity(0.04),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text(
"Detail Login",
style: TextStyle(
fontSize: 16,
fontWeight: FontWeight.bold,
color: Colors.black87,
),
),
const SizedBox(height: 15),
Row(
children: [
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: Colors.grey.shade100,
borderRadius: BorderRadius.circular(10),
),
child: const Icon(Icons.email_outlined, color: Colors.black54),
),
const SizedBox(width: 15),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const Text("Email", style: TextStyle(fontSize: 12, color: Colors.grey)),
const SizedBox(height: 2),
Text(
emailOrPhone,
style: const TextStyle(fontSize: 15, fontWeight: FontWeight.bold, color: Colors.black87),
),
],
),
),
],
),
const SizedBox(height: 15),
GestureDetector(
onTap: () => _handleResetPpm(context),
child: Container(
color: Colors.transparent,
child: Row(
children: [
Container(
padding: const EdgeInsets.all(10),
decoration: BoxDecoration(
color: const Color(0xFFE3F2FD),
borderRadius: BorderRadius.circular(10),
),
child: const Icon(Icons.restart_alt_rounded, color: Color(0xFF1565C0)),
),
const SizedBox(width: 15),
const Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Reset PPM", style: TextStyle(fontSize: 12, color: Colors.grey)),
SizedBox(height: 2),
Text(
"Reset Sensor PPM ke 0.0",
style: TextStyle(fontSize: 15, fontWeight: FontWeight.bold, color: Color(0xFF1565C0)),
),
],
),
),
],
),
),
),
],
),
),
),
const SizedBox(height: 60),
// TOMBOL LOGOUT
FadeInUp(
delay: 400,
child: GestureDetector(
onTap: () => _handleLogout(context),
child: Container(
width: double.infinity,
padding: const EdgeInsets.symmetric(vertical: 16),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(15),
border: Border.all(color: Colors.redAccent.withOpacity(0.5), width: 1.5),
boxShadow: [
BoxShadow(
color: Colors.redAccent.withOpacity(0.05),
blurRadius: 10,
offset: const Offset(0, 4),
),
],
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Icon(Icons.logout_rounded, color: Colors.redAccent, size: 22),
SizedBox(width: 10),
Text(
"Log Out",
style: TextStyle(
color: Colors.redAccent,
fontSize: 16,
fontWeight: FontWeight.bold,
letterSpacing: 0.5,
),
),
],
),
),
),
),
const SizedBox(height: 20),
],
),
),
),
],
),
),
),
bottomNavigationBar: BottomNavigationBar(
currentIndex: 3, // Highlight index Akun (0: Home, 1: History, 2: Notif, 3: Akun)
selectedItemColor: const Color(0xFF1565C0),
unselectedItemColor: Colors.grey,
type: BottomNavigationBarType.fixed, // Penting jika item > 3
onTap: (index) {
if (index == 0) {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const DashboardPage()),
);
} else if (index == 1) {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const RiwayatPage()),
);
} else if (index == 2) {
Navigator.pushReplacement(
context,
MaterialPageRoute(builder: (context) => const NotifikasiPage()),
);
}
},
items: const [
BottomNavigationBarItem(icon: Icon(Icons.home), label: "Beranda"),
BottomNavigationBarItem(icon: Icon(Icons.history), label: "History"),
BottomNavigationBarItem(icon: Icon(Icons.notifications), label: "Notif"),
BottomNavigationBarItem(icon: Icon(Icons.person), label: "Saya"),
],
),
);
} void _handleResetPpm(BuildContext context) async {
bool confirm = await showDialog(
context: context,
builder: (context) => AlertDialog(
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(15),
),
title: Row(
children: const [
Icon(Icons.restart_alt_rounded, color: Color(0xFF1565C0)),
SizedBox(width: 10),
Text("Reset PPM Sensor"),
],
),
content: const Text(
"Apakah Anda yakin ingin mereset nilai PPM sensor menjadi 0.0?",
style: TextStyle(fontSize: 14),
),
actions: [
TextButton(
onPressed: () => Navigator.pop(context, false),
child: const Text("Batal", style: TextStyle(color: Colors.grey)),
),
TextButton(
onPressed: () => Navigator.pop(context, true),
child: const Text(
"Reset",
style: TextStyle(color: Colors.red, fontWeight: FontWeight.bold),
),
),
],
),
) ??
false;
if (confirm) {
try {
await FirebaseDatabase.instance.ref().child("kontrol/reset").set(1);
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
const SnackBar(
content: Row(
children: [
Icon(Icons.check_circle_outline, color: Colors.white),
SizedBox(width: 10),
Expanded(
child: Text("Perintah Reset dikirim! Kalibrasi sensor dimulai..."),
),
],
),
backgroundColor: Colors.green,
behavior: SnackBarBehavior.floating,
),
);
}
} catch (e) {
if (context.mounted) {
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
content: Row(
children: [
const Icon(Icons.error_outline, color: Colors.white),
const SizedBox(width: 10),
Expanded(child: Text("Gagal mereset PPM: $e")),
],
),
backgroundColor: Colors.redAccent,
behavior: SnackBarBehavior.floating,
),
);
}
}
}
}
void _handleLogout(BuildContext context) async {
bool confirm = await showDialog(
context: context,
builder: (context) => AlertDialog(
title: const Text("Konfirmasi Logout"),
content: const Text("Apakah Anda yakin ingin keluar dari akun ini?"),
actions: [
TextButton(
onPressed: () => Navigator.pop(context, false),
child: const Text("Batal", style: TextStyle(color: Colors.grey)),
),
TextButton(
onPressed: () => Navigator.pop(context, true),
child: const Text("Keluar", style: TextStyle(color: Colors.red, fontWeight: FontWeight.bold)),
),
],
),
) ??
false;
if (confirm) {
WhatsAppNotificationService().stopListening();
await FirebaseAuth.instance.signOut();
if (context.mounted) {
Navigator.pushNamedAndRemoveUntil(context, '/welcome', (route) => false);
}
}
}
}