This commit is contained in:
Felipe
2023-11-10 15:34:13 -05:00
parent b3d1740649
commit f732d461d0
14 changed files with 613 additions and 235 deletions
@@ -187,6 +187,34 @@ class AuthenticationRepository extends GetxController {
return city;
}
Future<String> getGender(String uid) async {
String gender = '';
try {
final snapshot =
await FirebaseFirestore.instance.collection('users').doc(uid).get();
final Map<String, dynamic>? data = snapshot.data();
gender = data?['gender'] ?? '';
} catch (e) {
print('Error getting gender: $e');
}
return gender;
}
Future<String> getBirthday(String uid) async {
String birthDate = '';
try {
final snapshot =
await FirebaseFirestore.instance.collection('users').doc(uid).get();
final Map<String, dynamic>? data = snapshot.data();
birthDate = data?['birth_date'] ?? '';
print('nada $birthDate');
} catch (e) {
print('Error getting birthDate: $e');
}
return birthDate;
}
Future<String> getCoordsOfCity(String uid) async {
String coords = '';
try {
+13 -9
View File
@@ -30,9 +30,11 @@ class _LoginScreenState extends State<LoginScreen> {
SettingModel? settings;
void _clearPhoneNumber() {
setState(() {
controller.phoneNo.text = '';
});
if (mounted) {
setState(() {
controller.phoneNo.text = '';
});
}
}
void _launchURL(String url) async {
@@ -47,11 +49,13 @@ class _LoginScreenState extends State<LoginScreen> {
void initState() {
super.initState();
if (settings == null) {
SettingModel.getSettings().then(
(SettingModel value) => setState(() {
settings = value;
}),
);
SettingModel.getSettings().then((SettingModel value) {
if (mounted) {
setState(() {
settings = value;
});
}
});
}
}
@@ -182,12 +186,12 @@ class _LoginScreenState extends State<LoginScreen> {
PhoneAuthController.instance.phoneAuthentication(
completePhoneNumber.trim(),
);
_clearPhoneNumber();
await Get.to(
() => CodeValidationScreen(
phoneNumber: completePhoneNumber.trim(),
),
);
_clearPhoneNumber();
Provider.of<UserProvider>(context, listen: false)
.initUserProvider();
}
+38 -9
View File
@@ -9,6 +9,7 @@ import 'package:prosappco/src/components/pop_appbar.dart';
import 'package:prosappco/src/models/event_model.dart';
import 'package:prosappco/src/models/scores_model.dart';
import 'package:prosappco/src/presentation/screens/cita.dart';
import 'package:prosappco/src/presentation/screens/score.dart';
class MyServicesScreen extends StatelessWidget {
MyServicesScreen({super.key});
@@ -54,6 +55,7 @@ class MyServicesScreen extends StatelessWidget {
.asyncMap((snapshot) async {
try {
List<Event> eventos = [];
for (var element in snapshot.docs) {
final event = Event.fromJson(element.data());
event.scoresModel =
@@ -79,8 +81,10 @@ class MyServicesScreen extends StatelessWidget {
try {
eventos.addAll(snapshot.data!);
eventos.sort((a, b) => a.timeStamp!.compareTo(b.timeStamp!));
print('snapshot mi b ${eventos}');
} catch (e) {
print("Error" + e.toString());
print("Error snapshot" + e.toString());
}
if (eventos.isEmpty) {
@@ -122,14 +126,39 @@ class MyServicesScreen extends StatelessWidget {
? Colors.red[100]
: Colors.blue[100],
onTap: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (BuildContext context) {
return CitaScreen(evento: event);
},
),
);
if (event.status == 'terminado') {
if (event.userId == uid) {
if (event.userScored) {
Navigator.push(
context,
CupertinoPageRoute(
builder: (BuildContext context) {
return CitaScreen(evento: event);
},
),
);
} else {
Navigator.push(
context,
CupertinoPageRoute(
builder: (BuildContext context) {
return ScoreScreen(
evento: event, pro: false);
},
),
);
}
}
} else {
Navigator.push(
context,
CupertinoPageRoute(
builder: (BuildContext context) {
return CitaScreen(evento: event);
},
),
);
}
},
leading: event.status == 'aprobado'
? const Column(
@@ -9,6 +9,7 @@ import 'package:prosappco/src/components/pop_appbar.dart';
import 'package:prosappco/src/models/event_model.dart';
import 'package:prosappco/src/models/scores_model.dart';
import 'package:prosappco/src/presentation/screens/cita.dart';
import 'package:prosappco/src/presentation/screens/score.dart';
class MyServicesProScreen extends StatelessWidget {
MyServicesProScreen({super.key});
@@ -98,14 +99,38 @@ class MyServicesProScreen extends StatelessWidget {
? Colors.red[100]
: Colors.blue[100],
onTap: () {
Navigator.push(
context,
CupertinoPageRoute(
builder: (BuildContext context) {
return CitaScreen(evento: event);
},
),
);
if (event.status == 'terminado') {
if (event.professionalId == uid) {
if (event.professionalScored) {
Navigator.push(
context,
CupertinoPageRoute(
builder: (BuildContext context) {
return CitaScreen(evento: event);
},
),
);
} else {
Navigator.push(
context,
CupertinoPageRoute(
builder: (BuildContext context) {
return ScoreScreen(evento: event, pro: true);
},
),
);
}
}
} else {
Navigator.push(
context,
CupertinoPageRoute(
builder: (BuildContext context) {
return CitaScreen(evento: event);
},
),
);
}
},
leading: event.status == 'aprobado'
? const Column(
@@ -4,7 +4,6 @@ import 'package:firebase_auth/firebase_auth.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/presentation/screens/support.dart';
final CollectionReference professionsCollection =
FirebaseFirestore.instance.collection('professions');
@@ -1,3 +1,4 @@
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
@@ -38,6 +39,33 @@ class _ProfessionalInfoScreenState extends State<ProfessionalInfoScreen> {
}),
);
}
loadPaymentMethods();
}
Map<String, bool> paymentMethods = {};
String _formatPaymentMethods(Map<String, bool> paymentMethods) {
List<String> enabledMethods = paymentMethods.entries
.where((entry) => entry.value)
.map((entry) => entry.key)
.toList();
return enabledMethods.join(', ');
}
void loadPaymentMethods() {
FirebaseFirestore.instance
.collection('users')
.doc(widget.professional.id)
.get()
.then((doc) {
if (doc.exists) {
setState(() {
paymentMethods = Map<String, bool>.from(doc['paymentMethods'] ?? {});
});
}
});
}
@override
@@ -156,7 +184,38 @@ class _ProfessionalInfoScreenState extends State<ProfessionalInfoScreen> {
),
)
: const SizedBox(),
const SizedBox(height: 10),
const SizedBox(height: 5),
paymentMethods.containsValue(true)
? Container(
width: MediaQuery.of(context).size.width * 0.8,
padding: const EdgeInsets.symmetric(
horizontal: 16, vertical: 8),
decoration: BoxDecoration(
color: Colors.blue.withOpacity(0.1),
borderRadius: BorderRadius.circular(10),
),
child: RichText(
text: TextSpan(
style: const TextStyle(
fontSize: 12,
color: Colors.blue,
),
children: [
const TextSpan(
text: 'Métodos de pago recibidos: ',
style:
TextStyle(fontWeight: FontWeight.normal),
),
TextSpan(
text: _formatPaymentMethods(paymentMethods),
style: const TextStyle(
fontWeight: FontWeight.bold),
),
],
),
))
: const SizedBox(),
const SizedBox(height: 5),
const Text(
'Se unió el 02 de abril del 2023',
style: TextStyle(fontSize: 12),
@@ -1,6 +1,5 @@
import 'dart:io';
import 'package:cloud_firestore/cloud_firestore.dart';
import 'package:firebase_auth/firebase_auth.dart';
import 'package:firebase_storage/firebase_storage.dart';
import 'package:flutter/material.dart';
import 'package:get/get.dart';
@@ -25,7 +24,6 @@ class ProfessionalProfileScreenState extends State<ProfessionalProfileScreen> {
File? image_cedula;
File? image_certificado;
late final FirebaseAuth _auth;
final FirebaseStorage storage = FirebaseStorage.instance;
final uid = AuthenticationRepository.instance.getCurrentUserUid();
@@ -44,7 +42,6 @@ class ProfessionalProfileScreenState extends State<ProfessionalProfileScreen> {
@override
void initState() {
super.initState();
_auth = FirebaseAuth.instance;
if (_photo == '...') {
AuthenticationRepository.instance
.getPhoto(uid.toString())
@@ -43,13 +43,14 @@ class _ProfileScreenState extends State<ProfileScreen> {
var _photo = '...';
String? _email = '';
String gender = '';
String genderDb = '';
DateTime? birthDate;
String birthDateDb = '';
@override
void initState() {
super.initState();
final uid = AuthenticationRepository.instance.getCurrentUserUid();
_auth = FirebaseAuth.instance;
final currentUser = _auth.currentUser;
@@ -65,22 +66,40 @@ class _ProfileScreenState extends State<ProfileScreen> {
_emailController.text = currentUser.email!;
}
if (gender.isEmpty) {
AuthenticationRepository.instance.getGender(uid.toString()).then(
(String s) => setState(() {
genderDb = s;
}),
);
}
if (birthDate == null) {
AuthenticationRepository.instance.getBirthday(uid.toString()).then(
(String s) => setState(() {
if (s.isNotEmpty) {
birthDateDb = s;
}
}),
);
}
_email = currentUser?.email;
if (_ciudad == '...') {
AuthenticationRepository.instance
.getCity(uid.toString())
.then((String s) => setState(() {
_ciudad = s;
}));
AuthenticationRepository.instance.getCity(uid.toString()).then(
(String s) => setState(() {
_ciudad = s;
}),
);
}
if (_photo == '...') {
AuthenticationRepository.instance
.getPhoto(uid.toString())
.then((String s) => setState(() {
_photo = s;
}));
AuthenticationRepository.instance.getPhoto(uid.toString()).then(
(String s) => setState(() {
_photo = s;
}),
);
}
}
@@ -221,6 +240,32 @@ class _ProfileScreenState extends State<ProfileScreen> {
String newEmail = _emailController.text.trim();
String newPassword = _passwordController.text.trim();
if (gender.isNotEmpty) {
try {
await FirebaseFirestore.instance.collection('users').doc(uid).set({
'gender': gender,
}, SetOptions(merge: true));
genderDb = gender;
} catch (e) {
print('Error al actualizar el genero: $e');
}
}
if (birthDate != null) {
try {
await FirebaseFirestore.instance.collection('users').doc(uid).set({
'birth_date': birthDate.toString(),
}, SetOptions(merge: true));
birthDateDb = birthDate.toString();
} catch (e) {
print('Error al actualizar la fecha de nacimiento: $e');
}
}
setState(() {});
if (newName.isEmpty) {
Get.snackbar(
'Nombre Invalido',
@@ -281,7 +326,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
.doc(uid)
.update({'email': newEmail});
} catch (e) {
print('e');
print('Error al actualizar la imagen de perfil $e');
}
try {
@@ -296,7 +341,11 @@ class _ProfileScreenState extends State<ProfileScreen> {
print('Error al actualizar la imagen de perfil $e');
}
// notifyListeners();
Get.snackbar(
'Informacion actualizada',
'Tu informacion ha sido actualizada con exito.',
snackPosition: SnackPosition.BOTTOM,
);
}
Future<void> _updateEmailAndPassword(
@@ -435,7 +484,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
'Inicia sesión para asegurarnos de que seas tú.',
snackPosition: SnackPosition.BOTTOM,
);
AuthenticationRepository.instance.logout(uid!);
// AuthenticationRepository.instance.logout(uid!);
}
}
}
@@ -644,26 +693,32 @@ class _ProfileScreenState extends State<ProfileScreen> {
),
),
const SizedBox(height: 20.0),
GenderDropdown(
onChanged: (selectedGender) {
setState(() {
gender = selectedGender;
});
},
),
const SizedBox(height: 20.0),
BirthDatePicker(
onDateSelected: (birthDay) {
setState(() {
birthDate = birthDay;
});
},
controller: TextEditingController(
text: birthDate == null
? ''
: formatter.format(birthDate!),
),
),
genderDb == ''
? GenderDropdown(
onChanged: (selectedGender) {
setState(() {
gender = selectedGender;
});
},
)
: const SizedBox(),
genderDb == ''
? const SizedBox(height: 20.0)
: const SizedBox(),
birthDateDb == ''
? BirthDatePicker(
onDateSelected: (birthDay) {
setState(() {
birthDate = birthDay;
});
},
controller: TextEditingController(
text: birthDate == null
? ''
: formatter.format(birthDate!),
),
)
: const SizedBox(),
],
),
),
@@ -9,12 +9,13 @@ import 'package:get/get.dart';
import 'package:prosappco/src/authentication/authentication_repository.dart';
import 'package:prosappco/src/components/banner_photo.dart';
import 'package:prosappco/src/components/pop_appbar.dart';
import 'package:prosappco/src/components/primary_btn.dart';
import 'package:prosappco/src/components/schedule_picker.dart';
import 'package:prosappco/src/models/setting_model.dart';
import 'package:prosappco/src/presentation/screens/horario.dart';
import 'package:prosappco/src/presentation/screens/professional.dart';
import 'package:prosappco/src/presentation/screens/professional_direccion.dart';
import 'package:prosappco/src/presentation/widgets/shared/primary_button.dart';
import 'package:prosappco/src/presentation/widgets/shared/primary_checkbox.dart';
import 'package:prosappco/src/services/select_image_profile.dart';
class ProfileProScreen extends StatefulWidget {
@@ -47,8 +48,18 @@ class _ProfileProScreenState extends State<ProfileProScreen> {
int _tarifa = 0;
SettingModel? settings;
bool nequiValue = false;
bool banktransferValue = false;
bool datafoneValue = false;
Map<String, Schedule>? _horarios;
Map<String, bool> paymentMethods = {
'Nequi': false,
'Transferencia Bancaria': false,
'Datafono': false,
};
@override
void initState() {
super.initState();
@@ -131,6 +142,8 @@ class _ProfileProScreenState extends State<ProfileProScreen> {
),
);
}
loadPaymentMethods();
}
void createSchedules() async {
@@ -276,6 +289,8 @@ class _ProfileProScreenState extends State<ProfileProScreen> {
print('Error al actualizar la imagen de perfil $e');
}
updatePaymentMethods();
Get.snackbar(
'Información actualizada',
'Tu información ha sido actualizada con éxito.',
@@ -405,6 +420,22 @@ class _ProfileProScreenState extends State<ProfileProScreen> {
});
}
void updatePaymentMethods() {
FirebaseFirestore.instance.collection('users').doc(uid).update({
'paymentMethods': paymentMethods,
});
}
void loadPaymentMethods() {
FirebaseFirestore.instance.collection('users').doc(uid).get().then((doc) {
if (doc.exists) {
setState(() {
paymentMethods = Map<String, bool>.from(doc['paymentMethods'] ?? {});
});
}
});
}
@override
Widget build(BuildContext context) {
String address = _direccion.toString();
@@ -522,6 +553,33 @@ class _ProfileProScreenState extends State<ProfileProScreen> {
)
: const SizedBox(),
const Divider(),
Padding(
padding: const EdgeInsets.only(left: 30, right: 30, bottom: 30),
child: SizedBox(
width: double.infinity,
child: Column(
children: [
const Text(
'Metodos de pago',
style: TextStyle(
color: Colors.black,
fontSize: 17,
),
),
for (var entry in paymentMethods.entries)
PrimaryCheckbox(
text: entry.key,
initialValue: entry.value,
onChanged: (value) {
setState(() {
paymentMethods[entry.key] = value;
});
},
),
],
),
),
),
const Padding(
padding: EdgeInsets.symmetric(horizontal: 30),
child: SizedBox(
@@ -530,7 +588,7 @@ class _ProfileProScreenState extends State<ProfileProScreen> {
'Horario estandar',
style: TextStyle(
color: Colors.black,
fontSize: 15,
fontSize: 17,
),
),
),
@@ -666,15 +724,14 @@ class _ProfileProScreenState extends State<ProfileProScreen> {
),
),
),
PrimaryButtom(
onPressed: () {
updateInfo();
// name();
},
label: 'Guardar'),
const SizedBox(
height: 20,
)
const SizedBox(height: 10),
PrimaryButton(
onPressed: () {
updateInfo();
},
text: 'Guardar',
),
const SizedBox(height: 20),
],
),
),
+185 -141
View File
@@ -26,6 +26,8 @@ import 'package:prosappco/src/presentation/screens/ubicacion.dart';
import 'package:http/http.dart' as http;
import 'package:prosappco/src/components/network_utility.dart';
import 'package:package_info_plus/package_info_plus.dart';
import 'package:prosappco/src/presentation/widgets/shared/primary_button.dart';
import 'package:prosappco/src/presentation/widgets/shared/warning_snackbar.dart';
import 'package:url_launcher/url_launcher.dart';
class ServiceScreen extends StatefulWidget {
@@ -178,9 +180,11 @@ class _ServiceScreenState extends State<ServiceScreen> {
);
if (picked != null && picked != _selectedDate) {
setState(() {
_selectedDate = picked;
});
if (mounted) {
setState(() {
_selectedDate = picked;
});
}
}
}
@@ -191,9 +195,11 @@ class _ServiceScreenState extends State<ServiceScreen> {
);
if (pickedTime != null) {
setState(() {
_selectedTime = pickedTime;
});
if (mounted) {
setState(() {
_selectedTime = pickedTime;
});
}
}
}
@@ -252,13 +258,25 @@ class _ServiceScreenState extends State<ServiceScreen> {
),
),
);
setState(() {});
if (mounted) {
setState(() {});
}
} catch (e) {
print('Error: $e');
}
}
@override
void dispose() {
_locationController.dispose();
_ubicationController.dispose();
_profesionalController.dispose();
_serviceTypeController.dispose();
_observacionController.dispose();
super.dispose();
}
void updateMarkersForServiceType(String serviceType) {
getUsersWithActiveStatus(serviceType).then((value) {
markers.clear();
@@ -287,9 +305,11 @@ class _ServiceScreenState extends State<ServiceScreen> {
PackageInfo packageInfo = await PackageInfo.fromPlatform();
String version = packageInfo.version;
setState(() {
appVersion = version;
});
if (mounted) {
setState(() {
appVersion = version;
});
}
if (settings != null) {
_checkForUpdate(settings);
@@ -348,12 +368,14 @@ class _ServiceScreenState extends State<ServiceScreen> {
}
if (settings == null) {
SettingModel.getSettings().then(
(SettingModel value) => setState(() {
settings = value.version;
_getAppVersion();
}),
);
SettingModel.getSettings().then((SettingModel value) => (value) {
if (mounted) {
setState(() {
settings = value.version;
_getAppVersion();
});
}
});
}
if (_ciudad == '...') {
@@ -364,14 +386,18 @@ class _ServiceScreenState extends State<ServiceScreen> {
FirebaseFirestore.instance.collection('users').doc(uid).set({
'city': 'Cúcuta',
}).then((_) {
setState(() {
_ciudad = 'Cúcuta';
});
if (mounted) {
setState(() {
_ciudad = 'Cúcuta';
});
}
});
} else {
setState(() {
_ciudad = s;
});
if (mounted) {
setState(() {
_ciudad = s;
});
}
}
});
}
@@ -380,27 +406,33 @@ class _ServiceScreenState extends State<ServiceScreen> {
AuthenticationRepository.instance
.getCoordsOfCity(uid.toString())
.then((String s) {
setState(() {
_coordsOfCity = s;
_setInitialCameraPosition(_coordsOfCity);
});
if (mounted) {
setState(() {
_coordsOfCity = s;
_setInitialCameraPosition(_coordsOfCity);
});
}
});
}
_saveToken();
if (user == null) {
UserModel.getUser(uid.toString()).then(
(UserModel s) => setState(() => user = s),
);
UserModel.getUser(uid.toString()).then((UserModel s) => (value) {
if (mounted) {
setState(() => user = s);
}
});
}
BitmapDescriptor.fromAssetImage(
const ImageConfiguration(size: Size(6, 6)), 'images/pro_marke.png')
.then((icon) {
setState(() {
_markerIcon = icon;
});
if (mounted) {
setState(() {
_markerIcon = icon;
});
}
});
updateMarkersForServiceType(_serviceType);
@@ -456,9 +488,11 @@ class _ServiceScreenState extends State<ServiceScreen> {
String? response = await NetworkUtility.fetchUrl(uri);
if (response != null) {
setState(() {
_placesList = jsonDecode(response.toString())['results'];
});
if (mounted) {
setState(() {
_placesList = jsonDecode(response.toString())['results'];
});
}
}
}
@@ -511,26 +545,28 @@ class _ServiceScreenState extends State<ServiceScreen> {
ubicacion = datos[1];
if (profesional != null) {
setState(() {
_profesionalController.text =
profesional.name.toString();
professionalId = profesional.id;
professionalTarifa = profesional.tarifa ?? 0;
professionalUbicacion = profesional.ubicacion;
professionalAddress = _ubicationController.text;
if (profesional.token != '') {
professionalToken = profesional.token!;
print(professionalToken);
}
if (mounted) {
setState(() {
_profesionalController.text =
profesional.name.toString();
professionalId = profesional.id;
professionalTarifa = profesional.tarifa ?? 0;
professionalUbicacion = profesional.ubicacion;
professionalAddress = _ubicationController.text;
if (profesional.token != '') {
professionalToken = profesional.token!;
print(professionalToken);
}
if (ubicacion == 'sitio') {
professionalAddress = profesional.realAddress;
_ubicationController.text =
profesional.realAddress;
latUser = profesional.latitude;
lngUser = profesional.longitude;
}
});
if (ubicacion == 'sitio') {
professionalAddress = profesional.realAddress;
_ubicationController.text =
profesional.realAddress;
latUser = profesional.latitude;
lngUser = profesional.longitude;
}
});
}
}
}
},
@@ -558,11 +594,13 @@ class _ServiceScreenState extends State<ServiceScreen> {
final lat = datos[1];
final lng = datos[2];
setState(() {
_ubicationController.text = formattedAddress;
latUser = lat;
lngUser = lng;
});
if (mounted) {
setState(() {
_ubicationController.text = formattedAddress;
latUser = lat;
lngUser = lng;
});
}
}
},
decoration: const InputDecoration(
@@ -826,17 +864,21 @@ class _ServiceScreenState extends State<ServiceScreen> {
getLocationName(
coordinates.latitude, coordinates.longitude)
.then((locationName) {
setState(() {
_locationController.text = locationName;
});
if (mounted) {
setState(() {
_locationController.text = locationName;
});
}
});
}
}
},
onCameraMove: (position) {
setState(() {
coordinates = position.target;
});
if (mounted) {
setState(() {
coordinates = position.target;
});
}
},
gestureRecognizers: <Factory<OneSequenceGestureRecognizer>>{
Factory<OneSequenceGestureRecognizer>(
@@ -874,7 +916,9 @@ class _ServiceScreenState extends State<ServiceScreen> {
zoom: 17),
),
);
setState(() {});
if (mounted) {
setState(() {});
}
} catch (e) {
Get.snackbar(
'ubicación desactivada',
@@ -945,13 +989,16 @@ class _ServiceScreenState extends State<ServiceScreen> {
) as String?;
if (serviceType != null) {
setState(() {
_serviceType = serviceType;
_serviceTypeController.text =
_serviceType;
if (mounted) {
setState(() {
_serviceType = serviceType;
_serviceTypeController.text =
_serviceType;
updateMarkersForServiceType(_serviceType);
});
updateMarkersForServiceType(
_serviceType);
});
}
}
},
decoration: const InputDecoration(
@@ -984,56 +1031,59 @@ class _ServiceScreenState extends State<ServiceScreen> {
ubicacion = datos[1];
if (profesional != null) {
setState(() {
_profesionalController.text =
profesional.name.toString();
if (mounted) {
setState(() {
_profesionalController.text =
profesional.name.toString();
professionalId = profesional.id;
professionalId = profesional.id;
if (profesional.token != '') {
professionalToken =
profesional.token!;
}
professionalTarifa =
profesional.tarifa ?? 0;
professionalUbicacion =
profesional.ubicacion;
professionalLatitude =
profesional.latitude;
professionalLongitude =
profesional.longitude;
if (ubicacion == 'sitio') {
professionalAddress =
profesional.realAddress;
_locationController.text =
profesional.realAddress;
if (professionalLatitude !=
null &&
professionalLatitude != 0 &&
professionalLongitude !=
null &&
professionalLongitude != 0) {
googleMapController
?.animateCamera(
CameraUpdate
.newCameraPosition(
CameraPosition(
target: LatLng(
professionalLatitude!,
professionalLongitude!,
),
zoom: 17),
),
);
if (profesional.token != '') {
professionalToken =
profesional.token!;
}
}
});
professionalTarifa =
profesional.tarifa ?? 0;
professionalUbicacion =
profesional.ubicacion;
professionalLatitude =
profesional.latitude;
professionalLongitude =
profesional.longitude;
if (ubicacion == 'sitio') {
professionalAddress =
profesional.realAddress;
_locationController.text =
profesional.realAddress;
if (professionalLatitude !=
null &&
professionalLatitude != 0 &&
professionalLongitude !=
null &&
professionalLongitude !=
0) {
googleMapController
?.animateCamera(
CameraUpdate
.newCameraPosition(
CameraPosition(
target: LatLng(
professionalLatitude!,
professionalLongitude!,
),
zoom: 17),
),
);
}
}
});
}
}
}
},
@@ -1090,9 +1140,11 @@ class _ServiceScreenState extends State<ServiceScreen> {
newCoordinates),
);
setState(() {
_placesList = [];
});
if (mounted) {
setState(() {
_placesList = [];
});
}
},
title: Text(_placesList[index]
['formatted_address']),
@@ -1170,12 +1222,18 @@ class _ServiceScreenState extends State<ServiceScreen> {
hintText: 'Observaciones'),
),
const SizedBox(height: 20),
ElevatedButton(
PrimaryButton(
onPressed: () {
if (user?.name == null ||
user?.name == '' ||
user?.phoneNumber == null ||
user?.phoneNumber == '') {
WarningSnackbar.show(
title: 'Completa tu perfil',
message:
'Diligencia la información de tu perfil antes de solicitar un servicio.',
);
Navigator.push(
context,
CupertinoPageRoute(
@@ -1247,23 +1305,9 @@ class _ServiceScreenState extends State<ServiceScreen> {
}
}
},
style: ElevatedButton.styleFrom(
backgroundColor: const Color(0xFF2BA4EC),
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(50),
),
elevation: 0,
minimumSize: const Size(230, 50),
),
child: const Text(
'Solicitar servicio',
style: TextStyle(
color: Colors.white,
fontWeight: FontWeight.bold,
fontSize: 18,
),
),
),
text: 'Solicitar servicio',
minWidth: 230,
)
],
),
),
@@ -0,0 +1,28 @@
import 'package:flutter/material.dart';
class PrimaryCheckbox extends StatelessWidget {
final String text;
final bool initialValue;
final Function(bool) onChanged;
const PrimaryCheckbox({
Key? key,
required this.text,
required this.initialValue,
required this.onChanged,
}) : super(key: key);
@override
Widget build(BuildContext context) {
return CheckboxListTile(
title: Text(
text,
style: const TextStyle(fontSize: 15),
),
value: initialValue,
onChanged: (value) {
onChanged(value!);
},
);
}
}
@@ -0,0 +1,51 @@
import 'package:flutter/material.dart';
import 'package:get/get.dart';
class WarningSnackbar {
static void show({
required String title,
required String message,
SnackPosition position = SnackPosition.TOP,
Duration duration = const Duration(seconds: 4),
Color backgroundColor = Colors.red,
Color textColor = Colors.white,
double borderRadius = 10.0,
EdgeInsets margin = const EdgeInsets.all(10.0),
SnackStyle snackStyle = SnackStyle.FLOATING,
Duration animationDuration = const Duration(milliseconds: 800),
bool isDismissible = true,
DismissDirection dismissDirection = DismissDirection.horizontal,
Curve forwardAnimationCurve = Curves.easeOutBack,
Curve reverseAnimationCurve = Curves.easeInBack,
Icon icon = const Icon(Icons.warning, color: Colors.white),
bool shouldIconPulse = true,
}) {
Get.snackbar(
title,
message,
snackPosition: position,
duration: duration,
backgroundColor: backgroundColor,
colorText: textColor,
borderRadius: borderRadius,
margin: margin,
snackStyle: snackStyle,
animationDuration: animationDuration,
isDismissible: isDismissible,
dismissDirection: dismissDirection,
forwardAnimationCurve: forwardAnimationCurve,
reverseAnimationCurve: reverseAnimationCurve,
icon: icon,
shouldIconPulse: shouldIconPulse,
titleText: Text(
title,
style: const TextStyle(
fontSize: 18.0, fontWeight: FontWeight.bold, color: Colors.white),
),
messageText: Text(
message,
style: const TextStyle(fontSize: 16.0, color: Colors.white),
),
);
}
}
+19 -17
View File
@@ -1,7 +1,6 @@
import 'package:firebase_messaging/firebase_messaging.dart';
import 'package:get/get.dart';
class FirebaseMessagingService {
FirebaseMessaging _firebaseMessaging = FirebaseMessaging.instance;
@@ -21,32 +20,35 @@ class FirebaseMessagingService {
print('Token FCM: $token');
FirebaseMessaging.onMessage.listen((RemoteMessage message) {
print('Mensaje FCM recibido: ${message.notification?.title} - ${message.notification?.body}');
print(
'Mensaje FCM recibido: ${message.notification?.title} - ${message.notification?.body}');
// Obtener el valor de la clave "screen" de los datos de la notificación
String? notificationScreen = message.data['screen'];
// Navegar a la pantalla correspondiente según el valor de la clave "screen"
if (notificationScreen == "misservicios") {
// Navegar a MyServicesScreen
Get.offNamed('/misservicios');
} else if (notificationScreen == "solicitud") {
// Navegar a SolicitudScreen
Get.offNamed('/solicitud');
}
});
// Obtener el valor de la clave "screen" de los datos de la notificación
String? notificationScreen = message.data['screen'];
// Navegar a la pantalla correspondiente según el valor de la clave "screen"
if (notificationScreen == "misservicios") {
// Navegar a MyServicesScreen
Get.offNamed('/misservicios');
} else if (notificationScreen == "solicitud") {
// Navegar a SolicitudScreen
Get.offNamed('/solicitud');
}
});
// Manejar la notificación cuando se toca y la aplicación está en primer plano (opcional)
FirebaseMessaging.onMessageOpenedApp.listen((RemoteMessage message) {
print('Mensaje FCM abierto desde la aplicación en primer plano: ${message.notification?.title} - ${message.notification?.body}');
print(
'Mensaje FCM abierto desde la aplicación en primer plano: ${message.notification?.title} - ${message.notification?.body}');
// Aquí puedes redirigir al usuario a una pantalla específica o realizar acciones según los datos recibidos
});
// Manejar la notificación cuando se toca y la aplicación está cerrada (opcional)
RemoteMessage? initialMessage = await FirebaseMessaging.instance.getInitialMessage();
RemoteMessage? initialMessage =
await FirebaseMessaging.instance.getInitialMessage();
if (initialMessage != null) {
print('Mensaje FCM abierto desde la aplicación cerrada: ${initialMessage.notification?.title} - ${initialMessage.notification?.body}');
print(
'Mensaje FCM abierto desde la aplicación cerrada: ${initialMessage.notification?.title} - ${initialMessage.notification?.body}');
// Aquí puedes redirigir al usuario a una pantalla específica o realizar acciones según los datos recibidos
}
}
+1 -1
View File
@@ -51,7 +51,7 @@ dependencies:
flutter_animate:
flutter_rating_bar:
table_calendar:
google_maps_flutter: ^2.2.5
google_maps_flutter: ^2.5.0
flutter_polyline_points: ^2.0.0
http: ^1.1.0
geolocator: ^9.0.2