diff --git a/lib/src/authentication/authentication_repository.dart b/lib/src/authentication/authentication_repository.dart index c467741..6dbbf68 100644 --- a/lib/src/authentication/authentication_repository.dart +++ b/lib/src/authentication/authentication_repository.dart @@ -176,6 +176,19 @@ class AuthenticationRepository extends GetxController { return photo; } + Future getBanner(String uid) async { + String photo = ''; + try { + final snapshot = + await FirebaseFirestore.instance.collection('users').doc(uid).get(); + final Map? data = snapshot.data(); + photo = data?['banner'] ?? ''; + } catch (e) { + print('Error getting banner: $e'); + } + return photo; + } + Future getProfession(String uid) async { String profession = ''; try { diff --git a/lib/src/components/banner_photo.dart b/lib/src/components/banner_photo.dart index b3b5fac..2a5a091 100644 --- a/lib/src/components/banner_photo.dart +++ b/lib/src/components/banner_photo.dart @@ -26,6 +26,7 @@ class ReferenceBannerPhoto extends StatelessWidget { if (imageData != null) { return Image.memory( imageData, + width: double.infinity, height: size, fit: BoxFit.fill, ); diff --git a/lib/src/components/schedule_picker.dart b/lib/src/components/schedule_picker.dart index 4d76ee4..1ee86d4 100644 --- a/lib/src/components/schedule_picker.dart +++ b/lib/src/components/schedule_picker.dart @@ -1,4 +1,6 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; import 'package:prosappco/src/components/primary_btn.dart'; typedef TimeCallback = void Function(TimeOfDay? pickedTime); @@ -60,8 +62,8 @@ class _SchedulePickerState extends State { const Text('-'), ] : []), - datePicker(widget.schedule.range1Hour2, - (pickedTime) => widget.schedule.range1Hour2 = pickedTime), + datePicker(widget.schedule.range2Hour2, + (pickedTime) => widget.schedule.range2Hour2 = pickedTime), ]), ), ]; @@ -137,4 +139,74 @@ class Schedule { Schedule(this.habilitado, this.jornadaContinua, this.range1Hour1, this.range1Hour2, this.range2Hour1, this.range2Hour2); + + static Future> fromJson( + Map? json) async { + try { + if (json == null) { + return { + "Lunes": Schedule(false, false, null, null, null, null), + "Martes": Schedule(false, false, null, null, null, null), + "Miercoles": Schedule(false, false, null, null, null, null), + "Jueves": Schedule(false, false, null, null, null, null), + "Viernes": Schedule(false, false, null, null, null, null), + "Sabado": Schedule(false, false, null, null, null, null), + "Domingo": Schedule(false, false, null, null, null, null), + }; + } + Map horarios = json['horario']; + horarios.entries; + print('Entrada ${horarios.entries}'); + var hora = horarios.map((key, value) => MapEntry( + key, + Schedule( + value['habilitado'], + value['jornadaContinua'], + stringToTimeOfDay(value['range1Hour1']), + stringToTimeOfDay(value['range1Hour2']), + stringToTimeOfDay(value['range2Hour1']), + stringToTimeOfDay(value['range2Hour2'])))); + + print('Entradas ${hora}'); + return hora; + } catch (e) { + return { + "Lunes": Schedule(false, false, null, null, null, null), + "Martes": Schedule(false, false, null, null, null, null), + "Miercoles": Schedule(false, false, null, null, null, null), + "Jueves": Schedule(false, false, null, null, null, null), + "Viernes": Schedule(false, false, null, null, null, null), + "Sabado": Schedule(false, false, null, null, null, null), + "Domingo": Schedule(false, false, null, null, null, null), + }; + } + } + + static TimeOfDay stringToTimeOfDay(String? tod) { + if (tod == null) { + return TimeOfDay.now(); + } + final format = DateFormat.jm(); + return TimeOfDay.fromDateTime(format.parse(tod)); + } + + static Future> getHorarios(String uid) async { + try { + final snapshot = + await FirebaseFirestore.instance.collection('users').doc(uid).get(); + final Map? data = snapshot.data(); + return fromJson(data); + } catch (e) { + print('Error getting user: $e'); + return { + "Lunes": Schedule(false, false, null, null, null, null), + "Martes": Schedule(false, false, null, null, null, null), + "Miercoles": Schedule(false, false, null, null, null, null), + "Jueves": Schedule(false, false, null, null, null, null), + "Viernes": Schedule(false, false, null, null, null, null), + "Sabado": Schedule(false, false, null, null, null, null), + "Domingo": Schedule(false, false, null, null, null, null), + }; + } + } } diff --git a/lib/src/screens/horario.dart b/lib/src/screens/horario.dart index 3e5a05c..012495c 100644 --- a/lib/src/screens/horario.dart +++ b/lib/src/screens/horario.dart @@ -1,23 +1,28 @@ import 'package:cloud_firestore/cloud_firestore.dart'; -import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; import 'package:prosappco/src/authentication/authentication_repository.dart'; import 'package:prosappco/src/components/pop_appbar.dart'; import 'package:prosappco/src/components/primary_btn.dart'; +import 'package:prosappco/src/screens/profile_pro.dart'; import '../components/schedule_picker.dart'; class HorarioScreen extends StatefulWidget { - const HorarioScreen({super.key}); + Map horarios; + HorarioScreen({super.key, required this.horarios}); @override State createState() => _HorarioScreenState(); } class _HorarioScreenState extends State { - late final FirebaseAuth _auth; final uid = AuthenticationRepository.instance.getCurrentUserUid(); + @override + void initState() { + super.initState(); + } + bool lunesValue = false; bool martesValue = false; bool miercolesValue = false; @@ -27,20 +32,10 @@ class _HorarioScreenState extends State { bool domingoValue = false; bool jornadaContinuaLunes = false; - Map horarios = { - "Lunes": Schedule(false, false, null, null, null, null), - "Martes": Schedule(false, false, null, null, null, null), - "Miercoles": Schedule(false, false, null, null, null, null), - "Jueves": Schedule(false, false, null, null, null, null), - "Viernes": Schedule(false, false, null, null, null, null), - "Sabado": Schedule(false, false, null, null, null, null), - "Domingo": Schedule(false, false, null, null, null, null), - }; - Future updateHorario() async { try { Map horariosMap = {}; - horarios.forEach((key, value) { + widget.horarios.forEach((key, value) { horariosMap[key] = { 'habilitado': value.habilitado, 'jornadaContinua': value.jornadaContinua, @@ -74,7 +69,10 @@ class _HorarioScreenState extends State { child: Scaffold( appBar: PopAppbar( onPressed: () { - Navigator.pop(context); + Navigator.pushReplacement( + context, + MaterialPageRoute(builder: (context) => const ProfilePro()), + ); }, label: 'Horario'), body: SingleChildScrollView( @@ -84,7 +82,7 @@ class _HorarioScreenState extends State { height: 5, ), Column( - children: horarios.entries.map( + children: widget.horarios.entries.map( (entry) { return SchedulePicker( name: entry.key, @@ -97,7 +95,11 @@ class _HorarioScreenState extends State { padding: const EdgeInsets.only(top: 100, bottom: 30), child: PrimaryButtom( onPressed: () async { - updateHorario(); + updateHorario().then((value) => Navigator.pushReplacement( + context, + MaterialPageRoute( + builder: (context) => const ProfilePro()), + )); }, label: 'Guardar'), ) diff --git a/lib/src/screens/profile.dart b/lib/src/screens/profile.dart index 74591d0..b3c6edb 100644 --- a/lib/src/screens/profile.dart +++ b/lib/src/screens/profile.dart @@ -6,7 +6,6 @@ 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/components/pop_appbar.dart'; import 'package:prosappco/src/controllers/add_name_email_city.dart'; import 'package:prosappco/src/screens/city.dart'; @@ -155,7 +154,7 @@ class _ProfileScreenState extends State { _showChoiceDialog(context); }, child: Container( - margin: EdgeInsets.symmetric(vertical: 50), + margin: const EdgeInsets.symmetric(vertical: 50), child: ClipOval( child: Image.memory( imageData, diff --git a/lib/src/screens/profile_pro.dart b/lib/src/screens/profile_pro.dart index a99e073..18425a1 100644 --- a/lib/src/screens/profile_pro.dart +++ b/lib/src/screens/profile_pro.dart @@ -1,14 +1,16 @@ 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/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_animate/flutter_animate.dart'; import 'package:prosappco/src/authentication/authentication_repository.dart'; import 'package:prosappco/src/components/banner_photo.dart'; -import 'package:prosappco/src/components/column_padding.dart'; import 'package:prosappco/src/components/drawer_professional.dart'; import 'package:prosappco/src/components/primary_btn.dart'; +import 'package:prosappco/src/components/schedule_picker.dart'; import 'package:prosappco/src/screens/horario.dart'; import 'package:prosappco/src/screens/professional.dart'; import 'package:prosappco/src/services/select_image_profile.dart'; @@ -21,31 +23,191 @@ class ProfilePro extends StatefulWidget { } class _ProfileProState extends State { + final uid = AuthenticationRepository.instance.getCurrentUserUid(); + File? image_portada; File? imagen_to_upload; bool domicilioValue = false; bool sitioValue = false; + var photoTemp = ''; var _photo = '...'; + Map? _horarios; @override void initState() { super.initState(); final uid = AuthenticationRepository.instance.getCurrentUserUid(); - late final FirebaseAuth _auth; - _auth = FirebaseAuth.instance; if (_photo == '...') { - AuthenticationRepository.instance.getPhoto(uid.toString()).then( + AuthenticationRepository.instance.getBanner(uid.toString()).then( (String s) => setState( () { _photo = s; + print('HOLA $s'); }, ), ); } + + if (_horarios == null) { + Schedule.getHorarios(uid.toString()).then( + (Map s) => setState( + () { + _horarios = s; + }, + ), + ); + } + } + + Future updateInfo() async { + 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 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: const 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: const EdgeInsets.symmetric(vertical: 50), + // width: 100, + // height: 100, + // decoration: BoxDecoration( + // color: const Color(0xFF2BA4EC), + // borderRadius: BorderRadius.circular(50), + // ), + // child: const Icon( + // Icons.person, + // color: Colors.white, + // size: 90, + // ), + // ), + // ); + // } + // } + // } catch (e) { + // print('XD $e'); + // return GestureDetector( + // onTap: () { + // _showChoiceDialog(context); + // }, + // child: Container( + // margin: const EdgeInsets.symmetric(vertical: 50), + // width: 100, + // height: 100, + // decoration: BoxDecoration( + // color: const Color(0xFF2BA4EC), + // borderRadius: BorderRadius.circular(50), + // ), + // child: const Icon( + // Icons.person, + // color: Colors.white, + // size: 90, + // ), + // ), + // ); + // } + // } + + Future updateImage(image) async { + try { + await FirebaseFirestore.instance + .collection('users') + .doc(uid) + .update({'banner': image}); + + print('imagen actualizada correctamente'); + } catch (e) { + try { + await FirebaseFirestore.instance + .collection('users') + .doc(uid) + .set({'banner': image}); + } catch (e) { + print('Error al agregar la imagen de perfil: $e'); + } + + print('Error al actualizar la imagen de perfil: $e'); + } + } + + Future 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 _showChoiceDialog(BuildContext context) async { @@ -124,7 +286,7 @@ class _ProfileProState extends State { file: imagen_to_upload!, ) : ReferenceBannerPhoto( - ref: storage.ref().child('_photo'), + ref: storage.ref().child(_photo), ), ), ), @@ -191,7 +353,9 @@ class _ProfileProState extends State { context, CupertinoPageRoute( builder: (BuildContext context) { - return const HorarioScreen(); + return HorarioScreen( + horarios: _horarios!, + ); }, ), ); @@ -223,7 +387,7 @@ class _ProfileProState extends State { ), ), Padding( - padding: EdgeInsets.only(right: 35), + padding: EdgeInsets.only(right: 45), child: Icon(Icons.edit_outlined), ), ], @@ -251,17 +415,18 @@ class _ProfileProState extends State { ), ), Padding( - padding: const EdgeInsets.only(left: 35), + padding: const EdgeInsets.only(left: 25), child: Column( crossAxisAlignment: CrossAxisAlignment.start, - children: const [ - Text('N/A'), - Text('N/A'), - Text('N/A'), - Text('N/A'), - Text('N/A'), - Text('N/A'), - Text('N/A'), + children: [ + Text(timeList(_horarios?['Lunes'], context)), + Text(timeList(_horarios?['Martes'], context)), + Text( + timeList(_horarios?['Miercoles'], context)), + Text(timeList(_horarios?['Jueves'], context)), + Text(timeList(_horarios?['Viernes'], context)), + Text(timeList(_horarios?['Sabado'], context)), + Text(timeList(_horarios?['Domingo'], context)), ], ), ), @@ -271,7 +436,11 @@ class _ProfileProState extends State { ], ), ), - PrimaryButtom(onPressed: () {}, label: 'Guardar'), + PrimaryButtom( + onPressed: () { + updateInfo(); + }, + label: 'Guardar'), const SizedBox( height: 20, ) @@ -313,4 +482,19 @@ class _ProfileProState extends State { ), ); } + + String timeList(Schedule? schedule, BuildContext context) { + if (schedule == null) { + return 'N/A'; + } + + if (!schedule.habilitado) { + return 'N/A'; + } + if (schedule.jornadaContinua) { + return '${schedule.range1Hour1?.format(context).toString()} - ${schedule.range1Hour2?.format(context).toString()}'; + } else { + return '${schedule.range1Hour1?.format(context).toString()} - ${schedule.range1Hour2?.format(context).toString()}; ${schedule.range2Hour1?.format(context).toString()} - ${schedule.range2Hour2?.format(context).toString()}'; + } + } } diff --git a/pubspec.lock b/pubspec.lock index 8ba441b..1b9631b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -353,7 +353,7 @@ packages: source: hosted version: "2.6.3" intl: - dependency: transitive + dependency: "direct main" description: name: intl sha256: "910f85bce16fb5c6f614e117efa303e85a1731bb0081edf3604a2ae6e9a3cc91" diff --git a/pubspec.yaml b/pubspec.yaml index 1e4f2c2..cb7aa4c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -51,6 +51,7 @@ dependencies: image_picker: ^0.8.7+1 flutter_animate: ^4.1.1+1 flutter_rating_bar: ^4.0.1 + intl: dev_dependencies: flutter_test: