diff --git a/lib/src/components/drawer_menu.dart b/lib/src/components/drawer_menu.dart index 305f2ef..6398408 100644 --- a/lib/src/components/drawer_menu.dart +++ b/lib/src/components/drawer_menu.dart @@ -7,6 +7,7 @@ import 'package:prosappco/src/authentication/authentication_repository.dart'; import 'package:prosappco/src/components/photo_view.dart'; import 'package:prosappco/src/models/user_model.dart'; import 'package:prosappco/src/screens/profile.dart'; +import 'package:prosappco/src/screens/prueba.dart'; class DrawerMenu extends StatefulWidget { @override @@ -292,7 +293,14 @@ class _DrawerMenuState extends State { } else if (user?.state == 'revision') { Navigator.pushNamed(context, '/profesionalRevision'); } else if (user?.state == 'activo') { - Navigator.pushNamed(context, '/profilePro'); + Navigator.push( + context, + CupertinoPageRoute( + builder: (BuildContext context) { + return const PruebaScreen(); + }, + ), + ); } }, style: ElevatedButton.styleFrom( diff --git a/lib/src/components/drawer_professional.dart b/lib/src/components/drawer_professional.dart index 68a8238..59c9956 100644 --- a/lib/src/components/drawer_professional.dart +++ b/lib/src/components/drawer_professional.dart @@ -1,3 +1,4 @@ +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'; @@ -5,9 +6,14 @@ import 'package:flutter/material.dart'; import 'package:flutter_rating_bar/flutter_rating_bar.dart'; import 'package:prosappco/src/authentication/authentication_repository.dart'; import 'package:prosappco/src/components/photo_view.dart'; +import 'package:prosappco/src/models/score_model.dart'; import 'package:prosappco/src/models/user_model.dart'; import 'package:prosappco/src/screens/calendar.dart'; +import 'package:prosappco/src/screens/professional.dart'; +import 'package:prosappco/src/screens/professional_profile.dart'; import 'package:prosappco/src/screens/profile.dart'; +import 'package:prosappco/src/screens/profile_pro.dart'; +import 'package:prosappco/src/screens/reputation.dart'; class DrawerProfessional extends StatefulWidget { @override @@ -112,7 +118,16 @@ class _DrawerProfessionalState extends State { ), ), ListTile( - onTap: () {}, + onTap: () { + Navigator.push( + context, + CupertinoPageRoute( + builder: (BuildContext context) { + return const ProfilePro(); + }, + ), + ); + }, leading: const Icon( Icons.person_outline, color: Colors.black, @@ -211,7 +226,20 @@ class _DrawerProfessionalState extends State { child: Container( color: Colors.white, child: ListTile( - onTap: () {}, + onTap: () async { + var professional = + await Professional.getProfessional(uid!); + + Navigator.push( + context, + CupertinoPageRoute( + builder: (BuildContext context) { + return ReputationScreen( + professional: professional!); + }, + ), + ); + }, trailing: const Icon(Icons.keyboard_arrow_right, color: Colors.black), title: const Text( diff --git a/lib/src/models/event_model.dart b/lib/src/models/event_model.dart index d5b1b80..7577248 100644 --- a/lib/src/models/event_model.dart +++ b/lib/src/models/event_model.dart @@ -13,7 +13,7 @@ class EventoService { ) async { try { await FirebaseFirestore.instance.collection('services').add({ - 'profesional_id': uid, + 'user_id': uid, 'title': title, 'description': description, 'day': day, @@ -34,7 +34,7 @@ Future> getByProId(String day) async { try { var snapshot = await FirebaseFirestore.instance .collection('services') - .where('profesional_id', isEqualTo: uid) + .where('user_id', isEqualTo: uid) .where('day', isEqualTo: day.toString()) .get(); @@ -56,7 +56,7 @@ class Event { String? day; String? range1Hour1; String? range1Hour2; - String? profesionalId; + String? userId; Event({ this.title, @@ -64,7 +64,7 @@ class Event { this.day, this.range1Hour1, this.range1Hour2, - this.profesionalId, + this.userId, }); factory Event.fromJson(Map json) { @@ -74,7 +74,7 @@ class Event { day: json['day'], range1Hour1: json['range1Hour1'], range1Hour2: json['range1Hour2'], - profesionalId: json['profesional_id'], + userId: json['user_id'], ); } @@ -82,7 +82,7 @@ class Event { try { var snapshot = await FirebaseFirestore.instance .collection('services') - .where('profesional_id', isEqualTo: uid) + .where('user_id', isEqualTo: uid) .get(); List eventos = []; diff --git a/lib/src/models/score_model2.dart b/lib/src/models/score_model2.dart new file mode 100644 index 0000000..aeed790 --- /dev/null +++ b/lib/src/models/score_model2.dart @@ -0,0 +1,95 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:firebase_storage/firebase_storage.dart'; +import 'package:prosappco/src/models/user_model.dart'; + +class ScoresModel { + late int total; + late double average; + final List scores; + + ScoresModel(this.scores) { + total = scores.length; + average = averageScore(scores); + } + + double averageScore(List scores) { + if (scores.isEmpty) { + return 0.0; + } + final sum = scores.map((score) => score.score).reduce((a, b) => a + b); + return sum / scores.length; + } + + // Me + static Future scoreTo(String userReceived, bool userInfo) async { + final receivedScoresQuery = FirebaseFirestore.instance + .collection('scores') + .where('to_user', isEqualTo: userReceived); + + final receivedScoresSnapshot = await receivedScoresQuery.get(); + + final receivedScores = await Future.wait(receivedScoresSnapshot.docs + .map((doc) async => + await ScoreModel2.fromDocumentSnapshot(doc, userInfo)) + .toList()); + + return ScoresModel(receivedScores); + } + + // You + static Future scoreFrom(String userGiven, bool userInfo) async { + final givenScoresQuery = FirebaseFirestore.instance + .collection('scores') + .where('from_user', isEqualTo: userGiven); + + final givenScoresSnapshot = await givenScoresQuery.get(); + + final givenScores = await Future.wait(givenScoresSnapshot.docs + .map((doc) async => + await ScoreModel2.fromDocumentSnapshot(doc, userInfo)) + .toList()); + + return ScoresModel(givenScores); + } +} + +class ScoreModel2 { + final String id; + final double score; + final String fromUser; + final String toUser; + final String comment; + + final String name; + final Reference? avatar; + + ScoreModel2({ + required this.id, + required this.score, + required this.fromUser, + required this.toUser, + required this.comment, + required this.name, + required this.avatar, + }); + + static Future fromDocumentSnapshot( + DocumentSnapshot> snapshot, bool userInfo) async { + try { + final Map data = snapshot.data()!; + final user = userInfo ? await UserModel.getUser(data['from_user']) : null; + + return ScoreModel2( + id: snapshot.id, + score: double.parse(data['score'].toString()), + fromUser: data['from_user'], + toUser: data['to_user'], + comment: data['comment'], + name: user?.name ?? "...", + avatar: user?.photo); + } catch (e) { + print('error en score $e'); + rethrow; + } + } +} diff --git a/lib/src/screens/calendar.dart b/lib/src/screens/calendar.dart index dcacf4f..bcaebd0 100644 --- a/lib/src/screens/calendar.dart +++ b/lib/src/screens/calendar.dart @@ -1,11 +1,10 @@ -import 'dart:ffi'; - -import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:flutter/cupertino.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/models/event_model.dart'; +import 'package:prosappco/src/screens/cita.dart'; import 'package:table_calendar/table_calendar.dart'; import 'package:intl/intl.dart'; @@ -90,64 +89,62 @@ class _CalendarScreenState extends State { // DateTime firstDay = today.subtract(Duration(days: 365)); DateTime lastDay = today.add(const Duration(days: 365)); - return SafeArea( - child: Scaffold( - resizeToAvoidBottomInset: false, - appBar: PopAppbar( - onPressed: () { - Navigator.pop(context); - }, - label: 'Calendario', - ), - body: Column( - children: [ - Container( - color: const Color.fromARGB(255, 224, 247, 255), - child: TableCalendar( - locale: 'es_MX', - firstDay: DateTime.utc(2010, 10, 16), - lastDay: lastDay, - focusedDay: today, - availableGestures: AvailableGestures.all, - onDaySelected: _onDaySelected, - selectedDayPredicate: (day) => isSameDay(day, today), - calendarFormat: _calendarFormat, - onFormatChanged: _onFormatChange, - eventLoader: (date) { - return events - .where((element) { - DateTime day = DateTime.parse(element.day ?? ""); - return (date.year == day.year && - date.month == day.month && - date.day == day.day); - }) - .map((e) => e.description) - .toList(); - }, - availableCalendarFormats: const { - CalendarFormat.month: 'Mes', - CalendarFormat.week: 'Semana', - CalendarFormat.twoWeeks: '2 Semanas', - }, - ), + return Scaffold( + resizeToAvoidBottomInset: false, + appBar: PopAppbar( + onPressed: () { + Navigator.pop(context); + }, + label: 'Calendario', + ), + body: Column( + children: [ + Container( + color: const Color.fromARGB(255, 224, 247, 255), + child: TableCalendar( + locale: 'es_MX', + firstDay: DateTime.utc(2010, 10, 16), + lastDay: lastDay, + focusedDay: today, + availableGestures: AvailableGestures.all, + onDaySelected: _onDaySelected, + selectedDayPredicate: (day) => isSameDay(day, today), + calendarFormat: _calendarFormat, + onFormatChanged: _onFormatChange, + eventLoader: (date) { + return events + .where((element) { + DateTime day = DateTime.parse(element.day ?? ""); + return (date.year == day.year && + date.month == day.month && + date.day == day.day); + }) + .map((e) => e.description) + .toList(); + }, + availableCalendarFormats: const { + CalendarFormat.month: 'Mes', + CalendarFormat.week: 'Semana', + CalendarFormat.twoWeeks: '2 Semanas', + }, ), - SizedBox( - width: double.infinity, - child: Padding( - padding: - const EdgeInsets.symmetric(horizontal: 15, vertical: 8), - child: Text(DateFormat('dd MMMM yyyy', 'es').format(today)), - )), - const Divider( - height: 0, - ), - _eventList() - ], - ), - floatingActionButton: FloatingActionButton( - onPressed: _showDialog, - child: const Icon(Icons.add), - ), + ), + SizedBox( + width: double.infinity, + child: Padding( + padding: + const EdgeInsets.symmetric(horizontal: 15, vertical: 8), + child: Text(DateFormat('dd MMMM yyyy', 'es').format(today)), + )), + const Divider( + height: 0, + ), + _eventList() + ], + ), + floatingActionButton: FloatingActionButton( + onPressed: _showDialog, + child: const Icon(Icons.add), ), ); } @@ -329,7 +326,7 @@ class _CalendarScreenState extends State { try { eventos.addAll(snapshot.data!); } catch (e) { - print("Hola" + e.toString()); + print("Error" + e.toString()); } if (eventos.isEmpty) { @@ -339,6 +336,24 @@ class _CalendarScreenState extends State { children: [ ...eventos.map( (e) => ListTile( + onTap: () { + final evento = Event( + day: e.day, + description: e.description, + userId: e.userId, + range1Hour1: e.range1Hour1, + range1Hour2: e.range1Hour2, + title: e.title, + ); + Navigator.push( + context, + CupertinoPageRoute( + builder: (BuildContext context) { + return CitaScreen(evento: evento); + }, + ), + ); + }, leading: Text('${e.range1Hour1}'), title: RichText( text: TextSpan( @@ -354,8 +369,8 @@ class _CalendarScreenState extends State { TextSpan( text: DateFormat('dd MMM', 'es') .format(DateTime.parse(e.day!)), - style: TextStyle( - color: Colors.grey[400], + style: const TextStyle( + color: Colors.grey, fontSize: 16, ), ), diff --git a/lib/src/screens/cita.dart b/lib/src/screens/cita.dart new file mode 100644 index 0000000..f264523 --- /dev/null +++ b/lib/src/screens/cita.dart @@ -0,0 +1,149 @@ +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:firebase_storage/firebase_storage.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_rating_bar/flutter_rating_bar.dart'; +import 'package:intl/intl.dart'; +import 'package:prosappco/src/components/photo_view.dart'; +import 'package:prosappco/src/components/pop_appbar.dart'; +import 'package:prosappco/src/models/event_model.dart'; +import 'package:prosappco/src/models/user_model.dart'; + +class CitaScreen extends StatefulWidget { + final Event evento; + const CitaScreen({super.key, required this.evento}); + + @override + State createState() => _CitaScreenState(); +} + +class _CitaScreenState extends State { + UserModel? user; + @override + String nombre = ''; + Reference? ref_photo; + + @override + void initState() { + super.initState(); + + if (user == null) { + UserModel.getUser(uid.toString()).then( + (UserModel s) => setState(() => user = s), + ); + } + } + + Widget build(BuildContext context) { + if (nombre == '') { + UserModel.getUser(widget.evento.userId!).then((value) { + setState(() { + nombre = value.name; + ref_photo = value.photo; + }); + }); + } + + final User? currentUser = FirebaseAuth.instance.currentUser; + + return Scaffold( + appBar: PopAppbar( + onPressed: () { + Navigator.pop(context); + }, + label: 'Servicio'), + body: Column( + children: [ + Expanded( + child: Column( + children: [ + ListTile( + leading: ReferencePhoto( + ref: ref_photo, + size: 50, + sizeCircle: 50, + sizeIcon: 35, + ), + title: RichText( + text: TextSpan( + children: [ + TextSpan( + text: '${nombre}, ', + style: const TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold, + fontSize: 16, + ), + ), + TextSpan( + text: + '${DateFormat('dd MMM', 'es').format(DateTime.parse(widget.evento.day!))} ${widget.evento.range1Hour1}', + style: TextStyle( + color: Colors.grey, + fontSize: 16, + ), + ), + ], + ), + ), + subtitle: Row( + children: [ + RatingBar.builder( + initialRating: user?.score?.average ?? 0, + minRating: 1, + direction: Axis.horizontal, + allowHalfRating: true, + itemCount: 5, + itemSize: 25, + maxRating: 5, + itemPadding: const EdgeInsets.symmetric(horizontal: 0), + itemBuilder: (context, _) => const Icon( + Icons.star, + color: Color(0xFF2BA4EC), + ), + onRatingUpdate: (rating) {}, + ignoreGestures: true, + ), + const SizedBox(width: 5), + Text( + '(${user?.score?.total.toString()}) ${user?.score?.average.toString()}'), + ], + ), + ), + Text( + textAlign: TextAlign.center, + '" ${widget.evento.description} "', + style: TextStyle( + color: Colors.grey, fontStyle: FontStyle.italic), + ) + ], + ), + ), + Center( + child: Padding( + padding: const EdgeInsets.only(bottom: 30), + child: ElevatedButton( + onPressed: () {}, + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFFEC2B2B), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(50), + ), + elevation: 0, + minimumSize: const Size(230, 60), + ), + child: const Text( + 'Cancelar servicio', + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 18, + ), + ), + ), + ), + ), + ], + ), + ); + } +} diff --git a/lib/src/screens/professional.dart b/lib/src/screens/professional.dart index eb6d83a..5f64a69 100644 --- a/lib/src/screens/professional.dart +++ b/lib/src/screens/professional.dart @@ -9,6 +9,8 @@ import 'package:prosappco/src/components/pop_appbar.dart'; import 'package:prosappco/src/models/score_model.dart'; import 'package:prosappco/src/screens/professional_info.dart'; +import '../models/score_model2.dart'; + class ProfessionalScreen extends StatefulWidget { const ProfessionalScreen({super.key}); @@ -29,7 +31,7 @@ class Professional { final String cityName; final String ubicacion; final List professionalEspecializado; - final ScoreModel puntuacion; + final ScoresModel scores; Professional({ required this.professionalRef, @@ -38,7 +40,7 @@ class Professional { required this.cityName, required this.ubicacion, required this.professionalEspecializado, - required this.puntuacion, + required this.scores, }); String getEspecializaciones() { @@ -56,6 +58,42 @@ class Professional { ' professionalEspecializado: ${getEspecializaciones()}\n' '}'; } + + static Future getProfessional(String uid) async { + var photo = '...'; + final FirebaseStorage storage = FirebaseStorage.instance; + + try { + DocumentSnapshot user = + await FirebaseFirestore.instance.collection('users').doc(uid).get(); + + Map data = user.data() as Map; + + photo = await AuthenticationRepository.instance.getPhoto(user.id); + + if (data['estado'] == 'activo') { + List especializaciones; + + especializaciones = (data['especializaciones'] as List) + .map((e) => e.toString()) + .toList(); + + Professional professional = Professional( + name: data['name'], + professionName: data['profesion'], + cityName: data['city'], + professionalRef: storage.ref().child(photo), + professionalEspecializado: especializaciones, + ubicacion: data['ubicacion'] ?? '', + scores: await ScoresModel.scoreFrom(uid, true), + ); + return professional; + } + } catch (e) { + print('Error al obtener profesionales: $e'); + } + return null; + } } Future> getProfessionals() async { @@ -84,7 +122,7 @@ Future> getProfessionals() async { professionalRef: storage.ref().child(_photo), professionalEspecializado: especializaciones, ubicacion: data['ubicacion'] ?? '', - puntuacion: await ScoreModel.fromJson(data['puntuacion'], true), + scores: await ScoresModel.scoreTo(user.id, true), ); professionals.add(professional); } diff --git a/lib/src/screens/professional_info.dart b/lib/src/screens/professional_info.dart index 9f80a34..4061d19 100644 --- a/lib/src/screens/professional_info.dart +++ b/lib/src/screens/professional_info.dart @@ -1,13 +1,13 @@ -import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_rating_bar/flutter_rating_bar.dart'; import 'package:prosappco/src/components/photo_view.dart'; import 'package:prosappco/src/components/pop_appbar.dart'; -import 'package:prosappco/src/models/score_model.dart'; import 'package:prosappco/src/screens/professional.dart'; import 'package:prosappco/src/screens/reputation.dart'; +import '../models/score_model2.dart'; + class ProfessionalInfoScreen extends StatefulWidget { Professional professional; @@ -153,8 +153,7 @@ class _ProfessionalInfoScreenState extends State { subtitle: Row( children: [ RatingBar.builder( - initialRating: - widget.professional.puntuacion.average, + initialRating: widget.professional.scores.average, minRating: 1, direction: Axis.horizontal, allowHalfRating: true, @@ -172,12 +171,12 @@ class _ProfessionalInfoScreenState extends State { ), const SizedBox(width: 5), Text( - '(${widget.professional.puntuacion.total.toString()}) ${widget.professional.puntuacion.average.toString()}'), + '(${widget.professional.scores.total.toString()}) ${widget.professional.scores.average.toString()}'), ], ), ), ), - ..._scoresList(widget.professional.puntuacion.details), + ..._scoresList(widget.professional.scores.scores), const SizedBox( height: 10, ), @@ -202,11 +201,11 @@ class _ProfessionalInfoScreenState extends State { ); } - List _scoresList(List list) { + List _scoresList(List list) { return list.map((e) => _scoreItem(e)).toList(); } - Widget _scoreItem(ScoreDetailsModel scoreDetails) { + Widget _scoreItem(ScoreModel2 scoreDetails) { return ListTile( onTap: () {}, leading: ReferencePhoto( diff --git a/lib/src/screens/profile.dart b/lib/src/screens/profile.dart index e7bb09b..97897d3 100644 --- a/lib/src/screens/profile.dart +++ b/lib/src/screens/profile.dart @@ -341,169 +341,166 @@ class _ProfileScreenState extends State { Widget build(BuildContext context) { String city = _ciudad.toString(); - return SafeArea( - child: Scaffold( - appBar: PopAppbar( - onPressed: () { - Navigator.pop(context); - }, - label: 'Perfil'), - body: SingleChildScrollView( - reverse: true, - child: 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), - _email != null - ? TextFormField( - onTap: () { - Navigator.push(context, CupertinoPageRoute( - builder: (BuildContext context) { - return NewPasswordScreen(); - }, - )); - }, - 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; - }); - }, + return Scaffold( + appBar: PopAppbar( + onPressed: () { + Navigator.pop(context); + }, + label: 'Perfil'), + body: SingleChildScrollView( + reverse: true, + child: 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), + _email != null + ? TextFormField( + onTap: () { + Navigator.push(context, CupertinoPageRoute( + builder: (BuildContext context) { + return NewPasswordScreen(); + }, + )); + }, + 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, ), - hintText: 'Contraseña (Obligatorio)'), - ), - _email != null - ? const SizedBox.shrink() - : const SizedBox(height: 20.0), - TextFormField( - readOnly: true, - onTap: () async { - final String? ciudad = await Navigator.push( - context, - CupertinoPageRoute( - builder: (BuildContext context) { - return const CityScreen(); - }, - ), - ) as String?; + 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.push( + context, + CupertinoPageRoute( + builder: (BuildContext context) { + return const CityScreen(); + }, + ), + ) as String?; - if (ciudad != null) { - setState(() { - _ciudad = ciudad; - }); - } - }, - decoration: InputDecoration( - prefixIcon: const Icon(Icons.near_me), - suffixIcon: const Icon(Icons.arrow_drop_down), - hintStyle: city == '' - ? const TextStyle() - : const TextStyle(color: Colors.black87), - hintText: city == '' ? 'Ciudad' : city), - ), - const SizedBox(height: 20.0), - TextFormField( - controller: _phoneNumberController, - readOnly: true, - onTap: () { - Navigator.of(context).push( - CupertinoPageRoute( - builder: (BuildContext context) { - return const NewNumberScreen(); - }, - ), - ); - }, - decoration: const InputDecoration( - prefixIcon: Icon(Icons.phone_android), - suffixIcon: Icon(Icons.edit_outlined), - hintText: '+57'), - ), - ], - )), - ), - Container( - alignment: Alignment.bottomCenter, - margin: const EdgeInsets.only(top: 100), - padding: const EdgeInsets.only(bottom: 30), - child: ElevatedButton( - onPressed: () async { - await updateInfo(); - }, - style: ElevatedButton.styleFrom( - backgroundColor: const Color(0xFF2BA4EC), - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(50), - ), - elevation: 0, - minimumSize: const Size(200, 50), + if (ciudad != null) { + setState(() { + _ciudad = ciudad; + }); + } + }, + decoration: InputDecoration( + prefixIcon: const Icon(Icons.near_me), + suffixIcon: const Icon(Icons.arrow_drop_down), + hintStyle: city == '' + ? const TextStyle() + : const TextStyle(color: Colors.black87), + hintText: city == '' ? 'Ciudad' : city), + ), + const SizedBox(height: 20.0), + TextFormField( + controller: _phoneNumberController, + readOnly: true, + onTap: () { + Navigator.of(context).push( + CupertinoPageRoute( + builder: (BuildContext context) { + return const NewNumberScreen(); + }, + ), + ); + }, + decoration: const InputDecoration( + prefixIcon: Icon(Icons.phone_android), + suffixIcon: Icon(Icons.edit_outlined), + hintText: '+57'), + ), + ], + )), + ), + Container( + alignment: Alignment.bottomCenter, + margin: const EdgeInsets.only(top: 100), + padding: const EdgeInsets.only(bottom: 30), + child: ElevatedButton( + onPressed: () async { + await updateInfo(); + }, + style: ElevatedButton.styleFrom( + backgroundColor: const Color(0xFF2BA4EC), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(50), ), - child: const Text( - 'Guardar', - style: TextStyle( - color: Colors.white, - fontWeight: FontWeight.bold, - fontSize: 17, - ), + elevation: 0, + minimumSize: const Size(200, 50), + ), + child: const Text( + 'Guardar', + style: TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 17, ), ), ), - ], - ), + ), + ], ), ), ), diff --git a/lib/src/screens/profile_pro.dart b/lib/src/screens/profile_pro.dart index 9abca40..f215cc4 100644 --- a/lib/src/screens/profile_pro.dart +++ b/lib/src/screens/profile_pro.dart @@ -10,6 +10,7 @@ import 'package:get/get.dart'; import 'package:prosappco/src/authentication/authentication_repository.dart'; import 'package:prosappco/src/components/banner_photo.dart'; import 'package:prosappco/src/components/drawer_professional.dart'; +import 'package:prosappco/src/components/pop_appbar.dart'; import 'package:prosappco/src/components/primary_btn.dart'; import 'package:prosappco/src/components/schedule_picker.dart'; import 'package:prosappco/src/screens/horario.dart'; @@ -258,217 +259,205 @@ class _ProfileProState extends State { Widget build(BuildContext context) { String address = _direccion.toString(); - return SafeArea( - child: Scaffold( - appBar: AppBar( - backgroundColor: Colors.white, - iconTheme: const IconThemeData( - color: Colors.black, - ), - title: const Text( - 'Perfil profesional', - style: TextStyle( - color: Colors.black, - ), - ), - ), - drawer: DrawerProfessional(), - body: SingleChildScrollView( - reverse: true, - child: Column( - children: [ - GestureDetector( - onTap: () { - _showChoiceDialog(context); - }, - child: Container( - child: (imagen_to_upload != null) - ? LocalPhoto( - file: imagen_to_upload!, - ) - : ReferenceBannerPhoto( - ref: storage.ref().child(_photo), - ), - ), - ), - const Divider( - color: Colors.white, - height: 12, - ), - customSwitch( - 'Servicio a domicilio', - domicilioValue, - (value) { - domicilioValue = value; - }, - ), - const Divider(), - customSwitch( - 'Servicio en sitio', - sitioValue, - (value) { - sitioValue = value; - }, - ), - sitioValue - ? Padding( - padding: const EdgeInsets.only( - left: 40, right: 40, bottom: 15), - child: Column( - children: [ - TextFormField( - // controller: _emailController, - readOnly: true, - onTap: () async { - final String? direccion = await Navigator.push( - context, - CupertinoPageRoute( - builder: (BuildContext context) { - return const ProfessionalDireccionScreen(); - }, - ), - ) as String?; - - if (direccion != null) { - setState(() { - _direccion = direccion; - }); - } - }, - - decoration: InputDecoration( - prefixIcon: const Icon(Icons.near_me), - hintStyle: address == '' - ? const TextStyle() - : const TextStyle(color: Colors.black87), - hintText: - address == '' ? 'Dirección' : address), - ), - const SizedBox(height: 10), - TextFormField( - controller: _opcionalAddressController, - decoration: const InputDecoration( - hintText: 'Oficina / Piso / Conjunto'), - ), - ], + return Scaffold( + appBar: PopAppbar( + onPressed: () { + Navigator.pop(context); + }, + label: 'Perfil profesional'), + body: SingleChildScrollView( + reverse: true, + child: Column( + children: [ + GestureDetector( + onTap: () { + _showChoiceDialog(context); + }, + child: Container( + child: (imagen_to_upload != null) + ? LocalPhoto( + file: imagen_to_upload!, ) - .animate() - .moveY(duration: const Duration(milliseconds: 100)), + : ReferenceBannerPhoto( + ref: storage.ref().child(_photo), + ), + ), + ), + const Divider( + color: Colors.white, + height: 12, + ), + customSwitch( + 'Servicio a domicilio', + domicilioValue, + (value) { + domicilioValue = value; + }, + ), + const Divider(), + customSwitch( + 'Servicio en sitio', + sitioValue, + (value) { + sitioValue = value; + }, + ), + sitioValue + ? Padding( + padding: + const EdgeInsets.only(left: 40, right: 40, bottom: 15), + child: Column( + children: [ + TextFormField( + // controller: _emailController, + readOnly: true, + onTap: () async { + final String? direccion = await Navigator.push( + context, + CupertinoPageRoute( + builder: (BuildContext context) { + return const ProfessionalDireccionScreen(); + }, + ), + ) as String?; + + if (direccion != null) { + setState(() { + _direccion = direccion; + }); + } + }, + + decoration: InputDecoration( + prefixIcon: const Icon(Icons.near_me), + hintStyle: address == '' + ? const TextStyle() + : const TextStyle(color: Colors.black87), + hintText: address == '' ? 'Dirección' : address), + ), + const SizedBox(height: 10), + TextFormField( + controller: _opcionalAddressController, + decoration: const InputDecoration( + hintText: 'Oficina / Piso / Conjunto'), + ), + ], ) - : const SizedBox(), - const Divider(), - const Padding( - padding: EdgeInsets.symmetric(horizontal: 30), - child: SizedBox( - width: double.infinity, - child: Text( - 'Horario estandar', - style: TextStyle( - color: Colors.black, - fontSize: 15, - ), + .animate() + .moveY(duration: const Duration(milliseconds: 100)), + ) + : const SizedBox(), + const Divider(), + const Padding( + padding: EdgeInsets.symmetric(horizontal: 30), + child: SizedBox( + width: double.infinity, + child: Text( + 'Horario estandar', + style: TextStyle( + color: Colors.black, + fontSize: 15, ), ), ), - GestureDetector( - onTap: () { - Navigator.push( - context, - CupertinoPageRoute( - builder: (BuildContext context) { - return HorarioScreen( - horarios: _horarios!, - ); - }, - ), - ); - }, - child: Column( - children: [ - Padding( - padding: const EdgeInsets.symmetric(vertical: 10), - child: Row( - children: const [ - Expanded( - child: Padding( - padding: EdgeInsets.only(left: 30), - child: Text( - 'Dia', - style: TextStyle( - color: Colors.black, - fontWeight: FontWeight.w500), - ), - ), - ), - Padding( - padding: EdgeInsets.only(right: 170), + ), + GestureDetector( + onTap: () { + Navigator.push( + context, + CupertinoPageRoute( + builder: (BuildContext context) { + return HorarioScreen( + horarios: _horarios!, + ); + }, + ), + ); + }, + child: Column( + children: [ + Padding( + padding: const EdgeInsets.symmetric(vertical: 10), + child: Row( + children: const [ + Expanded( + child: Padding( + padding: EdgeInsets.only(left: 30), child: Text( - 'Hora', + 'Dia', style: TextStyle( color: Colors.black, fontWeight: FontWeight.w500), ), ), - Padding( - padding: EdgeInsets.only(right: 45), - child: Icon(Icons.edit_outlined), + ), + Padding( + padding: EdgeInsets.only(right: 170), + child: Text( + 'Hora', + style: TextStyle( + color: Colors.black, + fontWeight: FontWeight.w500), ), - ], - ), + ), + Padding( + padding: EdgeInsets.only(right: 45), + child: Icon(Icons.edit_outlined), + ), + ], ), - Padding( - padding: sitioValue - ? const EdgeInsets.only(bottom: 30) - : const EdgeInsets.only(bottom: 70), - child: Row( - children: [ - Padding( - padding: const EdgeInsets.only(left: 30), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - children: const [ - Text('Lunes'), - Text('Martes'), - Text('Miércoles'), - Text('Jueves'), - Text('Viernes'), - Text('Sábado'), - Text('Domingo'), - ], - ), + ), + Padding( + padding: sitioValue + ? const EdgeInsets.only(bottom: 30) + : const EdgeInsets.only(bottom: 70), + child: Row( + children: [ + Padding( + padding: const EdgeInsets.only(left: 30), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: const [ + Text('Lunes'), + Text('Martes'), + Text('Miércoles'), + Text('Jueves'), + Text('Viernes'), + Text('Sábado'), + Text('Domingo'), + ], ), - Padding( - padding: const EdgeInsets.only(left: 25), - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - 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)), - ], - ), + ), + Padding( + padding: const EdgeInsets.only(left: 25), + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + 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)), + ], ), - ], - ), + ), + ], ), - ], - ), + ), + ], ), - PrimaryButtom( - onPressed: () { - updateInfo(); - }, - label: 'Guardar'), - const SizedBox( - height: 20, - ) - ], - ), + ), + PrimaryButtom( + onPressed: () { + updateInfo(); + }, + label: 'Guardar'), + const SizedBox( + height: 20, + ) + ], ), ), ); @@ -515,7 +504,7 @@ class _ProfileProState extends State { return 'N/A'; } if (schedule.jornadaContinua) { - return '${schedule.range1Hour1?.format(context).toString()} - ${schedule.range1Hour2?.format(context).toString()}'; + return '${schedule.range1Hour1?.format(context).toString()} - ${schedule.range2Hour2?.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/lib/src/screens/prueba.dart b/lib/src/screens/prueba.dart new file mode 100644 index 0000000..bc9c75d --- /dev/null +++ b/lib/src/screens/prueba.dart @@ -0,0 +1,27 @@ +import 'package:flutter/material.dart'; +import 'package:prosappco/src/components/drawer_professional.dart'; + +class PruebaScreen extends StatelessWidget { + const PruebaScreen({super.key}); + + @override + Widget build(BuildContext context) { + return SafeArea( + child: Scaffold( + appBar: AppBar( + backgroundColor: Colors.white, + iconTheme: const IconThemeData( + color: Colors.black, + ), + title: const Text( + 'Prueba', + style: TextStyle( + color: Colors.black, + ), + ), + ), + drawer: DrawerProfessional(), + ), + ); + } +} diff --git a/lib/src/screens/reputation.dart b/lib/src/screens/reputation.dart index 2bfa956..c9e5de5 100644 --- a/lib/src/screens/reputation.dart +++ b/lib/src/screens/reputation.dart @@ -22,7 +22,7 @@ class ReputationScreen extends StatelessWidget { body: SingleChildScrollView( child: Column( children: [ - ..._scoresList(professional.puntuacion.details), + //..._scoresList(professional.puntuacion.details), ], )), ));