TKK_E32231651/lib/dashboard.dart

482 lines
16 KiB
Dart

import 'package:flutter/material.dart';
import 'cek_sensor.dart';
import 'history.dart';
import 'about.dart';
import 'profile.dart';
import 'login_screen.dart';
import 'pengaturan.dart';
import 'package:shared_preferences/shared_preferences.dart';
class DashboardScreen extends StatefulWidget {
const DashboardScreen({super.key});
@override
State<DashboardScreen> createState() => _DashboardScreenState();
}
class _DashboardScreenState extends State<DashboardScreen> {
String name = "User";
String email = "";
String? imageName;
int _imageVersion = 0;
final String baseUrl = "http://192.168.100.9/kopikaocare_api/uploads/";
@override
void initState() {
super.initState();
loadProfile();
}
Future<void> loadProfile() async {
final prefs = await SharedPreferences.getInstance();
setState(() {
name = prefs.getString('name') ?? 'User';
email = prefs.getString('email') ?? '';
imageName = prefs.getString('image');
_imageVersion++;
});
}
String getImageUrl() {
if (imageName == null || imageName!.isEmpty) return '';
return "$baseUrl$imageName?t=${DateTime.now().millisecondsSinceEpoch}";
}
Widget menuCard(
BuildContext context, String title, String gifPath, Widget page) {
return GestureDetector(
onTap: () async {
await Navigator.push(
context,
MaterialPageRoute(builder: (context) => page),
);
await loadProfile();
},
child: Container(
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(20),
boxShadow: [
BoxShadow(
blurRadius: 15,
color: Colors.red.withOpacity(0.15),
offset: const Offset(0, 8),
),
],
border: Border.all(
color: Colors.red.withOpacity(0.1),
width: 1,
),
),
padding: const EdgeInsets.all(20),
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Image.asset(gifPath, height: 90),
const SizedBox(height: 15),
Text(
title,
style: const TextStyle(
fontSize: 15,
fontWeight: FontWeight.w600,
color: Color(0xff2d2d2d),
),
),
// HAPUS TANDA PANAH DI SINI
],
),
),
);
}
void showLogoutDialog() {
showDialog(
context: context,
builder: (context) {
return AlertDialog(
backgroundColor: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(20),
),
title: const Text("Logout"),
content: const Text("Apakah anda ingin logout?"),
actions: [
TextButton(
child: const Text("Tidak"),
onPressed: () => Navigator.pop(context),
),
ElevatedButton(
style: ElevatedButton.styleFrom(
backgroundColor: Colors.red,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
),
child: const Text("Ya"),
onPressed: () async {
final prefs = await SharedPreferences.getInstance();
await prefs.clear();
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (context) => const LoginScreen()),
(route) => false,
);
},
),
],
);
},
);
}
Widget profileImage(double radius, {bool withGlow = false}) {
final imageUrl = getImageUrl();
Widget avatar;
if (imageUrl.isNotEmpty) {
avatar = CircleAvatar(
key: ValueKey(_imageVersion),
radius: radius - 2,
backgroundImage: NetworkImage(imageUrl),
onBackgroundImageError: (exception, stackTrace) {
print('❌ Error loading image: $exception');
},
);
} else {
avatar = CircleAvatar(
radius: radius - 2,
backgroundColor: Colors.grey[300],
child: Icon(Icons.person, size: radius, color: Colors.grey[600]),
);
}
if (withGlow) {
return Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
blurRadius: 20,
color: Colors.red.withOpacity(0.4),
offset: const Offset(0, 4),
),
],
border: Border.all(
color: Colors.white,
width: 3,
),
),
child: avatar,
);
}
return avatar;
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: const Color(0xffeeeeee),
appBar: AppBar(
title: const Text(
'Dashboard',
style: TextStyle(
fontWeight: FontWeight.bold,
letterSpacing: 0.5,
),
),
backgroundColor: Colors.red,
foregroundColor: Colors.white,
elevation: 0,
flexibleSpace: Container(
decoration: const BoxDecoration(
borderRadius: BorderRadius.only(
bottomLeft: Radius.circular(20),
bottomRight: Radius.circular(20),
),
),
),
),
drawer: Drawer(
child: Container(
color: Colors.white,
child: SafeArea(
child: Column(
children: [
Container(
width: double.infinity,
padding:
const EdgeInsets.symmetric(vertical: 40, horizontal: 20),
decoration: BoxDecoration(
gradient: LinearGradient(
begin: Alignment.topLeft,
end: Alignment.bottomRight,
colors: [
Colors.red.shade700,
Colors.red.shade500,
],
),
borderRadius: const BorderRadius.only(
bottomLeft: Radius.circular(30),
bottomRight: Radius.circular(30),
),
),
child: Column(
children: [
profileImage(50, withGlow: true),
const SizedBox(height: 15),
Text(
name,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Colors.white,
letterSpacing: 0.5,
),
),
const SizedBox(height: 8),
Container(
padding: const EdgeInsets.symmetric(
horizontal: 12, vertical: 4),
decoration: BoxDecoration(
color: Colors.white.withOpacity(0.2),
borderRadius: BorderRadius.circular(20),
),
child: Text(
email.isEmpty ? 'Email belum diisi' : email,
style: const TextStyle(
fontSize: 13,
color: Colors.white,
),
),
),
const SizedBox(height: 20),
ElevatedButton.icon(
onPressed: () async {
Navigator.pop(context);
await Navigator.push(
context,
MaterialPageRoute(
builder: (context) => const ProfileScreen()),
);
await loadProfile();
},
icon: const Icon(Icons.edit, size: 18),
label: const Text('Edit Profile'),
style: ElevatedButton.styleFrom(
backgroundColor: Colors.white,
foregroundColor: Colors.red,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(30),
),
elevation: 0,
),
),
],
),
),
const Spacer(),
Container(
margin: const EdgeInsets.all(20),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(15),
border: Border.all(
color: Colors.red.withOpacity(0.2),
),
),
child: ListTile(
leading: Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.red.withOpacity(0.1),
borderRadius: BorderRadius.circular(12),
),
child:
const Icon(Icons.logout, color: Colors.red, size: 20),
),
title: const Text(
'Logout',
style: TextStyle(
fontWeight: FontWeight.w600,
color: Color(0xff2d2d2d),
),
),
onTap: () {
Navigator.pop(context);
showLogoutDialog();
},
),
),
const SizedBox(height: 20),
],
),
),
),
),
body: SafeArea(
child: Padding(
padding: const EdgeInsets.all(20),
child: Column(
children: [
// Welcome Banner Modern dengan Foto Profil
Container(
width: double.infinity,
padding: const EdgeInsets.all(20),
decoration: BoxDecoration(
color: Colors.white,
borderRadius: BorderRadius.circular(25),
boxShadow: [
BoxShadow(
blurRadius: 20,
color: Colors.red.withOpacity(0.1),
offset: const Offset(0, 8),
),
],
border: Border.all(
color: Colors.red.withOpacity(0.1),
width: 1,
),
),
child: Row(
children: [
// Foto Profil dengan efek glow
Container(
decoration: BoxDecoration(
shape: BoxShape.circle,
boxShadow: [
BoxShadow(
blurRadius: 15,
color: Colors.red.withOpacity(0.3),
offset: const Offset(0, 4),
),
],
),
child: profileImage(35),
),
const SizedBox(width: 15),
// Teks Welcome
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
children: [
const Text(
"Halo, ",
style: TextStyle(
fontSize: 18,
color: Color(0xff666666),
),
),
Text(
name,
style: const TextStyle(
fontSize: 20,
fontWeight: FontWeight.bold,
color: Color(0xff2d2d2d),
),
),
const Text(
"!",
style: TextStyle(
fontSize: 18,
color: Color(0xff666666),
),
),
],
),
const SizedBox(height: 4),
const Text(
"Selamat datang di Kopikaocare",
style: TextStyle(
fontSize: 13,
color: Color(0xff888888),
),
),
],
),
),
// Icon futuristik
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.red.withOpacity(0.1),
borderRadius: BorderRadius.circular(15),
),
child: const Icon(
Icons.rocket_launch_rounded,
color: Colors.red,
size: 24,
),
),
],
),
),
const SizedBox(height: 30),
// Menu Layanan dengan efek futuristik
Container(
padding: const EdgeInsets.symmetric(horizontal: 5),
child: Row(
children: [
Container(
padding: const EdgeInsets.all(8),
decoration: BoxDecoration(
color: Colors.red.withOpacity(0.1),
borderRadius: BorderRadius.circular(12),
),
child: const Icon(Icons.grid_view_rounded,
color: Colors.red, size: 20),
),
const SizedBox(width: 12),
const Text(
"Menu Layanan",
style: TextStyle(
fontSize: 18,
fontWeight: FontWeight.bold,
color: Color(0xff2d2d2d),
),
),
const Spacer(),
Container(
height: 2,
width: 30,
decoration: BoxDecoration(
gradient: LinearGradient(
colors: [Colors.red, Colors.red.withOpacity(0.2)],
),
borderRadius: BorderRadius.circular(2),
),
),
],
),
),
const SizedBox(height: 20),
// Menu Grid dengan efek glassmorphism
Expanded(
child: GridView.count(
crossAxisCount: 2,
crossAxisSpacing: 15,
mainAxisSpacing: 15,
children: [
menuCard(context, "Cek Sensor", "assets/sensor.gif",
const CekSensor()),
menuCard(context, "Riwayat", "assets/history.gif",
const HistoryScreen()),
menuCard(context, "Tentang Aplikasi", "assets/about.gif",
const AboutAppScreen()),
menuCard(context, "Pengaturan", "assets/settings.gif",
const PengaturanScreen()),
],
),
),
],
),
),
),
);
}
}