diff --git a/lib/main.dart b/lib/main.dart index ed7a0ad..68f07f3 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -19,6 +19,7 @@ import 'package:prosappco/src/screens/profile_pro.dart'; import 'package:prosappco/src/screens/register.dart'; import 'package:prosappco/src/screens/request_sent.dart'; import 'package:prosappco/src/screens/service.dart'; +import 'package:prosappco/src/screens/solicitudes.dart'; import 'firebase_options.dart'; void main() async { @@ -61,6 +62,7 @@ class MyApp extends StatelessWidget { '/servicio': (context) => const ServiceScreen(), '/profilePro': (context) => const ProfilePro(), '/calendar': (context) => const CalendarScreen(), + '/solicitud': (context) => SolicitudScreen(), }, onGenerateRoute: (settings) { throw Exception('Ruta desconocida: ${settings.name}'); diff --git a/lib/src/components/drawer_menu.dart b/lib/src/components/drawer_menu.dart index 3daa705..1a5353e 100644 --- a/lib/src/components/drawer_menu.dart +++ b/lib/src/components/drawer_menu.dart @@ -7,7 +7,7 @@ import 'package:prosappco/src/components/photo_view.dart'; import 'package:prosappco/src/models/scores_model.dart'; import 'package:prosappco/src/models/user_model.dart'; import 'package:prosappco/src/screens/profile.dart'; -import 'package:prosappco/src/screens/prueba.dart'; +import 'package:prosappco/src/screens/solicitudes.dart'; class DrawerMenu extends StatefulWidget { @override @@ -295,14 +295,7 @@ class _DrawerMenuState extends State { } else if (user?.state == 'revision') { Navigator.pushNamed(context, '/profesionalRevision'); } else if (user?.state == 'activo') { - Navigator.push( - context, - CupertinoPageRoute( - builder: (BuildContext context) { - return const PruebaScreen(); - }, - ), - ); + Navigator.pushNamed(context, '/solicitud'); } }, style: ElevatedButton.styleFrom( diff --git a/lib/src/components/drawer_professional.dart b/lib/src/components/drawer_professional.dart index 5fef18f..af4d0c2 100644 --- a/lib/src/components/drawer_professional.dart +++ b/lib/src/components/drawer_professional.dart @@ -199,7 +199,14 @@ class _DrawerProfessionalState extends State { return Container( color: const Color(0xFF2BA4EC), child: ListTile( - onTap: () {}, + onTap: () { + if (ModalRoute.of(context)?.settings.name != + '/solicitud') { + Navigator.pushNamed(context, '/solicitud'); + } else { + Scaffold.of(context).openEndDrawer(); + } + }, trailing: const Icon( Icons.keyboard_arrow_right, color: Colors.white, @@ -239,8 +246,7 @@ class _DrawerProfessionalState extends State { context, CupertinoPageRoute( builder: (BuildContext context) { - return ReputationScreen( - professional: professional!); + return ReputationScreen(); }, ), ); diff --git a/lib/src/models/event_model.dart b/lib/src/models/event_model.dart index 93c70e7..9f51dde 100644 --- a/lib/src/models/event_model.dart +++ b/lib/src/models/event_model.dart @@ -1,5 +1,6 @@ import 'package:cloud_firestore/cloud_firestore.dart'; import 'package:prosappco/src/authentication/authentication_repository.dart'; +import 'package:prosappco/src/models/scores_model.dart'; final uid = AuthenticationRepository.instance.getCurrentUserUid(); @@ -46,6 +47,28 @@ Future> getByProId(String day) async { } } +Future> getByProIdAll() async { + try { + var snapshot = await FirebaseFirestore.instance + .collection('services') + .where('professional_id', isEqualTo: uid) + .get(); + + List eventos = []; + for (var element in snapshot.docs) { + final event = Event.fromJson(element.data()); + event.scoresModel = + await ScoresModel.scoreTo(event.userId ?? "", false, false); + eventos.add(event); + } + print('eventos $eventos'); + return eventos; + } catch (e) { + print('Error getByProId $e'); + return []; + } +} + class Event { String? title; String? description; @@ -54,6 +77,7 @@ class Event { String? range1Hour2; String? userId; String? professionalId; + ScoresModel? scoresModel; Event({ this.title, diff --git a/lib/src/models/scores_model.dart b/lib/src/models/scores_model.dart index 682ac92..f7b8c99 100644 --- a/lib/src/models/scores_model.dart +++ b/lib/src/models/scores_model.dart @@ -12,6 +12,11 @@ class ScoresModel { average = averageScore(details); } + @override + String toString() { + return 'ScoresModel{total: $total, average: $average, details: $details}'; + } + double averageScore(List details) { if (details.isEmpty) { return 0.0; @@ -39,9 +44,11 @@ class ScoresModel { } // You - static Future scoreFrom(String userGiven, bool userInfo) async { + static Future scoreFrom( + String userGiven, bool isFromClient, bool userInfo) async { final givenScoresQuery = FirebaseFirestore.instance .collection('scores') + .where('is_from_client', isEqualTo: isFromClient) .where('from_user', isEqualTo: userGiven); final givenScoresSnapshot = await givenScoresQuery.get(); @@ -77,6 +84,11 @@ class ScoreDetailModel { required this.avatar, }); + @override + String toString() { + return 'ScoreDetailModel{id: $id, score: $score, fromUser: $fromUser, toUser: $toUser, comment: $comment, isFromClient: $isFromClient, name: $name, avatar: $avatar}'; + } + static Future fromDocumentSnapshot( DocumentSnapshot> snapshot, bool userInfo) async { try { diff --git a/lib/src/screens/calendar.dart b/lib/src/screens/calendar.dart index 8931162..93c2e53 100644 --- a/lib/src/screens/calendar.dart +++ b/lib/src/screens/calendar.dart @@ -69,7 +69,7 @@ class _CalendarScreenState extends State { } if (scoresModel == null) { - ScoresModel.scoreFrom(uid.toString(), false).then( + ScoresModel.scoreFrom(uid.toString(), true, false).then( (ScoresModel s) => setState(() => scoresModel = s), ); } diff --git a/lib/src/screens/cita.dart b/lib/src/screens/cita.dart index 614395f..37b1acd 100644 --- a/lib/src/screens/cita.dart +++ b/lib/src/screens/cita.dart @@ -28,14 +28,11 @@ class _CitaScreenState extends State { void initState() { super.initState(); - if (user == null) { - UserModel.getUser(uid.toString()).then( - (UserModel s) => setState(() => user = s), - ); - } if (scoresModel == null) { - ScoresModel.scoreFrom(uid.toString(), false).then( - (ScoresModel s) => setState(() => scoresModel = s), + ScoresModel.scoreFrom(uid.toString(), true, false).then( + (ScoresModel s) => setState(() { + scoresModel = s; + }), ); } } @@ -50,8 +47,6 @@ class _CitaScreenState extends State { }); } - final User? currentUser = FirebaseAuth.instance.currentUser; - return Scaffold( appBar: PopAppbar( onPressed: () { diff --git a/lib/src/screens/professional.dart b/lib/src/screens/professional.dart index 909a20a..87663a1 100644 --- a/lib/src/screens/professional.dart +++ b/lib/src/screens/professional.dart @@ -88,7 +88,7 @@ class Professional { professionalRef: storage.ref().child(photo), professionalEspecializado: especializaciones, ubicacion: data['ubicacion'] ?? '', - scores: await ScoresModel.scoreFrom(uid, true), + scores: await ScoresModel.scoreFrom(uid, true, true), ); return professional; } diff --git a/lib/src/screens/professional_info.dart b/lib/src/screens/professional_info.dart index f16232e..835666b 100644 --- a/lib/src/screens/professional_info.dart +++ b/lib/src/screens/professional_info.dart @@ -138,8 +138,7 @@ class _ProfessionalInfoScreenState extends State { Navigator.of(context).push( CupertinoPageRoute( builder: (BuildContext context) { - return ReputationScreen( - professional: widget.professional); + return ReputationScreen(); }, ), ); diff --git a/lib/src/screens/prueba.dart b/lib/src/screens/prueba.dart deleted file mode 100644 index bc9c75d..0000000 --- a/lib/src/screens/prueba.dart +++ /dev/null @@ -1,27 +0,0 @@ -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 9c40c2f..1aa327c 100644 --- a/lib/src/screens/reputation.dart +++ b/lib/src/screens/reputation.dart @@ -1,19 +1,38 @@ 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/scores_model.dart'; -import 'package:prosappco/src/screens/professional.dart'; +import 'package:prosappco/src/models/user_model.dart'; -class ReputationScreen extends StatelessWidget { - Professional professional; +class ReputationScreen extends StatefulWidget { + ReputationScreen({ + super.key, + }); - ReputationScreen({super.key, required this.professional}); + @override + State createState() => _ReputationScreenState(); +} + +class _ReputationScreenState extends State { + ScoresModel? scoresModel; + + @override + void initState() { + super.initState(); + final uid = AuthenticationRepository.instance.getCurrentUserUid(); + + if (scoresModel == null) { + ScoresModel.scoreTo(uid.toString(), true, true).then( + (ScoresModel s) => setState(() => scoresModel = s), + ); + } + } @override Widget build(BuildContext context) { - return SafeArea( - child: Scaffold( + return Scaffold( appBar: PopAppbar( onPressed: () { Navigator.pop(context); @@ -22,10 +41,10 @@ class ReputationScreen extends StatelessWidget { body: SingleChildScrollView( child: Column( children: [ - ..._scoresList(professional.scores.details), + ..._scoresList(scoresModel?.details ?? []), ], )), - )); + ); } List _scoresList(List list) { diff --git a/lib/src/screens/solicitudes.dart b/lib/src/screens/solicitudes.dart new file mode 100644 index 0000000..9cbe2c3 --- /dev/null +++ b/lib/src/screens/solicitudes.dart @@ -0,0 +1,155 @@ +import 'package:flutter/cupertino.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/drawer_professional.dart'; +import 'package:prosappco/src/models/event_model.dart'; +import 'package:prosappco/src/models/scores_model.dart'; +import 'package:prosappco/src/screens/cita.dart'; + +class SolicitudScreen extends StatefulWidget { + SolicitudScreen({super.key}); + + @override + State createState() => _SolicitudScreenState(); +} + +class _SolicitudScreenState extends State { + DateTime today = DateTime.now(); + + @override + void initState() { + super.initState(); + } + + @override + Widget build(BuildContext context) { + return SafeArea( + child: Scaffold( + appBar: AppBar( + backgroundColor: Colors.white, + iconTheme: const IconThemeData( + color: Colors.black, + ), + title: const Text( + 'Solicitudes', + style: TextStyle( + color: Colors.black, + ), + ), + ), + drawer: DrawerProfessional(), + body: SingleChildScrollView( + child: Column( + children: [ + _eventList(), + ], + ), + ), + ), + ); + } + + Widget _eventList() { + return FutureBuilder( + future: getByProIdAll(), + builder: (BuildContext context, AsyncSnapshot> snapshot) { + if (!snapshot.hasData) { + return const Center( + child: CircularProgressIndicator(), + ); + } + + List eventos = []; + + try { + eventos.addAll(snapshot.data!); + } catch (e) { + print("Error" + e.toString()); + } + + if (eventos.isEmpty) { + return const Padding( + padding: EdgeInsets.symmetric(vertical: 50), + child: Center(child: Text('No tienes citas')), + ); + } + return Column( + children: [ + ...eventos.map( + (event) => ListTile( + onTap: () { + Navigator.push( + context, + CupertinoPageRoute( + builder: (BuildContext context) { + return CitaScreen(evento: event); + }, + ), + ); + }, + leading: Text('${event.range1Hour1}'), + title: RichText( + text: TextSpan( + children: [ + TextSpan( + text: '${event.title}, ', + style: const TextStyle( + color: Colors.black, + fontWeight: FontWeight.bold, + fontSize: 16, + ), + ), + TextSpan( + text: DateFormat('dd MMM', 'es') + .format(DateTime.parse(event.day!)), + style: const TextStyle( + color: Colors.grey, + fontSize: 16, + ), + ), + ], + ), + ), + subtitle: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + RatingBar.builder( + initialRating: event.scoresModel?.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( + '(${event.scoresModel?.total.toString()}) ${event.scoresModel?.average.toString()}'), + ], + ), + Text( + '" ${event.description} "', + style: const TextStyle(fontStyle: FontStyle.italic), + ), + ], + ), + trailing: const Icon(Icons.keyboard_arrow_right), + ), + ), + ], + ); + }, + ); + } +}