import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import '../../services/profile_service.dart'; import '../../services/auth_service.dart'; import '../../models/profile_model.dart'; import 'package:shared_preferences/shared_preferences.dart'; class EditProfileScreen extends StatefulWidget { final String currentName; final String currentEmail; final String currentPhone; final String currentAddress; final String currentNik; const EditProfileScreen({ Key? key, required this.currentName, required this.currentEmail, required this.currentPhone, required this.currentAddress, required this.currentNik, }) : super(key: key); @override _EditProfileScreenState createState() => _EditProfileScreenState(); } class _EditProfileScreenState extends State { final _formKey = GlobalKey(); final _profileService = ProfileService(); final _authService = AuthService(); late TextEditingController _nameController; late TextEditingController _emailController; late TextEditingController _phoneController; late TextEditingController _addressController; late TextEditingController _nikController; bool _isLoading = false; String? _errorMessage; @override void initState() { super.initState(); _nameController = TextEditingController(text: widget.currentName); _emailController = TextEditingController(text: widget.currentEmail); _phoneController = TextEditingController(text: widget.currentPhone); _addressController = TextEditingController(text: widget.currentAddress); _nikController = TextEditingController(text: widget.currentNik); } @override void dispose() { _nameController.dispose(); _emailController.dispose(); _phoneController.dispose(); _addressController.dispose(); _nikController.dispose(); super.dispose(); } Future _saveProfile() async { if (!_formKey.currentState!.validate()) return; setState(() { _isLoading = true; _errorMessage = null; }); try { // Get current user data first final userInfo = await _authService.getCurrentUser(); if (userInfo['success'] == true && userInfo['data'] != null) { final userData = userInfo['data']; // Update with new values userData['nama_ibu'] = _nameController.text; userData['email'] = _emailController.text; userData['no_telp'] = _phoneController.text; userData['alamat'] = _addressController.text; userData['nik'] = _nikController.text; // Create a clean update payload using ProfileModel final updateData = ProfileModel( id: userData['id'], name: _nameController.text, email: _emailController.text, phone: _phoneController.text, address: _addressController.text, nik: _nikController.text, role: userData['role'], age: userData['usia'], children: [], // We don't need to update children data ); // Save to API with ProfileModel await _profileService.updateProfile(updateData); // Update local storage final prefs = await SharedPreferences.getInstance(); await prefs.setString('nama_ibu', _nameController.text); await prefs.setString('email', _emailController.text); await prefs.setString('no_telp', _phoneController.text); await prefs.setString('alamat', _addressController.text); await prefs.setString('nik', _nikController.text); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Profil berhasil diperbarui'), backgroundColor: Colors.green, ), ); Navigator.pop(context, true); // Return true to indicate success } } else { throw Exception('Gagal mendapatkan data pengguna'); } } catch (e) { setState(() { _errorMessage = 'Gagal menyimpan profil: ${e.toString()}'; }); } finally { if (mounted) { setState(() { _isLoading = false; }); } } } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Edit Profil'), backgroundColor: Colors.teal.shade700, elevation: 0, ), body: SingleChildScrollView( child: Form( key: _formKey, child: Column( children: [ Container( width: double.infinity, padding: EdgeInsets.all(24), decoration: BoxDecoration( color: Colors.teal.shade700, borderRadius: BorderRadius.only( bottomLeft: Radius.circular(32), bottomRight: Radius.circular(32), ), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'Informasi Pribadi', style: TextStyle( fontSize: 20, fontWeight: FontWeight.bold, color: Colors.white, ), ), SizedBox(height: 8), Text( 'Silakan lengkapi data diri Anda', style: TextStyle( color: Colors.white.withOpacity(0.9), fontSize: 14, ), ), ], ), ), Padding( padding: EdgeInsets.all(24), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ if (_errorMessage != null) Container( width: double.infinity, padding: EdgeInsets.all(12), margin: EdgeInsets.only(bottom: 16), decoration: BoxDecoration( color: Colors.red.shade50, borderRadius: BorderRadius.circular(12), border: Border.all(color: Colors.red.shade200), ), child: Text( _errorMessage!, style: TextStyle(color: Colors.red.shade700), ), ), _buildTextField( label: 'Nama Lengkap', controller: _nameController, icon: Icons.person_outline, validator: (value) { if (value == null || value.isEmpty) { return 'Nama tidak boleh kosong'; } return null; }, ), SizedBox(height: 16), _buildTextField( label: 'Email', controller: _emailController, icon: Icons.email_outlined, keyboardType: TextInputType.emailAddress, validator: (value) { if (value == null || value.isEmpty) { return 'Email tidak boleh kosong'; } if (!value.contains('@') || !value.contains('.')) { return 'Email tidak valid'; } return null; }, ), SizedBox(height: 16), _buildTextField( label: 'Nomor Handphone', controller: _phoneController, icon: Icons.phone_outlined, keyboardType: TextInputType.phone, inputFormatters: [ FilteringTextInputFormatter.digitsOnly, LengthLimitingTextInputFormatter(13), ], validator: (value) { if (value == null || value.isEmpty) { return 'Nomor handphone tidak boleh kosong'; } if (value.length < 10) { return 'Nomor handphone tidak valid'; } return null; }, ), SizedBox(height: 16), _buildTextField( label: 'Alamat', controller: _addressController, icon: Icons.location_on_outlined, maxLines: 3, validator: (value) { if (value == null || value.isEmpty) { return 'Alamat tidak boleh kosong'; } return null; }, ), SizedBox(height: 16), _buildTextField( label: 'NIK', controller: _nikController, icon: Icons.credit_card_outlined, keyboardType: TextInputType.number, inputFormatters: [ FilteringTextInputFormatter.digitsOnly, LengthLimitingTextInputFormatter(16), ], validator: (value) { if (value == null || value.isEmpty) { return 'NIK tidak boleh kosong'; } if (value.length != 16) { return 'NIK harus 16 digit'; } return null; }, ), SizedBox(height: 32), SizedBox( width: double.infinity, child: ElevatedButton( onPressed: _isLoading ? null : _saveProfile, style: ElevatedButton.styleFrom( backgroundColor: Colors.teal.shade700, foregroundColor: Colors.white, padding: EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), child: _isLoading ? SizedBox( height: 20, width: 20, child: CircularProgressIndicator( strokeWidth: 2, valueColor: AlwaysStoppedAnimation(Colors.white), ), ) : Text( 'Simpan Perubahan', style: TextStyle( fontSize: 16, fontWeight: FontWeight.bold, ), ), ), ), ], ), ), ], ), ), ), ); } Widget _buildTextField({ required String label, required TextEditingController controller, required IconData icon, TextInputType? keyboardType, List? inputFormatters, String? Function(String?)? validator, int maxLines = 1, }) { return TextFormField( controller: controller, decoration: InputDecoration( labelText: label, prefixIcon: Icon(icon, color: Colors.teal.shade700), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: Colors.grey.shade300), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: Colors.grey.shade300), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: Colors.teal.shade700, width: 2), ), errorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: Colors.red.shade300), ), focusedErrorBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide(color: Colors.red.shade700, width: 2), ), filled: true, fillColor: Colors.grey.shade50, contentPadding: EdgeInsets.symmetric(horizontal: 16, vertical: 16), ), keyboardType: keyboardType, inputFormatters: inputFormatters, validator: validator, maxLines: maxLines, ); } }