This commit is contained in:
Felipe
2024-01-05 15:57:46 -05:00
parent d9a62ce404
commit 278fdfd9e1
16 changed files with 647 additions and 251 deletions
+1 -4
View File
@@ -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 {
+7 -7
View File
@@ -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),
};
}
}
+99
View File
@@ -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();
}
}
+1 -1
View File
@@ -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;
+103 -20
View File
@@ -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,
);
},
+81 -58
View File
@@ -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,
+12 -97
View File
@@ -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';
+1 -1
View File
@@ -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;
+19
View File
@@ -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;
}
}
+15
View File
@@ -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
View File
@@ -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"