diff --git a/lib/app_view.dart b/lib/app_view.dart index 34fe204..57c9409 100644 --- a/lib/app_view.dart +++ b/lib/app_view.dart @@ -3,6 +3,7 @@ import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:prosappco/screens/authentication/welcome_screen.dart'; import 'package:prosappco/screens/home/home_screen.dart'; import 'package:prosappco/screens/splash/splash_screen.dart'; +import 'package:flutter_localizations/flutter_localizations.dart'; import 'blocs/authentication_bloc/authentication_bloc.dart'; @@ -14,6 +15,13 @@ class MyAppView extends StatelessWidget { return MaterialApp( debugShowCheckedModeBanner: false, title: 'Prosappco', + localizationsDelegates: const [ + GlobalMaterialLocalizations.delegate, + GlobalWidgetsLocalizations.delegate, + ], + supportedLocales: const [ + Locale('es'), + ], theme: ThemeData( colorScheme: const ColorScheme.light( background: Colors.white, diff --git a/lib/blocs/professional_bloc/professional_bloc.dart b/lib/blocs/professional_bloc/professional_bloc.dart index 7ef0e14..1ea38cb 100644 --- a/lib/blocs/professional_bloc/professional_bloc.dart +++ b/lib/blocs/professional_bloc/professional_bloc.dart @@ -1,7 +1,6 @@ import 'dart:developer'; -// ignore: depend_on_referenced_packages -import 'package:bloc/bloc.dart'; +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'; diff --git a/lib/blocs/service_bloc/service_bloc.dart b/lib/blocs/service_bloc/service_bloc.dart new file mode 100644 index 0000000..3648100 --- /dev/null +++ b/lib/blocs/service_bloc/service_bloc.dart @@ -0,0 +1,17 @@ +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:equatable/equatable.dart'; + +import 'package:service_repository/service_repository.dart'; + +part 'service_event.dart'; +part 'service_state.dart'; + +class ServiceBloc extends Bloc { + final FirebaseServiceRepository _serviceRepository; + + ServiceBloc({required FirebaseServiceRepository serviceRepository}) + : _serviceRepository = serviceRepository, + super(ServiceInitial()) { + + } +} diff --git a/lib/blocs/service_bloc/service_event.dart b/lib/blocs/service_bloc/service_event.dart new file mode 100644 index 0000000..5243ca3 --- /dev/null +++ b/lib/blocs/service_bloc/service_event.dart @@ -0,0 +1,8 @@ +part of 'service_bloc.dart'; + +abstract class ServiceEvent extends Equatable { + const ServiceEvent(); + + @override + List get props => []; +} diff --git a/lib/blocs/service_bloc/service_state.dart b/lib/blocs/service_bloc/service_state.dart new file mode 100644 index 0000000..6dcfdd5 --- /dev/null +++ b/lib/blocs/service_bloc/service_state.dart @@ -0,0 +1,10 @@ +part of 'service_bloc.dart'; + +abstract class ServiceState extends Equatable { + const ServiceState(); + + @override + List get props => []; +} + +class ServiceInitial extends ServiceState {} diff --git a/lib/screens/lists/professional_list_screen.dart b/lib/screens/lists/professional_list_screen.dart index b027842..40cf5ae 100644 --- a/lib/screens/lists/professional_list_screen.dart +++ b/lib/screens/lists/professional_list_screen.dart @@ -99,15 +99,19 @@ class _ProfessionalListScreenState extends State { ), ), child: ListTile( - onTap: () { - Navigator.push( + onTap: () async { + var datos = await Navigator.push( context, CupertinoPageRoute( builder: (context) => UserCalendarScreen( - // userProfessional: filteredUsers[index], - ), + userProfessional: filteredUsers[index], + ), ), ); + + if (datos != null) { + Navigator.pop(context, datos); + } }, trailing: GestureDetector( onTap: () { diff --git a/lib/screens/professional/professional_calendar_screen.dart b/lib/screens/professional/professional_calendar_screen.dart index b6254ca..a5c122c 100644 --- a/lib/screens/professional/professional_calendar_screen.dart +++ b/lib/screens/professional/professional_calendar_screen.dart @@ -78,7 +78,7 @@ class _ProfessionalCalendarScreenState Container( color: const Color.fromARGB(255, 224, 247, 255), child: TableCalendar( - // locale: 'es_MX', + locale: 'es_MX', firstDay: DateTime.utc(2010, 10, 16), lastDay: lastDay, focusedDay: today, diff --git a/lib/screens/user/user_calendar_screen.dart b/lib/screens/user/user_calendar_screen.dart index 247a44a..fe9350d 100644 --- a/lib/screens/user/user_calendar_screen.dart +++ b/lib/screens/user/user_calendar_screen.dart @@ -1,9 +1,16 @@ import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; +import 'package:intl/intl.dart'; +import 'package:professional_repository/professional_repository.dart'; +import 'package:prosappco/blocs/professional_list_bloc/professional_list_bloc.dart'; +import 'package:prosappco/utils/time_of_day_utils.dart'; +import 'package:service_repository/service_repository.dart'; import 'package:table_calendar/table_calendar.dart'; class UserCalendarScreen extends StatefulWidget { - const UserCalendarScreen({super.key}); + final UserProfessional userProfessional; + + const UserCalendarScreen({super.key, required this.userProfessional}); @override State createState() => UserCalendarScreenState(); @@ -54,7 +61,7 @@ class UserCalendarScreenState extends State { Container( color: const Color.fromARGB(255, 224, 247, 255), child: TableCalendar( - // locale: 'es_MX', + locale: 'es_MX', firstDay: DateTime.now(), lastDay: lastDay, focusedDay: today, @@ -75,8 +82,7 @@ class UserCalendarScreenState extends State { child: Padding( padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 8), child: Text( - 'adwa', - // DateFormat('dd MMMM yyyy', 'es').format(today), + DateFormat('dd MMMM yyyy', 'es').format(today), style: const TextStyle( color: Colors.black, fontSize: 16, @@ -93,7 +99,7 @@ class UserCalendarScreenState extends State { padding: const EdgeInsets.only(bottom: 15), child: Column( children: [ - Text('Hola'), + ..._rangesItems(_getScheduleFromNumDay(numDay)), ], ), ), @@ -102,4 +108,179 @@ class UserCalendarScreenState extends State { ), ); } + + ScheduleEntity? _getScheduleFromNumDay(int numDay) { + switch (numDay) { + case 1: + return widget.userProfessional.professionalInfo.schedules.monday; + case 2: + return widget.userProfessional.professionalInfo.schedules.tuesday; + case 3: + return widget.userProfessional.professionalInfo.schedules.wednesday; + case 4: + return widget.userProfessional.professionalInfo.schedules.thursday; + case 5: + return widget.userProfessional.professionalInfo.schedules.friday; + case 6: + return widget.userProfessional.professionalInfo.schedules.saturday; + case 7: + return widget.userProfessional.professionalInfo.schedules.sunday; + default: + return null; + } + } + + List _rangesItems(ScheduleEntity? schedule) { + if (schedule == null || + schedule.enabled == false || + schedule.range1Hour1 == null || + schedule.range2Hour2 == null) { + return [const Text("No hay horarios disponibles")]; + } + + if (schedule.continuousDay) { + List ranges = TimeOfDayUtils.genRanges( + schedule.range1Hour1!, + schedule.range2Hour2!, + ); + + return rangesItemList(ranges, null); + } + + List ranges1 = TimeOfDayUtils.genRanges( + schedule.range1Hour1!, + schedule.range1Hour2!, + ); + List ranges2 = TimeOfDayUtils.genRanges( + schedule.range2Hour1!, + schedule.range2Hour2!, + ); + + return [ + ...rangesItemList(ranges1, null), + ...rangesItemList(ranges2, null), + ]; + } + + bool _isHora1Ocupada(TimeOfDay hora1, List? events) { + if (events != null) { + for (ServiceEntity event in events) { + DateTime time1 = DateTime( + today.year, + today.month, + today.day, + hora1.hour, + hora1.minute, + ); + + if (event.range1Hour1 == time1.toString()) { + return true; + } + } + } + return false; + } + + List rangesItemList( + List ranges, List? events) { + return ranges.map((time) { + if (_isHora1Ocupada(time, events)) { + return Card( + elevation: 4, + margin: const EdgeInsets.symmetric(vertical: 5, horizontal: 10), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + child: ListTile( + onTap: () { + ScaffoldMessenger.of(context).clearSnackBars(); + ScaffoldMessenger.of(context).showSnackBar(const SnackBar( + content: Text('Este horario ya fue ocupado'), + )); + }, + contentPadding: const EdgeInsets.all(16), + leading: Container( + width: 40, + height: 40, + decoration: const BoxDecoration( + gradient: LinearGradient( + colors: [Colors.yellow, Colors.red, Colors.red], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + shape: BoxShape.circle, + ), + child: const Center( + child: Icon( + Icons.access_time, + color: Colors.white, + ), + ), + ), + title: Text( + time.format(context), + style: const TextStyle(fontSize: 15, fontWeight: FontWeight.bold), + ), + subtitle: const Text( + 'Ocupado', + style: TextStyle( + color: Colors.red, fontSize: 13, fontWeight: FontWeight.bold), + ), + trailing: const Icon( + Icons.arrow_forward_ios, + color: Colors.grey, + ), + ), + ); + } else { + return Card( + elevation: 4, + margin: const EdgeInsets.symmetric(vertical: 5, horizontal: 10), + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(10), + ), + child: ListTile( + onTap: () { + Navigator.pop(context, [today, time, widget.userProfessional]); + }, + contentPadding: const EdgeInsets.all(16), + leading: Container( + width: 40, + height: 40, + decoration: const BoxDecoration( + gradient: LinearGradient( + colors: [Colors.blue, Colors.green], + begin: Alignment.topLeft, + end: Alignment.bottomRight, + ), + shape: BoxShape.circle, + ), + child: const Center( + child: Icon( + Icons.access_time, + color: Colors.white, + ), + ), + ), + title: Text( + time.format(context), + style: const TextStyle(fontSize: 15, fontWeight: FontWeight.bold), + ), + subtitle: const Text( + 'Disponible', + style: TextStyle( + color: Colors.green, + fontSize: 13, + fontWeight: FontWeight.bold, + ), + ), + trailing: const Icon( + Icons.arrow_forward_ios, + color: Colors.grey, + ), + ), + ); + } + }).toList(); + } } diff --git a/lib/screens/user/user_map_screen.dart b/lib/screens/user/user_map_screen.dart index 4879472..f4d8488 100644 --- a/lib/screens/user/user_map_screen.dart +++ b/lib/screens/user/user_map_screen.dart @@ -3,10 +3,12 @@ import 'dart:developer'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:geolocator/geolocator.dart'; import 'package:google_maps_flutter/google_maps_flutter.dart'; import 'package:injector/injector.dart'; -import 'package:prosappco/constansts.dart'; +import 'package:intl/intl.dart'; +import 'package:prosappco/blocs/my_user_bloc/my_user_bloc.dart'; import 'package:prosappco/screens/lists/professional_list_screen.dart'; import 'package:setting_repository/setting_repository.dart'; @@ -25,6 +27,11 @@ class _UserMapScreenState extends State { final settingRepository = Injector.appInstance.get(); SettingEntity? settings; + final DateFormat formatter = DateFormat('dd/MM/yyyy'); + + DateTime? fechaSeleccionada; + TimeOfDay? horaSeleccionada; + @override void initState() { super.initState(); @@ -42,102 +49,109 @@ class _UserMapScreenState extends State { @override Widget build(BuildContext context) { - return Column( - children: [ - Expanded( - child: Stack( - children: [ - GoogleMap( - myLocationEnabled: true, - onMapCreated: (GoogleMapController controller) { - _mapController.complete(controller); - }, - initialCameraPosition: const CameraPosition( - target: LatLng(7.078511421411328, -73.08832615613937 - // currentPosition.latitude, currentPosition.longitude - ), - zoom: 16, - ), - myLocationButtonEnabled: false, - ), - Positioned( - top: 10, - left: 0, - child: Builder( - builder: (context) { - return ElevatedButton( - style: ElevatedButton.styleFrom( - backgroundColor: Colors.white, - shape: const CircleBorder(), - elevation: 3, - minimumSize: const Size(50, 50), - ), - child: const Icon( - Icons.menu, - color: Colors.black, - size: 35, - ), - onPressed: () { - Scaffold.of(context).openDrawer(); - }, - ); - }, - ), - ), - const Positioned( - bottom: 30, - right: 0, - left: 0, - top: 0, - child: Icon( - Icons.location_on, - size: 40, - color: Color(0xFFFF0000), - ), - ), - Positioned( - top: 10, - right: 10, - child: FloatingActionButton( - onPressed: () async { - try { - Position position = await _determinePosition(); - - if (mounted) { - setState(() { - _currentP = LatLng( - position.latitude, - position.longitude, - ); - }); - - _animateCameraToPosition(_currentP!); - } - } catch (e) { - ScaffoldMessenger.of(context).clearSnackBars(); - ScaffoldMessenger.of(context).showSnackBar( - const SnackBar( - content: Text('Por favor activa la ubicacion'), - ), - ); - } - }, - elevation: 0, - child: const Icon( - Icons.gps_fixed, - size: 30, + return BlocBuilder( + builder: (context, state) { + return Column( + children: [ + Expanded( + child: Stack( + children: [ + GoogleMap( + myLocationEnabled: true, + onMapCreated: (GoogleMapController controller) { + _mapController.complete(controller); + }, + initialCameraPosition: const CameraPosition( + target: LatLng( + // 7.078511421411328, -73.08832615613937 + 7.1253900, + -73.1198000 + // currentPosition.latitude, currentPosition.longitude + ), + zoom: 16, + ), + myLocationButtonEnabled: false, ), - ), + Positioned( + top: 10, + left: 0, + child: Builder( + builder: (context) { + return ElevatedButton( + style: ElevatedButton.styleFrom( + backgroundColor: Colors.white, + shape: const CircleBorder(), + elevation: 3, + minimumSize: const Size(50, 50), + ), + child: const Icon( + Icons.menu, + color: Colors.black, + size: 35, + ), + onPressed: () { + Scaffold.of(context).openDrawer(); + }, + ); + }, + ), + ), + const Positioned( + bottom: 30, + right: 0, + left: 0, + top: 0, + child: Icon( + Icons.location_on, + size: 40, + color: Color(0xFFFF0000), + ), + ), + Positioned( + top: 10, + right: 10, + child: FloatingActionButton( + onPressed: () async { + try { + Position position = await _determinePosition(); + + if (mounted) { + setState(() { + _currentP = LatLng( + position.latitude, + position.longitude, + ); + }); + + _animateCameraToPosition(_currentP!); + } + } catch (e) { + ScaffoldMessenger.of(context).clearSnackBars(); + ScaffoldMessenger.of(context).showSnackBar( + const SnackBar( + content: Text('Por favor activa la ubicacion'), + ), + ); + } + }, + elevation: 0, + child: const Icon( + Icons.gps_fixed, + size: 30, + ), + ), + ), + ], ), - ], - ), - ), - buildBottom(context) - ], + ), + buildBottom(context, state), + ], + ); + }, ); } - Container buildBottom(BuildContext context) { + Container buildBottom(BuildContext context, MyUserState state) { return Container( padding: const EdgeInsets.symmetric(horizontal: 30, vertical: 10), color: Colors.white, @@ -147,11 +161,22 @@ class _UserMapScreenState extends State { TextField( readOnly: true, onTap: () async { - var datos = await Navigator.push(context, CupertinoPageRoute(builder: (context) { + var datos = await Navigator.push(context, + CupertinoPageRoute(builder: (context) { return const ProfessionalListScreen(); })); - log('xd -- $datos'); + log('xd -- datos $datos'); + + if (datos != null) { + fechaSeleccionada = datos[0]; + horaSeleccionada = datos[1]; + + log('xd -- $fechaSeleccionada'); + log('xd -- $horaSeleccionada'); + + setState(() {}); + } }, decoration: const InputDecoration( prefixIcon: Icon(Icons.assignment_ind_rounded), @@ -167,35 +192,52 @@ class _UserMapScreenState extends State { hintText: 'Dirección', ), ), - const SizedBox(height: 15), - const Row( - children: [ - Expanded( - child: TextField( - readOnly: true, + Visibility( + visible: fechaSeleccionada != null && horaSeleccionada != null, + child: Column( + children: [ + const SizedBox(height: 15), + Row( + children: [ + Expanded( + child: TextField( + readOnly: true, + controller: TextEditingController( + text: fechaSeleccionada == null + ? '' + : formatter.format(fechaSeleccionada!), + ), + decoration: const InputDecoration( + prefixIcon: Icon(Icons.calendar_month), + hintText: 'Fecha', + ), + ), + ), + Expanded( + child: TextField( + readOnly: true, + controller: TextEditingController( + text: horaSeleccionada == null + ? '' + : horaSeleccionada!.format(context), + ), + decoration: InputDecoration( + prefixIcon: Icon(Icons.watch_later_outlined), + hintText: 'Hora', + ), + ), + ), + ], + ), + const SizedBox(height: 15), + const TextField( + // controller: _observacionController, decoration: InputDecoration( - prefixIcon: Icon(Icons.calendar_month), - hintText: 'Fecha', + prefixIcon: Icon(Icons.message_outlined), + hintText: 'Observaciones', ), ), - ), - Expanded( - child: TextField( - readOnly: true, - decoration: InputDecoration( - prefixIcon: Icon(Icons.watch_later_outlined), - hintText: 'Hora', - ), - ), - ), - ], - ), - const SizedBox(height: 15), - const TextField( - // controller: _observacionController, - decoration: InputDecoration( - prefixIcon: Icon(Icons.message_outlined), - hintText: 'Observaciones', + ], ), ), const SizedBox(height: 15), diff --git a/lib/utils/time_of_day_extension.dart b/lib/utils/time_of_day_extension.dart new file mode 100644 index 0000000..a631b51 --- /dev/null +++ b/lib/utils/time_of_day_extension.dart @@ -0,0 +1,19 @@ +import 'package:flutter/material.dart'; + +extension TimeOfDayExtension on TimeOfDay { + TimeOfDay add({int hour = 0, int minute = 0}) { + return replacing(hour: this.hour + hour, minute: this.minute + minute); + } + + int compareTo(TimeOfDay other) { + if (hour < other.hour) return -1; + if (hour > other.hour) return 1; + if (minute < other.minute) return -1; + if (minute > other.minute) return 1; + return 0; + } + + bool isBefore(TimeOfDay other) { + return compareTo(other) == -1; + } +} diff --git a/lib/utils/time_of_day_utils.dart b/lib/utils/time_of_day_utils.dart new file mode 100644 index 0000000..cca94b1 --- /dev/null +++ b/lib/utils/time_of_day_utils.dart @@ -0,0 +1,15 @@ +import 'package:flutter/material.dart'; +import 'package:prosappco/utils/time_of_day_extension.dart'; + +class TimeOfDayUtils { + static List genRanges(TimeOfDay timeStart, TimeOfDay timeEnd) { + List ranges = []; + TimeOfDay current = timeStart; + while (current.isBefore(timeEnd)) { + ranges.add(current); + // Sumar 2 horas al objeto DateTime + current = current.add(hour: 2); + } + return ranges; + } +} diff --git a/packages/professional_repository/lib/src/entities/professional_entity.dart b/packages/professional_repository/lib/src/entities/professional_entity.dart index cff0a4d..f114bf5 100644 --- a/packages/professional_repository/lib/src/entities/professional_entity.dart +++ b/packages/professional_repository/lib/src/entities/professional_entity.dart @@ -53,14 +53,13 @@ class ProfessionalEntity extends Equatable { latitude: double.parse(doc['latitude'].toString()), longitude: double.parse(doc['longitude'].toString()), specializations: List.from(doc['specializations']), - specializationsPictures: List.from(doc['specializations_pictures']), + specializationsPictures: + List.from(doc['specializations_pictures']), schedules: Schedules.fromDocument(doc['schedules']), paymentMethods: PaymentMethodEntity.fromDocument(doc['payment_methods']), ); } - // copy func - ProfessionalEntity copyWith({ String? id, String? identification, diff --git a/packages/professional_repository/lib/src/entities/schedules.dart b/packages/professional_repository/lib/src/entities/schedules.dart index e1e3df5..d7ff84f 100644 --- a/packages/professional_repository/lib/src/entities/schedules.dart +++ b/packages/professional_repository/lib/src/entities/schedules.dart @@ -10,14 +10,15 @@ class Schedules extends Equatable { final ScheduleEntity saturday; final ScheduleEntity sunday; - const Schedules( - {required this.monday, - required this.tuesday, - required this.wednesday, - required this.thursday, - required this.friday, - required this.saturday, - required this.sunday}); + const Schedules({ + required this.monday, + required this.tuesday, + required this.wednesday, + required this.thursday, + required this.friday, + required this.saturday, + required this.sunday, + }); static const empty = Schedules( monday: ScheduleEntity.empty, 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 9553ac8..36a13c2 100644 --- a/packages/professional_repository/lib/src/repositories/firebase_professional_repository.dart +++ b/packages/professional_repository/lib/src/repositories/firebase_professional_repository.dart @@ -8,17 +8,14 @@ import 'package:professional_repository/professional_repository.dart'; import 'package:firebase_storage/firebase_storage.dart'; class FirebaseProfessionalRepository { - final professionalCollection = - FirebaseFirestore.instance.collection('professional_info'); + final professionalCollection = FirebaseFirestore.instance.collection('professional_info'); ProfessionalEntity? _proInfo; - final StreamController _proInfoBroadcast = - StreamController.broadcast(); + final StreamController _proInfoBroadcast = StreamController.broadcast(); bool isProModeActive = false; - final StreamController _isProModeActiveBroadcast = - StreamController.broadcast(); + final StreamController _isProModeActiveBroadcast = StreamController.broadcast(); FirebaseProfessionalRepository() { _isProModeActiveBroadcast.add(isProModeActive); diff --git a/packages/service_repository/lib/service_repository.dart b/packages/service_repository/lib/service_repository.dart new file mode 100644 index 0000000..8981468 --- /dev/null +++ b/packages/service_repository/lib/service_repository.dart @@ -0,0 +1,5 @@ +library service_repository; + +export 'src/entities/entities.dart'; +export 'src/models/models.dart'; +export 'src/repositories/firebase_service_repository.dart'; diff --git a/packages/service_repository/lib/src/entities/entities.dart b/packages/service_repository/lib/src/entities/entities.dart new file mode 100644 index 0000000..8435f2f --- /dev/null +++ b/packages/service_repository/lib/src/entities/entities.dart @@ -0,0 +1 @@ +export '/src/entities/service_entity.dart'; diff --git a/packages/service_repository/lib/src/entities/service_entity.dart b/packages/service_repository/lib/src/entities/service_entity.dart new file mode 100644 index 0000000..4494545 --- /dev/null +++ b/packages/service_repository/lib/src/entities/service_entity.dart @@ -0,0 +1,126 @@ +import 'package:equatable/equatable.dart'; +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:service_repository/service_repository.dart'; +import 'package:flutter/material.dart'; + +class ServiceEntity extends Equatable { + final String professionalId; + final bool professionalScored; + final String userId; + final bool userScored; + final String address; + final String aditionalAddress; + final double latitude; + final double longitude; + final String day; + final Timestamp createdAt; + final String description; + final TimeOfDay range1Hour1; + final TimeOfDay range1Hour2; + final String rate; + final ServiceStatus status; + final LocationPreferences location; + + const ServiceEntity({ + required this.professionalId, + required this.professionalScored, + required this.userId, + required this.userScored, + required this.address, + required this.aditionalAddress, + required this.latitude, + required this.longitude, + required this.day, + required this.createdAt, + required this.description, + required this.range1Hour1, + required this.range1Hour2, + required this.rate, + required this.status, + required this.location, + }); + + static ServiceEntity fromDocument(Map doc) { + return ServiceEntity( + professionalId: doc['professional_id'] as String, + professionalScored: doc['professional_scored'] as bool, + userId: doc['user_id'] as String, + userScored: doc['user_scored'] as bool, + address: doc['address'] as String, + aditionalAddress: doc['aditional_address'] as String, + latitude: doc['latitude'] as double, + longitude: doc['longitude'] as double, + day: doc['day'] as String, + createdAt: doc['created_at'] as Timestamp, + description: doc['description'] as String, + range1Hour1: doc['range1_hour1'] as TimeOfDay, + range1Hour2: doc['range1_hour2'] as TimeOfDay, + status: intToEnumService(doc['status'] as int), + rate: doc['rate'] as String, + location: intToEnum(doc['location'] as int), + ); + } + + Map toDocument() { + return { + 'professional_id': professionalId, + 'professional_scored': professionalScored, + 'user_id': userId, + 'user_scored': userScored, + 'address': address, + 'aditional_address': aditionalAddress, + 'latitude': latitude, + 'longitude': longitude, + 'day': day, + 'created_at': createdAt, + 'description': description, + 'range1_hour1': range1Hour1, + 'range1_hour2': range1Hour2, + 'rate': rate, + 'status': enumToIntService(status), + 'location': enumToInt(location), + }; + } + + @override + List get props => [ + professionalId, + professionalScored, + userId, + userScored, + address, + aditionalAddress, + latitude, + longitude, + day, + createdAt, + description, + range1Hour1, + range1Hour2, + rate, + status, + location, + ]; + + @override + String toString() { + return '''ServiceEntity{{ + professionalId: $professionalId, + professionalScored: $professionalScored, + userId: $userId, + userScored: $userScored, + address: $address, + aditionalAddress: $aditionalAddress, + latitude: $latitude, + longitude: $longitude, + day: $day, + createdAt: $createdAt, + description: $description, + range1Hour1: $range1Hour1, + range1Hour2: $range1Hour2, + rate: $rate, + status: $status, + location: $location + }}'''; + } +} diff --git a/packages/service_repository/lib/src/models/location_preferences.dart b/packages/service_repository/lib/src/models/location_preferences.dart new file mode 100644 index 0000000..45c8505 --- /dev/null +++ b/packages/service_repository/lib/src/models/location_preferences.dart @@ -0,0 +1,11 @@ +export 'location_preferences.dart'; + +enum LocationPreferences { office, delivery } + +int enumToInt(LocationPreferences state) { + return state.index; +} + +LocationPreferences intToEnum(int value) { + return LocationPreferences.values[value]; +} diff --git a/packages/service_repository/lib/src/models/models.dart b/packages/service_repository/lib/src/models/models.dart new file mode 100644 index 0000000..0f8ddda --- /dev/null +++ b/packages/service_repository/lib/src/models/models.dart @@ -0,0 +1,2 @@ +export 'location_preferences.dart'; +export 'service_status.dart'; diff --git a/packages/service_repository/lib/src/models/service_status.dart b/packages/service_repository/lib/src/models/service_status.dart new file mode 100644 index 0000000..4007918 --- /dev/null +++ b/packages/service_repository/lib/src/models/service_status.dart @@ -0,0 +1,11 @@ +export 'service_status.dart'; + +enum ServiceStatus { pending, active, cancelled, completed } + +int enumToIntService(ServiceStatus state) { + return state.index; +} + +ServiceStatus intToEnumService(int value) { + return ServiceStatus.values[value]; +} diff --git a/packages/service_repository/lib/src/repositories/firebase_service_repository.dart b/packages/service_repository/lib/src/repositories/firebase_service_repository.dart new file mode 100644 index 0000000..7287075 --- /dev/null +++ b/packages/service_repository/lib/src/repositories/firebase_service_repository.dart @@ -0,0 +1,10 @@ +import 'package:cloud_firestore/cloud_firestore.dart'; +import 'package:service_repository/service_repository.dart'; + +class FirebaseServiceRepository { + final serviceCollection = FirebaseFirestore.instance.collection('services'); + + Future createService(ServiceEntity entity) async { + await serviceCollection.doc().set(entity.toDocument()); + } +} diff --git a/packages/service_repository/pubspec.lock b/packages/service_repository/pubspec.lock new file mode 100644 index 0000000..cb1d0da --- /dev/null +++ b/packages/service_repository/pubspec.lock @@ -0,0 +1,266 @@ +# Generated by pub +# See https://dart.dev/tools/pub/glossary#lockfile +packages: + _flutterfire_internals: + dependency: transitive + description: + name: _flutterfire_internals + sha256: "4eec93681221723a686ad580c2e7d960e1017cf1a4e0a263c2573c2c6b0bf5cd" + url: "https://pub.dev" + source: hosted + version: "1.3.25" + async: + dependency: transitive + description: + name: async + sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c" + url: "https://pub.dev" + source: hosted + version: "2.11.0" + boolean_selector: + dependency: transitive + description: + name: boolean_selector + sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + characters: + dependency: transitive + description: + name: characters + sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605" + url: "https://pub.dev" + source: hosted + version: "1.3.0" + clock: + dependency: transitive + description: + name: clock + sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf + url: "https://pub.dev" + source: hosted + version: "1.1.1" + cloud_firestore: + dependency: "direct main" + description: + name: cloud_firestore + sha256: "31cfa4d65d6e9ea837234fffe121304034c30c9214c06207b4a35867e3757900" + url: "https://pub.dev" + source: hosted + version: "4.15.8" + cloud_firestore_platform_interface: + dependency: transitive + description: + name: cloud_firestore_platform_interface + sha256: a0097a26569b015faf8142e159e855241609ea9a1738b5fd1c40bfe8411b41a0 + url: "https://pub.dev" + source: hosted + version: "6.1.9" + cloud_firestore_web: + dependency: transitive + description: + name: cloud_firestore_web + sha256: ed680ece29a5750985119c09cdc276b460c3a2fa80e8c12f9b7241f6b4a7ca16 + url: "https://pub.dev" + source: hosted + version: "3.10.8" + collection: + dependency: transitive + description: + name: collection + sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a + url: "https://pub.dev" + source: hosted + version: "1.18.0" + equatable: + dependency: "direct main" + description: + name: equatable + sha256: c2b87cb7756efdf69892005af546c56c0b5037f54d2a88269b4f347a505e3ca2 + url: "https://pub.dev" + source: hosted + version: "2.0.5" + fake_async: + dependency: transitive + description: + name: fake_async + sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78" + url: "https://pub.dev" + source: hosted + version: "1.3.1" + firebase_core: + dependency: "direct main" + description: + name: firebase_core + sha256: "53316975310c8af75a96e365f9fccb67d1c544ef0acdbf0d88bbe30eedd1c4f9" + url: "https://pub.dev" + source: hosted + version: "2.27.0" + firebase_core_platform_interface: + dependency: transitive + description: + name: firebase_core_platform_interface + sha256: c437ae5d17e6b5cc7981cf6fd458a5db4d12979905f9aafd1fea930428a9fe63 + url: "https://pub.dev" + source: hosted + version: "5.0.0" + firebase_core_web: + dependency: transitive + description: + name: firebase_core_web + sha256: c8e1d59385eee98de63c92f961d2a7062c5d9a65e7f45bdc7f1b0b205aab2492 + url: "https://pub.dev" + source: hosted + version: "2.11.5" + flutter: + dependency: "direct main" + description: flutter + source: sdk + version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 + url: "https://pub.dev" + source: hosted + version: "2.0.3" + flutter_test: + dependency: "direct dev" + description: flutter + source: sdk + version: "0.0.0" + flutter_web_plugins: + dependency: transitive + description: flutter + source: sdk + version: "0.0.0" + js: + dependency: transitive + description: + name: js + sha256: f2c445dce49627136094980615a031419f7f3eb393237e4ecd97ac15dea343f3 + url: "https://pub.dev" + source: hosted + version: "0.6.7" + lints: + dependency: transitive + description: + name: lints + sha256: "0a217c6c989d21039f1498c3ed9f3ed71b354e69873f13a8dfc3c9fe76f1b452" + url: "https://pub.dev" + source: hosted + version: "2.1.1" + matcher: + dependency: transitive + description: + name: matcher + sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e" + url: "https://pub.dev" + source: hosted + version: "0.12.16" + material_color_utilities: + dependency: transitive + description: + name: material_color_utilities + sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41" + url: "https://pub.dev" + source: hosted + version: "0.5.0" + meta: + dependency: transitive + description: + name: meta + sha256: a6e590c838b18133bb482a2745ad77c5bb7715fb0451209e1a7567d416678b8e + url: "https://pub.dev" + source: hosted + version: "1.10.0" + path: + dependency: transitive + description: + name: path + sha256: "8829d8a55c13fc0e37127c29fedf290c102f4e40ae94ada574091fe0ff96c917" + url: "https://pub.dev" + source: hosted + version: "1.8.3" + plugin_platform_interface: + dependency: transitive + description: + name: plugin_platform_interface + sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02" + url: "https://pub.dev" + source: hosted + version: "2.1.8" + sky_engine: + dependency: transitive + description: flutter + source: sdk + version: "0.0.99" + source_span: + dependency: transitive + description: + name: source_span + sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c" + url: "https://pub.dev" + source: hosted + version: "1.10.0" + stack_trace: + dependency: transitive + description: + name: stack_trace + sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b" + url: "https://pub.dev" + source: hosted + version: "1.11.1" + stream_channel: + dependency: transitive + description: + name: stream_channel + sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7 + url: "https://pub.dev" + source: hosted + version: "2.1.2" + string_scanner: + dependency: transitive + description: + name: string_scanner + sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde" + url: "https://pub.dev" + source: hosted + version: "1.2.0" + term_glyph: + dependency: transitive + description: + name: term_glyph + sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84 + url: "https://pub.dev" + source: hosted + version: "1.2.1" + test_api: + dependency: transitive + description: + name: test_api + sha256: "5c2f730018264d276c20e4f1503fd1308dfbbae39ec8ee63c5236311ac06954b" + url: "https://pub.dev" + source: hosted + version: "0.6.1" + vector_math: + dependency: transitive + description: + name: vector_math + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" + url: "https://pub.dev" + source: hosted + version: "2.1.4" + web: + dependency: transitive + description: + name: web + sha256: afe077240a270dcfd2aafe77602b4113645af95d0ad31128cc02bce5ac5d5152 + url: "https://pub.dev" + source: hosted + version: "0.3.0" +sdks: + dart: ">=3.2.0 <4.0.0" + flutter: ">=3.3.0" diff --git a/packages/service_repository/pubspec.yaml b/packages/service_repository/pubspec.yaml new file mode 100644 index 0000000..d71b41a --- /dev/null +++ b/packages/service_repository/pubspec.yaml @@ -0,0 +1,25 @@ +name: service_repository +description: Dart package for the Service Repository. +publish_to: 'none' + +version: 1.0.11+11 + +environment: + sdk: ">=2.19.3 <3.0.0" + +dependencies: + flutter: + sdk: flutter + equatable: ^2.0.5 + + # Firebase + cloud_firestore: ^4.15.4 + firebase_core: ^2.25.4 + +dev_dependencies: + flutter_lints: ^2.0.0 + flutter_test: + sdk: flutter + +flutter: + uses-material-design: true \ No newline at end of file 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 a829329..df3bb95 100644 --- a/packages/user_repository/lib/src/repositories/firebase_user_repository.dart +++ b/packages/user_repository/lib/src/repositories/firebase_user_repository.dart @@ -395,8 +395,6 @@ class FirebaseUserRepository implements UserRepository { .where('professional_state', isEqualTo: ProState.active.index) .get(); - log('xd -- ${querySnapshot.docs}'); - return querySnapshot.docs .map((e) => MyUser.fromEntity(MyUserEntity.fromDocument(e.data()))) .toList(); diff --git a/pubspec.lock b/pubspec.lock index 33f967a..0d31cfa 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -13,10 +13,10 @@ packages: dependency: transitive description: name: _flutterfire_internals - sha256: "1a52f1afae8ab7ac4741425114713bdbba802f1ce1e0648e167ffcc6e05e96cf" + sha256: "4eec93681221723a686ad580c2e7d960e1017cf1a4e0a263c2573c2c6b0bf5cd" url: "https://pub.dev" source: hosted - version: "1.3.21" + version: "1.3.25" analyzer: dependency: transitive description: @@ -276,34 +276,34 @@ packages: dependency: "direct main" description: name: firebase_auth - sha256: "549f8ceb8cfc1920f85dea0ab73fb7dc209ee8182916b252eda342786c33369d" + sha256: "17b841e1b000c3441b8ffceca88f468e078d0443db9643e77541bdfb7a3fd16b" url: "https://pub.dev" source: hosted - version: "4.17.4" + version: "4.17.8" firebase_auth_platform_interface: dependency: transitive description: name: firebase_auth_platform_interface - sha256: "83bfc14649f673db17ad0bffaa0222019f99f3ddf499bcc8b46e1eb3443d3e08" + sha256: f294ceef40409a36c819a14280ca864fe487b44033e5276443377c66cb448310 url: "https://pub.dev" source: hosted - version: "7.1.4" + version: "7.1.8" firebase_auth_web: dependency: transitive description: name: firebase_auth_web - sha256: d2266452698dd5f6e522408dacfa06bb7f9703b5bdd11498fce2812ded50805b + sha256: "1f231da900fe7ff9f2974f8adcbdb3363c410c24725978afa5dc33e1e7e62e06" url: "https://pub.dev" source: hosted - version: "5.9.4" + version: "5.9.8" firebase_core: dependency: "direct main" description: name: firebase_core - sha256: "7e049e32a9d347616edb39542cf92cd53fdb4a99fb6af0a0bff327c14cd76445" + sha256: "53316975310c8af75a96e365f9fccb67d1c544ef0acdbf0d88bbe30eedd1c4f9" url: "https://pub.dev" source: hosted - version: "2.25.4" + version: "2.27.0" firebase_core_platform_interface: dependency: transitive description: @@ -316,10 +316,10 @@ packages: dependency: transitive description: name: firebase_core_web - sha256: "57e61d6010e253b36d38191cefd6199d7849152cdcd234b61ca290cdb278a0ba" + sha256: c8e1d59385eee98de63c92f961d2a7062c5d9a65e7f45bdc7f1b0b205aab2492 url: "https://pub.dev" source: hosted - version: "2.11.4" + version: "2.11.5" firebase_storage: dependency: transitive description: @@ -1018,6 +1018,13 @@ packages: url: "https://pub.dev" source: hosted version: "2.1.0" + service_repository: + dependency: "direct main" + description: + path: "packages/service_repository" + relative: true + source: path + version: "1.0.11+11" setting_repository: dependency: "direct main" description: diff --git a/pubspec.yaml b/pubspec.yaml index 4ddf796..145c6f1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -62,6 +62,8 @@ dependencies: path: packages/professional_repository profession_repository: path: packages/profession_repository + service_repository: + path: packages/service_repository webview_flutter: ^4.4.1 dev_dependencies: