import 'dart:io'; import 'package:flutter_image_compress/flutter_image_compress.dart'; import 'package:flutter/material.dart'; import 'package:image_picker/image_picker.dart'; import 'package:mobile/models.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'api.dart' as api; import 'base/variables.dart'; class EditProfilePage extends StatefulWidget { final User? userData; const EditProfilePage({super.key, required this.userData}); @override State createState() => _ProfilePageState(); } class _ProfilePageState extends State { TextEditingController usernameInput = TextEditingController(); TextEditingController emailInput = TextEditingController(); TextEditingController passwordInput = TextEditingController(); TextEditingController confirmPasswordInput = TextEditingController(); File? _selectedImage; set userData(User userData) {} @override void initState() { super.initState(); // Initialize the controllers with existing data usernameInput.text = widget.userData!.username; emailInput.text = widget.userData!.email; } @override void dispose() { // Dispose of the controllers when the widget is disposed usernameInput.dispose(); emailInput.dispose(); passwordInput.dispose(); confirmPasswordInput.dispose(); super.dispose(); } Future _pickImageFromGallery() async{ final picker = ImagePicker(); final XFile? image = await picker.pickImage(source: ImageSource.gallery); if(image == null) {return;} else{ File compressedFile = await _compressImage(File(image.path)); setState(() { _selectedImage = compressedFile; }); } } Future _pickImageFromCamera() async{ final picker = ImagePicker(); final XFile? image = await picker.pickImage(source: ImageSource.camera); if(image == null) {return;} else{ File compressedFile = await _compressImage(File(image.path)); setState(() { _selectedImage = compressedFile; }); } } Future _compressImage(File file) async { final filePath = file.absolute.path; final lastIndex = filePath.lastIndexOf(RegExp(r'.jp')); final splitted = filePath.substring(0, lastIndex); final outPath = "${splitted}_compressed.jpg"; var result = await FlutterImageCompress.compressAndGetFile( file.absolute.path, outPath, quality: 80, minWidth: 1024, minHeight: 1024, ); return File(result!.path); } void _saveProfile() async { if (passwordInput.text != confirmPasswordInput.text) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Passwords do not match'))); return; } final prefs = await SharedPreferences.getInstance(); String? id = prefs.getString('id'); if (!mounted) { return; } if (id != null){ final response = await api.request(context, api.ApiService.auth, 'PUT', '/api/users', { 'id' : id, 'username': usernameInput.text, 'email': emailInput.text, 'password': passwordInput.text, 'profilePicture': _selectedImage, }); if (!mounted) { return; } if (response != null) { User updatedUser = User( id, emailInput.text, usernameInput.text, _selectedImage, DateTime.now(), ); setState(() { user = updatedUser; }); Navigator.of(context).pop(); // Close the dialog Navigator.pushReplacementNamed(context, '/profile'); } else { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Something went wrong! Please contact an admin.')), ); } } } void _deleteProfile(BuildContext context) { showDialog( context: context, builder: (BuildContext context) { return AlertDialog( title: Text('Confirm Deletion'), content: Text('Are you sure you want to delete your profile?'), actions: [ TextButton( child: Text('Cancel'), onPressed: () { Navigator.of(context).pop(); // Close the dialog }, ), TextButton( child: Text('Delete'), style: TextButton.styleFrom(foregroundColor: Colors.red), onPressed: () async { final prefs = await SharedPreferences.getInstance(); String? id = prefs.getString('id'); final response = await api.request(context, api.ApiService.auth, 'DELETE', '/api/users/$id', null); if (response != null) { prefs.remove('token'); prefs.remove('id'); setState(() { user = null; }); Navigator.of(context).pop(); // Close the dialog Navigator.of(context).pop(); Navigator.pushReplacementNamed(context, '/register'); } else { ScaffoldMessenger.of(context).showSnackBar( const SnackBar(content: Text('Something went wrong! Please contact an admin.')), ); } }, ), ], ); }, ); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text('Edit Profile'), leading: IconButton( icon: Icon(Icons.arrow_back), onPressed: () { Navigator.pop(context); // Navigates back when the back button is pressed }, ), ), body: Padding( padding: const EdgeInsets.all(16.0), child: Column( children: [ TextField( controller: usernameInput, decoration: InputDecoration(labelText: 'Name'), ), TextField( controller: emailInput, decoration: InputDecoration(labelText: 'Email'), ), TextField( controller: passwordInput, decoration: InputDecoration(labelText: 'New password'), ), TextField( controller: confirmPasswordInput, decoration: InputDecoration(labelText: 'Repeat new password'), ), Row( children: [ ElevatedButton(onPressed: _pickImageFromGallery, child: Text('Gallery')), ElevatedButton(onPressed: _pickImageFromCamera, child: Text('Camera')) ], ), SizedBox(height: 20), Text('ProfilePicture:'), if(_selectedImage != null) Text(_selectedImage!.path.toString()), Row( mainAxisAlignment: MainAxisAlignment.center, children: [ ElevatedButton( onPressed: _saveProfile, // Save and pop child: Text('Save'), ), SizedBox(width: 10), ElevatedButton( onPressed: () => _deleteProfile(context), child: Text('Delete'), style: ElevatedButton.styleFrom( foregroundColor: Colors.red, // Red text ), ), ], ) ], ), ), ); } }