Files
prosappweb/lib/src/screens/profile.dart
T
2023-04-13 11:26:31 -05:00

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),
),
)),
],
),
),
),
);
}
}