import 'package:flutter/material.dart'; import 'package:mobile_monitoring/core/constants/constants.dart'; class ChangePasswordDialog extends StatefulWidget { final Function(String oldPassword, String newPassword) onChangePassword; const ChangePasswordDialog({super.key, required this.onChangePassword}); @override State createState() => _ChangePasswordDialogState(); } class _ChangePasswordDialogState extends State { final _formKey = GlobalKey(); final _oldPasswordController = TextEditingController(); final _newPasswordController = TextEditingController(); final _confirmPasswordController = TextEditingController(); bool _obscureOld = true; bool _obscureNew = true; bool _obscureConfirm = true; bool _isLoading = false; @override void dispose() { _oldPasswordController.dispose(); _newPasswordController.dispose(); _confirmPasswordController.dispose(); super.dispose(); } Future _handleSubmit() async { if (!_formKey.currentState!.validate()) return; setState(() => _isLoading = true); try { await widget.onChangePassword(_oldPasswordController.text, _newPasswordController.text); if (mounted) { Navigator.pop(context, true); ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Password berhasil diubah'), backgroundColor: AppColors.success), ); } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text('Gagal: $e'), backgroundColor: AppColors.error), ); } } finally { if (mounted) setState(() => _isLoading = false); } } Widget _buildPasswordField({ required TextEditingController controller, required bool obscure, required VoidCallback onToggle, required String label, required String hint, String? Function(String?)? validator, }) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(label, style: const TextStyle(fontSize: 14, fontWeight: FontWeight.w500)), const SizedBox(height: 8), TextFormField( controller: controller, obscureText: obscure, decoration: InputDecoration( prefixIcon: const Icon(Icons.lock, color: AppColors.textSecondary), suffixIcon: IconButton( icon: Icon(obscure ? Icons.visibility_off : Icons.visibility, color: AppColors.textSecondary), onPressed: onToggle, ), hintText: hint, border: OutlineInputBorder(borderRadius: BorderRadius.circular(30)), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(30), borderSide: const BorderSide(color: AppColors.black), ), contentPadding: const EdgeInsets.symmetric(horizontal: 20, vertical: 16), ), validator: validator, ), const SizedBox(height: 16), ], ); } @override Widget build(BuildContext context) { return Dialog( backgroundColor: AppColors.white, shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(20)), child: Container( constraints: const BoxConstraints(maxWidth: 400), padding: const EdgeInsets.all(24), child: SingleChildScrollView( padding: EdgeInsets.only(bottom: MediaQuery.of(context).viewInsets.bottom), child: Stack( children: [ Form( key: _formKey, child: Column( mainAxisSize: MainAxisSize.min, children: [ const Text('Ubah Password', style: TextStyle(fontSize: 20, fontWeight: FontWeight.bold)), const SizedBox(height: 24), _buildPasswordField( controller: _oldPasswordController, obscure: _obscureOld, onToggle: () => setState(() => _obscureOld = !_obscureOld), label: 'Password lama', hint: '************', validator: (v) => v?.isEmpty ?? true ? 'Masukkan password lama' : null, ), _buildPasswordField( controller: _newPasswordController, obscure: _obscureNew, onToggle: () => setState(() => _obscureNew = !_obscureNew), label: 'Password baru', hint: '************', validator: (v) { if (v?.isEmpty ?? true) return 'Masukkan password baru'; if (v!.length < 6) return 'Password minimal 6 karakter'; return null; }, ), _buildPasswordField( controller: _confirmPasswordController, obscure: _obscureConfirm, onToggle: () => setState(() => _obscureConfirm = !_obscureConfirm), label: 'Konfirmasi password baru', hint: '************', validator: (v) { if (v?.isEmpty ?? true) return 'Konfirmasi password tidak boleh kosong'; if (v != _newPasswordController.text) return 'Password tidak cocok'; return null; }, ), const SizedBox(height: 8), ElevatedButton( onPressed: _isLoading ? null : _handleSubmit, style: ElevatedButton.styleFrom( backgroundColor: AppColors.secondary, foregroundColor: AppColors.white, padding: const EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(30)), minimumSize: const Size.fromHeight(48), ), child: _isLoading ? const SizedBox(height: 20, width: 20, child: CircularProgressIndicator(strokeWidth: 2, color: AppColors.white)) : const Text('Ubah Password', style: TextStyle(fontSize: 16, fontWeight: FontWeight.bold)), ), ], ), ), Positioned( top: 0, right: 0, child: IconButton( onPressed: _isLoading ? null : () => Navigator.pop(context, false), icon: const Icon(Icons.close, color: AppColors.textSecondary), ), ), ], ), ), ), ); } }