NIM_E31222534/Androidnya/lib/screens/dashboard/edit_profile_screen.dart

363 lines
13 KiB
Dart

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<EditProfileScreen> {
final _formKey = GlobalKey<FormState>();
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<void> _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<Color>(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<TextInputFormatter>? 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,
);
}
}