import 'package:flutter/material.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:firebase_storage/firebase_storage.dart'; import 'package:image_picker/image_picker.dart'; import 'dart:io'; import '../constants.dart'; import '../models/user_profile.dart'; class EditProfilePage extends StatefulWidget { final UserProfile userData; const EditProfilePage({super.key, required this.userData}); @override EditProfilePageState createState() => EditProfilePageState(); } class EditProfilePageState extends State { final _formKey = GlobalKey(); late TextEditingController _nameController; late TextEditingController _bioController; late String? profileImageUrl; File? _profileImage; @override void initState() { super.initState(); _nameController = TextEditingController(text: widget.userData.name); _bioController = TextEditingController(text: widget.userData.bio); if (widget.userData.profilePictureUrl != null) { profileImageUrl = widget.userData.profilePictureUrl; } } Future _pickImage() async { final pickedFile = await ImagePicker().pickImage(source: ImageSource.gallery); if (pickedFile != null) { setState(() { _profileImage = File(pickedFile.path); }); } } void _clearProfileImage() { setState(() { _profileImage = null; profileImageUrl = null; widget.userData.profilePictureUrl = null; }); } Future _saveProfile() async { String nameTrim = _nameController.text.trim(); String bioTrim = _bioController.text.trim(); if (_formKey.currentState!.validate()) { String uid = FirebaseAuth.instance.currentUser!.uid; if (_profileImage != null) { final storageRef = FirebaseStorage.instance .ref() .child(Constants.dbStoragePathProfiles) .child(uid); // filename = userid await storageRef.putFile(_profileImage!); profileImageUrl = await storageRef.getDownloadURL(); } Map resultValues = { Constants.dbFieldUsersName: nameTrim, Constants.dbFieldUsersBio: bioTrim, Constants.dbFieldUsersProfilePic: profileImageUrl, }; await FirebaseFirestore.instance .collection(Constants.dbCollectionUsers) .doc(uid) .update(resultValues); _close(resultValues); } } /// close this page and return selected values void _close(Map map) { Navigator.pop(context, { Constants.dbFieldUsersProfilePic: map[Constants.dbFieldUsersProfilePic], Constants.dbFieldUsersName: map[Constants.dbFieldUsersName], Constants.dbFieldUsersBio: map[Constants.dbFieldUsersBio], }); } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: const Text('Edit Profile'), ), body: Padding( padding: const EdgeInsets.all(16.0), child: Form( key: _formKey, child: ListView( children: [ Center( child: Row( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.end, children: [ buildAvatar(context), if (_profileImage != null || widget.userData.profilePictureUrl != null) IconButton( icon: Ink( decoration: const ShapeDecoration( shape: CircleBorder(), ), child: const Icon( Icons.delete, color: Colors.red, size: 32, ), ), onPressed: _clearProfileImage, ), ], ), ), const SizedBox(height: 16), TextFormField( controller: _nameController, decoration: const InputDecoration(labelText: 'Name'), validator: (value) { if (value == null || value.trim().isEmpty) { return 'Please enter a name'; } return null; }, ), const SizedBox(height: 16), TextFormField( controller: _bioController, decoration: const InputDecoration(labelText: 'Bio'), maxLines: 3, maxLength: 4096, ), const SizedBox(height: 16), ElevatedButton( onPressed: _saveProfile, child: const Text('Save'), ), ], ), ), ), ); } Widget buildAvatar(BuildContext context) { return GestureDetector( onTap: _pickImage, child: Stack( children: [ CircleAvatar( radius: 50, backgroundImage: _profileImage != null ? FileImage(_profileImage!) as ImageProvider : (widget.userData.profilePictureUrl != null ? NetworkImage(widget.userData.profilePictureUrl!) as ImageProvider : null), child: ClipOval( child: _profileImage == null && widget.userData.profilePictureUrl == null ? const Icon(Icons.person, size: 50) : SizedBox( width: 100, height: 100, child: _profileImage != null ? Image.file( _profileImage!, fit: BoxFit.cover, ) : (widget.userData.profilePictureUrl != null ? Image.network( widget.userData.profilePictureUrl!, fit: BoxFit.cover, ) : null), ), ), ), Positioned( bottom: 0, right: 0, child: IconButton( icon: Ink( decoration: ShapeDecoration( color: Theme.of(context).colorScheme.primary, shape: const CircleBorder(), ), child: const Icon(Icons.edit)), onPressed: _pickImage, ), ), ], ), ); } }