From 60547febb6936ec88ea137b3c089913830c60c55 Mon Sep 17 00:00:00 2001 From: Felipe Date: Sun, 7 Apr 2024 18:03:51 -0500 Subject: [PATCH] antes de agregar el id --- lib/blocs/service_bloc/service_bloc.dart | 73 +++- lib/blocs/service_bloc/service_event.dart | 18 + lib/components/general_drawer.dart | 27 +- ...fessional_service_history_list_screen.dart | 15 +- .../professional_service_list_screen.dart | 214 ++++++++++ .../user_service_history_list_screen.dart | 10 +- .../lists/user_service_list_screen.dart | 10 +- lib/screens/service/service_screen.dart | 378 +++++++++++++++++- .../firebase_service_repository.dart | 22 + .../firebase_user_repository.dart | 3 +- 10 files changed, 751 insertions(+), 19 deletions(-) create mode 100644 lib/screens/lists/professional_service_list_screen.dart diff --git a/lib/blocs/service_bloc/service_bloc.dart b/lib/blocs/service_bloc/service_bloc.dart index 6b89643..9526450 100644 --- a/lib/blocs/service_bloc/service_bloc.dart +++ b/lib/blocs/service_bloc/service_bloc.dart @@ -29,7 +29,10 @@ class ServiceBloc extends Bloc { on(_onLoadService); on(_onUpdateServiceStatus); on(_onLoadServicesForUser); + on(_onLoadServicesForProfessional); on(_onLoadServicesHistoryForUser); + on( + _onLoadServicesHistoryForProfessional); } void _onCreateService(CreateService event, Emitter emit) async { @@ -115,6 +118,39 @@ class ServiceBloc extends Bloc { } } + void _onLoadServicesHistoryForProfessional( + LoadServicesHistoryForProfessional event, + Emitter emit) async { + try { + final servicesStream = + _serviceRepository.getServicesHistoryForProfessional(event.userId); + + await for (var services in servicesStream) { + if (services.isEmpty) { + emit(const ServicesForUserLoaded([])); + return; + } + final userIds = services.map((e) => e.userId); + final List users = + await _userRepository.getUsersFromIds(userIds); + + final usersDir = {for (var e in users) e.id: e}; + + final servicesInfo = services.map((e) { + return ServiceInfoUI( + service: e, + user: usersDir[e.userId]!, + ); + }).toList(); + + emit(ServicesForUserLoaded(servicesInfo)); + } + } catch (e) { + log(e.toString()); + emit(CreateServiceFailure()); + } + } + void _onLoadServicesForUser( LoadServicesForUser event, Emitter emit) async { try { @@ -154,6 +190,39 @@ class ServiceBloc extends Bloc { } } + void _onLoadServicesForProfessional( + LoadServicesForProfessional event, Emitter emit) async { + try { + final servicesStream = + _serviceRepository.getServicesForProfessional(event.userId); + + await for (var services in servicesStream) { + if (services.isEmpty) { + emit(const ServicesForUserLoaded([])); + return; + } + final userIds = services.map((e) => e.userId); + + final List users = + await _userRepository.getUsersFromIds(userIds); + + final usersDir = {for (var e in users) e.id: e}; + + final servicesInfo = services.map((e) { + return ServiceInfoUI( + service: e, + user: usersDir[e.userId]!, + ); + }).toList(); + + emit(ServicesForUserLoaded(servicesInfo)); + } + } catch (e) { + log(e.toString()); + emit(CreateServiceFailure()); + } + } + void _onUpdateServiceStatus( UpdateServiceStatus event, Emitter emit) async { try { @@ -171,11 +240,11 @@ class ServiceBloc extends Bloc { class ServiceInfoUI { final ServiceEntity service; final MyUser user; - final ProfessionalEntity professional; + final ProfessionalEntity? professional; ServiceInfoUI({ required this.service, required this.user, - required this.professional, + this.professional, }); } diff --git a/lib/blocs/service_bloc/service_event.dart b/lib/blocs/service_bloc/service_event.dart index 074babb..a314626 100644 --- a/lib/blocs/service_bloc/service_event.dart +++ b/lib/blocs/service_bloc/service_event.dart @@ -35,6 +35,24 @@ class LoadServicesForUser extends ServiceEvent { List get props => [userId]; } +class LoadServicesForProfessional extends ServiceEvent { + final String userId; + + const LoadServicesForProfessional(this.userId); + + @override + List get props => [userId]; +} + +class LoadServicesHistoryForProfessional extends ServiceEvent { + final String userId; + + const LoadServicesHistoryForProfessional(this.userId); + + @override + List get props => [userId]; +} + class LoadServicesHistoryForUser extends ServiceEvent { final String userId; diff --git a/lib/components/general_drawer.dart b/lib/components/general_drawer.dart index 36d398d..04da6d7 100644 --- a/lib/components/general_drawer.dart +++ b/lib/components/general_drawer.dart @@ -10,6 +10,7 @@ import 'package:prosappco/screens/configuration/configuration_screen.dart'; import 'package:prosappco/screens/configuration/configuration_support_screen.dart'; import 'package:prosappco/screens/lists/professional_list_screen.dart'; import 'package:prosappco/screens/lists/professional_service_history_list_screen.dart'; +import 'package:prosappco/screens/lists/professional_service_list_screen.dart'; import 'package:prosappco/screens/lists/user_service_history_list_screen.dart'; import 'package:prosappco/screens/lists/user_service_list_screen.dart'; import 'package:prosappco/screens/professional/professional_calendar_screen.dart'; @@ -17,6 +18,7 @@ import 'package:prosappco/screens/professional/professional_denied_screen.dart'; import 'package:prosappco/screens/professional/professional_form_screen.dart'; import 'package:prosappco/screens/professional/professional_pending_screen.dart'; import 'package:prosappco/screens/professional/professional_profile_screen.dart'; +import 'package:prosappco/screens/professional/professional_services_screen.dart'; import 'package:prosappco/screens/profile/profile_screen.dart'; import 'package:prosappco/screens/user/user_history_services_screen.dart'; import 'package:prosappco/screens/web/web_view_screen.dart'; @@ -81,14 +83,23 @@ class GeneralDrawer extends StatelessWidget { leading: Icons.checklist_outlined, label: 'Mis servicios', onTap: () { - Navigator.push( - context, - CupertinoPageRoute( - builder: (context) => - const UserServiceListScreen(), - // const UserServicesScreen(), - ), - ); + shouldProModeActive(context, professionalState) + ? Navigator.push( + context, + CupertinoPageRoute( + builder: (context) => + const ProfessionalServiceListScreen(), + // const UserServicesScreen(), + ), + ) + : Navigator.push( + context, + CupertinoPageRoute( + builder: (context) => + const UserServiceListScreen(), + // const UserServicesScreen(), + ), + ); }, ), GeneralDrawerItem( diff --git a/lib/screens/lists/professional_service_history_list_screen.dart b/lib/screens/lists/professional_service_history_list_screen.dart index 8f4fa1b..014b656 100644 --- a/lib/screens/lists/professional_service_history_list_screen.dart +++ b/lib/screens/lists/professional_service_history_list_screen.dart @@ -6,6 +6,7 @@ import 'package:injector/injector.dart'; import 'package:intl/intl.dart'; import 'package:professional_repository/professional_repository.dart'; import 'package:prosappco/blocs/service_bloc/service_bloc.dart'; +import 'package:prosappco/screens/service/service_screen.dart'; import 'package:service_repository/service_repository.dart'; import 'package:shimmer/shimmer.dart'; @@ -27,8 +28,8 @@ class _ProfessionalServiceHistoryListScreenState serviceBloc = Injector.appInstance.get(); - serviceBloc.add( - LoadServicesHistoryForUser(FirebaseAuth.instance.currentUser!.uid)); + serviceBloc.add(LoadServicesHistoryForProfessional( + FirebaseAuth.instance.currentUser!.uid)); } @override @@ -62,7 +63,15 @@ class _ProfessionalServiceHistoryListScreenState ), ), child: ListTile( - onTap: () {}, + onTap: () { + Navigator.push( + context, + CupertinoPageRoute( + builder: (context) => + const ServiceScreen(), + ), + ); + }, leading: Container( width: 60, height: 60, diff --git a/lib/screens/lists/professional_service_list_screen.dart b/lib/screens/lists/professional_service_list_screen.dart new file mode 100644 index 0000000..eb2eef5 --- /dev/null +++ b/lib/screens/lists/professional_service_list_screen.dart @@ -0,0 +1,214 @@ +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:injector/injector.dart'; +import 'package:intl/intl.dart'; +import 'package:professional_repository/professional_repository.dart'; +import 'package:prosappco/blocs/service_bloc/service_bloc.dart'; +import 'package:prosappco/screens/service/service_screen.dart'; +import 'package:service_repository/service_repository.dart'; +import 'package:shimmer/shimmer.dart'; + +class ProfessionalServiceListScreen extends StatefulWidget { + const ProfessionalServiceListScreen({super.key}); + + @override + State createState() => + _ProfessionalServiceListScreenState(); +} + +class _ProfessionalServiceListScreenState + extends State { + late final ServiceBloc serviceBloc; + + @override + void initState() { + super.initState(); + + serviceBloc = Injector.appInstance.get(); + + serviceBloc.add( + LoadServicesForProfessional(FirebaseAuth.instance.currentUser!.uid)); + } + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => serviceBloc, + child: Scaffold( + appBar: AppBar( + title: const Text('Mis Servicios'), + ), + body: BlocBuilder( + builder: (context, serviceState) { + if (serviceState is ServicesForUserLoaded) { + return serviceState.services.isEmpty + ? const Center( + child: Text('No tienes servicios'), + ) + : ListView.builder( + itemCount: serviceState.services.length, + itemBuilder: (_, index) { + final serviceInfo = serviceState.services[index]; + final user = serviceInfo.user; + final service = serviceInfo.service; + + return Container( + decoration: BoxDecoration( + border: Border( + bottom: BorderSide( + color: Colors.grey.withOpacity(0.2)), + ), + ), + child: ListTile( + onTap: () { + Navigator.push( + context, + CupertinoPageRoute( + builder: (context) => const ServiceScreen(), + ), + ); + }, + leading: Container( + width: 60, + height: 60, + decoration: BoxDecoration( + color: Colors.grey.shade300, + shape: BoxShape.circle, + image: user.picture == null + ? null + : DecorationImage( + image: NetworkImage(user.picture!), + fit: BoxFit.contain, + ), + ), + child: user.picture == null + ? Icon( + CupertinoIcons.person, + color: Colors.grey.shade400, + size: 40, + ) + : null, + ), + title: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Flexible( + child: Text( + '${user.name}', + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontWeight: FontWeight.bold, + ), + ), + ), + const SizedBox(width: 5), + Text( + '${DateFormat('dd MMMM', 'es').format(DateTime.parse(service.day))} - ${ScheduleEntity.getFormatTime(service.range1Hour1)}', + style: TextStyle( + color: Colors.grey[600], + ), + ), + ], + ), + subtitle: Column( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Row( + children: [ + const Text( + 'Estado:', + style: TextStyle( + fontStyle: FontStyle.italic, + ), + ), + const SizedBox(width: 5), + customStatus(service), + ], + ), + Text( + '"${service.description.trim()}"', + overflow: TextOverflow.ellipsis, + ), + ], + ), + ), + ); + }, + ); + } + + return Shimmer.fromColors( + baseColor: Colors.grey[300]!, + highlightColor: Colors.grey[100]!, + child: ListView.builder( + itemCount: 10, + itemBuilder: (_, __) => ListTile( + leading: CircleAvatar( + backgroundColor: Colors.grey[300], + radius: 30, + ), + title: Container( + height: 20, + decoration: BoxDecoration( + color: Colors.grey.shade300, + borderRadius: BorderRadius.circular(8), + ), + ), + subtitle: Container( + height: 15, + decoration: BoxDecoration( + color: Colors.grey.shade300, + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ), + ); + }, + ), + ), + ); + } + + Container customStatus(ServiceEntity service) { + if (service.status == ServiceStatus.pending) { + return itemStatus(Colors.black54, 'Pendiente'); + } + if (service.status == ServiceStatus.acepted) { + return itemStatus(Colors.green, 'Aceptado'); + } + if (service.status == ServiceStatus.active) { + return itemStatus(Colors.blueAccent, 'Activo'); + } + + return itemStatus(Colors.red, 'Cancelado'); + } + + Container itemStatus(Color color, String text) { + return Container( + padding: const EdgeInsets.symmetric( + horizontal: 8, + vertical: 3, + ), + decoration: BoxDecoration( + color: color, + borderRadius: BorderRadius.circular(8), + ), + child: Text( + text, + style: const TextStyle( + fontStyle: FontStyle.italic, + color: Colors.white, + ), + ), + ); + } +} + +// pending - 0 +// acepted - 1 +// active - 2 +// cancelled - 3 +// completed - 4 \ No newline at end of file diff --git a/lib/screens/lists/user_service_history_list_screen.dart b/lib/screens/lists/user_service_history_list_screen.dart index bad94d8..a92e3ae 100644 --- a/lib/screens/lists/user_service_history_list_screen.dart +++ b/lib/screens/lists/user_service_history_list_screen.dart @@ -6,6 +6,7 @@ import 'package:injector/injector.dart'; import 'package:intl/intl.dart'; import 'package:professional_repository/professional_repository.dart'; import 'package:prosappco/blocs/service_bloc/service_bloc.dart'; +import 'package:prosappco/screens/service/service_screen.dart'; import 'package:service_repository/service_repository.dart'; import 'package:shimmer/shimmer.dart'; @@ -62,7 +63,14 @@ class _UserServiceHistoryListScreenState ), ), child: ListTile( - onTap: () {}, + onTap: () { + Navigator.push( + context, + CupertinoPageRoute( + builder: (context) => const ServiceScreen(), + ), + ); + }, leading: Container( width: 60, height: 60, diff --git a/lib/screens/lists/user_service_list_screen.dart b/lib/screens/lists/user_service_list_screen.dart index 954087e..4c8ca6c 100644 --- a/lib/screens/lists/user_service_list_screen.dart +++ b/lib/screens/lists/user_service_list_screen.dart @@ -6,6 +6,7 @@ import 'package:injector/injector.dart'; import 'package:intl/intl.dart'; import 'package:professional_repository/professional_repository.dart'; import 'package:prosappco/blocs/service_bloc/service_bloc.dart'; +import 'package:prosappco/screens/service/service_screen.dart'; import 'package:service_repository/service_repository.dart'; import 'package:shimmer/shimmer.dart'; @@ -60,7 +61,14 @@ class _UserServiceListScreenState extends State { ), ), child: ListTile( - onTap: () {}, + onTap: () { + Navigator.push( + context, + CupertinoPageRoute( + builder: (context) => const ServiceScreen(), + ), + ); + }, leading: Container( width: 60, height: 60, diff --git a/lib/screens/service/service_screen.dart b/lib/screens/service/service_screen.dart index cc6935c..cd74766 100644 --- a/lib/screens/service/service_screen.dart +++ b/lib/screens/service/service_screen.dart @@ -1,15 +1,389 @@ +import 'package:firebase_auth/firebase_auth.dart'; +import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:injector/injector.dart'; +import 'package:intl/intl.dart'; +import 'package:professional_repository/professional_repository.dart'; +import 'package:prosappco/blocs/service_bloc/service_bloc.dart'; +import 'package:prosappco/components/general_primary_button.dart'; +import 'package:service_repository/service_repository.dart'; +import 'package:setting_repository/setting_repository.dart'; +import 'package:user_repository/user_repository.dart'; class ServiceScreen extends StatefulWidget { - const ServiceScreen({super.key}); + // final String serviceId; + const ServiceScreen({ + super.key, + // required this.serviceId + }); @override State createState() => _ServiceScreenState(); } class _ServiceScreenState extends State { + final settingRepository = Injector.appInstance.get(); + SettingEntity? settings; + + @override + void initState() { + super.initState(); + + _loadSettings(); + } + + void _loadSettings() { + settingRepository.getSettings().then( + (value) => setState(() { + settings = value; + }), + ); + } + @override Widget build(BuildContext context) { - return Container(); + return BlocProvider( + create: (context) => Injector.appInstance.get(), + child: Scaffold( + appBar: AppBar( + title: const Text('Servicio'), + ), + body: BlocBuilder( + builder: (context, state) { + if (state is ServiceLoaded) { + final service = state.service; + return FutureBuilder( + future: _getUserAndProfessionalInfo(service), + builder: (BuildContext context, + AsyncSnapshot> snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const Center(child: CircularProgressIndicator()); + } else { + if (snapshot.hasError) { + return Center( + child: Text('Error inesperado: ${snapshot.error}'), + ); + } else { + final userInfo = snapshot.data![0] as MyUser; + final professionalInfo = + snapshot.data![1] as ProfessionalEntity; + + return Column( + children: [ + ListTile( + leading: Container( + width: 60, + height: 60, + decoration: BoxDecoration( + color: Colors.grey.shade300, + shape: BoxShape.circle, + image: userInfo.picture == null + ? null + : DecorationImage( + image: NetworkImage(userInfo.picture!), + fit: BoxFit.contain, + ), + ), + child: userInfo.picture == null + ? Icon( + CupertinoIcons.person, + color: Colors.grey.shade400, + size: 40, + ) + : null, + ), + title: Row( + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + Text( + '${userInfo.name}', + style: const TextStyle( + fontWeight: FontWeight.bold), + ), + const SizedBox(width: 5), + Text( + '${DateFormat('dd MMMM', 'es').format(DateTime.parse(service.day))} - ${ScheduleEntity.getFormatTime(service.range1Hour1)}', + style: TextStyle( + color: Colors.grey[600], + ), + ), + ], + ), + subtitle: const Text('Rating: 5.0'), + ), + Container( + margin: const EdgeInsets.only( + left: 40, right: 40, top: 20, bottom: 20), + padding: const EdgeInsets.symmetric( + horizontal: 20, vertical: 15), + decoration: BoxDecoration( + color: const Color(0xFFD6F4FF), + borderRadius: BorderRadius.circular(20), + boxShadow: [ + BoxShadow( + color: Colors.grey.withOpacity(0.5), + spreadRadius: 1, + blurRadius: 5, + offset: const Offset(1, 3), + ), + ], + ), + child: Row( + children: [ + const Icon( + Icons.error_outline, + size: 27, + color: Colors.black54, + ), + const SizedBox(width: 15), + service.location == + ServiceLocationPreferences.delivery + ? const Text( + 'Servicio a su domicilio.', + style: TextStyle( + color: Colors.black, fontSize: 14), + ) + : const Text( + 'Servicio en sitio / consultorio', + style: TextStyle( + color: Colors.black, fontSize: 14), + ), + ], + ), + ), + Visibility( + visible: settings?.tarifas ?? false, + child: Column( + children: [ + Text( + formatCurrency( + int.tryParse(service.rate) ?? 0), + style: const TextStyle( + fontWeight: FontWeight.w600, + fontSize: 25), + ), + const Text('Tarifa de consulta'), + const SizedBox(height: 15), + const Text( + 'Metodos de pago', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.bold, + ), + ), + professionalInfo.paymentMethods.datafono || + professionalInfo.paymentMethods.nequi || + professionalInfo + .paymentMethods.transferencia + ? Wrap( + spacing: 8, + runSpacing: 8, + alignment: WrapAlignment.center, + children: [ + Visibility( + visible: professionalInfo + .paymentMethods.datafono, + child: const Chip( + label: Text('Datafono')), + ), + Visibility( + visible: professionalInfo + .paymentMethods.nequi, + child: const Chip( + label: Text('Nequi')), + ), + Visibility( + visible: professionalInfo + .paymentMethods.transferencia, + child: const Chip( + label: Text( + 'Transferencia Bancaria')), + ), + ], + ) + : const Text( + 'No hay metodos de pago registrados', + overflow: TextOverflow.ellipsis, + style: TextStyle( + fontSize: 15, + color: Colors.black45, + ), + ), + ], + ), + ), + ListTile( + leading: const Icon(Icons.near_me), + title: Text( + service.address, + style: TextStyle( + fontSize: 15, color: Colors.grey[600]), + ), + subtitle: service.aditionalAddress.isEmpty + ? null + : Text( + service.aditionalAddress, + style: TextStyle( + fontSize: 15, color: Colors.grey[600]), + ), + ), + service.description.isEmpty + ? const SizedBox() + : Container( + alignment: Alignment.center, + width: + MediaQuery.of(context).size.width * 0.8, + child: Text( + '"${service.description.trim()}"', + style: TextStyle( + color: Colors.grey[600], + fontStyle: FontStyle.italic, + ), + ), + ), + Expanded( + child: customMessageStatus(service), + ), + customButton(service, context), + const SizedBox(height: 20), + ], + ); + } + } + }, + ); + } else { + // BlocProvider.of(context) + // .add(LoadService(widget.serviceId)); + return const Center( + child: CircularProgressIndicator(), + ); + } + }, + ), + ), + ); + } + + Center customMessageStatus(ServiceEntity service) { + if (service.status == ServiceStatus.cancelled) { + return const Center( + child: Column( + children: [ + Padding( + padding: EdgeInsets.symmetric(vertical: 20), + child: Icon( + CupertinoIcons.xmark_circle, + color: Color(0xFF35A8ED), + size: 70, + ), + ), + Text( + 'Servicio cancelado exitosamente', + style: TextStyle( + color: Color(0xFF35A8ED), + fontSize: 17, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ); + } + + if (service.status == ServiceStatus.completed) { + return const Center( + child: Column( + children: [ + Padding( + padding: EdgeInsets.symmetric(vertical: 20), + child: Icon( + Icons.favorite_outline_sharp, + color: Color(0xFF35A8ED), + size: 70, + ), + ), + Text( + 'Servicio terminado exitosamente', + style: TextStyle( + color: Color(0xFF35A8ED), + fontSize: 17, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ); + } + + return const Center( + child: Column( + children: [ + Padding( + padding: EdgeInsets.symmetric(vertical: 20), + child: Icon( + Icons.check_circle_outline_rounded, + color: Color(0xFF35A8ED), + size: 70, + ), + ), + Text( + 'Servicio solicitado exitosamente', + style: TextStyle( + color: Color(0xFF35A8ED), + fontSize: 17, + fontWeight: FontWeight.w600, + ), + ), + ], + ), + ); + } + + GeneralPrimaryButton customButton( + ServiceEntity service, BuildContext context) { + if (service.status == ServiceStatus.pending) { + return GeneralPrimaryButton( + onPressed: () { + final currentState = context.read().state; + if (currentState is ServiceLoaded) { + // context.read().add( + // UpdateServiceStatus( + // widget.serviceId, + // ServiceStatus.cancelled, + // ), + // ); + } + }, + color: Colors.red, + label: 'Cancelar Servicio', + ); + } + + return GeneralPrimaryButton( + onPressed: () { + Navigator.pop(context); + }, + label: 'Volver', + ); + } + + String formatCurrency(int number) { + final formatter = + NumberFormat.currency(locale: 'es_CO', decimalDigits: 0, symbol: ''); + return '\$${formatter.format(number)}'; + } + + Future> _getUserAndProfessionalInfo( + ServiceEntity service) async { + final userRepo = FirebaseUserRepository(FirebaseAuth.instance); + final userInfo = await userRepo.getMyUser(service.professionalId); + + final professionalRepo = FirebaseProfessionalRepository(); + final professionalInfo = + await professionalRepo.getProInfo(service.professionalId); + + return [userInfo, professionalInfo]; } } diff --git a/packages/service_repository/lib/src/repositories/firebase_service_repository.dart b/packages/service_repository/lib/src/repositories/firebase_service_repository.dart index 4f08d37..f330f98 100644 --- a/packages/service_repository/lib/src/repositories/firebase_service_repository.dart +++ b/packages/service_repository/lib/src/repositories/firebase_service_repository.dart @@ -38,6 +38,17 @@ class FirebaseServiceRepository { .toList()); } + Stream> getServicesForProfessional( + String professionalId) { + return serviceCollection + .where('professional_id', isEqualTo: professionalId) + .where('status', whereIn: [0, 1, 2]) + .snapshots() + .map((querySnapshot) => querySnapshot.docs + .map((doc) => ServiceEntity.fromDocument(doc.data())) + .toList()); + } + Stream> getServicesHistoryForUser(String userId) { return serviceCollection .where('user_id', isEqualTo: userId) @@ -47,4 +58,15 @@ class FirebaseServiceRepository { .map((doc) => ServiceEntity.fromDocument(doc.data())) .toList()); } + + Stream> getServicesHistoryForProfessional( + String professionalId) { + return serviceCollection + .where('professional_id', isEqualTo: professionalId) + .where('status', whereIn: [3, 4]) + .snapshots() + .map((querySnapshot) => querySnapshot.docs + .map((doc) => ServiceEntity.fromDocument(doc.data())) + .toList()); + } } diff --git a/packages/user_repository/lib/src/repositories/firebase_user_repository.dart b/packages/user_repository/lib/src/repositories/firebase_user_repository.dart index 52b94c6..318b95a 100644 --- a/packages/user_repository/lib/src/repositories/firebase_user_repository.dart +++ b/packages/user_repository/lib/src/repositories/firebase_user_repository.dart @@ -407,8 +407,7 @@ class FirebaseUserRepository implements UserRepository { @override Future> getUsersFromIds(Iterable ids) async { try { - final querySnapshot = - await usersCollection.where(FieldPath.documentId, whereIn: ids).get(); + final querySnapshot = await usersCollection.where(FieldPath.documentId, whereIn: ids).get(); return querySnapshot.docs .map((e) => MyUser.fromEntity(MyUserEntity.fromDocument(e.data())))