From 672e7fc32f833a200cf985d973b92052d622f875 Mon Sep 17 00:00:00 2001 From: Juan Felipe Duarte <70235683+DuarteJFelipe@users.noreply.github.com> Date: Mon, 17 Apr 2023 11:29:27 -0500 Subject: [PATCH] update --- lib/src/models/score_model.dart | 47 +++++ lib/src/screens/professional.dart | 4 + lib/src/screens/professional_info.dart | 209 +++++++++++++--------- lib/src/screens/professional_profile.dart | 13 +- pubspec.lock | 8 + pubspec.yaml | 1 + 6 files changed, 194 insertions(+), 88 deletions(-) create mode 100644 lib/src/models/score_model.dart diff --git a/lib/src/models/score_model.dart b/lib/src/models/score_model.dart new file mode 100644 index 0000000..2047b61 --- /dev/null +++ b/lib/src/models/score_model.dart @@ -0,0 +1,47 @@ +class ScoreModel { + final int total; + final double average; + final List details; + + ScoreModel(this.total, this.average, this.details); + + factory ScoreModel.fromJson(Map? json) { + try { + if (json == null) return ScoreModel(0, 0, []); + + return ScoreModel( + json['total'], + json['promedio'], + (json['detalles'] as List?) + ?.map((e) => ScoreDetailsModel.fromJson(e)) + .toList() ?? + [], + ); + } catch (e) { + print('XD 54 $e'); + return ScoreModel(0, 0, []); + } + } +} + +class ScoreDetailsModel { + final String userId; + final double score; + final String comment; + + ScoreDetailsModel(this.userId, this.score, this.comment); + + factory ScoreDetailsModel.fromJson(Map? json) { + try { + if (json == null) return ScoreDetailsModel("no user", 0, ""); + return ScoreDetailsModel( + json['usuario_id'], + (json['puntaje'] is int) ? json['puntaje'].toDouble() : json['puntaje'], + json['comentario'], + ); + } catch (e) { + print('XD $e'); + return ScoreDetailsModel("no user", 0, ""); + } + } +} diff --git a/lib/src/screens/professional.dart b/lib/src/screens/professional.dart index be8405f..1a4b2c1 100644 --- a/lib/src/screens/professional.dart +++ b/lib/src/screens/professional.dart @@ -6,6 +6,7 @@ import 'package:flutter/material.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/models/score_model.dart'; import 'package:prosappco/src/screens/professional_info.dart'; class ProfessionalScreen extends StatefulWidget { @@ -28,6 +29,7 @@ class Professional { final String cityName; final String ubicacion; final List professionalEspecializado; + final ScoreModel puntuacion; Professional({ required this.professionalRef, @@ -36,6 +38,7 @@ class Professional { required this.cityName, required this.ubicacion, required this.professionalEspecializado, + required this.puntuacion, }); String getEspecializaciones() { @@ -81,6 +84,7 @@ Future> getProfessionals() async { professionalRef: storage.ref().child(_photo), professionalEspecializado: especializaciones, ubicacion: data['ubicacion'], + puntuacion: ScoreModel.fromJson(data['puntuacion']), ); professionals.add(professional); } diff --git a/lib/src/screens/professional_info.dart b/lib/src/screens/professional_info.dart index f3f165c..96e08fa 100644 --- a/lib/src/screens/professional_info.dart +++ b/lib/src/screens/professional_info.dart @@ -1,13 +1,50 @@ +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: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/models/score_model.dart'; import 'package:prosappco/src/screens/professional.dart'; -class ProfessionalInfoScreen extends StatelessWidget { +class ProfessionalInfoScreen extends StatefulWidget { Professional professional; ProfessionalInfoScreen({super.key, required this.professional}); + @override + State createState() => _ProfessionalInfoScreenState(); +} + +class _ProfessionalInfoScreenState extends State { + late final FirebaseAuth _auth; + final FirebaseStorage storage = FirebaseStorage.instance; + + final uid = AuthenticationRepository.instance.getCurrentUserUid(); + + @override + void initState() { + super.initState(); + + _auth = FirebaseAuth.instance; + } + + List months = [ + 'enero', + 'febrero', + 'marzo', + 'abril', + 'mayo', + 'junio', + 'julio', + 'agosto', + 'septiembre', + 'octubre', + 'noviembre', + 'diciembre', + ]; + @override Widget build(BuildContext context) { return SafeArea( @@ -16,7 +53,7 @@ class ProfessionalInfoScreen extends StatelessWidget { onPressed: () { Navigator.pop(context); }, - label: professional.name), + label: widget.professional.name), body: SingleChildScrollView( child: Stack( children: [ @@ -46,26 +83,26 @@ class ProfessionalInfoScreen extends StatelessWidget { height: 5, ), Text( - professional.name, + widget.professional.name, style: const TextStyle(fontWeight: FontWeight.w500), ), Text( - professional.professionName, + widget.professional.professionName, style: const TextStyle(color: Color(0xFF1688C9)), ), - professional.getEspecializaciones().isEmpty + widget.professional.getEspecializaciones().isEmpty ? const SizedBox() : Text( - 'Especializado/a en ${professional.getEspecializaciones()}', + 'Especializado/a en ${widget.professional.getEspecializaciones()}', style: const TextStyle(color: Colors.black54), ), Text( - professional.cityName, + widget.professional.cityName, ), ], ), ), - professional.ubicacion == 'domicilio' + widget.professional.ubicacion == 'domicilio' ? Container( margin: const EdgeInsets.only( left: 40, right: 40, top: 20, bottom: 20), @@ -127,82 +164,33 @@ class ProfessionalInfoScreen extends StatelessWidget { style: TextStyle(color: Colors.black), ), subtitle: Row( - children: const [ - Icon(Icons.star), - Icon(Icons.star), - Icon(Icons.star), - Icon(Icons.star), - Icon(Icons.star_half), + children: [ + RatingBar.builder( + initialRating: + widget.professional.puntuacion.average, + 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( + '(${widget.professional.puntuacion.total.toString()}) ${widget.professional.puntuacion.average.toString()}'), ], ), ), ), - ListTile( - onTap: () {}, - leading: ReferencePhoto( - ref: professional.professionalRef, - size: 50, - sizeCircle: 50, - sizeIcon: 35, - ), - title: Row( - children: const [ - Icon(Icons.star), - Icon(Icons.star), - Icon(Icons.star), - Icon(Icons.star), - Icon(Icons.star_half), - ], - ), - subtitle: const Text( - 'Mi perfil', - style: TextStyle(fontSize: 15), - ), - ), - ListTile( - onTap: () {}, - leading: ReferencePhoto( - ref: professional.professionalRef, - size: 50, - sizeCircle: 50, - sizeIcon: 35, - ), - title: Row( - children: const [ - Icon(Icons.star), - Icon(Icons.star), - Icon(Icons.star), - Icon(Icons.star), - Icon(Icons.star), - ], - ), - subtitle: const Text( - 'Mi perfil', - style: TextStyle(fontSize: 15), - ), - ), - ListTile( - onTap: () {}, - leading: ReferencePhoto( - ref: professional.professionalRef, - sizeCircle: 50, - sizeIcon: 35, - size: 50, - ), - title: Row( - children: const [ - Icon(Icons.star), - Icon(Icons.star), - Icon(Icons.star), - Icon(Icons.star), - Icon(Icons.star_border), - ], - ), - subtitle: const Text( - 'Mi perfil', - style: TextStyle(fontSize: 15), - ), - ), + ..._scoresList(widget.professional.puntuacion.details), const SizedBox( height: 10, ), @@ -214,7 +202,7 @@ class ProfessionalInfoScreen extends StatelessWidget { left: 10, ), child: ReferencePhoto( - ref: professional.professionalRef, + ref: widget.professional.professionalRef, size: 100, sizeCircle: 100, sizeIcon: 50, @@ -226,4 +214,63 @@ class ProfessionalInfoScreen extends StatelessWidget { ), ); } + + List _scoresList(List list) { + return list.map((e) => _scoreItem(e)).toList(); + } + + Widget _scoreItem(ScoreDetailsModel scoreDetails) { + return ListTile( + onTap: () {}, + leading: ReferencePhoto( + ref: widget.professional.professionalRef, + size: 50, + sizeCircle: 50, + sizeIcon: 35, + ), + title: Row( + children: [ + RatingBar.builder( + initialRating: scoreDetails.score, + minRating: 1, + direction: Axis.horizontal, + allowHalfRating: true, + itemCount: 5, + itemSize: 22, + maxRating: 5, + itemPadding: const EdgeInsets.symmetric(horizontal: 0), + itemBuilder: (context, _) => const Icon( + Icons.star, + color: Color(0xFF2BA4EC), + ), + onRatingUpdate: (rating) {}, + ignoreGestures: true, + ), + Text( + ' (${scoreDetails.score})', + style: const TextStyle(color: Colors.black54, fontSize: 13), + ) + ], + ), + subtitle: Row( + children: [ + Expanded( + child: Text.rich( + TextSpan( + children: [ + const TextSpan( + text: 'name, ', + style: TextStyle(fontSize: 15, color: Colors.black), + ), + TextSpan( + text: '"${scoreDetails.comment}"', + style: const TextStyle(fontSize: 15, color: Colors.grey), + ), + ], + ), + ), + ), + ], + )); + } } diff --git a/lib/src/screens/professional_profile.dart b/lib/src/screens/professional_profile.dart index 01662e5..9f1795c 100644 --- a/lib/src/screens/professional_profile.dart +++ b/lib/src/screens/professional_profile.dart @@ -5,7 +5,6 @@ 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:get/get_connect/http/src/utils/utils.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'; @@ -69,7 +68,7 @@ class ProfessionalProfileScreenState extends State { child: ListBody( children: [ GestureDetector( - child: Text( + child: const Text( textAlign: TextAlign.center, "Tomar foto", style: TextStyle(color: Color(0xFF2BA4EC)), @@ -82,9 +81,9 @@ class ProfessionalProfileScreenState extends State { Navigator.of(context).pop(); }, ), - Divider(color: Colors.black54), + const Divider(color: Colors.black54), GestureDetector( - child: Text( + child: const Text( textAlign: TextAlign.center, "Abrir GalerĂ­a", style: TextStyle(color: Color(0xFF2BA4EC)), @@ -114,7 +113,7 @@ class ProfessionalProfileScreenState extends State { child: ListBody( children: [ GestureDetector( - child: Text( + child: const Text( textAlign: TextAlign.center, "Tomar foto", style: TextStyle(color: Color(0xFF2BA4EC)), @@ -127,9 +126,9 @@ class ProfessionalProfileScreenState extends State { Navigator.of(context).pop(); }, ), - Divider(color: Colors.black54), + const Divider(color: Colors.black54), GestureDetector( - child: Text( + child: const Text( textAlign: TextAlign.center, "Abrir GalerĂ­a", style: TextStyle(color: Color(0xFF2BA4EC)), diff --git a/pubspec.lock b/pubspec.lock index 8c66f77..8ba441b 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -214,6 +214,14 @@ packages: url: "https://pub.dev" source: hosted version: "2.0.9" + flutter_rating_bar: + dependency: "direct main" + description: + name: flutter_rating_bar + sha256: d2af03469eac832c591a1eba47c91ecc871fe5708e69967073c043b2d775ed93 + url: "https://pub.dev" + source: hosted + version: "4.0.1" flutter_test: dependency: "direct dev" description: flutter diff --git a/pubspec.yaml b/pubspec.yaml index 2450de5..1e4f2c2 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -50,6 +50,7 @@ dependencies: firebase_storage: ^11.1.0 image_picker: ^0.8.7+1 flutter_animate: ^4.1.1+1 + flutter_rating_bar: ^4.0.1 dev_dependencies: flutter_test: