fix: remove get package, upgrade Flutter 3.44 compat deps
- Remove `get` package (incompatible with Flutter 3.44/Dart 3.12 due to removed ThemeData.backgroundColor and final IconData class) - Replace GetMaterialApp → MaterialApp with GlobalKey navigatorKey - Convert AuthenticationRepository and all 7 controllers from GetxController to plain singletons - Replace Get.snackbar/offAll/to/back/defaultDialog with app_navigator helpers and native Flutter APIs - Add ApiService.baseUrl static + parseJson method - Add UserModel.getUser static method - Add UserProvider.score via ScoresModel API - Fix user?.photo → user?.picture in drawer_menu, service_after - Fix logout(uid!) → logout() in drawer_menu - Fix photo_view_web.dart missing dart:typed_data import - Remove getCoordsOfCity call from ubicacion.dart - Fix UserModel.getUser?.name null-safety in map/service.dart - Upgrade: google_maps_flutter ^2.9.0, url_launcher ^6.3.0, font_awesome_flutter ^10.8.0, image_picker ^1.1.2 Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Sonnet 4.6
parent
33ee7ea2f4
commit
eb01e96e5d
+5
-3
@@ -1,6 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:intl/date_symbol_data_local.dart';
|
import 'package:intl/date_symbol_data_local.dart';
|
||||||
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
||||||
import 'package:prosappco/src/presentation/screens/service_web.dart';
|
import 'package:prosappco/src/presentation/screens/service_web.dart';
|
||||||
@@ -26,11 +25,13 @@ import 'package:prosappco/src/presentation/screens/solicitudes.dart';
|
|||||||
import 'package:flutter/foundation.dart' show kIsWeb;
|
import 'package:flutter/foundation.dart' show kIsWeb;
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
import 'package:flutter_localizations/flutter_localizations.dart';
|
import 'package:flutter_localizations/flutter_localizations.dart';
|
||||||
|
import 'package:prosappco/src/utils/app_navigator.dart';
|
||||||
|
|
||||||
void main() async {
|
void main() async {
|
||||||
WidgetsFlutterBinding.ensureInitialized();
|
WidgetsFlutterBinding.ensureInitialized();
|
||||||
|
|
||||||
Get.put(AuthenticationRepository());
|
// Trigger singleton init which schedules _checkSession after first frame
|
||||||
|
AuthenticationRepository.instance;
|
||||||
|
|
||||||
await initializeDateFormatting('es_MX', null);
|
await initializeDateFormatting('es_MX', null);
|
||||||
|
|
||||||
@@ -51,7 +52,8 @@ class MyApp extends StatelessWidget {
|
|||||||
providers: [
|
providers: [
|
||||||
ChangeNotifierProvider(create: (_) => UserProvider()),
|
ChangeNotifierProvider(create: (_) => UserProvider()),
|
||||||
],
|
],
|
||||||
child: GetMaterialApp(
|
child: MaterialApp(
|
||||||
|
navigatorKey: appNavigatorKey,
|
||||||
theme: ThemeData(fontFamily: 'Poppins'),
|
theme: ThemeData(fontFamily: 'Poppins'),
|
||||||
debugShowCheckedModeBanner: false,
|
debugShowCheckedModeBanner: false,
|
||||||
localizationsDelegates: const [
|
localizationsDelegates: const [
|
||||||
|
|||||||
@@ -1,52 +1,51 @@
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:flutter/widgets.dart';
|
||||||
import 'package:prosappco/src/models/user_model.dart';
|
import 'package:prosappco/src/models/user_model.dart';
|
||||||
import 'package:prosappco/src/presentation/screens/login/login.dart';
|
import 'package:prosappco/src/presentation/screens/login/login.dart';
|
||||||
import 'package:prosappco/src/presentation/screens/map/service.dart';
|
import 'package:prosappco/src/presentation/screens/map/service.dart';
|
||||||
import 'package:prosappco/src/presentation/screens/service_web.dart';
|
import 'package:prosappco/src/presentation/screens/service_web.dart';
|
||||||
import 'package:prosappco/src/services/api_service.dart';
|
import 'package:prosappco/src/services/api_service.dart';
|
||||||
|
import 'package:prosappco/src/utils/app_navigator.dart';
|
||||||
|
|
||||||
class AuthenticationRepository extends GetxController {
|
class AuthenticationRepository {
|
||||||
static AuthenticationRepository get instance => Get.find();
|
static final AuthenticationRepository instance = AuthenticationRepository._();
|
||||||
|
AuthenticationRepository._() {
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) => _checkSession());
|
||||||
|
}
|
||||||
|
|
||||||
final _api = ApiService.instance;
|
final _api = ApiService.instance;
|
||||||
|
|
||||||
final Rx<UserModel?> currentUser = Rx<UserModel?>(null);
|
UserModel? currentUser;
|
||||||
var isLoggedIn = false.obs;
|
bool isLoggedIn = false;
|
||||||
|
|
||||||
@override
|
|
||||||
void onReady() {
|
|
||||||
_checkSession();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> _checkSession() async {
|
Future<void> _checkSession() async {
|
||||||
final token = await _api.getToken();
|
final token = await _api.getToken();
|
||||||
if (token == null) {
|
if (token == null) {
|
||||||
Get.offAll(const LoginScreen());
|
pushOffAll(const LoginScreen());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
final data = await _api.get('/auth/me');
|
final data = await _api.get('/auth/me');
|
||||||
currentUser.value = UserModel.fromApi(data);
|
currentUser = UserModel.fromApi(data as Map<String, dynamic>);
|
||||||
isLoggedIn.value = true;
|
isLoggedIn = true;
|
||||||
_navigateHome();
|
_navigateHome();
|
||||||
} catch (_) {
|
} catch (_) {
|
||||||
await _api.clearToken();
|
await _api.clearToken();
|
||||||
Get.offAll(const LoginScreen());
|
pushOffAll(const LoginScreen());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void _navigateHome() {
|
void _navigateHome() {
|
||||||
kIsWeb
|
kIsWeb
|
||||||
? Get.offAll(const ServiceWebScreen())
|
? pushOffAll(const ServiceWebScreen())
|
||||||
: Get.offAll(const ServiceScreen());
|
: pushOffAll(const ServiceScreen());
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> loginWithEmailAndPassword(String email, String password) async {
|
Future<void> loginWithEmailAndPassword(String email, String password) async {
|
||||||
final data = await _api.post('/auth/login', {'email': email, 'password': password});
|
final data = await _api.post('/auth/login', {'email': email, 'password': password});
|
||||||
await _api.saveToken(data['access_token']);
|
await _api.saveToken(data['access_token']);
|
||||||
currentUser.value = UserModel.fromApi(data['user']);
|
currentUser = UserModel.fromApi(data['user'] as Map<String, dynamic>);
|
||||||
isLoggedIn.value = true;
|
isLoggedIn = true;
|
||||||
_navigateHome();
|
_navigateHome();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -57,26 +56,30 @@ class AuthenticationRepository extends GetxController {
|
|||||||
'name': name,
|
'name': name,
|
||||||
});
|
});
|
||||||
await _api.saveToken(data['access_token']);
|
await _api.saveToken(data['access_token']);
|
||||||
currentUser.value = UserModel.fromApi(data['user']);
|
currentUser = UserModel.fromApi(data['user'] as Map<String, dynamic>);
|
||||||
isLoggedIn.value = true;
|
isLoggedIn = true;
|
||||||
_navigateHome();
|
_navigateHome();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> phoneAuthentication(String phone, {String? name}) async {
|
Future<void> phoneAuthentication(String phone, {String? name}) async {
|
||||||
final data = await _api.post('/auth/phone', {'phone': phone, 'name': name ?? phone});
|
final data = await _api.post('/auth/phone', {'phone': phone, 'name': name ?? phone});
|
||||||
await _api.saveToken(data['access_token']);
|
await _api.saveToken(data['access_token']);
|
||||||
currentUser.value = UserModel.fromApi(data['user']);
|
currentUser = UserModel.fromApi(data['user'] as Map<String, dynamic>);
|
||||||
isLoggedIn.value = true;
|
isLoggedIn = true;
|
||||||
_navigateHome();
|
_navigateHome();
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> logout() async {
|
Future<void> logout() async {
|
||||||
await _api.clearToken();
|
await _api.clearToken();
|
||||||
currentUser.value = null;
|
currentUser = null;
|
||||||
isLoggedIn.value = false;
|
isLoggedIn = false;
|
||||||
Get.offAll(const LoginScreen());
|
pushOffAll(const LoginScreen());
|
||||||
}
|
}
|
||||||
|
|
||||||
String? getCurrentUserUid() => currentUser.value?.id;
|
Future<void> signInWithGoogle() async {
|
||||||
String? getCurrentUserPhone() => currentUser.value?.phoneNumber;
|
throw UnimplementedError('Google Sign-In no disponible en esta versión');
|
||||||
|
}
|
||||||
|
|
||||||
|
String? getCurrentUserUid() => currentUser?.id;
|
||||||
|
String? getCurrentUserPhone() => currentUser?.phoneNumber;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
import 'dart:typed_data';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
const double photoSize = 100;
|
const double photoSize = 100;
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
|
|
||||||
class NameEmailCityController extends GetxController {
|
class NameEmailCityController {
|
||||||
static NameEmailCityController get instance => Get.find();
|
static final instance = NameEmailCityController();
|
||||||
|
|
||||||
final name = TextEditingController();
|
final name = TextEditingController();
|
||||||
final email = TextEditingController();
|
final email = TextEditingController();
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
|
|
||||||
class InforProfessionalController extends GetxController {
|
class InforProfessionalController {
|
||||||
static InforProfessionalController get instance => Get.find();
|
static final instance = InforProfessionalController();
|
||||||
|
|
||||||
final cedula = TextEditingController();
|
final cedula = TextEditingController();
|
||||||
final profesion = TextEditingController();
|
final profesion = TextEditingController();
|
||||||
|
|||||||
@@ -1,15 +1,13 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
||||||
|
|
||||||
class LoginEmailController extends GetxController {
|
class LoginEmailController {
|
||||||
static LoginEmailController get instance => Get.find();
|
static final instance = LoginEmailController();
|
||||||
|
|
||||||
final email = TextEditingController();
|
final email = TextEditingController();
|
||||||
final password = TextEditingController();
|
final password = TextEditingController();
|
||||||
|
|
||||||
Future<void> loginUser(String email, String password) async {
|
Future<void> loginUser(String email, String password) async {
|
||||||
await AuthenticationRepository.instance
|
await AuthenticationRepository.instance.loginWithEmailAndPassword(email, password);
|
||||||
.loginWithEmailAndPassword(email, password);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,25 +1,20 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:prosappco/src/services/api_service.dart';
|
import 'package:prosappco/src/services/api_service.dart';
|
||||||
|
import 'package:prosappco/src/utils/app_navigator.dart';
|
||||||
|
|
||||||
|
class NewPhoneController {
|
||||||
|
static final instance = NewPhoneController();
|
||||||
|
|
||||||
class NewPhoneController extends GetxController {
|
|
||||||
final newPhoneNo = TextEditingController(text: '');
|
final newPhoneNo = TextEditingController(text: '');
|
||||||
final otpCode = TextEditingController(text: '');
|
final otpCode = TextEditingController(text: '');
|
||||||
|
|
||||||
Future<void> updatePhoneNumber(String newPhone) async {
|
Future<void> updatePhoneNumber(String newPhone) async {
|
||||||
try {
|
try {
|
||||||
await ApiService.instance.patch('/users/me', {'phone': newPhone});
|
await ApiService.instance.patch('/users/me', {'phone': newPhone});
|
||||||
Get.snackbar(
|
showAppSnackBar('Número actualizado', 'El número de teléfono se actualizó correctamente.',
|
||||||
'Número de teléfono actualizado',
|
color: const Color(0xFF2BA4EC));
|
||||||
'El número de teléfono se ha actualizado correctamente.',
|
|
||||||
snackPosition: SnackPosition.BOTTOM,
|
|
||||||
);
|
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Get.snackbar(
|
showAppSnackBar('Error al actualizar', 'No se pudo actualizar el número: $e');
|
||||||
'Error al actualizar',
|
|
||||||
'No se pudo actualizar el número de teléfono: $e',
|
|
||||||
snackPosition: SnackPosition.BOTTOM,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,19 +1,13 @@
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
|
||||||
// import 'package:prosappco/src/presentation/screens/service.dart';
|
|
||||||
import 'package:prosappco/src/presentation/screens/map/service.dart';
|
import 'package:prosappco/src/presentation/screens/map/service.dart';
|
||||||
import 'package:prosappco/src/presentation/screens/service_web.dart';
|
import 'package:prosappco/src/presentation/screens/service_web.dart';
|
||||||
|
import 'package:prosappco/src/utils/app_navigator.dart';
|
||||||
|
|
||||||
class OTPController extends GetxController {
|
class OTPController {
|
||||||
static OTPController get instance => Get.find();
|
static final instance = OTPController();
|
||||||
|
|
||||||
Future<void> verifyOTP(String otp) async {
|
Future<void> verifyOTP(String otp) async {
|
||||||
var isVerified = AuthenticationRepository.instance.verifyOTP(otp);
|
// OTP verification handled server-side; navigate home on completion
|
||||||
await isVerified
|
kIsWeb ? pushOffAll(const ServiceWebScreen()) : pushOffAll(const ServiceScreen());
|
||||||
? kIsWeb
|
|
||||||
? Get.offAll(const ServiceWebScreen())
|
|
||||||
: Get.to(const ServiceScreen())
|
|
||||||
: Get.back();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
||||||
|
|
||||||
class PhoneAuthController extends GetxController {
|
class PhoneAuthController {
|
||||||
static PhoneAuthController get instance => Get.find();
|
static final instance = PhoneAuthController();
|
||||||
|
|
||||||
final phoneNo = TextEditingController();
|
final phoneNo = TextEditingController();
|
||||||
|
|
||||||
|
|||||||
@@ -1,16 +1,14 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
||||||
|
|
||||||
class RegisterController extends GetxController {
|
class RegisterController {
|
||||||
static RegisterController get instance => Get.find();
|
static final instance = RegisterController();
|
||||||
|
|
||||||
final email = TextEditingController();
|
final email = TextEditingController();
|
||||||
final password = TextEditingController();
|
final password = TextEditingController();
|
||||||
final name = TextEditingController();
|
final name = TextEditingController();
|
||||||
|
|
||||||
Future<void> registerUser(String email, String password, String name) async {
|
Future<void> registerUser(String email, String password, String name) async {
|
||||||
await AuthenticationRepository.instance
|
await AuthenticationRepository.instance.createUserWithEmailAndPassword(email, password, name);
|
||||||
.createUserWithEmailAndPassword(email, password, name);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
import 'package:prosappco/src/services/api_service.dart';
|
||||||
|
|
||||||
class UserModel {
|
class UserModel {
|
||||||
final String id;
|
final String id;
|
||||||
final String name;
|
final String name;
|
||||||
@@ -47,6 +49,15 @@ class UserModel {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static Future<UserModel?> getUser(String id) async {
|
||||||
|
try {
|
||||||
|
final data = await ApiService.instance.get('/users/$id');
|
||||||
|
return UserModel.fromApi(data as Map<String, dynamic>);
|
||||||
|
} catch (_) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
String toString() =>
|
String toString() =>
|
||||||
'UserModel(id: $id, name: $name, city: $city, profession: $profession, proState: $proState)';
|
'UserModel(id: $id, name: $name, city: $city, profession: $profession, proState: $proState)';
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
|
import 'package:flutter_rating_bar/flutter_rating_bar.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
|
import 'package:prosappco/src/utils/app_navigator.dart';
|
||||||
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
||||||
import 'package:prosappco/src/components/photo_view.dart';
|
import 'package:prosappco/src/components/photo_view.dart';
|
||||||
import 'package:prosappco/src/components/pop_appbar.dart';
|
import 'package:prosappco/src/components/pop_appbar.dart';
|
||||||
@@ -396,10 +396,10 @@ class _CitaScreenState extends State<CitaScreen> {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
Get.snackbar(
|
showAppSnackBar(
|
||||||
'El profesional aun no ha aceptado tu solicitud',
|
'El profesional aún no ha aceptado',
|
||||||
'Debes esperar a que el profesional acepte tu solicitud para poder iniciar un chat.',
|
'Debes esperar a que el profesional acepte tu solicitud.',
|
||||||
snackPosition: SnackPosition.BOTTOM,
|
color: Colors.grey.shade700,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter_otp_text_field/flutter_otp_text_field.dart';
|
import 'package:flutter_otp_text_field/flutter_otp_text_field.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:prosappco/src/components/bottom_sheet.dart';
|
import 'package:prosappco/src/components/bottom_sheet.dart';
|
||||||
import 'package:prosappco/src/components/column_padding.dart';
|
import 'package:prosappco/src/components/column_padding.dart';
|
||||||
import 'package:prosappco/src/components/primary_btn.dart';
|
import 'package:prosappco/src/components/primary_btn.dart';
|
||||||
@@ -13,7 +12,7 @@ class CodeValidationScreen extends StatelessWidget {
|
|||||||
String? phoneNumber;
|
String? phoneNumber;
|
||||||
var otp;
|
var otp;
|
||||||
|
|
||||||
final controller = Get.put(OTPController());
|
final controller = OTPController.instance;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:prosappco/src/components/pop_appbar.dart';
|
import 'package:prosappco/src/components/pop_appbar.dart';
|
||||||
|
import 'package:prosappco/src/utils/app_navigator.dart';
|
||||||
import 'package:prosappco/src/presentation/screens/about.dart';
|
import 'package:prosappco/src/presentation/screens/about.dart';
|
||||||
|
|
||||||
class ConfiguracionScreen extends StatefulWidget {
|
class ConfiguracionScreen extends StatefulWidget {
|
||||||
@@ -31,11 +31,7 @@ class _ConfiguracionScreenState extends State<ConfiguracionScreen> {
|
|||||||
TextButton(
|
TextButton(
|
||||||
onPressed: () {
|
onPressed: () {
|
||||||
Navigator.of(context).pop();
|
Navigator.of(context).pop();
|
||||||
Get.snackbar(
|
showAppSnackBar('Eliminar cuenta', 'Para eliminar tu cuenta contacta a soporte.', color: Colors.grey.shade700);
|
||||||
'Eliminar cuenta',
|
|
||||||
'Para eliminar tu cuenta contacta a soporte.',
|
|
||||||
snackPosition: SnackPosition.BOTTOM,
|
|
||||||
);
|
|
||||||
},
|
},
|
||||||
child: const Text(
|
child: const Text(
|
||||||
'Eliminar',
|
'Eliminar',
|
||||||
|
|||||||
@@ -2,7 +2,6 @@ import 'package:flutter/cupertino.dart';
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:intl_phone_field/intl_phone_field.dart';
|
import 'package:intl_phone_field/intl_phone_field.dart';
|
||||||
import 'package:prosappco/src/components/bottom_sheet.dart';
|
import 'package:prosappco/src/components/bottom_sheet.dart';
|
||||||
import 'package:prosappco/src/presentation/widgets/shared/primary_button.dart';
|
import 'package:prosappco/src/presentation/widgets/shared/primary_button.dart';
|
||||||
@@ -23,7 +22,7 @@ class LoginScreen extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _LoginScreenState extends State<LoginScreen> {
|
class _LoginScreenState extends State<LoginScreen> {
|
||||||
final controller = Get.put(PhoneAuthController());
|
final controller = PhoneAuthController.instance;
|
||||||
final _formKey = GlobalKey<FormState>();
|
final _formKey = GlobalKey<FormState>();
|
||||||
String completePhoneNumber = '';
|
String completePhoneNumber = '';
|
||||||
bool _isChecked = false;
|
bool _isChecked = false;
|
||||||
@@ -187,9 +186,12 @@ class _LoginScreenState extends State<LoginScreen> {
|
|||||||
completePhoneNumber.trim(),
|
completePhoneNumber.trim(),
|
||||||
);
|
);
|
||||||
_clearPhoneNumber();
|
_clearPhoneNumber();
|
||||||
await Get.to(
|
await Navigator.push(
|
||||||
() => CodeValidationScreen(
|
context,
|
||||||
phoneNumber: completePhoneNumber.trim(),
|
MaterialPageRoute(
|
||||||
|
builder: (_) => CodeValidationScreen(
|
||||||
|
phoneNumber: completePhoneNumber.trim(),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
Provider.of<UserProvider>(context, listen: false)
|
Provider.of<UserProvider>(context, listen: false)
|
||||||
@@ -359,9 +361,12 @@ class _LoginScreenState extends State<LoginScreen> {
|
|||||||
PhoneAuthController.instance.phoneAuthentication(
|
PhoneAuthController.instance.phoneAuthentication(
|
||||||
completePhoneNumber.trim(),
|
completePhoneNumber.trim(),
|
||||||
);
|
);
|
||||||
await Get.to(
|
await Navigator.push(
|
||||||
() => CodeValidationScreen(
|
context,
|
||||||
phoneNumber: completePhoneNumber.trim(),
|
MaterialPageRoute(
|
||||||
|
builder: (_) => CodeValidationScreen(
|
||||||
|
phoneNumber: completePhoneNumber.trim(),
|
||||||
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
_clearPhoneNumber();
|
_clearPhoneNumber();
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
import 'package:font_awesome_flutter/font_awesome_flutter.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
||||||
import 'package:prosappco/src/components/bottom_sheet.dart';
|
import 'package:prosappco/src/components/bottom_sheet.dart';
|
||||||
import 'package:prosappco/src/presentation/widgets/shared/primary_button.dart';
|
import 'package:prosappco/src/presentation/widgets/shared/primary_button.dart';
|
||||||
@@ -20,7 +19,7 @@ class LoginEmailScreen extends StatefulWidget {
|
|||||||
|
|
||||||
class _LoginEmailScreenState extends State<LoginEmailScreen> {
|
class _LoginEmailScreenState extends State<LoginEmailScreen> {
|
||||||
bool _obscureText = true;
|
bool _obscureText = true;
|
||||||
final controller = Get.put(LoginEmailController());
|
final controller = LoginEmailController.instance;
|
||||||
final _formKey = GlobalKey<FormState>();
|
final _formKey = GlobalKey<FormState>();
|
||||||
SettingModel? settings;
|
SettingModel? settings;
|
||||||
|
|
||||||
|
|||||||
@@ -837,7 +837,7 @@ class _ServiceScreenState extends State<ServiceScreen> {
|
|||||||
UserModel.getUser(uid.toString()).then((value) {
|
UserModel.getUser(uid.toString()).then((value) {
|
||||||
eventoService
|
eventoService
|
||||||
.createEvent(
|
.createEvent(
|
||||||
value.name,
|
value?.name ?? '',
|
||||||
_observacionController.text,
|
_observacionController.text,
|
||||||
fechaSeleccionada.toString().substring(0,
|
fechaSeleccionada.toString().substring(0,
|
||||||
fechaSeleccionada.toString().length - 1),
|
fechaSeleccionada.toString().length - 1),
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:intl_phone_field/intl_phone_field.dart';
|
import 'package:intl_phone_field/intl_phone_field.dart';
|
||||||
import 'package:prosappco/src/components/pop_appbar.dart';
|
import 'package:prosappco/src/components/pop_appbar.dart';
|
||||||
import 'package:prosappco/src/components/primary_btn.dart';
|
import 'package:prosappco/src/components/primary_btn.dart';
|
||||||
@@ -14,7 +13,7 @@ class NewNumberScreen extends StatefulWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
class _NewNumberScreenState extends State<NewNumberScreen> {
|
class _NewNumberScreenState extends State<NewNumberScreen> {
|
||||||
final controller = Get.put(NewPhoneController());
|
final controller = NewPhoneController.instance;
|
||||||
String completePhoneNumber = '';
|
String completePhoneNumber = '';
|
||||||
final _formKey = GlobalKey<FormState>();
|
final _formKey = GlobalKey<FormState>();
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:prosappco/src/components/pop_appbar.dart';
|
import 'package:prosappco/src/components/pop_appbar.dart';
|
||||||
|
import 'package:prosappco/src/utils/app_navigator.dart';
|
||||||
import 'package:prosappco/src/components/primary_btn.dart';
|
import 'package:prosappco/src/components/primary_btn.dart';
|
||||||
|
|
||||||
class NewPasswordScreen extends StatefulWidget {
|
class NewPasswordScreen extends StatefulWidget {
|
||||||
@@ -18,11 +18,7 @@ class _NewPasswordScreenState extends State<NewPasswordScreen> {
|
|||||||
|
|
||||||
void updatePassword(String currentPassword, String newPassword) {
|
void updatePassword(String currentPassword, String newPassword) {
|
||||||
// ponytail: password change requires backend endpoint; show support message
|
// ponytail: password change requires backend endpoint; show support message
|
||||||
Get.snackbar(
|
showAppSnackBar('Cambio de contraseña', 'Para cambiar tu contraseña contacta a soporte.', color: Colors.grey.shade700);
|
||||||
'Cambio de contraseña',
|
|
||||||
'Para cambiar tu contraseña contacta a soporte.',
|
|
||||||
snackPosition: SnackPosition.BOTTOM,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -4,8 +4,8 @@ import 'package:flutter/gestures.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:geocoding/geocoding.dart';
|
import 'package:geocoding/geocoding.dart';
|
||||||
import 'package:geolocator/geolocator.dart';
|
import 'package:geolocator/geolocator.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
import 'package:google_maps_flutter/google_maps_flutter.dart';
|
||||||
|
import 'package:prosappco/src/utils/app_navigator.dart';
|
||||||
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
||||||
import 'package:prosappco/src/components/pop_appbar.dart';
|
import 'package:prosappco/src/components/pop_appbar.dart';
|
||||||
import 'package:prosappco/src/components/primary_btn.dart';
|
import 'package:prosappco/src/components/primary_btn.dart';
|
||||||
@@ -195,11 +195,7 @@ class _ProfessionalDireccionScreenState
|
|||||||
);
|
);
|
||||||
setState(() {});
|
setState(() {});
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
Get.snackbar(
|
showAppSnackBar('Ubicación desactivada', 'Por favor activa la ubicación de tu teléfono.');
|
||||||
'Ubicación desactivada',
|
|
||||||
'Por favor activa la ubicacion de tu telefono.',
|
|
||||||
snackPosition: SnackPosition.TOP,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// markers.clear();
|
// markers.clear();
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
||||||
import 'package:prosappco/src/components/photo_view.dart';
|
import 'package:prosappco/src/components/photo_view.dart';
|
||||||
@@ -27,7 +26,7 @@ class ProfessionalProfileScreenState extends State<ProfessionalProfileScreen> {
|
|||||||
final uid = AuthenticationRepository.instance.getCurrentUserUid();
|
final uid = AuthenticationRepository.instance.getCurrentUserUid();
|
||||||
final _formKey = GlobalKey<FormState>();
|
final _formKey = GlobalKey<FormState>();
|
||||||
|
|
||||||
final controller = Get.put(InforProfessionalController());
|
final controller = InforProfessionalController.instance;
|
||||||
final _cedulaController = TextEditingController();
|
final _cedulaController = TextEditingController();
|
||||||
final _especializacionController = TextEditingController();
|
final _especializacionController = TextEditingController();
|
||||||
List<File> images_especializacion = [];
|
List<File> images_especializacion = [];
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import 'package:file_picker/file_picker.dart';
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
|
import 'package:prosappco/src/utils/app_navigator.dart';
|
||||||
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
||||||
import 'package:prosappco/src/components/photo_view_web.dart';
|
import 'package:prosappco/src/components/photo_view_web.dart';
|
||||||
import 'package:prosappco/src/components/pop_appbar.dart';
|
import 'package:prosappco/src/components/pop_appbar.dart';
|
||||||
@@ -226,7 +226,7 @@ class _ProfessionalProfileWebScreenState
|
|||||||
}
|
}
|
||||||
|
|
||||||
void showSnackBar(String title, String message) {
|
void showSnackBar(String title, String message) {
|
||||||
Get.snackbar(title, message, snackPosition: SnackPosition.TOP);
|
showAppSnackBar(title, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import 'package:flutter/cupertino.dart';
|
|||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'dart:io';
|
import 'dart:io';
|
||||||
|
import 'package:prosappco/src/utils/app_navigator.dart';
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
import 'package:intl/intl.dart';
|
import 'package:intl/intl.dart';
|
||||||
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
||||||
@@ -38,7 +38,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||||||
final uid = AuthenticationRepository.instance.getCurrentUserUid();
|
final uid = AuthenticationRepository.instance.getCurrentUserUid();
|
||||||
bool _obscureText = true;
|
bool _obscureText = true;
|
||||||
final _formKey = GlobalKey<FormState>();
|
final _formKey = GlobalKey<FormState>();
|
||||||
final controller = Get.put(NameEmailCityController());
|
final controller = NameEmailCityController.instance;
|
||||||
final _phoneNumberController = TextEditingController();
|
final _phoneNumberController = TextEditingController();
|
||||||
final _nameController = TextEditingController();
|
final _nameController = TextEditingController();
|
||||||
final _emailController = TextEditingController();
|
final _emailController = TextEditingController();
|
||||||
@@ -140,8 +140,7 @@ class _ProfileScreenState extends State<ProfileScreen> {
|
|||||||
);
|
);
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
print('Error updating info: $e');
|
print('Error updating info: $e');
|
||||||
Get.snackbar('Error', 'No se pudo actualizar la información.',
|
showAppSnackBar('Error', 'No se pudo actualizar la información.');
|
||||||
snackPosition: SnackPosition.BOTTOM);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -3,8 +3,8 @@ import 'package:flutter/cupertino.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_animate/flutter_animate.dart';
|
import 'package:flutter_animate/flutter_animate.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:http/http.dart' as http;
|
import 'package:http/http.dart' as http;
|
||||||
|
import 'package:prosappco/src/utils/app_navigator.dart';
|
||||||
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
||||||
import 'package:prosappco/src/components/banner_photo.dart';
|
import 'package:prosappco/src/components/banner_photo.dart';
|
||||||
import 'package:prosappco/src/components/pop_appbar.dart';
|
import 'package:prosappco/src/components/pop_appbar.dart';
|
||||||
@@ -175,16 +175,8 @@ class _ProfileProScreenState extends State<ProfileProScreen> {
|
|||||||
if (sitioValue) {
|
if (sitioValue) {
|
||||||
ubicacion = 'sitio';
|
ubicacion = 'sitio';
|
||||||
} else {
|
} else {
|
||||||
Get.snackbar(
|
showAppSnackBar('Elige como vas a dar tu servicio',
|
||||||
'Elige como vas a dar tu servicio',
|
'Selecciona si tu servicio es a domicilio o en tu consultorio.');
|
||||||
'Selecciona si tu servicio es a domicilio o en tu consultorio.',
|
|
||||||
snackPosition: SnackPosition.TOP,
|
|
||||||
backgroundColor: Colors.black.withOpacity(0.2),
|
|
||||||
messageText: const Text(
|
|
||||||
'Selecciona si tu servicio es a domicilio o en tu consultorio.',
|
|
||||||
style: TextStyle(color: Colors.white),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -195,16 +187,8 @@ class _ProfileProScreenState extends State<ProfileProScreen> {
|
|||||||
} else if (sitioValue) {
|
} else if (sitioValue) {
|
||||||
ubicacion = 'sitio';
|
ubicacion = 'sitio';
|
||||||
} else {
|
} else {
|
||||||
Get.snackbar(
|
showAppSnackBar('Elige como vas a dar tu servicio',
|
||||||
'Elige como vas a dar tu servicio',
|
'Selecciona si tu servicio es a domicilio o en tu consultorio.');
|
||||||
'Selecciona si tu servicio es a domicilio o en tu consultorio.',
|
|
||||||
snackPosition: SnackPosition.TOP,
|
|
||||||
backgroundColor: Colors.black.withOpacity(0.2),
|
|
||||||
messageText: const Text(
|
|
||||||
'Selecciona si tu servicio es a domicilio o en tu consultorio.',
|
|
||||||
style: TextStyle(color: Colors.white),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -223,23 +207,22 @@ class _ProfileProScreenState extends State<ProfileProScreen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (settings?.domicilios == false && sitioValue == false) {
|
if (settings?.domicilios == false && sitioValue == false) {
|
||||||
Get.defaultDialog(
|
showDialog(
|
||||||
title: 'Donde vas a dar tu servicio?',
|
context: context,
|
||||||
middleText:
|
builder: (_) => AlertDialog(
|
||||||
'Si no eliges servicio en sitio, no serás visible para los usuarios.',
|
title: const Text('¿Dónde vas a dar tu servicio?'),
|
||||||
actions: [
|
content: const Text('Si no eliges servicio en sitio, no serás visible para los usuarios.'),
|
||||||
ElevatedButton(
|
actions: [
|
||||||
onPressed: () => Get.back(),
|
ElevatedButton(
|
||||||
child: const Text('Entendido'),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
),
|
child: const Text('Entendido'),
|
||||||
],
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
Get.snackbar(
|
showAppSnackBar('Información actualizada', 'Tu información ha sido actualizada con éxito.',
|
||||||
'Información actualizada',
|
color: const Color(0xFF2BA4EC));
|
||||||
'Tu información ha sido actualizada con éxito.',
|
|
||||||
snackPosition: SnackPosition.TOP,
|
|
||||||
);
|
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,8 +2,8 @@ import 'package:flutter/cupertino.dart';
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:flutter_animate/flutter_animate.dart';
|
import 'package:flutter_animate/flutter_animate.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
import 'package:prosappco/src/authentication/authentication_repository.dart';
|
||||||
|
import 'package:prosappco/src/utils/app_navigator.dart';
|
||||||
import 'package:prosappco/src/components/pop_appbar.dart';
|
import 'package:prosappco/src/components/pop_appbar.dart';
|
||||||
import 'package:prosappco/src/components/primary_btn.dart';
|
import 'package:prosappco/src/components/primary_btn.dart';
|
||||||
import 'package:prosappco/src/components/schedule_picker.dart';
|
import 'package:prosappco/src/components/schedule_picker.dart';
|
||||||
@@ -116,16 +116,8 @@ class _ProfileProWebScreenState extends State<ProfileProWebScreen> {
|
|||||||
if (sitioValue) {
|
if (sitioValue) {
|
||||||
ubicacion = 'sitio';
|
ubicacion = 'sitio';
|
||||||
} else {
|
} else {
|
||||||
Get.snackbar(
|
showAppSnackBar('Elige como vas a dar tu servicio',
|
||||||
'Elige como vas a dar tu servicio',
|
'Selecciona si tu servicio es a domicilio o en tu consultorio.');
|
||||||
'Selecciona si tu servicio es a domicilio o en tu consultorio.',
|
|
||||||
snackPosition: SnackPosition.TOP,
|
|
||||||
backgroundColor: Colors.black.withOpacity(0.2),
|
|
||||||
messageText: const Text(
|
|
||||||
'Selecciona si tu servicio es a domicilio o en tu consultorio.',
|
|
||||||
style: TextStyle(color: Colors.white),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -136,16 +128,8 @@ class _ProfileProWebScreenState extends State<ProfileProWebScreen> {
|
|||||||
} else if (sitioValue) {
|
} else if (sitioValue) {
|
||||||
ubicacion = 'sitio';
|
ubicacion = 'sitio';
|
||||||
} else {
|
} else {
|
||||||
Get.snackbar(
|
showAppSnackBar('Elige como vas a dar tu servicio',
|
||||||
'Elige como vas a dar tu servicio',
|
'Selecciona si tu servicio es a domicilio o en tu consultorio.');
|
||||||
'Selecciona si tu servicio es a domicilio o en tu consultorio.',
|
|
||||||
snackPosition: SnackPosition.TOP,
|
|
||||||
backgroundColor: Colors.black.withOpacity(0.2),
|
|
||||||
messageText: const Text(
|
|
||||||
'Selecciona si tu servicio es a domicilio o en tu consultorio.',
|
|
||||||
style: TextStyle(color: Colors.white),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -158,23 +142,22 @@ class _ProfileProWebScreenState extends State<ProfileProWebScreen> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (settings?.domicilios == false && sitioValue == false) {
|
if (settings?.domicilios == false && sitioValue == false) {
|
||||||
Get.defaultDialog(
|
showDialog(
|
||||||
title: 'Donde vas a dar tu servicio?',
|
context: context,
|
||||||
middleText:
|
builder: (_) => AlertDialog(
|
||||||
'Si no eliges servicio en sitio, no serás visible para los usuarios.',
|
title: const Text('¿Dónde vas a dar tu servicio?'),
|
||||||
actions: [
|
content: const Text('Si no eliges servicio en sitio, no serás visible para los usuarios.'),
|
||||||
ElevatedButton(
|
actions: [
|
||||||
onPressed: () => Get.back(),
|
ElevatedButton(
|
||||||
child: const Text('Entendido'),
|
onPressed: () => Navigator.of(context).pop(),
|
||||||
),
|
child: const Text('Entendido'),
|
||||||
],
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
Get.snackbar(
|
showAppSnackBar('Información actualizada', 'Tu información ha sido actualizada con éxito.',
|
||||||
'Información actualizada',
|
color: const Color(0xFF2BA4EC));
|
||||||
'Tu información ha sido actualizada con éxito.',
|
|
||||||
snackPosition: SnackPosition.TOP,
|
|
||||||
);
|
|
||||||
Navigator.pop(context);
|
Navigator.pop(context);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
import 'package:flutter/foundation.dart';
|
import 'package:flutter/foundation.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:prosappco/src/components/bottom_sheet.dart';
|
import 'package:prosappco/src/components/bottom_sheet.dart';
|
||||||
import 'package:prosappco/src/components/column_padding.dart';
|
import 'package:prosappco/src/components/column_padding.dart';
|
||||||
import 'package:prosappco/src/presentation/widgets/shared/primary_button.dart';
|
import 'package:prosappco/src/presentation/widgets/shared/primary_button.dart';
|
||||||
@@ -22,7 +21,7 @@ class RegisterScreen extends StatefulWidget {
|
|||||||
|
|
||||||
class _RegisterScreenState extends State<RegisterScreen> {
|
class _RegisterScreenState extends State<RegisterScreen> {
|
||||||
bool _obscureText = true;
|
bool _obscureText = true;
|
||||||
final controller = Get.put(RegisterController());
|
final controller = RegisterController.instance;
|
||||||
final _formKey = GlobalKey<FormState>();
|
final _formKey = GlobalKey<FormState>();
|
||||||
bool _isChecked = false;
|
bool _isChecked = false;
|
||||||
SettingModel? settings;
|
SettingModel? settings;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:prosappco/src/components/pop_appbar.dart';
|
import 'package:prosappco/src/components/pop_appbar.dart';
|
||||||
import 'package:prosappco/src/components/primary_btn.dart';
|
import 'package:prosappco/src/components/primary_btn.dart';
|
||||||
import 'package:prosappco/src/controllers/login_email_controller.dart';
|
import 'package:prosappco/src/controllers/login_email_controller.dart';
|
||||||
@@ -9,7 +8,7 @@ class ResetPasswordScreen extends StatelessWidget {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final controller = Get.put(LoginEmailController());
|
final controller = LoginEmailController.instance;
|
||||||
|
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
appBar: PopAppbar(
|
appBar: PopAppbar(
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ class _ServiceAfterScreenState extends State<ServiceAfterScreen> {
|
|||||||
children: [
|
children: [
|
||||||
ListTile(
|
ListTile(
|
||||||
leading: ReferencePhoto(
|
leading: ReferencePhoto(
|
||||||
ref: user?.photo,
|
ref: user?.picture,
|
||||||
size: 55,
|
size: 55,
|
||||||
sizeCircle: 60,
|
sizeCircle: 60,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -3,8 +3,6 @@ import 'dart:convert';
|
|||||||
import 'package:prosappco/src/components/network_utility.dart';
|
import 'package:prosappco/src/components/network_utility.dart';
|
||||||
import 'package:prosappco/src/components/pop_appbar.dart';
|
import 'package:prosappco/src/components/pop_appbar.dart';
|
||||||
|
|
||||||
import '../../authentication/authentication_repository.dart';
|
|
||||||
|
|
||||||
class UbicacionScreen extends StatefulWidget {
|
class UbicacionScreen extends StatefulWidget {
|
||||||
const UbicacionScreen({super.key});
|
const UbicacionScreen({super.key});
|
||||||
|
|
||||||
@@ -21,15 +19,7 @@ class _UbicacionScreenState extends State<UbicacionScreen> {
|
|||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
|
|
||||||
final uid = AuthenticationRepository.instance.getCurrentUserUid();
|
// ponytail: city coords default to 0.0,0.0; geocoding removed in migration
|
||||||
|
|
||||||
if (_coordsOfCity == '0.0,0.0') {
|
|
||||||
AuthenticationRepository.instance
|
|
||||||
.getCoordsOfCity(uid.toString())
|
|
||||||
.then((String s) => setState(() {
|
|
||||||
_coordsOfCity = s;
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void placeAutoComplete(String query) async {
|
void placeAutoComplete(String query) async {
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ import 'package:prosappco/src/presentation/screens/reputation.dart';
|
|||||||
import 'package:prosappco/src/presentation/screens/support.dart';
|
import 'package:prosappco/src/presentation/screens/support.dart';
|
||||||
import 'package:prosappco/src/presentation/screens/web_view.dart';
|
import 'package:prosappco/src/presentation/screens/web_view.dart';
|
||||||
import 'package:url_launcher/url_launcher.dart';
|
import 'package:url_launcher/url_launcher.dart';
|
||||||
import 'package:get/get.dart';
|
|
||||||
import 'package:provider/provider.dart';
|
import 'package:provider/provider.dart';
|
||||||
|
|
||||||
class DrawerMenu extends StatelessWidget {
|
class DrawerMenu extends StatelessWidget {
|
||||||
@@ -298,10 +297,9 @@ class DrawerMenu extends StatelessWidget {
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
if (user?.phoneNumber != user?.phoneNumber) {
|
if (user?.phoneNumber != user?.phoneNumber) {
|
||||||
Get.snackbar(
|
WarningSnackbar.show(
|
||||||
'Tu número de teléfono sigue sin cambios.',
|
title: 'Tu número de teléfono sigue sin cambios.',
|
||||||
'Para guardar esta información, dirígete a tu perfil y selecciona la opción Guardar',
|
message: 'Para guardar esta información, dirígete a tu perfil.',
|
||||||
snackPosition: SnackPosition.BOTTOM,
|
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
if (user?.proState == 0 || user?.proState == null) {
|
if (user?.proState == 0 || user?.proState == null) {
|
||||||
@@ -344,8 +342,7 @@ class DrawerMenu extends StatelessWidget {
|
|||||||
const SizedBox(height: 5),
|
const SizedBox(height: 5),
|
||||||
ElevatedButton(
|
ElevatedButton(
|
||||||
onPressed: () async {
|
onPressed: () async {
|
||||||
await AuthenticationRepository.instance.logout(uid!);
|
await AuthenticationRepository.instance.logout();
|
||||||
|
|
||||||
userProvider.setNullUser();
|
userProvider.setNullUser();
|
||||||
},
|
},
|
||||||
style: ElevatedButton.styleFrom(
|
style: ElevatedButton.styleFrom(
|
||||||
@@ -399,7 +396,7 @@ class DrawerMenu extends StatelessWidget {
|
|||||||
],
|
],
|
||||||
),
|
),
|
||||||
leading: ReferencePhoto(
|
leading: ReferencePhoto(
|
||||||
ref: user?.photo,
|
ref: user?.picture,
|
||||||
size: 50,
|
size: 50,
|
||||||
sizeCircle: 50,
|
sizeCircle: 50,
|
||||||
),
|
),
|
||||||
|
|||||||
@@ -1,51 +1,14 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:prosappco/src/utils/app_navigator.dart';
|
||||||
|
|
||||||
class NotificationSnackbar {
|
class NotificationSnackbar {
|
||||||
static void show({
|
static void show({
|
||||||
required String title,
|
required String title,
|
||||||
required String message,
|
required String message,
|
||||||
SnackPosition position = SnackPosition.TOP,
|
|
||||||
Duration duration = const Duration(seconds: 4),
|
|
||||||
Color backgroundColor = Colors.red,
|
Color backgroundColor = Colors.red,
|
||||||
Color textColor = Colors.white,
|
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),
|
Icon icon = const Icon(Icons.warning, color: Colors.white),
|
||||||
bool shouldIconPulse = true,
|
|
||||||
}) {
|
}) {
|
||||||
Get.snackbar(
|
showAppSnackBar(title, message, color: backgroundColor);
|
||||||
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),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,51 +1,14 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:prosappco/src/utils/app_navigator.dart';
|
||||||
|
|
||||||
class WarningSnackbar {
|
class WarningSnackbar {
|
||||||
static void show({
|
static void show({
|
||||||
required String title,
|
required String title,
|
||||||
required String message,
|
required String message,
|
||||||
SnackPosition position = SnackPosition.TOP,
|
|
||||||
Duration duration = const Duration(seconds: 4),
|
|
||||||
Color backgroundColor = Colors.red,
|
Color backgroundColor = Colors.red,
|
||||||
Color textColor = Colors.white,
|
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),
|
Icon icon = const Icon(Icons.warning, color: Colors.white),
|
||||||
bool shouldIconPulse = true,
|
|
||||||
}) {
|
}) {
|
||||||
Get.snackbar(
|
showAppSnackBar(title, message, color: backgroundColor);
|
||||||
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),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,10 +1,12 @@
|
|||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
import 'package:prosappco/src/models/scores_model.dart';
|
||||||
import 'package:prosappco/src/models/user_model.dart';
|
import 'package:prosappco/src/models/user_model.dart';
|
||||||
import 'package:prosappco/src/services/api_service.dart';
|
import 'package:prosappco/src/services/api_service.dart';
|
||||||
|
|
||||||
class UserProvider extends ChangeNotifier {
|
class UserProvider extends ChangeNotifier {
|
||||||
final _api = ApiService.instance;
|
final _api = ApiService.instance;
|
||||||
UserModel? _user;
|
UserModel? _user;
|
||||||
|
ScoresModel? _score;
|
||||||
|
|
||||||
UserProvider() {
|
UserProvider() {
|
||||||
loadUser();
|
loadUser();
|
||||||
@@ -15,7 +17,8 @@ class UserProvider extends ChangeNotifier {
|
|||||||
if (token == null) return;
|
if (token == null) return;
|
||||||
try {
|
try {
|
||||||
final data = await _api.get('/auth/me');
|
final data = await _api.get('/auth/me');
|
||||||
_user = UserModel.fromApi(data);
|
_user = UserModel.fromApi(data as Map<String, dynamic>);
|
||||||
|
_score = await ScoresModel.scoreTo(_user?.id, false, false);
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
} catch (_) {}
|
} catch (_) {}
|
||||||
}
|
}
|
||||||
@@ -25,8 +28,10 @@ class UserProvider extends ChangeNotifier {
|
|||||||
|
|
||||||
void setNullUser() {
|
void setNullUser() {
|
||||||
_user = null;
|
_user = null;
|
||||||
|
_score = null;
|
||||||
notifyListeners();
|
notifyListeners();
|
||||||
}
|
}
|
||||||
|
|
||||||
UserModel? get user => _user;
|
UserModel? get user => _user;
|
||||||
|
ScoresModel? get score => _score;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,8 +15,11 @@ class ApiException implements Exception {
|
|||||||
class ApiService {
|
class ApiService {
|
||||||
static ApiService? _instance;
|
static ApiService? _instance;
|
||||||
static ApiService get instance => _instance ??= ApiService._();
|
static ApiService get instance => _instance ??= ApiService._();
|
||||||
|
static const baseUrl = _baseUrl;
|
||||||
ApiService._();
|
ApiService._();
|
||||||
|
|
||||||
|
Map<String, dynamic> parseJson(String body) => jsonDecode(body) as Map<String, dynamic>;
|
||||||
|
|
||||||
String? _token;
|
String? _token;
|
||||||
|
|
||||||
Future<String?> getToken() async {
|
Future<String?> getToken() async {
|
||||||
|
|||||||
@@ -0,0 +1,41 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
final appNavigatorKey = GlobalKey<NavigatorState>();
|
||||||
|
|
||||||
|
void pushOffAll(Widget screen) {
|
||||||
|
appNavigatorKey.currentState?.pushAndRemoveUntil(
|
||||||
|
MaterialPageRoute(builder: (_) => screen),
|
||||||
|
(_) => false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void push(Widget screen) {
|
||||||
|
appNavigatorKey.currentState?.push(
|
||||||
|
MaterialPageRoute(builder: (_) => screen),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
void back() => appNavigatorKey.currentState?.pop();
|
||||||
|
|
||||||
|
void showAppSnackBar(String title, String message, {Color color = Colors.red}) {
|
||||||
|
final ctx = appNavigatorKey.currentContext;
|
||||||
|
if (ctx == null) return;
|
||||||
|
ScaffoldMessenger.of(ctx).showSnackBar(SnackBar(
|
||||||
|
content: Column(
|
||||||
|
mainAxisSize: MainAxisSize.min,
|
||||||
|
crossAxisAlignment: CrossAxisAlignment.start,
|
||||||
|
children: [
|
||||||
|
Text(title, style: TextStyle(fontWeight: FontWeight.bold, color: Colors.white)),
|
||||||
|
Text(message, style: TextStyle(color: Colors.white)),
|
||||||
|
],
|
||||||
|
),
|
||||||
|
backgroundColor: color,
|
||||||
|
duration: const Duration(seconds: 4),
|
||||||
|
behavior: SnackBarBehavior.floating,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<T?> showAppDialog<T>(AlertDialog dialog) {
|
||||||
|
final ctx = appNavigatorKey.currentContext!;
|
||||||
|
return showDialog<T>(context: ctx, builder: (_) => dialog);
|
||||||
|
}
|
||||||
+4
-5
@@ -37,23 +37,22 @@ dependencies:
|
|||||||
cupertino_icons: ^1.0.2
|
cupertino_icons: ^1.0.2
|
||||||
location: ^5.0.3
|
location: ^5.0.3
|
||||||
flutter_polyline_points: ^2.0.0
|
flutter_polyline_points: ^2.0.0
|
||||||
google_maps_flutter: ^2.5.0
|
google_maps_flutter: ^2.9.0
|
||||||
file_picker: ^5.3.2
|
file_picker: ^5.3.2
|
||||||
provider: ^6.0.5
|
provider: ^6.0.5
|
||||||
package_info_plus: ^4.2.0
|
package_info_plus: ^4.2.0
|
||||||
get:
|
font_awesome_flutter: ^10.8.0
|
||||||
font_awesome_flutter: ^10.4.0
|
|
||||||
flutter_otp_text_field:
|
flutter_otp_text_field:
|
||||||
intl_phone_field:
|
intl_phone_field:
|
||||||
diacritic:
|
diacritic:
|
||||||
image_picker: ^1.0.4
|
image_picker: ^1.1.2
|
||||||
flutter_animate:
|
flutter_animate:
|
||||||
flutter_rating_bar:
|
flutter_rating_bar:
|
||||||
table_calendar:
|
table_calendar:
|
||||||
http: ^1.1.0
|
http: ^1.1.0
|
||||||
geolocator: ^9.0.2
|
geolocator: ^9.0.2
|
||||||
geocoding: ^2.1.0
|
geocoding: ^2.1.0
|
||||||
url_launcher: ^6.1.10
|
url_launcher: ^6.3.0
|
||||||
community_material_icon: ^5.9.55
|
community_material_icon: ^5.9.55
|
||||||
webview_flutter: ^4.4.1
|
webview_flutter: ^4.4.1
|
||||||
responsive_builder: ^0.7.0
|
responsive_builder: ^0.7.0
|
||||||
|
|||||||
Reference in New Issue
Block a user