import 'package:flutter/material.dart'; import 'package:SIBAYAM/api_services/api_services.dart'; class ForgotPasswordPage extends StatefulWidget { @override _ForgotPasswordPageState createState() => _ForgotPasswordPageState(); } class _ForgotPasswordPageState extends State { final TextEditingController emailController = TextEditingController(); final ApiService apiService = ApiService(); bool isLoading = false; void _showErrorDialog(String message) { showDialog( context: context, builder: (context) => AlertDialog( title: Row( children: [ Icon(Icons.error_outline, color: Colors.red), SizedBox(width: 10), Text('Error'), ], ), content: Text(message), actions: [ TextButton( onPressed: () => Navigator.of(context).pop(), child: Text( 'OK', style: TextStyle(color: Color(0xFF9DC08D)), ), ), ], shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15), ), ), ); } void _showSuccessDialog(String title, String message) { showDialog( context: context, builder: (context) => AlertDialog( title: Row( children: [ Icon(Icons.check_circle, color: Color(0xFF9DC08D)), SizedBox(width: 10), Text(title), ], ), content: Text(message), actions: [ TextButton( onPressed: () { Navigator.of(context).pop(); if (title == 'Berhasil') { Navigator.of(context).pop(); // kembali ke halaman login } }, child: Text( 'OK', style: TextStyle(color: Color(0xFF9DC08D)), ), ), ], shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15), ), ), ); } // Fungsi untuk mengirim kode verifikasi void handleSendCode() async { if (emailController.text.trim().isEmpty) { _showErrorDialog('Email harus diisi'); return; } setState(() => isLoading = true); try { await apiService.sendResetCode(email: emailController.text.trim()); setState(() => isLoading = false); _showSuccessDialog( 'Kode Terkirim', 'Kode verifikasi telah dikirim ke email Anda.', ); showResetPasswordDialog(); } catch (e) { setState(() => isLoading = false); _showErrorDialog(e.toString()); } } // Dialog untuk input kode verifikasi dan reset password void showResetPasswordDialog() { final codeController = TextEditingController(); final passwordController = TextEditingController(); final confirmPasswordController = TextEditingController(); bool isDialogLoading = false; bool obscurePassword = true; bool obscureConfirmPassword = true; showDialog( context: context, barrierDismissible: false, builder: (context) => StatefulBuilder( builder: (context, setDialogState) => AlertDialog( title: Text('Reset Password'), content: SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.min, children: [ Text('Masukkan kode verifikasi dan password baru Anda.'), SizedBox(height: 16), TextField( controller: codeController, decoration: InputDecoration( labelText: 'Kode Verifikasi', labelStyle: TextStyle(color: Colors.black.withOpacity(0.7)), border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10), borderSide: BorderSide( color: Colors.black.withOpacity(0.6), width: 2, ), ), ), keyboardType: TextInputType.number, ), SizedBox(height: 16), TextField( controller: passwordController, obscureText: obscurePassword, decoration: InputDecoration( labelText: 'Password Baru', labelStyle: TextStyle(color: Colors.black.withOpacity(0.7)), border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10), borderSide: BorderSide( color: Colors.black.withOpacity(0.6), width: 2, ), ), suffixIcon: IconButton( icon: Icon( obscurePassword ? Icons.visibility : Icons.visibility_off, color: Colors.black.withOpacity(0.6), ), onPressed: () { setDialogState(() { obscurePassword = !obscurePassword; }); }, ), ), ), SizedBox(height: 16), TextField( controller: confirmPasswordController, obscureText: obscureConfirmPassword, decoration: InputDecoration( labelText: 'Konfirmasi Password', labelStyle: TextStyle(color: Colors.black.withOpacity(0.7)), border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10), borderSide: BorderSide( color: Colors.black.withOpacity(0.6), width: 2, ), ), suffixIcon: IconButton( icon: Icon( obscureConfirmPassword ? Icons.visibility : Icons.visibility_off, color: Colors.black.withOpacity(0.6), ), onPressed: () { setDialogState(() { obscureConfirmPassword = !obscureConfirmPassword; }); }, ), ), ), ], ), ), actions: [ TextButton( child: Text( 'Batal', style: TextStyle(color: Colors.grey), ), onPressed: () { Navigator.pop(context); }, ), TextButton( child: isDialogLoading ? SizedBox( width: 20, height: 20, child: CircularProgressIndicator( strokeWidth: 2, valueColor: AlwaysStoppedAnimation(Color(0xFF9DC08D)), ), ) : Text( 'Reset Password', style: TextStyle( color: Color(0xFF9DC08D), fontWeight: FontWeight.bold, ), ), onPressed: isDialogLoading ? null : () async { // Validasi input if (codeController.text.trim().isEmpty) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Silakan masukkan kode verifikasi.'), backgroundColor: Colors.red, ), ); return; } if (passwordController.text.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Silakan masukkan password baru.'), backgroundColor: Colors.red, ), ); return; } if (passwordController.text != confirmPasswordController.text) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Password tidak cocok.'), backgroundColor: Colors.red, ), ); return; } if (passwordController.text.length < 8) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Password minimal 8 karakter.'), backgroundColor: Colors.red, ), ); return; } setDialogState(() { isDialogLoading = true; }); try { // Panggil API untuk reset password await apiService.resetPasswordWithCode( code: codeController.text.trim(), password: passwordController.text, ); setDialogState(() { isDialogLoading = false; }); // Tutup dialog dan tampilkan pesan sukses Navigator.pop(context); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Password berhasil direset!'), backgroundColor: Colors.green, ), ); // Redirect ke login page // Navigator.pushReplacementNamed(context, '/login'); } catch (e) { setDialogState(() { isDialogLoading = false; }); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Terjadi kesalahan: ${e.toString()}'), backgroundColor: Colors.red, ), ); } }, ), ], ), ), ); } @override void dispose() { emailController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Color(0xFF9DC08D), appBar: AppBar( backgroundColor: Color(0xFF9DC08D), title: Text('Lupa Password'), elevation: 0, ), body: Center( child: SingleChildScrollView( child: Padding( padding: const EdgeInsets.symmetric(horizontal: 20.0), child: Card( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(15), ), elevation: 5, child: Padding( padding: const EdgeInsets.all(20.0), child: Column( mainAxisSize: MainAxisSize.min, children: [ Text( 'Masukkan email Anda untuk menerima kode verifikasi', textAlign: TextAlign.center, style: TextStyle(fontSize: 16), ), SizedBox(height: 20), TextField( controller: emailController, decoration: InputDecoration( labelText: 'Email', labelStyle: TextStyle( color: Colors.black.withOpacity(0.7), ), border: OutlineInputBorder( borderRadius: BorderRadius.circular(10), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(10), borderSide: BorderSide( color: Colors.black.withOpacity(0.6), width: 2, ), ), ), keyboardType: TextInputType.emailAddress, ), SizedBox(height: 20), SizedBox( width: double.infinity, height: 50, child: ElevatedButton( style: ElevatedButton.styleFrom( backgroundColor: Colors.green, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(10), ), ), onPressed: isLoading ? null : handleSendCode, child: isLoading ? CircularProgressIndicator(color: Colors.white) : Text( 'Kirim Kode Verifikasi', style: TextStyle( color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold, ), ), ), ), ], ), ), ), ), ), ), ); } }