Files
prosappweb/lib/src/screens/professional_profile.dart
T

686 lines
22 KiB
Dart

import 'dart:io';
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 'package:prosappco/src/authentication/authentication_repository.dart';
import 'package:prosappco/src/components/photo_view.dart';
import 'package:prosappco/src/components/pop_appbar.dart';
import 'package:prosappco/src/controllers/info_%20professional.dart';
import 'package:prosappco/src/services/select_image_profile.dart';
class ProfessionalProfileScreen extends StatefulWidget {
const ProfessionalProfileScreen({super.key});
@override
State<ProfessionalProfileScreen> createState() =>
ProfessionalProfileScreenState();
}
class ProfessionalProfileScreenState extends State<ProfessionalProfileScreen> {
File? imagen_to_upload;
File? image_cedula;
File? image_certificado;
late final FirebaseAuth _auth;
final FirebaseStorage storage = FirebaseStorage.instance;
final uid = AuthenticationRepository.instance.getCurrentUserUid();
final _formKey = GlobalKey<FormState>();
final controller = Get.put(InforProfessionalController());
final _cedulaController = TextEditingController();
final _especializacionController = TextEditingController();
List<File> images_especializacion = [];
var _profession = '...';
var photoTemp = '';
var _photo = '...';
@override
void initState() {
super.initState();
_auth = FirebaseAuth.instance;
if (_photo == '...') {
AuthenticationRepository.instance
.getPhoto(uid.toString())
.then((String s) => setState(() {
_photo = s;
}));
}
if (_profession == '...') {
AuthenticationRepository.instance
.getProfession(uid.toString())
.then((String s) => setState(() {
_profession = s;
}));
}
}
Future<void> _showChoiceDialog(BuildContext context) async {
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
content: SingleChildScrollView(
child: ListBody(
children: [
GestureDetector(
child: const 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();
},
),
const Divider(color: Colors.black54),
GestureDetector(
child: const 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();
},
),
],
),
),
);
},
);
}
Future<void> _showChoiceDialogCedula(BuildContext context) async {
return showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
content: SingleChildScrollView(
child: ListBody(
children: [
GestureDetector(
child: const Text(
textAlign: TextAlign.center,
"Tomar foto",
style: TextStyle(color: Color(0xFF2BA4EC)),
),
onTap: () async {
final imagen = await getImage(1);
setState(() {
image_cedula = File(imagen[0]!.path);
});
Navigator.of(context).pop();
},
),
const Divider(color: Colors.black54),
GestureDetector(
child: const Text(
textAlign: TextAlign.center,
"Abrir Galería",
style: TextStyle(color: Color(0xFF2BA4EC)),
),
onTap: () async {
final imagen = await getImage(2);
setState(() {
image_cedula = File(imagen[0]!.path);
});
Navigator.of(context).pop();
},
),
],
),
),
);
},
);
}
Future<void> _showChoiceDialogCertificado(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(() {
image_certificado = 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(() {
image_certificado = File(imagen[0]!.path);
});
Navigator.of(context).pop();
},
),
],
),
),
);
},
);
}
Future<bool> uploadCedula(File image) async {
final String namefile = image.path.split('/').last;
Reference ref = storage
.ref()
.child('users')
.child(uid!)
.child('cedula')
.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<List<String>> uploadEspecializaciones(List<File> images) async {
List<String> photoPaths = [];
for (File image in images) {
final String namefile = image.path.split('/').last;
Reference ref = storage
.ref()
.child('users')
.child(uid!)
.child('especializaciones')
.child(namefile);
final UploadTask uploadTask = ref.putFile(image);
final TaskSnapshot snapshot = await uploadTask.whenComplete(() => true);
photoPaths.add(ref.fullPath);
if (snapshot.state != TaskState.success) {
return [];
}
}
return photoPaths;
}
Future<bool> uploadCertificado(File image) async {
final String namefile = image.path.split('/').last;
Reference ref = storage
.ref()
.child('users')
.child(uid!)
.child('certificado_profesional')
.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<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<void> sendInfo() async {
final String cedula = _cedulaController.text.trim();
final String especializacion = _especializacionController.text.trim();
final List<String> especializaciones =
especializacion.split(',').map((e) => e.trim()).toList();
if (cedula.isEmpty) {
showSnackBar('Ingrese una cedula válida');
return;
}
if (image_cedula == null) {
showSnackBar('Ingrese la imagen de la cedula');
return;
}
if (image_certificado == null) {
showSnackBar('Ingrese la imagen de su certificado');
return;
}
// Actualiza los datos del usuario en Firestore
await FirebaseFirestore.instance.collection('users').doc(uid).update({
'cedula': cedula,
'estado': 'revision',
'especializaciones': especializaciones
});
// Sube las imágenes al storage de Firebase
uploadCedula(image_cedula!);
uploadCertificado(image_certificado!);
uploadEspecializaciones(images_especializacion);
// Actualiza la imagen de perfil si hay cambios
if (imagen_to_upload != null) {
updateImage(photoTemp);
}
// Navega a la siguiente pantalla
Navigator.pushReplacementNamed(context, '/solicitudEnviada');
}
void showSnackBar(String message) {
ScaffoldMessenger.of(context)
.showSnackBar(SnackBar(content: Text(message)));
}
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: const Icon(
Icons.person,
color: Colors.white,
size: 90,
),
),
);
} else {
final imageData = await ref.getData();
if (imageData != null) {
// final widgetImage = Image.memory(imageData);
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('$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,
),
),
);
}
}
@override
Widget build(BuildContext context) {
final User? user = FirebaseAuth.instance.currentUser;
String profession = _profession.toString();
double _space = 10;
return SafeArea(
child: Scaffold(
appBar: PopAppbar(
onPressed: () {
Navigator.pop(context);
},
label: 'Perfil profesional'),
body: SingleChildScrollView(
reverse: true,
child: Center(
child: Column(
children: [
GestureDetector(
onTap: () {
_showChoiceDialog(context);
},
child: Container(
margin: const EdgeInsets.symmetric(vertical: 25),
child: (imagen_to_upload != null)
? LocalPhoto(
file: imagen_to_upload!,
)
: ReferencePhoto(
ref: storage.ref().child(_photo),
size: 100,
sizeCircle: 100,
),
),
),
Container(
width: 300,
padding: const EdgeInsets.only(top: 0),
child: Form(
key: _formKey,
child: Column(
children: [
TextFormField(
keyboardType: TextInputType.number,
controller: _cedulaController,
decoration: const InputDecoration(
prefixIcon: Icon(Icons.person_outline),
hintText: 'Cedula (Obligatorio)'),
),
SizedBox(height: _space),
ElevatedButton(
onPressed: () {
_showChoiceDialogCedula(context);
},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFFD6F4FF),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
elevation: 0,
minimumSize: const Size(250, 50),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'Cedula',
style: TextStyle(
color: Color(0xFF2BA4EC),
fontSize: 17,
),
),
const SizedBox(width: 15),
Icon(
image_cedula != null
? Icons.check
: Icons.file_upload_outlined,
color: const Color(0xFF2BA4EC),
size: 30,
),
],
),
),
SizedBox(height: _space),
TextFormField(
readOnly: true,
onTap: () async {
final String? profesion =
(await Navigator.pushNamed(
context, '/profession')) as String?;
if (profesion != null) {
setState(() {
_profession = profesion;
});
}
},
decoration: InputDecoration(
prefixIcon:
const Icon(Icons.assignment_ind_rounded),
suffixIcon: const Icon(Icons.arrow_drop_down),
hintStyle: profession == ''
? const TextStyle()
: const TextStyle(color: Colors.black87),
hintText: profession == ''
? 'Profesión (Obligatorio)'
: profession),
),
SizedBox(height: _space),
ElevatedButton(
onPressed: () {
_showChoiceDialogCertificado(context);
},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFFD6F4FF),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
elevation: 0,
minimumSize: const Size(250, 50),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'Certificado profesional',
style: TextStyle(
color: Color(0xFF2BA4EC),
fontSize: 17,
),
),
const SizedBox(width: 15),
Icon(
image_certificado != null
? Icons.check
: Icons.file_upload_outlined,
color: const Color(0xFF2BA4EC),
size: 30,
),
],
),
),
SizedBox(height: _space),
TextFormField(
controller: _especializacionController,
decoration: const InputDecoration(
prefixIcon: Icon(Icons.assignment_ind_rounded),
hintText: 'Especialización'),
),
SizedBox(height: _space),
ElevatedButton(
onPressed: () async {
final images = await getImage(3);
setState(() {
images_especializacion =
images.map((e) => File(e!.path)).toList();
});
},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFFD6F4FF),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
elevation: 0,
minimumSize: const Size(250, 50),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: [
const Text(
'Especialización',
style: TextStyle(
color: Color(0xFF2BA4EC),
fontSize: 17,
),
),
const SizedBox(width: 15),
Icon(
images_especializacion.isEmpty
? Icons.file_upload_outlined
: Icons.check,
color: const Color(0xFF2BA4EC),
size: 30,
),
],
),
),
],
)),
),
Container(
alignment: Alignment.bottomCenter,
margin: const EdgeInsets.only(
top: 80, right: 70, left: 70, bottom: 30),
child: ElevatedButton(
onPressed: () {
sendInfo();
},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF2BA4EC),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
elevation: 0,
minimumSize: const Size(250, 50),
),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: const [
Text(
'Enviar información',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 17,
),
),
SizedBox(width: 15),
Icon(
Icons.send,
color: Colors.white,
size: 20,
),
],
),
),
),
],
),
),
),
));
}
}