diff --git a/lib/blocs/professional_list_bloc/professional_list_bloc.dart b/lib/blocs/professional_list_bloc/professional_list_bloc.dart new file mode 100644 index 0000000..1cf7003 --- /dev/null +++ b/lib/blocs/professional_list_bloc/professional_list_bloc.dart @@ -0,0 +1,57 @@ +import 'dart:developer'; + +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:equatable/equatable.dart'; +import 'package:professional_repository/professional_repository.dart'; +import 'package:user_repository/user_repository.dart'; + +part 'professional_list_event.dart'; +part 'professional_list_state.dart'; + +class ProfessionalListBloc + extends Bloc { + final UserRepository _userRepository; + final FirebaseProfessionalRepository _firebaseProfessionalRepository; + + ProfessionalListBloc({ + required UserRepository userRepository, + required FirebaseProfessionalRepository firebaseProfessonalRepository, + }) : _userRepository = userRepository, + _firebaseProfessionalRepository = firebaseProfessonalRepository, + super(ProfessionalListInitial()) { + on(_onProfessionalListFetch); + } + + void _onProfessionalListFetch(ProfessionalListFetch event, Emitter emit) async { + emit(ProfessionalListLoading()); + final users = await _userRepository.getUsersProfessionalActive(); + + final professionals = await _firebaseProfessionalRepository.getProfessionalInfo(); + + final professionalInfoMap = {for (var doc in professionals) doc.id: doc}; + + final usersMap = users + .map((user) => UserProfessional( + myUser: user, + professionalInfo: professionalInfoMap[user.id]!, + )) + .toList(); + + emit(ProfessionalListSuccess(users: usersMap)); + } +} + +class UserProfessional { + final MyUser myUser; + final ProfessionalEntity professionalInfo; + + UserProfessional({required this.myUser, required this.professionalInfo}); + + @override + String toString() { + return '''UserProfessional{ + myUser: $myUser, + professionalInfo: $professionalInfo + }'''; + } +} diff --git a/lib/blocs/professional_list_bloc/professional_list_event.dart b/lib/blocs/professional_list_bloc/professional_list_event.dart new file mode 100644 index 0000000..f9232e5 --- /dev/null +++ b/lib/blocs/professional_list_bloc/professional_list_event.dart @@ -0,0 +1,15 @@ +part of 'professional_list_bloc.dart'; + +abstract class ProfessionalListEvent extends Equatable { + const ProfessionalListEvent(); + + @override + List get props => []; +} + +class ProfessionalListFetch extends ProfessionalListEvent { + const ProfessionalListFetch(); + + @override + List get props => []; +} diff --git a/lib/blocs/professional_list_bloc/professional_list_state.dart b/lib/blocs/professional_list_bloc/professional_list_state.dart new file mode 100644 index 0000000..8fdb140 --- /dev/null +++ b/lib/blocs/professional_list_bloc/professional_list_state.dart @@ -0,0 +1,21 @@ +part of 'professional_list_bloc.dart'; + +abstract class ProfessionalListState extends Equatable { + const ProfessionalListState(); + + @override + List get props => []; +} + +class ProfessionalListInitial extends ProfessionalListState {} + +class ProfessionalListLoading extends ProfessionalListState {} + +class ProfessionalListSuccess extends ProfessionalListState { + final List users; + + const ProfessionalListSuccess({required this.users}); + + @override + List get props => [users]; +} diff --git a/lib/blocs/profile_bloc/profile_bloc.dart b/lib/blocs/profile_bloc/profile_bloc.dart index 6789279..ef5739f 100644 --- a/lib/blocs/profile_bloc/profile_bloc.dart +++ b/lib/blocs/profile_bloc/profile_bloc.dart @@ -10,6 +10,9 @@ class ProfileBloc extends Bloc { ProfileBloc({required UserRepository userRepository,}) : _userRepository = userRepository, super(UpdateUserInfoInitial()) { + + + on(_onUpdateUserInfo); } diff --git a/lib/components/general_drawer.dart b/lib/components/general_drawer.dart index ed79d44..296d002 100644 --- a/lib/components/general_drawer.dart +++ b/lib/components/general_drawer.dart @@ -8,6 +8,7 @@ import 'package:prosappco/components/general_drawer_header.dart'; import 'package:prosappco/components/general_drawer_item.dart'; 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/professional/professional_calendar_screen.dart'; import 'package:prosappco/screens/professional/professional_denied_screen.dart'; import 'package:prosappco/screens/professional/professional_form_screen.dart'; @@ -81,7 +82,8 @@ class GeneralDrawer extends StatelessWidget { context, CupertinoPageRoute( builder: (context) => - const UserServicesScreen(), + const ProfessionalListScreen(), + // const UserServicesScreen(), ), ); }, diff --git a/lib/dependency/app_di.dart b/lib/dependency/app_di.dart index 73189da..4351342 100644 --- a/lib/dependency/app_di.dart +++ b/lib/dependency/app_di.dart @@ -6,6 +6,7 @@ import 'package:prosappco/blocs/auth_bloc/auth_bloc.dart'; import 'package:prosappco/blocs/authentication_bloc/authentication_bloc.dart'; import 'package:prosappco/blocs/my_user_bloc/my_user_bloc.dart'; import 'package:prosappco/blocs/professional_bloc/professional_bloc.dart'; +import 'package:prosappco/blocs/professional_list_bloc/professional_list_bloc.dart'; import 'package:prosappco/blocs/professional_profile_bloc/professional_profile_bloc.dart'; import 'package:prosappco/blocs/profile_bloc/profile_bloc.dart'; import 'package:prosappco/blocs/setting_bloc/setting_bloc.dart'; @@ -63,5 +64,12 @@ class AppDI { injector.registerSingleton((() => ProfessionalProfileBloc(professionalRepository: injector.get()))); + + injector.registerDependency( + () => ProfessionalListBloc( + userRepository: injector.get(), + firebaseProfessonalRepository: + injector.get()), + ); } } diff --git a/lib/screens/city/city_screen.dart b/lib/screens/lists/city_list_screen.dart similarity index 96% rename from lib/screens/city/city_screen.dart rename to lib/screens/lists/city_list_screen.dart index 08b1e7a..0b5d979 100644 --- a/lib/screens/city/city_screen.dart +++ b/lib/screens/lists/city_list_screen.dart @@ -4,14 +4,14 @@ import 'package:injector/injector.dart'; import 'package:intl_phone_field/helpers.dart'; import 'package:shimmer/shimmer.dart'; -class CityScreen extends StatefulWidget { - const CityScreen({Key? key}) : super(key: key); +class CityListScreen extends StatefulWidget { + const CityListScreen({Key? key}) : super(key: key); @override - State createState() => _CityScreenState(); + State createState() => _CityListScreenState(); } -class _CityScreenState extends State { +class _CityListScreenState extends State { final _searchController = TextEditingController(); final cityRepository = Injector.appInstance.get(); List? _cities; diff --git a/lib/screens/profession/profession_screen.dart b/lib/screens/lists/profession_list_screen.dart similarity index 94% rename from lib/screens/profession/profession_screen.dart rename to lib/screens/lists/profession_list_screen.dart index 4daa4fb..ce82133 100644 --- a/lib/screens/profession/profession_screen.dart +++ b/lib/screens/lists/profession_list_screen.dart @@ -1,19 +1,17 @@ -import 'dart:developer'; - import 'package:flutter/material.dart'; import 'package:injector/injector.dart'; import 'package:intl_phone_field/helpers.dart'; import 'package:profession_repository/profession_repository.dart'; import 'package:shimmer/shimmer.dart'; -class ProfessionScreen extends StatefulWidget { - const ProfessionScreen({super.key}); +class ProfessionListScreen extends StatefulWidget { + const ProfessionListScreen({super.key}); @override - State createState() => _ProfessionScreenState(); + State createState() => _ProfessionListScreenState(); } -class _ProfessionScreenState extends State { +class _ProfessionListScreenState extends State { final _searchController = TextEditingController(); final professionRepository = Injector.appInstance.get(); List? _professions; diff --git a/lib/screens/lists/professional_list_screen.dart b/lib/screens/lists/professional_list_screen.dart new file mode 100644 index 0000000..053eed7 --- /dev/null +++ b/lib/screens/lists/professional_list_screen.dart @@ -0,0 +1,244 @@ +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_phone_field/helpers.dart'; +import 'package:professional_repository/professional_repository.dart'; +import 'package:prosappco/blocs/professional_list_bloc/professional_list_bloc.dart'; +import 'package:prosappco/screens/user/user_view_profile_screen.dart'; +import 'package:shimmer/shimmer.dart'; + +class ProfessionalListScreen extends StatefulWidget { + const ProfessionalListScreen({super.key}); + + @override + State createState() => _ProfessionalListScreenState(); +} + +class _ProfessionalListScreenState extends State { + final _searchController = TextEditingController(); + late final ProfessionalListBloc bloc; + + @override + void initState() { + super.initState(); + bloc = Injector.appInstance.get(); + bloc.add(const ProfessionalListFetch()); + } + + @override + Widget build(BuildContext context) { + return BlocProvider( + create: (context) => bloc, + child: BlocBuilder( + builder: (context, state) { + return Scaffold( + appBar: AppBar( + title: const Text('Selecciona un profesional'), + ), + body: Column( + children: [ + TextField( + controller: _searchController, + onChanged: (value) { + setState(() { + _searchController.text = value; + }); + }, + decoration: const InputDecoration( + hintText: 'Busca un profesional', + prefixIcon: Icon(Icons.search), + enabledBorder: UnderlineInputBorder( + borderSide: BorderSide(color: Colors.grey), + ), + focusedBorder: UnderlineInputBorder( + borderSide: BorderSide(color: Colors.grey), + ), + ), + ), + Expanded( + child: _body(state), + ), + ], + ), + ); + }, + ), + ); + } + + _body(ProfessionalListState state) { + if (state is ProfessionalListSuccess) { + final List filteredUsers; + // filtrar por nombre + if (_searchController.text.isNotEmpty) { + filteredUsers = state.users + .where((element) => removeDiacritics(element.myUser.name!) + .toLowerCase() + .contains( + removeDiacritics(_searchController.text.toLowerCase()))) + .toList(); + } else { + filteredUsers = state.users; + } + + if (filteredUsers.isEmpty) { + return const Center( + child: Text('No hay profesionales'), + ); + } + + return ListView.builder( + itemCount: filteredUsers.length, + itemBuilder: (BuildContext context, int index) { + return Container( + decoration: BoxDecoration( + border: Border( + bottom: BorderSide(color: Colors.grey.withOpacity(0.2)), + ), + ), + child: ListTile( + onTap: () {}, + trailing: GestureDetector( + onTap: () { + Navigator.push( + context, + CupertinoPageRoute( + builder: (context) => UserViewProfileScreen( + userProfessional: filteredUsers[index], + ), + ), + ); + }, + child: filteredUsers[index].professionalInfo.rate.isEmpty + ? const Icon( + Icons.keyboard_arrow_right, + color: Colors.black, + ) + : Column( + children: [ + const SizedBox(height: 5), + const Icon( + Icons.keyboard_arrow_right, + color: Colors.black, + ), + Container( + //fondo azul + decoration: BoxDecoration( + color: Colors.blue[200], + borderRadius: BorderRadius.circular(50), + ), + child: Padding( + padding: const EdgeInsets.symmetric( + horizontal: 6, vertical: 2), + child: Text( + '\$${filteredUsers[index].professionalInfo.rate}', + style: const TextStyle( + fontSize: 13, + ), + ), + ), + ), + ], + ), + ), + leading: Container( + width: 60, + height: 60, + decoration: BoxDecoration( + color: Colors.grey.shade300, + shape: BoxShape.circle, + image: filteredUsers[index].myUser.picture == null + ? null + : DecorationImage( + image: NetworkImage( + filteredUsers[index].myUser.picture ?? ''), + fit: BoxFit.contain, + ), + ), + child: filteredUsers[index].myUser.picture == null + ? Icon( + CupertinoIcons.person, + color: Colors.grey.shade400, + size: 40, + ) + : null, + ), + title: Text( + '${filteredUsers[index].myUser.name ?? ''}, ${filteredUsers[index].professionalInfo.profession}', + overflow: TextOverflow.ellipsis, + style: const TextStyle( + fontSize: 15, + ), + ), + subtitle: Text( + _disponibilidad(filteredUsers[index].professionalInfo), + style: const TextStyle( + fontSize: 13, + color: Colors.blue, + ), + ), + ), + ); + }, + ); + } + + return Shimmer.fromColors( + baseColor: Colors.grey[300]!, + highlightColor: Colors.grey[100]!, + child: ListView.builder( + itemCount: 8, + itemBuilder: (_, __) => Container( + decoration: BoxDecoration( + border: Border( + bottom: BorderSide(color: Colors.grey.withOpacity(0.4)), + ), + ), + child: ListTile( + trailing: const Icon( + Icons.keyboard_arrow_right, + color: Colors.black, + ), + leading: Container( + width: 60, + height: 60, + decoration: BoxDecoration( + color: Colors.grey.shade300, + shape: BoxShape.circle, + ), + ), + title: Container( + width: MediaQuery.of(context).size.width * 0.8, + height: 20.0, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + ), + subtitle: Container( + width: MediaQuery.of(context).size.width * 0.3, + height: 15.0, + decoration: BoxDecoration( + color: Colors.white, + borderRadius: BorderRadius.circular(8), + ), + ), + ), + ), + ), + ); + } + + String _disponibilidad(ProfessionalEntity professionalInfo) { + if (professionalInfo.locationPreferences == LocationPreferences.office) { + return 'Disponibilidad: en sitio.'; + } + + if (professionalInfo.locationPreferences == LocationPreferences.delivery) { + return 'Disponibilidad: domicilio.'; + } + + return 'Disponibilidad: domicilio, en sitio.'; + } +} diff --git a/lib/screens/professional/professional_form_screen.dart b/lib/screens/professional/professional_form_screen.dart index de2fdd5..2c4674c 100644 --- a/lib/screens/professional/professional_form_screen.dart +++ b/lib/screens/professional/professional_form_screen.dart @@ -8,7 +8,7 @@ import 'package:prosappco/blocs/auth_bloc/auth_bloc.dart'; import 'package:prosappco/blocs/my_user_bloc/my_user_bloc.dart'; import 'package:prosappco/blocs/professional_bloc/professional_bloc.dart'; import 'package:prosappco/blocs/profile_bloc/profile_bloc.dart'; -import 'package:prosappco/screens/profession/profession_screen.dart'; +import 'package:prosappco/screens/lists/profession_list_screen.dart'; import 'package:user_repository/user_repository.dart'; import 'package:file_picker/file_picker.dart'; @@ -111,7 +111,7 @@ class _ProfessionalFormScreenState extends State { context, CupertinoPageRoute( builder: (BuildContext context) { - return const ProfessionScreen(); + return const ProfessionListScreen(); }, ), ); @@ -123,7 +123,7 @@ class _ProfessionalFormScreenState extends State { decoration: const InputDecoration( labelText: 'Profesión', prefixIcon: Icon(Icons.work_rounded), - hintText: 'Elige tu profesión', + hintText: 'Selecciona tu profesión', border: OutlineInputBorder( borderRadius: BorderRadius.all( Radius.circular(10.0), @@ -303,7 +303,8 @@ class _ProfessionalFormScreenState extends State { // elevation: 0, ), child: Container( - constraints: const BoxConstraints(maxWidth: 300.0, minHeight: 50.0), + constraints: const BoxConstraints( + maxWidth: 300.0, minHeight: 50.0), alignment: Alignment.center, child: const Text( 'Enviar a revisión', diff --git a/lib/screens/profile/profile_screen.dart b/lib/screens/profile/profile_screen.dart index b89b9b8..1a40326 100644 --- a/lib/screens/profile/profile_screen.dart +++ b/lib/screens/profile/profile_screen.dart @@ -10,7 +10,7 @@ import 'package:prosappco/blocs/my_user_bloc/my_user_bloc.dart'; import 'package:prosappco/blocs/profile_bloc/profile_bloc.dart'; import 'package:prosappco/components/birthday_picker.dart'; import 'package:prosappco/components/gender_dropdown.dart'; -import 'package:prosappco/screens/city/city_screen.dart'; +import 'package:prosappco/screens/lists/city_list_screen.dart'; import 'package:prosappco/screens/profile/components/profile_item.dart'; import 'package:prosappco/screens/profile/profile_register_email_screen.dart'; import 'package:prosappco/screens/profile/profile_register_phone_screen.dart'; @@ -141,7 +141,7 @@ class _ProfileScreenState extends State { context, CupertinoPageRoute( builder: (BuildContext context) { - return const CityScreen(); + return const CityListScreen(); }, ), ); @@ -153,7 +153,7 @@ class _ProfileScreenState extends State { decoration: const InputDecoration( labelText: 'Ciudad', prefixIcon: Icon(Icons.near_me_rounded), - hintText: 'Elige tu ciudad', + hintText: 'Selecciona tu ciudad', border: OutlineInputBorder( borderRadius: BorderRadius.all( Radius.circular(10.0), diff --git a/lib/screens/user/user_view_profile_screen.dart b/lib/screens/user/user_view_profile_screen.dart new file mode 100644 index 0000000..4f857e0 --- /dev/null +++ b/lib/screens/user/user_view_profile_screen.dart @@ -0,0 +1,217 @@ +import 'package:flutter/cupertino.dart'; +import 'package:flutter/material.dart'; +import 'package:prosappco/blocs/professional_list_bloc/professional_list_bloc.dart'; + +class UserViewProfileScreen extends StatelessWidget { + UserProfessional userProfessional; + + UserViewProfileScreen({ + super.key, + required this.userProfessional, + }); + + final double bannerHeight = 200; + final double profileHeight = 160; + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: AppBar( + title: const Text('Perfil Profesional'), + ), + body: ListView( + padding: EdgeInsets.zero, + children: [ + buildTop(), + buildContent(), + ], + ), + ); + + // Container( + // decoration: BoxDecoration( + // gradient: LinearGradient( + // colors: [ + // Colors.blue.withOpacity(1), + // Colors.blue.withOpacity(0), + // Colors.blue.withOpacity(0), + // ], + // begin: Alignment.bottomCenter, + // end: Alignment.topCenter, + // ), + // ), + } + + Stack buildTop() { + final top = bannerHeight - profileHeight / 2; + final bottom = profileHeight / 2; + return Stack( + clipBehavior: Clip.none, + alignment: Alignment.center, + children: [ + Container( + margin: EdgeInsets.only(bottom: bottom), + child: buildBannerImage(), + ), + Positioned( + top: top, + child: buildProfileImage(), + ), + ], + ); + } + + buildContent() { + return Column( + children: [ + Text( + userProfessional.myUser.name ?? '', + overflow: TextOverflow.ellipsis, + style: const TextStyle(fontSize: 22, fontWeight: FontWeight.bold), + ), + Text( + '${userProfessional.professionalInfo.profession}, ${userProfessional.myUser.city ?? ''}', + overflow: TextOverflow.ellipsis, + style: const TextStyle(fontSize: 18, color: Colors.black54), + ), + const Divider(), + const Text( + 'Especialidades:', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w500, + ), + ), + userProfessional.professionalInfo.specializations.isEmpty + ? const Text( + 'No posee especialidades', + overflow: TextOverflow.ellipsis, + style: TextStyle(fontSize: 15, color: Colors.black45), + ) + : Wrap( + spacing: 8, + runSpacing: 8, + alignment: WrapAlignment.center, + children: userProfessional.professionalInfo.specializations + .map((specialization) { + return Chip( + label: Text(specialization), + ); + }).toList(), + ), + Visibility( + visible: userProfessional.professionalInfo.rate.isNotEmpty, + child: const Divider(), + ), + Visibility( + visible: userProfessional.professionalInfo.rate.isNotEmpty, + child: const Text( + 'Tarifa:', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w500, + ), + ), + ), + Visibility( + visible: userProfessional.professionalInfo.rate.isNotEmpty, + child: Wrap( + spacing: 8, + runSpacing: 8, + alignment: WrapAlignment.center, + children: [ + Chip(label: Text('\$${userProfessional.professionalInfo.rate}')), + ], + ), + ), + const Divider(), + const Text( + 'Metodos de pago recibidos:', + style: TextStyle( + fontSize: 18, + fontWeight: FontWeight.w500, + ), + ), + userProfessional.professionalInfo.paymentMethods.datafono || + userProfessional.professionalInfo.paymentMethods.nequi || + userProfessional.professionalInfo.paymentMethods.transferencia + ? Wrap( + spacing: 8, + runSpacing: 8, + alignment: WrapAlignment.center, + children: [ + Visibility( + visible: userProfessional + .professionalInfo.paymentMethods.datafono, + child: const Chip(label: Text('Datafono')), + ), + Visibility( + visible: + userProfessional.professionalInfo.paymentMethods.nequi, + child: const Chip(label: Text('Nequi')), + ), + Visibility( + visible: userProfessional + .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), + ), + const Divider(), + ], + ); + } + + Container buildProfileImage() { + return Container( + width: 155, + height: 155, + decoration: BoxDecoration( + shape: BoxShape.circle, + border: Border.all( + color: Colors.white, + width: 5, + ), + ), + child: Container( + width: 150, + height: 150, + decoration: BoxDecoration( + color: Colors.grey.shade300, + shape: BoxShape.circle, + border: Border.all(width: 0), + image: userProfessional.myUser.picture == null + ? null + : DecorationImage( + image: NetworkImage(userProfessional.myUser.picture ?? ''), + fit: BoxFit.contain, + ), + ), + child: userProfessional.myUser.picture == null + ? Icon( + CupertinoIcons.person, + color: Colors.grey.shade400, + size: 40, + ) + : null, + ), + ); + } + + Container buildBannerImage() { + return Container( + color: Colors.grey, + child: Image.network( + userProfessional.professionalInfo.bannerPicture, + fit: BoxFit.cover, + width: double.infinity, + height: bannerHeight, + ), + ); + } +} diff --git a/packages/professional_repository/lib/src/entities/payment_method_entity.dart b/packages/professional_repository/lib/src/entities/payment_method_entity.dart index b74c8c9..7b1706e 100644 --- a/packages/professional_repository/lib/src/entities/payment_method_entity.dart +++ b/packages/professional_repository/lib/src/entities/payment_method_entity.dart @@ -42,7 +42,7 @@ class PaymentMethodEntity extends Equatable { @override String toString() { - return '''SettingEntity { + return '''PaymentMethodEntity { nequi: $nequi datafono: $datafono transferencia: $transferencia diff --git a/packages/professional_repository/lib/src/repositories/firebase_professional_repository.dart b/packages/professional_repository/lib/src/repositories/firebase_professional_repository.dart index 6fd54e1..9553ac8 100644 --- a/packages/professional_repository/lib/src/repositories/firebase_professional_repository.dart +++ b/packages/professional_repository/lib/src/repositories/firebase_professional_repository.dart @@ -177,4 +177,16 @@ class FirebaseProfessionalRepository { rethrow; } } + + Future> getProfessionalInfo() async { + try { + QuerySnapshot> querySnapshot = await professionalCollection.get(); + return querySnapshot.docs + .map((e) => ProfessionalEntity.fromDocument(e.data())) + .toList(); + } catch (e) { + log(e.toString()); + rethrow; + } + } } 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 7e38927..a829329 100644 --- a/packages/user_repository/lib/src/repositories/firebase_user_repository.dart +++ b/packages/user_repository/lib/src/repositories/firebase_user_repository.dart @@ -367,7 +367,8 @@ class FirebaseUserRepository implements UserRepository { Future uploadPicture(String file, String userId) async { try { File imageFile = File(file); - Reference firebaseStoreRef = FirebaseStorage.instance.ref().child('$userId/PP/${userId}_lead'); + Reference firebaseStoreRef = + FirebaseStorage.instance.ref().child('$userId/PP/${userId}_lead'); await firebaseStoreRef.putFile(imageFile); String url = await firebaseStoreRef.getDownloadURL(); return url; @@ -383,6 +384,25 @@ class FirebaseUserRepository implements UserRepository { await usersCollection.doc(myUser.id).set(myUser.toEntity().toDocument()); } catch (e) { log(e.toString()); + rethrow; + } + } + + @override + Future> getUsersProfessionalActive() async { + try { + final querySnapshot = await usersCollection + .where('professional_state', isEqualTo: ProState.active.index) + .get(); + + log('xd -- ${querySnapshot.docs}'); + + return querySnapshot.docs + .map((e) => MyUser.fromEntity(MyUserEntity.fromDocument(e.data()))) + .toList(); + } catch (e) { + log('xd -- ${e.toString()}'); + rethrow; } } } diff --git a/packages/user_repository/lib/src/repositories/user_repo.dart b/packages/user_repository/lib/src/repositories/user_repo.dart index d6cbb3e..838009a 100644 --- a/packages/user_repository/lib/src/repositories/user_repo.dart +++ b/packages/user_repository/lib/src/repositories/user_repo.dart @@ -43,6 +43,8 @@ abstract class UserRepository { Future uploadPicture(String file, String userId); Future createUser(MyUser myUser); + + Future> getUsersProfessionalActive(); } enum UpdatePassworErros { credentialsWrong, userNotFound, unknown }