516 lines
17 KiB
Dart
516 lines
17 KiB
Dart
import 'package:cloud_firestore/cloud_firestore.dart';
|
|
import 'package:firebase_auth/firebase_auth.dart';
|
|
import 'package:firebase_storage/firebase_storage.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:get/get.dart';
|
|
import 'dart:io';
|
|
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
|
import 'package:prosappco/src/components/drawer_menu.dart';
|
|
import 'package:prosappco/src/controllers/add_name_email_city.dart';
|
|
import 'package:prosappco/src/services/select_image_profile.dart';
|
|
|
|
import '../components/photo_view.dart';
|
|
|
|
class ProfileScreen extends StatefulWidget {
|
|
ProfileScreen({Key? key}) : super(key: key);
|
|
|
|
@override
|
|
State<ProfileScreen> createState() => _ProfileScreenState();
|
|
}
|
|
|
|
class _ProfileScreenState extends State<ProfileScreen> {
|
|
File? imagen_to_upload;
|
|
|
|
final uid = AuthenticationRepository.instance.getCurrentUserUid();
|
|
bool _obscureText = true;
|
|
final _formKey = GlobalKey<FormState>();
|
|
final controller = Get.put(NameEmailCityController());
|
|
final _phoneNumberController = TextEditingController();
|
|
final _nameController = TextEditingController();
|
|
final _emailController = TextEditingController();
|
|
final _passwordController = TextEditingController();
|
|
late final FirebaseAuth _auth;
|
|
final FirebaseStorage storage = FirebaseStorage.instance;
|
|
var photoTemp = '';
|
|
var _ciudad = '...';
|
|
var _photo = '...';
|
|
var _estado = '...';
|
|
String? _email = '';
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
|
|
final uid = AuthenticationRepository.instance.getCurrentUserUid();
|
|
_auth = FirebaseAuth.instance;
|
|
|
|
final currentUser = _auth.currentUser;
|
|
|
|
if (currentUser != null && currentUser.phoneNumber != null) {
|
|
_phoneNumberController.text = currentUser.phoneNumber!;
|
|
}
|
|
|
|
if (currentUser != null && currentUser.displayName != null) {
|
|
_nameController.text = currentUser.displayName!;
|
|
}
|
|
if (currentUser != null && currentUser.email != null) {
|
|
_emailController.text = currentUser.email!;
|
|
}
|
|
|
|
_email = currentUser?.email;
|
|
|
|
if (_ciudad == '...') {
|
|
AuthenticationRepository.instance
|
|
.getCity(uid.toString())
|
|
.then((String s) => setState(() {
|
|
_ciudad = s;
|
|
}));
|
|
}
|
|
|
|
if (_photo == '...') {
|
|
AuthenticationRepository.instance
|
|
.getPhoto(uid.toString())
|
|
.then((String s) => setState(() {
|
|
_photo = s;
|
|
}));
|
|
}
|
|
if (_estado == '...') {
|
|
AuthenticationRepository.instance
|
|
.getState(uid.toString())
|
|
.then((String s) => setState(() {
|
|
_estado = s;
|
|
}));
|
|
}
|
|
}
|
|
|
|
Future<void> updateImage(image) async {
|
|
try {
|
|
await FirebaseFirestore.instance
|
|
.collection('users')
|
|
.doc(uid)
|
|
.update({'photo': image});
|
|
|
|
print('imagen actualizada correctamente');
|
|
} catch (e) {
|
|
try {
|
|
await FirebaseFirestore.instance
|
|
.collection('users')
|
|
.doc(uid)
|
|
.set({'photo': image});
|
|
} catch (e) {
|
|
print('Error al agregar la imagen de perfil: $e');
|
|
}
|
|
|
|
print('Error al actualizar la imagen de perfil: $e');
|
|
}
|
|
}
|
|
|
|
Future<bool> uploadImage(File image) async {
|
|
final String namefile = image.path.split('/').last;
|
|
|
|
Reference ref = storage
|
|
.ref()
|
|
.child('users')
|
|
.child(uid!)
|
|
.child('profile')
|
|
.child(namefile);
|
|
|
|
final UploadTask uploadTask = ref.putFile(image);
|
|
|
|
final TaskSnapshot snapshot = await uploadTask.whenComplete(() => true);
|
|
|
|
photoTemp = ref.fullPath;
|
|
|
|
if (snapshot.state == TaskState.success) {
|
|
return true;
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
Future<Widget> downloadImage(Reference ref) async {
|
|
try {
|
|
if (_photo == '...' || _photo.isEmpty) {
|
|
return GestureDetector(
|
|
onTap: () {
|
|
_showChoiceDialog(context);
|
|
},
|
|
child: Container(
|
|
margin: EdgeInsets.symmetric(vertical: 50),
|
|
width: 100,
|
|
height: 100,
|
|
decoration: BoxDecoration(
|
|
color: Color(0xFF2BA4EC),
|
|
borderRadius: BorderRadius.circular(50),
|
|
),
|
|
child: Icon(
|
|
Icons.person,
|
|
color: Colors.white,
|
|
size: 90,
|
|
),
|
|
),
|
|
);
|
|
} else {
|
|
final imageData = await ref.getData();
|
|
if (imageData != null) {
|
|
final widgetImage = GestureDetector(
|
|
onTap: () {
|
|
_showChoiceDialog(context);
|
|
},
|
|
child: Container(
|
|
margin: EdgeInsets.symmetric(vertical: 50),
|
|
child: ClipOval(
|
|
child: Image.memory(
|
|
imageData,
|
|
width: 60,
|
|
height: 60,
|
|
fit: BoxFit.cover,
|
|
),
|
|
),
|
|
),
|
|
);
|
|
return widgetImage;
|
|
} else {
|
|
return GestureDetector(
|
|
onTap: () {
|
|
_showChoiceDialog(context);
|
|
},
|
|
child: Container(
|
|
margin: EdgeInsets.symmetric(vertical: 50),
|
|
width: 100,
|
|
height: 100,
|
|
decoration: BoxDecoration(
|
|
color: Color(0xFF2BA4EC),
|
|
borderRadius: BorderRadius.circular(50),
|
|
),
|
|
child: Icon(
|
|
Icons.person,
|
|
color: Colors.white,
|
|
size: 90,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
} catch (e) {
|
|
print('XD $e');
|
|
return GestureDetector(
|
|
onTap: () {
|
|
_showChoiceDialog(context);
|
|
},
|
|
child: Container(
|
|
margin: EdgeInsets.symmetric(vertical: 50),
|
|
width: 100,
|
|
height: 100,
|
|
decoration: BoxDecoration(
|
|
color: Color(0xFF2BA4EC),
|
|
borderRadius: BorderRadius.circular(50),
|
|
),
|
|
child: Icon(
|
|
Icons.person,
|
|
color: Colors.white,
|
|
size: 90,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> updateInfo() async {
|
|
final currentUser = _auth.currentUser;
|
|
|
|
String newName = _nameController.text.trim();
|
|
String newEmail = _emailController.text.trim();
|
|
String newPassword = _passwordController.text.trim();
|
|
|
|
if (newName.isEmpty) {
|
|
// Si el nuevo nombre está vacío, no lo actualizamos y mostramos un mensaje al usuario
|
|
Get.snackbar(
|
|
'Nombre Invalido',
|
|
'Ingrese un nombre válido.',
|
|
snackPosition: SnackPosition.BOTTOM,
|
|
);
|
|
return;
|
|
}
|
|
|
|
if (newEmail.isEmpty) {
|
|
// Si el nuevo nombre está vacío, no lo actualizamos y mostramos un mensaje al usuario
|
|
Get.snackbar(
|
|
'Correo Invalido',
|
|
'Ingrese un email válido.',
|
|
snackPosition: SnackPosition.BOTTOM,
|
|
);
|
|
return;
|
|
}
|
|
|
|
if (currentUser?.displayName != newName) {
|
|
try {
|
|
await FirebaseAuth.instance.currentUser!.updateDisplayName(newName);
|
|
await FirebaseFirestore.instance.collection('users').doc(uid).update({
|
|
'name': newName,
|
|
});
|
|
print('Nombre actualizado correctamente');
|
|
} catch (e) {
|
|
print('Error al actualizar el nombre: $e');
|
|
}
|
|
}
|
|
|
|
if (currentUser?.email != newEmail) {
|
|
if (newPassword.isNotEmpty) {
|
|
updateEmailAndPassword(newEmail, newPassword);
|
|
} else {
|
|
Get.snackbar(
|
|
'Contraseña Invalida',
|
|
'Porfavor ingrese una contraseña.',
|
|
snackPosition: SnackPosition.BOTTOM,
|
|
);
|
|
}
|
|
}
|
|
|
|
try {
|
|
if (imagen_to_upload == null) {
|
|
return;
|
|
} else {
|
|
final uploaded = await uploadImage(imagen_to_upload!);
|
|
updateImage(photoTemp);
|
|
//image
|
|
}
|
|
} catch (e) {
|
|
print('Error al actualizar la imagen de perfil $e');
|
|
}
|
|
}
|
|
|
|
Future<void> updateEmailAndPassword(String email, String password) async {
|
|
final User? user = FirebaseAuth.instance.currentUser;
|
|
if (user != null) {
|
|
try {
|
|
await user.updateEmail(email);
|
|
await user.updatePassword(password);
|
|
} catch (e) {
|
|
Get.snackbar(
|
|
'Agregar correo',
|
|
'Inicie sesión para asegurarnos de que seas tú .',
|
|
snackPosition: SnackPosition.BOTTOM,
|
|
);
|
|
AuthenticationRepository.instance.logout();
|
|
}
|
|
}
|
|
}
|
|
|
|
Future<void> _showChoiceDialog(BuildContext context) async {
|
|
return showDialog(
|
|
context: context,
|
|
builder: (BuildContext context) {
|
|
return AlertDialog(
|
|
content: SingleChildScrollView(
|
|
child: ListBody(
|
|
children: [
|
|
GestureDetector(
|
|
child: Text(
|
|
textAlign: TextAlign.center,
|
|
"Tomar foto",
|
|
style: TextStyle(color: Color(0xFF2BA4EC)),
|
|
),
|
|
onTap: () async {
|
|
final imagen = await getImage(1);
|
|
setState(() {
|
|
imagen_to_upload = File(imagen[0]!.path);
|
|
});
|
|
Navigator.of(context).pop();
|
|
},
|
|
),
|
|
Divider(color: Colors.black54),
|
|
GestureDetector(
|
|
child: Text(
|
|
textAlign: TextAlign.center,
|
|
"Abrir Galería",
|
|
style: TextStyle(color: Color(0xFF2BA4EC)),
|
|
),
|
|
onTap: () async {
|
|
final imagen = await getImage(2);
|
|
setState(() {
|
|
imagen_to_upload = File(imagen[0]!.path);
|
|
});
|
|
Navigator.of(context).pop();
|
|
},
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
final User? user = FirebaseAuth.instance.currentUser;
|
|
String city = _ciudad.toString();
|
|
String state = _estado.toString();
|
|
|
|
return SafeArea(
|
|
child: Scaffold(
|
|
resizeToAvoidBottomInset: false,
|
|
appBar: AppBar(
|
|
backgroundColor: Colors.white,
|
|
iconTheme: const IconThemeData(
|
|
color: Colors.black,
|
|
),
|
|
title: const Text(
|
|
'Perfil',
|
|
style: TextStyle(
|
|
color: Colors.black,
|
|
),
|
|
),
|
|
),
|
|
drawer: DrawerMenu(
|
|
ref: storage.ref().child(_photo),
|
|
userName: user?.displayName ?? '',
|
|
userPhoneNumber: user?.phoneNumber ?? '',
|
|
userCity: city,
|
|
userState: state),
|
|
body: Center(
|
|
child: Column(
|
|
children: [
|
|
GestureDetector(
|
|
onTap: () {
|
|
_showChoiceDialog(context);
|
|
},
|
|
child: Container(
|
|
margin: const EdgeInsets.symmetric(vertical: 50),
|
|
child: (imagen_to_upload != null)
|
|
? LocalPhoto(
|
|
file: imagen_to_upload!,
|
|
)
|
|
: ReferencePhoto(
|
|
ref: storage.ref().child(_photo),
|
|
)),
|
|
),
|
|
Container(
|
|
width: 300,
|
|
padding: const EdgeInsets.only(top: 0),
|
|
child: Form(
|
|
key: _formKey,
|
|
child: Column(
|
|
children: [
|
|
TextFormField(
|
|
controller: _nameController,
|
|
decoration: const InputDecoration(
|
|
prefixIcon: Icon(Icons.person_outline),
|
|
hintText: 'Nombre (Obligatorio)'),
|
|
),
|
|
const SizedBox(
|
|
height:
|
|
20.0), // Agrega espacio vertical entre los TextFormFields
|
|
_email != null
|
|
? TextFormField(
|
|
onTap: () {
|
|
Navigator.pushNamed(
|
|
context, '/nuevaPassword');
|
|
},
|
|
readOnly: true,
|
|
controller: _emailController,
|
|
decoration: const InputDecoration(
|
|
prefixIcon: Icon(Icons.email_outlined),
|
|
hintText: 'Email (Obligatorio)'),
|
|
)
|
|
: TextFormField(
|
|
controller: _emailController,
|
|
decoration: const InputDecoration(
|
|
prefixIcon: Icon(Icons.email_outlined),
|
|
hintText: 'Email (Obligatorio)'),
|
|
),
|
|
const SizedBox(height: 20.0),
|
|
_email != null
|
|
? const SizedBox.shrink()
|
|
: TextFormField(
|
|
controller: _passwordController,
|
|
obscureText: _obscureText,
|
|
decoration: InputDecoration(
|
|
prefixIcon: const Icon(Icons.lock_outline),
|
|
suffixIcon: IconButton(
|
|
icon: Icon(
|
|
_obscureText
|
|
? Icons.visibility
|
|
: Icons.visibility_off,
|
|
color: Colors.grey,
|
|
),
|
|
onPressed: () {
|
|
setState(() {
|
|
_obscureText = !_obscureText;
|
|
});
|
|
},
|
|
),
|
|
hintText: 'Contraseña (Obligatorio)'),
|
|
),
|
|
_email != null
|
|
? const SizedBox.shrink()
|
|
: const SizedBox(height: 20.0),
|
|
TextFormField(
|
|
readOnly: true,
|
|
onTap: () async {
|
|
final String? ciudad =
|
|
(await Navigator.pushNamed(context, '/city'))
|
|
as String?;
|
|
|
|
if (ciudad != null) {
|
|
setState(() {
|
|
_ciudad = ciudad as String;
|
|
});
|
|
}
|
|
},
|
|
decoration: InputDecoration(
|
|
prefixIcon: Icon(Icons.near_me),
|
|
suffixIcon: Icon(Icons.arrow_drop_down),
|
|
hintStyle: city == ''
|
|
? TextStyle()
|
|
: TextStyle(color: Colors.black87),
|
|
hintText: city == '' ? 'Ciudad' : '$city'),
|
|
),
|
|
const SizedBox(height: 20.0),
|
|
TextFormField(
|
|
controller: _phoneNumberController,
|
|
readOnly: true,
|
|
onTap: () {
|
|
Navigator.pushNamed(context, '/newNumber');
|
|
},
|
|
decoration: InputDecoration(
|
|
prefixIcon: Icon(Icons.phone_android),
|
|
suffixIcon: Icon(Icons.edit_outlined),
|
|
hintText: '+57'),
|
|
),
|
|
],
|
|
)),
|
|
),
|
|
Container(
|
|
alignment: Alignment.bottomCenter,
|
|
margin: EdgeInsets.only(top: 100),
|
|
child: ElevatedButton(
|
|
onPressed: () async {
|
|
await updateInfo();
|
|
},
|
|
child: Text(
|
|
'Guardar',
|
|
style: TextStyle(
|
|
color: Colors.white,
|
|
fontWeight: FontWeight.bold,
|
|
fontSize: 17,
|
|
),
|
|
),
|
|
style: ElevatedButton.styleFrom(
|
|
backgroundColor: Color(0xFF2BA4EC),
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(50),
|
|
),
|
|
elevation: 0,
|
|
minimumSize: Size(200, 50),
|
|
),
|
|
)),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|