import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; import 'package:sijentik/api/api.dart'; class BuatKataSandiBaruPage extends StatefulWidget { final String email; const BuatKataSandiBaruPage({super.key, required this.email}); @override State createState() => _BuatKataSandiBaruPageState(); } class _BuatKataSandiBaruPageState extends State { final TextEditingController passwordController = TextEditingController(); final TextEditingController confirmPasswordController = TextEditingController(); final FocusNode passwordFocusNode = FocusNode(); final FocusNode confirmPasswordFocusNode = FocusNode(); bool obscurePassword = true; bool obscureConfirmPassword = true; @override void dispose() { passwordController.dispose(); confirmPasswordController.dispose(); passwordFocusNode.dispose(); confirmPasswordFocusNode.dispose(); super.dispose(); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: const Color(0xFFF5F9FF), body: SafeArea( child: SingleChildScrollView( child: Column( children: [ Padding( padding: const EdgeInsets.only(top: 16, left: 16), child: Align( alignment: Alignment.centerLeft, child: IconButton( onPressed: () { Navigator.pop(context); }, icon: const Icon( Icons.arrow_back, color: Colors.black, size: 25, ), ), ), ), const SizedBox(height: 20), const Text( 'Buat Kata Sandi Baru', style: TextStyle( fontSize: 24, fontWeight: FontWeight.bold, color: Colors.black, ), ), const SizedBox(height: 30), Image.asset('assets/images/sandidua.png', width: 150), Padding( padding: const EdgeInsets.all(24.0), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ const Text( 'Kata Sandi Baru', style: TextStyle( fontSize: 16, fontWeight: FontWeight.w500, color: Colors.black87, ), ), const SizedBox(height: 8), TextField( controller: passwordController, focusNode: passwordFocusNode, obscureText: obscurePassword, decoration: InputDecoration( hintText: 'Masukkan kata sandi baru', hintStyle: TextStyle(color: Colors.grey[500]), filled: true, fillColor: Colors.white, border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: BorderSide( color: Colors.grey[300]!, width: 1.0, ), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: BorderSide( color: Colors.grey[300]!, width: 1.0, ), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: const BorderSide( color: Color(0xFF206E97), width: 1.5, ), ), prefixIcon: Icon( Icons.lock_outline, color: Colors.grey[600], size: 20, ), suffixIcon: IconButton( icon: Icon( obscurePassword ? Icons.visibility_off : Icons.visibility, color: Colors.grey[600], size: 20, ), onPressed: () { setState(() { obscurePassword = !obscurePassword; }); }, ), contentPadding: const EdgeInsets.symmetric( vertical: 14, horizontal: 16, ), ), ), const SizedBox(height: 20), const Text( 'Konfirmasi Kata Sandi Baru', style: TextStyle( fontSize: 16, fontWeight: FontWeight.w500, color: Colors.black87, ), ), const SizedBox(height: 8), TextField( controller: confirmPasswordController, focusNode: confirmPasswordFocusNode, obscureText: obscureConfirmPassword, decoration: InputDecoration( hintText: 'Masukkan konfirmasi kata sandi baru', hintStyle: TextStyle(color: Colors.grey[500]), filled: true, fillColor: Colors.white, border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: BorderSide( color: Colors.grey[300]!, width: 1.0, ), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: BorderSide( color: Colors.grey[300]!, width: 1.0, ), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(8), borderSide: const BorderSide( color: Color(0xFF206E97), width: 1.5, ), ), prefixIcon: Icon( Icons.lock_outline, color: Colors.grey[600], size: 20, ), suffixIcon: IconButton( icon: Icon( obscureConfirmPassword ? Icons.visibility_off : Icons.visibility, color: Colors.grey[600], size: 20, ), onPressed: () { setState(() { obscureConfirmPassword = !obscureConfirmPassword; }); }, ), contentPadding: const EdgeInsets.symmetric( vertical: 14, horizontal: 16, ), ), ), const SizedBox(height: 40), SizedBox( width: double.infinity, height: 50, child: ElevatedButton( onPressed: () { _simpanKataSandiBaru(); }, style: ElevatedButton.styleFrom( backgroundColor: const Color(0xFF206E97), foregroundColor: Colors.white, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), elevation: 0, ), child: const Text( 'Simpan', style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, ), ), ), ), ], ), ), ], ), ), ), ); } Future _simpanKataSandiBaru() async { if (passwordController.text.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Harap masukkan kata sandi baru'), backgroundColor: Colors.red, ), ); return; } if (confirmPasswordController.text.isEmpty) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Harap masukkan konfirmasi kata sandi'), backgroundColor: Colors.red, ), ); return; } if (passwordController.text.length < 6) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Kata sandi minimal 6 karakter'), backgroundColor: Colors.red, ), ); return; } if (passwordController.text != confirmPasswordController.text) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text('Kata sandi tidak cocok'), backgroundColor: Colors.red, ), ); return; } FocusScope.of(context).unfocus(); showDialog( context: context, barrierDismissible: false, builder: (context) => const AlertDialog( content: Column( mainAxisSize: MainAxisSize.min, children: [ CircularProgressIndicator(), SizedBox(height: 16), Text('Menyimpan kata sandi baru...'), ], ), ), ); try { final response = await http.post( Uri.parse('$baseUrl/reset-password'), // 🔥 pakai baseUrl global headers: {'Accept': 'application/json'}, body: { 'email': widget.email, 'password': passwordController.text.trim(), 'password_confirmation': confirmPasswordController.text.trim(), }, ); final dynamic data = jsonDecode(response.body); if (!mounted) return; Navigator.pop(context); if (response.statusCode == 200) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( data['message'] ?? 'Kata sandi berhasil diperbarui untuk email ${widget.email}', style: const TextStyle(color: Colors.white), ), backgroundColor: Colors.green, duration: const Duration(seconds: 3), ), ); await Future.delayed(const Duration(seconds: 1)); if (!mounted) return; Navigator.popUntil(context, (route) => route.isFirst); } else { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text( data['message'] ?? data['error'] ?? 'Gagal memperbarui kata sandi', ), backgroundColor: Colors.red, duration: const Duration(seconds: 3), ), ); } } catch (e) { if (!mounted) return; Navigator.pop(context); ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Terjadi kesalahan koneksi: $e'), backgroundColor: Colors.red, ), ); } } }