import 'package:flutter/material.dart'; import '../services/auth_service.dart'; import '../models/user.dart'; import '../login.dart'; import 'edit_profile_screen.dart'; import 'change_password_screen.dart'; import 'booking_history_screen.dart'; class ProfileScreen extends StatefulWidget { const ProfileScreen({super.key}); @override State createState() => _ProfileScreenState(); } class _ProfileScreenState extends State { final _authService = AuthService(); User? _currentUser; bool _isLoading = true; @override void initState() { super.initState(); _loadUser(); } Future _loadUser() async { setState(() => _isLoading = true); final user = await _authService.getCurrentUser(); setState(() { _currentUser = user; _isLoading = false; }); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFFF8F9FA), body: _isLoading ? const Center( child: CircularProgressIndicator(color: Color(0xFF1565C0))) : RefreshIndicator( onRefresh: _loadUser, color: const Color(0xFF1565C0), child: CustomScrollView( physics: const AlwaysScrollableScrollPhysics(), slivers: [ // --- Profile Header --- SliverToBoxAdapter( child: Container( decoration: const BoxDecoration( gradient: LinearGradient( colors: [Color(0xFF0D47A1), Color(0xFF1976D2)], begin: Alignment.topLeft, end: Alignment.bottomRight, ), borderRadius: BorderRadius.only( bottomLeft: Radius.circular(32), bottomRight: Radius.circular(32), ), ), child: SafeArea( bottom: false, child: Padding( padding: const EdgeInsets.fromLTRB(24, 20, 24, 32), child: Column( children: [ // Title const Row( children: [ Text( 'Profil Saya', style: TextStyle( fontSize: 22, fontWeight: FontWeight.bold, color: Colors.white, ), ), ], ), const SizedBox(height: 24), // Avatar & Info Row( children: [ Container( padding: const EdgeInsets.all(3), decoration: BoxDecoration( shape: BoxShape.circle, border: Border.all( color: Colors.white, width: 2.5), ), child: CircleAvatar( radius: 38, backgroundColor: Colors.white.withOpacity(0.95), child: Text( _currentUser?.name .substring(0, 1) .toUpperCase() ?? 'U', style: const TextStyle( fontSize: 30, fontWeight: FontWeight.bold, color: Color(0xFF0D47A1), ), ), ), ), const SizedBox(width: 16), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( _currentUser?.name ?? 'User', style: const TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: Colors.white, ), maxLines: 1, overflow: TextOverflow.ellipsis, ), const SizedBox(height: 4), Row( children: [ Icon(Icons.email_outlined, size: 14, color: Colors.white .withOpacity(0.8)), const SizedBox(width: 6), Expanded( child: Text( _currentUser?.email ?? '', style: TextStyle( fontSize: 13, color: Colors.white .withOpacity(0.85), ), maxLines: 1, overflow: TextOverflow.ellipsis, ), ), ], ), if (_currentUser?.phone != null && _currentUser!.phone!.isNotEmpty) ...[ const SizedBox(height: 2), Row( children: [ Icon(Icons.phone_outlined, size: 14, color: Colors.white .withOpacity(0.8)), const SizedBox(width: 6), Text( _currentUser!.phone!, style: TextStyle( fontSize: 13, color: Colors.white .withOpacity(0.85), ), ), ], ), ], ], ), ), ], ), ], ), ), ), ), ), // --- Menu Sections --- SliverPadding( padding: const EdgeInsets.fromLTRB(16, 24, 16, 16), sliver: SliverList( delegate: SliverChildListDelegate([ // Akun section _sectionLabel('Akun'), const SizedBox(height: 8), _menuCard([ _menuTile( icon: Icons.person_outline, title: 'Edit Profil', subtitle: 'Ubah nama, email, dan no. HP', onTap: () async { if (_currentUser == null) return; final result = await Navigator.push( context, MaterialPageRoute( builder: (_) => EditProfileScreen(user: _currentUser!), ), ); if (result == true) _loadUser(); }, ), _divider(), _menuTile( icon: Icons.lock_outline, title: 'Ubah Password', subtitle: 'Ganti password akun Anda', onTap: () { Navigator.push( context, MaterialPageRoute( builder: (_) => const ChangePasswordScreen(), ), ); }, ), ]), const SizedBox(height: 20), // Aktivitas section _sectionLabel('Aktivitas'), const SizedBox(height: 8), _menuCard([ _menuTile( icon: Icons.receipt_long_outlined, title: 'Booking Saya', subtitle: 'Lihat riwayat booking Anda', onTap: () { Navigator.push( context, MaterialPageRoute( builder: (_) => const BookingHistoryScreen(), ), ); }, ), ]), const SizedBox(height: 20), // Informasi section _sectionLabel('Informasi'), const SizedBox(height: 8), _menuCard([ _menuTile( icon: Icons.info_outline, title: 'Tentang Aplikasi', subtitle: 'SPK Kontrakan v1.0.0', onTap: _showAboutDialog, ), ]), const SizedBox(height: 28), // Logout SizedBox( width: double.infinity, height: 52, child: OutlinedButton.icon( onPressed: _handleLogout, icon: const Icon(Icons.logout, size: 20), label: const Text( 'Keluar dari Akun', style: TextStyle( fontSize: 15, fontWeight: FontWeight.w600), ), style: OutlinedButton.styleFrom( foregroundColor: Colors.red.shade600, side: BorderSide(color: Colors.red.shade300), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(14), ), ), ), ), const SizedBox(height: 32), ]), ), ), ], ), ), ); } // --- Helper Widgets --- Widget _sectionLabel(String text) { return Padding( padding: const EdgeInsets.only(left: 4), child: Text( text.toUpperCase(), style: TextStyle( fontSize: 12, fontWeight: FontWeight.w700, color: Colors.grey.shade500, letterSpacing: 1.2, ), ), ); } Widget _menuCard(List children) { return Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( color: Colors.black.withOpacity(0.04), blurRadius: 10, offset: const Offset(0, 2), ), ], ), child: ClipRRect( borderRadius: BorderRadius.circular(16), child: Column(children: children), ), ); } Widget _menuTile({ required IconData icon, required String title, required String subtitle, required VoidCallback onTap, }) { return Material( color: Colors.transparent, child: InkWell( onTap: onTap, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14), child: Row( children: [ Container( width: 42, height: 42, decoration: BoxDecoration( color: const Color(0xFF1565C0).withOpacity(0.08), borderRadius: BorderRadius.circular(12), ), child: Icon(icon, color: const Color(0xFF1565C0), size: 22), ), const SizedBox(width: 14), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: const TextStyle( fontSize: 15, fontWeight: FontWeight.w600, color: Color(0xFF1A1A2E), ), ), const SizedBox(height: 2), Text( subtitle, style: TextStyle( fontSize: 12, color: Colors.grey.shade500, ), ), ], ), ), Icon(Icons.chevron_right, color: Colors.grey.shade400, size: 22), ], ), ), ), ); } Widget _divider() { return Divider( height: 1, thickness: 0.5, indent: 72, color: Colors.grey.shade200); } // --- Dialogs --- void _showAboutDialog() { showDialog( context: context, builder: (context) => AlertDialog( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), contentPadding: const EdgeInsets.fromLTRB(24, 24, 24, 16), content: Column( mainAxisSize: MainAxisSize.min, children: [ Container( padding: const EdgeInsets.all(16), decoration: BoxDecoration( color: const Color(0xFF1565C0).withOpacity(0.08), borderRadius: BorderRadius.circular(16), ), child: const Icon(Icons.home_work, color: Color(0xFF1565C0), size: 40), ), const SizedBox(height: 16), const Text( 'SPK Kontrakan', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold), ), const SizedBox(height: 4), Text( 'Versi 1.0.0', style: TextStyle(fontSize: 13, color: Colors.grey.shade500), ), const SizedBox(height: 16), Text( 'Sistem Pendukung Keputusan untuk membantu mahasiswa menemukan kontrakan terbaik menggunakan metode SAW.', textAlign: TextAlign.center, style: TextStyle( fontSize: 14, color: Colors.grey.shade600, height: 1.5), ), const SizedBox(height: 16), const Divider(), const SizedBox(height: 8), _aboutRow('Developer', 'SPK Team'), _aboutRow('Tahun', '2026'), ], ), actions: [ TextButton( onPressed: () => Navigator.pop(context), child: const Text('Tutup'), ), ], ), ); } Widget _aboutRow(String label, String value) { return Padding( padding: const EdgeInsets.symmetric(vertical: 3), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text(label, style: TextStyle(fontSize: 13, color: Colors.grey.shade600)), Text(value, style: const TextStyle( fontSize: 13, fontWeight: FontWeight.w600, color: Colors.black87)), ], ), ); } Future _handleLogout() async { final confirm = await showDialog( context: context, builder: (context) => AlertDialog( shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), title: Row( children: [ Icon(Icons.logout, color: Colors.red.shade600, size: 24), const SizedBox(width: 10), const Text('Keluar', style: TextStyle(fontSize: 18)), ], ), content: const Text('Apakah Anda yakin ingin keluar dari akun?'), actions: [ TextButton( onPressed: () => Navigator.pop(context, false), child: Text('Batal', style: TextStyle(color: Colors.grey.shade600)), ), ElevatedButton( onPressed: () => Navigator.pop(context, true), style: ElevatedButton.styleFrom( backgroundColor: Colors.red.shade600, foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10)), ), child: const Text('Keluar'), ), ], ), ); if (confirm == true) { await _authService.logout(); if (mounted) { Navigator.pushAndRemoveUntil( context, MaterialPageRoute(builder: (_) => const LoginScreen()), (route) => false, ); } } } }