update
This commit is contained in:
@@ -7,9 +7,7 @@ import 'package:prosappco/src/authentication/authentication_repository.dart';
|
||||
import 'package:prosappco/src/components/photo_view.dart';
|
||||
import 'package:prosappco/src/models/user_model.dart';
|
||||
import 'package:prosappco/src/presentation/screens/calendar.dart';
|
||||
import 'package:prosappco/src/presentation/screens/messages.dart';
|
||||
import 'package:prosappco/src/presentation/screens/my_services_pro.dart';
|
||||
import 'package:prosappco/src/presentation/screens/professional.dart';
|
||||
import 'package:prosappco/src/presentation/screens/profile/profile.dart';
|
||||
import 'package:prosappco/src/presentation/screens/profile/profile_pro.dart';
|
||||
import 'package:prosappco/src/presentation/screens/profile/profile_pro_web.dart';
|
||||
@@ -31,8 +29,7 @@ class _DrawerProfessionalState extends State<DrawerProfessional> {
|
||||
ScoresModel? scoresModel;
|
||||
|
||||
Future<void> _irSugerencias() async {
|
||||
const url =
|
||||
'https://admin.prosapp.co/sugerencias '; // Aquí debes poner la URL a la que quieres dirigirte
|
||||
const url = 'https://admin.prosapp.co/sugerencias';
|
||||
if (await canLaunch(url)) {
|
||||
await launch(url);
|
||||
} else {
|
||||
|
||||
@@ -199,13 +199,13 @@ class Schedule {
|
||||
} catch (e) {
|
||||
print('Error getting user: $e');
|
||||
return {
|
||||
"Lunes": Schedule(false, false, null, null, null, null),
|
||||
"Martes": Schedule(false, false, null, null, null, null),
|
||||
"Miercoles": Schedule(false, false, null, null, null, null),
|
||||
"Jueves": Schedule(false, false, null, null, null, null),
|
||||
"Viernes": Schedule(false, false, null, null, null, null),
|
||||
"Sabado": Schedule(false, false, null, null, null, null),
|
||||
"Domingo": Schedule(false, false, null, null, null, null),
|
||||
"1": Schedule(false, false, null, null, null, null),
|
||||
"2": Schedule(false, false, null, null, null, null),
|
||||
"3": Schedule(false, false, null, null, null, null),
|
||||
"4": Schedule(false, false, null, null, null, null),
|
||||
"5": Schedule(false, false, null, null, null, null),
|
||||
"6": Schedule(false, false, null, null, null, null),
|
||||
"7": Schedule(false, false, null, null, null, null),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,99 @@
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:firebase_storage/firebase_storage.dart';
|
||||
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
||||
import 'package:prosappco/src/models/scores_model.dart';
|
||||
|
||||
class Professional {
|
||||
final String id;
|
||||
final Reference professionalRef;
|
||||
final String name;
|
||||
final String professionName;
|
||||
final String cityName;
|
||||
final String ubicacion;
|
||||
final String realAddress;
|
||||
final double latitude;
|
||||
final double longitude;
|
||||
final List<String> professionalEspecializado;
|
||||
final ScoresModel scores;
|
||||
final int? tarifa;
|
||||
final String? token;
|
||||
|
||||
Professional({
|
||||
required this.id,
|
||||
required this.professionalRef,
|
||||
required this.name,
|
||||
required this.professionName,
|
||||
required this.cityName,
|
||||
required this.ubicacion,
|
||||
required this.professionalEspecializado,
|
||||
required this.scores,
|
||||
required this.realAddress,
|
||||
required this.latitude,
|
||||
required this.longitude,
|
||||
this.tarifa,
|
||||
this.token,
|
||||
});
|
||||
|
||||
String getEspecializaciones() {
|
||||
return professionalEspecializado.join(',\n');
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Professional {\n'
|
||||
' professionalRef: $professionalRef,\n'
|
||||
' name: $name,\n'
|
||||
' professionName: $professionName,\n'
|
||||
' cityName: $cityName,\n'
|
||||
' ubicacion: $ubicacion,\n'
|
||||
' realAddress: $realAddress,\n'
|
||||
' latitude: $latitude,\n'
|
||||
' longitude: $longitude,\n'
|
||||
' professionalEspecializado: ${getEspecializaciones()}\n'
|
||||
' tarifa: $tarifa,\n'
|
||||
' token: $token,\n'
|
||||
'}';
|
||||
}
|
||||
|
||||
static Future<Professional?> getProfessional(String uid) async {
|
||||
var photo = '...';
|
||||
final FirebaseStorage storage = FirebaseStorage.instance;
|
||||
|
||||
try {
|
||||
DocumentSnapshot user =
|
||||
await FirebaseFirestore.instance.collection('users').doc(uid).get();
|
||||
|
||||
Map<String, dynamic> data = user.data() as Map<String, dynamic>;
|
||||
|
||||
photo = await AuthenticationRepository.instance.getPhoto(user.id);
|
||||
|
||||
if (data['estado'] == 'activo') {
|
||||
List<String> especializaciones;
|
||||
|
||||
especializaciones = (data['especializaciones'] as List<dynamic>)
|
||||
.map((e) => e.toString())
|
||||
.toList();
|
||||
|
||||
Professional professional = Professional(
|
||||
id: user.id,
|
||||
name: data['name'],
|
||||
professionName: data['profesion'],
|
||||
cityName: data['city'],
|
||||
professionalRef: storage.ref().child(photo),
|
||||
professionalEspecializado: especializaciones,
|
||||
ubicacion: data['ubicacion'] ?? '',
|
||||
realAddress: data['address'] ?? '',
|
||||
latitude: data['latitude'] ?? 0,
|
||||
longitude: data['longitude'] ?? 0,
|
||||
scores: await ScoresModel.scoreFrom(uid, true, true),
|
||||
tarifa: data['tarifas'] ?? 0,
|
||||
token: data['token'] ?? '',
|
||||
);
|
||||
return professional;
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error al obtener profesionales: $e');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,264 @@
|
||||
import 'package:flutter/foundation.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
||||
import 'package:prosappco/src/components/pop_appbar.dart';
|
||||
import 'package:prosappco/src/components/schedule_picker.dart';
|
||||
import 'package:prosappco/src/models/event_model.dart';
|
||||
import 'package:prosappco/src/models/professional_model.dart';
|
||||
import 'package:prosappco/src/presentation/screens/map/service.dart';
|
||||
import 'package:prosappco/src/utils/time_of_day_utils.dart';
|
||||
import 'package:table_calendar/table_calendar.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
class CalendarProScreen extends StatefulWidget {
|
||||
final Professional professional;
|
||||
|
||||
const CalendarProScreen({super.key, required this.professional});
|
||||
|
||||
@override
|
||||
State<CalendarProScreen> createState() => _CalendarProScreenState();
|
||||
}
|
||||
|
||||
class _CalendarProScreenState extends State<CalendarProScreen> {
|
||||
final uid = AuthenticationRepository.instance.getCurrentUserUid();
|
||||
List<Event>? _events;
|
||||
|
||||
EventoService eventoService = EventoService();
|
||||
CalendarFormat _calendarFormat = CalendarFormat.month;
|
||||
|
||||
DateTime today = DateTime.now();
|
||||
DateTime now = DateTime.now();
|
||||
late int numDay;
|
||||
|
||||
Map<String, Schedule>? _horarios;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
if (_horarios == null) {
|
||||
Schedule.getHorarios(widget.professional.id.toString()).then(
|
||||
(Map<String, Schedule> data) {
|
||||
setState(() {
|
||||
_horarios = data;
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
today = DateTime.utc(today.year, today.month, today.day);
|
||||
numDay = today.weekday;
|
||||
|
||||
if (_events == null) {
|
||||
Event.getEventsAllByIdStatus(uid ?? "", 'aprobado')
|
||||
.then((value) => setState(() {
|
||||
_events = value;
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
void _onDaySelected(DateTime day, DateTime focusedDay) {
|
||||
setState(() {
|
||||
today = day;
|
||||
numDay = today.weekday;
|
||||
});
|
||||
}
|
||||
|
||||
void _onFormatChange(CalendarFormat format) {
|
||||
setState(() {
|
||||
_calendarFormat = format;
|
||||
});
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
if (_events == null) {
|
||||
return const Scaffold(
|
||||
body: Center(
|
||||
child: CircularProgressIndicator(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
var events = _events!;
|
||||
|
||||
DateTime lastDay = today.add(const Duration(days: 365));
|
||||
|
||||
return Scaffold(
|
||||
floatingActionButtonLocation: kIsWeb
|
||||
? FloatingActionButtonLocation.startFloat
|
||||
: FloatingActionButtonLocation.endFloat,
|
||||
resizeToAvoidBottomInset: false,
|
||||
appBar: PopAppbar(
|
||||
onPressed: () {
|
||||
Navigator.pop(context);
|
||||
},
|
||||
label: 'Calendario',
|
||||
),
|
||||
body: Column(
|
||||
children: [
|
||||
Container(
|
||||
color: const Color.fromARGB(255, 224, 247, 255),
|
||||
child: TableCalendar(
|
||||
locale: 'es_MX',
|
||||
firstDay: DateTime.utc(2010, 10, 16),
|
||||
lastDay: lastDay,
|
||||
focusedDay: today,
|
||||
availableGestures: AvailableGestures.all,
|
||||
onDaySelected: _onDaySelected,
|
||||
selectedDayPredicate: (day) => isSameDay(day, today),
|
||||
calendarFormat: _calendarFormat,
|
||||
onFormatChanged: _onFormatChange,
|
||||
// eventLoader: (date) {
|
||||
// return events
|
||||
// .where((element) {
|
||||
// DateTime day = DateTime.parse(element.day);
|
||||
// return (date.year == day.year &&
|
||||
// date.month == day.month &&
|
||||
// date.day == day.day);
|
||||
// })
|
||||
// .map((e) => e.description)
|
||||
// .toList();
|
||||
// },
|
||||
availableCalendarFormats: const {
|
||||
CalendarFormat.month: 'Mes',
|
||||
CalendarFormat.week: 'Semana',
|
||||
CalendarFormat.twoWeeks: '2 Semanas',
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(
|
||||
width: double.infinity,
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 15, vertical: 8),
|
||||
child: Text(DateFormat('dd MMMM yyyy', 'es').format(today),
|
||||
style: const TextStyle(
|
||||
color: Colors.black,
|
||||
fontSize: 16,
|
||||
fontWeight: FontWeight.w600,
|
||||
)),
|
||||
),
|
||||
),
|
||||
const Divider(
|
||||
height: 0,
|
||||
),
|
||||
Expanded(
|
||||
child: SingleChildScrollView(
|
||||
padding: const EdgeInsets.only(bottom: 15),
|
||||
child: Column(
|
||||
children: [...rangesItems(_horarios?[numDay.toString()])],
|
||||
),
|
||||
))
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
List<Widget> rangesItems(Schedule? schedule) {
|
||||
if (schedule == null) {
|
||||
return const [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 20, left: 30, right: 30),
|
||||
child: Text(
|
||||
'El profesional no acepta turnos este día',
|
||||
style: TextStyle(fontSize: 15, fontWeight: FontWeight.w500),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
),
|
||||
];
|
||||
}
|
||||
if (!schedule.habilitado) {
|
||||
return const [
|
||||
Padding(
|
||||
padding: EdgeInsets.only(top: 20, left: 30, right: 30),
|
||||
child: Text(
|
||||
'El profesional no acepta turnos este día',
|
||||
style: TextStyle(fontSize: 15, fontWeight: FontWeight.w500),
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
)
|
||||
];
|
||||
}
|
||||
if (schedule.jornadaContinua) {
|
||||
List<TimeOfDay> ranges = TimeOfDayUtils.genRanges(
|
||||
schedule.range1Hour1!,
|
||||
schedule.range2Hour2!,
|
||||
);
|
||||
|
||||
return rangesItemsa(ranges);
|
||||
} else {
|
||||
List<TimeOfDay> ranges1 = TimeOfDayUtils.genRanges(
|
||||
schedule.range1Hour1!,
|
||||
schedule.range1Hour2!,
|
||||
);
|
||||
List<TimeOfDay> ranges2 = TimeOfDayUtils.genRanges(
|
||||
schedule.range2Hour1!,
|
||||
schedule.range2Hour2!,
|
||||
);
|
||||
|
||||
return [
|
||||
...rangesItemsa(ranges1),
|
||||
...rangesItemsa(ranges2),
|
||||
];
|
||||
}
|
||||
}
|
||||
|
||||
List<Widget> rangesItemsa(List<TimeOfDay> ranges) {
|
||||
return ranges
|
||||
.map((time) => Card(
|
||||
elevation: 4,
|
||||
margin: const EdgeInsets.symmetric(vertical: 5, horizontal: 10),
|
||||
shape: RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: ListTile(
|
||||
onTap: () {
|
||||
Navigator.pushAndRemoveUntil(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => ServiceScreen(
|
||||
fechaSeleccionada: today, horaSeleccionada: time),
|
||||
),
|
||||
(route) => false, // Elimina todas las rutas en la pila
|
||||
);
|
||||
},
|
||||
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();
|
||||
}
|
||||
}
|
||||
@@ -9,8 +9,8 @@ import 'package:prosappco/src/components/photo_view.dart';
|
||||
import 'package:prosappco/src/components/pop_appbar.dart';
|
||||
import 'package:prosappco/src/models/chat_model.dart';
|
||||
import 'package:prosappco/src/models/event_model.dart';
|
||||
import 'package:prosappco/src/models/professional_model.dart';
|
||||
import 'package:prosappco/src/models/user_model.dart';
|
||||
import 'package:prosappco/src/presentation/screens/professional.dart';
|
||||
import 'package:prosappco/src/presentation/screens/professional_info.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import 'package:cloud_firestore/cloud_firestore.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
||||
import 'package:prosappco/src/components/pop_appbar.dart';
|
||||
import 'package:prosappco/src/components/primary_btn.dart';
|
||||
@@ -22,22 +23,32 @@ class HorarioScreen extends StatelessWidget {
|
||||
Future<void> updateHorario(BuildContext context) async {
|
||||
try {
|
||||
Map<String, dynamic> horariosMap = {};
|
||||
|
||||
horarios.forEach((key, value) {
|
||||
if (value.habilitado && !value.jornadaContinua) {
|
||||
if (value.range1Hour1 == null ||
|
||||
value.range1Hour2 == null ||
|
||||
value.range2Hour1 == null ||
|
||||
value.range2Hour2 == null) {
|
||||
value.habilitado = false;
|
||||
value.jornadaContinua = false;
|
||||
}
|
||||
}
|
||||
|
||||
if (value.habilitado && value.jornadaContinua) {
|
||||
if (value.range1Hour1 == null || value.range2Hour2 == null) {
|
||||
value.habilitado = false;
|
||||
value.jornadaContinua = false;
|
||||
}
|
||||
}
|
||||
|
||||
horariosMap[key] = {
|
||||
'habilitado': value.habilitado,
|
||||
'jornadaContinua': value.jornadaContinua,
|
||||
'range1Hour1': value.range1Hour1 != null
|
||||
? value.range1Hour1!.format(context).toString()
|
||||
: null,
|
||||
'range1Hour2': value.range1Hour2 != null
|
||||
? value.range1Hour2!.format(context).toString()
|
||||
: null,
|
||||
'range2Hour1': value.range2Hour1 != null
|
||||
? value.range2Hour1!.format(context).toString()
|
||||
: null,
|
||||
'range2Hour2': value.range2Hour2 != null
|
||||
? value.range2Hour2!.format(context).toString()
|
||||
: null,
|
||||
'range1Hour1': formatTimeOfDay(value.range1Hour1),
|
||||
'range1Hour2': formatTimeOfDay(value.range1Hour2),
|
||||
'range2Hour1': formatTimeOfDay(value.range2Hour1),
|
||||
'range2Hour2': formatTimeOfDay(value.range2Hour2),
|
||||
};
|
||||
});
|
||||
|
||||
@@ -49,27 +60,99 @@ class HorarioScreen extends StatelessWidget {
|
||||
}
|
||||
}
|
||||
|
||||
// Future<void> updateHorario(BuildContext context) async {
|
||||
// try {
|
||||
// Map<String, dynamic> horariosMap = {};
|
||||
// horarios.forEach((key, value) {
|
||||
// if (value.habilitado && !value.jornadaContinua) {
|
||||
// if (value.range1Hour1 == null ||
|
||||
// value.range1Hour2 == null ||
|
||||
// value.range2Hour1 == null ||
|
||||
// value.range2Hour2 == null) {
|
||||
// value.habilitado = false;
|
||||
// value.jornadaContinua = false;
|
||||
// return;
|
||||
// }
|
||||
// }
|
||||
|
||||
// if (value.habilitado && value.jornadaContinua) {
|
||||
// if (value.range1Hour1 == null || value.range2Hour2 == null) {
|
||||
// value.habilitado = false;
|
||||
// value.jornadaContinua = false;
|
||||
// }
|
||||
// }
|
||||
|
||||
// horariosMap[key] = {
|
||||
// 'habilitado': value.habilitado,
|
||||
// 'jornadaContinua': value.jornadaContinua,
|
||||
// 'range1Hour1': formatTimeOfDay(value.range1Hour1),
|
||||
// 'range1Hour2': formatTimeOfDay(value.range1Hour2),
|
||||
// 'range2Hour1': formatTimeOfDay(value.range2Hour1),
|
||||
// 'range2Hour2': formatTimeOfDay(value.range2Hour2),
|
||||
// };
|
||||
// });
|
||||
|
||||
// await FirebaseFirestore.instance.collection('users').doc(uid).update({
|
||||
// 'horario': horariosMap,
|
||||
// });
|
||||
// } catch (e) {
|
||||
// print('Error al actualizar el horario: $e');
|
||||
// }
|
||||
// }
|
||||
|
||||
String? formatTimeOfDay(TimeOfDay? time) {
|
||||
if (time != null) {
|
||||
final now = DateTime.now();
|
||||
final dateTime =
|
||||
DateTime(now.year, now.month, now.day, time.hour, time.minute);
|
||||
final format = DateFormat.jm();
|
||||
return format.format(dateTime);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
int _dayOfWeekToInt(String dayOfWeek) {
|
||||
switch (dayOfWeek) {
|
||||
case 'Lunes':
|
||||
case '1':
|
||||
return 1;
|
||||
case 'Martes':
|
||||
case '2':
|
||||
return 2;
|
||||
case 'Miercoles':
|
||||
case '3':
|
||||
return 3;
|
||||
case 'Jueves':
|
||||
case '4':
|
||||
return 4;
|
||||
case 'Viernes':
|
||||
case '5':
|
||||
return 5;
|
||||
case 'Sabado':
|
||||
case '6':
|
||||
return 6;
|
||||
case 'Domingo':
|
||||
case '7':
|
||||
return 7;
|
||||
default:
|
||||
throw ArgumentError('Invalid day of week: $dayOfWeek');
|
||||
}
|
||||
}
|
||||
|
||||
String _stringToDayOfWeek(String dayOfWeek) {
|
||||
switch (dayOfWeek) {
|
||||
case '1':
|
||||
return 'Lunes';
|
||||
case '2':
|
||||
return 'Martes';
|
||||
case '3':
|
||||
return 'Miércoles';
|
||||
case '4':
|
||||
return 'Jueves';
|
||||
case '5':
|
||||
return 'Viernes';
|
||||
case '6':
|
||||
return 'Sábado';
|
||||
case '7':
|
||||
return 'Domingo';
|
||||
default:
|
||||
throw ArgumentError('Invalid day of week: $dayOfWeek');
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final sortedHorarios = Map.fromEntries(
|
||||
@@ -94,7 +177,7 @@ class HorarioScreen extends StatelessWidget {
|
||||
children: sortedHorarios.entries.map<Widget>(
|
||||
(entry) {
|
||||
return SchedulePicker(
|
||||
name: entry.key,
|
||||
name: _stringToDayOfWeek(entry.key),
|
||||
schedule: entry.value,
|
||||
);
|
||||
},
|
||||
|
||||
@@ -18,6 +18,7 @@ import 'package:prosappco/constansts.dart';
|
||||
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
||||
import 'package:prosappco/src/components/network_utility.dart';
|
||||
import 'package:prosappco/src/models/event_model.dart';
|
||||
import 'package:prosappco/src/models/professional_model.dart';
|
||||
import 'package:prosappco/src/models/setting_model.dart';
|
||||
import 'package:prosappco/src/models/user_model.dart';
|
||||
import 'package:prosappco/src/presentation/screens/professional.dart';
|
||||
@@ -32,7 +33,11 @@ import 'package:provider/provider.dart';
|
||||
import 'package:url_launcher/url_launcher.dart';
|
||||
|
||||
class ServiceScreen extends StatefulWidget {
|
||||
const ServiceScreen({super.key});
|
||||
final DateTime? fechaSeleccionada;
|
||||
final TimeOfDay? horaSeleccionada;
|
||||
|
||||
const ServiceScreen(
|
||||
{super.key, this.fechaSeleccionada, this.horaSeleccionada});
|
||||
|
||||
@override
|
||||
State<ServiceScreen> createState() => _ServiceScreenState();
|
||||
@@ -100,6 +105,9 @@ class _ServiceScreenState extends State<ServiceScreen> {
|
||||
|
||||
_auth = FirebaseAuth.instance;
|
||||
|
||||
print('jurgo 1 ${widget.fechaSeleccionada}');
|
||||
print('jurgo 2 ${widget.horaSeleccionada}');
|
||||
|
||||
final currentUser = _auth.currentUser;
|
||||
|
||||
if (currentUser != null && currentUser.displayName != null) {
|
||||
@@ -611,64 +619,79 @@ class _ServiceScreenState extends State<ServiceScreen> {
|
||||
},
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
readOnly: true,
|
||||
decoration: InputDecoration(
|
||||
prefixIcon: const Icon(Icons.calendar_month),
|
||||
suffixIcon: _selectedDate == null
|
||||
? const Icon(Icons.arrow_drop_down)
|
||||
: null,
|
||||
hintText: 'Fecha',
|
||||
),
|
||||
controller: TextEditingController(
|
||||
text: _selectedDate == null
|
||||
? ''
|
||||
: formatter.format(_selectedDate!),
|
||||
),
|
||||
onTap: () {
|
||||
if (_profesionalController.text.isNotEmpty) {
|
||||
_selectDateAndTime(context);
|
||||
} else {
|
||||
WarningSnackbar.show(
|
||||
title: 'Selecciona un profesional',
|
||||
message:
|
||||
'Selecciona un profesional antes de elegir la fecha y la hora de la cita.',
|
||||
backgroundColor: Colors.orange,
|
||||
);
|
||||
}
|
||||
},
|
||||
widget.fechaSeleccionada == null &&
|
||||
widget.horaSeleccionada == null
|
||||
? const SizedBox()
|
||||
: const SizedBox(height: 15),
|
||||
widget.fechaSeleccionada == null &&
|
||||
widget.horaSeleccionada == null
|
||||
? const SizedBox()
|
||||
: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
readOnly: true,
|
||||
decoration: const InputDecoration(
|
||||
prefixIcon: Icon(Icons.calendar_month),
|
||||
hintText: 'Fecha',
|
||||
),
|
||||
// controller: TextEditingController(
|
||||
// text: _selectedDate == null
|
||||
// ? ''
|
||||
// : formatter.format(_selectedDate!),
|
||||
// ),
|
||||
controller: TextEditingController(
|
||||
text: widget.fechaSeleccionada == null
|
||||
? ''
|
||||
: formatter
|
||||
.format(widget.fechaSeleccionada!),
|
||||
),
|
||||
// onTap: () {
|
||||
// if (_profesionalController
|
||||
// .text.isNotEmpty) {
|
||||
// _selectDateAndTime(context);
|
||||
// } else {
|
||||
// WarningSnackbar.show(
|
||||
// title: 'Selecciona un profesional',
|
||||
// message:
|
||||
// 'Selecciona un profesional antes de elegir la fecha y la hora de la cita.',
|
||||
// backgroundColor: Colors.orange,
|
||||
// );
|
||||
// }
|
||||
// },
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
// onTap: () {
|
||||
// if (_profesionalController.text.isNotEmpty) {
|
||||
// _selectDateAndTime(context);
|
||||
// } else {
|
||||
// WarningSnackbar.show(
|
||||
// title: 'Selecciona un profesional',
|
||||
// message:
|
||||
// 'Selecciona un profesional antes de elegir la fecha y la hora de la cita.',
|
||||
// backgroundColor: Colors.orange);
|
||||
// }
|
||||
// },
|
||||
readOnly: true,
|
||||
decoration: const InputDecoration(
|
||||
prefixIcon: Icon(Icons.watch_later_outlined),
|
||||
hintText: 'Hora',
|
||||
),
|
||||
// controller: TextEditingController(
|
||||
// text: _selectedTime == null
|
||||
// ? ''
|
||||
// : ' ${_selectedTime!.format(context)}',
|
||||
// ),
|
||||
controller: TextEditingController(
|
||||
text: widget.horaSeleccionada == null
|
||||
? ''
|
||||
: ' ${widget.horaSeleccionada!.format(context)}',
|
||||
),
|
||||
))
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
child: TextFormField(
|
||||
onTap: () {
|
||||
if (_profesionalController.text.isNotEmpty) {
|
||||
_selectDateAndTime(context);
|
||||
} else {
|
||||
WarningSnackbar.show(
|
||||
title: 'Selecciona un profesional',
|
||||
message:
|
||||
'Selecciona un profesional antes de elegir la fecha y la hora de la cita.',
|
||||
backgroundColor: Colors.orange);
|
||||
}
|
||||
},
|
||||
readOnly: true,
|
||||
decoration: const InputDecoration(
|
||||
suffixIcon: Icon(Icons.arrow_drop_down),
|
||||
hintText: 'Hora',
|
||||
),
|
||||
controller: TextEditingController(
|
||||
text: _selectedTime == null
|
||||
? ''
|
||||
: ' ${_selectedTime!.format(context)}',
|
||||
),
|
||||
))
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 15),
|
||||
TextFormField(
|
||||
controller: _observacionController,
|
||||
|
||||
@@ -7,8 +7,10 @@ import 'package:intl/intl.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/professional_model.dart';
|
||||
import 'package:prosappco/src/models/setting_model.dart';
|
||||
import 'package:prosappco/src/models/user_model.dart';
|
||||
import 'package:prosappco/src/presentation/screens/calendar_pro.dart';
|
||||
import 'package:prosappco/src/presentation/screens/professional_info.dart';
|
||||
import 'package:prosappco/src/presentation/widgets/shared/loading_item_list.dart';
|
||||
import '../../models/scores_model.dart';
|
||||
@@ -27,101 +29,6 @@ final CollectionReference usersCollection =
|
||||
FirebaseFirestore.instance.collection('users');
|
||||
var _photo = '...';
|
||||
|
||||
class Professional {
|
||||
final String id;
|
||||
final Reference professionalRef;
|
||||
final String name;
|
||||
final String professionName;
|
||||
final String cityName;
|
||||
final String ubicacion;
|
||||
final String realAddress;
|
||||
final double latitude;
|
||||
final double longitude;
|
||||
final List<String> professionalEspecializado;
|
||||
final ScoresModel scores;
|
||||
final int? tarifa;
|
||||
final String? token;
|
||||
|
||||
Professional({
|
||||
required this.id,
|
||||
required this.professionalRef,
|
||||
required this.name,
|
||||
required this.professionName,
|
||||
required this.cityName,
|
||||
required this.ubicacion,
|
||||
required this.professionalEspecializado,
|
||||
required this.scores,
|
||||
required this.realAddress,
|
||||
required this.latitude,
|
||||
required this.longitude,
|
||||
this.tarifa,
|
||||
this.token,
|
||||
});
|
||||
|
||||
String getEspecializaciones() {
|
||||
return professionalEspecializado.join(',\n');
|
||||
}
|
||||
|
||||
@override
|
||||
String toString() {
|
||||
return 'Professional {\n'
|
||||
' professionalRef: $professionalRef,\n'
|
||||
' name: $name,\n'
|
||||
' professionName: $professionName,\n'
|
||||
' cityName: $cityName,\n'
|
||||
' ubicacion: $ubicacion,\n'
|
||||
' realAddress: $realAddress,\n'
|
||||
' latitude: $latitude,\n'
|
||||
' longitude: $longitude,\n'
|
||||
' professionalEspecializado: ${getEspecializaciones()}\n'
|
||||
' tarifa: $tarifa,\n'
|
||||
' token: $token,\n'
|
||||
'}';
|
||||
}
|
||||
|
||||
static Future<Professional?> getProfessional(String uid) async {
|
||||
var photo = '...';
|
||||
final FirebaseStorage storage = FirebaseStorage.instance;
|
||||
|
||||
try {
|
||||
DocumentSnapshot user =
|
||||
await FirebaseFirestore.instance.collection('users').doc(uid).get();
|
||||
|
||||
Map<String, dynamic> data = user.data() as Map<String, dynamic>;
|
||||
|
||||
photo = await AuthenticationRepository.instance.getPhoto(user.id);
|
||||
|
||||
if (data['estado'] == 'activo') {
|
||||
List<String> especializaciones;
|
||||
|
||||
especializaciones = (data['especializaciones'] as List<dynamic>)
|
||||
.map((e) => e.toString())
|
||||
.toList();
|
||||
|
||||
Professional professional = Professional(
|
||||
id: user.id,
|
||||
name: data['name'],
|
||||
professionName: data['profesion'],
|
||||
cityName: data['city'],
|
||||
professionalRef: storage.ref().child(photo),
|
||||
professionalEspecializado: especializaciones,
|
||||
ubicacion: data['ubicacion'] ?? '',
|
||||
realAddress: data['address'] ?? '',
|
||||
latitude: data['latitude'] ?? 0,
|
||||
longitude: data['longitude'] ?? 0,
|
||||
scores: await ScoresModel.scoreFrom(uid, true, true),
|
||||
tarifa: data['tarifas'] ?? 0,
|
||||
token: data['token'] ?? '',
|
||||
);
|
||||
return professional;
|
||||
}
|
||||
} catch (e) {
|
||||
print('Error al obtener profesionales: $e');
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
class _ProfessionalScreenState extends State<ProfessionalScreen> {
|
||||
UserModel? userme;
|
||||
SettingModel? settings;
|
||||
@@ -480,8 +387,16 @@ class _ProfessionalScreenState extends State<ProfessionalScreen> {
|
||||
});
|
||||
} else if (professionals[index].ubicacion ==
|
||||
'sitio') {
|
||||
Navigator.pop(
|
||||
context, [professionals[index], 'sitio']);
|
||||
// Navigator.pop(context, [professionals[index], 'sitio']);
|
||||
|
||||
Navigator.of(context).push(
|
||||
CupertinoPageRoute(
|
||||
builder: (BuildContext context) {
|
||||
return CalendarProScreen(
|
||||
professional: professionals[index]);
|
||||
},
|
||||
),
|
||||
);
|
||||
} else {
|
||||
Navigator.pop(
|
||||
context, [professionals[index], 'domicilio']);
|
||||
|
||||
@@ -5,8 +5,8 @@ import 'package:flutter_rating_bar/flutter_rating_bar.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:prosappco/src/components/photo_view.dart';
|
||||
import 'package:prosappco/src/components/pop_appbar.dart';
|
||||
import 'package:prosappco/src/models/professional_model.dart';
|
||||
import 'package:prosappco/src/models/setting_model.dart';
|
||||
import 'package:prosappco/src/presentation/screens/professional.dart';
|
||||
import 'package:prosappco/src/presentation/screens/reputation.dart';
|
||||
|
||||
import '../../models/scores_model.dart';
|
||||
|
||||
@@ -65,7 +65,7 @@ class _ProfileProScreenState extends State<ProfileProScreen> {
|
||||
super.initState();
|
||||
if (settings == null) {
|
||||
SettingModel.getSettings().then((SettingModel value) => setState(
|
||||
() => {print('Settings: $value'), settings = value},
|
||||
() => settings = value,
|
||||
));
|
||||
}
|
||||
|
||||
@@ -149,7 +149,7 @@ class _ProfileProScreenState extends State<ProfileProScreen> {
|
||||
void createSchedules() async {
|
||||
if (_horarios == null || _horarios!.isEmpty) {
|
||||
final defaultSchedule = {
|
||||
'Lunes': {
|
||||
'1': {
|
||||
'habilitado': false,
|
||||
'jornadaContinua': false,
|
||||
'range1Hour1': null,
|
||||
@@ -157,7 +157,7 @@ class _ProfileProScreenState extends State<ProfileProScreen> {
|
||||
'range2Hour1': null,
|
||||
'range2Hour2': null
|
||||
},
|
||||
'Martes': {
|
||||
'2': {
|
||||
'habilitado': false,
|
||||
'jornadaContinua': false,
|
||||
'range1Hour1': null,
|
||||
@@ -165,7 +165,7 @@ class _ProfileProScreenState extends State<ProfileProScreen> {
|
||||
'range2Hour1': null,
|
||||
'range2Hour2': null
|
||||
},
|
||||
'Miercoles': {
|
||||
'3': {
|
||||
'habilitado': false,
|
||||
'jornadaContinua': false,
|
||||
'range1Hour1': null,
|
||||
@@ -173,7 +173,7 @@ class _ProfileProScreenState extends State<ProfileProScreen> {
|
||||
'range2Hour1': null,
|
||||
'range2Hour2': null
|
||||
},
|
||||
'Jueves': {
|
||||
'4': {
|
||||
'habilitado': false,
|
||||
'jornadaContinua': false,
|
||||
'range1Hour1': null,
|
||||
@@ -181,7 +181,7 @@ class _ProfileProScreenState extends State<ProfileProScreen> {
|
||||
'range2Hour1': null,
|
||||
'range2Hour2': null
|
||||
},
|
||||
'Viernes': {
|
||||
'5': {
|
||||
'habilitado': false,
|
||||
'jornadaContinua': false,
|
||||
'range1Hour1': null,
|
||||
@@ -189,7 +189,7 @@ class _ProfileProScreenState extends State<ProfileProScreen> {
|
||||
'range2Hour1': null,
|
||||
'range2Hour2': null
|
||||
},
|
||||
'Sabado': {
|
||||
'6': {
|
||||
'habilitado': false,
|
||||
'jornadaContinua': false,
|
||||
'range1Hour1': null,
|
||||
@@ -197,7 +197,7 @@ class _ProfileProScreenState extends State<ProfileProScreen> {
|
||||
'range2Hour1': null,
|
||||
'range2Hour2': null
|
||||
},
|
||||
'Domingo': {
|
||||
'7': {
|
||||
'habilitado': false,
|
||||
'jornadaContinua': false,
|
||||
'range1Hour1': null,
|
||||
@@ -642,7 +642,7 @@ class _ProfileProScreenState extends State<ProfileProScreen> {
|
||||
TableCell(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(timeList(_horarios?['Lunes'], context)),
|
||||
child: Text(timeList(_horarios?['1'], context)),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -658,8 +658,7 @@ class _ProfileProScreenState extends State<ProfileProScreen> {
|
||||
TableCell(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child:
|
||||
Text(timeList(_horarios?['Martes'], context)),
|
||||
child: Text(timeList(_horarios?['2'], context)),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -675,8 +674,7 @@ class _ProfileProScreenState extends State<ProfileProScreen> {
|
||||
TableCell(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
timeList(_horarios?['Miercoles'], context)),
|
||||
child: Text(timeList(_horarios?['3'], context)),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -692,8 +690,7 @@ class _ProfileProScreenState extends State<ProfileProScreen> {
|
||||
TableCell(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child:
|
||||
Text(timeList(_horarios?['Jueves'], context)),
|
||||
child: Text(timeList(_horarios?['4'], context)),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -709,8 +706,7 @@ class _ProfileProScreenState extends State<ProfileProScreen> {
|
||||
TableCell(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child:
|
||||
Text(timeList(_horarios?['Viernes'], context)),
|
||||
child: Text(timeList(_horarios?['5'], context)),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -726,8 +722,7 @@ class _ProfileProScreenState extends State<ProfileProScreen> {
|
||||
TableCell(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child:
|
||||
Text(timeList(_horarios?['Sabado'], context)),
|
||||
child: Text(timeList(_horarios?['6'], context)),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -743,8 +738,7 @@ class _ProfileProScreenState extends State<ProfileProScreen> {
|
||||
TableCell(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child:
|
||||
Text(timeList(_horarios?['Domingo'], context)),
|
||||
child: Text(timeList(_horarios?['7'], context)),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -251,7 +251,7 @@ class _ProfileProWebScreenState extends State<ProfileProWebScreen> {
|
||||
void createSchedules() async {
|
||||
if (_horarios == null || _horarios!.isEmpty) {
|
||||
final defaultSchedule = {
|
||||
'Lunes': {
|
||||
'1': {
|
||||
'habilitado': false,
|
||||
'jornadaContinua': false,
|
||||
'range1Hour1': null,
|
||||
@@ -259,7 +259,7 @@ class _ProfileProWebScreenState extends State<ProfileProWebScreen> {
|
||||
'range2Hour1': null,
|
||||
'range2Hour2': null
|
||||
},
|
||||
'Martes': {
|
||||
'2': {
|
||||
'habilitado': false,
|
||||
'jornadaContinua': false,
|
||||
'range1Hour1': null,
|
||||
@@ -267,7 +267,7 @@ class _ProfileProWebScreenState extends State<ProfileProWebScreen> {
|
||||
'range2Hour1': null,
|
||||
'range2Hour2': null
|
||||
},
|
||||
'Miercoles': {
|
||||
'3': {
|
||||
'habilitado': false,
|
||||
'jornadaContinua': false,
|
||||
'range1Hour1': null,
|
||||
@@ -275,7 +275,7 @@ class _ProfileProWebScreenState extends State<ProfileProWebScreen> {
|
||||
'range2Hour1': null,
|
||||
'range2Hour2': null
|
||||
},
|
||||
'Jueves': {
|
||||
'4': {
|
||||
'habilitado': false,
|
||||
'jornadaContinua': false,
|
||||
'range1Hour1': null,
|
||||
@@ -283,7 +283,7 @@ class _ProfileProWebScreenState extends State<ProfileProWebScreen> {
|
||||
'range2Hour1': null,
|
||||
'range2Hour2': null
|
||||
},
|
||||
'Viernes': {
|
||||
'5': {
|
||||
'habilitado': false,
|
||||
'jornadaContinua': false,
|
||||
'range1Hour1': null,
|
||||
@@ -291,7 +291,7 @@ class _ProfileProWebScreenState extends State<ProfileProWebScreen> {
|
||||
'range2Hour1': null,
|
||||
'range2Hour2': null
|
||||
},
|
||||
'Sabado': {
|
||||
'6': {
|
||||
'habilitado': false,
|
||||
'jornadaContinua': false,
|
||||
'range1Hour1': null,
|
||||
@@ -299,7 +299,7 @@ class _ProfileProWebScreenState extends State<ProfileProWebScreen> {
|
||||
'range2Hour1': null,
|
||||
'range2Hour2': null
|
||||
},
|
||||
'Domingo': {
|
||||
'7': {
|
||||
'habilitado': false,
|
||||
'jornadaContinua': false,
|
||||
'range1Hour1': null,
|
||||
@@ -513,7 +513,7 @@ class _ProfileProWebScreenState extends State<ProfileProWebScreen> {
|
||||
TableCell(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(timeList(_horarios?['Lunes'], context)),
|
||||
child: Text(timeList(_horarios?['1'], context)),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -529,8 +529,7 @@ class _ProfileProWebScreenState extends State<ProfileProWebScreen> {
|
||||
TableCell(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child:
|
||||
Text(timeList(_horarios?['Martes'], context)),
|
||||
child: Text(timeList(_horarios?['2'], context)),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -546,8 +545,7 @@ class _ProfileProWebScreenState extends State<ProfileProWebScreen> {
|
||||
TableCell(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: Text(
|
||||
timeList(_horarios?['Miercoles'], context)),
|
||||
child: Text(timeList(_horarios?['3'], context)),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -563,8 +561,7 @@ class _ProfileProWebScreenState extends State<ProfileProWebScreen> {
|
||||
TableCell(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child:
|
||||
Text(timeList(_horarios?['Jueves'], context)),
|
||||
child: Text(timeList(_horarios?['4'], context)),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -580,8 +577,7 @@ class _ProfileProWebScreenState extends State<ProfileProWebScreen> {
|
||||
TableCell(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child:
|
||||
Text(timeList(_horarios?['Viernes'], context)),
|
||||
child: Text(timeList(_horarios?['5'], context)),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -597,8 +593,7 @@ class _ProfileProWebScreenState extends State<ProfileProWebScreen> {
|
||||
TableCell(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child:
|
||||
Text(timeList(_horarios?['Sabado'], context)),
|
||||
child: Text(timeList(_horarios?['6'], context)),
|
||||
),
|
||||
),
|
||||
],
|
||||
@@ -614,8 +609,7 @@ class _ProfileProWebScreenState extends State<ProfileProWebScreen> {
|
||||
TableCell(
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child:
|
||||
Text(timeList(_horarios?['Domingo'], context)),
|
||||
child: Text(timeList(_horarios?['7'], context)),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@@ -8,6 +8,7 @@ import 'package:geocoding/geocoding.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
||||
import 'package:prosappco/src/models/professional_model.dart';
|
||||
import 'package:prosappco/src/presentation/screens/profile/profile.dart';
|
||||
import 'package:prosappco/src/presentation/widgets/shared/drawer_menu.dart';
|
||||
import 'package:prosappco/src/models/event_model.dart';
|
||||
|
||||
@@ -38,7 +38,7 @@ class _WebViewScreenState extends State<WebViewScreen> {
|
||||
},
|
||||
onWebResourceError: (WebResourceError error) {},
|
||||
onNavigationRequest: (NavigationRequest request) {
|
||||
if (request.url.startsWith('https://www.youtube.com/')) {
|
||||
if (request.url.startsWith('https://www.google.com/')) {
|
||||
return NavigationDecision.prevent;
|
||||
}
|
||||
return NavigationDecision.navigate;
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:prosappco/src/utils/time_of_day_extension.dart';
|
||||
|
||||
class TimeOfDayUtils {
|
||||
static List<TimeOfDay> genRanges(TimeOfDay timeStart, TimeOfDay timeEnd) {
|
||||
List<TimeOfDay> ranges = [];
|
||||
TimeOfDay current = timeStart;
|
||||
while (current.isBefore(timeEnd)) {
|
||||
ranges.add(current);
|
||||
// Sumar 2 horas al objeto DateTime
|
||||
current = current.add(hour: 2);
|
||||
}
|
||||
return ranges;
|
||||
}
|
||||
}
|
||||
+13
-21
@@ -117,10 +117,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: collection
|
||||
sha256: f092b211a4319e98e5ff58223576de6c2803db36221657b46c82574721240687
|
||||
sha256: "4a07be6cb69c84d677a6c3096fcf960cc3285a8330b4603e0d463d15d9bd934c"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.17.2"
|
||||
version: "1.17.1"
|
||||
community_material_icon:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -745,10 +745,10 @@ packages:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
name: intl
|
||||
sha256: "3bc132a9dbce73a7e4a21a17d06e1878839ffbf975568bc875c60537824b0c4d"
|
||||
sha256: a3715e3bc90294e971cb7dc063fbf3cd9ee0ebf8604ffeafabd9e6f16abbdbe6
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.18.1"
|
||||
version: "0.18.0"
|
||||
intl_phone_field:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -809,18 +809,18 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
sha256: "1803e76e6653768d64ed8ff2e1e67bea3ad4b923eb5c56a295c3e634bad5960e"
|
||||
sha256: "6501fbd55da300384b768785b83e5ce66991266cec21af89ab9ae7f5ce1c4cbb"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.16"
|
||||
version: "0.12.15"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
sha256: "9528f2f296073ff54cb9fee677df673ace1218163c3bc7628093e7eed5203d41"
|
||||
sha256: d92141dc6fe1dad30722f9aa826c7fbc896d021d792f80678280601aff8cf724
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.5.0"
|
||||
version: "0.2.0"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1062,10 +1062,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: source_span
|
||||
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
|
||||
sha256: dd904f795d4b4f3b870833847c461801f6750a9fa8e61ea5ac53f9422b31f250
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.10.0"
|
||||
version: "1.9.1"
|
||||
stack_trace:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1118,10 +1118,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: "75760ffd7786fffdfb9597c35c5b27eaeec82be8edfb6d71d32651128ed7aab8"
|
||||
sha256: eb6ac1540b26de412b3403a163d919ba86f6a973fe6cc50ae3541b80092fdcfb
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.6.0"
|
||||
version: "0.5.1"
|
||||
timezone:
|
||||
dependency: transitive
|
||||
description:
|
||||
@@ -1242,14 +1242,6 @@ packages:
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.1.0"
|
||||
web:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: web
|
||||
sha256: dc8ccd225a2005c1be616fe02951e2e342092edf968cf0844220383757ef8f10
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.1.4-beta"
|
||||
webview_flutter:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@@ -1315,5 +1307,5 @@ packages:
|
||||
source: hosted
|
||||
version: "3.1.2"
|
||||
sdks:
|
||||
dart: ">=3.1.0-185.0.dev <4.0.0"
|
||||
dart: ">=3.0.0 <4.0.0"
|
||||
flutter: ">=3.10.0"
|
||||
|
||||
Reference in New Issue
Block a user