From 083f2d200d470c2a5cf77fe3cfb6afe90ae1a39e Mon Sep 17 00:00:00 2001 From: "J. A. Messias" Date: Mon, 27 Jan 2025 14:28:34 -0300 Subject: [PATCH 01/47] implement vehicle crud screens --- .../backend/api_requests/api_calls.dart | 503 +++++++++--------- lib/flutter_flow/nav/nav.dart | 152 ++---- lib/main.dart | 13 +- lib/pages/pets_page/pets_page_model.dart | 1 + lib/pages/pets_page/pets_page_widget.dart | 2 + .../vehicle_history_screen.dart | 220 ++++++++ .../vehicle_model.dart | 449 +++++++++++++++- .../vehicle_register_screen.dart | 102 ++++ .../vehicle_update_screen.dart | 103 ++++ .../vehicles_on_the_property.dart | 318 ++++------- lib/pages/visits_on_the_property/model.dart | 12 +- 11 files changed, 1233 insertions(+), 642 deletions(-) create mode 100644 lib/pages/vehicles_on_the_property/vehicle_history_screen.dart create mode 100644 lib/pages/vehicles_on_the_property/vehicle_register_screen.dart create mode 100644 lib/pages/vehicles_on_the_property/vehicle_update_screen.dart diff --git a/lib/features/backend/api_requests/api_calls.dart b/lib/features/backend/api_requests/api_calls.dart index 72d1a8a2..e73db478 100644 --- a/lib/features/backend/api_requests/api_calls.dart +++ b/lib/features/backend/api_requests/api_calls.dart @@ -31,20 +31,17 @@ class PhpGroup extends Api { static ForgotPasswordCall forgotPasswordCall = ForgotPasswordCall(); static ChangePasswordCall changePasswordCall = ChangePasswordCall(); static GetLocalsCall getLocalsCall = GetLocalsCall(); - static PostScheduleVisitorCall postScheduleVisitorCall = - PostScheduleVisitorCall(); + static PostScheduleVisitorCall postScheduleVisitorCall = PostScheduleVisitorCall(); static PostScheduleVisitCall postScheduleVisitCall = PostScheduleVisitCall(); static GetScheduleVisitCall getScheduleVisitCall = GetScheduleVisitCall(); static GetDadosCall getDadosCall = GetDadosCall(); static GetVisitorByDocCall getVisitorByDocCall = GetVisitorByDocCall(); static GetFotoVisitanteCall getFotoVisitanteCall = GetFotoVisitanteCall(); - static PostProvVisitSchedulingCall postProvVisitSchedulingCall = - PostProvVisitSchedulingCall(); + static PostProvVisitSchedulingCall postProvVisitSchedulingCall = PostProvVisitSchedulingCall(); static GetVisitsCall getVisitsCall = GetVisitsCall(); static DeleteVisitCall deleteVisitCall = DeleteVisitCall(); static GetPessoasLocalCall getPessoasLocalCall = GetPessoasLocalCall(); - static RespondeSolicitacaoCall respondeSolicitacaoCall = - RespondeSolicitacaoCall(); + static RespondeSolicitacaoCall respondeSolicitacaoCall = RespondeSolicitacaoCall(); static GetAccessCall getAccessCall = GetAccessCall(); static GetLiberationsCall getLiberationsCall = GetLiberationsCall(); static GetMessagesCall getMessagesCall = GetMessagesCall(); @@ -63,22 +60,134 @@ class PhpGroup extends Api { static GetPetPhoto getPetPhoto = GetPetPhoto(); static UnregisterDevice unregisterDevice = UnregisterDevice(); static GetVehiclesByProperty getVehiclesByProperty = GetVehiclesByProperty(); - static GetResidentsByProperty getResidentsByProperty = - GetResidentsByProperty(); + static GetResidentsByProperty getResidentsByProperty = GetResidentsByProperty(); static GetOpenedVisits getOpenedVisits = GetOpenedVisits(); GetLicense getLicense = GetLicense(); static GetProvSchedules getProvSchedules = GetProvSchedules(); + static RegisterVehicle registerVehicle = RegisterVehicle(); + static UpdateVehicle updateVehicle = UpdateVehicle(); + static DeleteVehicle deleteVehicle = DeleteVehicle(); +} + +class DeleteVehicle { + Future call({vehicleId}) async { + final String baseUrl = PhpGroup.getBaseUrl(); + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + const String atividade = 'excluirVeiculo'; + + return await ApiManager.instance.makeApiCall( + callName: 'deleteVehicle', + apiUrl: '$baseUrl/processRequest.php', + callType: ApiCallType.POST, + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + params: { + 'devUUID': devUUID, + 'userUUID': userUUID, + 'cliID': cliID, + 'atividade': atividade, + 'vehicleId': vehicleId, + }, + bodyType: BodyType.X_WWW_FORM_URL_ENCODED, + returnBody: true, + encodeBodyUtf8: false, + decodeUtf8: false, + cache: false, + isStreamingApi: false, + alwaysAllowBody: false, + ); + } +} + +class RegisterVehicle { + Future call({ + final String? licensePlate, + final String? color, + final String? model, + }) async { + final String baseUrl = PhpGroup.getBaseUrl(); + + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + const String atividade = 'cadastrarVeiculo'; + + return await ApiManager.instance.makeApiCall( + callName: 'registerVehicle', + apiUrl: '$baseUrl/processRequest.php', + callType: ApiCallType.POST, + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + params: { + 'devUUID': devUUID, + 'userUUID': userUUID, + 'cliID': cliID, + 'atividade': atividade, + 'licensePlate': licensePlate, + 'color': color, + 'model': model, + }, + bodyType: BodyType.X_WWW_FORM_URL_ENCODED, + returnBody: true, + encodeBodyUtf8: false, + decodeUtf8: false, + cache: false, + isStreamingApi: false, + alwaysAllowBody: false, + ); + } +} + +class UpdateVehicle { + Future call({ + final String? vehicleId, + final String? licensePlate, + final String? color, + final String? model, + }) async { + final String baseUrl = PhpGroup.getBaseUrl(); + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + const String atividade = 'atualizarVeiculo'; + + return await ApiManager.instance.makeApiCall( + callName: 'updateVehicle', + apiUrl: '$baseUrl/processRequest.php', + callType: ApiCallType.POST, + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + params: { + 'devUUID': devUUID, + 'userUUID': userUUID, + 'cliID': cliID, + 'atividade': atividade, + 'licensePlate': licensePlate, + 'color': color, + 'model': model, + }, + bodyType: BodyType.X_WWW_FORM_URL_ENCODED, + returnBody: true, + encodeBodyUtf8: false, + decodeUtf8: false, + cache: false, + isStreamingApi: false, + alwaysAllowBody: false, + ); + } } class GetProvSchedules { Future call(final String page, final String status) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'getAgendamentoProv'; const String pageSize = '10'; final bool isFiltered = status != '' && status != '.*'; @@ -111,12 +220,9 @@ class GetProvSchedules { class GetOpenedVisits { Future call(final String page) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'getOpenedVisits'; const String pageSize = '10'; return await ApiManager.instance.makeApiCall( @@ -146,12 +252,9 @@ class GetOpenedVisits { class GetResidentsByProperty { Future call(final String page) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - await StorageHelper().get(ProfileStorageKey.devUUID.key) ?? ''; - final String userUUID = - await StorageHelper().get(ProfileStorageKey.userUUID.key) ?? ''; - final String cliID = - await StorageHelper().get(ProfileStorageKey.clientUUID.key) ?? ''; + final String devUUID = await StorageHelper().get(ProfileStorageKey.devUUID.key) ?? ''; + final String userUUID = await StorageHelper().get(ProfileStorageKey.userUUID.key) ?? ''; + final String cliID = await StorageHelper().get(ProfileStorageKey.clientUUID.key) ?? ''; const String atividade = 'getResidentsByProperty'; const String pageSize = '10'; return await ApiManager.instance.makeApiCall( @@ -180,12 +283,9 @@ class GetResidentsByProperty { class GetVehiclesByProperty { Future call(final String page) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'getVehiclesByProperty'; const String pageSize = '10'; return await ApiManager.instance.makeApiCall( @@ -216,12 +316,9 @@ class GetVehiclesByProperty { class GetLicense { Future call() async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; return await ApiManager.instance.makeApiCall( callName: 'getLicense', @@ -250,10 +347,8 @@ class GetLicense { class UnregisterDevice { Future call() async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; return await ApiManager.instance.makeApiCall( callName: 'unregisterDevice', @@ -280,12 +375,9 @@ class UnregisterDevice { class DeletePet { Future call({final int? petID = 0}) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'excluirPet'; return await ApiManager.instance.makeApiCall( @@ -328,12 +420,9 @@ class UpdatePet { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'atualizarPet'; return await ApiManager.instance.makeApiCall( @@ -354,9 +443,7 @@ class UpdatePet { 'species': species, 'breed': breed, if (color != '') 'color': color, - if (birthdayDate != '') - 'birthdayDate': - ValidatorUtil.toISO8601USA('dd/MM/yyyy', birthdayDate!), + if (birthdayDate != '') 'birthdayDate': ValidatorUtil.toISO8601USA('dd/MM/yyyy', birthdayDate!), 'gender': gender, 'size': size, if (notes != '') 'notes': notes, @@ -379,12 +466,9 @@ class GetPets { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'consultaPets'; return await ApiManager.instance.makeApiCall( @@ -416,12 +500,9 @@ class GetPetPhoto { Future call({final int? petId}) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'consultaFotoPet'; return await ApiManager.instance.makeApiCall( @@ -462,12 +543,9 @@ class RegisterPet { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'cadastrarPet'; return await ApiManager.instance.makeApiCall( @@ -487,9 +565,7 @@ class RegisterPet { 'species': species, 'breed': breed, if (color != '') 'color': color, - if (birthdayDate != '') - 'birthdayDate': - ValidatorUtil.toISO8601USA('dd/MM/yyyy', birthdayDate!), + if (birthdayDate != '') 'birthdayDate': ValidatorUtil.toISO8601USA('dd/MM/yyyy', birthdayDate!), 'gender': gender, 'size': size, if (notes != '') 'notes': notes, @@ -512,12 +588,9 @@ class BuscaEnconcomendas { final String? adresseeType, final String? status, }) async { - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'getEncomendas'; final String baseUrl = PhpGroup.getBaseUrl(); @@ -559,12 +632,9 @@ class CancelaVisita { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'cancelaVisita'; return await ApiManager.instance.makeApiCall( @@ -596,10 +666,8 @@ class CancelaVisita { class DeleteAccount { Future call() async { - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; final String baseUrl = PhpGroup.getBaseUrl(); return await ApiManager.instance.makeApiCall( @@ -630,12 +698,9 @@ class ChangePanic { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'updVisitado'; return await ApiManager.instance.makeApiCall( @@ -669,12 +734,9 @@ class ChangePass { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'updVisitado'; return await ApiManager.instance.makeApiCall( @@ -708,12 +770,9 @@ class RespondeVinculo { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; return await ApiManager.instance.makeApiCall( callName: 'respondeVinculo', @@ -745,12 +804,9 @@ class ChangeNotifica { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'updVisitado'; return await ApiManager.instance.makeApiCall( @@ -782,14 +838,10 @@ class UpdateIDE { Future call() async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliUUID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; - final String newIde = - (await StorageHelper().get(ProfileStorageKey.userDevUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String newIde = (await StorageHelper().get(ProfileStorageKey.userDevUUID.key)) ?? ''; const String atividade = 'updVisitado'; return await ApiManager.instance.makeApiCall( @@ -821,12 +873,9 @@ class UpdToken { Future call() async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String token = - (await StorageHelper().get(SecureStorageKey.token.value)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String token = (await StorageHelper().get(SecureStorageKey.token.value)) ?? ''; return await ApiManager.instance.makeApiCall( callName: 'updToken', @@ -853,17 +902,11 @@ class UpdToken { class LoginCall { Future call() async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String email = - (await StorageHelper().get(SecureStorageKey.email.value)) ?? ''; - final String password = - (await StorageHelper().get(SecureStorageKey.password.value)) ?? ''; - final String type = - (await StorageHelper().get(SecureStorageKey.deviceType.value)) ?? ''; - final String description = - (await StorageHelper().get(SecureStorageKey.deviceDescription.value)) ?? - ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String email = (await StorageHelper().get(SecureStorageKey.email.value)) ?? ''; + final String password = (await StorageHelper().get(SecureStorageKey.password.value)) ?? ''; + final String type = (await StorageHelper().get(SecureStorageKey.deviceType.value)) ?? ''; + final String description = (await StorageHelper().get(SecureStorageKey.deviceDescription.value)) ?? ''; late final String token; try { token = await FirebaseMessagingService.getToken(); @@ -946,12 +989,9 @@ class ChangePasswordCall { required final String psswd, }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; return await ApiManager.instance.makeApiCall( callName: 'changePassword', @@ -1010,10 +1050,8 @@ class GetLocalsCall { Future call() async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - await StorageHelper().get(ProfileStorageKey.devUUID.key) ?? ''; - final String userUUID = - await StorageHelper().get(ProfileStorageKey.userUUID.key) ?? ''; + final String devUUID = await StorageHelper().get(ProfileStorageKey.devUUID.key) ?? ''; + final String userUUID = await StorageHelper().get(ProfileStorageKey.userUUID.key) ?? ''; return await ApiManager.instance .makeApiCall( @@ -1054,12 +1092,9 @@ class PostScheduleVisitorCall { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'putVisitante'; return await ApiManager.instance.makeApiCall( @@ -1112,12 +1147,9 @@ class PostScheduleVisitCall { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'putVisita'; return await ApiManager.instance.makeApiCall( @@ -1169,12 +1201,9 @@ class GetScheduleVisitCall { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliUUID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'getVisitas'; return await ApiManager.instance.makeApiCall( @@ -1446,12 +1475,9 @@ class GetDadosCall { Future call() async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliUUID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'getDados'; return await ApiManager.instance @@ -1487,8 +1513,7 @@ class GetDadosCall { response, r'''$.error_msg''', )); - String? visitedDesNomeStr(dynamic response) => - castToType(getJsonField( + String? visitedDesNomeStr(dynamic response) => castToType(getJsonField( response, r'''$.visitado.DES_NOME''', )); @@ -1496,33 +1521,27 @@ class GetDadosCall { response, r'''$.visitado.VDO_ID''', )); - String? visitedVDOTNomeStr(dynamic response) => - castToType(getJsonField( + String? visitedVDOTNomeStr(dynamic response) => castToType(getJsonField( response, r'''$.visitado.VDO_NOME''', )); - String? visitedVDOTipoStr(dynamic response) => - castToType(getJsonField( + String? visitedVDOTipoStr(dynamic response) => castToType(getJsonField( response, r'''$.visitado.VDO_TIPO''', )); - String? visitedVDOImeiStr(dynamic response) => - castToType(getJsonField( + String? visitedVDOImeiStr(dynamic response) => castToType(getJsonField( response, r'''$.visitado.VDO_IMEI''', )); - String? visitedVDODocumentoStr(dynamic response) => - castToType(getJsonField( + String? visitedVDODocumentoStr(dynamic response) => castToType(getJsonField( response, r'''$.visitado.VDO_DOCUMENTO''', )); - String? visitedVDOEmailStr(dynamic response) => - castToType(getJsonField( + String? visitedVDOEmailStr(dynamic response) => castToType(getJsonField( response, r'''$.visitado.VDO_EMAIL''', )); - String? visitedVDOStatusWebStr(dynamic response) => - castToType(getJsonField( + String? visitedVDOStatusWebStr(dynamic response) => castToType(getJsonField( response, r'''$.visitado.VDO_STATUSWEB''', )); @@ -1570,8 +1589,7 @@ class GetDadosCall { response, r'''$.visitado.DES_ID''', )); - String? visitedVDoNotTerceirosStr(dynamic response) => - castToType(getJsonField( + String? visitedVDoNotTerceirosStr(dynamic response) => castToType(getJsonField( response, r'''$.visitado.VDO_NOTTERCEIROS''', )); @@ -1640,8 +1658,7 @@ class GetDadosCall { .map((x) => castToType(x)) .withoutNulls .toList(); - List? levelNACIndPermiteReentradaStrList(dynamic response) => - (getJsonField( + List? levelNACIndPermiteReentradaStrList(dynamic response) => (getJsonField( response, r'''$.niveis[:].NAC_INDPERMITEREENTRADA''', true, @@ -1659,8 +1676,7 @@ class GetDadosCall { .map((x) => castToType(x)) .withoutNulls .toList(); - List? levelNACTempoAntiCaronaStrList(dynamic response) => - (getJsonField( + List? levelNACTempoAntiCaronaStrList(dynamic response) => (getJsonField( response, r'''$.niveis[:].NAC_TEMPOANTICARONA''', true, @@ -1694,12 +1710,9 @@ class GetVisitorByDocCall { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'getVisitante'; return await ApiManager.instance.makeApiCall( @@ -1751,12 +1764,9 @@ class GetFotoVisitanteCall { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'getFotoVisitante'; return await ApiManager.instance.makeApiCall( @@ -1793,12 +1803,9 @@ class PostProvVisitSchedulingCall { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'putAgendamentoProv'; return await ApiManager.instance.makeApiCall( @@ -1845,12 +1852,9 @@ class GetVisitsCall { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'getVisitas'; return await ApiManager.instance.makeApiCall( @@ -2111,12 +2115,9 @@ class DeleteVisitCall { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'cancelaVisita'; return await ApiManager.instance.makeApiCall( @@ -2157,14 +2158,10 @@ class GetPessoasLocalCall { Future call() async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String ownerUUID = - (await StorageHelper().get(ProfileStorageKey.ownerUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliUUID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String ownerUUID = (await StorageHelper().get(ProfileStorageKey.ownerUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; return await ApiManager.instance.makeApiCall( callName: 'getPessoasLocal', @@ -2227,12 +2224,9 @@ class RespondeSolicitacaoCall { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliUUID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'respondeSolicitacao'; return await ApiManager.instance.makeApiCall( @@ -2280,12 +2274,9 @@ class GetAccessCall { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliUUID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'getAcessos'; return await ApiManager.instance.makeApiCall( @@ -2532,12 +2523,9 @@ class GetLiberationsCall { final StreamController controller = StreamController(); Future.microtask(() async { - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliUUID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'getSolicitacoes'; try { @@ -2727,12 +2715,9 @@ class GetMessagesCall { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliUUID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'getMensagens'; return await ApiManager.instance.makeApiCall( diff --git a/lib/flutter_flow/nav/nav.dart b/lib/flutter_flow/nav/nav.dart index 22782a4d..73675f50 100644 --- a/lib/flutter_flow/nav/nav.dart +++ b/lib/flutter_flow/nav/nav.dart @@ -86,20 +86,11 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { builder: (context, _) { return FutureBuilder( future: () async { - final bool isLogged = - await StorageHelper().get(SecureStorageKey.isLogged.value) == - 'true'; - final bool haveLocal = - await StorageHelper().get(SecureStorageKey.haveLocal.value) == - 'true'; + final bool isLogged = await StorageHelper().get(SecureStorageKey.isLogged.value) == 'true'; + final bool haveLocal = await StorageHelper().get(SecureStorageKey.haveLocal.value) == 'true'; final bool haveUserUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) - ?.isNotEmpty ?? - false; - final bool haveDevUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) - ?.isNotEmpty ?? - false; + (await StorageHelper().get(ProfileStorageKey.userUUID.key))?.isNotEmpty ?? false; + final bool haveDevUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key))?.isNotEmpty ?? false; if (isLogged && haveDevUUID && haveUserUUID) { return haveLocal @@ -109,20 +100,17 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { create: (context) => MenuBloc( style: MenuView.list_grid, item: EnumMenuItem.button, - entries: MenuEntry.getEntriesByType( - MenuEntryType.Home), + entries: MenuEntry.getEntriesByType(MenuEntryType.Home), )..add(MenuEvent()), ), BlocProvider( create: (context) => HomeBloc()..add(HomeEvent()), ), BlocProvider( - create: (context) => - LocalProfileBloc()..add(LocalProfileEvent()), + create: (context) => LocalProfileBloc()..add(LocalProfileEvent()), ), ], - child: HomePageWidget( - key: UniqueKey(), LocalsRepositoryImpl().update), + child: HomePageWidget(key: UniqueKey(), LocalsRepositoryImpl().update), ) : const ReceptionPageWidget(); } else { @@ -146,10 +134,8 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { name: 'forgotPassword', path: '/forgotPassword', builder: (context, params) { - late final String email = - params.getParam('email', ParamType.String); - late final String token = - params.getParam('token', ParamType.String); + late final String email = params.getParam('email', ParamType.String); + late final String token = params.getParam('token', ParamType.String); return ForgotPasswordScreen( key: UniqueKey(), @@ -166,8 +152,7 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { name: 'homePage', path: '/homePage', builder: (context, params) { - final Future Function(BuildContext context)? update = - params.getParam('update', ParamType.Function); + final Future Function(BuildContext context)? update = params.getParam('update', ParamType.Function); return MultiBlocProvider( providers: [ BlocProvider( @@ -181,8 +166,7 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { create: (context) => HomeBloc()..add(HomeEvent()), ), BlocProvider( - create: (context) => - LocalProfileBloc()..add(LocalProfileEvent()), + create: (context) => LocalProfileBloc()..add(LocalProfileEvent()), ), ], child: HomePageWidget(key: UniqueKey(), update), @@ -191,16 +175,12 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { FFRoute( name: 'petsOnThePropertyPage', path: '/petsOnThePropertyPage', - builder: (context, params) => - Scaffold(body: const PetsHistoryScreen(isApp: true))), + builder: (context, params) => Scaffold(body: const PetsHistoryScreen(isApp: true))), FFRoute( name: 'vehiclesOnThePropertyPage', path: '/vehiclesOnThePropertyPage', - builder: (context, params) => const VehicleOnTheProperty()), - FFRoute( - name: 'receptionPage', - path: '/receptionPage', - builder: (context, params) => const ReceptionPageWidget()), + builder: (context, params) => const VehiclePage()), + FFRoute(name: 'receptionPage', path: '/receptionPage', builder: (context, params) => const ReceptionPageWidget()), FFRoute( name: 'messageHistoryPage', path: '/messageHistoryPage', @@ -212,28 +192,19 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { FFRoute( name: 'scheduleCompleteVisitPage', path: '/scheduleCompleteVisitPage', - builder: (context, params) => - const ScheduleCompleteVisitPageWidget()), + builder: (context, params) => const ScheduleCompleteVisitPageWidget()), FFRoute( - name: 'deliverySchedule', - path: '/deliverySchedule', - builder: (context, params) => const DeliverySchedule()), + name: 'deliverySchedule', path: '/deliverySchedule', builder: (context, params) => const DeliverySchedule()), FFRoute( name: 'provisionalSchedule', path: '/provisionalSchedule', builder: (context, params) => const ProvisionalSchedule()), - FFRoute( - name: 'fastPassPage', - path: '/fastPassPage', - builder: (context, params) => FastPassPageWidget()), + FFRoute(name: 'fastPassPage', path: '/fastPassPage', builder: (context, params) => FastPassPageWidget()), FFRoute( name: 'preferencesSettings', path: '/preferencesSettings', builder: (context, params) => PreferencesPageWidget()), - FFRoute( - name: 'aboutProperty', - path: '/aboutProperty', - builder: (context, params) => AboutPropertyPage()), + FFRoute(name: 'aboutProperty', path: '/aboutProperty', builder: (context, params) => AboutPropertyPage()), FFRoute( name: 'residentsOnThePropertyPage', path: '/residentsOnThePropertyPage', @@ -249,11 +220,8 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { FFRoute( name: 'acessHistoryPage', path: '/acessHistoryPage', - builder: (context, params) => AccessHistoryScreen(opt: const { - 'personType': '.*', - 'accessType': '.*', - 'search': '.*' - })), + builder: (context, params) => + AccessHistoryScreen(opt: const {'personType': '.*', 'accessType': '.*', 'search': '.*'})), FFRoute( name: 'provisionalHistoryPage', path: '/provisionalHistoryPage', @@ -262,34 +230,13 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { name: 'liberationHistory', path: '/liberationHistory', builder: (context, params) => const LiberationHistoryWidget()), - FFRoute( - name: 'signInPage', - path: '/signInPage', - builder: (context, params) => const SignInPageWidget()), - FFRoute( - name: 'signUpPage', - path: '/signUpPage', - builder: (context, params) => const SignUpPageWidget()), - FFRoute( - name: 'welcomePage', - path: '/welcomePage', - builder: (context, params) => const WelcomePage()), - FFRoute( - name: 'qrCodePage', - path: '/qrCodePage', - builder: (context, params) => const QrCodePageWidget()), - FFRoute( - name: 'preferencesPage', - path: '/preferencesPage', - builder: (context, params) => PreferencesPageWidget()), - FFRoute( - name: 'packageOrder', - path: '/packageOrder', - builder: (context, params) => const PackageOrderPage()), - FFRoute( - name: 'reservation', - path: '/reservation', - builder: (context, params) => ReservationPageWidget()), + FFRoute(name: 'signInPage', path: '/signInPage', builder: (context, params) => const SignInPageWidget()), + FFRoute(name: 'signUpPage', path: '/signUpPage', builder: (context, params) => const SignUpPageWidget()), + FFRoute(name: 'welcomePage', path: '/welcomePage', builder: (context, params) => const WelcomePage()), + FFRoute(name: 'qrCodePage', path: '/qrCodePage', builder: (context, params) => const QrCodePageWidget()), + FFRoute(name: 'preferencesPage', path: '/preferencesPage', builder: (context, params) => PreferencesPageWidget()), + FFRoute(name: 'packageOrder', path: '/packageOrder', builder: (context, params) => const PackageOrderPage()), + FFRoute(name: 'reservation', path: '/reservation', builder: (context, params) => ReservationPageWidget()), FFRoute( name: 'petsPage', path: '/petsPage', @@ -305,9 +252,7 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { extension NavParamExtensions on Map { Map get withoutNulls => Map.fromEntries( - entries - .where((e) => e.value != null) - .map((e) => MapEntry(e.key, e.value!)), + entries.where((e) => e.value != null).map((e) => MapEntry(e.key, e.value!)), ); } @@ -321,8 +266,7 @@ extension NavigationExtensions on BuildContext { } extension _GoRouterStateExtensions on GoRouterState { - Map get extraMap => - extra != null ? extra as Map : {}; + Map get extraMap => extra != null ? extra as Map : {}; Map get allParams => {} ..addAll(pathParameters) ..addAll(uri.queryParameters) @@ -335,9 +279,8 @@ extension _GoRouterStateExtensions on GoRouterState { extension GoRouterLocationExtension on GoRouter { String getCurrentLocation() { final RouteMatch lastMatch = routerDelegate.currentConfiguration.last; - final RouteMatchList matchList = lastMatch is ImperativeRouteMatch - ? lastMatch.matches - : routerDelegate.currentConfiguration; + final RouteMatchList matchList = + lastMatch is ImperativeRouteMatch ? lastMatch.matches : routerDelegate.currentConfiguration; return matchList.uri.toString(); } } @@ -350,17 +293,13 @@ class FFParameters { Map futureParamValues = {}; bool get isEmpty => - state.allParams.isEmpty || - (state.allParams.length == 1 && - state.extraMap.containsKey(kTransitionInfoKey)); - bool isAsyncParam(MapEntry param) => - asyncParams.containsKey(param.key) && param.value is String; + state.allParams.isEmpty || (state.allParams.length == 1 && state.extraMap.containsKey(kTransitionInfoKey)); + bool isAsyncParam(MapEntry param) => asyncParams.containsKey(param.key) && param.value is String; bool get hasFutures => state.allParams.entries.any(isAsyncParam); Future completeFutures() => Future.wait( state.allParams.entries.where(isAsyncParam).map( (param) async { - final doc = await asyncParams[param.key]!(param.value) - .onError((_, __) => null); + final doc = await asyncParams[param.key]!(param.value).onError((_, __) => null); if (doc != null) { futureParamValues[param.key] = doc; return true; @@ -370,15 +309,12 @@ class FFParameters { ), ).onError((_, __) => [false]).then((v) => v.every((e) => e)); - dynamic getParam(String paramName, ParamType type, - {bool isList = false, StructBuilder? structBuilder}) { - if (futureParamValues.containsKey(paramName)) - return futureParamValues[paramName]; + dynamic getParam(String paramName, ParamType type, {bool isList = false, StructBuilder? structBuilder}) { + if (futureParamValues.containsKey(paramName)) return futureParamValues[paramName]; if (!state.allParams.containsKey(paramName)) return null; final param = state.allParams[paramName]; if (param is! String) return param; - return deserializeParam(param, type, isList, - structBuilder: structBuilder); + return deserializeParam(param, type, isList, structBuilder: structBuilder); } } @@ -418,16 +354,13 @@ class FFRoute { key: state.pageKey, child: child, transitionDuration: transitionInfo.duration, - transitionsBuilder: - (context, animation, secondaryAnimation, child) => - PageTransition( + transitionsBuilder: (context, animation, secondaryAnimation, child) => PageTransition( type: transitionInfo.transitionType, duration: transitionInfo.duration, reverseDuration: transitionInfo.duration, alignment: transitionInfo.alignment, child: child, - ).buildTransitions( - context, animation, secondaryAnimation, child), + ).buildTransitions(context, animation, secondaryAnimation, child), ) : MaterialPage(key: state.pageKey, child: child); }, @@ -448,8 +381,7 @@ class TransitionInfo { final Duration duration; final Alignment? alignment; - static TransitionInfo appDefault() => - const TransitionInfo(hasTransition: false); + static TransitionInfo appDefault() => const TransitionInfo(hasTransition: false); } class RootPageContext { @@ -461,9 +393,7 @@ class RootPageContext { final rootPageContext = context.read(); final isRootPage = rootPageContext?.isRootPage ?? false; final location = GoRouterState.of(context).uri.toString(); - return isRootPage && - location != '/' && - location != rootPageContext?.errorRoute; + return isRootPage && location != '/' && location != rootPageContext?.errorRoute; } static Widget wrap(Widget child, {String? errorRoute}) => diff --git a/lib/main.dart b/lib/main.dart index 03c6b70d..8db0f7c8 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -54,8 +54,7 @@ class App extends StatefulWidget { @override State createState() => _AppState(); - static _AppState of(BuildContext context) => - context.findAncestorStateOfType<_AppState>()!; + static _AppState of(BuildContext context) => context.findAncestorStateOfType<_AppState>()!; } class _AppState extends State { @@ -97,8 +96,7 @@ class _AppState extends State { }), ), ); - final Iterable>? localizationsDelegates = - const [ + final Iterable>? localizationsDelegates = const [ FFLocalizationsDelegate(), GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, @@ -140,8 +138,7 @@ class _AppState extends State { await StorageHelper().set(SecureStorageKey.haveLocal.value, true); log('onMessageOpenedApp'); } else { - onMessageReceived(message.data, message.notification!.body, - message.data['click_action']); + onMessageReceived(message.data, message.notification!.body, message.data['click_action']); } }); FirebaseMessaging.instance.getInitialMessage().then((message) async { @@ -175,9 +172,7 @@ class _AppState extends State { _router = createRouter(_appStateNotifier); Future.delayed( const Duration(milliseconds: 1000), - () => mounted - ? setState(() => _appStateNotifier.stopShowingSplashImage()) - : null, + () => mounted ? setState(() => _appStateNotifier.stopShowingSplashImage()) : null, ); _setupFirebaseMessaging(); diff --git a/lib/pages/pets_page/pets_page_model.dart b/lib/pages/pets_page/pets_page_model.dart index e7de27fe..b24db31b 100644 --- a/lib/pages/pets_page/pets_page_model.dart +++ b/lib/pages/pets_page/pets_page_model.dart @@ -504,6 +504,7 @@ class PetsPageModel extends FlutterFlowModel { ); }); }); + }, options: FFButtonOptions( height: 40, diff --git a/lib/pages/pets_page/pets_page_widget.dart b/lib/pages/pets_page/pets_page_widget.dart index 8816c468..a2aae357 100644 --- a/lib/pages/pets_page/pets_page_widget.dart +++ b/lib/pages/pets_page/pets_page_widget.dart @@ -1049,4 +1049,6 @@ class _PetsPageWidgetState extends State ), ); } + + } diff --git a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart new file mode 100644 index 00000000..0e496a76 --- /dev/null +++ b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart @@ -0,0 +1,220 @@ +part of 'vehicles_on_the_property.dart'; + +/// [VehicleHistoryScreen] is a StatefulWidget that displays a list of vehicles. + +// ignore: must_be_immutable +class VehicleHistoryScreen extends StatefulWidget { + VehicleHistoryScreen(this.model, {super.key}); + late VehicleModel model; + + @override + State createState() => _VehicleHistoryScreenState(); +} + +class _VehicleHistoryScreenState extends State { + late Future _future = _fetchVisits(); + late ScrollController _scrollController; + List _wrap = []; + int _pageNumber = 1; + bool _hasData = false; + bool _loading = false; + int count = 0; + + @override + void initState() { + super.initState(); + + // widget.model = createModel(context, () => VehicleModel()); + _future = _fetchVisits(); + _scrollController = ScrollController() + ..addListener(() { + if (_scrollController.position.atEdge && _scrollController.position.pixels != 0) { + _loadMore(); + } + }); + } + + void _showNoMoreDataSnackBar(BuildContext context) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + FFLocalizations.of(context).getVariableText( + ptText: "Não há mais dados.", + enText: "No more data.", + ), + style: TextStyle( + color: Colors.white, + fontSize: LimitedFontSizeUtil.getBodyFontSize(context), + ), + ), + duration: const Duration(seconds: 3), + backgroundColor: FlutterFlowTheme.of(context).primary, + ), + ); + } + + String getRandomStatus() { + var statuses = ['ATI', 'INA', 'APR_CREATE', 'APR_DELETE', 'APR_UPDATE', 'AGU_CHANGE']; + statuses.shuffle(); + return statuses.first; + } + + Widget _item(BuildContext context, Map uItem) { + uItem['status'] = getRandomStatus(); + return CardItemTemplateComponentWidget( + imagePath: null, + labelsHashMap: { + '${FFLocalizations.of(context).getVariableText(ptText: "Placa", enText: "License Plate")}:': + uItem['licensePlate'] ?? '', + '${FFLocalizations.of(context).getVariableText(ptText: "Modelo", enText: "Model")}:': uItem['model'] ?? '', + '${FFLocalizations.of(context).getVariableText(ptText: "Tag", enText: "Tag")}:': uItem['tag'] ?? '', + }, + statusHashMap: [widget.model.generateStatusColorMap(uItem)], + onTapCardItemAction: () async { + await showDialog( + useSafeArea: true, + context: context, + builder: (context) { + return Dialog( + alignment: Alignment.center, + child: widget.model.buildVehicleDetails( + item: uItem, + context: context, + model: widget.model, + )); + }, + ).whenComplete(() { + safeSetState(() { + _pageNumber = 1; + _wrap = []; + _future = _fetchVisits().then((value) => value!.jsonBody['vehicles'] ?? []); + }); + }).catchError((e, s) { + DialogUtil.errorDefault(context); + LogUtil.requestAPIFailed("proccessRequest.php", "", "Consulta de Veículos", e, s); + safeSetState(() { + _hasData = false; + _loading = false; + }); + }); + }, + ); + } + + Future _fetchVisits() async { + try { + setState(() => _loading = true); + + var response = await PhpGroup.getVehiclesByProperty.call(_pageNumber.toString()); + + final List vehicles = response.jsonBody['vehicles'] ?? []; + safeSetState(() => count = response.jsonBody['total_rows'] ?? 0); + + if (vehicles.isNotEmpty) { + setState(() { + _wrap.addAll(vehicles); + _hasData = true; + _loading = false; + }); + + return response; + } + + _showNoMoreDataSnackBar(context); + + setState(() { + _hasData = false; + _loading = false; + }); + + return null; + } catch (e, s) { + DialogUtil.errorDefault(context); + LogUtil.requestAPIFailed("proccessRequest.php", "", "Consulta de Veículo", e, s); + setState(() { + _hasData = false; + _loading = false; + }); + } + return null; + } + + void _loadMore() { + if (_hasData == true) { + _pageNumber++; + + _future = _fetchVisits(); + } + } + + @override + Widget build(BuildContext context) { + late final limitedHeaderTextSize = LimitedFontSizeUtil.getHeaderFontSize(context); + + return Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + if (_hasData == false && _pageNumber <= 1 && _loading == false) + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.max, + children: [ + Center( + child: Text( + FFLocalizations.of(context).getVariableText( + ptText: "Nenhum veículo encontrado!", + enText: "No vehicle found", + ), + style: TextStyle( + fontFamily: 'Nunito', + fontSize: limitedHeaderTextSize, + ), + ), + ) + ], + ), + ) + else if (_hasData == true || _pageNumber >= 1) + Expanded( + child: FutureBuilder( + future: _future, + builder: (context, snapshot) { + return ListView.builder( + shrinkWrap: true, + physics: const BouncingScrollPhysics(), + controller: _scrollController, + itemCount: _wrap.length + 1, + itemBuilder: (context, index) { + if (index == 0) { + // Add your item here + return Padding( + padding: const EdgeInsets.only(right: 30, top: 10), + child: Text( + '', + textAlign: TextAlign.right, + ), + ); + } else { + Map item = _wrap[index - 1]; + return _item(context, item); + } + }); + }, + )), + if (_hasData == true && _loading == true) + Container( + padding: const EdgeInsets.only(top: 15, bottom: 15), + child: Center( + child: CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation( + FlutterFlowTheme.of(context).primary, + ), + ), + ), + ) + ].addToStart(const SizedBox(height: 0)), + ); + } +} diff --git a/lib/pages/vehicles_on_the_property/vehicle_model.dart b/lib/pages/vehicles_on_the_property/vehicle_model.dart index 826095f5..78d5fbaf 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_model.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_model.dart @@ -1,54 +1,447 @@ import 'package:flutter/material.dart'; import 'package:hub/components/templates_components/details_component/details_component_widget.dart'; -import 'package:hub/flutter_flow/flutter_flow_model.dart'; -import 'package:hub/flutter_flow/internationalization.dart'; +import 'package:hub/features/backend/index.dart'; +import 'package:hub/flutter_flow/index.dart'; import 'package:hub/pages/vehicles_on_the_property/vehicles_on_the_property.dart'; +import 'package:hub/shared/utils/index.dart'; + +class VehicleModel extends FlutterFlowModel { + @override + void initState(BuildContext context) { + resetInstance(); + initAsync(); + tabBarController = TabController( + vsync: Navigator.of(context), + length: 2, + ); + + textFieldFocusLicensePlate = FocusNode(); + textFieldControllerLicensePlate = TextEditingController(); + + textFieldFocusColor = FocusNode(); + textFieldControllerColor = TextEditingController(); + + textFieldFocusModel = FocusNode(); + textFieldControllerModel = TextEditingController(); + } + + @override + void dispose() { + tabBarController.dispose(); + textFieldFocusLicensePlate!.dispose(); + textFieldControllerLicensePlate!.dispose(); + textFieldFocusColor!.dispose(); + textFieldControllerColor!.dispose(); + textFieldFocusModel!.dispose(); + textFieldControllerModel!.dispose(); + } -class VehicleModel extends FlutterFlowModel { static VehicleModel? _instance = VehicleModel._internal(); VehicleModel._internal(); factory VehicleModel() => _instance ?? VehicleModel._internal(); static void resetInstance() => _instance = null; dynamic item; + String? vehicleId; - @override - void initState(BuildContext context) { - resetInstance(); + late final TabController tabBarController; + VoidCallback? onUpdateVehicle; + VoidCallback? onRegisterVehicle; + VoidCallback? safeSetState; - initAsync(); + final GlobalKey registerFormKey = GlobalKey(); + final GlobalKey updateFormKey = GlobalKey(); + + ApiCallResponse? vehicleResponse; + bool isEditing = false; + BuildContext context = navigatorKey.currentContext!; + + FocusNode? textFieldFocusLicensePlate; + TextEditingController? textFieldControllerLicensePlate; + String? textControllerLicensePlateValidator(BuildContext context, String? value) { + if (value == null || value.isEmpty) { + return FFLocalizations.of(context).getVariableText( + ptText: 'Placa é obrigatória', + enText: 'License Plate is required', + ); + } + + // (ABC-1234) + final brazilianPlateRegex = RegExp(r'^[A-Z]{3}-\d{4}$'); + // (ABC1D23) + final mercosurPlateRegex = RegExp(r'^[A-Z]{3}\d[A-Z]\d{2}$'); + + if (!brazilianPlateRegex.hasMatch(value) && !mercosurPlateRegex.hasMatch(value)) { + return FFLocalizations.of(context).getVariableText( + ptText: 'Placa inválida', + enText: 'Invalid license plate', + ); + } + + return null; } - @override - void dispose() {} + FocusNode? textFieldFocusColor; + TextEditingController? textFieldControllerColor; + String? textControllerColorValidator(BuildContext contexnt, String? value) { + if (value == null || value.isEmpty) { + return FFLocalizations.of(context).getVariableText( + ptText: 'Cor é obrigatória', + enText: 'Color is required', + ); + } + return null; + } + + FocusNode? textFieldFocusModel; + TextEditingController? textFieldControllerModel; + String? textControllerModelValidator(BuildContext contexnt, String? value) { + if (value == null || value.isEmpty) { + return FFLocalizations.of(context).getVariableText( + ptText: 'Modelo é obrigatório', + enText: 'Model is required', + ); + } + return null; + } Future initAsync() async {} + Map generateStatusColorMap(dynamic uItem) { + final statusMap = { + "ATI": { + "text": FFLocalizations.of(context).getVariableText( + ptText: 'Ativo', + enText: 'Active', + ), + "color": FlutterFlowTheme.of(context).success, + }, + "INA": { + "text": FFLocalizations.of(context).getVariableText( + ptText: 'Inativo', + enText: 'Inactive', + ), + "color": FlutterFlowTheme.of(context).accent2, + }, + "APR_CREATE": { + "text": FFLocalizations.of(context).getVariableText( + ptText: 'Criando', + enText: 'Creating', + ), + "color": FlutterFlowTheme.of(context).success, + }, + "APR_DELETE": { + "text": FFLocalizations.of(context).getVariableText( + ptText: 'Deletando', + enText: 'Deleting', + ), + "color": FlutterFlowTheme.of(context).error, + }, + "APR_UPDATE": { + "text": FFLocalizations.of(context).getVariableText( + ptText: 'Atualizando', + enText: 'Updating', + ), + "color": FlutterFlowTheme.of(context).warning, + }, + "AGU_CHANGE": { + "text": FFLocalizations.of(context).getVariableText( + ptText: 'Aguardando', + enText: 'Waiting', + ), + "color": FlutterFlowTheme.of(context).accent2, + }, + }; + + final status = uItem['status']; + if (statusMap.containsKey(status)) { + return { + statusMap[status]!['text'] as String: statusMap[status]!['color'] as Color, + }; + } + return {}; + } + + List generateActionButtons(dynamic item) { + final Color iconButtonColor = FlutterFlowTheme.of(context).primaryText; + final FFButtonOptions buttonOptions = FFButtonOptions( + height: 40, + color: FlutterFlowTheme.of(context).primaryBackground, + elevation: 0, + textStyle: TextStyle( + color: FlutterFlowTheme.of(context).primaryText, + fontSize: LimitedFontSizeUtil.getNoResizeFont(context, 15), + ), + splashColor: FlutterFlowTheme.of(context).success, + borderSide: BorderSide( + color: FlutterFlowTheme.of(context).primaryBackground, + width: 1, + ), + ); + + return [ + if (item['status'].contains('AGU')) + FFButtonWidget( + text: FFLocalizations.of(context).getVariableText( + ptText: 'Editar', + enText: 'Edit', + ), + icon: Icon( + Icons.close, + color: iconButtonColor, + ), + onPressed: () async { + context.pop(); + isEditing = true; + item = item; + + switchTab(1); + setEditForm(); + }, + options: buttonOptions, + ), + if (item['status'].contains('APR') || item['status'].contains('AGU')) + FFButtonWidget( + text: FFLocalizations.of(context).getVariableText( + ptText: 'Cancelar', + enText: 'Cancel', + ), + icon: Icon(Icons.close, color: iconButtonColor), + onPressed: () async { + showAlertDialog( + context, + FFLocalizations.of(context).getVariableText( + ptText: 'Cancelar Solicitação', + enText: 'Cancel Request', + ), + FFLocalizations.of(context).getVariableText( + ptText: 'Você tem certeza que deseja cancelar essa solicitação?', + enText: 'Are you sure you want to delete this request?', + ), () async { + int id = item['vehicleId']; + await PhpGroup.deleteVehicle.call(vehicleId: id).then((value) { + context.pop(value); + context.pop(value); + + if (value.jsonBody['error'] == false) { + showSnackbar( + context, + FFLocalizations.of(context).getVariableText( + ptText: 'Erro ao cancelar solicitação', + enText: 'Error canceling request', + ), + true, + ); + } else if (value.jsonBody['error'] == true) { + showSnackbar( + context, + FFLocalizations.of(context).getVariableText( + enText: 'Success canceling request', + ptText: 'Succeso ao cancelar solicitação', + ), + false, + ); + } + }).catchError((err, stack) { + context.pop(); + showSnackbar( + context, + FFLocalizations.of(context).getVariableText( + enText: 'Error canceling request', + ptText: 'Erro ao cancelar solicitação', + ), + true, + ); + }); + }); + }, + options: buttonOptions, + ), + if (item['status'].contains('ATI')) + FFButtonWidget( + text: FFLocalizations.of(context).getVariableText( + ptText: 'Excluir', + enText: 'Delete', + ), + icon: Icon( + Icons.close, + color: iconButtonColor, + ), + onPressed: () async { + showAlertDialog( + context, + FFLocalizations.of(context).getVariableText( + ptText: 'Excluir Veículo', + enText: 'Delete Vehicle', + ), + FFLocalizations.of(context).getVariableText( + ptText: 'Você tem certeza que deseja excluir esse veículo?', + enText: 'Are you sure you want to delete this vehicle?', + ), () async { + int id = item['vehicleId']; + await PhpGroup.deleteVehicle.call(vehicleId: id).then((value) { + context.pop(value); + context.pop(value); + + if (value == false) { + showSnackbar( + context, + FFLocalizations.of(context).getVariableText( + ptText: 'Erro ao excluir veículo', + enText: 'Error deleting vehicle', + ), + true, + ); + } else if (value == true) { + showSnackbar( + context, + FFLocalizations.of(context).getVariableText( + enText: 'Success deleting vehicle', + ptText: 'Succeso ao excluir veículo', + ), + false, + ); + } + }).catchError((err, stack) { + context.pop(); + showSnackbar( + context, + FFLocalizations.of(context).getVariableText( + enText: 'Error deleting vehicle', + ptText: 'Erro ao excluir veículo', + ), + true, + ); + }); + }); + }, + options: buttonOptions, + ), + ]; + } + + Map generateLabelsHashMap(dynamic item) { + return { + if (item['model'] != null && item['model'] != '') + '${FFLocalizations.of(context).getVariableText(ptText: "Modelo", enText: "Model")}:': + item['model'].toString().toUpperCase(), + if (item['licensePlate'] != null && item['licensePlate'] != '') + '${FFLocalizations.of(context).getVariableText(ptText: "Placa", enText: "License Plate")}:': + item['licensePlate'].toString().toUpperCase(), + if (item['color'] != null && item['color'] != '') + '${FFLocalizations.of(context).getVariableText(ptText: "Cor", enText: "Color")}:': + item['color'].toString().toUpperCase(), + if (item['personName'] != null && item['personName'] != '') + '${FFLocalizations.of(context).getVariableText(ptText: "Proprietário", enText: "Owner")}:': + item['personName'].toString().toUpperCase(), + if (item['tag'] != null && item['tag'] != '') + '${FFLocalizations.of(context).getVariableText(ptText: "Tag", enText: "Tag")}:': + item['tag'].toString().toUpperCase(), + }; + } + Widget buildVehicleDetails({ required dynamic item, required BuildContext context, required VehicleModel model, }) { + final status = generateStatusColorMap(item); + final buttons = generateActionButtons(item); + final labels = generateLabelsHashMap(item); return DetailsComponentWidget( - buttons: [], - labelsHashMap: Map.from({ - if (item['model'] != null && item['model'] != '') - '${FFLocalizations.of(context).getVariableText(ptText: "Modelo", enText: "Model")}:': - item['model'].toString().toUpperCase(), - if (item['licensePlate'] != null && item['licensePlate'] != '') - '${FFLocalizations.of(context).getVariableText(ptText: "Placa", enText: "License Plate")}:': - item['licensePlate'].toString().toUpperCase(), - if (item['color'] != null && item['color'] != '') - '${FFLocalizations.of(context).getVariableText(ptText: "Cor", enText: "Color")}:': - item['color'].toString().toUpperCase(), - if (item['personName'] != null && item['personName'] != '') - '${FFLocalizations.of(context).getVariableText(ptText: "Proprietário", enText: "Owner")}:': - item['personName'].toString().toUpperCase(), - if (item['tag'] != null && item['tag'] != '') - '${FFLocalizations.of(context).getVariableText(ptText: "Tag", enText: "Tag")}:': - item['tag'].toString().toUpperCase(), - }), - statusHashMap: [], + buttons: buttons, + labelsHashMap: labels, + statusHashMap: [status], ); } + + void setEditForm() { + if (item != null) { + vehicleId = item['vehicleId']; + textFieldControllerLicensePlate!.text = item['licensePlate']; + textFieldControllerColor!.text = item['color']; + textFieldControllerModel!.text = item['model']; + } + } + + bool isFormValid(BuildContext context) { + if (registerFormKey.currentState == null) return false; + return registerFormKey.currentState!.validate(); + } + + Future updateVehicle() async { + final response = await PhpGroup.updateVehicle.call( + licensePlate: textFieldControllerLicensePlate!.text, + color: textFieldControllerColor!.text, + model: textFieldControllerModel!.text, + vehicleId: vehicleId!, + ); + if (response.jsonBody['error'] == false) { + await DialogUtil.success( + context, + FFLocalizations.of(context).getVariableText( + ptText: 'Veículo atualizado com sucesso', + enText: 'Vehicle updated successfully', + )).then((_) async { + switchTab(0); + }); + } else { + String errorMessage; + try { + errorMessage = response.jsonBody['message']; + } catch (e) { + errorMessage = FFLocalizations.of(context).getVariableText( + ptText: 'Erro ao atualizar veículo', + enText: 'Error updating vehicle', + ); + } + await DialogUtil.error(context, errorMessage); + } + } + + Future registerVehicle() async { + final response = await PhpGroup.registerVehicle.call( + licensePlate: textFieldControllerLicensePlate!.text, + color: textFieldControllerColor!.text, + model: textFieldControllerModel!.text, + ); + if (response.jsonBody['error'] == false) { + await DialogUtil.success( + context, + FFLocalizations.of(context).getVariableText( + ptText: 'Veículo cadastrado com sucesso', + enText: 'Vehicle registered successfully', + )).then((_) async { + switchTab(0); + }); + } else { + String errorMessage; + try { + errorMessage = response.jsonBody['message']; + } catch (e) { + errorMessage = FFLocalizations.of(context).getVariableText( + ptText: 'Erro ao cadastrar veículo', + enText: 'Error registering vehicle', + ); + } + await DialogUtil.error(context, errorMessage); + } + } + + void switchTab(int index) { + tabBarController.animateTo(index); + if (index == 0) handleEditingChanged(false); + safeSetState?.call(); + } + + void clearFields() async { + textFieldControllerLicensePlate!.clear(); + textFieldControllerColor!.clear(); + textFieldControllerModel!.clear(); + } + + void handleEditingChanged(bool editing) { + isEditing = editing; + clearFields(); + } } diff --git a/lib/pages/vehicles_on_the_property/vehicle_register_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_register_screen.dart new file mode 100644 index 00000000..b6dd5004 --- /dev/null +++ b/lib/pages/vehicles_on_the_property/vehicle_register_screen.dart @@ -0,0 +1,102 @@ +part of 'vehicles_on_the_property.dart'; + +/// [VehicleRegisterScreen] is a StatefulWidget that displays a form to register a vehicle. + +// ignore: must_be_immutable +class VehicleRegisterScreen extends StatefulWidget { + VehicleRegisterScreen(this.model, {super.key}); + late VehicleModel model; + + @override + State createState() => _VehicleRegisterScreenState(); +} + +class _VehicleRegisterScreenState extends State { + @override + Widget build(BuildContext context) { + double limitedInputFontSize = LimitedFontSizeUtil.getInputFontSize(context); + double limitedHeaderFontSize = LimitedFontSizeUtil.getHeaderFontSize(context); + double limitedSubHeaderFontSize = LimitedFontSizeUtil.getSubHeaderFontSize(context); + + return SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Align( + alignment: const AlignmentDirectional(-1.0, 0.0), + child: Padding( + padding: const EdgeInsetsDirectional.fromSTEB(24.0, 20, 0.0, 15), + child: Text( + FFLocalizations.of(context).getVariableText( + ptText: 'Preencha o formulário de cadastro com os dados do seu veículo', + enText: 'Fill out the registration form with your vehicle data', + ), + textAlign: TextAlign.start, + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).bodyMediumFamily), + fontSize: limitedHeaderFontSize, + ), + ), + ), + ), + Form( + key: widget.model.registerFormKey, + autovalidateMode: AutovalidateMode.onUserInteraction, + child: Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + CustomInputUtil( + controller: widget.model.textFieldControllerLicensePlate, + validator: widget.model.textControllerLicensePlateValidator.asValidator(context), + focusNode: widget.model.textFieldFocusLicensePlate, + labelText: FFLocalizations.of(context).getVariableText(ptText: 'Placa', enText: 'License Plate'), + hintText: FFLocalizations.of(context).getVariableText(ptText: 'Placa', enText: 'License Plate'), + suffixIcon: Symbols.format_color_text, + haveMaxLength: true, + onChanged: (value) => setState(() {}), + maxLength: 80, + ), + CustomInputUtil( + controller: widget.model.textFieldControllerModel, + validator: widget.model.textControllerModelValidator.asValidator(context), + focusNode: widget.model.textFieldFocusModel, + labelText: FFLocalizations.of(context).getVariableText(ptText: 'Modelo', enText: 'Model'), + hintText: FFLocalizations.of(context).getVariableText( + ptText: 'Ex: Voyage, Ford', + enText: 'e.g. Voyage, Ford', + ), + suffixIcon: Symbols.car_repair, + haveMaxLength: true, + onChanged: (value) => setState(() {}), + maxLength: 80, + ), + CustomInputUtil( + controller: widget.model.textFieldControllerColor, + validator: widget.model.textControllerColorValidator.asValidator(context), + focusNode: widget.model.textFieldFocusColor, + labelText: FFLocalizations.of(context).getVariableText(ptText: 'Cor', enText: 'Color'), + hintText: FFLocalizations.of(context).getVariableText( + ptText: 'Ex: Preto, Amarelo, Branco', + enText: 'e.g. Black, Yellow, White', + ), + suffixIcon: Symbols.palette, + haveMaxLength: true, + onChanged: (value) => setState(() {}), + maxLength: 80, + ), + Padding( + padding: const EdgeInsets.fromLTRB(70, 20, 70, 30), + child: SubmitButtonUtil( + labelText: FFLocalizations.of(context).getVariableText(ptText: 'Cadastrar', enText: 'Register'), + onPressed: widget.model.isFormValid(context) ? widget.model.registerVehicle : null), + ), + ], + )), + ], + ), + ); + } +} diff --git a/lib/pages/vehicles_on_the_property/vehicle_update_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_update_screen.dart new file mode 100644 index 00000000..a9293149 --- /dev/null +++ b/lib/pages/vehicles_on_the_property/vehicle_update_screen.dart @@ -0,0 +1,103 @@ +part of 'vehicles_on_the_property.dart'; + +/// [VehicleUpdateScreen] is a StatefulWidget that displays a form to update a vehicle. + +// ignore: must_be_immutable +class VehicleUpdateScreen extends StatefulWidget { + VehicleUpdateScreen(this.model, {super.key}); + late VehicleModel model; + + @override + State createState() => _VehicleUpdateScreenState(); +} + +class _VehicleUpdateScreenState extends State { + @override + Widget build(BuildContext context) { + return SingleChildScrollView( + child: Column( + mainAxisSize: MainAxisSize.max, + children: [ + Align( + alignment: const AlignmentDirectional(-1.0, 0.0), + child: Padding( + padding: const EdgeInsetsDirectional.fromSTEB(24.0, 20, 0.0, 15), + child: Text( + FFLocalizations.of(context).getVariableText( + ptText: 'Preencha o formulário de alteração com os dados do seu veículo', + enText: 'Fill out the update form with your vehicle data', + ), + textAlign: TextAlign.start, + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).bodyMediumFamily), + ), + ), + ), + ), + Form( + key: widget.model.updateFormKey, + autovalidateMode: AutovalidateMode.onUserInteraction, + child: Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + CustomInputUtil( + controller: widget.model.textFieldControllerLicensePlate, + validator: widget.model.textControllerLicensePlateValidator.asValidator(context), + focusNode: widget.model.textFieldFocusLicensePlate, + labelText: FFLocalizations.of(context).getVariableText(ptText: 'Placa', enText: 'License Plate'), + hintText: FFLocalizations.of(context).getVariableText(ptText: 'Placa', enText: 'License Plate'), + suffixIcon: Symbols.format_color_text, + haveMaxLength: true, + onChanged: (value) => setState(() {}), + maxLength: 80, + ), + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 15), + child: CustomInputUtil( + controller: widget.model.textFieldControllerModel, + validator: widget.model.textControllerModelValidator.asValidator(context), + focusNode: widget.model.textFieldFocusModel, + labelText: FFLocalizations.of(context).getVariableText(ptText: 'Modelo', enText: 'Model'), + hintText: FFLocalizations.of(context).getVariableText( + ptText: 'Ex: Voyage, Ford', + enText: 'e.g. Voyage, Ford', + ), + suffixIcon: Icons.car_repair, + haveMaxLength: true, + onChanged: (value) => setState(() {}), + maxLength: 80, + ), + ), + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 15), + child: CustomInputUtil( + controller: widget.model.textFieldControllerColor, + validator: widget.model.textControllerColorValidator.asValidator(context), + focusNode: widget.model.textFieldFocusColor, + labelText: FFLocalizations.of(context).getVariableText(ptText: 'Cor', enText: 'Color'), + hintText: FFLocalizations.of(context).getVariableText( + ptText: 'Ex: Preto, Amarelo, Branco', + enText: 'e.g. Black, Yellow, White', + ), + suffixIcon: Icons.pets_outlined, + haveMaxLength: true, + onChanged: (value) => setState(() {}), + maxLength: 80, + ), + ), + Padding( + padding: const EdgeInsets.fromLTRB(70, 20, 70, 30), + child: SubmitButtonUtil( + labelText: FFLocalizations.of(context).getVariableText(ptText: 'Salvar', enText: 'Save'), + onPressed: widget.model.isFormValid(context) ? widget.model.updateVehicle : null), + ), + ], + )), + ], + ), + ); + } +} diff --git a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart index c27a067e..e78b7773 100644 --- a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart +++ b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart @@ -1,5 +1,10 @@ +import 'dart:developer'; + import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; +import 'package:hub/components/atomic_components/shared_components_atoms/custom_input.dart'; +import 'package:hub/components/atomic_components/shared_components_atoms/submit_button.dart'; +import 'package:hub/components/atomic_components/shared_components_atoms/tabview.dart'; import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart'; import 'package:hub/features/backend/index.dart'; import 'package:hub/flutter_flow/flutter_flow_icon_button.dart'; @@ -9,141 +14,109 @@ import 'package:hub/pages/vehicles_on_the_property/vehicle_model.dart'; import 'package:hub/shared/utils/dialog_util.dart'; import 'package:hub/shared/utils/limited_text_size.dart'; import 'package:hub/shared/utils/log_util.dart'; +import 'package:material_symbols_icons/symbols.dart'; -class VehicleOnTheProperty extends StatefulWidget { - const VehicleOnTheProperty({super.key}); +part 'vehicle_history_screen.dart'; +part 'vehicle_register_screen.dart'; +part 'vehicle_update_screen.dart'; + +/// [VehiclePage] is a StatefulWidget that displays the vehicle screens. + +class VehiclePage extends StatefulWidget { + const VehiclePage({super.key}); @override - _VehicleOnThePropertyState createState() => _VehicleOnThePropertyState(); + _VehiclePageState createState() => _VehiclePageState(); } -class _VehicleOnThePropertyState extends State - with TickerProviderStateMixin { - late ScrollController _scrollController; - - int _pageNumber = 1; - bool _hasData = false; - bool _loading = false; +class _VehiclePageState extends State with TickerProviderStateMixin { int count = 0; - late final VehicleModel model; - - late Future _future; - List _wrap = []; + late final VehicleModel _model; @override void initState() { super.initState(); - model = createModel(context, () => VehicleModel()); - _future = _fetchVisits(); - _scrollController = ScrollController() - ..addListener(() { - if (_scrollController.position.atEdge && - _scrollController.position.pixels != 0) { - _loadMore(); - } + _model = createModel(context, () => VehicleModel()); + + _model.updateOnChange = true; + _model.onUpdateVehicle = () { + safeSetState(() { + _model.clearFields(); }); + }; + _model.onRegisterVehicle = () { + safeSetState(() { + _model.clearFields(); + }); + }; + _model.safeSetState = () { + safeSetState(() {}); + }; } @override void dispose() { - _scrollController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { - late final limitedHeaderTextSize = - LimitedFontSizeUtil.getHeaderFontSize(context); - + final backgroundColor = FlutterFlowTheme.of(context).primaryBackground; return Scaffold( - backgroundColor: FlutterFlowTheme.of(context).primaryBackground, - appBar: _appBar(context), - body: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - if (_hasData == false && _pageNumber <= 1 && _loading == false) - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.max, - children: [ - Center( - child: Text( - FFLocalizations.of(context).getVariableText( - ptText: "Nenhum veículo encontrado!", - enText: "No vehicle found", - ), - style: TextStyle( - fontFamily: 'Nunito', - fontSize: limitedHeaderTextSize, - ), - ), - ) - ], - ), - ) - else if (_hasData == true || _pageNumber >= 1) - Expanded( - child: FutureBuilder( - future: _future, - builder: (context, snapshot) { - return ListView.builder( - shrinkWrap: true, - physics: const BouncingScrollPhysics(), - controller: _scrollController, - itemCount: _wrap.length + 1, - itemBuilder: (context, index) { - if (index == 0) { - // Add your item here - return Padding( - padding: const EdgeInsets.only(right: 30, top: 10), - child: Text( - '', - textAlign: TextAlign.right, - ), - ); - } else { - final item = _wrap[index - 1]; - return _item(context, item); - } - }); - }, - )), - if (_hasData == true && _loading == true) - Container( - padding: const EdgeInsets.only(top: 15, bottom: 15), - child: Center( - child: CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation( - FlutterFlowTheme.of(context).primary, - ), - ), - ), - ) - ].addToStart(const SizedBox(height: 0)), - ), + backgroundColor: backgroundColor, + appBar: _buildAppBar(context), + body: _buildBody(context), ); } - PreferredSizeWidget _appBar(BuildContext context) { + /// [Body] of the page. + void onEditingChanged(bool value) { + setState(() { + _model.handleEditingChanged(value); + }); + } + + Widget _buildBody(BuildContext context) { + final vehicleHistoryScreenLabel = + FFLocalizations.of(context).getVariableText(ptText: 'Consultar', enText: 'Consult'); + final vehicleRegisterScreenLabel = + FFLocalizations.of(context).getVariableText(ptText: 'Cadastrar', enText: 'Register'); + final vehicleUpdateScreenLabel = FFLocalizations.of(context).getVariableText(ptText: 'Editar', enText: 'Edit'); + + return TabViewUtil( + context: context, + model: _model, + labelTab1: vehicleHistoryScreenLabel, + labelTab2: _model.isEditing ? vehicleUpdateScreenLabel : vehicleRegisterScreenLabel, + controller: _model.tabBarController, + widget1: VehicleHistoryScreen(_model), + widget2: _model.isEditing ? VehicleUpdateScreen(_model) : VehicleRegisterScreen(_model), + onEditingChanged: onEditingChanged, + ); + } + + /// ----------------------------------- + /// [AppBar] with the title of the page. + PreferredSizeWidget _buildAppBar(BuildContext context) { + final theme = FlutterFlowTheme.of(context); + final backgroundColor = theme.primaryBackground; + final primaryText = theme.primaryText; + final title = FFLocalizations.of(context).getVariableText(enText: 'Vehicles', ptText: 'Veículos'); + final titleStyle = theme.headlineMedium.override( + fontFamily: theme.headlineMediumFamily, + color: primaryText, + fontSize: 16.0, + fontWeight: FontWeight.bold, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey(theme.headlineMediumFamily), + ); + final backButton = _backButton(context, theme); + return AppBar( - backgroundColor: FlutterFlowTheme.of(context).primaryBackground, + backgroundColor: backgroundColor, automaticallyImplyLeading: false, - title: Text( - FFLocalizations.of(context) - .getVariableText(enText: 'Vehicles', ptText: 'Veículos'), - style: FlutterFlowTheme.of(context).headlineMedium.override( - fontFamily: FlutterFlowTheme.of(context).headlineMediumFamily, - color: FlutterFlowTheme.of(context).primaryText, - fontSize: 16.0, - fontWeight: FontWeight.bold, - letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap().containsKey( - FlutterFlowTheme.of(context).headlineMediumFamily), - ), - ), - leading: _backButton(context, FlutterFlowTheme.of(context)), + title: Text(title, style: titleStyle), + leading: backButton, centerTitle: true, elevation: 0.0, actions: [], @@ -151,131 +124,22 @@ class _VehicleOnThePropertyState extends State } Widget _backButton(BuildContext context, FlutterFlowTheme theme) { + final Icon icon = Icon( + Icons.keyboard_arrow_left, + color: theme.primaryText, + size: 30.0, + ); + onPressed() => Navigator.of(context).pop(); return FlutterFlowIconButton( key: ValueKey('BackNavigationAppBar'), borderColor: Colors.transparent, borderRadius: 30.0, borderWidth: 1.0, buttonSize: 60.0, - icon: Icon( - Icons.keyboard_arrow_left, - color: theme.primaryText, - size: 30.0, - ), - onPressed: () => Navigator.of(context).pop(), + icon: icon, + onPressed: onPressed, ); } - Future _fetchVisits() async { - try { - setState(() => _loading = true); - - var response = - await PhpGroup.getVehiclesByProperty.call(_pageNumber.toString()); - - final List vehicles = response.jsonBody['vehicles'] ?? []; - safeSetState(() => count = response.jsonBody['total_rows'] ?? 0); - - if (vehicles.isNotEmpty) { - setState(() { - _wrap.addAll(vehicles); - _hasData = true; - _loading = false; - }); - - return response; - } - - _showNoMoreDataSnackBar(context); - - setState(() { - _hasData = false; - _loading = false; - }); - - return null; - } catch (e, s) { - DialogUtil.errorDefault(context); - LogUtil.requestAPIFailed( - "proccessRequest.php", "", "Consulta de Veículo", e, s); - setState(() { - _hasData = false; - _loading = false; - }); - } - return null; - } - - void _loadMore() { - if (_hasData == true) { - _pageNumber++; - - _future = _fetchVisits(); - } - } - - void _showNoMoreDataSnackBar(BuildContext context) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - FFLocalizations.of(context).getVariableText( - ptText: "Não há mais dados.", - enText: "No more data.", - ), - style: TextStyle( - color: Colors.white, - fontSize: LimitedFontSizeUtil.getBodyFontSize(context), - ), - ), - duration: const Duration(seconds: 3), - backgroundColor: FlutterFlowTheme.of(context).primary, - ), - ); - } - - Widget _item(BuildContext context, dynamic uItem) { - return CardItemTemplateComponentWidget( - imagePath: null, - labelsHashMap: { - '${FFLocalizations.of(context).getVariableText(ptText: "Placa", enText: "License Plate")}:': - uItem['licensePlate'] ?? '', - '${FFLocalizations.of(context).getVariableText(ptText: "Modelo", enText: "Model")}:': - uItem['model'] ?? '', - '${FFLocalizations.of(context).getVariableText(ptText: "Tag", enText: "Tag")}:': - uItem['tag'] ?? '', - }, - statusHashMap: [], - onTapCardItemAction: () async { - await showDialog( - useSafeArea: true, - context: context, - builder: (context) { - return Dialog( - alignment: Alignment.center, - child: model.buildVehicleDetails( - item: uItem, - context: context, - model: model, - ), - ); - }, - ).whenComplete(() { - safeSetState(() { - _pageNumber = 1; - _wrap = []; - _future = _fetchVisits() - .then((value) => value!.jsonBody['vehicles'] ?? []); - }); - }).catchError((e, s) { - DialogUtil.errorDefault(context); - LogUtil.requestAPIFailed( - "proccessRequest.php", "", "Consulta de Veículos", e, s); - safeSetState(() { - _hasData = false; - _loading = false; - }); - }); - }, - ); - } + /// ----------------------------------- } diff --git a/lib/pages/visits_on_the_property/model.dart b/lib/pages/visits_on_the_property/model.dart index fec4e8a1..ef521047 100644 --- a/lib/pages/visits_on_the_property/model.dart +++ b/lib/pages/visits_on_the_property/model.dart @@ -6,13 +6,12 @@ import 'package:hub/flutter_flow/flutter_flow_theme.dart'; import 'package:hub/flutter_flow/internationalization.dart'; import 'package:hub/pages/vehicles_on_the_property/vehicles_on_the_property.dart'; -class VisitsModel extends FlutterFlowModel { +class VisitsModel extends FlutterFlowModel { static VisitsModel? _instance; VisitsModel._internal({this.onRefresh}); - factory VisitsModel({VoidCallback? onRefresh}) => - _instance ??= VisitsModel._internal(onRefresh: onRefresh); + factory VisitsModel({VoidCallback? onRefresh}) => _instance ??= VisitsModel._internal(onRefresh: onRefresh); static void resetInstance() => _instance = null; late final VoidCallback? onRefresh; @@ -34,8 +33,7 @@ class VisitsModel extends FlutterFlowModel { Future initAsync() async { devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - cliUUID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; onRefresh?.call(); } @@ -89,9 +87,7 @@ class VisitsModel extends FlutterFlowModel { FFLocalizations.of(context).getVariableText( ptText: item['VTA_FIXA'] ? "Entrada Recorrente" : "Entrada Única", enText: item['VTA_FIXA'] ? "Recurrent Entry" : "Single Entry", - ): item['VTA_FIXA'] == false - ? FlutterFlowTheme.of(context).success - : FlutterFlowTheme.of(context).warning, + ): item['VTA_FIXA'] == false ? FlutterFlowTheme.of(context).success : FlutterFlowTheme.of(context).warning, }) ], ); From fb91e62a2520179928ffb25fd29d92eb7674a674 Mon Sep 17 00:00:00 2001 From: "J. A. Messias" Date: Mon, 27 Jan 2025 14:33:08 -0300 Subject: [PATCH 02/47] WIP --- integration_test/app_test.dart | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index 239f2e4a..9803dde4 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -65,7 +65,7 @@ void main() { // AuthenticationTest.signIn(); // AuthenticationTest.signUp(); // AuthenticationTest.signOut(); - AuthenticationTest.recovery(); + // AuthenticationTest.recovery(); // ModularizationTest.switchLicense(); // ModularizationTest.containLicense(); From f33081a7733a9ad37fd256c2b9ef205b1ad5a022 Mon Sep 17 00:00:00 2001 From: "J. A. Messias" Date: Tue, 28 Jan 2025 08:53:56 -0300 Subject: [PATCH 03/47] WIP --- integration_test/app_test.dart | 9 ++ integration_test/vehicle_test.dart | 132 ++++++++++++++++++ .../shared_components_atoms/tabview.dart | 5 +- .../home/presentation/pages/home_page.dart | 16 ++- .../locals_remote_data_source.dart | 31 ++-- .../repositories/locals_repository_impl.dart | 11 +- lib/pages/vehicles_on_the_property/index.dart | 2 + .../vehicles_on_the_property.dart | 2 +- 8 files changed, 177 insertions(+), 31 deletions(-) create mode 100644 integration_test/vehicle_test.dart create mode 100644 lib/pages/vehicles_on_the_property/index.dart diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index 9803dde4..b67c9085 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -12,6 +12,7 @@ import 'package:go_router/go_router.dart'; import 'package:hub/components/molecular_components/throw_exception/throw_exception_widget.dart'; import 'package:hub/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart'; import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart'; +import 'package:hub/components/templates_components/details_component/details_component_widget.dart'; import 'package:hub/components/templates_components/forgot_password_template_component/forgot_password_template_component_widget.dart'; import 'package:hub/features/backend/api_requests/index.dart'; import 'package:hub/features/local/index.dart'; @@ -25,6 +26,8 @@ import 'package:hub/flutter_flow/index.dart'; import 'package:hub/initialization.dart'; import 'package:hub/main.dart'; import 'package:hub/pages/forgot_password_page/forgot_password_screen.dart'; +import 'package:hub/pages/vehicles_on_the_property/vehicle_model.dart'; +import 'package:hub/pages/vehicles_on_the_property/vehicles_on_the_property.dart'; import 'package:integration_test/integration_test.dart'; import 'package:material_symbols_icons/symbols.dart'; import 'package:patrol/patrol.dart'; @@ -49,6 +52,7 @@ part 'setting_test.dart'; part 'storage_test.dart'; part 'utils_test.dart'; part 'welcome_test.dart'; +part 'vehicle_test.dart'; late PatrolIntegrationTester $; @@ -76,4 +80,9 @@ void main() { // LocalsTest.setLocal(); // LocalsTest.unlinkLocal(); + + VehicleTest.vehiclePage(); + VehicleTest.historyScreen(); + VehicleTest.registerScreen(); + VehicleTest.updateScreen(); } diff --git a/integration_test/vehicle_test.dart b/integration_test/vehicle_test.dart new file mode 100644 index 00000000..f96e8580 --- /dev/null +++ b/integration_test/vehicle_test.dart @@ -0,0 +1,132 @@ +part of 'app_test.dart'; + +class VehicleTest { + static Future vehiclePage() async { + patrol( + 'Vehicle Page', + (PatrolIntegrationTester tester) async { + $ = tester; + $.tester.printToConsole('Vehicle Page'); + final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget); + + await _loggedWithMultiLocalsAccount($); + await $.pumpWidgetAndSettle(const App()); + + ff.navigatorKey.currentContext!.go('/vehiclesOnThePropertyPage'); + + final String title = MenuEntry.entries // + .where((entry) => entry.key == 'FRE-HUB-VEHICLES') // + .map((entry) => entry.name) + .first; + + final PatrolFinder appBar = await $(AppBar) // + .waitUntilExists(); + final PatrolFinder titleAppBar = await appBar // + .$(title) + .waitUntilVisible(); + expect(titleAppBar, findsOneWidget); + + final PatrolFinder tab1 = await $(#TabView_Tab1) // + .waitUntilExists(); + final PatrolFinder tab2 = await $(#TabView_Tab2) // + .waitUntilExists(); + + await tab2.tap(); + await Future.delayed(const Duration(milliseconds: 500)); + await tab1.tap(); + + final PatrolFinder listViewFinder = await $(VehicleHistoryScreen) // + .$(ListView) + .waitUntilVisible(); + + expect(listViewFinder, findsOneWidget); + + final PatrolFinder entriesFinder = + await $(listViewFinder).$(CardItemTemplateComponentWidget).waitUntilVisible(); + + expect(entriesFinder, findsWidgets); + final int entriesCount = entriesFinder.evaluate().length; + await $.pumpAndSettle(); + + for (int i = 0; i < entriesCount; i++) { + await $(entriesFinder.at(i)).scrollTo(); + + await $(entriesFinder.at(i)).waitUntilVisible(timeout: const Duration(seconds: 1)).tap( + settleTimeout: const Duration(seconds: 1), + settlePolicy: SettlePolicy.noSettle, + ); + + await $.pumpAndSettle(duration: Duration(milliseconds: 500)); + final PatrolFinder detailsFinder = await $(DetailsComponentWidget).waitUntilVisible(); + expect(detailsFinder, findsOneWidget); + + await $.native.pressBack().then((_) => $.pumpAndSettle()); + } + }, + ); + } + + static Future historyScreen() async { + patrol( + 'historyScreen', + (PatrolIntegrationTester tester) async { + $ = tester; + $.tester.printToConsole('Vehicle Page'); + final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget); + + await _loggedWithMultiLocalsAccount($); + await $.pumpWidgetAndSettle(const App()); + + ff.navigatorKey.currentContext!.go('/vehiclesOnThePropertyPage'); + + final String title = MenuEntry.entries // + .where((entry) => entry.key == 'FRE-HUB-VEHICLES') // + .map((entry) => entry.name) + .first; + + final PatrolFinder appBar = await $(AppBar) // + .waitUntilExists(); + final PatrolFinder titleAppBar = await appBar // + .$(title) + .waitUntilVisible(); + expect(titleAppBar, findsOneWidget); + + final PatrolFinder tab2 = await $(#TabView_Tab2) // + .waitUntilExists(); + + await tab2.tap(); + + final PatrolFinder listViewFinder = await $(VehicleHistoryScreen) // + .$(ListView) + .waitUntilVisible(); + + expect(listViewFinder, findsOneWidget); + + final PatrolFinder entriesFinder = + await $(listViewFinder).$(CardItemTemplateComponentWidget).waitUntilVisible(); + + expect(entriesFinder, findsWidgets); + final int entriesCount = entriesFinder.evaluate().length; + await $.pumpAndSettle(); + + for (int i = 0; i < entriesCount; i++) { + await $(entriesFinder.at(i)).scrollTo(); + + await $(entriesFinder.at(i)).waitUntilVisible(timeout: const Duration(seconds: 1)).tap( + settleTimeout: const Duration(seconds: 1), + settlePolicy: SettlePolicy.noSettle, + ); + + await $.pumpAndSettle(duration: Duration(milliseconds: 500)); + final PatrolFinder detailsFinder = await $(DetailsComponentWidget).waitUntilVisible(); + expect(detailsFinder, findsOneWidget); + + await $.native.pressBack().then((_) => $.pumpAndSettle()); + } + }, + ); + } + + static Future registerScreen() async {} + static Future updateScreen() async {} +} diff --git a/lib/components/atomic_components/shared_components_atoms/tabview.dart b/lib/components/atomic_components/shared_components_atoms/tabview.dart index 8a62cbf3..8fe92916 100644 --- a/lib/components/atomic_components/shared_components_atoms/tabview.dart +++ b/lib/components/atomic_components/shared_components_atoms/tabview.dart @@ -41,17 +41,18 @@ class TabViewUtil extends StatelessWidget { fontFamily: FlutterFlowTheme.of(context).titleMediumFamily, fontSize: LimitedFontSizeUtil.getBodyFontSize(context), letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap().containsKey( - FlutterFlowTheme.of(context).titleMediumFamily), + useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).titleMediumFamily), ), unselectedLabelStyle: const TextStyle(), indicatorColor: FlutterFlowTheme.of(context).primary, padding: const EdgeInsets.all(4.0), tabs: [ Tab( + key: ValueKey('TabView_Tab1'), text: labelTab1, ), Tab( + key: ValueKey('TabView_Tab2'), text: labelTab2, ), ], diff --git a/lib/features/home/presentation/pages/home_page.dart b/lib/features/home/presentation/pages/home_page.dart index 3963a497..c8571947 100644 --- a/lib/features/home/presentation/pages/home_page.dart +++ b/lib/features/home/presentation/pages/home_page.dart @@ -4,6 +4,7 @@ import 'package:google_fonts/google_fonts.dart'; import 'package:hub/features/home/presentation/widgets/drawer_widget.dart'; import 'package:hub/features/local/index.dart'; import 'package:hub/features/menu/index.dart'; +import 'package:hub/features/storage/index.dart'; import 'package:hub/flutter_flow/flutter_flow_icon_button.dart'; import 'package:hub/flutter_flow/flutter_flow_theme.dart'; import 'package:hub/flutter_flow/flutter_flow_util.dart'; @@ -16,8 +17,7 @@ class HomePageWidget extends StatefulWidget { State createState() => _HomePageWidgetState(); } -class _HomePageWidgetState extends State - with WidgetsBindingObserver { +class _HomePageWidgetState extends State with WidgetsBindingObserver { final scaffoldKey = GlobalKey(); @override @@ -25,6 +25,15 @@ class _HomePageWidgetState extends State super.initState(); WidgetsBinding.instance.addObserver(this); WidgetsBinding.instance.addPostFrameCallback((_) async { + final email = await StorageHelper().get(SecureStorageKey.email.value); + final pass = await StorageHelper().get(SecureStorageKey.password.value); + final cli = await StorageHelper().get(ProfileStorageKey.clientUUID.key); + final owner = await StorageHelper().get(ProfileStorageKey.ownerUUID.key); + print('Email: $email'); + print('Password: $pass'); + print('Client: $cli'); + print('Owner: $owner'); + await LocalsRepositoryImpl().check(context); if (widget.update != null) { await widget.update!(context); @@ -97,8 +106,7 @@ class _HomePageWidgetState extends State fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily, color: FlutterFlowTheme.of(context).info, letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap().containsKey( - FlutterFlowTheme.of(context).bodyMediumFamily), + useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).bodyMediumFamily), ), ), ].divide(const SizedBox(width: 8.0)), diff --git a/lib/features/local/data/data_sources/locals_remote_data_source.dart b/lib/features/local/data/data_sources/locals_remote_data_source.dart index fd91b648..0babde3a 100644 --- a/lib/features/local/data/data_sources/locals_remote_data_source.dart +++ b/lib/features/local/data/data_sources/locals_remote_data_source.dart @@ -24,8 +24,7 @@ abstract class LocalsRemoteDataSource { } class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource { - static final LocalsRemoteDataSourceImpl _instance = - LocalsRemoteDataSourceImpl._internal(); + static final LocalsRemoteDataSourceImpl _instance = LocalsRemoteDataSourceImpl._internal(); factory LocalsRemoteDataSourceImpl() => _instance; LocalsRemoteDataSourceImpl._internal(); @@ -51,8 +50,7 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource { final List locals = response.jsonBody['locais'] ?? []; final bool isEmpty = locals.isEmpty; - final bool isActive = - locals.where((local) => local['CLU_STATUS'] != 'B').isNotEmpty; + final bool isActive = locals.where((local) => local['CLU_STATUS'] != 'B').isNotEmpty; final bool isEnable = !isEmpty && isActive; if (isEnable) { @@ -97,8 +95,7 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource { final bool isInactived = await LocalUtil.isInactived(locals); final bool isPending = LocalUtil.isPending(locals); final bool isUnique = locals.length == 1; - final bool isBlocked = - locals.where((local) => local['CLU_STATUS'] == 'B').isNotEmpty; + final bool isBlocked = locals.where((local) => local['CLU_STATUS'] == 'B').isNotEmpty; final bool isEnabled = isUnique && isActive; final bool isDisabled = isUnique && isBlocked; final bool isUnselected = await LocalUtil.isUnselected(); @@ -151,11 +148,11 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource { @override Future checkLocals(BuildContext context) async { - String cliUUID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; - String cliName = - (await StorageHelper().get(ProfileStorageKey.clientName.key)) ?? ''; - return cliUUID.isEmpty && cliName.isEmpty; + final String? cliUUID = await StorageHelper().get(ProfileStorageKey.clientUUID.key); + final String? cliName = await StorageHelper().get(ProfileStorageKey.clientName.key); + final haveCli = cliUUID != null && cliUUID.isNotEmpty; + final haveName = cliName != null && cliName.isNotEmpty; + return haveCli && haveName; } @override @@ -178,8 +175,7 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource { if (isError == true) { final GetLocalsCall callback = PhpGroup.getLocalsCall; response = await callback.call(); - final String errorMsg = - response.jsonBody['error_msg'] ?? 'Local indisponível'; + final String errorMsg = response.jsonBody['error_msg'] ?? 'Local indisponível'; // await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, response)); return false; } else { @@ -198,8 +194,7 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource { } @override - Future selectLocal( - BuildContext context, ApiCallResponse? response) async { + Future selectLocal(BuildContext context, ApiCallResponse? response) async { return await showModalBottomSheet( isScrollControlled: true, backgroundColor: Colors.transparent, @@ -229,15 +224,13 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource { enText: 'Device unlinked successfully', ptText: 'Dispositivo desvinculado com sucesso', ); - final bool status = - await PhpGroup.resopndeVinculo.call(tarefa: 'I').then((value) async { + final bool status = await PhpGroup.resopndeVinculo.call(tarefa: 'I').then((value) async { if (value.jsonBody['error'] == false) { await StorageHelper().set(ProfileStorageKey.clientName.key, ''); await StorageHelper().set(ProfileStorageKey.ownerName.key, ''); await StorageHelper().set(ProfileStorageKey.clientUUID.key, ''); context.pop(); - context.go('/homePage', - extra: {'update': LocalsRepositoryImpl().update}); + context.go('/homePage', extra: {'update': LocalsRepositoryImpl().update}); SnackBarUtil.showSnackBar(context, content); return true; } diff --git a/lib/features/local/data/repositories/locals_repository_impl.dart b/lib/features/local/data/repositories/locals_repository_impl.dart index 232e511e..ea37e12e 100644 --- a/lib/features/local/data/repositories/locals_repository_impl.dart +++ b/lib/features/local/data/repositories/locals_repository_impl.dart @@ -49,13 +49,12 @@ class LocalsRepositoryImpl implements LocalsRepository { } Future check(BuildContext context) async { - final String? cliUUID = - await StorageHelper().get(ProfileStorageKey.clientUUID.key); - final String? ownerUUID = - await StorageHelper().get(ProfileStorageKey.ownerUUID.key); + final String? cliUUID = await StorageHelper().get(ProfileStorageKey.clientUUID.key); + final String? ownerUUID = await StorageHelper().get(ProfileStorageKey.ownerUUID.key); final bool haveCli = cliUUID != null && cliUUID.isNotEmpty; final bool haveOwner = ownerUUID != null && ownerUUID.isNotEmpty; if (!haveCli && !haveOwner) { + log('No client or owner selected'); await update(context); await FirebaseMessagingService().updateDeviceToken(); } @@ -64,7 +63,8 @@ class LocalsRepositoryImpl implements LocalsRepository { Future _handleLocal(BuildContext context) async { bool response = false; final bool isUnselected = await remoteDataSource.checkLocals(context); - if (isUnselected) { + if (!isUnselected) { + log('_handleLocal -> No local selected'); while (!response) { try { response = await remoteDataSource.processLocals(context); @@ -77,6 +77,7 @@ class LocalsRepositoryImpl implements LocalsRepository { } } } else { + log('_handleLocal -> Local selected'); return true; } diff --git a/lib/pages/vehicles_on_the_property/index.dart b/lib/pages/vehicles_on_the_property/index.dart new file mode 100644 index 00000000..f159a317 --- /dev/null +++ b/lib/pages/vehicles_on_the_property/index.dart @@ -0,0 +1,2 @@ +export 'vehicles_on_the_property.dart'; +export 'vehicle_model.dart'; diff --git a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart index e78b7773..2f087c22 100644 --- a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart +++ b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart @@ -78,7 +78,7 @@ class _VehiclePageState extends State with TickerProviderStateMixin Widget _buildBody(BuildContext context) { final vehicleHistoryScreenLabel = - FFLocalizations.of(context).getVariableText(ptText: 'Consultar', enText: 'Consult'); + FFLocalizations.of(context).getVariableText(ptText: 'Consultar', enText: 'History'); final vehicleRegisterScreenLabel = FFLocalizations.of(context).getVariableText(ptText: 'Cadastrar', enText: 'Register'); final vehicleUpdateScreenLabel = FFLocalizations.of(context).getVariableText(ptText: 'Editar', enText: 'Edit'); From e5bd18dec67e1aa206af24a472b44b08d115060e Mon Sep 17 00:00:00 2001 From: "J. A. Messias" Date: Tue, 28 Jan 2025 08:59:00 -0300 Subject: [PATCH 04/47] WIP --- lib/features/home/presentation/pages/home_page.dart | 9 --------- 1 file changed, 9 deletions(-) diff --git a/lib/features/home/presentation/pages/home_page.dart b/lib/features/home/presentation/pages/home_page.dart index c8571947..0d87ea9f 100644 --- a/lib/features/home/presentation/pages/home_page.dart +++ b/lib/features/home/presentation/pages/home_page.dart @@ -25,15 +25,6 @@ class _HomePageWidgetState extends State with WidgetsBindingObse super.initState(); WidgetsBinding.instance.addObserver(this); WidgetsBinding.instance.addPostFrameCallback((_) async { - final email = await StorageHelper().get(SecureStorageKey.email.value); - final pass = await StorageHelper().get(SecureStorageKey.password.value); - final cli = await StorageHelper().get(ProfileStorageKey.clientUUID.key); - final owner = await StorageHelper().get(ProfileStorageKey.ownerUUID.key); - print('Email: $email'); - print('Password: $pass'); - print('Client: $cli'); - print('Owner: $owner'); - await LocalsRepositoryImpl().check(context); if (widget.update != null) { await widget.update!(context); From 3b7a33801f2633ed06c2e64849d0ae7387a89b4f Mon Sep 17 00:00:00 2001 From: "J. A. Messias" Date: Tue, 28 Jan 2025 11:29:42 -0300 Subject: [PATCH 05/47] licenes -> vehicle manager module --- .../menu/presentation/mappers/menu_entry.dart | 10 +++++ .../module/domain/entities/license.dart | 40 +++++++---------- .../vehicle_model.dart | 4 +- .../vehicles_on_the_property.dart | 44 +++++++++++++++++-- 4 files changed, 69 insertions(+), 29 deletions(-) diff --git a/lib/features/menu/presentation/mappers/menu_entry.dart b/lib/features/menu/presentation/mappers/menu_entry.dart index 7e1a4b00..79c5e770 100644 --- a/lib/features/menu/presentation/mappers/menu_entry.dart +++ b/lib/features/menu/presentation/mappers/menu_entry.dart @@ -72,6 +72,16 @@ class MenuEntry implements BaseModule { route: '/residentsOnThePropertyPage', types: [MenuEntryType.Property], ), + // MenuEntry( + // key: 'FRE-HUB-VEHICLES-MANAGER', + // icon: Icons.directions_car, + // name: FFLocalizations.of(navigatorKey.currentContext!).getVariableText( + // ptText: 'Veículos', + // enText: 'Vehicles', + // ), + // route: '/vehiclesOnThePropertyPage', + // types: [MenuEntryType.Property], + // ), MenuEntry( key: 'FRE-HUB-VEHICLES', icon: Icons.directions_car, diff --git a/lib/features/module/domain/entities/license.dart b/lib/features/module/domain/entities/license.dart index 17a70650..275776b9 100644 --- a/lib/features/module/domain/entities/license.dart +++ b/lib/features/module/domain/entities/license.dart @@ -10,6 +10,7 @@ enum LicenseKeys { access('FRE-HUB-ACCESS'), openedVisits('FRE-HUB-OPENED-VISITS'), vehicles('FRE-HUB-VEHICLES'), + vehiclesManager('FRE-HUB-VEHICLES-MANAGER'), residents('FRE-HUB-RESIDENTS'), about('FRE-HUB-ABOUT-SYSTEM'), pets('FRE-HUB-PETS'), @@ -60,9 +61,7 @@ class License { } static Future _precessWpp() async { - final bool whatsapp = await StorageHelper() - .get(LocalsStorageKey.whatsapp.key) - .then((v) => v.toBoolean()); + final bool whatsapp = await StorageHelper().get(LocalsStorageKey.whatsapp.key).then((v) => v.toBoolean()); if (whatsapp) return ModuleStatus.active.key; else @@ -70,9 +69,7 @@ class License { } static Future _processProvisional() async { - final bool provisional = await StorageHelper() - .get(LocalsStorageKey.provisional.key) - .then((v) => v.toBoolean()); + final bool provisional = await StorageHelper().get(LocalsStorageKey.provisional.key).then((v) => v.toBoolean()); if (provisional) return ModuleStatus.active.key; else @@ -80,9 +77,7 @@ class License { } static Future _processPets() async { - final bool pets = await StorageHelper() - .get(LocalsStorageKey.pets.key) - .then((v) => v.toBoolean()); + final bool pets = await StorageHelper().get(LocalsStorageKey.pets.key).then((v) => v.toBoolean()); if (pets) return ModuleStatus.active.key; else @@ -139,27 +134,28 @@ class License { ), Module( key: LicenseKeys.openedVisits.value, - display: isNewVersionWithModule - ? ModuleStatus.active.key - : ModuleStatus.inactive.key, + display: isNewVersionWithModule ? ModuleStatus.active.key : ModuleStatus.inactive.key, expirationDate: '', startDate: '', quantity: 0, ), Module( key: LicenseKeys.vehicles.value, - display: isNewVersionWithModule - ? ModuleStatus.active.key - : ModuleStatus.inactive.key, + display: isNewVersionWithModule ? ModuleStatus.active.key : ModuleStatus.inactive.key, + expirationDate: '', + startDate: '', + quantity: 0, + ), + Module( + key: LicenseKeys.vehicles.value, + display: ModuleStatus.inactive.key, expirationDate: '', startDate: '', quantity: 0, ), Module( key: LicenseKeys.residents.value, - display: isNewVersionWithModule - ? ModuleStatus.active.key - : ModuleStatus.inactive.key, + display: isNewVersionWithModule ? ModuleStatus.active.key : ModuleStatus.inactive.key, expirationDate: '', startDate: '', quantity: 0, @@ -222,18 +218,14 @@ class License { ), Module( key: LicenseKeys.property.value, - display: isNewVersionWithModule - ? ModuleStatus.active.key - : ModuleStatus.inactive.key, + display: isNewVersionWithModule ? ModuleStatus.active.key : ModuleStatus.inactive.key, expirationDate: '', startDate: '', quantity: 0, ), Module( key: LicenseKeys.people.value, - display: isNewVersionWithModule - ? ModuleStatus.inactive.key - : ModuleStatus.active.key, + display: isNewVersionWithModule ? ModuleStatus.inactive.key : ModuleStatus.active.key, expirationDate: '', startDate: '', quantity: 0, diff --git a/lib/pages/vehicles_on_the_property/vehicle_model.dart b/lib/pages/vehicles_on_the_property/vehicle_model.dart index 78d5fbaf..4732e9ba 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_model.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_model.dart @@ -107,7 +107,7 @@ class VehicleModel extends FlutterFlowModel { Future initAsync() async {} - Map generateStatusColorMap(dynamic uItem) { + Map? generateStatusColorMap(dynamic uItem) { final statusMap = { "ATI": { "text": FFLocalizations.of(context).getVariableText( @@ -162,7 +162,7 @@ class VehicleModel extends FlutterFlowModel { return {}; } - List generateActionButtons(dynamic item) { + List? generateActionButtons(dynamic item) { final Color iconButtonColor = FlutterFlowTheme.of(context).primaryText; final FFButtonOptions buttonOptions = FFButtonOptions( height: 40, diff --git a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart index 2f087c22..468bd50f 100644 --- a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart +++ b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart @@ -7,9 +7,11 @@ import 'package:hub/components/atomic_components/shared_components_atoms/submit_ import 'package:hub/components/atomic_components/shared_components_atoms/tabview.dart'; import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart'; import 'package:hub/features/backend/index.dart'; +import 'package:hub/features/module/index.dart'; import 'package:hub/flutter_flow/flutter_flow_icon_button.dart'; import 'package:hub/flutter_flow/flutter_flow_theme.dart'; import 'package:hub/flutter_flow/flutter_flow_util.dart'; +import 'package:hub/flutter_flow/index.dart'; import 'package:hub/pages/vehicles_on_the_property/vehicle_model.dart'; import 'package:hub/shared/utils/dialog_util.dart'; import 'package:hub/shared/utils/limited_text_size.dart'; @@ -21,7 +23,6 @@ part 'vehicle_register_screen.dart'; part 'vehicle_update_screen.dart'; /// [VehiclePage] is a StatefulWidget that displays the vehicle screens. - class VehiclePage extends StatefulWidget { const VehiclePage({super.key}); @@ -65,18 +66,55 @@ class _VehiclePageState extends State with TickerProviderStateMixin return Scaffold( backgroundColor: backgroundColor, appBar: _buildAppBar(context), - body: _buildBody(context), + body: buildBody(context), ); } /// [Body] of the page. + Widget buildBody(BuildContext context) { + Widget progressEvent() { + return CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation( + FlutterFlowTheme.of(context).primary, + ), + ); + } + + Widget errorEvent() { + WidgetsBinding.instance.addPostFrameCallback((_) async { + context.pop(); + await DialogUtil.errorDefault(navigatorKey.currentContext!); + }); + return progressEvent(); + } + + return FutureBuilder( + future: LicenseRepositoryImpl().getModule('FRE-HUB-VEHICLES-MANAGER'), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return progressEvent(); + } else if (snapshot.hasError) { + return errorEvent(); + } else if (snapshot.hasData && snapshot.data!.isNotEmpty) { + return _buildVehicleManager(context); + } else { + return _buildVehicleHistory(context); + } + }, + ); + } + void onEditingChanged(bool value) { setState(() { _model.handleEditingChanged(value); }); } - Widget _buildBody(BuildContext context) { + Widget _buildVehicleHistory(BuildContext context) { + return VehicleHistoryScreen(_model); + } + + Widget _buildVehicleManager(BuildContext context) { final vehicleHistoryScreenLabel = FFLocalizations.of(context).getVariableText(ptText: 'Consultar', enText: 'History'); final vehicleRegisterScreenLabel = From 7dd7ed7a324e8ddc0603adcb19a1828b2dc8dac7 Mon Sep 17 00:00:00 2001 From: "J. A. Messias" Date: Wed, 29 Jan 2025 10:27:23 -0300 Subject: [PATCH 06/47] WIP --- integration_test/app_test.dart | 6 +- integration_test/utils_test.dart | 33 +- integration_test/vehicle_test.dart | 68 +++ ..._arrow_linked_locals_component_widget.dart | 82 ++-- .../backend/api_requests/api_calls.dart | 2 +- .../locals_remote_data_source.dart | 2 +- lib/features/local/utils/local_util.dart | 111 ++--- .../data_sources/menu_local_data_source.dart | 64 +-- .../repositories/menu_repository_impl.dart | 34 +- .../vehicle_model.dart | 450 ++++++++++-------- .../vehicle_register_screen.dart | 162 ++++--- .../vehicles_on_the_property.dart | 53 ++- lib/shared/utils/datetime_util.dart | 26 + lib/shared/utils/license_util.dart | 17 + 14 files changed, 581 insertions(+), 529 deletions(-) create mode 100644 lib/shared/utils/datetime_util.dart create mode 100644 lib/shared/utils/license_util.dart diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index b67c9085..028840ca 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -82,7 +82,7 @@ void main() { // LocalsTest.unlinkLocal(); VehicleTest.vehiclePage(); - VehicleTest.historyScreen(); - VehicleTest.registerScreen(); - VehicleTest.updateScreen(); + // VehicleTest.historyScreen(); + // VehicleTest.registerScreen(); + // VehicleTest.updateScreen(); } diff --git a/integration_test/utils_test.dart b/integration_test/utils_test.dart index 309c0923..d3b4bfca 100644 --- a/integration_test/utils_test.dart +++ b/integration_test/utils_test.dart @@ -1,7 +1,6 @@ part of 'app_test.dart'; -Future _loggedWithMultiLocalsAccount(PatrolIntegrationTester $, - [bool forceLinkedLocal = true]) async { +Future _loggedWithMultiLocalsAccount(PatrolIntegrationTester $, [bool forceLinkedLocal = true]) async { await _init($); await StorageHelper() // .set(SecureStorageKey.isLogged.value, 'true'); @@ -19,18 +18,15 @@ Future _loggedWithMultiLocalsAccount(PatrolIntegrationTester $, await StorageHelper() // .set(LocalsStorageKey.isNewVersion.key, true); if (forceLinkedLocal == true) { - await StorageHelper() // - .set(ProfileStorageKey.clientUUID.key, '7'); - await PhpGroup // - .resopndeVinculo - .call(tarefa: 'A'); - await LicenseRepositoryImpl() // - .resetLicense(); + await StorageHelper().set(ProfileStorageKey.clientUUID.key, '7'); + await StorageHelper().set(ProfileStorageKey.ownerUUID.key, '7'); + await StorageHelper().set(ProfileStorageKey.clientName.key, 'FRE ACCESS DEMO'); + await PhpGroup.respondeVinculo.call(tarefa: 'A'); + await LicenseRepositoryImpl().resetLicense(); } } -Future _loggedWithSomeoneLocalAccount(PatrolIntegrationTester $, - [bool forceLinkedLocal = true]) async { +Future _loggedWithSomeoneLocalAccount(PatrolIntegrationTester $, [bool forceLinkedLocal = true]) async { await _init($); await StorageHelper() // .set(SecureStorageKey.isLogged.value, 'true'); @@ -48,13 +44,11 @@ Future _loggedWithSomeoneLocalAccount(PatrolIntegrationTester $, await StorageHelper() // .set(LocalsStorageKey.isNewVersion.key, true); if (forceLinkedLocal == true) { - await StorageHelper() // - .set(ProfileStorageKey.clientUUID.key, '7'); - await PhpGroup // - .resopndeVinculo - .call(tarefa: 'A'); - await LicenseRepositoryImpl() // - .resetLicense(); + await StorageHelper().set(ProfileStorageKey.clientUUID.key, '7'); + await StorageHelper().set(ProfileStorageKey.ownerUUID.key, '7'); + await StorageHelper().set(ProfileStorageKey.clientName.key, 'FRE ACCESS DEMO'); + await PhpGroup.respondeVinculo.call(tarefa: 'A'); + await LicenseRepositoryImpl().resetLicense(); } } @@ -101,8 +95,7 @@ Future _navigateToSignUp(PatrolIntegrationTester $) async { } Future _navigateBackUsingSystemGesture() async => - IntegrationTestWidgetsFlutterBinding.instance.keyboard - .isLogicalKeyPressed(LogicalKeyboardKey.escape); + IntegrationTestWidgetsFlutterBinding.instance.keyboard.isLogicalKeyPressed(LogicalKeyboardKey.escape); Future _initializeTracking() async { print('Requesting tracking authorization...'); diff --git a/integration_test/vehicle_test.dart b/integration_test/vehicle_test.dart index f96e8580..1fa43131 100644 --- a/integration_test/vehicle_test.dart +++ b/integration_test/vehicle_test.dart @@ -64,6 +64,74 @@ class VehicleTest { } }, ); + patrol( + 'License', + (PatrolIntegrationTester tester) async { + $ = tester; + $.tester.printToConsole('Vehicle Page'); + + await _loggedWithMultiLocalsAccount($); + + // await StorageHelper().set( + // LicenseKeys.vehiclesManager.value, + // { + // 'display': 'VISIVEL', + // 'expirationDate': '', + // 'startDate': '', + // 'quantity': 0, + // }, + // ); + // // await $.pumpAndSettle(); + // ff.navigatorKey.currentContext!.go('/vehiclesOnThePropertyPage'); + // await Future.delayed(const Duration(milliseconds: 1000)); + + await StorageHelper().set( + LicenseKeys.vehiclesManager.value, + { + 'display': 'VISIVEL', + 'expirationDate': '', + 'startDate': '', + 'quantity': 0, + }, + ); + await $.pumpWidgetAndSettle(const App()); + + ff.navigatorKey.currentContext!.go('/vehiclesOnThePropertyPage'); + final String title = MenuEntry.entries // + .where((entry) => entry.key == 'FRE-HUB-VEHICLES') // + .map((entry) => entry.name) + .first; + + final PatrolFinder appBar = await $(AppBar) // + .waitUntilExists(); + final PatrolFinder titleAppBar = await appBar // + .$(title) + .waitUntilVisible(); + expect(titleAppBar, findsOneWidget); + + final PatrolFinder tab1 = await $(#TabView_Tab1) // + .waitUntilExists(); + final PatrolFinder tab2 = await $(#TabView_Tab2) // + .waitUntilExists(); + + await tab2.tap(); + await Future.delayed(const Duration(milliseconds: 500)); + await tab1.tap(); + + final PatrolFinder listViewFinder = await $(VehicleHistoryScreen) // + .$(ListView) + .waitUntilVisible(); + + expect(listViewFinder, findsOneWidget); + + final PatrolFinder entriesFinder = + await $(listViewFinder).$(CardItemTemplateComponentWidget).waitUntilVisible(); + + expect(entriesFinder, findsWidgets); + await $.pumpAndSettle(); + await Future.delayed(const Duration(milliseconds: 1000)); + }, + ); } static Future historyScreen() async { diff --git a/lib/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart b/lib/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart index b832653e..0b3ddd85 100644 --- a/lib/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart +++ b/lib/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart @@ -19,12 +19,10 @@ class BottomArrowLinkedLocalsComponentWidget extends StatefulWidget { ApiCallResponse? response; @override - State createState() => - _BottomArrowLinkedLocalsComponentWidgetState(); + State createState() => _BottomArrowLinkedLocalsComponentWidgetState(); } -class _BottomArrowLinkedLocalsComponentWidgetState - extends State { +class _BottomArrowLinkedLocalsComponentWidgetState extends State { late BottomArrowLinkedLocalsComponentModel _model; bool _loading = false; @@ -42,8 +40,7 @@ class _BottomArrowLinkedLocalsComponentWidgetState @override void initState() { super.initState(); - _model = - createModel(context, () => BottomArrowLinkedLocalsComponentModel()); + _model = createModel(context, () => BottomArrowLinkedLocalsComponentModel()); _localsFuture = _fetchLocals(); } @@ -109,14 +106,10 @@ class _BottomArrowLinkedLocalsComponentWidgetState if (isEnabled) { final local = locals[0]; - await StorageHelper() - .set(ProfileStorageKey.clientName.key, local['CLI_NOME']); - await StorageHelper() - .set(ProfileStorageKey.ownerName.key, local['CLU_OWNER_DSC']); - await StorageHelper() - .set(ProfileStorageKey.clientUUID.key, local['CLI_ID']); - await StorageHelper() - .set(ProfileStorageKey.ownerUUID.key, local['CLU_OWNER_ID']); + await StorageHelper().set(ProfileStorageKey.clientName.key, local['CLI_NOME']); + await StorageHelper().set(ProfileStorageKey.ownerName.key, local['CLU_OWNER_DSC']); + await StorageHelper().set(ProfileStorageKey.clientUUID.key, local['CLI_ID']); + await StorageHelper().set(ProfileStorageKey.ownerUUID.key, local['CLU_OWNER_ID']); context.pop(); return widget.response; @@ -140,22 +133,20 @@ class _BottomArrowLinkedLocalsComponentWidgetState return null; } - static Future _handleError( - BuildContext context, String errorMsg) async { + static Future _handleError(BuildContext context, String errorMsg) async { await DialogUtil.error(context, errorMsg); } Future _fetchResponseLink(String status, String cliID) async { try { await StorageHelper().set(ProfileStorageKey.clientUUID.key, cliID); - var response = await PhpGroup.resopndeVinculo.call(tarefa: status); + var response = await PhpGroup.respondeVinculo.call(tarefa: status); if (response.jsonBody['error'] == false) { return { 'error': false, - 'error_msg': FFLocalizations.of(context).getVariableText( - ptText: "Vínculo Ativado com Sucesso", - enText: "Link Activated Successfully") + 'error_msg': FFLocalizations.of(context) + .getVariableText(ptText: "Vínculo Ativado com Sucesso", enText: "Link Activated Successfully") }; } else { await StorageHelper().set(ProfileStorageKey.clientUUID.key, ''); @@ -163,8 +154,7 @@ class _BottomArrowLinkedLocalsComponentWidgetState } } catch (e, s) { await DialogUtil.errorDefault(context); - LogUtil.requestAPIFailed( - 'responderVinculo.php', '', 'Responder Vínculo', e, s); + LogUtil.requestAPIFailed('responderVinculo.php', '', 'Responder Vínculo', e, s); return { 'error': true, 'error_msg': FFLocalizations.of(context).getVariableText( @@ -189,17 +179,14 @@ class _BottomArrowLinkedLocalsComponentWidgetState Map _statusHashMap(dynamic local) { return Map.from({ if (local['CLU_STATUS'] == 'A') - FFLocalizations.of(context).getVariableText( - ptText: 'Ativo', - enText: 'Active'): FlutterFlowTheme.of(context).success + FFLocalizations.of(context).getVariableText(ptText: 'Ativo', enText: 'Active'): + FlutterFlowTheme.of(context).success else if (local['CLU_STATUS'] == 'B') - FFLocalizations.of(context).getVariableText( - ptText: 'Bloqueado', - enText: 'Blocked'): FlutterFlowTheme.of(context).error + FFLocalizations.of(context).getVariableText(ptText: 'Bloqueado', enText: 'Blocked'): + FlutterFlowTheme.of(context).error else - FFLocalizations.of(context).getVariableText( - ptText: 'Pendente', - enText: 'Pending'): FlutterFlowTheme.of(context).warning + FFLocalizations.of(context).getVariableText(ptText: 'Pendente', enText: 'Pending'): + FlutterFlowTheme.of(context).warning }); } @@ -212,21 +199,16 @@ class _BottomArrowLinkedLocalsComponentWidgetState statusHashMap: [_statusHashMap(local)], onTapCardItemAction: () async { if (local['CLU_STATUS'] == 'A') { - await StorageHelper() - .set(ProfileStorageKey.clientUUID.key, local['CLI_ID']); - await StorageHelper() - .set(ProfileStorageKey.clientName.key, local['CLI_NOME']); - await StorageHelper() - .set(ProfileStorageKey.ownerName.key, local['CLU_OWNER_DSC']); - await StorageHelper() - .set(ProfileStorageKey.ownerUUID.key, local['CLU_OWNER_ID']); + await StorageHelper().set(ProfileStorageKey.clientUUID.key, local['CLI_ID']); + await StorageHelper().set(ProfileStorageKey.clientName.key, local['CLI_NOME']); + await StorageHelper().set(ProfileStorageKey.ownerName.key, local['CLU_OWNER_DSC']); + await StorageHelper().set(ProfileStorageKey.ownerUUID.key, local['CLU_OWNER_ID']); context.pop(true); return true; } else if (local['CLU_STATUS'] == 'B') { String message = FFLocalizations.of(context).getVariableText( - ptText: - 'Local Bloqueado para Acesso, Entre em Contato com Administração', + ptText: 'Local Bloqueado para Acesso, Entre em Contato com Administração', enText: 'Location Blocked for Access, Contact Administration', ); @@ -242,8 +224,7 @@ class _BottomArrowLinkedLocalsComponentWidgetState String localName = local['CLI_NOME']; showAlertDialog( context, - FFLocalizations.of(context).getVariableText( - ptText: 'Ativar Vínculo', enText: 'Activate Link'), + FFLocalizations.of(context).getVariableText(ptText: 'Ativar Vínculo', enText: 'Activate Link'), FFLocalizations.of(context).getVariableText( ptText: 'Deseja aceitar o vínculo a $localName?', enText: 'Do you wish to accept the link to $localName?'), @@ -300,8 +281,7 @@ class _BottomArrowLinkedLocalsComponentWidgetState height: height - (height * 0.5), decoration: BoxDecoration( color: FlutterFlowTheme.of(context).primaryBackground, - borderRadius: const BorderRadius.only( - topLeft: Radius.circular(25), topRight: Radius.circular(25))), + borderRadius: const BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25))), child: Column( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.start, @@ -313,16 +293,13 @@ class _BottomArrowLinkedLocalsComponentWidgetState mainAxisSize: MainAxisSize.max, children: [ Center( - child: Text(FFLocalizations.of(context).getVariableText( - ptText: "Nenhum Local Encontrado.", - enText: "No local found")), + child: Text(FFLocalizations.of(context) + .getVariableText(ptText: "Nenhum Local Encontrado.", enText: "No local found")), ) ], ), ) - else if (_hasData == true && - _loading == false && - _localsWrap.isNotEmpty) + else if (_hasData == true && _loading == false && _localsWrap.isNotEmpty) Expanded(child: _listItems(context)), if (_loading == true) Container( @@ -339,8 +316,7 @@ class _BottomArrowLinkedLocalsComponentWidgetState padding: const EdgeInsets.only(top: 10), child: Center( child: Text( - FFLocalizations.of(context).getVariableText( - ptText: 'Escolha um local', enText: 'Choose a location'), + FFLocalizations.of(context).getVariableText(ptText: 'Escolha um local', enText: 'Choose a location'), overflow: TextOverflow.ellipsis, style: const TextStyle(fontWeight: FontWeight.bold), )))), diff --git a/lib/features/backend/api_requests/api_calls.dart b/lib/features/backend/api_requests/api_calls.dart index e73db478..1b205891 100644 --- a/lib/features/backend/api_requests/api_calls.dart +++ b/lib/features/backend/api_requests/api_calls.dart @@ -47,7 +47,7 @@ class PhpGroup extends Api { static GetMessagesCall getMessagesCall = GetMessagesCall(); static ChangeNotifica changeNotifica = ChangeNotifica(); static UpdateIDE updateIDE = UpdateIDE(); - static RespondeVinculo resopndeVinculo = RespondeVinculo(); + static RespondeVinculo respondeVinculo = RespondeVinculo(); static ChangePass changePass = ChangePass(); static ChangePanic changePanic = ChangePanic(); static DeleteAccount deleteAccount = DeleteAccount(); diff --git a/lib/features/local/data/data_sources/locals_remote_data_source.dart b/lib/features/local/data/data_sources/locals_remote_data_source.dart index 0babde3a..85ec65fa 100644 --- a/lib/features/local/data/data_sources/locals_remote_data_source.dart +++ b/lib/features/local/data/data_sources/locals_remote_data_source.dart @@ -224,7 +224,7 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource { enText: 'Device unlinked successfully', ptText: 'Dispositivo desvinculado com sucesso', ); - final bool status = await PhpGroup.resopndeVinculo.call(tarefa: 'I').then((value) async { + final bool status = await PhpGroup.respondeVinculo.call(tarefa: 'I').then((value) async { if (value.jsonBody['error'] == false) { await StorageHelper().set(ProfileStorageKey.clientName.key, ''); await StorageHelper().set(ProfileStorageKey.ownerName.key, ''); diff --git a/lib/features/local/utils/local_util.dart b/lib/features/local/utils/local_util.dart index 8de35b63..35b6ed37 100644 --- a/lib/features/local/utils/local_util.dart +++ b/lib/features/local/utils/local_util.dart @@ -11,13 +11,10 @@ import 'package:hub/shared/utils/log_util.dart'; class LocalUtil { static void handleError(BuildContext context, String errorMsg) async { - final String devUUID = - await StorageHelper().get(ProfileStorageKey.devUUID.key) ?? ''; - final String userUUID = - await StorageHelper().get(ProfileStorageKey.userUUID.key) ?? ''; + final String devUUID = await StorageHelper().get(ProfileStorageKey.devUUID.key) ?? ''; + final String userUUID = await StorageHelper().get(ProfileStorageKey.userUUID.key) ?? ''; final bool isAuthenticated = userUUID.isNotEmpty && devUUID.isNotEmpty; - final bool isDevLinked = - !errorMsg.contains('Esse dispositivo nao pertence a esse usuario'); + final bool isDevLinked = !errorMsg.contains('Esse dispositivo nao pertence a esse usuario'); log('() => isLinked: $errorMsg'); if (!isAuthenticated) { errorMsg = FFLocalizations.of(context).getVariableText( @@ -39,20 +36,15 @@ class LocalUtil { // await DialogUtil.error(context, errorMsg).whenComplete(() async => await LocalsRemoteDataSourceImpl().selectLocal(context, null)); } - static Future handleUnavailable( - BuildContext context, List locals) async { + static Future handleUnavailable(BuildContext context, List locals) async { log('() => isUnavailable'); try { - await StorageHelper() - .set(ProfileStorageKey.clientUUID.key, locals[0]['CLI_ID']); - await StorageHelper() - .set(ProfileStorageKey.ownerUUID.key, locals[0]['CLU_OWNER_ID']); - await StorageHelper() - .set(ProfileStorageKey.clientName.key, locals[0]['CLI_NOME']); - await StorageHelper() - .set(ProfileStorageKey.ownerName.key, locals[0]['CLU_OWNER_DSC']); + await StorageHelper().set(ProfileStorageKey.clientUUID.key, locals[0]['CLI_ID']); + await StorageHelper().set(ProfileStorageKey.ownerUUID.key, locals[0]['CLU_OWNER_ID']); + await StorageHelper().set(ProfileStorageKey.clientName.key, locals[0]['CLI_NOME']); + await StorageHelper().set(ProfileStorageKey.ownerName.key, locals[0]['CLU_OWNER_DSC']); - var response = await PhpGroup.resopndeVinculo.call(tarefa: 'A'); + var response = await PhpGroup.respondeVinculo.call(tarefa: 'A'); if (response.jsonBody['error'] == true) { await StorageHelper().set(ProfileStorageKey.clientUUID.key, ''); await StorageHelper().set(ProfileStorageKey.ownerUUID.key, ''); @@ -62,13 +54,10 @@ class LocalUtil { return false; } if (response.jsonBody['error'] == false) - return await LocalsRemoteDataSourceImpl() - .processProperty(context) - .then((value) => value); + return await LocalsRemoteDataSourceImpl().processProperty(context).then((value) => value); } catch (e, s) { await DialogUtil.errorDefault(context); - LogUtil.requestAPIFailed( - 'responderVinculo.php', '', 'Responder Vínculo', e, s); + LogUtil.requestAPIFailed('responderVinculo.php', '', 'Responder Vínculo', e, s); return false; } return false; @@ -76,19 +65,12 @@ class LocalUtil { static Future handleEnabled(BuildContext context, dynamic local) async { log('() => isEnabled'); - await StorageHelper() - .set(ProfileStorageKey.clientUUID.key, local['CLI_ID']); - await StorageHelper() - .set(ProfileStorageKey.ownerUUID.key, local['CLU_OWNER_ID']); - await StorageHelper() - .set(ProfileStorageKey.clientName.key, local['CLI_NOME']); - await StorageHelper() - .set(ProfileStorageKey.ownerName.key, local['CLU_OWNER_DSC']); - await StorageHelper() - .set(ProfileStorageKey.userName.key, local['USU_NOME']); - return await LocalsRemoteDataSourceImpl() - .processProperty(context) - .then((v) async { + await StorageHelper().set(ProfileStorageKey.clientUUID.key, local['CLI_ID']); + await StorageHelper().set(ProfileStorageKey.ownerUUID.key, local['CLU_OWNER_ID']); + await StorageHelper().set(ProfileStorageKey.clientName.key, local['CLI_NOME']); + await StorageHelper().set(ProfileStorageKey.ownerName.key, local['CLU_OWNER_DSC']); + await StorageHelper().set(ProfileStorageKey.userName.key, local['USU_NOME']); + return await LocalsRemoteDataSourceImpl().processProperty(context).then((v) async { if (v == true) return await LicenseRepositoryImpl().updateLicense(); return v; }); @@ -111,10 +93,8 @@ class LocalUtil { static Future updateStorageUtil(Map jsonBody) async { try { - await StorageHelper() - .set(LocalsStorageKey.whatsapp.key, jsonBody['whatsapp'] ?? false); - await StorageHelper().set( - LocalsStorageKey.provisional.key, jsonBody['provisional'] ?? false); + await StorageHelper().set(LocalsStorageKey.whatsapp.key, jsonBody['whatsapp'] ?? false); + await StorageHelper().set(LocalsStorageKey.provisional.key, jsonBody['provisional'] ?? false); await StorageHelper().set( LocalsStorageKey.pets.key, jsonBody['pet'] ?? false, @@ -136,21 +116,14 @@ class LocalUtil { ); } - await StorageHelper().set( - LocalsStorageKey.petAmount.key, - jsonBody['petAmountRegister']?.toString().isEmpty ?? true - ? '0' - : jsonBody['petAmountRegister'].toString()); - await StorageHelper().set(ProfileStorageKey.userName.key, - jsonBody['visitado']['VDO_NOME'] ?? ''); - await StorageHelper().set(ProfileStorageKey.userEmail.key, - jsonBody['visitado']['VDO_EMAIL'] ?? ''); - await StorageHelper().set( - LocalsStorageKey.provisional.key, jsonBody['provisional'] ?? false); + await StorageHelper().set(LocalsStorageKey.petAmount.key, + jsonBody['petAmountRegister']?.toString().isEmpty ?? true ? '0' : jsonBody['petAmountRegister'].toString()); + await StorageHelper().set(ProfileStorageKey.userName.key, jsonBody['visitado']['VDO_NOME'] ?? ''); + await StorageHelper().set(ProfileStorageKey.userEmail.key, jsonBody['visitado']['VDO_EMAIL'] ?? ''); + await StorageHelper().set(LocalsStorageKey.provisional.key, jsonBody['provisional'] ?? false); final bool isNewVersion = jsonBody['newVersion'] ?? false; - await StorageHelper() - .set(LocalsStorageKey.isNewVersion.key, isNewVersion); + await StorageHelper().set(LocalsStorageKey.isNewVersion.key, isNewVersion); return isNewVersion; } catch (e, s) { log('Error in _updateStorageUtil: $e', stackTrace: s); @@ -163,44 +136,30 @@ class LocalUtil { } static Future isInactived(List locals) async { - String cliUUID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; - return locals - .where( - (local) => local['CLI_ID'] != cliUUID && local['CLU_STATUS'] == 'A') - .isNotEmpty; + String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + return locals.where((local) => local['CLI_ID'] != cliUUID && local['CLU_STATUS'] == 'A').isNotEmpty; } static bool isPending(List locals) { - return locals - .where( - (local) => local['CLU_STATUS'] != 'B' && local['CLU_STATUS'] != 'A') - .isNotEmpty; + return locals.where((local) => local['CLU_STATUS'] != 'B' && local['CLU_STATUS'] != 'A').isNotEmpty; } static Future isUnselected() async { - String cliUUID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; - String cliName = - (await StorageHelper().get(ProfileStorageKey.clientName.key)) ?? ''; - String ownerUUID = - (await StorageHelper().get(ProfileStorageKey.ownerUUID.key)) ?? ''; + String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + String cliName = (await StorageHelper().get(ProfileStorageKey.clientName.key)) ?? ''; + String ownerUUID = (await StorageHelper().get(ProfileStorageKey.ownerUUID.key)) ?? ''; return cliUUID.isEmpty && cliName.isEmpty && ownerUUID.isEmpty; } static Future isSelected(bool isInactived) async { - String cliUUID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; - String cliName = - (await StorageHelper().get(ProfileStorageKey.clientName.key)) ?? ''; + String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + String cliName = (await StorageHelper().get(ProfileStorageKey.clientName.key)) ?? ''; return cliUUID.isNotEmpty && cliName.isNotEmpty && isInactived; } static Future isAvailable() async { - String cliUUID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; - String cliName = - (await StorageHelper().get(ProfileStorageKey.clientName.key)) ?? ''; + String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + String cliName = (await StorageHelper().get(ProfileStorageKey.clientName.key)) ?? ''; return cliUUID.isNotEmpty && cliName.isNotEmpty; } } diff --git a/lib/features/menu/data/data_sources/menu_local_data_source.dart b/lib/features/menu/data/data_sources/menu_local_data_source.dart index 796378cb..b736ed41 100644 --- a/lib/features/menu/data/data_sources/menu_local_data_source.dart +++ b/lib/features/menu/data/data_sources/menu_local_data_source.dart @@ -9,23 +9,16 @@ import 'package:hub/shared/extensions/dialog_extensions.dart'; import 'package:hub/shared/utils/path_util.dart'; abstract class MenuLocalDataSource { - Future addMenuEntry(Key key, EnumMenuItem item, - List entries, IconData icon, String text, Function() action); + Future addMenuEntry( + Key key, EnumMenuItem item, List entries, IconData icon, String text, Function() action); - Future processDisplayDefault( - EnumMenuItem item, MenuEntry opt, List entries); + Future processDisplayDefault(EnumMenuItem item, MenuEntry opt, List entries); - Future handleMenu(EnumMenuItem item, EnumDisplay display, MenuEntry opt, - List entries); - - Future processStartDate(String startDate, MenuEntry entry); - - Future processExpirationDate(String expirationDate, MenuEntry entry); + Future handleMenu(EnumMenuItem item, EnumDisplay display, MenuEntry opt, List entries); } class MenuLocalDataSourceImpl implements MenuLocalDataSource { - static final MenuLocalDataSourceImpl _instance = - MenuLocalDataSourceImpl._internal(); + static final MenuLocalDataSourceImpl _instance = MenuLocalDataSourceImpl._internal(); factory MenuLocalDataSourceImpl() => _instance; @@ -52,12 +45,9 @@ class MenuLocalDataSourceImpl implements MenuLocalDataSource { } @override - Future processDisplayDefault( - EnumMenuItem item, MenuEntry opt, List entries) async { + Future processDisplayDefault(EnumMenuItem item, MenuEntry opt, List entries) async { if (opt.key == 'FRE-HUB-LOGOUT') { - await addMenuEntry( - ValueKey(opt.key), item, entries, opt.icon, opt.name, - () async { + await addMenuEntry(ValueKey(opt.key), item, entries, opt.icon, opt.name, () async { await AuthenticationService.signOut(navigatorKey.currentContext!); }); return true; @@ -66,23 +56,17 @@ class MenuLocalDataSourceImpl implements MenuLocalDataSource { } @override - Future handleMenu(EnumMenuItem item, EnumDisplay display, MenuEntry opt, - List entries) async { + Future handleMenu(EnumMenuItem item, EnumDisplay display, MenuEntry opt, List entries) async { try { switch (display.value) { case 'VISIVEL': - await addMenuEntry( - ValueKey(opt.key), item, entries, opt.icon, opt.name, - () async { + await addMenuEntry(ValueKey(opt.key), item, entries, opt.icon, opt.name, () async { await PathUtil.nav(opt.route); }); break; case 'DESABILITADO': - await addMenuEntry( - ValueKey(opt.key), item, entries, opt.icon, opt.name, - () async { - await DialogUnavailable.unavailableFeature( - navigatorKey.currentContext!); + await addMenuEntry(ValueKey(opt.key), item, entries, opt.icon, opt.name, () async { + await DialogUnavailable.unavailableFeature(navigatorKey.currentContext!); }); break; case 'INVISIVEL': @@ -92,30 +76,4 @@ class MenuLocalDataSourceImpl implements MenuLocalDataSource { log('Error processing display for module ${opt.key}: $e'); } } - - @override - Future processStartDate(String startDate, MenuEntry opt) async { - try { - if (startDate.isEmpty) return true; - final start = DateTime.tryParse(startDate); - if (start == null) return false; - return DateTime.now().isAfter(start); - } catch (e) { - log('Error processing start date for module ${opt.key}: $e'); - } - return false; - } - - @override - Future processExpirationDate( - String expirationDate, MenuEntry opt) async { - try { - if (expirationDate.isEmpty) return false; - final expiration = DateTime.tryParse(expirationDate); - return expiration != null && DateTime.now().isAfter(expiration); - } catch (e) { - log('Error processing expiration date for module ${opt.key}: $e'); - } - return false; - } } diff --git a/lib/features/menu/data/repositories/menu_repository_impl.dart b/lib/features/menu/data/repositories/menu_repository_impl.dart index 96eec795..bf59361b 100644 --- a/lib/features/menu/data/repositories/menu_repository_impl.dart +++ b/lib/features/menu/data/repositories/menu_repository_impl.dart @@ -4,20 +4,19 @@ import 'package:hub/features/menu/index.dart'; import 'package:hub/features/module/index.dart'; import 'package:hub/features/storage/index.dart'; import 'package:hub/flutter_flow/custom_functions.dart'; +import 'package:hub/shared/utils/datetime_util.dart'; class MenuRepositoryImpl implements MenuRepository { final MenuLocalDataSource menuDataSource = MenuLocalDataSourceImpl(); @override - Future> entries2Items( - List menuEntries, EnumMenuItem menuItem) async { + Future> entries2Items(List menuEntries, EnumMenuItem menuItem) async { List entries = []; // final bool isNewVersion = await StorageHelper().get(KeychainStorageKey.isNewVersion.value).then((v) => v.toBoolean()); try { for (var entry in menuEntries) { - final bool isDefault = await menuDataSource.processDisplayDefault( - menuItem, entry, entries); + final bool isDefault = await menuDataSource.processDisplayDefault(menuItem, entry, entries); if (isDefault) continue; final licenseValue = await LicenseRepositoryImpl().getModule(entry.key); if (licenseValue != null) { @@ -25,22 +24,18 @@ class MenuRepositoryImpl implements MenuRepository { final display = EnumDisplay.fromString(licenseMap['display']); final startDate = licenseMap['startDate'] ?? ''; final expirationDate = licenseMap['expirationDate'] ?? ''; - final isStarted = - await menuDataSource.processStartDate(startDate, entry); - final isExpired = - await menuDataSource.processExpirationDate(expirationDate, entry); + final isStarted = await DateTimeUtil.processStartDate(startDate); + final isExpired = await DateTimeUtil.processExpirationDate(expirationDate); if (isStarted && !isExpired) { await menuDataSource.handleMenu(menuItem, display, entry, entries); } if (isExpired) { log('Entry ${entry.key} is expired'); - await menuDataSource.handleMenu( - menuItem, EnumDisplay.inactive, entry, entries); + await menuDataSource.handleMenu(menuItem, EnumDisplay.inactive, entry, entries); } if (!isStarted) { log('Entry ${entry.key} is not started'); - await menuDataSource.handleMenu( - menuItem, EnumDisplay.inactive, entry, entries); + await menuDataSource.handleMenu(menuItem, EnumDisplay.inactive, entry, entries); } } } @@ -50,11 +45,9 @@ class MenuRepositoryImpl implements MenuRepository { return entries; } - Future processDisplay( - Map module, bool isNewVersion) async { + Future processDisplay(Map module, bool isNewVersion) async { if (await _shouldUpdateDisplay(module, isNewVersion)) { - final displayValue = - module['display'] == EnumDisplay.active ? 'VISIVEL' : 'INVISIVEL'; + final displayValue = module['display'] == EnumDisplay.active ? 'VISIVEL' : 'INVISIVEL'; await LicenseLocalDataSourceImpl(DatabaseService.database) .setDisplayByKey(['FRE-HUB-ABOUT-PROPERTY'], displayValue); return EnumDisplay.fromString(displayValue); @@ -63,13 +56,8 @@ class MenuRepositoryImpl implements MenuRepository { return EnumDisplay.fromString(module['display']); } - Future _shouldUpdateDisplay( - Map module, bool isNewVersion) async { - const keysToCheck = [ - LicenseKeys.residents, - LicenseKeys.vehicles, - LicenseKeys.openedVisits - ]; + Future _shouldUpdateDisplay(Map module, bool isNewVersion) async { + const keysToCheck = [LicenseKeys.residents, LicenseKeys.vehicles, LicenseKeys.openedVisits]; return isNewVersion && keysToCheck.any((key) => module['key'] == key.value); } } diff --git a/lib/pages/vehicles_on_the_property/vehicle_model.dart b/lib/pages/vehicles_on_the_property/vehicle_model.dart index 4732e9ba..0e225a37 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_model.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_model.dart @@ -5,7 +5,15 @@ import 'package:hub/flutter_flow/index.dart'; import 'package:hub/pages/vehicles_on_the_property/vehicles_on_the_property.dart'; import 'package:hub/shared/utils/index.dart'; -class VehicleModel extends FlutterFlowModel { +/// [VehicleModel] is a class that contains the business logic of the vehicle page. +class VehicleModel extends FlutterFlowModel + with _BaseVehiclePage, _VehicleHistoryScreenModel, _VehicleRegisterScreenModel, _VehicleUpdateScreenModel { + /// [VehicleModel] is a singleton class that contains the business logic of the vehicle page. + static VehicleModel? _instance = VehicleModel._internal(); + VehicleModel._internal(); + factory VehicleModel() => _instance ?? VehicleModel._internal(); + static void resetInstance() => _instance = null; + @override void initState(BuildContext context) { resetInstance(); @@ -36,25 +44,31 @@ class VehicleModel extends FlutterFlowModel { textFieldControllerModel!.dispose(); } - static VehicleModel? _instance = VehicleModel._internal(); - VehicleModel._internal(); - factory VehicleModel() => _instance ?? VehicleModel._internal(); - static void resetInstance() => _instance = null; - - dynamic item; - String? vehicleId; - - late final TabController tabBarController; - VoidCallback? onUpdateVehicle; - VoidCallback? onRegisterVehicle; - VoidCallback? safeSetState; - final GlobalKey registerFormKey = GlobalKey(); final GlobalKey updateFormKey = GlobalKey(); - ApiCallResponse? vehicleResponse; - bool isEditing = false; + Future initAsync() async {} + + bool isFormValid(BuildContext context) { + if (registerFormKey.currentState == null) return false; + return registerFormKey.currentState!.validate(); + } +} + +/// [_BaseVehiclePage] is a mixin that contains the base logic of the vehicle page. +mixin class _BaseVehiclePage { + int count = 0; + late final VehicleModel model; + late final TabController tabBarController; + dynamic item; BuildContext context = navigatorKey.currentContext!; + bool isEditing = false; + String? vehicleId; + ApiCallResponse? vehicleResponse; + + VoidCallback? onUpdateVehicle; + VoidCallback? onRegisterVehicle; + VoidCallback? safeSetState; FocusNode? textFieldFocusLicensePlate; TextEditingController? textFieldControllerLicensePlate; @@ -105,8 +119,35 @@ class VehicleModel extends FlutterFlowModel { return null; } - Future initAsync() async {} + void switchTab(int index) { + tabBarController.animateTo(index); + if (index == 0) handleEditingChanged(false); + safeSetState?.call(); + } + void clearFields() async { + textFieldControllerLicensePlate!.clear(); + textFieldControllerColor!.clear(); + textFieldControllerModel!.clear(); + } + + void handleEditingChanged(bool editing) { + isEditing = editing; + clearFields(); + } + + void setEditForm() { + if (item != null) { + vehicleId = item['vehicleId']; + textFieldControllerLicensePlate!.text = item['licensePlate']; + textFieldControllerColor!.text = item['color']; + textFieldControllerModel!.text = item['model']; + } + } +} + +/// [_VehicleHistoryScreenModel] is a mixin that contains the business logic of the vehicle history page. +mixin _VehicleHistoryScreenModel on _BaseVehiclePage { Map? generateStatusColorMap(dynamic uItem) { final statusMap = { "ATI": { @@ -179,147 +220,183 @@ class VehicleModel extends FlutterFlowModel { ), ); + final updateText = FFLocalizations.of(context).getVariableText(ptText: 'Editar', enText: 'Edit'); + final updateIcon = Icon(Icons.edit, color: iconButtonColor); + Future updateOnPressed() async { + context.pop(); + isEditing = true; + item = item; + + switchTab(1); + setEditForm(); + } + + final cancelText = FFLocalizations.of(context).getVariableText(ptText: 'Cancelar', enText: 'Cancel'); + final cancelIcon = Icon(Icons.close, color: iconButtonColor); + Future cancelOnPressed() async { + showAlertDialog( + context, + FFLocalizations.of(context).getVariableText( + ptText: 'Cancelar Solicitação', + enText: 'Cancel Request', + ), + FFLocalizations.of(context).getVariableText( + ptText: 'Você tem certeza que deseja cancelar essa solicitação?', + enText: 'Are you sure you want to delete this request?', + ), + () async => await processCancelRequest(item['status']), + ); + } + + final deleteText = FFLocalizations.of(context).getVariableText(ptText: 'Excluir', enText: 'Delete'); + final deleteIcon = Icon(Icons.delete, color: iconButtonColor); + Future deleteOnPressed() async { + showAlertDialog( + context, + FFLocalizations.of(context).getVariableText( + ptText: 'Excluir Veículo', + enText: 'Delete Vehicle', + ), + FFLocalizations.of(context).getVariableText( + ptText: 'Você tem certeza que deseja excluir esse veículo?', + enText: 'Are you sure you want to delete this vehicle?', + ), + () async => await processDeleteRequest(), + ); + } + return [ if (item['status'].contains('AGU')) FFButtonWidget( - text: FFLocalizations.of(context).getVariableText( - ptText: 'Editar', - enText: 'Edit', - ), - icon: Icon( - Icons.close, - color: iconButtonColor, - ), - onPressed: () async { - context.pop(); - isEditing = true; - item = item; - - switchTab(1); - setEditForm(); - }, + text: updateText, + icon: updateIcon, + onPressed: updateOnPressed, options: buttonOptions, ), if (item['status'].contains('APR') || item['status'].contains('AGU')) FFButtonWidget( - text: FFLocalizations.of(context).getVariableText( - ptText: 'Cancelar', - enText: 'Cancel', - ), - icon: Icon(Icons.close, color: iconButtonColor), - onPressed: () async { - showAlertDialog( - context, - FFLocalizations.of(context).getVariableText( - ptText: 'Cancelar Solicitação', - enText: 'Cancel Request', - ), - FFLocalizations.of(context).getVariableText( - ptText: 'Você tem certeza que deseja cancelar essa solicitação?', - enText: 'Are you sure you want to delete this request?', - ), () async { - int id = item['vehicleId']; - await PhpGroup.deleteVehicle.call(vehicleId: id).then((value) { - context.pop(value); - context.pop(value); - - if (value.jsonBody['error'] == false) { - showSnackbar( - context, - FFLocalizations.of(context).getVariableText( - ptText: 'Erro ao cancelar solicitação', - enText: 'Error canceling request', - ), - true, - ); - } else if (value.jsonBody['error'] == true) { - showSnackbar( - context, - FFLocalizations.of(context).getVariableText( - enText: 'Success canceling request', - ptText: 'Succeso ao cancelar solicitação', - ), - false, - ); - } - }).catchError((err, stack) { - context.pop(); - showSnackbar( - context, - FFLocalizations.of(context).getVariableText( - enText: 'Error canceling request', - ptText: 'Erro ao cancelar solicitação', - ), - true, - ); - }); - }); - }, + text: cancelText, + icon: cancelIcon, + onPressed: cancelOnPressed, options: buttonOptions, ), if (item['status'].contains('ATI')) FFButtonWidget( - text: FFLocalizations.of(context).getVariableText( - ptText: 'Excluir', - enText: 'Delete', - ), - icon: Icon( - Icons.close, - color: iconButtonColor, - ), - onPressed: () async { - showAlertDialog( - context, - FFLocalizations.of(context).getVariableText( - ptText: 'Excluir Veículo', - enText: 'Delete Vehicle', - ), - FFLocalizations.of(context).getVariableText( - ptText: 'Você tem certeza que deseja excluir esse veículo?', - enText: 'Are you sure you want to delete this vehicle?', - ), () async { - int id = item['vehicleId']; - await PhpGroup.deleteVehicle.call(vehicleId: id).then((value) { - context.pop(value); - context.pop(value); - - if (value == false) { - showSnackbar( - context, - FFLocalizations.of(context).getVariableText( - ptText: 'Erro ao excluir veículo', - enText: 'Error deleting vehicle', - ), - true, - ); - } else if (value == true) { - showSnackbar( - context, - FFLocalizations.of(context).getVariableText( - enText: 'Success deleting vehicle', - ptText: 'Succeso ao excluir veículo', - ), - false, - ); - } - }).catchError((err, stack) { - context.pop(); - showSnackbar( - context, - FFLocalizations.of(context).getVariableText( - enText: 'Error deleting vehicle', - ptText: 'Erro ao excluir veículo', - ), - true, - ); - }); - }); - }, + text: deleteText, + icon: deleteIcon, + onPressed: deleteOnPressed, options: buttonOptions, ), ]; } + Future processDeleteRequest() async { + int id = item['vehicleId']; + await PhpGroup.deleteVehicle.call(vehicleId: id).then((value) { + context.pop(value); + context.pop(value); + + // ignore: unrelated_type_equality_checks + if (value == false) { + showSnackbar( + context, + FFLocalizations.of(context).getVariableText( + ptText: 'Erro ao excluir veículo', + enText: 'Error deleting vehicle', + ), + true, + ); + // ignore: unrelated_type_equality_checks + } else if (value == true) { + showSnackbar( + context, + FFLocalizations.of(context).getVariableText( + enText: 'Success deleting vehicle', + ptText: 'Succeso ao excluir veículo', + ), + false, + ); + } + }).catchError((err, stack) { + context.pop(); + showSnackbar( + context, + FFLocalizations.of(context).getVariableText( + enText: 'Error deleting vehicle', + ptText: 'Erro ao excluir veículo', + ), + true, + ); + }); + } + + Future processCancelRequest(String status) async { + late final ApiCallResponse value; + try { + switch (status) { + case 'APR_CREATE': + value = await processCancelDeleteRequest(); + break; + case 'AGU_CHANGE': + value = await processCancelUpdateRequest(); + break; + case 'APR_DELETE': + value = await processCancelCreateRequest(); + break; + default: + break; + } + + context.pop(value); + context.pop(value); + + if (value.jsonBody['error'] == false) { + showSnackbar( + context, + FFLocalizations.of(context).getVariableText( + ptText: 'Erro ao cancelar solicitação', + enText: 'Error canceling request', + ), + true, + ); + } else if (value.jsonBody['error'] == true) { + showSnackbar( + context, + FFLocalizations.of(context).getVariableText( + enText: 'Success canceling request', + ptText: 'Succeso ao cancelar solicitação', + ), + false, + ); + } + } catch (err) { + context.pop(); + showSnackbar( + context, + FFLocalizations.of(context).getVariableText( + enText: 'Error canceling request', + ptText: 'Erro ao cancelar solicitação', + ), + true, + ); + } + } + + Future processCancelDeleteRequest() async { + final int id = item['vehicleId']; + return await PhpGroup.deleteVehicle.call(vehicleId: id); + } + + Future processCancelUpdateRequest() async { + final int id = item['vehicleId']; + return await PhpGroup.deleteVehicle.call(vehicleId: id); + } + + Future processCancelCreateRequest() async { + final int id = item['vehicleId']; + return await PhpGroup.deleteVehicle.call(vehicleId: id); + } + Map generateLabelsHashMap(dynamic item) { return { if (item['model'] != null && item['model'] != '') @@ -354,21 +431,42 @@ class VehicleModel extends FlutterFlowModel { statusHashMap: [status], ); } +} - void setEditForm() { - if (item != null) { - vehicleId = item['vehicleId']; - textFieldControllerLicensePlate!.text = item['licensePlate']; - textFieldControllerColor!.text = item['color']; - textFieldControllerModel!.text = item['model']; +/// [_VehicleRegisterScreenModel] is a mixin that contains the business logic of the vehicle register page. +mixin _VehicleRegisterScreenModel on _BaseVehiclePage { + Future registerVehicle() async { + final response = await PhpGroup.registerVehicle.call( + licensePlate: textFieldControllerLicensePlate!.text, + color: textFieldControllerColor!.text, + model: textFieldControllerModel!.text, + ); + if (response.jsonBody['error'] == false) { + await DialogUtil.success( + context, + FFLocalizations.of(context).getVariableText( + ptText: 'Veículo cadastrado com sucesso', + enText: 'Vehicle registered successfully', + )).then((_) async { + switchTab(0); + }); + } else { + String errorMessage; + try { + errorMessage = response.jsonBody['message']; + } catch (e) { + errorMessage = FFLocalizations.of(context).getVariableText( + ptText: 'Erro ao cadastrar veículo', + enText: 'Error registering vehicle', + ); + } + await DialogUtil.error(context, errorMessage); } } +} - bool isFormValid(BuildContext context) { - if (registerFormKey.currentState == null) return false; - return registerFormKey.currentState!.validate(); - } - +/// [_VehicleUpdateScreenModel] is a mixin that contains the business logic of the vehicle update page. +mixin _VehicleUpdateScreenModel on _BaseVehiclePage { Future updateVehicle() async { final response = await PhpGroup.updateVehicle.call( licensePlate: textFieldControllerLicensePlate!.text, @@ -398,50 +496,4 @@ class VehicleModel extends FlutterFlowModel { await DialogUtil.error(context, errorMessage); } } - - Future registerVehicle() async { - final response = await PhpGroup.registerVehicle.call( - licensePlate: textFieldControllerLicensePlate!.text, - color: textFieldControllerColor!.text, - model: textFieldControllerModel!.text, - ); - if (response.jsonBody['error'] == false) { - await DialogUtil.success( - context, - FFLocalizations.of(context).getVariableText( - ptText: 'Veículo cadastrado com sucesso', - enText: 'Vehicle registered successfully', - )).then((_) async { - switchTab(0); - }); - } else { - String errorMessage; - try { - errorMessage = response.jsonBody['message']; - } catch (e) { - errorMessage = FFLocalizations.of(context).getVariableText( - ptText: 'Erro ao cadastrar veículo', - enText: 'Error registering vehicle', - ); - } - await DialogUtil.error(context, errorMessage); - } - } - - void switchTab(int index) { - tabBarController.animateTo(index); - if (index == 0) handleEditingChanged(false); - safeSetState?.call(); - } - - void clearFields() async { - textFieldControllerLicensePlate!.clear(); - textFieldControllerColor!.clear(); - textFieldControllerModel!.clear(); - } - - void handleEditingChanged(bool editing) { - isEditing = editing; - clearFields(); - } } diff --git a/lib/pages/vehicles_on_the_property/vehicle_register_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_register_screen.dart index b6dd5004..07b786a3 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_register_screen.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_register_screen.dart @@ -14,89 +14,97 @@ class VehicleRegisterScreen extends StatefulWidget { class _VehicleRegisterScreenState extends State { @override Widget build(BuildContext context) { - double limitedInputFontSize = LimitedFontSizeUtil.getInputFontSize(context); - double limitedHeaderFontSize = LimitedFontSizeUtil.getHeaderFontSize(context); - double limitedSubHeaderFontSize = LimitedFontSizeUtil.getSubHeaderFontSize(context); - return SingleChildScrollView( child: Column( mainAxisSize: MainAxisSize.max, children: [ - Align( - alignment: const AlignmentDirectional(-1.0, 0.0), - child: Padding( - padding: const EdgeInsetsDirectional.fromSTEB(24.0, 20, 0.0, 15), - child: Text( - FFLocalizations.of(context).getVariableText( - ptText: 'Preencha o formulário de cadastro com os dados do seu veículo', - enText: 'Fill out the registration form with your vehicle data', - ), - textAlign: TextAlign.start, - style: FlutterFlowTheme.of(context).bodyMedium.override( - fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily, - letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).bodyMediumFamily), - fontSize: limitedHeaderFontSize, - ), - ), - ), - ), - Form( - key: widget.model.registerFormKey, - autovalidateMode: AutovalidateMode.onUserInteraction, - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - CustomInputUtil( - controller: widget.model.textFieldControllerLicensePlate, - validator: widget.model.textControllerLicensePlateValidator.asValidator(context), - focusNode: widget.model.textFieldFocusLicensePlate, - labelText: FFLocalizations.of(context).getVariableText(ptText: 'Placa', enText: 'License Plate'), - hintText: FFLocalizations.of(context).getVariableText(ptText: 'Placa', enText: 'License Plate'), - suffixIcon: Symbols.format_color_text, - haveMaxLength: true, - onChanged: (value) => setState(() {}), - maxLength: 80, - ), - CustomInputUtil( - controller: widget.model.textFieldControllerModel, - validator: widget.model.textControllerModelValidator.asValidator(context), - focusNode: widget.model.textFieldFocusModel, - labelText: FFLocalizations.of(context).getVariableText(ptText: 'Modelo', enText: 'Model'), - hintText: FFLocalizations.of(context).getVariableText( - ptText: 'Ex: Voyage, Ford', - enText: 'e.g. Voyage, Ford', - ), - suffixIcon: Symbols.car_repair, - haveMaxLength: true, - onChanged: (value) => setState(() {}), - maxLength: 80, - ), - CustomInputUtil( - controller: widget.model.textFieldControllerColor, - validator: widget.model.textControllerColorValidator.asValidator(context), - focusNode: widget.model.textFieldFocusColor, - labelText: FFLocalizations.of(context).getVariableText(ptText: 'Cor', enText: 'Color'), - hintText: FFLocalizations.of(context).getVariableText( - ptText: 'Ex: Preto, Amarelo, Branco', - enText: 'e.g. Black, Yellow, White', - ), - suffixIcon: Symbols.palette, - haveMaxLength: true, - onChanged: (value) => setState(() {}), - maxLength: 80, - ), - Padding( - padding: const EdgeInsets.fromLTRB(70, 20, 70, 30), - child: SubmitButtonUtil( - labelText: FFLocalizations.of(context).getVariableText(ptText: 'Cadastrar', enText: 'Register'), - onPressed: widget.model.isFormValid(context) ? widget.model.registerVehicle : null), - ), - ], - )), + _buildHeader(context), + _buildBody(context), ], ), ); } + + Form _buildBody(BuildContext context) { + return Form( + key: widget.model.registerFormKey, + autovalidateMode: AutovalidateMode.onUserInteraction, + child: Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceEvenly, + children: [ + CustomInputUtil( + controller: widget.model.textFieldControllerLicensePlate, + validator: widget.model.textControllerLicensePlateValidator.asValidator(context), + focusNode: widget.model.textFieldFocusLicensePlate, + labelText: FFLocalizations.of(context).getVariableText(ptText: 'Placa', enText: 'License Plate'), + hintText: FFLocalizations.of(context).getVariableText(ptText: 'Placa', enText: 'License Plate'), + suffixIcon: Symbols.format_color_text, + haveMaxLength: true, + onChanged: (value) => setState(() {}), + maxLength: 80, + ), + CustomInputUtil( + controller: widget.model.textFieldControllerModel, + validator: widget.model.textControllerModelValidator.asValidator(context), + focusNode: widget.model.textFieldFocusModel, + labelText: FFLocalizations.of(context).getVariableText(ptText: 'Modelo', enText: 'Model'), + hintText: FFLocalizations.of(context).getVariableText( + ptText: 'Ex: Voyage, Ford', + enText: 'e.g. Voyage, Ford', + ), + suffixIcon: Symbols.car_repair, + haveMaxLength: true, + onChanged: (value) => setState(() {}), + maxLength: 80, + ), + CustomInputUtil( + controller: widget.model.textFieldControllerColor, + validator: widget.model.textControllerColorValidator.asValidator(context), + focusNode: widget.model.textFieldFocusColor, + labelText: FFLocalizations.of(context).getVariableText(ptText: 'Cor', enText: 'Color'), + hintText: FFLocalizations.of(context).getVariableText( + ptText: 'Ex: Preto, Amarelo, Branco', + enText: 'e.g. Black, Yellow, White', + ), + suffixIcon: Symbols.palette, + haveMaxLength: true, + onChanged: (value) => setState(() {}), + maxLength: 80, + ), + Padding( + padding: const EdgeInsets.fromLTRB(70, 20, 70, 30), + child: SubmitButtonUtil( + labelText: FFLocalizations.of(context).getVariableText(ptText: 'Cadastrar', enText: 'Register'), + onPressed: widget.model.isFormValid(context) ? widget.model.registerVehicle : null), + ), + ], + )); + } + + Align _buildHeader(BuildContext context) { + // double limitedInputFontSize = LimitedFontSizeUtil.getInputFontSize(context); + double limitedHeaderFontSize = LimitedFontSizeUtil.getHeaderFontSize(context); + // double limitedSubHeaderFontSize = LimitedFontSizeUtil.getSubHeaderFontSize(context); + + return Align( + alignment: const AlignmentDirectional(-1.0, 0.0), + child: Padding( + padding: const EdgeInsetsDirectional.fromSTEB(24.0, 20, 0.0, 15), + child: Text( + FFLocalizations.of(context).getVariableText( + ptText: 'Preencha o formulário de cadastro com os dados do seu veículo', + enText: 'Fill out the registration form with your vehicle data', + ), + textAlign: TextAlign.start, + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).bodyMediumFamily), + fontSize: limitedHeaderFontSize, + ), + ), + ), + ); + } } diff --git a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart index 468bd50f..c96108fb 100644 --- a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart +++ b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart @@ -14,6 +14,7 @@ import 'package:hub/flutter_flow/flutter_flow_util.dart'; import 'package:hub/flutter_flow/index.dart'; import 'package:hub/pages/vehicles_on_the_property/vehicle_model.dart'; import 'package:hub/shared/utils/dialog_util.dart'; +import 'package:hub/shared/utils/license_util.dart'; import 'package:hub/shared/utils/limited_text_size.dart'; import 'package:hub/shared/utils/log_util.dart'; import 'package:material_symbols_icons/symbols.dart'; @@ -27,6 +28,7 @@ class VehiclePage extends StatefulWidget { const VehiclePage({super.key}); @override + // ignore: library_private_types_in_public_api _VehiclePageState createState() => _VehiclePageState(); } @@ -55,24 +57,24 @@ class _VehiclePageState extends State with TickerProviderStateMixin }; } - @override - void dispose() { - super.dispose(); - } + // @override + // void dispose() { + // super.dispose(); + // } @override Widget build(BuildContext context) { final backgroundColor = FlutterFlowTheme.of(context).primaryBackground; return Scaffold( backgroundColor: backgroundColor, - appBar: _buildAppBar(context), - body: buildBody(context), + appBar: _buildHeader(context), + body: _buildBody(context), ); } /// [Body] of the page. - Widget buildBody(BuildContext context) { - Widget progressEvent() { + FutureBuilder _buildBody(BuildContext context) { + Widget progressIndicator() { return CircularProgressIndicator( valueColor: AlwaysStoppedAnimation( FlutterFlowTheme.of(context).primary, @@ -80,22 +82,14 @@ class _VehiclePageState extends State with TickerProviderStateMixin ); } - Widget errorEvent() { - WidgetsBinding.instance.addPostFrameCallback((_) async { - context.pop(); - await DialogUtil.errorDefault(navigatorKey.currentContext!); - }); - return progressEvent(); - } - - return FutureBuilder( - future: LicenseRepositoryImpl().getModule('FRE-HUB-VEHICLES-MANAGER'), + return FutureBuilder( + future: _initializeModule(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { - return progressEvent(); + return progressIndicator(); } else if (snapshot.hasError) { - return errorEvent(); - } else if (snapshot.hasData && snapshot.data!.isNotEmpty) { + return progressIndicator(); + } else if (snapshot.hasData && snapshot.data == true) { return _buildVehicleManager(context); } else { return _buildVehicleHistory(context); @@ -104,6 +98,19 @@ class _VehiclePageState extends State with TickerProviderStateMixin ); } + Future _initializeModule() async { + try { + final module = await LicenseRepositoryImpl().getModule('FRE-HUB-VEHICLES-MANAGER'); + return await LicenseUtil.processModule(module); + } catch (e) { + WidgetsBinding.instance.addPostFrameCallback((_) async { + context.pop(); + await DialogUtil.errorDefault(navigatorKey.currentContext!); + }); + return false; + } + } + void onEditingChanged(bool value) { setState(() { _model.handleEditingChanged(value); @@ -134,8 +141,8 @@ class _VehiclePageState extends State with TickerProviderStateMixin } /// ----------------------------------- - /// [AppBar] with the title of the page. - PreferredSizeWidget _buildAppBar(BuildContext context) { + /// [Header] of the page. + PreferredSizeWidget _buildHeader(BuildContext context) { final theme = FlutterFlowTheme.of(context); final backgroundColor = theme.primaryBackground; final primaryText = theme.primaryText; diff --git a/lib/shared/utils/datetime_util.dart b/lib/shared/utils/datetime_util.dart new file mode 100644 index 00000000..cbbc5cb9 --- /dev/null +++ b/lib/shared/utils/datetime_util.dart @@ -0,0 +1,26 @@ +import 'dart:developer'; + +class DateTimeUtil { + static Future processStartDate(String startDate) async { + try { + if (startDate.isEmpty) return true; + final start = DateTime.tryParse(startDate); + if (start == null) return false; + return DateTime.now().isAfter(start); + } catch (e) { + log('Error processing start date for module: $e'); + } + return false; + } + + static Future processExpirationDate(String expirationDate) async { + try { + if (expirationDate.isEmpty) return false; + final expiration = DateTime.tryParse(expirationDate); + return expiration != null && DateTime.now().isAfter(expiration); + } catch (e) { + log('Error processing expiration date for module: $e'); + } + return false; + } +} diff --git a/lib/shared/utils/license_util.dart b/lib/shared/utils/license_util.dart new file mode 100644 index 00000000..78e8bcb8 --- /dev/null +++ b/lib/shared/utils/license_util.dart @@ -0,0 +1,17 @@ +import 'package:hub/features/module/index.dart'; +import 'package:hub/flutter_flow/index.dart'; +import 'package:hub/shared/utils/datetime_util.dart'; + +class LicenseUtil { + static Future processModule(String? module) async { + if (module == null) return false; + final moduleMap = await stringToMap(module); + final startDate = moduleMap['startDate'] ?? ''; + final expirationDate = moduleMap['expirationDate'] ?? ''; + final isStarted = await DateTimeUtil.processStartDate(startDate); + final isExpired = await DateTimeUtil.processExpirationDate(expirationDate); + if (isStarted && !isExpired) return EnumDisplay.fromString(moduleMap["display"]) == EnumDisplay.active; + if (isExpired) return false; + return false; + } +} From a79b1656359448e64b293791fe553ec43db28a83 Mon Sep 17 00:00:00 2001 From: "J. A. Messias" Date: Thu, 30 Jan 2025 09:30:57 -0300 Subject: [PATCH 07/47] WIP --- .../vehicle_model.dart | 79 ++++++++++++------- 1 file changed, 52 insertions(+), 27 deletions(-) diff --git a/lib/pages/vehicles_on_the_property/vehicle_model.dart b/lib/pages/vehicles_on_the_property/vehicle_model.dart index 0e225a37..23704747 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_model.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_model.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:flutter/material.dart'; import 'package:hub/components/templates_components/details_component/details_component_widget.dart'; import 'package:hub/features/backend/index.dart'; @@ -7,7 +9,11 @@ import 'package:hub/shared/utils/index.dart'; /// [VehicleModel] is a class that contains the business logic of the vehicle page. class VehicleModel extends FlutterFlowModel - with _BaseVehiclePage, _VehicleHistoryScreenModel, _VehicleRegisterScreenModel, _VehicleUpdateScreenModel { + with + _BaseVehiclePage, + _VehicleHistoryScreenModel, + _VehicleRegisterScreenModel, + _VehicleUpdateScreenModel { /// [VehicleModel] is a singleton class that contains the business logic of the vehicle page. static VehicleModel? _instance = VehicleModel._internal(); VehicleModel._internal(); @@ -31,6 +37,10 @@ class VehicleModel extends FlutterFlowModel textFieldFocusModel = FocusNode(); textFieldControllerModel = TextEditingController(); + + WidgetsBinding.instance.addPostFrameCallback((_) async { + vehicleAmountRegister = 0; + }); } @override @@ -60,11 +70,12 @@ mixin class _BaseVehiclePage { int count = 0; late final VehicleModel model; late final TabController tabBarController; - dynamic item; + // dynamic item; BuildContext context = navigatorKey.currentContext!; bool isEditing = false; String? vehicleId; ApiCallResponse? vehicleResponse; + late final vehicleAmountRegister; VoidCallback? onUpdateVehicle; VoidCallback? onRegisterVehicle; @@ -72,7 +83,8 @@ mixin class _BaseVehiclePage { FocusNode? textFieldFocusLicensePlate; TextEditingController? textFieldControllerLicensePlate; - String? textControllerLicensePlateValidator(BuildContext context, String? value) { + String? textControllerLicensePlateValidator( + BuildContext context, String? value) { if (value == null || value.isEmpty) { return FFLocalizations.of(context).getVariableText( ptText: 'Placa é obrigatória', @@ -85,7 +97,8 @@ mixin class _BaseVehiclePage { // (ABC1D23) final mercosurPlateRegex = RegExp(r'^[A-Z]{3}\d[A-Z]\d{2}$'); - if (!brazilianPlateRegex.hasMatch(value) && !mercosurPlateRegex.hasMatch(value)) { + if (!brazilianPlateRegex.hasMatch(value) && + !mercosurPlateRegex.hasMatch(value)) { return FFLocalizations.of(context).getVariableText( ptText: 'Placa inválida', enText: 'Invalid license plate', @@ -126,9 +139,9 @@ mixin class _BaseVehiclePage { } void clearFields() async { - textFieldControllerLicensePlate!.clear(); - textFieldControllerColor!.clear(); - textFieldControllerModel!.clear(); + textFieldControllerLicensePlate = TextEditingController(text: ''); + textFieldControllerColor = TextEditingController(text: ''); + textFieldControllerModel = TextEditingController(text: ''); } void handleEditingChanged(bool editing) { @@ -136,12 +149,18 @@ mixin class _BaseVehiclePage { clearFields(); } - void setEditForm() { + void setEditForm(dynamic item) { if (item != null) { vehicleId = item['vehicleId']; - textFieldControllerLicensePlate!.text = item['licensePlate']; - textFieldControllerColor!.text = item['color']; - textFieldControllerModel!.text = item['model']; + log("setEditForm "); + log("setEditForm -> ${item.toString()}"); + + textFieldControllerLicensePlate = TextEditingController( + text: item != null ? item['licensePlate'] ?? '' : ''); + textFieldControllerColor = + TextEditingController(text: item != null ? item['color'] ?? '' : ''); + textFieldControllerModel = + TextEditingController(text: item != null ? item['model'] ?? '' : ''); } } } @@ -149,6 +168,9 @@ mixin class _BaseVehiclePage { /// [_VehicleHistoryScreenModel] is a mixin that contains the business logic of the vehicle history page. mixin _VehicleHistoryScreenModel on _BaseVehiclePage { Map? generateStatusColorMap(dynamic uItem) { + final autoApproval = uItem['autoApproval']; + if (autoApproval == true) return null; + final statusMap = { "ATI": { "text": FFLocalizations.of(context).getVariableText( @@ -197,7 +219,8 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { final status = uItem['status']; if (statusMap.containsKey(status)) { return { - statusMap[status]!['text'] as String: statusMap[status]!['color'] as Color, + statusMap[status]!['text'] as String: + statusMap[status]!['color'] as Color, }; } return {}; @@ -220,18 +243,19 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { ), ); - final updateText = FFLocalizations.of(context).getVariableText(ptText: 'Editar', enText: 'Edit'); + final updateText = FFLocalizations.of(context) + .getVariableText(ptText: 'Editar', enText: 'Edit'); final updateIcon = Icon(Icons.edit, color: iconButtonColor); Future updateOnPressed() async { context.pop(); isEditing = true; - item = item; switchTab(1); - setEditForm(); + setEditForm(item); } - final cancelText = FFLocalizations.of(context).getVariableText(ptText: 'Cancelar', enText: 'Cancel'); + final cancelText = FFLocalizations.of(context) + .getVariableText(ptText: 'Cancelar', enText: 'Cancel'); final cancelIcon = Icon(Icons.close, color: iconButtonColor); Future cancelOnPressed() async { showAlertDialog( @@ -244,11 +268,12 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { ptText: 'Você tem certeza que deseja cancelar essa solicitação?', enText: 'Are you sure you want to delete this request?', ), - () async => await processCancelRequest(item['status']), + () async => await processCancelRequest(item['status'], item), ); } - final deleteText = FFLocalizations.of(context).getVariableText(ptText: 'Excluir', enText: 'Delete'); + final deleteText = FFLocalizations.of(context) + .getVariableText(ptText: 'Excluir', enText: 'Delete'); final deleteIcon = Icon(Icons.delete, color: iconButtonColor); Future deleteOnPressed() async { showAlertDialog( @@ -261,7 +286,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { ptText: 'Você tem certeza que deseja excluir esse veículo?', enText: 'Are you sure you want to delete this vehicle?', ), - () async => await processDeleteRequest(), + () async => await processDeleteRequest(item), ); } @@ -290,7 +315,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { ]; } - Future processDeleteRequest() async { + Future processDeleteRequest(dynamic item) async { int id = item['vehicleId']; await PhpGroup.deleteVehicle.call(vehicleId: id).then((value) { context.pop(value); @@ -330,18 +355,18 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { }); } - Future processCancelRequest(String status) async { + Future processCancelRequest(String status, dynamic item) async { late final ApiCallResponse value; try { switch (status) { case 'APR_CREATE': - value = await processCancelDeleteRequest(); + value = await processCancelDeleteRequest(item); break; case 'AGU_CHANGE': - value = await processCancelUpdateRequest(); + value = await processCancelUpdateRequest(item); break; case 'APR_DELETE': - value = await processCancelCreateRequest(); + value = await processCancelCreateRequest(item); break; default: break; @@ -382,17 +407,17 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { } } - Future processCancelDeleteRequest() async { + Future processCancelDeleteRequest(dynamic item) async { final int id = item['vehicleId']; return await PhpGroup.deleteVehicle.call(vehicleId: id); } - Future processCancelUpdateRequest() async { + Future processCancelUpdateRequest(dynamic item) async { final int id = item['vehicleId']; return await PhpGroup.deleteVehicle.call(vehicleId: id); } - Future processCancelCreateRequest() async { + Future processCancelCreateRequest(dynamic item) async { final int id = item['vehicleId']; return await PhpGroup.deleteVehicle.call(vehicleId: id); } From 1d4041f92b30888cd9997aa165beeedd9965f3c2 Mon Sep 17 00:00:00 2001 From: "J. A. Messias" Date: Thu, 30 Jan 2025 12:14:24 -0300 Subject: [PATCH 08/47] WIP --- lib/features/docs/documentation_page.dart | 779 ++++++++++++++++++++++ 1 file changed, 779 insertions(+) create mode 100644 lib/features/docs/documentation_page.dart diff --git a/lib/features/docs/documentation_page.dart b/lib/features/docs/documentation_page.dart new file mode 100644 index 00000000..f2d04826 --- /dev/null +++ b/lib/features/docs/documentation_page.dart @@ -0,0 +1,779 @@ +import 'dart:async'; +import 'dart:developer'; + +import 'package:flutter/material.dart'; +import 'package:flutter_spinkit/flutter_spinkit.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart'; +import 'package:hub/features/backend/index.dart'; +import 'package:hub/flutter_flow/flutter_flow_icon_button.dart'; +import 'package:hub/flutter_flow/flutter_flow_theme.dart'; +import 'package:hub/flutter_flow/flutter_flow_util.dart'; +import 'package:hub/shared/utils/dialog_util.dart'; +import 'package:hub/shared/utils/log_util.dart'; +import 'package:hub/shared/utils/snackbar_util.dart'; +import 'package:rxdart/rxdart.dart'; +import '/flutter_flow/form_field_controller.dart'; + +import 'package:hub/flutter_flow/nav/nav.dart'; +import 'package:hub/shared/utils/limited_text_size.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:hub/features/storage/index.dart'; + +/// [ProvisionalHistoryEvent] +class ProvisionalHistoryEvent {} + +/// [LoadProvisionalHistory] +class LoadProvisionalHistory extends ProvisionalHistoryEvent {} + +/// [ProvisionalHistoryStateBloc] +class ProvisionalHistoryStateBloc { + final String devUUID; + final String userUUID; + final String cliUUID; + final bool isLoading; + + ProvisionalHistoryStateBloc({ + required this.devUUID, + required this.userUUID, + required this.cliUUID, + this.isLoading = false, + }); + + ProvisionalHistoryStateBloc copyWith({ + String? devUUID, + String? userUUID, + String? cliUUID, + bool? isLoading, + }) { + return ProvisionalHistoryStateBloc( + devUUID: devUUID ?? this.devUUID, + userUUID: userUUID ?? this.userUUID, + cliUUID: cliUUID ?? this.cliUUID, + isLoading: isLoading ?? this.isLoading, + ); + } +} + +/// [ProvisionalHistoryBloc] +class ProvisionalHistoryBloc + extends Bloc { + ProvisionalHistoryBloc() + : super(ProvisionalHistoryStateBloc( + devUUID: '', userUUID: '', cliUUID: '')) { + on(_onLoadProvisionalHistory); + } + + Future _onLoadProvisionalHistory( + LoadProvisionalHistory event, + Emitter emit, + ) async { + emit(state.copyWith(isLoading: true)); + final devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final cliUUID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + emit(state.copyWith( + devUUID: devUUID, + userUUID: userUUID, + cliUUID: cliUUID, + isLoading: false)); + } +} + +/// [ProvisionalHistoryPage] +@immutable +// ignore: must_be_immutable +class ProvisionalHistoryPage extends StatefulWidget { + Map opt; + + ProvisionalHistoryPage({super.key, Map? opt}) + : opt = opt ?? const {'AGP_STATUS': '.*'}; + + @override + State createState() => ProvisionalHistoryState(opt); +} + +/// [ProvisionalHistoryState] +class ProvisionalHistoryState extends State { + final BehaviorSubject> selectedTypeSubject; + late ScrollController _scrollController; + final scaffoldKey = GlobalKey(); + + bool _isSubjectClosed = false; + int _pageNumber = 1; + bool hasData = false; + bool _loading = false; + + String status = '.*'; + + late Future future; + List wrap = []; + + ProvisionalHistoryState(Map opt) + : selectedTypeSubject = BehaviorSubject.seeded(opt) { + selectedTypeSubject.listen((value) {}); + } + + @override + void initState() { + super.initState(); + future = fetchHistoryService(); + _scrollController = ScrollController() + ..addListener(() { + if (_scrollController.position.atEdge && + _scrollController.position.pixels != 0) { + _loadMore(); + } + }); + } + + @override + void dispose() { + selectedTypeSubject.close(); + _isSubjectClosed = true; + super.dispose(); + } + + @override + Widget build(BuildContext context) { + final theme = FlutterFlowTheme.of(context); + return Scaffold( + key: scaffoldKey, + backgroundColor: FlutterFlowTheme.of(context).primaryBackground, + appBar: _appBar(context, theme), + body: _body(context), + ); + } + + PreferredSizeWidget _appBar(BuildContext context, FlutterFlowTheme theme) { + return AppBar( + backgroundColor: theme.primaryBackground, + automaticallyImplyLeading: false, + leading: _backButton(context, theme), + title: _title(context, theme), + centerTitle: true, + elevation: 0.0, + actions: [_filterButton(context)], + ); + } + + Widget _backButton(BuildContext context, FlutterFlowTheme theme) { + return FlutterFlowIconButton( + key: ValueKey('BackNavigationAppBar'), + borderColor: Colors.transparent, + borderRadius: 30.0, + borderWidth: 1.0, + buttonSize: 60.0, + icon: Icon( + Icons.keyboard_arrow_left, + color: theme.primaryText, + size: 30.0, + ), + onPressed: () => Navigator.of(context).pop(), + ); + } + + Widget _title(BuildContext context, FlutterFlowTheme theme) { + return Text( + FFLocalizations.of(context).getVariableText( + ptText: 'Consultar Agendas', + enText: 'Provisional History', + ), + style: FlutterFlowTheme.of(context).headlineMedium.override( + fontFamily: FlutterFlowTheme.of(context).headlineMediumFamily, + color: FlutterFlowTheme.of(context).primaryText, + fontSize: 16.0, + fontWeight: FontWeight.bold, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap() + .containsKey(FlutterFlowTheme.of(context).headlineMediumFamily), + ), + ); + } + + Widget _filterButton(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 10, 0), + child: IconButton( + icon: const Icon(Icons.filter_list), + onPressed: () async { + final Map? selectedFilter = + await showModalBottomSheet>( + isScrollControlled: true, + backgroundColor: Colors.transparent, + context: context, + builder: (context) { + return GestureDetector( + onTap: () => Navigator.of(context).pop(), + child: Container( + color: Colors.transparent, + child: GestureDetector( + onTap: () {}, + child: FilterWidget( + defaultSelections: selectedTypeSubject.value, + filterOptions: { + 'AGP_STATUS': [ + { + 'title': FFLocalizations.of(context) + .getVariableText( + ptText: 'Ativo', + enText: 'Active', + ), + 'value': 'AT', + }, + { + 'title': FFLocalizations.of(context) + .getVariableText( + ptText: 'Concluído', + enText: 'Completed', + ), + 'value': 'CO', + }, + { + 'title': FFLocalizations.of(context) + .getVariableText( + ptText: 'Inativo', + enText: 'Inactive', + ), + 'value': 'IN', + }, + { + 'title': FFLocalizations.of(context) + .getVariableText( + ptText: 'Aguardando Aprovação', + enText: 'Awaiting Approval', + ), + 'value': 'AA', + }, + ], + }, + filterTitles: {'AGP_STATUS': ''}, + ), + ), + ), + ); + }); + + if (selectedFilter != null) { + _updateHistoryAction(selectedFilter); + } + }, + ), + ), + ], + ); + } + + void _updateHistoryAction(Map newType) { + if (!_isSubjectClosed) { + final currentType = selectedTypeSubject.value; + final updatedType = Map.from(currentType); + bool needsUpdate = false; + newType.forEach((key, newValue) { + if (currentType[key] != newValue) { + updatedType[key] = newValue; + needsUpdate = true; + } + }); + if (needsUpdate) { + selectedTypeSubject.add(updatedType); + fetchCardListViewService(updatedType); + safeSetState(() {}); + } + } + } + + Future fetchHistoryService() async { + try { + setState(() => _loading = true); + var response = + await PhpGroup.getProvSchedules(_pageNumber.toString(), status); + + final List history = + response.jsonBody['agendamento']['value'] ?? []; + + if (history.isNotEmpty) { + setState(() { + wrap.addAll(history); + hasData = true; + _loading = false; + }); + return response; + } + SnackBarUtil.showNoMoreDataSnackbar(context); + setState(() { + hasData = false; + _loading = false; + }); + return null; + } catch (e, s) { + await DialogUtil.errorDefault(context); + LogUtil.requestAPIFailed('processRequest', "", "Busca Acesso", e, s); + setState(() { + hasData = false; + _loading = false; + }); + } + return null; + } + + Widget _body(BuildContext context) { + return Column( + crossAxisAlignment: CrossAxisAlignment.center, + children: [ + if (hasData == false && _pageNumber <= 1 && _loading == false) + Expanded( + child: Column( + mainAxisAlignment: MainAxisAlignment.center, + mainAxisSize: MainAxisSize.max, + children: [ + Center( + child: Text( + FFLocalizations.of(context).getVariableText( + ptText: "Nenhum histórico encontrado!", + enText: "No history found!"), + )), + ], + ), + ) + else if (hasData || _pageNumber >= 1) + Expanded(child: _cardListViewOrganismWidget()), + if (hasData == true && _loading) + Container( + padding: const EdgeInsets.only(top: 15, bottom: 15), + child: Center( + child: CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation( + FlutterFlowTheme.of(context).primary, + ), + ), + ), + ) + ], + ); + } + + void _loadMore() { + if (hasData == true) { + _pageNumber++; + future = fetchHistoryService(); + } + } + + void fetchCardListViewService(Map select) { + status = select['AGP_STATUS']!; + wrap = []; + _pageNumber = 1; + future = fetchHistoryService(); + } + + Widget _cardListViewOrganismWidget() { + return FutureBuilder( + future: future, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting && + wrap.isEmpty) { + return Center( + child: SizedBox( + width: 50.0, + height: 50.0, + child: SpinKitCircle( + color: FlutterFlowTheme.of(context).primary, + size: 50.0, + ), + ), + ); + } else if (snapshot.hasError) { + return Center( + child: Text(FFLocalizations.of(context).getVariableText( + ptText: "Falha ao efetuar operação!", + enText: "Failed to perform operation!")), + ); + } + + return ListView.builder( + shrinkWrap: true, + physics: const BouncingScrollPhysics(), + controller: _scrollController, + itemCount: wrap.length, + itemBuilder: (context, index) { + final historyItem = wrap[index]; + return _historyCardMoleculeWidget(context, historyItem); + }, + ); + }, + ); + } + + Widget _historyCardMoleculeWidget(BuildContext context, dynamic historyItem) { + return CardItemTemplateComponentWidget( + imagePath: null, + labelsHashMap: _buildLabelsHashMap(context, historyItem), + statusHashMap: _buildStatusHashMap(context, historyItem), + onTapCardItemAction: () async {}, + ); + } + + String _imageUrlAtomWidget(String document, String type) { + return valueOrDefault( + "https://freaccess.com.br/freaccess/getImage.php?&cliID=&atividade=getFoto&Documento=$document&tipo=$type", + "https://storage.googleapis.com/flutterflow-io-6f20.appspot.com/projects/flutter-freaccess-hub-0xgz9q/assets/7ftdetkzc3s0/360_F_64676383_LdbmhiNM6Ypzb3FM4PPuFP9rHe7ri8Ju.jpg", + ); + } + + Map _buildLabelsHashMap( + BuildContext context, dynamic historyItem) { + return { + FFLocalizations.of(context).getVariableText( + ptText: 'Nome:', + enText: 'Name:', + ): historyItem['AGP_NOME'] ?? '', + FFLocalizations.of(context).getVariableText( + ptText: 'Vencimento', + enText: 'Expiration', + ): formatDate(historyItem['AGP_DT_VISITA']), + FFLocalizations.of(context).getVariableText( + ptText: 'Observação:', + enText: 'Observation:', + ): formatObs(historyItem['AGP_OBSERVACAO']), + }; + } + + String formatObs(String? obs) { + if (obs == null || obs.isEmpty) { + return FFLocalizations.of(context).getVariableText( + ptText: 'Não fornecida', + enText: 'No provided', + ); + } + return obs; + } + + String formatDate(String dateString) { + DateTime dateTime = DateTime.parse(dateString); + return "${dateTime.day.toString().padLeft(2, '0')}/${dateTime.month.toString().padLeft(2, '0')}/${dateTime.year} ${dateTime.hour.toString().padLeft(2, '0')}:${dateTime.minute.toString().padLeft(2, '0')}"; + } + + List> _buildStatusHashMap( + BuildContext context, dynamic historyItem) { + return [ + { + FFLocalizations.of(context).getVariableText( + ptText: 'Visitante', + enText: 'Visitor', + ): FlutterFlowTheme.of(context).alternate2, + }, + _getStatusMap(context, historyItem) + ]; + } + + Map _getStatusMap(BuildContext context, dynamic json) { + late Map statusColorMap; + log(DateTime.parse(json['AGP_DT_VISITA']).toString()); + log(DateTime.now().toString()); + final DateTime now = DateTime.now(); + final DateTime date = DateTime.parse(json['AGP_DT_VISITA']); + final bool isExpired = now.isAfter(date); + + final String statusMap = json['AGP_STATUS']; + switch (statusMap) { + case 'AT': + return isExpired + ? { + FFLocalizations.of(context).getVariableText( + ptText: 'Vencido', + enText: 'Expired', + ): FlutterFlowTheme.of(context).error, + } + : { + FFLocalizations.of(context).getVariableText( + ptText: 'Ativo', + enText: 'Active', + ): FlutterFlowTheme.of(context).success, + }; + case 'CO': + return { + FFLocalizations.of(context).getVariableText( + ptText: 'Concluido', + enText: 'Completed', + ): Colors.blue, + }; + case 'IN': + return { + FFLocalizations.of(context).getVariableText( + ptText: 'Inativo', + enText: 'Inactive', + ): FlutterFlowTheme.of(context).error, + }; + case 'AA': + return { + FFLocalizations.of(context).getVariableText( + ptText: 'Aguardando Aprovação', + enText: 'Awaiting Approval', + ): FlutterFlowTheme.of(context).warning, + }; + default: + return { + FFLocalizations.of(context).getVariableText( + ptText: 'Desconhecido', + enText: 'Unknown', + ): FlutterFlowTheme.of(context).alternate2, + }; + } + } +} + +/// [FilterModel] +class FilterModel extends FlutterFlowModel { + FocusNode? textFieldFocusNode; + TextEditingController? textController; + String? Function(BuildContext, String?)? textControllerValidator; + bool? checkboxValue1; + bool? checkboxValue2; + FormFieldController>? checkboxGroupValueController; + + List? get checkboxGroupValues => checkboxGroupValueController?.value; + + set checkboxGroupValues(List? v) => + checkboxGroupValueController?.value = v; + + @override + void initState(BuildContext context) {} + + @override + void dispose() { + textFieldFocusNode?.dispose(); + textController?.dispose(); + } +} + +/// [FilterWidget] +class FilterWidget extends StatefulWidget { + final Map defaultSelections; + final Map>> filterOptions; + final Map filterTitles; + + const FilterWidget({ + super.key, + required this.defaultSelections, + required this.filterOptions, + required this.filterTitles, + }); + + @override + _FilterWidgetState createState() => _FilterWidgetState(); +} + +/// [_FilterWidgetState] +class _FilterWidgetState extends State { + late FilterModel _model; + late Map selected; + + @override + void setState(VoidCallback callback) { + super.setState(callback); + _model.onUpdate(); + } + + @override + void initState() { + super.initState(); + + _model = createModel(context, () => FilterModel()); + + _model.textController ??= TextEditingController(); + _model.textFieldFocusNode ??= FocusNode(); + + selected = Map.from(widget.defaultSelections); + } + + void _applyFilter() { + Map filterResult = { + 'search': _model.textController?.text == '' + ? '.*' + : _model.textController!.text.toLowerCase(), + }; + + widget.filterOptions.forEach((key, options) { + filterResult[key] = selected[key]!.isEmpty || selected[key]!.length < 1 + ? '.*' + : selected[key]!; + }); + setState(() { + // Update the state with the new filter result + selected = filterResult; + }); + context.pop(filterResult); + } + + Widget _buildCheckboxListTile( + String key, List> options, double fontsize) { + double limitedInputFontSize = LimitedFontSizeUtil.getInputFontSize(context); + return Column( + children: [ + Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsetsDirectional.fromSTEB(0.0, 3.0, 0.0, 0.0), + child: Text( + widget.filterTitles[key]!, + textAlign: TextAlign.left, + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily, + fontSize: limitedInputFontSize, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey( + FlutterFlowTheme.of(context).bodyMediumFamily), + color: FlutterFlowTheme.of(context).primaryText, + ), + ), + ), + ], + ), + ListView.builder( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: options.length, + itemBuilder: (context, index) { + final option = options[index]; + return CheckboxListTile( + title: Text( + option['title']!, + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily, + letterSpacing: 0.0, + fontSize: limitedInputFontSize, + useGoogleFonts: GoogleFonts.asMap().containsKey( + FlutterFlowTheme.of(context).bodyMediumFamily), + color: FlutterFlowTheme.of(context).primaryText, + ), + ), + dense: true, + value: selected[key]!.contains(option['value']), + onChanged: (bool? value) { + setState(() { + if (value == true) { + if (!selected[key]!.contains(option['value'])) { + selected[key] = option['value']; + } + } else { + selected[key] = ''; + } + }); + }, + activeColor: FlutterFlowTheme.of(context).primary, + checkColor: FlutterFlowTheme.of(context).info, + checkboxShape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(100), + ), + enableFeedback: true, + side: BorderSide( + width: 5, + color: FlutterFlowTheme.of(context).secondaryText, + ), + controlAffinity: ListTileControlAffinity.leading, + ); + }, + ), + ], + ); + } + + @override + Widget build(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; + + return Center( + child: Container( + width: screenWidth - (screenWidth * 0.35), + height: screenWidth, + decoration: BoxDecoration( + color: FlutterFlowTheme.of(context).primaryBackground, + borderRadius: BorderRadius.circular(24.0), + ), + child: Padding( + padding: const EdgeInsets.all(4.0), + child: Column( + children: [ + Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsetsDirectional.fromSTEB( + 10.0, 10.0, 0.0, 10.0), + child: Text( + FFLocalizations.of(context).getVariableText( + ptText: 'Filtros', + enText: 'Filters', + ), + style: FlutterFlowTheme.of(context) + .headlineMedium + .override( + fontFamily: FlutterFlowTheme.of(context) + .headlineMediumFamily, + color: FlutterFlowTheme.of(context).primaryText, + fontSize: + LimitedFontSizeUtil.getHeaderFontSize(context), + letterSpacing: 0.0, + fontWeight: FontWeight.bold, + useGoogleFonts: GoogleFonts.asMap().containsKey( + FlutterFlowTheme.of(context) + .headlineMediumFamily), + ), + ), + ), + ], + ), + Expanded( + child: SingleChildScrollView( + child: Container( + padding: const EdgeInsets.all(10), + child: Column( + mainAxisSize: MainAxisSize.min, + children: widget.filterOptions.keys.map((key) { + return _buildCheckboxListTile( + key, widget.filterOptions[key]!, 14); + }).toList(), + ), + ), + ), + ), + ElevatedButton( + onPressed: _applyFilter, + style: ElevatedButton.styleFrom( + foregroundColor: FlutterFlowTheme.of(context).info, + backgroundColor: FlutterFlowTheme.of(context).primary, + ), + child: Text( + FFLocalizations.of(context).getVariableText( + ptText: 'Aplicar', + enText: 'Apply', + ), + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: + FlutterFlowTheme.of(context).bodyMediumFamily, + color: FlutterFlowTheme.of(context).info, + fontSize: + LimitedFontSizeUtil.getInputFontSize(context), + letterSpacing: 0.0, + fontWeight: FontWeight.bold, + useGoogleFonts: GoogleFonts.asMap().containsKey( + FlutterFlowTheme.of(context).bodyMediumFamily), + )), + ), + ], + ), + ), + ), + ); + } +} From 742312e888ff79fa00c75cc33628d4393cf03c1c Mon Sep 17 00:00:00 2001 From: "J. A. Messias" Date: Thu, 30 Jan 2025 19:33:04 -0300 Subject: [PATCH 09/47] wip --- lib/features/docs/documentation_page.dart | 779 ---------------------- 1 file changed, 779 deletions(-) delete mode 100644 lib/features/docs/documentation_page.dart diff --git a/lib/features/docs/documentation_page.dart b/lib/features/docs/documentation_page.dart deleted file mode 100644 index f2d04826..00000000 --- a/lib/features/docs/documentation_page.dart +++ /dev/null @@ -1,779 +0,0 @@ -import 'dart:async'; -import 'dart:developer'; - -import 'package:flutter/material.dart'; -import 'package:flutter_spinkit/flutter_spinkit.dart'; -import 'package:google_fonts/google_fonts.dart'; -import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart'; -import 'package:hub/features/backend/index.dart'; -import 'package:hub/flutter_flow/flutter_flow_icon_button.dart'; -import 'package:hub/flutter_flow/flutter_flow_theme.dart'; -import 'package:hub/flutter_flow/flutter_flow_util.dart'; -import 'package:hub/shared/utils/dialog_util.dart'; -import 'package:hub/shared/utils/log_util.dart'; -import 'package:hub/shared/utils/snackbar_util.dart'; -import 'package:rxdart/rxdart.dart'; -import '/flutter_flow/form_field_controller.dart'; - -import 'package:hub/flutter_flow/nav/nav.dart'; -import 'package:hub/shared/utils/limited_text_size.dart'; -import 'package:flutter_bloc/flutter_bloc.dart'; -import 'package:hub/features/storage/index.dart'; - -/// [ProvisionalHistoryEvent] -class ProvisionalHistoryEvent {} - -/// [LoadProvisionalHistory] -class LoadProvisionalHistory extends ProvisionalHistoryEvent {} - -/// [ProvisionalHistoryStateBloc] -class ProvisionalHistoryStateBloc { - final String devUUID; - final String userUUID; - final String cliUUID; - final bool isLoading; - - ProvisionalHistoryStateBloc({ - required this.devUUID, - required this.userUUID, - required this.cliUUID, - this.isLoading = false, - }); - - ProvisionalHistoryStateBloc copyWith({ - String? devUUID, - String? userUUID, - String? cliUUID, - bool? isLoading, - }) { - return ProvisionalHistoryStateBloc( - devUUID: devUUID ?? this.devUUID, - userUUID: userUUID ?? this.userUUID, - cliUUID: cliUUID ?? this.cliUUID, - isLoading: isLoading ?? this.isLoading, - ); - } -} - -/// [ProvisionalHistoryBloc] -class ProvisionalHistoryBloc - extends Bloc { - ProvisionalHistoryBloc() - : super(ProvisionalHistoryStateBloc( - devUUID: '', userUUID: '', cliUUID: '')) { - on(_onLoadProvisionalHistory); - } - - Future _onLoadProvisionalHistory( - LoadProvisionalHistory event, - Emitter emit, - ) async { - emit(state.copyWith(isLoading: true)); - final devUUID = - (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final userUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final cliUUID = - (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; - emit(state.copyWith( - devUUID: devUUID, - userUUID: userUUID, - cliUUID: cliUUID, - isLoading: false)); - } -} - -/// [ProvisionalHistoryPage] -@immutable -// ignore: must_be_immutable -class ProvisionalHistoryPage extends StatefulWidget { - Map opt; - - ProvisionalHistoryPage({super.key, Map? opt}) - : opt = opt ?? const {'AGP_STATUS': '.*'}; - - @override - State createState() => ProvisionalHistoryState(opt); -} - -/// [ProvisionalHistoryState] -class ProvisionalHistoryState extends State { - final BehaviorSubject> selectedTypeSubject; - late ScrollController _scrollController; - final scaffoldKey = GlobalKey(); - - bool _isSubjectClosed = false; - int _pageNumber = 1; - bool hasData = false; - bool _loading = false; - - String status = '.*'; - - late Future future; - List wrap = []; - - ProvisionalHistoryState(Map opt) - : selectedTypeSubject = BehaviorSubject.seeded(opt) { - selectedTypeSubject.listen((value) {}); - } - - @override - void initState() { - super.initState(); - future = fetchHistoryService(); - _scrollController = ScrollController() - ..addListener(() { - if (_scrollController.position.atEdge && - _scrollController.position.pixels != 0) { - _loadMore(); - } - }); - } - - @override - void dispose() { - selectedTypeSubject.close(); - _isSubjectClosed = true; - super.dispose(); - } - - @override - Widget build(BuildContext context) { - final theme = FlutterFlowTheme.of(context); - return Scaffold( - key: scaffoldKey, - backgroundColor: FlutterFlowTheme.of(context).primaryBackground, - appBar: _appBar(context, theme), - body: _body(context), - ); - } - - PreferredSizeWidget _appBar(BuildContext context, FlutterFlowTheme theme) { - return AppBar( - backgroundColor: theme.primaryBackground, - automaticallyImplyLeading: false, - leading: _backButton(context, theme), - title: _title(context, theme), - centerTitle: true, - elevation: 0.0, - actions: [_filterButton(context)], - ); - } - - Widget _backButton(BuildContext context, FlutterFlowTheme theme) { - return FlutterFlowIconButton( - key: ValueKey('BackNavigationAppBar'), - borderColor: Colors.transparent, - borderRadius: 30.0, - borderWidth: 1.0, - buttonSize: 60.0, - icon: Icon( - Icons.keyboard_arrow_left, - color: theme.primaryText, - size: 30.0, - ), - onPressed: () => Navigator.of(context).pop(), - ); - } - - Widget _title(BuildContext context, FlutterFlowTheme theme) { - return Text( - FFLocalizations.of(context).getVariableText( - ptText: 'Consultar Agendas', - enText: 'Provisional History', - ), - style: FlutterFlowTheme.of(context).headlineMedium.override( - fontFamily: FlutterFlowTheme.of(context).headlineMediumFamily, - color: FlutterFlowTheme.of(context).primaryText, - fontSize: 16.0, - fontWeight: FontWeight.bold, - letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap() - .containsKey(FlutterFlowTheme.of(context).headlineMediumFamily), - ), - ); - } - - Widget _filterButton(BuildContext context) { - return Row( - mainAxisAlignment: MainAxisAlignment.end, - children: [ - Padding( - padding: const EdgeInsets.fromLTRB(0, 0, 10, 0), - child: IconButton( - icon: const Icon(Icons.filter_list), - onPressed: () async { - final Map? selectedFilter = - await showModalBottomSheet>( - isScrollControlled: true, - backgroundColor: Colors.transparent, - context: context, - builder: (context) { - return GestureDetector( - onTap: () => Navigator.of(context).pop(), - child: Container( - color: Colors.transparent, - child: GestureDetector( - onTap: () {}, - child: FilterWidget( - defaultSelections: selectedTypeSubject.value, - filterOptions: { - 'AGP_STATUS': [ - { - 'title': FFLocalizations.of(context) - .getVariableText( - ptText: 'Ativo', - enText: 'Active', - ), - 'value': 'AT', - }, - { - 'title': FFLocalizations.of(context) - .getVariableText( - ptText: 'Concluído', - enText: 'Completed', - ), - 'value': 'CO', - }, - { - 'title': FFLocalizations.of(context) - .getVariableText( - ptText: 'Inativo', - enText: 'Inactive', - ), - 'value': 'IN', - }, - { - 'title': FFLocalizations.of(context) - .getVariableText( - ptText: 'Aguardando Aprovação', - enText: 'Awaiting Approval', - ), - 'value': 'AA', - }, - ], - }, - filterTitles: {'AGP_STATUS': ''}, - ), - ), - ), - ); - }); - - if (selectedFilter != null) { - _updateHistoryAction(selectedFilter); - } - }, - ), - ), - ], - ); - } - - void _updateHistoryAction(Map newType) { - if (!_isSubjectClosed) { - final currentType = selectedTypeSubject.value; - final updatedType = Map.from(currentType); - bool needsUpdate = false; - newType.forEach((key, newValue) { - if (currentType[key] != newValue) { - updatedType[key] = newValue; - needsUpdate = true; - } - }); - if (needsUpdate) { - selectedTypeSubject.add(updatedType); - fetchCardListViewService(updatedType); - safeSetState(() {}); - } - } - } - - Future fetchHistoryService() async { - try { - setState(() => _loading = true); - var response = - await PhpGroup.getProvSchedules(_pageNumber.toString(), status); - - final List history = - response.jsonBody['agendamento']['value'] ?? []; - - if (history.isNotEmpty) { - setState(() { - wrap.addAll(history); - hasData = true; - _loading = false; - }); - return response; - } - SnackBarUtil.showNoMoreDataSnackbar(context); - setState(() { - hasData = false; - _loading = false; - }); - return null; - } catch (e, s) { - await DialogUtil.errorDefault(context); - LogUtil.requestAPIFailed('processRequest', "", "Busca Acesso", e, s); - setState(() { - hasData = false; - _loading = false; - }); - } - return null; - } - - Widget _body(BuildContext context) { - return Column( - crossAxisAlignment: CrossAxisAlignment.center, - children: [ - if (hasData == false && _pageNumber <= 1 && _loading == false) - Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.max, - children: [ - Center( - child: Text( - FFLocalizations.of(context).getVariableText( - ptText: "Nenhum histórico encontrado!", - enText: "No history found!"), - )), - ], - ), - ) - else if (hasData || _pageNumber >= 1) - Expanded(child: _cardListViewOrganismWidget()), - if (hasData == true && _loading) - Container( - padding: const EdgeInsets.only(top: 15, bottom: 15), - child: Center( - child: CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation( - FlutterFlowTheme.of(context).primary, - ), - ), - ), - ) - ], - ); - } - - void _loadMore() { - if (hasData == true) { - _pageNumber++; - future = fetchHistoryService(); - } - } - - void fetchCardListViewService(Map select) { - status = select['AGP_STATUS']!; - wrap = []; - _pageNumber = 1; - future = fetchHistoryService(); - } - - Widget _cardListViewOrganismWidget() { - return FutureBuilder( - future: future, - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.waiting && - wrap.isEmpty) { - return Center( - child: SizedBox( - width: 50.0, - height: 50.0, - child: SpinKitCircle( - color: FlutterFlowTheme.of(context).primary, - size: 50.0, - ), - ), - ); - } else if (snapshot.hasError) { - return Center( - child: Text(FFLocalizations.of(context).getVariableText( - ptText: "Falha ao efetuar operação!", - enText: "Failed to perform operation!")), - ); - } - - return ListView.builder( - shrinkWrap: true, - physics: const BouncingScrollPhysics(), - controller: _scrollController, - itemCount: wrap.length, - itemBuilder: (context, index) { - final historyItem = wrap[index]; - return _historyCardMoleculeWidget(context, historyItem); - }, - ); - }, - ); - } - - Widget _historyCardMoleculeWidget(BuildContext context, dynamic historyItem) { - return CardItemTemplateComponentWidget( - imagePath: null, - labelsHashMap: _buildLabelsHashMap(context, historyItem), - statusHashMap: _buildStatusHashMap(context, historyItem), - onTapCardItemAction: () async {}, - ); - } - - String _imageUrlAtomWidget(String document, String type) { - return valueOrDefault( - "https://freaccess.com.br/freaccess/getImage.php?&cliID=&atividade=getFoto&Documento=$document&tipo=$type", - "https://storage.googleapis.com/flutterflow-io-6f20.appspot.com/projects/flutter-freaccess-hub-0xgz9q/assets/7ftdetkzc3s0/360_F_64676383_LdbmhiNM6Ypzb3FM4PPuFP9rHe7ri8Ju.jpg", - ); - } - - Map _buildLabelsHashMap( - BuildContext context, dynamic historyItem) { - return { - FFLocalizations.of(context).getVariableText( - ptText: 'Nome:', - enText: 'Name:', - ): historyItem['AGP_NOME'] ?? '', - FFLocalizations.of(context).getVariableText( - ptText: 'Vencimento', - enText: 'Expiration', - ): formatDate(historyItem['AGP_DT_VISITA']), - FFLocalizations.of(context).getVariableText( - ptText: 'Observação:', - enText: 'Observation:', - ): formatObs(historyItem['AGP_OBSERVACAO']), - }; - } - - String formatObs(String? obs) { - if (obs == null || obs.isEmpty) { - return FFLocalizations.of(context).getVariableText( - ptText: 'Não fornecida', - enText: 'No provided', - ); - } - return obs; - } - - String formatDate(String dateString) { - DateTime dateTime = DateTime.parse(dateString); - return "${dateTime.day.toString().padLeft(2, '0')}/${dateTime.month.toString().padLeft(2, '0')}/${dateTime.year} ${dateTime.hour.toString().padLeft(2, '0')}:${dateTime.minute.toString().padLeft(2, '0')}"; - } - - List> _buildStatusHashMap( - BuildContext context, dynamic historyItem) { - return [ - { - FFLocalizations.of(context).getVariableText( - ptText: 'Visitante', - enText: 'Visitor', - ): FlutterFlowTheme.of(context).alternate2, - }, - _getStatusMap(context, historyItem) - ]; - } - - Map _getStatusMap(BuildContext context, dynamic json) { - late Map statusColorMap; - log(DateTime.parse(json['AGP_DT_VISITA']).toString()); - log(DateTime.now().toString()); - final DateTime now = DateTime.now(); - final DateTime date = DateTime.parse(json['AGP_DT_VISITA']); - final bool isExpired = now.isAfter(date); - - final String statusMap = json['AGP_STATUS']; - switch (statusMap) { - case 'AT': - return isExpired - ? { - FFLocalizations.of(context).getVariableText( - ptText: 'Vencido', - enText: 'Expired', - ): FlutterFlowTheme.of(context).error, - } - : { - FFLocalizations.of(context).getVariableText( - ptText: 'Ativo', - enText: 'Active', - ): FlutterFlowTheme.of(context).success, - }; - case 'CO': - return { - FFLocalizations.of(context).getVariableText( - ptText: 'Concluido', - enText: 'Completed', - ): Colors.blue, - }; - case 'IN': - return { - FFLocalizations.of(context).getVariableText( - ptText: 'Inativo', - enText: 'Inactive', - ): FlutterFlowTheme.of(context).error, - }; - case 'AA': - return { - FFLocalizations.of(context).getVariableText( - ptText: 'Aguardando Aprovação', - enText: 'Awaiting Approval', - ): FlutterFlowTheme.of(context).warning, - }; - default: - return { - FFLocalizations.of(context).getVariableText( - ptText: 'Desconhecido', - enText: 'Unknown', - ): FlutterFlowTheme.of(context).alternate2, - }; - } - } -} - -/// [FilterModel] -class FilterModel extends FlutterFlowModel { - FocusNode? textFieldFocusNode; - TextEditingController? textController; - String? Function(BuildContext, String?)? textControllerValidator; - bool? checkboxValue1; - bool? checkboxValue2; - FormFieldController>? checkboxGroupValueController; - - List? get checkboxGroupValues => checkboxGroupValueController?.value; - - set checkboxGroupValues(List? v) => - checkboxGroupValueController?.value = v; - - @override - void initState(BuildContext context) {} - - @override - void dispose() { - textFieldFocusNode?.dispose(); - textController?.dispose(); - } -} - -/// [FilterWidget] -class FilterWidget extends StatefulWidget { - final Map defaultSelections; - final Map>> filterOptions; - final Map filterTitles; - - const FilterWidget({ - super.key, - required this.defaultSelections, - required this.filterOptions, - required this.filterTitles, - }); - - @override - _FilterWidgetState createState() => _FilterWidgetState(); -} - -/// [_FilterWidgetState] -class _FilterWidgetState extends State { - late FilterModel _model; - late Map selected; - - @override - void setState(VoidCallback callback) { - super.setState(callback); - _model.onUpdate(); - } - - @override - void initState() { - super.initState(); - - _model = createModel(context, () => FilterModel()); - - _model.textController ??= TextEditingController(); - _model.textFieldFocusNode ??= FocusNode(); - - selected = Map.from(widget.defaultSelections); - } - - void _applyFilter() { - Map filterResult = { - 'search': _model.textController?.text == '' - ? '.*' - : _model.textController!.text.toLowerCase(), - }; - - widget.filterOptions.forEach((key, options) { - filterResult[key] = selected[key]!.isEmpty || selected[key]!.length < 1 - ? '.*' - : selected[key]!; - }); - setState(() { - // Update the state with the new filter result - selected = filterResult; - }); - context.pop(filterResult); - } - - Widget _buildCheckboxListTile( - String key, List> options, double fontsize) { - double limitedInputFontSize = LimitedFontSizeUtil.getInputFontSize(context); - return Column( - children: [ - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsetsDirectional.fromSTEB(0.0, 3.0, 0.0, 0.0), - child: Text( - widget.filterTitles[key]!, - textAlign: TextAlign.left, - style: FlutterFlowTheme.of(context).bodyMedium.override( - fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily, - fontSize: limitedInputFontSize, - letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap().containsKey( - FlutterFlowTheme.of(context).bodyMediumFamily), - color: FlutterFlowTheme.of(context).primaryText, - ), - ), - ), - ], - ), - ListView.builder( - physics: const NeverScrollableScrollPhysics(), - shrinkWrap: true, - itemCount: options.length, - itemBuilder: (context, index) { - final option = options[index]; - return CheckboxListTile( - title: Text( - option['title']!, - style: FlutterFlowTheme.of(context).bodyMedium.override( - fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily, - letterSpacing: 0.0, - fontSize: limitedInputFontSize, - useGoogleFonts: GoogleFonts.asMap().containsKey( - FlutterFlowTheme.of(context).bodyMediumFamily), - color: FlutterFlowTheme.of(context).primaryText, - ), - ), - dense: true, - value: selected[key]!.contains(option['value']), - onChanged: (bool? value) { - setState(() { - if (value == true) { - if (!selected[key]!.contains(option['value'])) { - selected[key] = option['value']; - } - } else { - selected[key] = ''; - } - }); - }, - activeColor: FlutterFlowTheme.of(context).primary, - checkColor: FlutterFlowTheme.of(context).info, - checkboxShape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(100), - ), - enableFeedback: true, - side: BorderSide( - width: 5, - color: FlutterFlowTheme.of(context).secondaryText, - ), - controlAffinity: ListTileControlAffinity.leading, - ); - }, - ), - ], - ); - } - - @override - Widget build(BuildContext context) { - double screenWidth = MediaQuery.of(context).size.width; - - return Center( - child: Container( - width: screenWidth - (screenWidth * 0.35), - height: screenWidth, - decoration: BoxDecoration( - color: FlutterFlowTheme.of(context).primaryBackground, - borderRadius: BorderRadius.circular(24.0), - ), - child: Padding( - padding: const EdgeInsets.all(4.0), - child: Column( - children: [ - Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsetsDirectional.fromSTEB( - 10.0, 10.0, 0.0, 10.0), - child: Text( - FFLocalizations.of(context).getVariableText( - ptText: 'Filtros', - enText: 'Filters', - ), - style: FlutterFlowTheme.of(context) - .headlineMedium - .override( - fontFamily: FlutterFlowTheme.of(context) - .headlineMediumFamily, - color: FlutterFlowTheme.of(context).primaryText, - fontSize: - LimitedFontSizeUtil.getHeaderFontSize(context), - letterSpacing: 0.0, - fontWeight: FontWeight.bold, - useGoogleFonts: GoogleFonts.asMap().containsKey( - FlutterFlowTheme.of(context) - .headlineMediumFamily), - ), - ), - ), - ], - ), - Expanded( - child: SingleChildScrollView( - child: Container( - padding: const EdgeInsets.all(10), - child: Column( - mainAxisSize: MainAxisSize.min, - children: widget.filterOptions.keys.map((key) { - return _buildCheckboxListTile( - key, widget.filterOptions[key]!, 14); - }).toList(), - ), - ), - ), - ), - ElevatedButton( - onPressed: _applyFilter, - style: ElevatedButton.styleFrom( - foregroundColor: FlutterFlowTheme.of(context).info, - backgroundColor: FlutterFlowTheme.of(context).primary, - ), - child: Text( - FFLocalizations.of(context).getVariableText( - ptText: 'Aplicar', - enText: 'Apply', - ), - style: FlutterFlowTheme.of(context).bodyMedium.override( - fontFamily: - FlutterFlowTheme.of(context).bodyMediumFamily, - color: FlutterFlowTheme.of(context).info, - fontSize: - LimitedFontSizeUtil.getInputFontSize(context), - letterSpacing: 0.0, - fontWeight: FontWeight.bold, - useGoogleFonts: GoogleFonts.asMap().containsKey( - FlutterFlowTheme.of(context).bodyMediumFamily), - )), - ), - ], - ), - ), - ), - ); - } -} From bc16df866a962a351c3e29513a72cb32828477d5 Mon Sep 17 00:00:00 2001 From: jantunemesssias Date: Thu, 30 Jan 2025 17:58:30 -0300 Subject: [PATCH 10/47] WIP --- integration_test/utils_test.dart | 4 +- ..._arrow_linked_locals_component_widget.dart | 2 +- .../backend/api_requests/api_calls.dart | 475 ++++++++++++------ .../locals_remote_data_source.dart | 2 +- lib/features/local/utils/local_util.dart | 2 +- .../vehicle_model.dart | 32 +- lib/shared/extensions/string_extensions.dart | 6 + 7 files changed, 369 insertions(+), 154 deletions(-) diff --git a/integration_test/utils_test.dart b/integration_test/utils_test.dart index d3b4bfca..1f1bedc2 100644 --- a/integration_test/utils_test.dart +++ b/integration_test/utils_test.dart @@ -21,7 +21,7 @@ Future _loggedWithMultiLocalsAccount(PatrolIntegrationTester $, [bool forc await StorageHelper().set(ProfileStorageKey.clientUUID.key, '7'); await StorageHelper().set(ProfileStorageKey.ownerUUID.key, '7'); await StorageHelper().set(ProfileStorageKey.clientName.key, 'FRE ACCESS DEMO'); - await PhpGroup.respondeVinculo.call(tarefa: 'A'); + await PhpGroup.resopndeVinculo.call(tarefa: 'A'); await LicenseRepositoryImpl().resetLicense(); } } @@ -47,7 +47,7 @@ Future _loggedWithSomeoneLocalAccount(PatrolIntegrationTester $, [bool for await StorageHelper().set(ProfileStorageKey.clientUUID.key, '7'); await StorageHelper().set(ProfileStorageKey.ownerUUID.key, '7'); await StorageHelper().set(ProfileStorageKey.clientName.key, 'FRE ACCESS DEMO'); - await PhpGroup.respondeVinculo.call(tarefa: 'A'); + await PhpGroup.resopndeVinculo.call(tarefa: 'A'); await LicenseRepositoryImpl().resetLicense(); } } diff --git a/lib/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart b/lib/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart index 0b3ddd85..141400e6 100644 --- a/lib/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart +++ b/lib/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart @@ -140,7 +140,7 @@ class _BottomArrowLinkedLocalsComponentWidgetState extends State _fetchResponseLink(String status, String cliID) async { try { await StorageHelper().set(ProfileStorageKey.clientUUID.key, cliID); - var response = await PhpGroup.respondeVinculo.call(tarefa: status); + var response = await PhpGroup.resopndeVinculo.call(tarefa: status); if (response.jsonBody['error'] == false) { return { diff --git a/lib/features/backend/api_requests/api_calls.dart b/lib/features/backend/api_requests/api_calls.dart index 1b205891..3219ac27 100644 --- a/lib/features/backend/api_requests/api_calls.dart +++ b/lib/features/backend/api_requests/api_calls.dart @@ -31,23 +31,26 @@ class PhpGroup extends Api { static ForgotPasswordCall forgotPasswordCall = ForgotPasswordCall(); static ChangePasswordCall changePasswordCall = ChangePasswordCall(); static GetLocalsCall getLocalsCall = GetLocalsCall(); - static PostScheduleVisitorCall postScheduleVisitorCall = PostScheduleVisitorCall(); + static PostScheduleVisitorCall postScheduleVisitorCall = + PostScheduleVisitorCall(); static PostScheduleVisitCall postScheduleVisitCall = PostScheduleVisitCall(); static GetScheduleVisitCall getScheduleVisitCall = GetScheduleVisitCall(); static GetDadosCall getDadosCall = GetDadosCall(); static GetVisitorByDocCall getVisitorByDocCall = GetVisitorByDocCall(); static GetFotoVisitanteCall getFotoVisitanteCall = GetFotoVisitanteCall(); - static PostProvVisitSchedulingCall postProvVisitSchedulingCall = PostProvVisitSchedulingCall(); + static PostProvVisitSchedulingCall postProvVisitSchedulingCall = + PostProvVisitSchedulingCall(); static GetVisitsCall getVisitsCall = GetVisitsCall(); static DeleteVisitCall deleteVisitCall = DeleteVisitCall(); static GetPessoasLocalCall getPessoasLocalCall = GetPessoasLocalCall(); - static RespondeSolicitacaoCall respondeSolicitacaoCall = RespondeSolicitacaoCall(); + static RespondeSolicitacaoCall respondeSolicitacaoCall = + RespondeSolicitacaoCall(); static GetAccessCall getAccessCall = GetAccessCall(); static GetLiberationsCall getLiberationsCall = GetLiberationsCall(); static GetMessagesCall getMessagesCall = GetMessagesCall(); static ChangeNotifica changeNotifica = ChangeNotifica(); static UpdateIDE updateIDE = UpdateIDE(); - static RespondeVinculo respondeVinculo = RespondeVinculo(); + static RespondeVinculo resopndeVinculo = RespondeVinculo(); static ChangePass changePass = ChangePass(); static ChangePanic changePanic = ChangePanic(); static DeleteAccount deleteAccount = DeleteAccount(); @@ -60,22 +63,74 @@ class PhpGroup extends Api { static GetPetPhoto getPetPhoto = GetPetPhoto(); static UnregisterDevice unregisterDevice = UnregisterDevice(); static GetVehiclesByProperty getVehiclesByProperty = GetVehiclesByProperty(); - static GetResidentsByProperty getResidentsByProperty = GetResidentsByProperty(); + static GetResidentsByProperty getResidentsByProperty = + GetResidentsByProperty(); static GetOpenedVisits getOpenedVisits = GetOpenedVisits(); GetLicense getLicense = GetLicense(); static GetProvSchedules getProvSchedules = GetProvSchedules(); static RegisterVehicle registerVehicle = RegisterVehicle(); static UpdateVehicle updateVehicle = UpdateVehicle(); static DeleteVehicle deleteVehicle = DeleteVehicle(); + static CancelVehicle cancelVehicle = CancelVehicle(); +} + +class CancelVehicle { + Future call({ + required final String vehicleId, + required final String licensePlate, + required final String model, + required final String color, + }) async { + final String baseUrl = PhpGroup.getBaseUrl(); + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + const String atividade = 'cancelDeleteRequest'; + + return await ApiManager.instance.makeApiCall( + callName: atividade, + apiUrl: '$baseUrl/processRequest.php', + callType: ApiCallType.POST, + headers: {'Content-Type': 'application/x-www-form-urlencoded'}, + params: { + 'devUUID': devUUID, + 'userUUID': userUUID, + 'cliID': cliID, + 'atividade': atividade, + 'vehicleId': vehicleId, + 'licensePlate': licensePlate, + 'model': model, + 'color': color + }, + bodyType: BodyType.X_WWW_FORM_URL_ENCODED, + returnBody: true, + encodeBodyUtf8: false, + decodeUtf8: false, + cache: false, + isStreamingApi: false, + alwaysAllowBody: false, + ); + } } class DeleteVehicle { - Future call({vehicleId}) async { + Future call({ + required final String vehicleId, + required final String licensePlate, + required final String model, + required final String color, + }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; - const String atividade = 'excluirVeiculo'; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + const String atividade = 'deleteVehicle'; return await ApiManager.instance.makeApiCall( callName: 'deleteVehicle', @@ -90,6 +145,9 @@ class DeleteVehicle { 'cliID': cliID, 'atividade': atividade, 'vehicleId': vehicleId, + 'licensePlate': licensePlate, + 'model': model, + 'color': color }, bodyType: BodyType.X_WWW_FORM_URL_ENCODED, returnBody: true, @@ -110,10 +168,13 @@ class RegisterVehicle { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; - const String atividade = 'cadastrarVeiculo'; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + const String atividade = 'insertVehicle'; return await ApiManager.instance.makeApiCall( callName: 'registerVehicle', @@ -150,10 +211,13 @@ class UpdateVehicle { final String? model, }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; - const String atividade = 'atualizarVeiculo'; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + const String atividade = 'updateVehicleToInsertRequest'; return await ApiManager.instance.makeApiCall( callName: 'updateVehicle', @@ -185,9 +249,12 @@ class UpdateVehicle { class GetProvSchedules { Future call(final String page, final String status) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'getAgendamentoProv'; const String pageSize = '10'; final bool isFiltered = status != '' && status != '.*'; @@ -220,9 +287,12 @@ class GetProvSchedules { class GetOpenedVisits { Future call(final String page) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'getOpenedVisits'; const String pageSize = '10'; return await ApiManager.instance.makeApiCall( @@ -252,9 +322,12 @@ class GetOpenedVisits { class GetResidentsByProperty { Future call(final String page) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = await StorageHelper().get(ProfileStorageKey.devUUID.key) ?? ''; - final String userUUID = await StorageHelper().get(ProfileStorageKey.userUUID.key) ?? ''; - final String cliID = await StorageHelper().get(ProfileStorageKey.clientUUID.key) ?? ''; + final String devUUID = + await StorageHelper().get(ProfileStorageKey.devUUID.key) ?? ''; + final String userUUID = + await StorageHelper().get(ProfileStorageKey.userUUID.key) ?? ''; + final String cliID = + await StorageHelper().get(ProfileStorageKey.clientUUID.key) ?? ''; const String atividade = 'getResidentsByProperty'; const String pageSize = '10'; return await ApiManager.instance.makeApiCall( @@ -283,9 +356,12 @@ class GetResidentsByProperty { class GetVehiclesByProperty { Future call(final String page) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'getVehiclesByProperty'; const String pageSize = '10'; return await ApiManager.instance.makeApiCall( @@ -316,9 +392,12 @@ class GetVehiclesByProperty { class GetLicense { Future call() async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; return await ApiManager.instance.makeApiCall( callName: 'getLicense', @@ -347,8 +426,10 @@ class GetLicense { class UnregisterDevice { Future call() async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; return await ApiManager.instance.makeApiCall( callName: 'unregisterDevice', @@ -375,9 +456,12 @@ class UnregisterDevice { class DeletePet { Future call({final int? petID = 0}) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'excluirPet'; return await ApiManager.instance.makeApiCall( @@ -420,9 +504,12 @@ class UpdatePet { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'atualizarPet'; return await ApiManager.instance.makeApiCall( @@ -443,7 +530,9 @@ class UpdatePet { 'species': species, 'breed': breed, if (color != '') 'color': color, - if (birthdayDate != '') 'birthdayDate': ValidatorUtil.toISO8601USA('dd/MM/yyyy', birthdayDate!), + if (birthdayDate != '') + 'birthdayDate': + ValidatorUtil.toISO8601USA('dd/MM/yyyy', birthdayDate!), 'gender': gender, 'size': size, if (notes != '') 'notes': notes, @@ -466,9 +555,12 @@ class GetPets { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'consultaPets'; return await ApiManager.instance.makeApiCall( @@ -500,9 +592,12 @@ class GetPetPhoto { Future call({final int? petId}) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'consultaFotoPet'; return await ApiManager.instance.makeApiCall( @@ -543,9 +638,12 @@ class RegisterPet { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'cadastrarPet'; return await ApiManager.instance.makeApiCall( @@ -565,7 +663,9 @@ class RegisterPet { 'species': species, 'breed': breed, if (color != '') 'color': color, - if (birthdayDate != '') 'birthdayDate': ValidatorUtil.toISO8601USA('dd/MM/yyyy', birthdayDate!), + if (birthdayDate != '') + 'birthdayDate': + ValidatorUtil.toISO8601USA('dd/MM/yyyy', birthdayDate!), 'gender': gender, 'size': size, if (notes != '') 'notes': notes, @@ -588,9 +688,12 @@ class BuscaEnconcomendas { final String? adresseeType, final String? status, }) async { - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'getEncomendas'; final String baseUrl = PhpGroup.getBaseUrl(); @@ -632,9 +735,12 @@ class CancelaVisita { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'cancelaVisita'; return await ApiManager.instance.makeApiCall( @@ -666,8 +772,10 @@ class CancelaVisita { class DeleteAccount { Future call() async { - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; final String baseUrl = PhpGroup.getBaseUrl(); return await ApiManager.instance.makeApiCall( @@ -698,9 +806,12 @@ class ChangePanic { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'updVisitado'; return await ApiManager.instance.makeApiCall( @@ -734,9 +845,12 @@ class ChangePass { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'updVisitado'; return await ApiManager.instance.makeApiCall( @@ -770,9 +884,12 @@ class RespondeVinculo { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; return await ApiManager.instance.makeApiCall( callName: 'respondeVinculo', @@ -804,9 +921,12 @@ class ChangeNotifica { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'updVisitado'; return await ApiManager.instance.makeApiCall( @@ -838,10 +958,14 @@ class UpdateIDE { Future call() async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; - final String newIde = (await StorageHelper().get(ProfileStorageKey.userDevUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliUUID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String newIde = + (await StorageHelper().get(ProfileStorageKey.userDevUUID.key)) ?? ''; const String atividade = 'updVisitado'; return await ApiManager.instance.makeApiCall( @@ -873,9 +997,12 @@ class UpdToken { Future call() async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String token = (await StorageHelper().get(SecureStorageKey.token.value)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String token = + (await StorageHelper().get(SecureStorageKey.token.value)) ?? ''; return await ApiManager.instance.makeApiCall( callName: 'updToken', @@ -902,11 +1029,17 @@ class UpdToken { class LoginCall { Future call() async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String email = (await StorageHelper().get(SecureStorageKey.email.value)) ?? ''; - final String password = (await StorageHelper().get(SecureStorageKey.password.value)) ?? ''; - final String type = (await StorageHelper().get(SecureStorageKey.deviceType.value)) ?? ''; - final String description = (await StorageHelper().get(SecureStorageKey.deviceDescription.value)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String email = + (await StorageHelper().get(SecureStorageKey.email.value)) ?? ''; + final String password = + (await StorageHelper().get(SecureStorageKey.password.value)) ?? ''; + final String type = + (await StorageHelper().get(SecureStorageKey.deviceType.value)) ?? ''; + final String description = + (await StorageHelper().get(SecureStorageKey.deviceDescription.value)) ?? + ''; late final String token; try { token = await FirebaseMessagingService.getToken(); @@ -989,9 +1122,12 @@ class ChangePasswordCall { required final String psswd, }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; return await ApiManager.instance.makeApiCall( callName: 'changePassword', @@ -1050,8 +1186,10 @@ class GetLocalsCall { Future call() async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = await StorageHelper().get(ProfileStorageKey.devUUID.key) ?? ''; - final String userUUID = await StorageHelper().get(ProfileStorageKey.userUUID.key) ?? ''; + final String devUUID = + await StorageHelper().get(ProfileStorageKey.devUUID.key) ?? ''; + final String userUUID = + await StorageHelper().get(ProfileStorageKey.userUUID.key) ?? ''; return await ApiManager.instance .makeApiCall( @@ -1092,9 +1230,12 @@ class PostScheduleVisitorCall { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'putVisitante'; return await ApiManager.instance.makeApiCall( @@ -1147,9 +1288,12 @@ class PostScheduleVisitCall { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'putVisita'; return await ApiManager.instance.makeApiCall( @@ -1201,9 +1345,12 @@ class GetScheduleVisitCall { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliUUID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'getVisitas'; return await ApiManager.instance.makeApiCall( @@ -1475,9 +1622,12 @@ class GetDadosCall { Future call() async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliUUID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'getDados'; return await ApiManager.instance @@ -1513,7 +1663,8 @@ class GetDadosCall { response, r'''$.error_msg''', )); - String? visitedDesNomeStr(dynamic response) => castToType(getJsonField( + String? visitedDesNomeStr(dynamic response) => + castToType(getJsonField( response, r'''$.visitado.DES_NOME''', )); @@ -1521,27 +1672,33 @@ class GetDadosCall { response, r'''$.visitado.VDO_ID''', )); - String? visitedVDOTNomeStr(dynamic response) => castToType(getJsonField( + String? visitedVDOTNomeStr(dynamic response) => + castToType(getJsonField( response, r'''$.visitado.VDO_NOME''', )); - String? visitedVDOTipoStr(dynamic response) => castToType(getJsonField( + String? visitedVDOTipoStr(dynamic response) => + castToType(getJsonField( response, r'''$.visitado.VDO_TIPO''', )); - String? visitedVDOImeiStr(dynamic response) => castToType(getJsonField( + String? visitedVDOImeiStr(dynamic response) => + castToType(getJsonField( response, r'''$.visitado.VDO_IMEI''', )); - String? visitedVDODocumentoStr(dynamic response) => castToType(getJsonField( + String? visitedVDODocumentoStr(dynamic response) => + castToType(getJsonField( response, r'''$.visitado.VDO_DOCUMENTO''', )); - String? visitedVDOEmailStr(dynamic response) => castToType(getJsonField( + String? visitedVDOEmailStr(dynamic response) => + castToType(getJsonField( response, r'''$.visitado.VDO_EMAIL''', )); - String? visitedVDOStatusWebStr(dynamic response) => castToType(getJsonField( + String? visitedVDOStatusWebStr(dynamic response) => + castToType(getJsonField( response, r'''$.visitado.VDO_STATUSWEB''', )); @@ -1589,7 +1746,8 @@ class GetDadosCall { response, r'''$.visitado.DES_ID''', )); - String? visitedVDoNotTerceirosStr(dynamic response) => castToType(getJsonField( + String? visitedVDoNotTerceirosStr(dynamic response) => + castToType(getJsonField( response, r'''$.visitado.VDO_NOTTERCEIROS''', )); @@ -1658,7 +1816,8 @@ class GetDadosCall { .map((x) => castToType(x)) .withoutNulls .toList(); - List? levelNACIndPermiteReentradaStrList(dynamic response) => (getJsonField( + List? levelNACIndPermiteReentradaStrList(dynamic response) => + (getJsonField( response, r'''$.niveis[:].NAC_INDPERMITEREENTRADA''', true, @@ -1676,7 +1835,8 @@ class GetDadosCall { .map((x) => castToType(x)) .withoutNulls .toList(); - List? levelNACTempoAntiCaronaStrList(dynamic response) => (getJsonField( + List? levelNACTempoAntiCaronaStrList(dynamic response) => + (getJsonField( response, r'''$.niveis[:].NAC_TEMPOANTICARONA''', true, @@ -1710,9 +1870,12 @@ class GetVisitorByDocCall { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'getVisitante'; return await ApiManager.instance.makeApiCall( @@ -1764,9 +1927,12 @@ class GetFotoVisitanteCall { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'getFotoVisitante'; return await ApiManager.instance.makeApiCall( @@ -1803,9 +1969,12 @@ class PostProvVisitSchedulingCall { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'putAgendamentoProv'; return await ApiManager.instance.makeApiCall( @@ -1852,9 +2021,12 @@ class GetVisitsCall { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'getVisitas'; return await ApiManager.instance.makeApiCall( @@ -2115,9 +2287,12 @@ class DeleteVisitCall { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'cancelaVisita'; return await ApiManager.instance.makeApiCall( @@ -2158,10 +2333,14 @@ class GetPessoasLocalCall { Future call() async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String ownerUUID = (await StorageHelper().get(ProfileStorageKey.ownerUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String ownerUUID = + (await StorageHelper().get(ProfileStorageKey.ownerUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliUUID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; return await ApiManager.instance.makeApiCall( callName: 'getPessoasLocal', @@ -2224,9 +2403,12 @@ class RespondeSolicitacaoCall { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliUUID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'respondeSolicitacao'; return await ApiManager.instance.makeApiCall( @@ -2274,9 +2456,12 @@ class GetAccessCall { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliUUID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'getAcessos'; return await ApiManager.instance.makeApiCall( @@ -2523,9 +2708,12 @@ class GetLiberationsCall { final StreamController controller = StreamController(); Future.microtask(() async { - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliUUID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'getSolicitacoes'; try { @@ -2715,9 +2903,12 @@ class GetMessagesCall { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - final String devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - final String userUUID = (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; - final String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + final String devUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; + final String userUUID = + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; + final String cliUUID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; const String atividade = 'getMensagens'; return await ApiManager.instance.makeApiCall( diff --git a/lib/features/local/data/data_sources/locals_remote_data_source.dart b/lib/features/local/data/data_sources/locals_remote_data_source.dart index 85ec65fa..0babde3a 100644 --- a/lib/features/local/data/data_sources/locals_remote_data_source.dart +++ b/lib/features/local/data/data_sources/locals_remote_data_source.dart @@ -224,7 +224,7 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource { enText: 'Device unlinked successfully', ptText: 'Dispositivo desvinculado com sucesso', ); - final bool status = await PhpGroup.respondeVinculo.call(tarefa: 'I').then((value) async { + final bool status = await PhpGroup.resopndeVinculo.call(tarefa: 'I').then((value) async { if (value.jsonBody['error'] == false) { await StorageHelper().set(ProfileStorageKey.clientName.key, ''); await StorageHelper().set(ProfileStorageKey.ownerName.key, ''); diff --git a/lib/features/local/utils/local_util.dart b/lib/features/local/utils/local_util.dart index 35b6ed37..88214b27 100644 --- a/lib/features/local/utils/local_util.dart +++ b/lib/features/local/utils/local_util.dart @@ -44,7 +44,7 @@ class LocalUtil { await StorageHelper().set(ProfileStorageKey.clientName.key, locals[0]['CLI_NOME']); await StorageHelper().set(ProfileStorageKey.ownerName.key, locals[0]['CLU_OWNER_DSC']); - var response = await PhpGroup.respondeVinculo.call(tarefa: 'A'); + var response = await PhpGroup.resopndeVinculo.call(tarefa: 'A'); if (response.jsonBody['error'] == true) { await StorageHelper().set(ProfileStorageKey.clientUUID.key, ''); await StorageHelper().set(ProfileStorageKey.ownerUUID.key, ''); diff --git a/lib/pages/vehicles_on_the_property/vehicle_model.dart b/lib/pages/vehicles_on_the_property/vehicle_model.dart index 23704747..a279e972 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_model.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_model.dart @@ -317,7 +317,12 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { Future processDeleteRequest(dynamic item) async { int id = item['vehicleId']; - await PhpGroup.deleteVehicle.call(vehicleId: id).then((value) { + await PhpGroup.deleteVehicle.call( + vehicleId: item['vehicleId'], + licensePlate: item['licensePlate'], + model: item['model'], + color: item['color'], + ).then((value) { context.pop(value); context.pop(value); @@ -408,18 +413,31 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { } Future processCancelDeleteRequest(dynamic item) async { - final int id = item['vehicleId']; - return await PhpGroup.deleteVehicle.call(vehicleId: id); + return await PhpGroup.cancelVehicle.call( + vehicleId: item['vehicleId'], + licensePlate: item['licensePlate'], + model: item['model'], + color: item['color'], + ); } Future processCancelUpdateRequest(dynamic item) async { - final int id = item['vehicleId']; - return await PhpGroup.deleteVehicle.call(vehicleId: id); + return await PhpGroup.deleteVehicle.call( + vehicleId: item['vehicleId'], + licensePlate: item['licensePlate'], + model: item['model'], + color: item['color'], + + ); } Future processCancelCreateRequest(dynamic item) async { - final int id = item['vehicleId']; - return await PhpGroup.deleteVehicle.call(vehicleId: id); + return await PhpGroup.deleteVehicle.call( + vehicleId: item['vehicleId'], + licensePlate: item['licensePlate'], + model: item['model'], + color: item['color'], + ); } Map generateLabelsHashMap(dynamic item) { diff --git a/lib/shared/extensions/string_extensions.dart b/lib/shared/extensions/string_extensions.dart index dc0b62c6..32290e61 100644 --- a/lib/shared/extensions/string_extensions.dart +++ b/lib/shared/extensions/string_extensions.dart @@ -9,6 +9,12 @@ extension StringNullableExtensions on String? { if (this == '') return true; return false; } + + bool isNotNullAndEmpty() { + if (this == null) return false; + if (this == '') return false; + return true; + } } extension StringExtensions on String { From 268c4c897be0995593272de6f06c7881e92b188d Mon Sep 17 00:00:00 2001 From: jantunemesssias Date: Fri, 31 Jan 2025 14:30:52 -0300 Subject: [PATCH 11/47] WIP --- .vscode/launch.json | 29 + integration_test/app_test.dart | 7 - integration_test/auth_test.dart | 4 +- .../shared_components_atoms/custom_input.dart | 1 + .../media_upload_button.dart | 10 +- .../shared_components_atoms/toast.dart | 1 - ..._arrow_linked_locals_component_widget.dart | 1 + .../card_item_template_component_widget.dart | 134 +++- .../details_component_widget.dart | 42 +- ...item_details_template_component_model.dart | 1 - .../provisional_schedule_template_model.dart | 1 - ...siter_vistor_template_component_model.dart | 1 - ...iter_vistor_template_component_widget.dart | 2 +- .../view_visit_detail_model.dart | 1 - ...search_modal_template_component_model.dart | 1 - lib/core/meta/anotations.dart | 1 - .../backend/api_requests/api_calls.dart | 5 +- .../backend/schema/structs/device_struct.dart | 1 - .../widgets/provisional_filter_modal.dart | 1 - .../home/presentation/pages/about_system.dart | 2 + .../home/presentation/pages/home_page.dart | 1 - .../locals_local_data_source.dart | 2 +- .../local_profile/local_profile_widget.dart | 2 +- lib/features/local/utils/local_util.dart | 7 + .../menu/presentation/mappers/menu_entry.dart | 4 + .../widgets/menu_item/menu_item_button.dart | 17 +- .../license_local_data_source.dart | 2 +- .../module/data/models/license_model.dart | 1 - .../module/data/models/module_model.dart | 1 - .../module/domain/entities/base_module.dart | 2 - .../module/domain/entities/license.dart | 6 +- .../notification/deep_link_service.dart | 1 - .../profile_local_data_source.dart | 2 - .../storage/enums/database_storage_key.dart | 4 +- .../repositories/storage_repository_impl.dart | 1 - lib/flutter_flow/flutter_flow_widgets.dart | 1 - lib/initialization.dart | 1 - lib/main.dart | 1 - .../reception_page/reception_page_widget.dart | 1 - .../residents_on_the_property_screen.dart | 2 +- .../vehicle_history_screen.dart | 153 ++-- .../vehicle_model.dart | 695 ++++++++++-------- .../vehicles_on_the_property.dart | 5 +- lib/pages/visits_on_the_property/model.dart | 2 +- lib/shared/extensions/string_extensions.dart | 11 +- lib/shared/utils/text_util.dart | 4 +- 46 files changed, 713 insertions(+), 462 deletions(-) create mode 100644 .vscode/launch.json diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 00000000..3bfc4b44 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,29 @@ +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + + { + "name": "flutter-freaccesss-hub", + "request": "launch", + "type": "dart", + "args": [ + "--no-enable-impeller" + ] + }, + { + "name": "flutter-freaccesss-hub (profile mode)", + "request": "launch", + "type": "dart", + "flutterMode": "profile" + }, + { + "name": "flutter-freaccesss-hub (release mode)", + "request": "launch", + "type": "dart", + "flutterMode": "release" + } + ] +} \ No newline at end of file diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index 028840ca..fe7ff027 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -7,13 +7,10 @@ import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:go_router/go_router.dart'; import 'package:hub/components/molecular_components/throw_exception/throw_exception_widget.dart'; import 'package:hub/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart'; import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart'; import 'package:hub/components/templates_components/details_component/details_component_widget.dart'; -import 'package:hub/components/templates_components/forgot_password_template_component/forgot_password_template_component_widget.dart'; import 'package:hub/features/backend/api_requests/index.dart'; import 'package:hub/features/local/index.dart'; import 'package:hub/features/menu/index.dart'; @@ -23,14 +20,10 @@ import 'package:hub/features/notification/index.dart'; import 'package:hub/features/storage/index.dart'; import 'package:hub/flutter_flow/index.dart' as ff; import 'package:hub/flutter_flow/index.dart'; -import 'package:hub/initialization.dart'; import 'package:hub/main.dart'; -import 'package:hub/pages/forgot_password_page/forgot_password_screen.dart'; -import 'package:hub/pages/vehicles_on_the_property/vehicle_model.dart'; import 'package:hub/pages/vehicles_on_the_property/vehicles_on_the_property.dart'; import 'package:integration_test/integration_test.dart'; import 'package:material_symbols_icons/symbols.dart'; -import 'package:patrol/patrol.dart'; import 'package:flutter_web_plugins/url_strategy.dart'; import 'app_test.dart'; diff --git a/integration_test/auth_test.dart b/integration_test/auth_test.dart index e18a3916..b1105a8b 100644 --- a/integration_test/auth_test.dart +++ b/integration_test/auth_test.dart @@ -34,7 +34,7 @@ class AuthenticationTest { ); Map concat(String username, String domain, String password) { return { - 'emailTextFormField': '${username}@${domain}.test', + 'emailTextFormField': '$username@$domain.test', 'passwordTextFormField': password, }; } @@ -138,7 +138,7 @@ class AuthenticationTest { Map concat(String name, String username, String domain, String password) { return { 'nameTextFormField': name, - 'emailTextFormField': '${username}@${domain}.test', + 'emailTextFormField': '$username@$domain.test', 'passwordTextFormField': password, }; } diff --git a/lib/components/atomic_components/shared_components_atoms/custom_input.dart b/lib/components/atomic_components/shared_components_atoms/custom_input.dart index cac159f4..02634611 100644 --- a/lib/components/atomic_components/shared_components_atoms/custom_input.dart +++ b/lib/components/atomic_components/shared_components_atoms/custom_input.dart @@ -150,6 +150,7 @@ class _CustomInputUtilState extends State { maxLines: null, maxLength: widget.haveMaxLength ? widget.maxLength : null, keyboardType: widget.keyboardType, + inputFormatters: [ LengthLimitingTextInputFormatter(widget.maxLength), ], diff --git a/lib/components/atomic_components/shared_components_atoms/media_upload_button.dart b/lib/components/atomic_components/shared_components_atoms/media_upload_button.dart index ec1c5af3..c2424e70 100644 --- a/lib/components/atomic_components/shared_components_atoms/media_upload_button.dart +++ b/lib/components/atomic_components/shared_components_atoms/media_upload_button.dart @@ -33,7 +33,7 @@ class _MediaUploadButtonUtilState extends State { @override Widget build(BuildContext context) { double limitedInputTextSize = LimitedFontSizeUtil.getInputFontSize(context); - bool _isLoading = false; + bool isLoading = false; return Builder( builder: (context) { @@ -72,7 +72,7 @@ class _MediaUploadButtonUtilState extends State { child: GestureDetector( onTap: () async { setState(() { - _isLoading = true; + isLoading = true; }); final selectedMedia = await selectMediaWithSourceBottomSheet( @@ -120,7 +120,7 @@ class _MediaUploadButtonUtilState extends State { showUploadMessage(context, message); } else { setState(() { - _isLoading = false; + isLoading = false; }); final message = FFLocalizations.of(context) .getVariableText( @@ -131,7 +131,7 @@ class _MediaUploadButtonUtilState extends State { } } else { setState(() { - _isLoading = false; + isLoading = false; }); } }, @@ -150,7 +150,7 @@ class _MediaUploadButtonUtilState extends State { mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, children: [ - _isLoading + isLoading ? SizedBox( width: 30.0, height: 30.0, diff --git a/lib/components/atomic_components/shared_components_atoms/toast.dart b/lib/components/atomic_components/shared_components_atoms/toast.dart index 1be2a15e..30cc5332 100644 --- a/lib/components/atomic_components/shared_components_atoms/toast.dart +++ b/lib/components/atomic_components/shared_components_atoms/toast.dart @@ -1,6 +1,5 @@ import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; -import 'package:hub/shared/utils/limited_text_size.dart'; class ToastUtil { static void showToast({ diff --git a/lib/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart b/lib/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart index 141400e6..1993ba8e 100644 --- a/lib/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart +++ b/lib/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart @@ -195,6 +195,7 @@ class _BottomArrowLinkedLocalsComponentWidgetState extends State(local['CLI_NOME']), imagePath: _imagePath(local), + icon: null, labelsHashMap: _labelsHashMap(local), statusHashMap: [_statusHashMap(local)], onTapCardItemAction: () async { diff --git a/lib/components/templates_components/card_item_template_component/card_item_template_component_widget.dart b/lib/components/templates_components/card_item_template_component/card_item_template_component_widget.dart index 9c96f384..049f78e4 100644 --- a/lib/components/templates_components/card_item_template_component/card_item_template_component_widget.dart +++ b/lib/components/templates_components/card_item_template_component/card_item_template_component_widget.dart @@ -12,18 +12,73 @@ import 'card_item_template_component_model.dart'; export 'card_item_template_component_model.dart'; +class FreCardIcon extends StatelessWidget { + final double height; + final double width; + final Icon icon; + + const FreCardIcon({ + super.key, + required this.height, + required this.width, + required this.icon, + }); + + @override + Widget build(BuildContext context) { + return SizedBox( + height: height, + width: width, + child: icon, + ); + } +} + +class FreCardPin extends StatelessWidget { + final double height; + final double width; + final Color color; + + const FreCardPin({ + super.key, + required this.height, + required this.width, + required this.color, + }); + + @override + Widget build(BuildContext context) { + return Padding( + padding: const EdgeInsets.all(8.0), + child: Container( + height: height, + width: width, + decoration: BoxDecoration( + color: color, + shape: BoxShape.circle, + ), + ), + ); + } +} + + class CardItemTemplateComponentWidget extends StatefulWidget { const CardItemTemplateComponentWidget({ super.key, required this.labelsHashMap, required this.statusHashMap, - required this.imagePath, + this.imagePath, + this.icon, + this.pin, required this.onTapCardItemAction, }); final Map? labelsHashMap; final List?> statusHashMap; final String? imagePath; + final FreCardIcon? icon; + final FreCardPin? pin; final Future Function()? onTapCardItemAction; @override @@ -124,8 +179,25 @@ class _CardItemTemplateComponentWidgetState ); } + Widget _generateIcon() { + return Column( + children: [ + widget.icon!, + ], + ); + + } + + Widget _generatePin() { + return widget.pin!; + + } + List _generateStatus() { double limitedBodyTextSize = LimitedFontSizeUtil.getBodyFontSize(context); + int statusCount = statusLinkedHashMap.length; + double itemWidthFactor = statusCount == 1 ? 0.5 : 0.25; + return statusLinkedHashMap.expand((statusLinked) { return statusLinked.entries.map((entry) { final text = entry.key; @@ -135,7 +207,7 @@ class _CardItemTemplateComponentWidgetState message: text, child: Container( padding: const EdgeInsets.all(5), - width: MediaQuery.of(context).size.width * 0.25, + width: MediaQuery.of(context).size.width * itemWidthFactor, decoration: BoxDecoration( color: color, borderRadius: BorderRadius.circular(5), @@ -161,38 +233,54 @@ class _CardItemTemplateComponentWidgetState return LayoutBuilder( builder: (context, constraints) { if (constraints.maxWidth > 360) { - return Row( + return Column( + mainAxisAlignment: MainAxisAlignment.center, + crossAxisAlignment: CrossAxisAlignment.center, mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ - Expanded( - child: Column( - crossAxisAlignment: CrossAxisAlignment.start, - mainAxisSize: MainAxisSize.min, - children: [ - ..._generateLabels(), - SizedBox(height: 3), - Wrap( - spacing: 8, - runSpacing: 4, - children: _generateStatus(), + Row( + mainAxisAlignment: MainAxisAlignment.end, + mainAxisSize: MainAxisSize.max, + children: [if(widget.pin != null) _generatePin()]), + Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Expanded( + child: Column( + crossAxisAlignment: CrossAxisAlignment.start, + mainAxisSize: MainAxisSize.min, + children: [ + ..._generateLabels(), + + Wrap( + spacing: 8, + runSpacing: 4, + children: _generateStatus(), + ), + ] + .addToEnd(const SizedBox(height: 5)) + .divide(const SizedBox(height: 3)) + .addToStart(const SizedBox(height: 5)), ), - ] - .addToEnd(const SizedBox(height: 5)) - .divide(const SizedBox(height: 1)) - .addToStart(const SizedBox(height: 5)), - ), + ), + if(widget.icon != null) _generateIcon(), + if (widget.imagePath != null) _generateImage() + + ] + .addToEnd(const SizedBox(width: 10)) + .addToStart(const SizedBox(width: 10)), ), - if (widget.imagePath != null) _generateImage(), ] - .addToEnd(const SizedBox(width: 10)) - .addToStart(const SizedBox(width: 10)), + .addToStart(SizedBox(height: 5)) + .addToEnd(SizedBox(height: 5)), ); } else { return Column( mainAxisSize: MainAxisSize.min, children: [ if (widget.imagePath != null) _generateImage(), + if(widget.icon != null) _generateIcon(), Container( padding: const EdgeInsets.all(8), child: Column( diff --git a/lib/components/templates_components/details_component/details_component_widget.dart b/lib/components/templates_components/details_component/details_component_widget.dart index 6a4f5cec..b7c1c616 100644 --- a/lib/components/templates_components/details_component/details_component_widget.dart +++ b/lib/components/templates_components/details_component/details_component_widget.dart @@ -3,6 +3,7 @@ import 'dart:collection'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; +import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart'; import 'package:hub/components/templates_components/details_component/details_component_model.dart'; import 'package:hub/flutter_flow/flutter_flow_theme.dart'; import 'package:hub/flutter_flow/flutter_flow_util.dart'; @@ -10,10 +11,11 @@ import 'package:hub/shared/utils/limited_text_size.dart'; class DetailsComponentWidget extends StatefulWidget { const DetailsComponentWidget({ - Key? key, + super.key, required this.labelsHashMap, required this.statusHashMap, this.imagePath, + this.icon, this.onTapCardItemAction, required this.buttons, }); @@ -23,6 +25,7 @@ class DetailsComponentWidget extends StatefulWidget { final String? imagePath; final Future Function()? onTapCardItemAction; final List? buttons; + final FreCardIcon? icon; @override State createState() => _DetailsComponentWidgetState(); @@ -95,6 +98,16 @@ class _DetailsComponentWidgetState extends State { useOldImageOnUrlChange: true, ), ), + if (widget.icon != null && widget.icon != '') + Container( + width: MediaQuery.of(context).size.width * 0.3, + height: MediaQuery.of(context).size.width * 0.3, + clipBehavior: Clip.antiAlias, + decoration: const BoxDecoration( + shape: BoxShape.circle, + ), + child: widget.icon!, + ), SizedBox(height: MediaQuery.of(context).size.height * 0.03), Row( children: statusLinkedHashMap.expand((linkedHashMap) { @@ -109,6 +122,7 @@ class _DetailsComponentWidgetState extends State { autofocus: false, canRequestFocus: false, readOnly: true, + initialValue: item.key, obscureText: false, decoration: InputDecoration( isDense: true, @@ -120,7 +134,7 @@ class _DetailsComponentWidgetState extends State { ), filled: true, fillColor: item.value, - labelText: item.key, + // labelText: item.key, labelStyle: FlutterFlowTheme.of(context) .labelMedium .override( @@ -156,16 +170,20 @@ class _DetailsComponentWidgetState extends State { color: FlutterFlowTheme.of(context).info, ), ), - style: FlutterFlowTheme.of(context).bodyMedium.override( - fontFamily: - FlutterFlowTheme.of(context).bodyMediumFamily, - color: FlutterFlowTheme.of(context).info, - letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap().containsKey( - FlutterFlowTheme.of(context).bodyMediumFamily, + style: FlutterFlowTheme.of(context) + .labelMedium + .override( + fontFamily: FlutterFlowTheme.of(context) + .labelMediumFamily, + fontWeight: FontWeight.bold, + color: FlutterFlowTheme.of(context).info, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey( + FlutterFlowTheme.of(context) + .labelMediumFamily, + ), + fontSize: limitedBodyFontSize, ), - fontSize: limitedBodyFontSize, - ), textAlign: TextAlign.center, maxLines: null, keyboardType: TextInputType.name, @@ -188,7 +206,7 @@ class _DetailsComponentWidgetState extends State { // return Text('key: $key, value: $value'); return TextFormField( readOnly: true, - initialValue: '$value', + initialValue: value, style: FlutterFlowTheme.of(context).bodyMedium.override( fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily, diff --git a/lib/components/templates_components/liberation_history_item_details_template_component/liberation_history_item_details_template_component_model.dart b/lib/components/templates_components/liberation_history_item_details_template_component/liberation_history_item_details_template_component_model.dart index 0fefa607..98d1c915 100644 --- a/lib/components/templates_components/liberation_history_item_details_template_component/liberation_history_item_details_template_component_model.dart +++ b/lib/components/templates_components/liberation_history_item_details_template_component/liberation_history_item_details_template_component_model.dart @@ -32,7 +32,6 @@ class LiberationHistoryItemDetailsTemplateComponentModel (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; - ; } @override diff --git a/lib/components/templates_components/provisional_schedule_template/provisional_schedule_template_model.dart b/lib/components/templates_components/provisional_schedule_template/provisional_schedule_template_model.dart index c1e82767..7674b173 100644 --- a/lib/components/templates_components/provisional_schedule_template/provisional_schedule_template_model.dart +++ b/lib/components/templates_components/provisional_schedule_template/provisional_schedule_template_model.dart @@ -1,4 +1,3 @@ -import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:hub/components/templates_components/provisional_schedule_template/provisional_shcedule_template_widget.dart'; diff --git a/lib/components/templates_components/regisiter_vistor_template_component/regisiter_vistor_template_component_model.dart b/lib/components/templates_components/regisiter_vistor_template_component/regisiter_vistor_template_component_model.dart index acff7931..c3d0ee0b 100644 --- a/lib/components/templates_components/regisiter_vistor_template_component/regisiter_vistor_template_component_model.dart +++ b/lib/components/templates_components/regisiter_vistor_template_component/regisiter_vistor_template_component_model.dart @@ -140,7 +140,6 @@ class RegisiterVistorTemplateComponentModel (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; - ; } @override diff --git a/lib/components/templates_components/regisiter_vistor_template_component/regisiter_vistor_template_component_widget.dart b/lib/components/templates_components/regisiter_vistor_template_component/regisiter_vistor_template_component_widget.dart index 4a9c5ebe..b6c71aaf 100644 --- a/lib/components/templates_components/regisiter_vistor_template_component/regisiter_vistor_template_component_widget.dart +++ b/lib/components/templates_components/regisiter_vistor_template_component/regisiter_vistor_template_component_widget.dart @@ -35,7 +35,7 @@ class RegisiterVistorTemplateComponentWidget extends StatefulWidget { class _RegisiterVistorTemplateComponentWidgetState extends State { late RegisiterVistorTemplateComponentModel _model; - bool _isLoading = false; + final bool _isLoading = false; final scaffoldKey = GlobalKey(); bool _isVisitorRegistered = false; diff --git a/lib/components/templates_components/view_visit_detail/view_visit_detail_model.dart b/lib/components/templates_components/view_visit_detail/view_visit_detail_model.dart index d115ada3..b7628924 100644 --- a/lib/components/templates_components/view_visit_detail/view_visit_detail_model.dart +++ b/lib/components/templates_components/view_visit_detail/view_visit_detail_model.dart @@ -41,7 +41,6 @@ class ViewVisitDetailModel extends FlutterFlowModel { (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; - ; } @override diff --git a/lib/components/templates_components/visitor_search_modal_template_component/visitor_search_modal_template_component_model.dart b/lib/components/templates_components/visitor_search_modal_template_component/visitor_search_modal_template_component_model.dart index 17cc8baf..34b0bfc2 100644 --- a/lib/components/templates_components/visitor_search_modal_template_component/visitor_search_modal_template_component_model.dart +++ b/lib/components/templates_components/visitor_search_modal_template_component/visitor_search_modal_template_component_model.dart @@ -43,7 +43,6 @@ class VisitorSearchModalTemplateComponentModel (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; - ; } @override diff --git a/lib/core/meta/anotations.dart b/lib/core/meta/anotations.dart index af721eaa..b75916be 100644 --- a/lib/core/meta/anotations.dart +++ b/lib/core/meta/anotations.dart @@ -1,4 +1,3 @@ -import 'package:meta/meta.dart'; class DeadCode { final String? desc; diff --git a/lib/features/backend/api_requests/api_calls.dart b/lib/features/backend/api_requests/api_calls.dart index 3219ac27..4b828e00 100644 --- a/lib/features/backend/api_requests/api_calls.dart +++ b/lib/features/backend/api_requests/api_calls.dart @@ -66,6 +66,7 @@ class PhpGroup extends Api { static GetResidentsByProperty getResidentsByProperty = GetResidentsByProperty(); static GetOpenedVisits getOpenedVisits = GetOpenedVisits(); + @override GetLicense getLicense = GetLicense(); static GetProvSchedules getProvSchedules = GetProvSchedules(); static RegisterVehicle registerVehicle = RegisterVehicle(); @@ -76,7 +77,7 @@ class PhpGroup extends Api { class CancelVehicle { Future call({ - required final String vehicleId, + required final int vehicleId, required final String licensePlate, required final String model, required final String color, @@ -118,7 +119,7 @@ class CancelVehicle { class DeleteVehicle { Future call({ - required final String vehicleId, + required final int vehicleId, required final String licensePlate, required final String model, required final String color, diff --git a/lib/features/backend/schema/structs/device_struct.dart b/lib/features/backend/schema/structs/device_struct.dart index db8a8896..3a765860 100644 --- a/lib/features/backend/schema/structs/device_struct.dart +++ b/lib/features/backend/schema/structs/device_struct.dart @@ -3,7 +3,6 @@ import 'package:hub/features/backend/index.dart'; import 'package:hub/flutter_flow/nav/nav.dart'; -import 'index.dart'; class DeviceStruct extends BaseStruct { DeviceStruct({ diff --git a/lib/features/history/presentation/widgets/provisional_filter_modal.dart b/lib/features/history/presentation/widgets/provisional_filter_modal.dart index 44d0f538..bd46e621 100644 --- a/lib/features/history/presentation/widgets/provisional_filter_modal.dart +++ b/lib/features/history/presentation/widgets/provisional_filter_modal.dart @@ -1,4 +1,3 @@ -import 'dart:developer'; import 'package:flutter/material.dart'; diff --git a/lib/features/home/presentation/pages/about_system.dart b/lib/features/home/presentation/pages/about_system.dart index 78a409c2..4ba7d028 100644 --- a/lib/features/home/presentation/pages/about_system.dart +++ b/lib/features/home/presentation/pages/about_system.dart @@ -12,6 +12,8 @@ import 'package:package_info_plus/package_info_plus.dart'; import 'package:url_launcher/url_launcher.dart'; class AboutSystemPage extends StatefulWidget { + const AboutSystemPage({super.key}); + @override _AboutSystemPageState createState() => _AboutSystemPageState(); } diff --git a/lib/features/home/presentation/pages/home_page.dart b/lib/features/home/presentation/pages/home_page.dart index 0d87ea9f..f2496866 100644 --- a/lib/features/home/presentation/pages/home_page.dart +++ b/lib/features/home/presentation/pages/home_page.dart @@ -4,7 +4,6 @@ import 'package:google_fonts/google_fonts.dart'; import 'package:hub/features/home/presentation/widgets/drawer_widget.dart'; import 'package:hub/features/local/index.dart'; import 'package:hub/features/menu/index.dart'; -import 'package:hub/features/storage/index.dart'; import 'package:hub/flutter_flow/flutter_flow_icon_button.dart'; import 'package:hub/flutter_flow/flutter_flow_theme.dart'; import 'package:hub/flutter_flow/flutter_flow_util.dart'; diff --git a/lib/features/local/data/data_sources/locals_local_data_source.dart b/lib/features/local/data/data_sources/locals_local_data_source.dart index e259f2c3..c63aec38 100644 --- a/lib/features/local/data/data_sources/locals_local_data_source.dart +++ b/lib/features/local/data/data_sources/locals_local_data_source.dart @@ -58,7 +58,7 @@ class LocalsLocalDataSourceImpl implements LocalsLocalDataSource { }, conflictAlgorithm: ConflictAlgorithm.replace, ); - } catch (e, s) {} + } catch (e) {} } @override diff --git a/lib/features/local/presentation/widgets/local_profile/local_profile_widget.dart b/lib/features/local/presentation/widgets/local_profile/local_profile_widget.dart index 3cabc3e7..4215d501 100644 --- a/lib/features/local/presentation/widgets/local_profile/local_profile_widget.dart +++ b/lib/features/local/presentation/widgets/local_profile/local_profile_widget.dart @@ -255,7 +255,7 @@ class _LocalProfileComponentWidgetState ), Tooltip( message: - valueOrDefault(' ' + state.ownerName, ''), + valueOrDefault(' ${state.ownerName}', ''), child: Text( valueOrDefault( state.ownerName.length > 30 diff --git a/lib/features/local/utils/local_util.dart b/lib/features/local/utils/local_util.dart index 88214b27..2a0b6d6b 100644 --- a/lib/features/local/utils/local_util.dart +++ b/lib/features/local/utils/local_util.dart @@ -95,6 +95,8 @@ class LocalUtil { try { await StorageHelper().set(LocalsStorageKey.whatsapp.key, jsonBody['whatsapp'] ?? false); await StorageHelper().set(LocalsStorageKey.provisional.key, jsonBody['provisional'] ?? false); + await StorageHelper().set(LocalsStorageKey.vehicleAutoApproval.key, jsonBody['vehicleAutoApproval'] ?? false); + await StorageHelper().set( LocalsStorageKey.pets.key, jsonBody['pet'] ?? false, @@ -118,6 +120,11 @@ class LocalUtil { await StorageHelper().set(LocalsStorageKey.petAmount.key, jsonBody['petAmountRegister']?.toString().isEmpty ?? true ? '0' : jsonBody['petAmountRegister'].toString()); + + await StorageHelper().set(LocalsStorageKey.vehicleAmountRegister.key, + jsonBody['vehicleAmountRegister']?.toString().isEmpty ?? true ? '0' : jsonBody['vehicleAmountRegister'].toString()); + + await StorageHelper().set(ProfileStorageKey.userName.key, jsonBody['visitado']['VDO_NOME'] ?? ''); await StorageHelper().set(ProfileStorageKey.userEmail.key, jsonBody['visitado']['VDO_EMAIL'] ?? ''); await StorageHelper().set(LocalsStorageKey.provisional.key, jsonBody['provisional'] ?? false); diff --git a/lib/features/menu/presentation/mappers/menu_entry.dart b/lib/features/menu/presentation/mappers/menu_entry.dart index 79c5e770..3398b0ae 100644 --- a/lib/features/menu/presentation/mappers/menu_entry.dart +++ b/lib/features/menu/presentation/mappers/menu_entry.dart @@ -7,9 +7,13 @@ import 'package:material_symbols_icons/symbols.dart'; enum MenuEntryType { Home, Drawer, Property } class MenuEntry implements BaseModule { + @override final String key; + @override final IconData icon; + @override final String name; + @override final String route; final List types; diff --git a/lib/features/menu/presentation/widgets/menu_item/menu_item_button.dart b/lib/features/menu/presentation/widgets/menu_item/menu_item_button.dart index c8f81e31..d5142c21 100644 --- a/lib/features/menu/presentation/widgets/menu_item/menu_item_button.dart +++ b/lib/features/menu/presentation/widgets/menu_item/menu_item_button.dart @@ -76,16 +76,15 @@ class _MenuButtonWidgetState extends State { mainAxisAlignment: MainAxisAlignment.spaceEvenly, crossAxisAlignment: CrossAxisAlignment.start, children: [ - if (widget.icon != null) - Container( - alignment: Alignment.topLeft, - padding: const EdgeInsets.only(left: 8.0), - child: Icon( - widget.icon, - size: 24.0, - color: FlutterFlowTheme.of(context).primaryText, - ), + Container( + alignment: Alignment.topLeft, + padding: const EdgeInsets.only(left: 8.0), + child: Icon( + widget.icon, + size: 24.0, + color: FlutterFlowTheme.of(context).primaryText, ), + ), Flexible( child: Padding( padding: const EdgeInsets.only(left: 10.0), diff --git a/lib/features/module/data/data_sources/license_local_data_source.dart b/lib/features/module/data/data_sources/license_local_data_source.dart index cc377225..4cbe143f 100644 --- a/lib/features/module/data/data_sources/license_local_data_source.dart +++ b/lib/features/module/data/data_sources/license_local_data_source.dart @@ -94,7 +94,7 @@ class LicenseLocalDataSourceImpl implements LicenseLocalDataSource { Future isNewVersion() async { final String? reponse = await StorageHelper().get(LocalsStorageKey.isNewVersion.key); - final bool isNewVersion = reponse.toBoolean(); + final bool isNewVersion = reponse.toBoolean; return isNewVersion; } diff --git a/lib/features/module/data/models/license_model.dart b/lib/features/module/data/models/license_model.dart index 48e215cc..df9e8f87 100644 --- a/lib/features/module/data/models/license_model.dart +++ b/lib/features/module/data/models/license_model.dart @@ -1,4 +1,3 @@ -import 'package:flutter/material.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; import 'module_model.dart'; diff --git a/lib/features/module/data/models/module_model.dart b/lib/features/module/data/models/module_model.dart index e373edc3..17a2f23b 100644 --- a/lib/features/module/data/models/module_model.dart +++ b/lib/features/module/data/models/module_model.dart @@ -1,4 +1,3 @@ -import 'package:flutter/material.dart'; import 'package:freezed_annotation/freezed_annotation.dart'; part 'module_model.freezed.dart'; diff --git a/lib/features/module/domain/entities/base_module.dart b/lib/features/module/domain/entities/base_module.dart index 1cfbeef0..9e8759aa 100644 --- a/lib/features/module/domain/entities/base_module.dart +++ b/lib/features/module/domain/entities/base_module.dart @@ -1,6 +1,4 @@ import 'package:flutter/material.dart'; -import 'package:hub/flutter_flow/internationalization.dart'; -import 'package:hub/flutter_flow/nav/nav.dart'; abstract class BaseModule { String get key; diff --git a/lib/features/module/domain/entities/license.dart b/lib/features/module/domain/entities/license.dart index 275776b9..130c7462 100644 --- a/lib/features/module/domain/entities/license.dart +++ b/lib/features/module/domain/entities/license.dart @@ -61,7 +61,7 @@ class License { } static Future _precessWpp() async { - final bool whatsapp = await StorageHelper().get(LocalsStorageKey.whatsapp.key).then((v) => v.toBoolean()); + final bool whatsapp = await StorageHelper().get(LocalsStorageKey.whatsapp.key).then((v) => v.toBoolean); if (whatsapp) return ModuleStatus.active.key; else @@ -69,7 +69,7 @@ class License { } static Future _processProvisional() async { - final bool provisional = await StorageHelper().get(LocalsStorageKey.provisional.key).then((v) => v.toBoolean()); + final bool provisional = await StorageHelper().get(LocalsStorageKey.provisional.key).then((v) => v.toBoolean); if (provisional) return ModuleStatus.active.key; else @@ -77,7 +77,7 @@ class License { } static Future _processPets() async { - final bool pets = await StorageHelper().get(LocalsStorageKey.pets.key).then((v) => v.toBoolean()); + final bool pets = await StorageHelper().get(LocalsStorageKey.pets.key).then((v) => v.toBoolean); if (pets) return ModuleStatus.active.key; else diff --git a/lib/features/notification/deep_link_service.dart b/lib/features/notification/deep_link_service.dart index cf7e13f2..374a8cd5 100644 --- a/lib/features/notification/deep_link_service.dart +++ b/lib/features/notification/deep_link_service.dart @@ -1,5 +1,4 @@ import 'dart:async'; -import 'dart:developer'; import 'package:app_links/app_links.dart'; import 'package:flutter/material.dart'; import 'package:hub/features/storage/index.dart'; diff --git a/lib/features/profile/data/data_sources/profile_local_data_source.dart b/lib/features/profile/data/data_sources/profile_local_data_source.dart index 8b0f9d1e..b1ee1258 100644 --- a/lib/features/profile/data/data_sources/profile_local_data_source.dart +++ b/lib/features/profile/data/data_sources/profile_local_data_source.dart @@ -1,8 +1,6 @@ import 'dart:developer'; -import 'package:hub/features/storage/constants/profile_constants.dart'; import 'package:hub/features/storage/index.dart'; -import 'package:hub/shared/constants/index.dart'; import 'package:sqflite/sqflite.dart'; diff --git a/lib/features/storage/enums/database_storage_key.dart b/lib/features/storage/enums/database_storage_key.dart index f4028646..92442313 100644 --- a/lib/features/storage/enums/database_storage_key.dart +++ b/lib/features/storage/enums/database_storage_key.dart @@ -34,7 +34,9 @@ enum LocalsStorageKey implements DatabaseStorageKey { panic('fre_panic'), person('fre_person'), requestOSNotification('fre_requestOSnotification'), - isNewVersion('fre_isNewVersion'); + isNewVersion('fre_isNewVersion'), + vehicleAutoApproval('fre_vehicleAutoApproval'), + vehicleAmountRegister('fre_vehicleAmountRegister'); final String key; diff --git a/lib/features/storage/repositories/storage_repository_impl.dart b/lib/features/storage/repositories/storage_repository_impl.dart index 30f3fd0d..1649b05e 100644 --- a/lib/features/storage/repositories/storage_repository_impl.dart +++ b/lib/features/storage/repositories/storage_repository_impl.dart @@ -1,7 +1,6 @@ import 'dart:developer'; import 'package:flutter/cupertino.dart'; -import 'package:hub/features/profile/data/data_sources/profile_local_data_source.dart'; import 'package:hub/features/storage/index.dart'; class StorageHelper implements StorageRepository { diff --git a/lib/flutter_flow/flutter_flow_widgets.dart b/lib/flutter_flow/flutter_flow_widgets.dart index 6845d783..122432eb 100644 --- a/lib/flutter_flow/flutter_flow_widgets.dart +++ b/lib/flutter_flow/flutter_flow_widgets.dart @@ -1,6 +1,5 @@ import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:flutter/material.dart'; -import 'package:auto_size_text/auto_size_text.dart'; class FFButtonOptions { const FFButtonOptions({ diff --git a/lib/initialization.dart b/lib/initialization.dart index 32198a5d..217044ec 100644 --- a/lib/initialization.dart +++ b/lib/initialization.dart @@ -1,4 +1,3 @@ -import 'dart:developer'; import 'package:app_tracking_transparency/app_tracking_transparency.dart'; import 'package:firebase_core/firebase_core.dart'; diff --git a/lib/main.dart b/lib/main.dart index 8db0f7c8..144a9fb5 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -14,7 +14,6 @@ import 'package:hub/features/storage/index.dart'; import 'package:hub/flutter_flow/flutter_flow_theme.dart'; import 'package:hub/flutter_flow/internationalization.dart'; import 'package:hub/flutter_flow/nav/nav.dart'; -import 'package:hub/shared/utils/test_util.dart'; import 'package:responsive_framework/responsive_framework.dart'; import 'initialization.dart'; diff --git a/lib/pages/reception_page/reception_page_widget.dart b/lib/pages/reception_page/reception_page_widget.dart index e7d5718e..b56f8bfe 100644 --- a/lib/pages/reception_page/reception_page_widget.dart +++ b/lib/pages/reception_page/reception_page_widget.dart @@ -1,4 +1,3 @@ -import 'dart:developer'; import 'package:awesome_notifications/awesome_notifications.dart'; import 'package:flutter/material.dart'; diff --git a/lib/pages/residents_on_the_property/residents_on_the_property_screen.dart b/lib/pages/residents_on_the_property/residents_on_the_property_screen.dart index 8f63d8a2..64b61acf 100644 --- a/lib/pages/residents_on_the_property/residents_on_the_property_screen.dart +++ b/lib/pages/residents_on_the_property/residents_on_the_property_screen.dart @@ -29,7 +29,7 @@ class _ResidentsOnThePropertyState extends State late final ResidentsOnThePropertyModel model; late Future _future; - List _wrap = []; + final List _wrap = []; @override void initState() { diff --git a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart index 0e496a76..8a618838 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart @@ -18,6 +18,7 @@ class _VehicleHistoryScreenState extends State { int _pageNumber = 1; bool _hasData = false; bool _loading = false; + int count = 0; @override @@ -28,7 +29,8 @@ class _VehicleHistoryScreenState extends State { _future = _fetchVisits(); _scrollController = ScrollController() ..addListener(() { - if (_scrollController.position.atEdge && _scrollController.position.pixels != 0) { + if (_scrollController.position.atEdge && + _scrollController.position.pixels != 0) { _loadMore(); } }); @@ -53,59 +55,101 @@ class _VehicleHistoryScreenState extends State { ); } - String getRandomStatus() { - var statuses = ['ATI', 'INA', 'APR_CREATE', 'APR_DELETE', 'APR_UPDATE', 'AGU_CHANGE']; + String mockRandomMapStatusColor() { + var statuses = [ + 'ATI', + 'INA', + 'APR_CREATE', + 'APR_DELETE', + 'APR_UPDATE', + 'AGU_CHANGE' + ]; statuses.shuffle(); return statuses.first; } - Widget _item(BuildContext context, Map uItem) { - uItem['status'] = getRandomStatus(); - return CardItemTemplateComponentWidget( - imagePath: null, - labelsHashMap: { - '${FFLocalizations.of(context).getVariableText(ptText: "Placa", enText: "License Plate")}:': - uItem['licensePlate'] ?? '', - '${FFLocalizations.of(context).getVariableText(ptText: "Modelo", enText: "Model")}:': uItem['model'] ?? '', - '${FFLocalizations.of(context).getVariableText(ptText: "Tag", enText: "Tag")}:': uItem['tag'] ?? '', - }, - statusHashMap: [widget.model.generateStatusColorMap(uItem)], - onTapCardItemAction: () async { - await showDialog( - useSafeArea: true, - context: context, - builder: (context) { - return Dialog( - alignment: Alignment.center, - child: widget.model.buildVehicleDetails( + Future _item(BuildContext context, Map uItem) async { + // uItem['status'] = mockRandomMapStatusColor(); + final bool? isOwner = uItem['isOwnerVehicle']; + late final IconData? iconData; + late final FreCardIcon? cardIcon; + + if(isOwner is bool) { + iconData = isOwner ? Symbols.no_crash :Symbols.directions_car; + cardIcon = FreCardIcon(height: 50, width: 100, icon: Icon(iconData, size: 80, opticalSize: 10)); + } + final String? tag = uItem['tag']; + final bool containTag = tag.isNotNullAndEmpty; + final Map labelsHashMap = { + '${FFLocalizations.of(context).getVariableText(ptText: "Placa", enText: "License Plate")}:': + uItem['licensePlate'] ?? '', + '${FFLocalizations.of(context).getVariableText(ptText: "Modelo", enText: "Model")}:': + uItem['model'] ?? '', + '${FFLocalizations.of(context).getVariableText(ptText: "Proprietário", enText: "Owner")}:': + uItem['personName'] ?? '', + if (containTag) + '${FFLocalizations.of(context).getVariableText(ptText: "Tag", enText: "Tag")}:': + uItem['tag'] ?? '', + }; + final List?> statusHashMap = [ + await widget.model.generateStatusColorMap(uItem, 2) + ]; + Future onTapCardItemAction() async { + await showDialog( + useSafeArea: true, + context: context, + builder: (context) { + return Dialog( + alignment: Alignment.center, + child: FutureBuilder( + future: widget.model.buildVehicleDetails( + icon: isOwner is bool ? cardIcon : null, item: uItem, context: context, model: widget.model, - )); - }, - ).whenComplete(() { - safeSetState(() { - _pageNumber = 1; - _wrap = []; - _future = _fetchVisits().then((value) => value!.jsonBody['vehicles'] ?? []); - }); - }).catchError((e, s) { - DialogUtil.errorDefault(context); - LogUtil.requestAPIFailed("proccessRequest.php", "", "Consulta de Veículos", e, s); - safeSetState(() { - _hasData = false; - _loading = false; - }); + ), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + return snapshot.data ?? Container(); + } else { + return Center(child: CircularProgressIndicator()); + } + }, + )); + }, + ).whenComplete(() { + safeSetState(() { + _pageNumber = 1; + _wrap = []; + _future = + _fetchVisits().then((value) => value!.jsonBody['vehicles'] ?? []); }); - }, - ); + }).catchError((e, s) { + DialogUtil.errorDefault(context); + LogUtil.requestAPIFailed( + "proccessRequest.php", "", "Consulta de Veículos", e, s); + safeSetState(() { + _hasData = false; + _loading = false; + }); + }); + return null; + return null; + } + + return CardItemTemplateComponentWidget( + icon: cardIcon, + labelsHashMap: labelsHashMap, + statusHashMap: statusHashMap, + onTapCardItemAction: onTapCardItemAction); } Future _fetchVisits() async { try { setState(() => _loading = true); - var response = await PhpGroup.getVehiclesByProperty.call(_pageNumber.toString()); + var response = + await PhpGroup.getVehiclesByProperty.call(_pageNumber.toString()); final List vehicles = response.jsonBody['vehicles'] ?? []; safeSetState(() => count = response.jsonBody['total_rows'] ?? 0); @@ -130,7 +174,8 @@ class _VehicleHistoryScreenState extends State { return null; } catch (e, s) { DialogUtil.errorDefault(context); - LogUtil.requestAPIFailed("proccessRequest.php", "", "Consulta de Veículo", e, s); + LogUtil.requestAPIFailed( + "proccessRequest.php", "", "Consulta de Veículo", e, s); setState(() { _hasData = false; _loading = false; @@ -149,7 +194,10 @@ class _VehicleHistoryScreenState extends State { @override Widget build(BuildContext context) { - late final limitedHeaderTextSize = LimitedFontSizeUtil.getHeaderFontSize(context); + late final limitedHeaderTextSize = + LimitedFontSizeUtil.getHeaderFontSize(context); + late final double limitedBodyTextSize = + LimitedFontSizeUtil.getBodyFontSize(context); return Column( mainAxisSize: MainAxisSize.max, @@ -192,13 +240,30 @@ class _VehicleHistoryScreenState extends State { return Padding( padding: const EdgeInsets.only(right: 30, top: 10), child: Text( - '', + (widget.model.amountRegister == '0' || + widget.model.amountRegister == null) + ? '' + : "${FFLocalizations.of(context).getVariableText(ptText: "Quantidade de Pets: ", enText: "Amount of Vehicles: ")}${widget.model.amountRegister}/$count", textAlign: TextAlign.right, + style: TextStyle( + fontFamily: 'Nunito', + fontSize: limitedBodyTextSize, + ), ), ); } else { Map item = _wrap[index - 1]; - return _item(context, item); + return FutureBuilder( + future: _item(context, item), + builder: (context, snapshot) { + if (snapshot.connectionState == + ConnectionState.done) { + return snapshot.data ?? Container(); + } else { + return Center(child: CircularProgressIndicator()); + } + }, + ); } }); }, diff --git a/lib/pages/vehicles_on_the_property/vehicle_model.dart b/lib/pages/vehicles_on_the_property/vehicle_model.dart index a279e972..2a643014 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_model.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_model.dart @@ -1,10 +1,13 @@ import 'dart:developer'; import 'package:flutter/material.dart'; +import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart'; import 'package:hub/components/templates_components/details_component/details_component_widget.dart'; import 'package:hub/features/backend/index.dart'; +import 'package:hub/features/storage/index.dart'; import 'package:hub/flutter_flow/index.dart'; import 'package:hub/pages/vehicles_on_the_property/vehicles_on_the_property.dart'; +import 'package:hub/shared/extensions/index.dart'; import 'package:hub/shared/utils/index.dart'; /// [VehicleModel] is a class that contains the business logic of the vehicle page. @@ -39,7 +42,7 @@ class VehicleModel extends FlutterFlowModel textFieldControllerModel = TextEditingController(); WidgetsBinding.instance.addPostFrameCallback((_) async { - vehicleAmountRegister = 0; + amountRegister = '0'; }); } @@ -57,7 +60,10 @@ class VehicleModel extends FlutterFlowModel final GlobalKey registerFormKey = GlobalKey(); final GlobalKey updateFormKey = GlobalKey(); - Future initAsync() async {} + Future initAsync() async { + + amountRegister = await StorageHelper().get(LocalsStorageKey.vehicleAmountRegister.key); + } bool isFormValid(BuildContext context) { if (registerFormKey.currentState == null) return false; @@ -75,7 +81,7 @@ mixin class _BaseVehiclePage { bool isEditing = false; String? vehicleId; ApiCallResponse? vehicleResponse; - late final vehicleAmountRegister; + String? amountRegister = '0'; VoidCallback? onUpdateVehicle; VoidCallback? onRegisterVehicle; @@ -93,9 +99,9 @@ mixin class _BaseVehiclePage { } // (ABC-1234) - final brazilianPlateRegex = RegExp(r'^[A-Z]{3}-\d{4}$'); + final brazilianPlateRegex = RegExp(r'^[A-Z]{3}\d{4}$'); // (ABC1D23) - final mercosurPlateRegex = RegExp(r'^[A-Z]{3}\d[A-Z]\d{2}$'); + final mercosurPlateRegex = RegExp(r'^[A-Z]{3}\d[A-Z0-9]\d{2}$'); if (!brazilianPlateRegex.hasMatch(value) && !mercosurPlateRegex.hasMatch(value)) { @@ -165,316 +171,6 @@ mixin class _BaseVehiclePage { } } -/// [_VehicleHistoryScreenModel] is a mixin that contains the business logic of the vehicle history page. -mixin _VehicleHistoryScreenModel on _BaseVehiclePage { - Map? generateStatusColorMap(dynamic uItem) { - final autoApproval = uItem['autoApproval']; - if (autoApproval == true) return null; - - final statusMap = { - "ATI": { - "text": FFLocalizations.of(context).getVariableText( - ptText: 'Ativo', - enText: 'Active', - ), - "color": FlutterFlowTheme.of(context).success, - }, - "INA": { - "text": FFLocalizations.of(context).getVariableText( - ptText: 'Inativo', - enText: 'Inactive', - ), - "color": FlutterFlowTheme.of(context).accent2, - }, - "APR_CREATE": { - "text": FFLocalizations.of(context).getVariableText( - ptText: 'Criando', - enText: 'Creating', - ), - "color": FlutterFlowTheme.of(context).success, - }, - "APR_DELETE": { - "text": FFLocalizations.of(context).getVariableText( - ptText: 'Deletando', - enText: 'Deleting', - ), - "color": FlutterFlowTheme.of(context).error, - }, - "APR_UPDATE": { - "text": FFLocalizations.of(context).getVariableText( - ptText: 'Atualizando', - enText: 'Updating', - ), - "color": FlutterFlowTheme.of(context).warning, - }, - "AGU_CHANGE": { - "text": FFLocalizations.of(context).getVariableText( - ptText: 'Aguardando', - enText: 'Waiting', - ), - "color": FlutterFlowTheme.of(context).accent2, - }, - }; - - final status = uItem['status']; - if (statusMap.containsKey(status)) { - return { - statusMap[status]!['text'] as String: - statusMap[status]!['color'] as Color, - }; - } - return {}; - } - - List? generateActionButtons(dynamic item) { - final Color iconButtonColor = FlutterFlowTheme.of(context).primaryText; - final FFButtonOptions buttonOptions = FFButtonOptions( - height: 40, - color: FlutterFlowTheme.of(context).primaryBackground, - elevation: 0, - textStyle: TextStyle( - color: FlutterFlowTheme.of(context).primaryText, - fontSize: LimitedFontSizeUtil.getNoResizeFont(context, 15), - ), - splashColor: FlutterFlowTheme.of(context).success, - borderSide: BorderSide( - color: FlutterFlowTheme.of(context).primaryBackground, - width: 1, - ), - ); - - final updateText = FFLocalizations.of(context) - .getVariableText(ptText: 'Editar', enText: 'Edit'); - final updateIcon = Icon(Icons.edit, color: iconButtonColor); - Future updateOnPressed() async { - context.pop(); - isEditing = true; - - switchTab(1); - setEditForm(item); - } - - final cancelText = FFLocalizations.of(context) - .getVariableText(ptText: 'Cancelar', enText: 'Cancel'); - final cancelIcon = Icon(Icons.close, color: iconButtonColor); - Future cancelOnPressed() async { - showAlertDialog( - context, - FFLocalizations.of(context).getVariableText( - ptText: 'Cancelar Solicitação', - enText: 'Cancel Request', - ), - FFLocalizations.of(context).getVariableText( - ptText: 'Você tem certeza que deseja cancelar essa solicitação?', - enText: 'Are you sure you want to delete this request?', - ), - () async => await processCancelRequest(item['status'], item), - ); - } - - final deleteText = FFLocalizations.of(context) - .getVariableText(ptText: 'Excluir', enText: 'Delete'); - final deleteIcon = Icon(Icons.delete, color: iconButtonColor); - Future deleteOnPressed() async { - showAlertDialog( - context, - FFLocalizations.of(context).getVariableText( - ptText: 'Excluir Veículo', - enText: 'Delete Vehicle', - ), - FFLocalizations.of(context).getVariableText( - ptText: 'Você tem certeza que deseja excluir esse veículo?', - enText: 'Are you sure you want to delete this vehicle?', - ), - () async => await processDeleteRequest(item), - ); - } - - return [ - if (item['status'].contains('AGU')) - FFButtonWidget( - text: updateText, - icon: updateIcon, - onPressed: updateOnPressed, - options: buttonOptions, - ), - if (item['status'].contains('APR') || item['status'].contains('AGU')) - FFButtonWidget( - text: cancelText, - icon: cancelIcon, - onPressed: cancelOnPressed, - options: buttonOptions, - ), - if (item['status'].contains('ATI')) - FFButtonWidget( - text: deleteText, - icon: deleteIcon, - onPressed: deleteOnPressed, - options: buttonOptions, - ), - ]; - } - - Future processDeleteRequest(dynamic item) async { - int id = item['vehicleId']; - await PhpGroup.deleteVehicle.call( - vehicleId: item['vehicleId'], - licensePlate: item['licensePlate'], - model: item['model'], - color: item['color'], - ).then((value) { - context.pop(value); - context.pop(value); - - // ignore: unrelated_type_equality_checks - if (value == false) { - showSnackbar( - context, - FFLocalizations.of(context).getVariableText( - ptText: 'Erro ao excluir veículo', - enText: 'Error deleting vehicle', - ), - true, - ); - // ignore: unrelated_type_equality_checks - } else if (value == true) { - showSnackbar( - context, - FFLocalizations.of(context).getVariableText( - enText: 'Success deleting vehicle', - ptText: 'Succeso ao excluir veículo', - ), - false, - ); - } - }).catchError((err, stack) { - context.pop(); - showSnackbar( - context, - FFLocalizations.of(context).getVariableText( - enText: 'Error deleting vehicle', - ptText: 'Erro ao excluir veículo', - ), - true, - ); - }); - } - - Future processCancelRequest(String status, dynamic item) async { - late final ApiCallResponse value; - try { - switch (status) { - case 'APR_CREATE': - value = await processCancelDeleteRequest(item); - break; - case 'AGU_CHANGE': - value = await processCancelUpdateRequest(item); - break; - case 'APR_DELETE': - value = await processCancelCreateRequest(item); - break; - default: - break; - } - - context.pop(value); - context.pop(value); - - if (value.jsonBody['error'] == false) { - showSnackbar( - context, - FFLocalizations.of(context).getVariableText( - ptText: 'Erro ao cancelar solicitação', - enText: 'Error canceling request', - ), - true, - ); - } else if (value.jsonBody['error'] == true) { - showSnackbar( - context, - FFLocalizations.of(context).getVariableText( - enText: 'Success canceling request', - ptText: 'Succeso ao cancelar solicitação', - ), - false, - ); - } - } catch (err) { - context.pop(); - showSnackbar( - context, - FFLocalizations.of(context).getVariableText( - enText: 'Error canceling request', - ptText: 'Erro ao cancelar solicitação', - ), - true, - ); - } - } - - Future processCancelDeleteRequest(dynamic item) async { - return await PhpGroup.cancelVehicle.call( - vehicleId: item['vehicleId'], - licensePlate: item['licensePlate'], - model: item['model'], - color: item['color'], - ); - } - - Future processCancelUpdateRequest(dynamic item) async { - return await PhpGroup.deleteVehicle.call( - vehicleId: item['vehicleId'], - licensePlate: item['licensePlate'], - model: item['model'], - color: item['color'], - - ); - } - - Future processCancelCreateRequest(dynamic item) async { - return await PhpGroup.deleteVehicle.call( - vehicleId: item['vehicleId'], - licensePlate: item['licensePlate'], - model: item['model'], - color: item['color'], - ); - } - - Map generateLabelsHashMap(dynamic item) { - return { - if (item['model'] != null && item['model'] != '') - '${FFLocalizations.of(context).getVariableText(ptText: "Modelo", enText: "Model")}:': - item['model'].toString().toUpperCase(), - if (item['licensePlate'] != null && item['licensePlate'] != '') - '${FFLocalizations.of(context).getVariableText(ptText: "Placa", enText: "License Plate")}:': - item['licensePlate'].toString().toUpperCase(), - if (item['color'] != null && item['color'] != '') - '${FFLocalizations.of(context).getVariableText(ptText: "Cor", enText: "Color")}:': - item['color'].toString().toUpperCase(), - if (item['personName'] != null && item['personName'] != '') - '${FFLocalizations.of(context).getVariableText(ptText: "Proprietário", enText: "Owner")}:': - item['personName'].toString().toUpperCase(), - if (item['tag'] != null && item['tag'] != '') - '${FFLocalizations.of(context).getVariableText(ptText: "Tag", enText: "Tag")}:': - item['tag'].toString().toUpperCase(), - }; - } - - Widget buildVehicleDetails({ - required dynamic item, - required BuildContext context, - required VehicleModel model, - }) { - final status = generateStatusColorMap(item); - final buttons = generateActionButtons(item); - final labels = generateLabelsHashMap(item); - return DetailsComponentWidget( - buttons: buttons, - labelsHashMap: labels, - statusHashMap: [status], - ); - } -} /// [_VehicleRegisterScreenModel] is a mixin that contains the business logic of the vehicle register page. mixin _VehicleRegisterScreenModel on _BaseVehiclePage { @@ -540,3 +236,372 @@ mixin _VehicleUpdateScreenModel on _BaseVehiclePage { } } } + +/// [_VehicleHistoryScreenModel] is a mixin that contains the business logic of the vehicle history page. +mixin _VehicleHistoryScreenModel on _BaseVehiclePage { + + Future?> generateStatusColorMap(dynamic uItem, int count) async { + final autoApproval = await StorageHelper().get(LocalsStorageKey.vehicleAutoApproval.key); + if(autoApproval.toBoolean == true) return null; + + final theme = FlutterFlowTheme.of(context); + final localization = FFLocalizations.of(context); + + + byLanguage(en, pt) => localization.getVariableText(enText: en, ptText: pt); + + + final preFixStatusMap = { + "ATI": { + "text": '', + "color": theme.success, + }, + "INA": { + "text": '', + "color": theme.accent2, + }, + + "APR_CREATE": { + "text": byLanguage('Awaiting', 'Aguardando'), + "color": theme.success, + }, + "APR_DELETE": { + "text": byLanguage('Awaiting', 'Aguardando'), + "color": theme.error, + }, + "APR_UPDATE": { + "text": byLanguage('Awaiting', 'Aguardando'), + "color": theme.warning, + }, + "AGU_CHANGE": { + "text": byLanguage('Awaiting', 'Aguardando'), + "color": theme.accent2, + }, + }; + final vehicleStatusMap = { + "ATI": { + "text": byLanguage('Active', 'Ativo'), + "color": theme.success, + }, + "INA": { + "text": byLanguage('Inactive', 'Inativo'), + "color": theme.accent2, + }, + + "APR_CREATE": { + "text": byLanguage('Creation', 'Criação'), + "color": theme.success, + }, + "APR_DELETE": { + "text": byLanguage('Deletion', 'Exclusão'), + "color": theme.error, + }, + "APR_UPDATE": { + "text": byLanguage('Update', 'Atualização'), + "color": theme.warning, + }, + "AGU_CHANGE": { + "text": byLanguage('Correction', 'Correção'), + "color": theme.accent2, + }, + }; + final ownerStatusMap = { + true: { + "text": byLanguage('My Vehicle', 'Meu Veículo'), + "color": theme.primaryText, + }, + false: { + "text": byLanguage('', ''), + "color": theme.accent2, + }, + }; + + final status = uItem['status']; + final isOwner = uItem['isOwnerVehicle']; + + if (vehicleStatusMap.containsKey(status)) { + if(count > 1) return { + preFixStatusMap[status]!['text'] as String: preFixStatusMap[status]!['color'] as Color, + vehicleStatusMap[status]!['text'] as String: vehicleStatusMap[status]!['color'] as Color, + // if (ownerStatusMap.containsKey(isOwner)) + // ownerStatusMap[isOwner]!['text'] as String: ownerStatusMap[isOwner]!['color'] as Color + }; + else return { + "${preFixStatusMap[status]!['text']} ${vehicleStatusMap[status]!['text']}": vehicleStatusMap[status]!['color'] as Color + }; + } + return {}; + } + + Future?> generateActionButtons(dynamic item) async { + final Color iconButtonColor = FlutterFlowTheme.of(context).primaryText; + final FFButtonOptions buttonOptions = FFButtonOptions( + height: 40, + color: FlutterFlowTheme.of(context).primaryBackground, + elevation: 0, + textStyle: TextStyle( + color: FlutterFlowTheme.of(context).primaryText, + fontSize: LimitedFontSizeUtil.getNoResizeFont(context, 15), + ), + splashColor: FlutterFlowTheme.of(context).success, + borderSide: BorderSide( + color: FlutterFlowTheme.of(context).primaryBackground, + width: 1, + ), + ); + + final updateText = FFLocalizations.of(context) + .getVariableText(ptText: 'Editar', enText: 'Edit'); + final updateIcon = Icon(Icons.edit, color: iconButtonColor); + Future updateOnPressed() async { + context.pop(); + isEditing = true; + + switchTab(1); + setEditForm(item); + } + + final cancelText = FFLocalizations.of(context) + .getVariableText(ptText: 'Cancelar', enText: 'Cancel'); + final cancelIcon = Icon(Icons.close, color: iconButtonColor); + Future cancelOnPressed() async { + showAlertDialog( + context, + FFLocalizations.of(context).getVariableText( + ptText: 'Cancelar Solicitação', + enText: 'Cancel Request', + ), + FFLocalizations.of(context).getVariableText( + ptText: 'Você tem certeza que deseja cancelar essa solicitação?', + enText: 'Are you sure you want to delete this request?', + ), + () async => await processCancelRequest(item['status'], item) + ); + } + + final deleteText = FFLocalizations.of(context) + .getVariableText(ptText: 'Excluir', enText: 'Delete'); + final deleteIcon = Icon(Icons.delete, color: iconButtonColor); + Future deleteOnPressed() async { + showAlertDialog( + context, + FFLocalizations.of(context).getVariableText( + ptText: 'Excluir Veículo', + enText: 'Delete Vehicle', + ), + FFLocalizations.of(context).getVariableText( + ptText: 'Você tem certeza que deseja excluir esse veículo?', + enText: 'Are you sure you want to delete this vehicle?', + ), + () async => await processDeleteRequest(item), + ); + } + + final bool containStatus = item['status'] == null; + final bool isOwnerVehicle = item['isOwnerVehicle']; + final bool isAGU = item['status'].contains('AGU'); + final bool isAPR = item['status'].contains('APR'); + final bool isATI = item['status'].contains('ATI'); + + if(containStatus) return [ + FFButtonWidget( + text: deleteText, + icon: deleteIcon, + onPressed: deleteOnPressed, + options: buttonOptions, + ), + ]; + + return [ + if (isAGU && isOwnerVehicle) + FFButtonWidget( + text: updateText, + icon: updateIcon, + onPressed: updateOnPressed, + options: buttonOptions, + ), + if ((isAPR || isAGU) && (isOwnerVehicle)) + FFButtonWidget( + text: cancelText, + icon: cancelIcon, + onPressed: cancelOnPressed, + options: buttonOptions, + ), + if (isATI && isOwnerVehicle) + FFButtonWidget( + text: deleteText, + icon: deleteIcon, + onPressed: deleteOnPressed, + options: buttonOptions, + ), + ]; + } + + Future processDeleteRequest(dynamic item) async { + log('processDeleteRequest -> item[$item]'); + return await PhpGroup.deleteVehicle.call( + vehicleId: item['vehicleId'], + licensePlate: item['licensePlate'], + model: item['model'], + color: item['color'], + ) + .then((value) { + + + context.pop(value); + context.pop(value); + + // ignore: unrelated_type_equality_checks + if (value.jsonBody['error'] == true) { + final String errorMsg = value.jsonBody['error_msg']; + return showSnackbar( + context, + FFLocalizations.of(context).getVariableText( + ptText: errorMsg, + enText: 'Error deleting vehicle', + ), + true, + ); + // ignore: unrelated_type_equality_checks + } + return showSnackbar( + context, + FFLocalizations.of(context).getVariableText( + enText: 'Success deleting vehicle', + ptText: 'Succeso ao excluir veículo', + ), + false, + ); + + }).catchError((err, stack) { + context.pop(); + return showSnackbar( + context, + FFLocalizations.of(context).getVariableText( + enText: 'Error deleting vehicle', + ptText: 'Erro ao excluir veículo', + ), + true, + ); + }); + } + + Future processCancelRequest(String status, dynamic item) async { + late final ApiCallResponse value; + try { + switch (status) { + case 'APR_CREATE': + value = await processCancelDeleteRequest(item); + break; + case 'AGU_CHANGE': + value = await processCancelUpdateRequest(item); + break; + case 'APR_DELETE': + value = await processCancelCreateRequest(item); + break; + default: + break; + } + + context.pop(value); + context.pop(value); + + if (value.jsonBody['error'] == true) { + final String errorMsg = value.jsonBody['error_msg'] ; + return showSnackbar( + context, + FFLocalizations.of(context).getVariableText( + ptText: errorMsg, + enText: 'Error canceling request', + ), + true, + ); + } + return showSnackbar( + context, + FFLocalizations.of(context).getVariableText( + enText: 'Success canceling request', + ptText: 'Succeso ao cancelar solicitação', + ), + false, + ); + + } catch (err) { + context.pop(); + return showSnackbar( + context, + FFLocalizations.of(context).getVariableText( + enText: 'Error canceling request', + ptText: 'Erro ao cancelar solicitação', + ), + true, + ); + } + } + + Future processCancelDeleteRequest(dynamic item) async { + return await PhpGroup.deleteVehicle.call( + vehicleId: item['vehicleId'], + licensePlate: item['licensePlate'], + model: item['model'], + color: item['color'], + ); + } + + Future processCancelUpdateRequest(dynamic item) async { + return await PhpGroup.deleteVehicle.call( + vehicleId: item['vehicleId'], + licensePlate: item['licensePlate'], + model: item['model'], + color: item['color'], + + ); + } + + Future processCancelCreateRequest(dynamic item) async { + return await PhpGroup.deleteVehicle.call( + vehicleId: item['vehicleId'], + licensePlate: item['licensePlate'], + model: item['model'], + color: item['color'], + ); + } + + Future> generateLabelsHashMap(dynamic item) async { + return { + if (item['model'] != null && item['model'] != '') + '${FFLocalizations.of(context).getVariableText(ptText: "Modelo", enText: "Model")}:': + item['model'].toString().toUpperCase(), + if (item['licensePlate'] != null && item['licensePlate'] != '') + '${FFLocalizations.of(context).getVariableText(ptText: "Placa", enText: "License Plate")}:': + item['licensePlate'].toString().toUpperCase(), + if (item['color'] != null && item['color'] != '') + '${FFLocalizations.of(context).getVariableText(ptText: "Cor", enText: "Color")}:': + item['color'].toString().toUpperCase(), + if (item['personName'] != null && item['personName'] != '') + '${FFLocalizations.of(context).getVariableText(ptText: "Proprietário", enText: "Owner")}:': + item['personName'].toString().toUpperCase(), + if (item['tag'] != null && item['tag'] != '') + '${FFLocalizations.of(context).getVariableText(ptText: "Tag", enText: "Tag")}:': + item['tag'].toString().toUpperCase(), + }; + } + + Future buildVehicleDetails({ + required dynamic item, + required BuildContext context, + required VehicleModel model, + required FreCardIcon? icon, + }) async { + + final status = await generateStatusColorMap(item, 1); + final buttons = await generateActionButtons(item); + final labels = await generateLabelsHashMap(item); + return DetailsComponentWidget( + icon: icon, + buttons: buttons, + labelsHashMap: labels, + statusHashMap: [status], + ); + } +} diff --git a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart index c96108fb..0d989e1c 100644 --- a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart +++ b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart @@ -1,4 +1,3 @@ -import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; @@ -8,11 +7,9 @@ import 'package:hub/components/atomic_components/shared_components_atoms/tabview import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart'; import 'package:hub/features/backend/index.dart'; import 'package:hub/features/module/index.dart'; -import 'package:hub/flutter_flow/flutter_flow_icon_button.dart'; -import 'package:hub/flutter_flow/flutter_flow_theme.dart'; -import 'package:hub/flutter_flow/flutter_flow_util.dart'; import 'package:hub/flutter_flow/index.dart'; import 'package:hub/pages/vehicles_on_the_property/vehicle_model.dart'; +import 'package:hub/shared/extensions/index.dart'; import 'package:hub/shared/utils/dialog_util.dart'; import 'package:hub/shared/utils/license_util.dart'; import 'package:hub/shared/utils/limited_text_size.dart'; diff --git a/lib/pages/visits_on_the_property/model.dart b/lib/pages/visits_on_the_property/model.dart index ef521047..4e15ebef 100644 --- a/lib/pages/visits_on_the_property/model.dart +++ b/lib/pages/visits_on_the_property/model.dart @@ -80,7 +80,7 @@ class VisitsModel extends FlutterFlowModel { ), }), imagePath: - 'https://freaccess.com.br/freaccess/getImage.php?devUUID=${devUUID}&cliID=${cliUUID}&atividade=getFoto&Documento=${item['VDO_DOCUMENTO']}&tipo=E', + 'https://freaccess.com.br/freaccess/getImage.php?devUUID=$devUUID&cliID=$cliUUID&atividade=getFoto&Documento=${item['VDO_DOCUMENTO']}&tipo=E', statusHashMap: [ Map.from({ if (item['VTA_FIXA'] != null) diff --git a/lib/shared/extensions/string_extensions.dart b/lib/shared/extensions/string_extensions.dart index 32290e61..67cf03db 100644 --- a/lib/shared/extensions/string_extensions.dart +++ b/lib/shared/extensions/string_extensions.dart @@ -1,16 +1,16 @@ extension StringNullableExtensions on String? { - bool toBoolean() { + bool get toBoolean { if (this == null) return false; return this!.toLowerCase() == 'true'; } - bool isNullOrEmpty() { + bool get isNullOrEmpty { if (this == null) return true; if (this == '') return true; return false; } - bool isNotNullAndEmpty() { + bool get isNotNullAndEmpty { if (this == null) return false; if (this == '') return false; return true; @@ -18,8 +18,9 @@ extension StringNullableExtensions on String? { } extension StringExtensions on String { - bool toBoolean() { - return this.toLowerCase() == 'true'; + bool get toBoolean { + + return toLowerCase() == 'true'; } } diff --git a/lib/shared/utils/text_util.dart b/lib/shared/utils/text_util.dart index d2876a0b..00d40ef9 100644 --- a/lib/shared/utils/text_util.dart +++ b/lib/shared/utils/text_util.dart @@ -6,11 +6,11 @@ class TextUtil extends StatelessWidget { final TextAlign? textAlign; const TextUtil({ - Key? key, + super.key, required this.text, this.style, this.textAlign, - }) : super(key: key); + }); @override Widget build(BuildContext context) { From 1cc481a83eb043d933aa37edbf3dcf7ab79195c0 Mon Sep 17 00:00:00 2001 From: jantunemesssias Date: Fri, 31 Jan 2025 15:28:53 -0300 Subject: [PATCH 12/47] checkpoint --- .../card_item_template_component_widget.dart | 20 ++-- .../vehicle_history_screen.dart | 101 ++++++++++-------- .../vehicle_model.dart | 25 ++--- 3 files changed, 77 insertions(+), 69 deletions(-) diff --git a/lib/components/templates_components/card_item_template_component/card_item_template_component_widget.dart b/lib/components/templates_components/card_item_template_component/card_item_template_component_widget.dart index 049f78e4..ded91f90 100644 --- a/lib/components/templates_components/card_item_template_component/card_item_template_component_widget.dart +++ b/lib/components/templates_components/card_item_template_component/card_item_template_component_widget.dart @@ -1,4 +1,5 @@ import 'dart:collection'; +import 'dart:developer'; import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; @@ -68,9 +69,10 @@ class CardItemTemplateComponentWidget extends StatefulWidget { super.key, required this.labelsHashMap, required this.statusHashMap, - this.imagePath, - this.icon, - this.pin, + this.imagePath, + this.icon, + this.pin, + this.itemWidthFactor = 0.25, required this.onTapCardItemAction, }); @@ -79,6 +81,7 @@ class CardItemTemplateComponentWidget extends StatefulWidget { final String? imagePath; final FreCardIcon? icon; final FreCardPin? pin; + final double itemWidthFactor; final Future Function()? onTapCardItemAction; @override @@ -195,19 +198,22 @@ class _CardItemTemplateComponentWidgetState List _generateStatus() { double limitedBodyTextSize = LimitedFontSizeUtil.getBodyFontSize(context); - int statusCount = statusLinkedHashMap.length; - double itemWidthFactor = statusCount == 1 ? 0.5 : 0.25; - + return statusLinkedHashMap.expand((statusLinked) { + + log('statusHashMap: ${statusLinked.length}'); + return statusLinked.entries.map((entry) { final text = entry.key; final color = entry.value; + + return Tooltip( message: text, child: Container( padding: const EdgeInsets.all(5), - width: MediaQuery.of(context).size.width * itemWidthFactor, + width: MediaQuery.of(context).size.width * widget.itemWidthFactor, decoration: BoxDecoration( color: color, borderRadius: BorderRadius.circular(5), diff --git a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart index 8a618838..97666429 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart @@ -91,57 +91,64 @@ class _VehicleHistoryScreenState extends State { '${FFLocalizations.of(context).getVariableText(ptText: "Tag", enText: "Tag")}:': uItem['tag'] ?? '', }; - final List?> statusHashMap = [ - await widget.model.generateStatusColorMap(uItem, 2) - ]; - Future onTapCardItemAction() async { - await showDialog( - useSafeArea: true, - context: context, - builder: (context) { - return Dialog( - alignment: Alignment.center, - child: FutureBuilder( - future: widget.model.buildVehicleDetails( - icon: isOwner is bool ? cardIcon : null, - item: uItem, - context: context, - model: widget.model, - ), - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.done) { - return snapshot.data ?? Container(); - } else { - return Center(child: CircularProgressIndicator()); - } - }, - )); - }, - ).whenComplete(() { - safeSetState(() { - _pageNumber = 1; - _wrap = []; - _future = - _fetchVisits().then((value) => value!.jsonBody['vehicles'] ?? []); - }); - }).catchError((e, s) { - DialogUtil.errorDefault(context); - LogUtil.requestAPIFailed( - "proccessRequest.php", "", "Consulta de Veículos", e, s); - safeSetState(() { - _hasData = false; - _loading = false; - }); - }); - return null; - return null; - } + final Map? statusHashMap = await widget.model.generateStatusColorMap(uItem, 2); + final List?> statusHashMapList = [await widget.model.generateStatusColorMap(uItem, 2)]; + Future onTapCardItemAction() async { + final widgetFuture = widget.model.buildVehicleDetails( + icon: isOwner is bool ? cardIcon : null, + item: uItem, + context: context, + model: widget.model, + ); + final dialogContent = await widgetFuture; + + await showDialog( + useSafeArea: true, + context: context, + builder: (context) { + return Dialog( + alignment: Alignment.center, + child: dialogContent, + ); + }, + ).whenComplete(() { + safeSetState(() { + _pageNumber = 1; + _wrap = []; + _future = _fetchVisits(); + }); + }).catchError((e, s) { + DialogUtil.errorDefault(context); + LogUtil.requestAPIFailed( + "proccessRequest.php", "", "Consulta de Veículos", e, s); + safeSetState(() { + _hasData = false; + _loading = false; + }); + }); + } + final statusLinkedHashMap = statusHashMapList + .map((map) => LinkedHashMap.from(map ?? {})) + .toList(); + print('CardItemTemplateComponentWidget: ${statusLinkedHashMap}'); return CardItemTemplateComponentWidget( icon: cardIcon, labelsHashMap: labelsHashMap, - statusHashMap: statusHashMap, - onTapCardItemAction: onTapCardItemAction); + statusHashMap: statusHashMapList, + onTapCardItemAction: onTapCardItemAction, + itemWidthFactor: statusLinkedHashMap!.length == 1 ? 0.25 : 0.50 + ); + // double itemWidthFactor = statusHashMap.length == 1 ? 0.5 : 0.5; + // double itemWidthFactor; + // if (statusCount >= 3 && statusCount % 3 != 0) { + // itemWidthFactor = (index % 3 == 2) ? 0.5 : 0.25; + // } else if (statusCount == 3) { + // itemWidthFactor = (index == 2) ? 0.52 : 0.25; + // } else { + // itemWidthFactor = statusCount == 1 ? 0.5 : 0.25; + // } + } Future _fetchVisits() async { diff --git a/lib/pages/vehicles_on_the_property/vehicle_model.dart b/lib/pages/vehicles_on_the_property/vehicle_model.dart index 2a643014..5c828797 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_model.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_model.dart @@ -251,23 +251,14 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { byLanguage(en, pt) => localization.getVariableText(enText: en, ptText: pt); - final preFixStatusMap = { - "ATI": { - "text": '', - "color": theme.success, - }, - "INA": { - "text": '', - "color": theme.accent2, - }, - + final preFixStatusMap = { "APR_CREATE": { "text": byLanguage('Awaiting', 'Aguardando'), - "color": theme.success, + "color": theme.warning, }, "APR_DELETE": { "text": byLanguage('Awaiting', 'Aguardando'), - "color": theme.error, + "color": theme.warning, }, "APR_UPDATE": { "text": byLanguage('Awaiting', 'Aguardando'), @@ -294,7 +285,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { }, "APR_DELETE": { "text": byLanguage('Deletion', 'Exclusão'), - "color": theme.error, + "color": theme.warning, }, "APR_UPDATE": { "text": byLanguage('Update', 'Atualização'), @@ -321,12 +312,16 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { if (vehicleStatusMap.containsKey(status)) { if(count > 1) return { + if (preFixStatusMap.containsKey(status)) preFixStatusMap[status]!['text'] as String: preFixStatusMap[status]!['color'] as Color, vehicleStatusMap[status]!['text'] as String: vehicleStatusMap[status]!['color'] as Color, - // if (ownerStatusMap.containsKey(isOwner)) + // if (ownerStatusMap.containsKey(isOwner) && (status != 'ATI' || status != 'INA')) // ownerStatusMap[isOwner]!['text'] as String: ownerStatusMap[isOwner]!['color'] as Color }; - else return { + if(status == 'ATI' || status == 'INA') return { + vehicleStatusMap[status]!['text'] as String: vehicleStatusMap[status]!['color'] as Color, + }; + return { "${preFixStatusMap[status]!['text']} ${vehicleStatusMap[status]!['text']}": vehicleStatusMap[status]!['color'] as Color }; } From a07edd0c21b84b1e7a488372b5e1973dac172e03 Mon Sep 17 00:00:00 2001 From: "J. A. Messias" Date: Fri, 31 Jan 2025 20:58:08 -0300 Subject: [PATCH 13/47] milestone --- .../vehicle_history_screen.dart | 101 ++++++----- .../vehicle_model.dart | 163 +++++++++--------- .../vehicles_on_the_property.dart | 2 + 3 files changed, 135 insertions(+), 131 deletions(-) diff --git a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart index 97666429..2f734437 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart @@ -74,9 +74,12 @@ class _VehicleHistoryScreenState extends State { late final IconData? iconData; late final FreCardIcon? cardIcon; - if(isOwner is bool) { - iconData = isOwner ? Symbols.no_crash :Symbols.directions_car; - cardIcon = FreCardIcon(height: 50, width: 100, icon: Icon(iconData, size: 80, opticalSize: 10)); + if (isOwner is bool) { + iconData = isOwner ? Symbols.no_crash : Symbols.directions_car; + cardIcon = FreCardIcon( + height: 50, + width: 100, + icon: Icon(iconData, size: 80, opticalSize: 10)); } final String? tag = uItem['tag']; final bool containTag = tag.isNotNullAndEmpty; @@ -91,64 +94,68 @@ class _VehicleHistoryScreenState extends State { '${FFLocalizations.of(context).getVariableText(ptText: "Tag", enText: "Tag")}:': uItem['tag'] ?? '', }; - final Map? statusHashMap = await widget.model.generateStatusColorMap(uItem, 2); - final List?> statusHashMapList = [await widget.model.generateStatusColorMap(uItem, 2)]; + final Map? statusHashMap = + await widget.model.generateStatusColorMap(uItem, 2); + final List?> statusHashMapList = [ + await widget.model.generateStatusColorMap(uItem, 2) + ]; Future onTapCardItemAction() async { final widgetFuture = widget.model.buildVehicleDetails( - icon: isOwner is bool ? cardIcon : null, - item: uItem, - context: context, - model: widget.model, + icon: isOwner is bool ? cardIcon : null, + item: uItem, + context: context, + model: widget.model, ); final dialogContent = await widgetFuture; await showDialog( - useSafeArea: true, - context: context, - builder: (context) { - return Dialog( - alignment: Alignment.center, - child: dialogContent, - ); - }, + useSafeArea: true, + context: context, + builder: (context) { + return Dialog( + alignment: Alignment.center, + child: dialogContent, + ); + }, ).whenComplete(() { - safeSetState(() { - _pageNumber = 1; - _wrap = []; - _future = _fetchVisits(); - }); + safeSetState(() { + _pageNumber = 1; + _wrap = []; + _future = _fetchVisits(); + }); }).catchError((e, s) { - DialogUtil.errorDefault(context); - LogUtil.requestAPIFailed( - "proccessRequest.php", "", "Consulta de Veículos", e, s); - safeSetState(() { - _hasData = false; - _loading = false; - }); + DialogUtil.errorDefault(context); + LogUtil.requestAPIFailed( + "proccessRequest.php", "", "Consulta de Veículos", e, s); + safeSetState(() { + _hasData = false; + _loading = false; + }); }); } - final statusLinkedHashMap = statusHashMapList + + final statusLinkedHashMap = statusHashMapList .map((map) => LinkedHashMap.from(map ?? {})) .toList(); - print('CardItemTemplateComponentWidget: ${statusLinkedHashMap}'); + final length = statusLinkedHashMap.expand((e) => [e.length]); + print('CardItemTemplateComponentWidget: ${length}'); return CardItemTemplateComponentWidget( - icon: cardIcon, - labelsHashMap: labelsHashMap, - statusHashMap: statusHashMapList, - onTapCardItemAction: onTapCardItemAction, - itemWidthFactor: statusLinkedHashMap!.length == 1 ? 0.25 : 0.50 - ); - // double itemWidthFactor = statusHashMap.length == 1 ? 0.5 : 0.5; - // double itemWidthFactor; - // if (statusCount >= 3 && statusCount % 3 != 0) { - // itemWidthFactor = (index % 3 == 2) ? 0.5 : 0.25; - // } else if (statusCount == 3) { - // itemWidthFactor = (index == 2) ? 0.52 : 0.25; - // } else { - // itemWidthFactor = statusCount == 1 ? 0.5 : 0.25; - // } - + icon: cardIcon, + labelsHashMap: labelsHashMap, + statusHashMap: statusHashMapList, + onTapCardItemAction: onTapCardItemAction, + itemWidthFactor: length == 1 ? 0.25 : 0.50, + ); + // double itemWidthFactor = statusHashMap.length == 1 ? 0.5 : 0.5; + // double itemWidthFactor; + // if (statusCount >= 3 && statusCount % 3 != 0) { + // itemWidthFactor = (index % 3 == 2) ? 0.5 : 0.25; + // } else if (statusCount == 3) { + // itemWidthFactor = (index == 2) ? 0.52 : 0.25; + // } else { + // itemWidthFactor = statusCount == 1 ? 0.5 : 0.25; + // } } Future _fetchVisits() async { diff --git a/lib/pages/vehicles_on_the_property/vehicle_model.dart b/lib/pages/vehicles_on_the_property/vehicle_model.dart index 5c828797..354fceea 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_model.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_model.dart @@ -61,8 +61,8 @@ class VehicleModel extends FlutterFlowModel final GlobalKey updateFormKey = GlobalKey(); Future initAsync() async { - - amountRegister = await StorageHelper().get(LocalsStorageKey.vehicleAmountRegister.key); + amountRegister = + await StorageHelper().get(LocalsStorageKey.vehicleAmountRegister.key); } bool isFormValid(BuildContext context) { @@ -171,7 +171,6 @@ mixin class _BaseVehiclePage { } } - /// [_VehicleRegisterScreenModel] is a mixin that contains the business logic of the vehicle register page. mixin _VehicleRegisterScreenModel on _BaseVehiclePage { Future registerVehicle() async { @@ -239,19 +238,18 @@ mixin _VehicleUpdateScreenModel on _BaseVehiclePage { /// [_VehicleHistoryScreenModel] is a mixin that contains the business logic of the vehicle history page. mixin _VehicleHistoryScreenModel on _BaseVehiclePage { - - Future?> generateStatusColorMap(dynamic uItem, int count) async { - final autoApproval = await StorageHelper().get(LocalsStorageKey.vehicleAutoApproval.key); - if(autoApproval.toBoolean == true) return null; + Future?> generateStatusColorMap( + dynamic uItem, int count) async { + final autoApproval = + await StorageHelper().get(LocalsStorageKey.vehicleAutoApproval.key); + if (autoApproval.toBoolean == true) return null; final theme = FlutterFlowTheme.of(context); final localization = FFLocalizations.of(context); - byLanguage(en, pt) => localization.getVariableText(enText: en, ptText: pt); - - final preFixStatusMap = { + final preFixStatusMap = { "APR_CREATE": { "text": byLanguage('Awaiting', 'Aguardando'), "color": theme.warning, @@ -278,13 +276,12 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { "text": byLanguage('Inactive', 'Inativo'), "color": theme.accent2, }, - "APR_CREATE": { "text": byLanguage('Creation', 'Criação'), "color": theme.success, }, "APR_DELETE": { - "text": byLanguage('Deletion', 'Exclusão'), + "text": byLanguage('Awaiting Deletion', 'Exclusão'), "color": theme.warning, }, "APR_UPDATE": { @@ -301,28 +298,31 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { "text": byLanguage('My Vehicle', 'Meu Veículo'), "color": theme.primaryText, }, - false: { - "text": byLanguage('', ''), - "color": theme.accent2, - }, }; final status = uItem['status']; final isOwner = uItem['isOwnerVehicle']; if (vehicleStatusMap.containsKey(status)) { - if(count > 1) return { - if (preFixStatusMap.containsKey(status)) - preFixStatusMap[status]!['text'] as String: preFixStatusMap[status]!['color'] as Color, - vehicleStatusMap[status]!['text'] as String: vehicleStatusMap[status]!['color'] as Color, - // if (ownerStatusMap.containsKey(isOwner) && (status != 'ATI' || status != 'INA')) - // ownerStatusMap[isOwner]!['text'] as String: ownerStatusMap[isOwner]!['color'] as Color - }; - if(status == 'ATI' || status == 'INA') return { - vehicleStatusMap[status]!['text'] as String: vehicleStatusMap[status]!['color'] as Color, - }; + if (count > 1) + return { + // if (preFixStatusMap.containsKey(status)) + // preFixStatusMap[status]!['text'] as String: preFixStatusMap[status]!['color'] as Color, + vehicleStatusMap[status]!['text'] as String: + vehicleStatusMap[status]!['color'] as Color, + if (ownerStatusMap.containsKey(isOwner) && + (status != 'ATI' || status != 'INA')) + ownerStatusMap[isOwner]!['text'] as String: + ownerStatusMap[isOwner]!['color'] as Color + }; + if (status == 'ATI' || status == 'INA') + return { + vehicleStatusMap[status]!['text'] as String: + vehicleStatusMap[status]!['color'] as Color, + }; return { - "${preFixStatusMap[status]!['text']} ${vehicleStatusMap[status]!['text']}": vehicleStatusMap[status]!['color'] as Color + "${preFixStatusMap[status]!['text']} ${vehicleStatusMap[status]!['text']}": + vehicleStatusMap[status]!['color'] as Color }; } return {}; @@ -361,17 +361,16 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { final cancelIcon = Icon(Icons.close, color: iconButtonColor); Future cancelOnPressed() async { showAlertDialog( - context, - FFLocalizations.of(context).getVariableText( - ptText: 'Cancelar Solicitação', - enText: 'Cancel Request', - ), - FFLocalizations.of(context).getVariableText( - ptText: 'Você tem certeza que deseja cancelar essa solicitação?', - enText: 'Are you sure you want to delete this request?', - ), - () async => await processCancelRequest(item['status'], item) - ); + context, + FFLocalizations.of(context).getVariableText( + ptText: 'Cancelar Solicitação', + enText: 'Cancel Request', + ), + FFLocalizations.of(context).getVariableText( + ptText: 'Você tem certeza que deseja cancelar essa solicitação?', + enText: 'Are you sure you want to delete this request?', + ), + () async => await processCancelRequest(item['status'], item)); } final deleteText = FFLocalizations.of(context) @@ -398,14 +397,15 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { final bool isAPR = item['status'].contains('APR'); final bool isATI = item['status'].contains('ATI'); - if(containStatus) return [ + if (containStatus) + return [ FFButtonWidget( text: deleteText, icon: deleteIcon, onPressed: deleteOnPressed, options: buttonOptions, ), - ]; + ]; return [ if (isAGU && isOwnerVehicle) @@ -434,15 +434,14 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { Future processDeleteRequest(dynamic item) async { log('processDeleteRequest -> item[$item]'); - return await PhpGroup.deleteVehicle.call( - vehicleId: item['vehicleId'], - licensePlate: item['licensePlate'], - model: item['model'], - color: item['color'], - ) - .then((value) { - - + return await PhpGroup.deleteVehicle + .call( + vehicleId: item['vehicleId'], + licensePlate: item['licensePlate'], + model: item['model'], + color: item['color'], + ) + .then((value) { context.pop(value); context.pop(value); @@ -460,14 +459,13 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { // ignore: unrelated_type_equality_checks } return showSnackbar( - context, - FFLocalizations.of(context).getVariableText( - enText: 'Success deleting vehicle', - ptText: 'Succeso ao excluir veículo', - ), - false, - ); - + context, + FFLocalizations.of(context).getVariableText( + enText: 'Success deleting vehicle', + ptText: 'Succeso ao excluir veículo', + ), + false, + ); }).catchError((err, stack) { context.pop(); return showSnackbar( @@ -502,7 +500,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { context.pop(value); if (value.jsonBody['error'] == true) { - final String errorMsg = value.jsonBody['error_msg'] ; + final String errorMsg = value.jsonBody['error_msg']; return showSnackbar( context, FFLocalizations.of(context).getVariableText( @@ -512,15 +510,14 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { true, ); } - return showSnackbar( - context, - FFLocalizations.of(context).getVariableText( - enText: 'Success canceling request', - ptText: 'Succeso ao cancelar solicitação', - ), - false, - ); - + return showSnackbar( + context, + FFLocalizations.of(context).getVariableText( + enText: 'Success canceling request', + ptText: 'Succeso ao cancelar solicitação', + ), + false, + ); } catch (err) { context.pop(); return showSnackbar( @@ -536,30 +533,29 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { Future processCancelDeleteRequest(dynamic item) async { return await PhpGroup.deleteVehicle.call( - vehicleId: item['vehicleId'], - licensePlate: item['licensePlate'], - model: item['model'], - color: item['color'], - ); + vehicleId: item['vehicleId'], + licensePlate: item['licensePlate'], + model: item['model'], + color: item['color'], + ); } Future processCancelUpdateRequest(dynamic item) async { return await PhpGroup.deleteVehicle.call( - vehicleId: item['vehicleId'], - licensePlate: item['licensePlate'], - model: item['model'], - color: item['color'], - - ); + vehicleId: item['vehicleId'], + licensePlate: item['licensePlate'], + model: item['model'], + color: item['color'], + ); } Future processCancelCreateRequest(dynamic item) async { return await PhpGroup.deleteVehicle.call( - vehicleId: item['vehicleId'], - licensePlate: item['licensePlate'], - model: item['model'], - color: item['color'], - ); + vehicleId: item['vehicleId'], + licensePlate: item['licensePlate'], + model: item['model'], + color: item['color'], + ); } Future> generateLabelsHashMap(dynamic item) async { @@ -588,7 +584,6 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { required VehicleModel model, required FreCardIcon? icon, }) async { - final status = await generateStatusColorMap(item, 1); final buttons = await generateActionButtons(item); final labels = await generateLabelsHashMap(item); diff --git a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart index 0d989e1c..cd3b28a4 100644 --- a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart +++ b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart @@ -1,4 +1,6 @@ +import 'dart:collection'; + import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:hub/components/atomic_components/shared_components_atoms/custom_input.dart'; From 73ea7d5641ec6c484da02e41ce6b541088c18829 Mon Sep 17 00:00:00 2001 From: jantunemesssias Date: Mon, 3 Feb 2025 09:02:23 -0300 Subject: [PATCH 14/47] format --- integration_test/auth_test.dart | 34 +- integration_test/example_test.dart | 1 + integration_test/test_bundle.dart | 3 +- integration_test/utils_test.dart | 15 +- integration_test/vehicle_test.dart | 29 +- .../shared_components_atoms/custom_input.dart | 1 - .../shared_components_atoms/tabview.dart | 3 +- ..._arrow_linked_locals_component_widget.dart | 80 +- .../card_item_template_component_widget.dart | 32 +- .../details_component_widget.dart | 27 +- ...ot_password_template_component_widget.dart | 118 ++- .../provisional_schedule_template_model.dart | 1 - .../sign_in_template_component_widget.dart | 839 +++++++++++++----- lib/core/meta/anotations.dart | 1 - .../backend/schema/structs/device_struct.dart | 1 - .../widgets/provisional_filter_modal.dart | 1 - .../home/presentation/pages/home_page.dart | 6 +- .../locals_remote_data_source.dart | 27 +- .../repositories/locals_repository_impl.dart | 6 +- lib/features/local/utils/local_util.dart | 120 ++- .../data_sources/menu_local_data_source.dart | 34 +- .../repositories/menu_repository_impl.dart | 30 +- .../module/domain/entities/license.dart | 32 +- .../notification/deep_link_service.dart | 3 +- lib/flutter_flow/nav/nav.dart | 150 +++- lib/initialization.dart | 1 - lib/main.dart | 13 +- .../forgot_password_screen.dart | 111 ++- lib/pages/pets_page/pets_page_model.dart | 1 - lib/pages/pets_page/pets_page_widget.dart | 2 - .../reception_page/reception_page_widget.dart | 1 - .../vehicle_register_screen.dart | 37 +- .../vehicle_update_screen.dart | 34 +- .../vehicles_on_the_property.dart | 32 +- lib/pages/visits_on_the_property/model.dart | 10 +- lib/shared/constants/index.dart | 1 + lib/shared/extensions/string_extensions.dart | 3 +- lib/shared/utils/license_util.dart | 3 +- 38 files changed, 1254 insertions(+), 589 deletions(-) diff --git a/integration_test/auth_test.dart b/integration_test/auth_test.dart index b1105a8b..e353d565 100644 --- a/integration_test/auth_test.dart +++ b/integration_test/auth_test.dart @@ -6,7 +6,8 @@ class AuthenticationTest { 'Sign-In with fuzzed emails', (PatrolIntegrationTester tester) async { $ = tester; - $.tester.printToConsole('Authentication Test - Sign-In with fuzzed emails'); + $.tester + .printToConsole('Authentication Test - Sign-In with fuzzed emails'); final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget); final Fuzzer fuzzer = Fuzzer( @@ -32,7 +33,8 @@ class AuthenticationTest { ], iterations: 2, ); - Map concat(String username, String domain, String password) { + Map concat( + String username, String domain, String password) { return { 'emailTextFormField': '$username@$domain.test', 'passwordTextFormField': password, @@ -61,7 +63,8 @@ class AuthenticationTest { 'Sign-In with email_app@exemplo.com', (PatrolIntegrationTester tester) async { $ = tester; - $.tester.printToConsole('Authentication Test - Sign-In with email_app@exemplo.com'); + $.tester.printToConsole( + 'Authentication Test - Sign-In with email_app@exemplo.com'); final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget); final Map credentials = { @@ -82,7 +85,8 @@ class AuthenticationTest { 'Sign Up - credenciais já registradas', (PatrolIntegrationTester tester) async { $ = tester; - $.tester.printToConsole('Authentication Test - Sign-Up: credenciais já registradas'); + $.tester.printToConsole( + 'Authentication Test - Sign-Up: credenciais já registradas'); final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget); final Map credentials = { @@ -102,7 +106,8 @@ class AuthenticationTest { 'Sign Up - credenciais novas', (PatrolIntegrationTester tester) async { $ = tester; - $.tester.printToConsole('Authentication Test - Sign-Up: credenciais novas'); + $.tester + .printToConsole('Authentication Test - Sign-Up: credenciais novas'); final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget); @@ -135,7 +140,8 @@ class AuthenticationTest { ], iterations: 2, ); - Map concat(String name, String username, String domain, String password) { + Map concat( + String name, String username, String domain, String password) { return { 'nameTextFormField': name, 'emailTextFormField': '$username@$domain.test', @@ -168,7 +174,8 @@ class AuthenticationTest { 'Deslogar da Conta', (PatrolIntegrationTester tester) async { $ = tester; - $.tester.printToConsole('Authentication Test - Sign-Out: Deslogar da Conta'); + $.tester.printToConsole( + 'Authentication Test - Sign-Out: Deslogar da Conta'); await _loggedWithMultiLocalsAccount($); await $.pumpWidget(const App()); @@ -179,7 +186,9 @@ class AuthenticationTest { await $.waitUntilVisible($(MenuListView)); - await $(Icons.exit_to_app).waitUntilVisible().tap(settlePolicy: SettlePolicy.trySettle); + await $(Icons.exit_to_app) + .waitUntilVisible() + .tap(settlePolicy: SettlePolicy.trySettle); await Future.delayed(const Duration(milliseconds: 500)); }, @@ -203,7 +212,8 @@ class AuthenticationTest { Future.delayed(Duration(seconds: 3)); await $.pump(Duration(seconds: 3)); await $.pumpAndSettle(); - final PatrolFinder forgotPassword = await $(#ForgotPasswordScreen).waitUntilVisible(); + final PatrolFinder forgotPassword = + await $(#ForgotPasswordScreen).waitUntilVisible(); expect(forgotPassword, findsOneWidget); }); } @@ -230,7 +240,8 @@ Future _enterCredentials( } } -Future _submit(String key, PatrolIntegrationTester $, PatrolFinder throwsException) async { +Future _submit( + String key, PatrolIntegrationTester $, PatrolFinder throwsException) async { await $(ValueKey(key)) // .waitUntilVisible() .tap(); @@ -248,5 +259,6 @@ Future _submit(String key, PatrolIntegrationTester $, PatrolFinder throwsE String _generateRandomString(int length) { const chars = 'abcdefghijklmnopqrstuvwxyz0123456789'; final rand = Random(); - return List.generate(length, (index) => chars[rand.nextInt(chars.length)]).join(); + return List.generate(length, (index) => chars[rand.nextInt(chars.length)]) + .join(); } diff --git a/integration_test/example_test.dart b/integration_test/example_test.dart index e69de29b..8b137891 100644 --- a/integration_test/example_test.dart +++ b/integration_test/example_test.dart @@ -0,0 +1 @@ + diff --git a/integration_test/test_bundle.dart b/integration_test/test_bundle.dart index 52ae7570..55d38e30 100644 --- a/integration_test/test_bundle.dart +++ b/integration_test/test_bundle.dart @@ -59,7 +59,8 @@ Future main() async { // Maybe somewhat counterintuitively, this callback runs *after* the calls // to group() below. final topLevelGroup = Invoker.current!.liveTest.groups.first; - final dartTestGroup = createDartTestGroup(topLevelGroup, + final dartTestGroup = createDartTestGroup( + topLevelGroup, tags: null, excludeTags: null, ); diff --git a/integration_test/utils_test.dart b/integration_test/utils_test.dart index 1f1bedc2..1ed65d0a 100644 --- a/integration_test/utils_test.dart +++ b/integration_test/utils_test.dart @@ -1,6 +1,7 @@ part of 'app_test.dart'; -Future _loggedWithMultiLocalsAccount(PatrolIntegrationTester $, [bool forceLinkedLocal = true]) async { +Future _loggedWithMultiLocalsAccount(PatrolIntegrationTester $, + [bool forceLinkedLocal = true]) async { await _init($); await StorageHelper() // .set(SecureStorageKey.isLogged.value, 'true'); @@ -20,13 +21,15 @@ Future _loggedWithMultiLocalsAccount(PatrolIntegrationTester $, [bool forc if (forceLinkedLocal == true) { await StorageHelper().set(ProfileStorageKey.clientUUID.key, '7'); await StorageHelper().set(ProfileStorageKey.ownerUUID.key, '7'); - await StorageHelper().set(ProfileStorageKey.clientName.key, 'FRE ACCESS DEMO'); + await StorageHelper() + .set(ProfileStorageKey.clientName.key, 'FRE ACCESS DEMO'); await PhpGroup.resopndeVinculo.call(tarefa: 'A'); await LicenseRepositoryImpl().resetLicense(); } } -Future _loggedWithSomeoneLocalAccount(PatrolIntegrationTester $, [bool forceLinkedLocal = true]) async { +Future _loggedWithSomeoneLocalAccount(PatrolIntegrationTester $, + [bool forceLinkedLocal = true]) async { await _init($); await StorageHelper() // .set(SecureStorageKey.isLogged.value, 'true'); @@ -46,7 +49,8 @@ Future _loggedWithSomeoneLocalAccount(PatrolIntegrationTester $, [bool for if (forceLinkedLocal == true) { await StorageHelper().set(ProfileStorageKey.clientUUID.key, '7'); await StorageHelper().set(ProfileStorageKey.ownerUUID.key, '7'); - await StorageHelper().set(ProfileStorageKey.clientName.key, 'FRE ACCESS DEMO'); + await StorageHelper() + .set(ProfileStorageKey.clientName.key, 'FRE ACCESS DEMO'); await PhpGroup.resopndeVinculo.call(tarefa: 'A'); await LicenseRepositoryImpl().resetLicense(); } @@ -95,7 +99,8 @@ Future _navigateToSignUp(PatrolIntegrationTester $) async { } Future _navigateBackUsingSystemGesture() async => - IntegrationTestWidgetsFlutterBinding.instance.keyboard.isLogicalKeyPressed(LogicalKeyboardKey.escape); + IntegrationTestWidgetsFlutterBinding.instance.keyboard + .isLogicalKeyPressed(LogicalKeyboardKey.escape); Future _initializeTracking() async { print('Requesting tracking authorization...'); diff --git a/integration_test/vehicle_test.dart b/integration_test/vehicle_test.dart index 1fa43131..6e89c69d 100644 --- a/integration_test/vehicle_test.dart +++ b/integration_test/vehicle_test.dart @@ -41,8 +41,9 @@ class VehicleTest { expect(listViewFinder, findsOneWidget); - final PatrolFinder entriesFinder = - await $(listViewFinder).$(CardItemTemplateComponentWidget).waitUntilVisible(); + final PatrolFinder entriesFinder = await $(listViewFinder) + .$(CardItemTemplateComponentWidget) + .waitUntilVisible(); expect(entriesFinder, findsWidgets); final int entriesCount = entriesFinder.evaluate().length; @@ -51,13 +52,16 @@ class VehicleTest { for (int i = 0; i < entriesCount; i++) { await $(entriesFinder.at(i)).scrollTo(); - await $(entriesFinder.at(i)).waitUntilVisible(timeout: const Duration(seconds: 1)).tap( + await $(entriesFinder.at(i)) + .waitUntilVisible(timeout: const Duration(seconds: 1)) + .tap( settleTimeout: const Duration(seconds: 1), settlePolicy: SettlePolicy.noSettle, ); await $.pumpAndSettle(duration: Duration(milliseconds: 500)); - final PatrolFinder detailsFinder = await $(DetailsComponentWidget).waitUntilVisible(); + final PatrolFinder detailsFinder = + await $(DetailsComponentWidget).waitUntilVisible(); expect(detailsFinder, findsOneWidget); await $.native.pressBack().then((_) => $.pumpAndSettle()); @@ -124,8 +128,9 @@ class VehicleTest { expect(listViewFinder, findsOneWidget); - final PatrolFinder entriesFinder = - await $(listViewFinder).$(CardItemTemplateComponentWidget).waitUntilVisible(); + final PatrolFinder entriesFinder = await $(listViewFinder) + .$(CardItemTemplateComponentWidget) + .waitUntilVisible(); expect(entriesFinder, findsWidgets); await $.pumpAndSettle(); @@ -170,8 +175,9 @@ class VehicleTest { expect(listViewFinder, findsOneWidget); - final PatrolFinder entriesFinder = - await $(listViewFinder).$(CardItemTemplateComponentWidget).waitUntilVisible(); + final PatrolFinder entriesFinder = await $(listViewFinder) + .$(CardItemTemplateComponentWidget) + .waitUntilVisible(); expect(entriesFinder, findsWidgets); final int entriesCount = entriesFinder.evaluate().length; @@ -180,13 +186,16 @@ class VehicleTest { for (int i = 0; i < entriesCount; i++) { await $(entriesFinder.at(i)).scrollTo(); - await $(entriesFinder.at(i)).waitUntilVisible(timeout: const Duration(seconds: 1)).tap( + await $(entriesFinder.at(i)) + .waitUntilVisible(timeout: const Duration(seconds: 1)) + .tap( settleTimeout: const Duration(seconds: 1), settlePolicy: SettlePolicy.noSettle, ); await $.pumpAndSettle(duration: Duration(milliseconds: 500)); - final PatrolFinder detailsFinder = await $(DetailsComponentWidget).waitUntilVisible(); + final PatrolFinder detailsFinder = + await $(DetailsComponentWidget).waitUntilVisible(); expect(detailsFinder, findsOneWidget); await $.native.pressBack().then((_) => $.pumpAndSettle()); diff --git a/lib/components/atomic_components/shared_components_atoms/custom_input.dart b/lib/components/atomic_components/shared_components_atoms/custom_input.dart index 02634611..cac159f4 100644 --- a/lib/components/atomic_components/shared_components_atoms/custom_input.dart +++ b/lib/components/atomic_components/shared_components_atoms/custom_input.dart @@ -150,7 +150,6 @@ class _CustomInputUtilState extends State { maxLines: null, maxLength: widget.haveMaxLength ? widget.maxLength : null, keyboardType: widget.keyboardType, - inputFormatters: [ LengthLimitingTextInputFormatter(widget.maxLength), ], diff --git a/lib/components/atomic_components/shared_components_atoms/tabview.dart b/lib/components/atomic_components/shared_components_atoms/tabview.dart index 8fe92916..32114202 100644 --- a/lib/components/atomic_components/shared_components_atoms/tabview.dart +++ b/lib/components/atomic_components/shared_components_atoms/tabview.dart @@ -41,7 +41,8 @@ class TabViewUtil extends StatelessWidget { fontFamily: FlutterFlowTheme.of(context).titleMediumFamily, fontSize: LimitedFontSizeUtil.getBodyFontSize(context), letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).titleMediumFamily), + useGoogleFonts: GoogleFonts.asMap().containsKey( + FlutterFlowTheme.of(context).titleMediumFamily), ), unselectedLabelStyle: const TextStyle(), indicatorColor: FlutterFlowTheme.of(context).primary, diff --git a/lib/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart b/lib/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart index 1993ba8e..6502afbc 100644 --- a/lib/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart +++ b/lib/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart @@ -19,10 +19,12 @@ class BottomArrowLinkedLocalsComponentWidget extends StatefulWidget { ApiCallResponse? response; @override - State createState() => _BottomArrowLinkedLocalsComponentWidgetState(); + State createState() => + _BottomArrowLinkedLocalsComponentWidgetState(); } -class _BottomArrowLinkedLocalsComponentWidgetState extends State { +class _BottomArrowLinkedLocalsComponentWidgetState + extends State { late BottomArrowLinkedLocalsComponentModel _model; bool _loading = false; @@ -40,7 +42,8 @@ class _BottomArrowLinkedLocalsComponentWidgetState extends State BottomArrowLinkedLocalsComponentModel()); + _model = + createModel(context, () => BottomArrowLinkedLocalsComponentModel()); _localsFuture = _fetchLocals(); } @@ -106,10 +109,14 @@ class _BottomArrowLinkedLocalsComponentWidgetState extends State _handleError(BuildContext context, String errorMsg) async { + static Future _handleError( + BuildContext context, String errorMsg) async { await DialogUtil.error(context, errorMsg); } @@ -145,8 +153,9 @@ class _BottomArrowLinkedLocalsComponentWidgetState extends State _statusHashMap(dynamic local) { return Map.from({ if (local['CLU_STATUS'] == 'A') - FFLocalizations.of(context).getVariableText(ptText: 'Ativo', enText: 'Active'): - FlutterFlowTheme.of(context).success + FFLocalizations.of(context).getVariableText( + ptText: 'Ativo', + enText: 'Active'): FlutterFlowTheme.of(context).success else if (local['CLU_STATUS'] == 'B') - FFLocalizations.of(context).getVariableText(ptText: 'Bloqueado', enText: 'Blocked'): - FlutterFlowTheme.of(context).error + FFLocalizations.of(context).getVariableText( + ptText: 'Bloqueado', + enText: 'Blocked'): FlutterFlowTheme.of(context).error else - FFLocalizations.of(context).getVariableText(ptText: 'Pendente', enText: 'Pending'): - FlutterFlowTheme.of(context).warning + FFLocalizations.of(context).getVariableText( + ptText: 'Pendente', + enText: 'Pending'): FlutterFlowTheme.of(context).warning }); } @@ -200,16 +213,21 @@ class _BottomArrowLinkedLocalsComponentWidgetState extends State _generateStatus() { double limitedBodyTextSize = LimitedFontSizeUtil.getBodyFontSize(context); - - return statusLinkedHashMap.expand((statusLinked) { + return statusLinkedHashMap.expand((statusLinked) { log('statusHashMap: ${statusLinked.length}'); return statusLinked.entries.map((entry) { final text = entry.key; final color = entry.value; - - return Tooltip( message: text, child: Container( @@ -245,9 +239,9 @@ class _CardItemTemplateComponentWidgetState mainAxisSize: MainAxisSize.max, children: [ Row( - mainAxisAlignment: MainAxisAlignment.end, - mainAxisSize: MainAxisSize.max, - children: [if(widget.pin != null) _generatePin()]), + mainAxisAlignment: MainAxisAlignment.end, + mainAxisSize: MainAxisSize.max, + children: [if (widget.pin != null) _generatePin()]), Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceBetween, @@ -258,7 +252,6 @@ class _CardItemTemplateComponentWidgetState mainAxisSize: MainAxisSize.min, children: [ ..._generateLabels(), - Wrap( spacing: 8, runSpacing: 4, @@ -270,23 +263,20 @@ class _CardItemTemplateComponentWidgetState .addToStart(const SizedBox(height: 5)), ), ), - if(widget.icon != null) _generateIcon(), + if (widget.icon != null) _generateIcon(), if (widget.imagePath != null) _generateImage() - ] .addToEnd(const SizedBox(width: 10)) .addToStart(const SizedBox(width: 10)), ), - ] - .addToStart(SizedBox(height: 5)) - .addToEnd(SizedBox(height: 5)), + ].addToStart(SizedBox(height: 5)).addToEnd(SizedBox(height: 5)), ); } else { return Column( mainAxisSize: MainAxisSize.min, children: [ if (widget.imagePath != null) _generateImage(), - if(widget.icon != null) _generateIcon(), + if (widget.icon != null) _generateIcon(), Container( padding: const EdgeInsets.all(8), child: Column( diff --git a/lib/components/templates_components/details_component/details_component_widget.dart b/lib/components/templates_components/details_component/details_component_widget.dart index b7c1c616..67a21e19 100644 --- a/lib/components/templates_components/details_component/details_component_widget.dart +++ b/lib/components/templates_components/details_component/details_component_widget.dart @@ -11,7 +11,7 @@ import 'package:hub/shared/utils/limited_text_size.dart'; class DetailsComponentWidget extends StatefulWidget { const DetailsComponentWidget({ - super.key, + super.key, required this.labelsHashMap, required this.statusHashMap, this.imagePath, @@ -98,7 +98,7 @@ class _DetailsComponentWidgetState extends State { useOldImageOnUrlChange: true, ), ), - if (widget.icon != null && widget.icon != '') + if (widget.icon != null && widget.icon != '') Container( width: MediaQuery.of(context).size.width * 0.3, height: MediaQuery.of(context).size.width * 0.3, @@ -171,19 +171,18 @@ class _DetailsComponentWidgetState extends State { ), ), style: FlutterFlowTheme.of(context) - .labelMedium - .override( - fontFamily: FlutterFlowTheme.of(context) - .labelMediumFamily, - fontWeight: FontWeight.bold, - color: FlutterFlowTheme.of(context).info, - letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap().containsKey( - FlutterFlowTheme.of(context) - .labelMediumFamily, - ), - fontSize: limitedBodyFontSize, + .labelMedium + .override( + fontFamily: FlutterFlowTheme.of(context) + .labelMediumFamily, + fontWeight: FontWeight.bold, + color: FlutterFlowTheme.of(context).info, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey( + FlutterFlowTheme.of(context).labelMediumFamily, ), + fontSize: limitedBodyFontSize, + ), textAlign: TextAlign.center, maxLines: null, keyboardType: TextInputType.name, diff --git a/lib/components/templates_components/forgot_password_template_component/forgot_password_template_component_widget.dart b/lib/components/templates_components/forgot_password_template_component/forgot_password_template_component_widget.dart index 62e99c23..12bdc25e 100644 --- a/lib/components/templates_components/forgot_password_template_component/forgot_password_template_component_widget.dart +++ b/lib/components/templates_components/forgot_password_template_component/forgot_password_template_component_widget.dart @@ -19,10 +19,12 @@ class ForgotPasswordTemplateComponentWidget extends StatefulWidget { const ForgotPasswordTemplateComponentWidget({super.key}); @override - State createState() => _ForgotPasswordTemplateComponentWidgetState(); + State createState() => + _ForgotPasswordTemplateComponentWidgetState(); } -class _ForgotPasswordTemplateComponentWidgetState extends State { +class _ForgotPasswordTemplateComponentWidgetState + extends State { late ForgotPasswordTemplateComponentModel _model; @override @@ -49,9 +51,11 @@ class _ForgotPasswordTemplateComponentWidgetState extends State('BackButton'), splashColor: Colors.transparent, @@ -98,7 +103,8 @@ class _ForgotPasswordTemplateComponentWidgetState extends State('SendButtonWidget'), - onPressed: (_model.emailAddressTextController.text == '' || - !ValidatorUtil.isValidEmail(_model.emailAddressTextController.text)) + onPressed: (_model.emailAddressTextController.text == + '' || + !ValidatorUtil.isValidEmail( + _model.emailAddressTextController.text)) ? null - : () async => await AuthenticationService.forgotPassword( + : () async => + await AuthenticationService.forgotPassword( context, _model.emailAddressTextController.text, ).then((v) => v == true ? context.pop() : null), @@ -251,23 +278,28 @@ class _ForgotPasswordTemplateComponentWidgetState extends State createState() => _SignInTemplateComponentWidgetState(); + State createState() => + _SignInTemplateComponentWidgetState(); } -class _SignInTemplateComponentWidgetState extends State with TickerProviderStateMixin { +class _SignInTemplateComponentWidgetState + extends State with TickerProviderStateMixin { late SignInTemplateComponentModel _model; final animationsMap = {}; @@ -99,14 +101,17 @@ class _SignInTemplateComponentWidgetState extends State('emailTextFormField'), - controller: _model.emailAddressTextController, - focusNode: _model.emailAddressFocusNode, - cursorColor: FlutterFlowTheme.of(context).primary, - onChanged: (_) => EasyDebounce.debounce( + key: const ValueKey( + 'emailTextFormField'), + controller: _model + .emailAddressTextController, + focusNode: _model + .emailAddressFocusNode, + cursorColor: + FlutterFlowTheme.of(context) + .primary, + onChanged: (_) => + EasyDebounce.debounce( '_model.emailAddressTextController', - const Duration(milliseconds: 500), + const Duration( + milliseconds: 500), () => setState(() {}), ), autofocus: true, - autofillHints: const [AutofillHints.email], - textCapitalization: TextCapitalization.none, - textInputAction: TextInputAction.next, + autofillHints: const [ + AutofillHints.email + ], + textCapitalization: + TextCapitalization.none, + textInputAction: + TextInputAction.next, obscureText: false, decoration: InputDecoration( isDense: true, - labelText: FFLocalizations.of(context).getText( + labelText: FFLocalizations.of( + context) + .getText( '1ltg0ylb' /* Email */, ), - labelStyle: FlutterFlowTheme.of(context).labelLarge.override( - fontFamily: 'Plus Jakarta Sans', - color: FlutterFlowTheme.of(context).primaryText, - fontSize: limitedInputFontSize, + labelStyle: FlutterFlowTheme + .of(context) + .labelLarge + .override( + fontFamily: + 'Plus Jakarta Sans', + color: + FlutterFlowTheme.of( + context) + .primaryText, + fontSize: + limitedInputFontSize, letterSpacing: 0.0, - fontWeight: FontWeight.w500, - useGoogleFonts: - GoogleFonts.asMap().containsKey('Plus Jakarta Sans'), + fontWeight: + FontWeight.w500, + useGoogleFonts: GoogleFonts + .asMap() + .containsKey( + 'Plus Jakarta Sans'), ), - enabledBorder: OutlineInputBorder( + enabledBorder: + OutlineInputBorder( borderSide: BorderSide( - color: FlutterFlowTheme.of(context).customColor1, + color: + FlutterFlowTheme.of( + context) + .customColor1, width: 0.25, ), - borderRadius: BorderRadius.circular(12.0), + borderRadius: + BorderRadius.circular( + 12.0), ), - focusedBorder: OutlineInputBorder( + focusedBorder: + OutlineInputBorder( borderSide: BorderSide( - color: FlutterFlowTheme.of(context).success, + color: + FlutterFlowTheme.of( + context) + .success, width: 0.25, ), - borderRadius: BorderRadius.circular(12.0), + borderRadius: + BorderRadius.circular( + 12.0), ), - errorBorder: OutlineInputBorder( + errorBorder: + OutlineInputBorder( borderSide: BorderSide( - color: FlutterFlowTheme.of(context).error, + color: + FlutterFlowTheme.of( + context) + .error, width: 0.25, ), - borderRadius: BorderRadius.circular(12.0), + borderRadius: + BorderRadius.circular( + 12.0), ), errorStyle: TextStyle( - color: FlutterFlowTheme.of(context).error, - fontSize: limitedInputFontSize, + color: FlutterFlowTheme.of( + context) + .error, + fontSize: + limitedInputFontSize, fontWeight: FontWeight.w500, ), - focusedErrorBorder: OutlineInputBorder( + focusedErrorBorder: + OutlineInputBorder( borderSide: BorderSide( - color: FlutterFlowTheme.of(context).error, + color: + FlutterFlowTheme.of( + context) + .error, width: 0.25, ), - borderRadius: BorderRadius.circular(12.0), + borderRadius: + BorderRadius.circular( + 12.0), ), suffixIcon: Icon( Icons.email, - color: FlutterFlowTheme.of(context).accent1, + color: FlutterFlowTheme.of( + context) + .accent1, size: 22.0, ), ), - style: FlutterFlowTheme.of(context).bodyLarge.override( - fontFamily: 'Plus Jakarta Sans', - color: FlutterFlowTheme.of(context).primaryText, - fontSize: limitedInputFontSize, - letterSpacing: 0.0, - fontWeight: FontWeight.w500, - useGoogleFonts: - GoogleFonts.asMap().containsKey('Plus Jakarta Sans'), - ), - keyboardType: TextInputType.emailAddress, - validator: - _model.emailAddressTextControllerValidator.asValidator(context), + style: + FlutterFlowTheme.of(context) + .bodyLarge + .override( + fontFamily: + 'Plus Jakarta Sans', + color: FlutterFlowTheme + .of(context) + .primaryText, + fontSize: + limitedInputFontSize, + letterSpacing: 0.0, + fontWeight: + FontWeight.w500, + useGoogleFonts: + GoogleFonts + .asMap() + .containsKey( + 'Plus Jakarta Sans'), + ), + keyboardType: + TextInputType.emailAddress, + validator: _model + .emailAddressTextControllerValidator + .asValidator(context), ), ), ), Padding( - padding: const EdgeInsetsDirectional.fromSTEB(0.0, 0.0, 0.0, 16.0), + padding: const EdgeInsetsDirectional + .fromSTEB(0.0, 0.0, 0.0, 16.0), child: SizedBox( width: double.infinity, child: TextFormField( - key: const ValueKey('passwordTextFormField'), - controller: _model.passwordTextController, - cursorColor: FlutterFlowTheme.of(context).primary, - focusNode: _model.passwordFocusNode, - onChanged: (_) => EasyDebounce.debounce('_model.passwordTextController', - const Duration(milliseconds: 500), () => setState(() {})), + key: const ValueKey( + 'passwordTextFormField'), + controller: _model + .passwordTextController, + cursorColor: + FlutterFlowTheme.of(context) + .primary, + focusNode: + _model.passwordFocusNode, + onChanged: (_) => + EasyDebounce.debounce( + '_model.passwordTextController', + const Duration( + milliseconds: 500), + () => setState(() {})), autofocus: true, - autofillHints: const [AutofillHints.password], - textInputAction: TextInputAction.send, - obscureText: !_model.passwordVisibility, + autofillHints: const [ + AutofillHints.password + ], + textInputAction: + TextInputAction.send, + obscureText: + !_model.passwordVisibility, decoration: InputDecoration( isDense: true, - labelText: - FFLocalizations.of(context).getText('2x19ce8k' /* Senha */), - labelStyle: FlutterFlowTheme.of(context).labelLarge.override( - fontFamily: 'Plus Jakarta Sans', - color: FlutterFlowTheme.of(context).primaryText, - fontSize: limitedInputFontSize, - letterSpacing: 0.0, - fontWeight: FontWeight.w500, - useGoogleFonts: - GoogleFonts.asMap().containsKey('Plus Jakarta Sans')), - enabledBorder: OutlineInputBorder( + labelText: FFLocalizations.of( + context) + .getText( + '2x19ce8k' /* Senha */), + labelStyle: FlutterFlowTheme + .of(context) + .labelLarge + .override( + fontFamily: + 'Plus Jakarta Sans', + color: FlutterFlowTheme + .of(context) + .primaryText, + fontSize: + limitedInputFontSize, + letterSpacing: 0.0, + fontWeight: + FontWeight.w500, + useGoogleFonts: + GoogleFonts + .asMap() + .containsKey( + 'Plus Jakarta Sans')), + enabledBorder: + OutlineInputBorder( borderSide: BorderSide( - color: FlutterFlowTheme.of(context).customColor1, width: 0.25), - borderRadius: BorderRadius.circular(12.0), + color: + FlutterFlowTheme.of( + context) + .customColor1, + width: 0.25), + borderRadius: + BorderRadius.circular( + 12.0), ), errorStyle: TextStyle( - color: FlutterFlowTheme.of(context).error, - fontSize: limitedInputFontSize, + color: FlutterFlowTheme.of( + context) + .error, + fontSize: + limitedInputFontSize, fontWeight: FontWeight.w500, ), focusedBorder: OutlineInputBorder( borderSide: - const BorderSide(color: Color(0xFF1AAB5F), width: 0.25), - borderRadius: BorderRadius.circular(12.0)), - errorBorder: OutlineInputBorder( - borderSide: const BorderSide(color: Color(0xFFFF5963), width: 0.25), - borderRadius: BorderRadius.circular(12.0), + const BorderSide( + color: Color( + 0xFF1AAB5F), + width: 0.25), + borderRadius: + BorderRadius.circular( + 12.0)), + errorBorder: + OutlineInputBorder( + borderSide: + const BorderSide( + color: Color( + 0xFFFF5963), + width: 0.25), + borderRadius: + BorderRadius.circular( + 12.0), ), - focusedErrorBorder: OutlineInputBorder( - borderSide: const BorderSide(color: Color(0xFFFF5963), width: 0.25), - borderRadius: BorderRadius.circular(12.0), + focusedErrorBorder: + OutlineInputBorder( + borderSide: + const BorderSide( + color: Color( + 0xFFFF5963), + width: 0.25), + borderRadius: + BorderRadius.circular( + 12.0), ), filled: true, - fillColor: FlutterFlowTheme.of(context).primaryBackground, + fillColor: + FlutterFlowTheme.of( + context) + .primaryBackground, suffixIcon: InkWell( - onTap: () => setState( - () => _model.passwordVisibility = !_model.passwordVisibility), - focusNode: FocusNode(skipTraversal: true), + onTap: () => setState(() => + _model.passwordVisibility = + !_model + .passwordVisibility), + focusNode: FocusNode( + skipTraversal: true), child: Icon( _model.passwordVisibility - ? Icons.visibility_outlined - : Icons.visibility_off_outlined, - color: FlutterFlowTheme.of(context).accent1, + ? Icons + .visibility_outlined + : Icons + .visibility_off_outlined, + color: + FlutterFlowTheme.of( + context) + .accent1, size: 24.0), ), ), - style: FlutterFlowTheme.of(context).bodyLarge.override( - fontFamily: 'Plus Jakarta Sans', - color: FlutterFlowTheme.of(context).primaryText, - fontSize: limitedInputFontSize, - letterSpacing: 0.0, - fontWeight: FontWeight.w500, - useGoogleFonts: - GoogleFonts.asMap().containsKey('Plus Jakarta Sans'), - ), - validator: _model.passwordTextControllerValidator.asValidator(context), + style: + FlutterFlowTheme.of(context) + .bodyLarge + .override( + fontFamily: + 'Plus Jakarta Sans', + color: FlutterFlowTheme + .of(context) + .primaryText, + fontSize: + limitedInputFontSize, + letterSpacing: 0.0, + fontWeight: + FontWeight.w500, + useGoogleFonts: + GoogleFonts + .asMap() + .containsKey( + 'Plus Jakarta Sans'), + ), + validator: _model + .passwordTextControllerValidator + .asValidator(context), ), ), ), @@ -353,77 +512,153 @@ class _SignInTemplateComponentWidgetState extends State('SubmitButtonWidget'), + key: const ValueKey( + 'SubmitButtonWidget'), onPressed: _isFormInvalid() ? null : () async { - await AuthenticationService.signIn( + await AuthenticationService + .signIn( context, _model, - emailAdress: _model.emailAddressTextController.text, - password: _model.passwordTextController.text, + emailAdress: _model + .emailAddressTextController + .text, + password: _model + .passwordTextController + .text, ); setState(() {}); }, - text: FFLocalizations.of(context).getText('k44tm7wo' /* Entrar */), + text: FFLocalizations.of( + context) + .getText( + 'k44tm7wo' /* Entrar */), options: FFButtonOptions( width: double.infinity, height: 44.0, - padding: const EdgeInsetsDirectional.fromSTEB(0.0, 0.0, 0.0, 0.0), + padding: + const EdgeInsetsDirectional + .fromSTEB( + 0.0, 0.0, 0.0, 0.0), iconPadding: - const EdgeInsetsDirectional.fromSTEB(0.0, 0.0, 0.0, 0.0), - color: FlutterFlowTheme.of(context).primary, - textStyle: FlutterFlowTheme.of(context).titleSmall.override( - fontFamily: 'Plus Jakarta Sans', - color: FlutterFlowTheme.of(context).info, - fontSize: limitedInputFontSize, - letterSpacing: 0.0, - fontWeight: FontWeight.w500, - useGoogleFonts: - GoogleFonts.asMap().containsKey('Plus Jakarta Sans')), + const EdgeInsetsDirectional + .fromSTEB( + 0.0, 0.0, 0.0, 0.0), + color: FlutterFlowTheme.of( + context) + .primary, + textStyle: FlutterFlowTheme + .of(context) + .titleSmall + .override( + fontFamily: + 'Plus Jakarta Sans', + color: FlutterFlowTheme + .of(context) + .info, + fontSize: + limitedInputFontSize, + letterSpacing: 0.0, + fontWeight: + FontWeight.w500, + useGoogleFonts: + GoogleFonts + .asMap() + .containsKey( + 'Plus Jakarta Sans')), elevation: 3.0, - borderSide: const BorderSide(color: Colors.transparent, width: 1.0), - borderRadius: BorderRadius.circular(12.0), - disabledColor: FlutterFlowTheme.of(context).customColor5, - disabledTextColor: Colors.white, + borderSide: + const BorderSide( + color: Colors + .transparent, + width: 1.0), + borderRadius: + BorderRadius.circular( + 12.0), + disabledColor: + FlutterFlowTheme.of( + context) + .customColor5, + disabledTextColor: + Colors.white, ), showLoadingIndicator: false, ), ), Padding( - padding: const EdgeInsetsDirectional.fromSTEB(0.0, 0.0, 0.0, 16.0), + padding: + const EdgeInsetsDirectional + .fromSTEB( + 0.0, 0.0, 0.0, 16.0), child: FFButtonWidget( - key: const ValueKey('toggleSignUpPage'), - onPressed: () async => await widget.toggleSignUpPage?.call(), - text: FFLocalizations.of(context).getText( + key: const ValueKey( + 'toggleSignUpPage'), + onPressed: () async => + await widget + .toggleSignUpPage + ?.call(), + text: FFLocalizations.of( + context) + .getText( '14u7ipws' /* Cadastrar */, ), options: FFButtonOptions( width: double.infinity, height: 44.0, - padding: const EdgeInsetsDirectional.fromSTEB(0.0, 0.0, 0.0, 0.0), + padding: + const EdgeInsetsDirectional + .fromSTEB( + 0.0, 0.0, 0.0, 0.0), iconPadding: - const EdgeInsetsDirectional.fromSTEB(0.0, 0.0, 0.0, 0.0), - color: FlutterFlowTheme.of(context).customColor1, - textStyle: FlutterFlowTheme.of(context).titleSmall.override( - fontFamily: 'Plus Jakarta Sans', - color: FlutterFlowTheme.of(context).secondaryText, - fontSize: limitedInputFontSize, + const EdgeInsetsDirectional + .fromSTEB( + 0.0, 0.0, 0.0, 0.0), + color: FlutterFlowTheme.of( + context) + .customColor1, + textStyle: FlutterFlowTheme + .of(context) + .titleSmall + .override( + fontFamily: + 'Plus Jakarta Sans', + color: FlutterFlowTheme + .of(context) + .secondaryText, + fontSize: + limitedInputFontSize, letterSpacing: 0.0, - fontWeight: FontWeight.w500, + fontWeight: + FontWeight.w500, useGoogleFonts: - GoogleFonts.asMap().containsKey('Plus Jakarta Sans'), + GoogleFonts + .asMap() + .containsKey( + 'Plus Jakarta Sans'), ), elevation: 3.0, - borderSide: const BorderSide(color: Colors.transparent, width: 1.0), - borderRadius: BorderRadius.circular(12.0), + borderSide: + const BorderSide( + color: Colors + .transparent, + width: 1.0), + borderRadius: + BorderRadius.circular( + 12.0), ), showLoadingIndicator: false, ), @@ -433,158 +668,279 @@ class _SignInTemplateComponentWidgetState extends State('SubmitButtonWidget'), - onPressed: _isFormInvalid() - ? null - : () async { - try { - await AuthenticationService.signIn( - context, - _model, - emailAdress: _model.emailAddressTextController.text, - password: _model.passwordTextController.text, - ); - setState(() {}); - } catch (e, s) { - await DialogUtil.errorDefault(context); - LogUtil.requestAPIFailed( - 'login.php', - _model.emailAddressTextController.text, - "Login", - e, - s); - } - }, - text: FFLocalizations.of(context).getText('1x926nsn'), + key: const ValueKey< + String>( + 'SubmitButtonWidget'), + onPressed: + _isFormInvalid() + ? null + : () async { + try { + await AuthenticationService + .signIn( + context, + _model, + emailAdress: _model + .emailAddressTextController + .text, + password: _model + .passwordTextController + .text, + ); + setState( + () {}); + } catch (e, s) { + await DialogUtil + .errorDefault( + context); + LogUtil.requestAPIFailed( + 'login.php', + _model + .emailAddressTextController + .text, + "Login", + e, + s); + } + }, + text: FFLocalizations.of( + context) + .getText('1x926nsn'), options: FFButtonOptions( width: double.infinity, height: 44.0, padding: - const EdgeInsetsDirectional.fromSTEB(0.0, 0.0, 0.0, 0.0), + const EdgeInsetsDirectional + .fromSTEB(0.0, + 0.0, 0.0, 0.0), iconPadding: - const EdgeInsetsDirectional.fromSTEB(0.0, 0.0, 0.0, 0.0), - color: FlutterFlowTheme.of(context).accent1, - textStyle: FlutterFlowTheme.of(context).titleSmall.override( - fontFamily: 'Plus Jakarta Sans', - color: FlutterFlowTheme.of(context).info, - fontSize: limitedInputFontSize, - letterSpacing: 0.0, - fontWeight: FontWeight.w500, - useGoogleFonts: - GoogleFonts.asMap().containsKey('Plus Jakarta Sans'), - ), + const EdgeInsetsDirectional + .fromSTEB(0.0, + 0.0, 0.0, 0.0), + color: + FlutterFlowTheme.of( + context) + .accent1, + textStyle: + FlutterFlowTheme.of( + context) + .titleSmall + .override( + fontFamily: + 'Plus Jakarta Sans', + color: FlutterFlowTheme.of( + context) + .info, + fontSize: + limitedInputFontSize, + letterSpacing: + 0.0, + fontWeight: + FontWeight + .w500, + useGoogleFonts: GoogleFonts + .asMap() + .containsKey( + 'Plus Jakarta Sans'), + ), elevation: 3.0, - borderSide: const BorderSide( - color: Colors.transparent, + borderSide: + const BorderSide( + color: Colors + .transparent, width: 1.0, ), - borderRadius: BorderRadius.circular(12.0), - disabledColor: const Color(0xE81AAB5F), + borderRadius: + BorderRadius + .circular(12.0), + disabledColor: + const Color( + 0xE81AAB5F), ), - showLoadingIndicator: true, + showLoadingIndicator: + true, ), ), ), Expanded( child: Padding( - padding: const EdgeInsetsDirectional.fromSTEB(0.0, 0.0, 0.0, 16.0), + padding: + const EdgeInsetsDirectional + .fromSTEB(0.0, 0.0, + 0.0, 16.0), child: FFButtonWidget( - key: const ValueKey('toggleSignUpPage'), - onPressed: () async => await widget.toggleSignUpPage?.call(), - text: FFLocalizations.of(context) - .getText('jwvd4ai1' /* Cadastrar */), + key: const ValueKey< + String>( + 'toggleSignUpPage'), + onPressed: () async => + await widget + .toggleSignUpPage + ?.call(), + text: FFLocalizations.of( + context) + .getText( + 'jwvd4ai1' /* Cadastrar */), options: FFButtonOptions( width: double.infinity, height: 44.0, padding: - const EdgeInsetsDirectional.fromSTEB(0.0, 0.0, 0.0, 0.0), + const EdgeInsetsDirectional + .fromSTEB(0.0, + 0.0, 0.0, 0.0), iconPadding: - const EdgeInsetsDirectional.fromSTEB(0.0, 0.0, 0.0, 0.0), - color: FlutterFlowTheme.of(context).customColor1, - textStyle: FlutterFlowTheme.of(context).titleSmall.override( - fontFamily: 'Plus Jakarta Sans', - color: FlutterFlowTheme.of(context).secondaryText, - fontSize: 16.0, - letterSpacing: 0.0, - fontWeight: FontWeight.w500, - useGoogleFonts: - GoogleFonts.asMap().containsKey('Plus Jakarta Sans'), - ), + const EdgeInsetsDirectional + .fromSTEB(0.0, + 0.0, 0.0, 0.0), + color: + FlutterFlowTheme.of( + context) + .customColor1, + textStyle: + FlutterFlowTheme.of( + context) + .titleSmall + .override( + fontFamily: + 'Plus Jakarta Sans', + color: FlutterFlowTheme.of( + context) + .secondaryText, + fontSize: + 16.0, + letterSpacing: + 0.0, + fontWeight: + FontWeight + .w500, + useGoogleFonts: GoogleFonts + .asMap() + .containsKey( + 'Plus Jakarta Sans'), + ), elevation: 3.0, - borderSide: const BorderSide( - color: Colors.transparent, + borderSide: + const BorderSide( + color: Colors + .transparent, width: 1.0, ), - borderRadius: BorderRadius.circular(12.0), + borderRadius: + BorderRadius + .circular(12.0), ), - showLoadingIndicator: false, + showLoadingIndicator: + false, ), ), ), - ].divide(const SizedBox(width: 7.0))); + ].divide( + const SizedBox(width: 7.0))); } }, ), Padding( - padding: const EdgeInsetsDirectional.fromSTEB(0.0, 12.0, 0.0, 12.0), + padding: + const EdgeInsetsDirectional.fromSTEB( + 0.0, 12.0, 0.0, 12.0), child: InkWell( - key: const ValueKey('ForgotPassword'), + key: const ValueKey( + 'ForgotPassword'), splashColor: Colors.transparent, focusColor: Colors.transparent, hoverColor: Colors.transparent, highlightColor: Colors.transparent, onTap: () async { await showModalBottomSheet( - isScrollControlled: true, - backgroundColor: Colors.transparent, - context: context, - builder: (context) { - return Padding( - padding: MediaQuery.viewInsetsOf(context), - child: const ForgotPasswordTemplateComponentWidget(), - ); - }).then((value) => safeSetState(() {})); + isScrollControlled: true, + backgroundColor: + Colors.transparent, + context: context, + builder: (context) { + return Padding( + padding: MediaQuery + .viewInsetsOf( + context), + child: + const ForgotPasswordTemplateComponentWidget(), + ); + }) + .then((value) => + safeSetState(() {})); }, child: RichText( - textScaler: MediaQuery.of(context).textScaler, + textScaler: + MediaQuery.of(context).textScaler, text: TextSpan( children: [ TextSpan( - text: FFLocalizations.of(context).getText( + text: + FFLocalizations.of(context) + .getText( '05dx91ku' /* Você esqueceu a sua senha? */, ), style: TextStyle( - color: FlutterFlowTheme.of(context).primaryText, - fontSize: limitedInputFontSize, + color: FlutterFlowTheme.of( + context) + .primaryText, + fontSize: + limitedInputFontSize, ), ), TextSpan( - text: FFLocalizations.of(context) - .getText('p5c6d54y' /* Recupere aqui */), - style: FlutterFlowTheme.of(context).bodyMedium.override( - fontFamily: 'Plus Jakarta Sans', - color: FlutterFlowTheme.of(context).primary, - fontSize: limitedInputFontSize, - letterSpacing: 0.0, - fontWeight: FontWeight.normal, - useGoogleFonts: - GoogleFonts.asMap().containsKey('Plus Jakarta Sans'), - ), - mouseCursor: SystemMouseCursors.click, + text: FFLocalizations.of( + context) + .getText( + 'p5c6d54y' /* Recupere aqui */), + style: + FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: + 'Plus Jakarta Sans', + color: FlutterFlowTheme + .of(context) + .primary, + fontSize: + limitedInputFontSize, + letterSpacing: 0.0, + fontWeight: + FontWeight.normal, + useGoogleFonts: + GoogleFonts + .asMap() + .containsKey( + 'Plus Jakarta Sans'), + ), + mouseCursor: + SystemMouseCursors.click, ) ], - style: FlutterFlowTheme.of(context).bodyMedium.override( - fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily, - letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap() - .containsKey(FlutterFlowTheme.of(context).bodyMediumFamily), - fontSize: limitedInputFontSize), + style: FlutterFlowTheme.of(context) + .bodyMedium + .override( + fontFamily: + FlutterFlowTheme.of( + context) + .bodyMediumFamily, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts + .asMap() + .containsKey( + FlutterFlowTheme.of( + context) + .bodyMediumFamily), + fontSize: + limitedInputFontSize), ), ), ), @@ -594,7 +950,8 @@ class _SignInTemplateComponentWidgetState extends State createState() => _HomePageWidgetState(); } -class _HomePageWidgetState extends State with WidgetsBindingObserver { +class _HomePageWidgetState extends State + with WidgetsBindingObserver { final scaffoldKey = GlobalKey(); @override @@ -96,7 +97,8 @@ class _HomePageWidgetState extends State with WidgetsBindingObse fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily, color: FlutterFlowTheme.of(context).info, letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).bodyMediumFamily), + useGoogleFonts: GoogleFonts.asMap().containsKey( + FlutterFlowTheme.of(context).bodyMediumFamily), ), ), ].divide(const SizedBox(width: 8.0)), diff --git a/lib/features/local/data/data_sources/locals_remote_data_source.dart b/lib/features/local/data/data_sources/locals_remote_data_source.dart index 0babde3a..a40883cf 100644 --- a/lib/features/local/data/data_sources/locals_remote_data_source.dart +++ b/lib/features/local/data/data_sources/locals_remote_data_source.dart @@ -24,7 +24,8 @@ abstract class LocalsRemoteDataSource { } class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource { - static final LocalsRemoteDataSourceImpl _instance = LocalsRemoteDataSourceImpl._internal(); + static final LocalsRemoteDataSourceImpl _instance = + LocalsRemoteDataSourceImpl._internal(); factory LocalsRemoteDataSourceImpl() => _instance; LocalsRemoteDataSourceImpl._internal(); @@ -50,7 +51,8 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource { final List locals = response.jsonBody['locais'] ?? []; final bool isEmpty = locals.isEmpty; - final bool isActive = locals.where((local) => local['CLU_STATUS'] != 'B').isNotEmpty; + final bool isActive = + locals.where((local) => local['CLU_STATUS'] != 'B').isNotEmpty; final bool isEnable = !isEmpty && isActive; if (isEnable) { @@ -95,7 +97,8 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource { final bool isInactived = await LocalUtil.isInactived(locals); final bool isPending = LocalUtil.isPending(locals); final bool isUnique = locals.length == 1; - final bool isBlocked = locals.where((local) => local['CLU_STATUS'] == 'B').isNotEmpty; + final bool isBlocked = + locals.where((local) => local['CLU_STATUS'] == 'B').isNotEmpty; final bool isEnabled = isUnique && isActive; final bool isDisabled = isUnique && isBlocked; final bool isUnselected = await LocalUtil.isUnselected(); @@ -148,8 +151,10 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource { @override Future checkLocals(BuildContext context) async { - final String? cliUUID = await StorageHelper().get(ProfileStorageKey.clientUUID.key); - final String? cliName = await StorageHelper().get(ProfileStorageKey.clientName.key); + final String? cliUUID = + await StorageHelper().get(ProfileStorageKey.clientUUID.key); + final String? cliName = + await StorageHelper().get(ProfileStorageKey.clientName.key); final haveCli = cliUUID != null && cliUUID.isNotEmpty; final haveName = cliName != null && cliName.isNotEmpty; return haveCli && haveName; @@ -175,7 +180,8 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource { if (isError == true) { final GetLocalsCall callback = PhpGroup.getLocalsCall; response = await callback.call(); - final String errorMsg = response.jsonBody['error_msg'] ?? 'Local indisponível'; + final String errorMsg = + response.jsonBody['error_msg'] ?? 'Local indisponível'; // await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, response)); return false; } else { @@ -194,7 +200,8 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource { } @override - Future selectLocal(BuildContext context, ApiCallResponse? response) async { + Future selectLocal( + BuildContext context, ApiCallResponse? response) async { return await showModalBottomSheet( isScrollControlled: true, backgroundColor: Colors.transparent, @@ -224,13 +231,15 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource { enText: 'Device unlinked successfully', ptText: 'Dispositivo desvinculado com sucesso', ); - final bool status = await PhpGroup.resopndeVinculo.call(tarefa: 'I').then((value) async { + final bool status = + await PhpGroup.resopndeVinculo.call(tarefa: 'I').then((value) async { if (value.jsonBody['error'] == false) { await StorageHelper().set(ProfileStorageKey.clientName.key, ''); await StorageHelper().set(ProfileStorageKey.ownerName.key, ''); await StorageHelper().set(ProfileStorageKey.clientUUID.key, ''); context.pop(); - context.go('/homePage', extra: {'update': LocalsRepositoryImpl().update}); + context.go('/homePage', + extra: {'update': LocalsRepositoryImpl().update}); SnackBarUtil.showSnackBar(context, content); return true; } diff --git a/lib/features/local/data/repositories/locals_repository_impl.dart b/lib/features/local/data/repositories/locals_repository_impl.dart index ea37e12e..a7245383 100644 --- a/lib/features/local/data/repositories/locals_repository_impl.dart +++ b/lib/features/local/data/repositories/locals_repository_impl.dart @@ -49,8 +49,10 @@ class LocalsRepositoryImpl implements LocalsRepository { } Future check(BuildContext context) async { - final String? cliUUID = await StorageHelper().get(ProfileStorageKey.clientUUID.key); - final String? ownerUUID = await StorageHelper().get(ProfileStorageKey.ownerUUID.key); + final String? cliUUID = + await StorageHelper().get(ProfileStorageKey.clientUUID.key); + final String? ownerUUID = + await StorageHelper().get(ProfileStorageKey.ownerUUID.key); final bool haveCli = cliUUID != null && cliUUID.isNotEmpty; final bool haveOwner = ownerUUID != null && ownerUUID.isNotEmpty; if (!haveCli && !haveOwner) { diff --git a/lib/features/local/utils/local_util.dart b/lib/features/local/utils/local_util.dart index 2a0b6d6b..783e7fa7 100644 --- a/lib/features/local/utils/local_util.dart +++ b/lib/features/local/utils/local_util.dart @@ -11,10 +11,13 @@ import 'package:hub/shared/utils/log_util.dart'; class LocalUtil { static void handleError(BuildContext context, String errorMsg) async { - final String devUUID = await StorageHelper().get(ProfileStorageKey.devUUID.key) ?? ''; - final String userUUID = await StorageHelper().get(ProfileStorageKey.userUUID.key) ?? ''; + final String devUUID = + await StorageHelper().get(ProfileStorageKey.devUUID.key) ?? ''; + final String userUUID = + await StorageHelper().get(ProfileStorageKey.userUUID.key) ?? ''; final bool isAuthenticated = userUUID.isNotEmpty && devUUID.isNotEmpty; - final bool isDevLinked = !errorMsg.contains('Esse dispositivo nao pertence a esse usuario'); + final bool isDevLinked = + !errorMsg.contains('Esse dispositivo nao pertence a esse usuario'); log('() => isLinked: $errorMsg'); if (!isAuthenticated) { errorMsg = FFLocalizations.of(context).getVariableText( @@ -36,13 +39,18 @@ class LocalUtil { // await DialogUtil.error(context, errorMsg).whenComplete(() async => await LocalsRemoteDataSourceImpl().selectLocal(context, null)); } - static Future handleUnavailable(BuildContext context, List locals) async { + static Future handleUnavailable( + BuildContext context, List locals) async { log('() => isUnavailable'); try { - await StorageHelper().set(ProfileStorageKey.clientUUID.key, locals[0]['CLI_ID']); - await StorageHelper().set(ProfileStorageKey.ownerUUID.key, locals[0]['CLU_OWNER_ID']); - await StorageHelper().set(ProfileStorageKey.clientName.key, locals[0]['CLI_NOME']); - await StorageHelper().set(ProfileStorageKey.ownerName.key, locals[0]['CLU_OWNER_DSC']); + await StorageHelper() + .set(ProfileStorageKey.clientUUID.key, locals[0]['CLI_ID']); + await StorageHelper() + .set(ProfileStorageKey.ownerUUID.key, locals[0]['CLU_OWNER_ID']); + await StorageHelper() + .set(ProfileStorageKey.clientName.key, locals[0]['CLI_NOME']); + await StorageHelper() + .set(ProfileStorageKey.ownerName.key, locals[0]['CLU_OWNER_DSC']); var response = await PhpGroup.resopndeVinculo.call(tarefa: 'A'); if (response.jsonBody['error'] == true) { @@ -54,10 +62,13 @@ class LocalUtil { return false; } if (response.jsonBody['error'] == false) - return await LocalsRemoteDataSourceImpl().processProperty(context).then((value) => value); + return await LocalsRemoteDataSourceImpl() + .processProperty(context) + .then((value) => value); } catch (e, s) { await DialogUtil.errorDefault(context); - LogUtil.requestAPIFailed('responderVinculo.php', '', 'Responder Vínculo', e, s); + LogUtil.requestAPIFailed( + 'responderVinculo.php', '', 'Responder Vínculo', e, s); return false; } return false; @@ -65,12 +76,19 @@ class LocalUtil { static Future handleEnabled(BuildContext context, dynamic local) async { log('() => isEnabled'); - await StorageHelper().set(ProfileStorageKey.clientUUID.key, local['CLI_ID']); - await StorageHelper().set(ProfileStorageKey.ownerUUID.key, local['CLU_OWNER_ID']); - await StorageHelper().set(ProfileStorageKey.clientName.key, local['CLI_NOME']); - await StorageHelper().set(ProfileStorageKey.ownerName.key, local['CLU_OWNER_DSC']); - await StorageHelper().set(ProfileStorageKey.userName.key, local['USU_NOME']); - return await LocalsRemoteDataSourceImpl().processProperty(context).then((v) async { + await StorageHelper() + .set(ProfileStorageKey.clientUUID.key, local['CLI_ID']); + await StorageHelper() + .set(ProfileStorageKey.ownerUUID.key, local['CLU_OWNER_ID']); + await StorageHelper() + .set(ProfileStorageKey.clientName.key, local['CLI_NOME']); + await StorageHelper() + .set(ProfileStorageKey.ownerName.key, local['CLU_OWNER_DSC']); + await StorageHelper() + .set(ProfileStorageKey.userName.key, local['USU_NOME']); + return await LocalsRemoteDataSourceImpl() + .processProperty(context) + .then((v) async { if (v == true) return await LicenseRepositoryImpl().updateLicense(); return v; }); @@ -93,9 +111,12 @@ class LocalUtil { static Future updateStorageUtil(Map jsonBody) async { try { - await StorageHelper().set(LocalsStorageKey.whatsapp.key, jsonBody['whatsapp'] ?? false); - await StorageHelper().set(LocalsStorageKey.provisional.key, jsonBody['provisional'] ?? false); - await StorageHelper().set(LocalsStorageKey.vehicleAutoApproval.key, jsonBody['vehicleAutoApproval'] ?? false); + await StorageHelper() + .set(LocalsStorageKey.whatsapp.key, jsonBody['whatsapp'] ?? false); + await StorageHelper().set( + LocalsStorageKey.provisional.key, jsonBody['provisional'] ?? false); + await StorageHelper().set(LocalsStorageKey.vehicleAutoApproval.key, + jsonBody['vehicleAutoApproval'] ?? false); await StorageHelper().set( LocalsStorageKey.pets.key, @@ -118,19 +139,28 @@ class LocalUtil { ); } - await StorageHelper().set(LocalsStorageKey.petAmount.key, - jsonBody['petAmountRegister']?.toString().isEmpty ?? true ? '0' : jsonBody['petAmountRegister'].toString()); - - await StorageHelper().set(LocalsStorageKey.vehicleAmountRegister.key, - jsonBody['vehicleAmountRegister']?.toString().isEmpty ?? true ? '0' : jsonBody['vehicleAmountRegister'].toString()); + await StorageHelper().set( + LocalsStorageKey.petAmount.key, + jsonBody['petAmountRegister']?.toString().isEmpty ?? true + ? '0' + : jsonBody['petAmountRegister'].toString()); + await StorageHelper().set( + LocalsStorageKey.vehicleAmountRegister.key, + jsonBody['vehicleAmountRegister']?.toString().isEmpty ?? true + ? '0' + : jsonBody['vehicleAmountRegister'].toString()); - await StorageHelper().set(ProfileStorageKey.userName.key, jsonBody['visitado']['VDO_NOME'] ?? ''); - await StorageHelper().set(ProfileStorageKey.userEmail.key, jsonBody['visitado']['VDO_EMAIL'] ?? ''); - await StorageHelper().set(LocalsStorageKey.provisional.key, jsonBody['provisional'] ?? false); + await StorageHelper().set(ProfileStorageKey.userName.key, + jsonBody['visitado']['VDO_NOME'] ?? ''); + await StorageHelper().set(ProfileStorageKey.userEmail.key, + jsonBody['visitado']['VDO_EMAIL'] ?? ''); + await StorageHelper().set( + LocalsStorageKey.provisional.key, jsonBody['provisional'] ?? false); final bool isNewVersion = jsonBody['newVersion'] ?? false; - await StorageHelper().set(LocalsStorageKey.isNewVersion.key, isNewVersion); + await StorageHelper() + .set(LocalsStorageKey.isNewVersion.key, isNewVersion); return isNewVersion; } catch (e, s) { log('Error in _updateStorageUtil: $e', stackTrace: s); @@ -143,30 +173,44 @@ class LocalUtil { } static Future isInactived(List locals) async { - String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; - return locals.where((local) => local['CLI_ID'] != cliUUID && local['CLU_STATUS'] == 'A').isNotEmpty; + String cliUUID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + return locals + .where( + (local) => local['CLI_ID'] != cliUUID && local['CLU_STATUS'] == 'A') + .isNotEmpty; } static bool isPending(List locals) { - return locals.where((local) => local['CLU_STATUS'] != 'B' && local['CLU_STATUS'] != 'A').isNotEmpty; + return locals + .where( + (local) => local['CLU_STATUS'] != 'B' && local['CLU_STATUS'] != 'A') + .isNotEmpty; } static Future isUnselected() async { - String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; - String cliName = (await StorageHelper().get(ProfileStorageKey.clientName.key)) ?? ''; - String ownerUUID = (await StorageHelper().get(ProfileStorageKey.ownerUUID.key)) ?? ''; + String cliUUID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + String cliName = + (await StorageHelper().get(ProfileStorageKey.clientName.key)) ?? ''; + String ownerUUID = + (await StorageHelper().get(ProfileStorageKey.ownerUUID.key)) ?? ''; return cliUUID.isEmpty && cliName.isEmpty && ownerUUID.isEmpty; } static Future isSelected(bool isInactived) async { - String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; - String cliName = (await StorageHelper().get(ProfileStorageKey.clientName.key)) ?? ''; + String cliUUID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + String cliName = + (await StorageHelper().get(ProfileStorageKey.clientName.key)) ?? ''; return cliUUID.isNotEmpty && cliName.isNotEmpty && isInactived; } static Future isAvailable() async { - String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; - String cliName = (await StorageHelper().get(ProfileStorageKey.clientName.key)) ?? ''; + String cliUUID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + String cliName = + (await StorageHelper().get(ProfileStorageKey.clientName.key)) ?? ''; return cliUUID.isNotEmpty && cliName.isNotEmpty; } } diff --git a/lib/features/menu/data/data_sources/menu_local_data_source.dart b/lib/features/menu/data/data_sources/menu_local_data_source.dart index b736ed41..ad8502f8 100644 --- a/lib/features/menu/data/data_sources/menu_local_data_source.dart +++ b/lib/features/menu/data/data_sources/menu_local_data_source.dart @@ -9,16 +9,19 @@ import 'package:hub/shared/extensions/dialog_extensions.dart'; import 'package:hub/shared/utils/path_util.dart'; abstract class MenuLocalDataSource { - Future addMenuEntry( - Key key, EnumMenuItem item, List entries, IconData icon, String text, Function() action); + Future addMenuEntry(Key key, EnumMenuItem item, + List entries, IconData icon, String text, Function() action); - Future processDisplayDefault(EnumMenuItem item, MenuEntry opt, List entries); + Future processDisplayDefault( + EnumMenuItem item, MenuEntry opt, List entries); - Future handleMenu(EnumMenuItem item, EnumDisplay display, MenuEntry opt, List entries); + Future handleMenu(EnumMenuItem item, EnumDisplay display, MenuEntry opt, + List entries); } class MenuLocalDataSourceImpl implements MenuLocalDataSource { - static final MenuLocalDataSourceImpl _instance = MenuLocalDataSourceImpl._internal(); + static final MenuLocalDataSourceImpl _instance = + MenuLocalDataSourceImpl._internal(); factory MenuLocalDataSourceImpl() => _instance; @@ -45,9 +48,12 @@ class MenuLocalDataSourceImpl implements MenuLocalDataSource { } @override - Future processDisplayDefault(EnumMenuItem item, MenuEntry opt, List entries) async { + Future processDisplayDefault( + EnumMenuItem item, MenuEntry opt, List entries) async { if (opt.key == 'FRE-HUB-LOGOUT') { - await addMenuEntry(ValueKey(opt.key), item, entries, opt.icon, opt.name, () async { + await addMenuEntry( + ValueKey(opt.key), item, entries, opt.icon, opt.name, + () async { await AuthenticationService.signOut(navigatorKey.currentContext!); }); return true; @@ -56,17 +62,23 @@ class MenuLocalDataSourceImpl implements MenuLocalDataSource { } @override - Future handleMenu(EnumMenuItem item, EnumDisplay display, MenuEntry opt, List entries) async { + Future handleMenu(EnumMenuItem item, EnumDisplay display, MenuEntry opt, + List entries) async { try { switch (display.value) { case 'VISIVEL': - await addMenuEntry(ValueKey(opt.key), item, entries, opt.icon, opt.name, () async { + await addMenuEntry( + ValueKey(opt.key), item, entries, opt.icon, opt.name, + () async { await PathUtil.nav(opt.route); }); break; case 'DESABILITADO': - await addMenuEntry(ValueKey(opt.key), item, entries, opt.icon, opt.name, () async { - await DialogUnavailable.unavailableFeature(navigatorKey.currentContext!); + await addMenuEntry( + ValueKey(opt.key), item, entries, opt.icon, opt.name, + () async { + await DialogUnavailable.unavailableFeature( + navigatorKey.currentContext!); }); break; case 'INVISIVEL': diff --git a/lib/features/menu/data/repositories/menu_repository_impl.dart b/lib/features/menu/data/repositories/menu_repository_impl.dart index bf59361b..0a73d855 100644 --- a/lib/features/menu/data/repositories/menu_repository_impl.dart +++ b/lib/features/menu/data/repositories/menu_repository_impl.dart @@ -10,13 +10,15 @@ class MenuRepositoryImpl implements MenuRepository { final MenuLocalDataSource menuDataSource = MenuLocalDataSourceImpl(); @override - Future> entries2Items(List menuEntries, EnumMenuItem menuItem) async { + Future> entries2Items( + List menuEntries, EnumMenuItem menuItem) async { List entries = []; // final bool isNewVersion = await StorageHelper().get(KeychainStorageKey.isNewVersion.value).then((v) => v.toBoolean()); try { for (var entry in menuEntries) { - final bool isDefault = await menuDataSource.processDisplayDefault(menuItem, entry, entries); + final bool isDefault = await menuDataSource.processDisplayDefault( + menuItem, entry, entries); if (isDefault) continue; final licenseValue = await LicenseRepositoryImpl().getModule(entry.key); if (licenseValue != null) { @@ -25,17 +27,20 @@ class MenuRepositoryImpl implements MenuRepository { final startDate = licenseMap['startDate'] ?? ''; final expirationDate = licenseMap['expirationDate'] ?? ''; final isStarted = await DateTimeUtil.processStartDate(startDate); - final isExpired = await DateTimeUtil.processExpirationDate(expirationDate); + final isExpired = + await DateTimeUtil.processExpirationDate(expirationDate); if (isStarted && !isExpired) { await menuDataSource.handleMenu(menuItem, display, entry, entries); } if (isExpired) { log('Entry ${entry.key} is expired'); - await menuDataSource.handleMenu(menuItem, EnumDisplay.inactive, entry, entries); + await menuDataSource.handleMenu( + menuItem, EnumDisplay.inactive, entry, entries); } if (!isStarted) { log('Entry ${entry.key} is not started'); - await menuDataSource.handleMenu(menuItem, EnumDisplay.inactive, entry, entries); + await menuDataSource.handleMenu( + menuItem, EnumDisplay.inactive, entry, entries); } } } @@ -45,9 +50,11 @@ class MenuRepositoryImpl implements MenuRepository { return entries; } - Future processDisplay(Map module, bool isNewVersion) async { + Future processDisplay( + Map module, bool isNewVersion) async { if (await _shouldUpdateDisplay(module, isNewVersion)) { - final displayValue = module['display'] == EnumDisplay.active ? 'VISIVEL' : 'INVISIVEL'; + final displayValue = + module['display'] == EnumDisplay.active ? 'VISIVEL' : 'INVISIVEL'; await LicenseLocalDataSourceImpl(DatabaseService.database) .setDisplayByKey(['FRE-HUB-ABOUT-PROPERTY'], displayValue); return EnumDisplay.fromString(displayValue); @@ -56,8 +63,13 @@ class MenuRepositoryImpl implements MenuRepository { return EnumDisplay.fromString(module['display']); } - Future _shouldUpdateDisplay(Map module, bool isNewVersion) async { - const keysToCheck = [LicenseKeys.residents, LicenseKeys.vehicles, LicenseKeys.openedVisits]; + Future _shouldUpdateDisplay( + Map module, bool isNewVersion) async { + const keysToCheck = [ + LicenseKeys.residents, + LicenseKeys.vehicles, + LicenseKeys.openedVisits + ]; return isNewVersion && keysToCheck.any((key) => module['key'] == key.value); } } diff --git a/lib/features/module/domain/entities/license.dart b/lib/features/module/domain/entities/license.dart index 130c7462..dde5fee0 100644 --- a/lib/features/module/domain/entities/license.dart +++ b/lib/features/module/domain/entities/license.dart @@ -61,7 +61,9 @@ class License { } static Future _precessWpp() async { - final bool whatsapp = await StorageHelper().get(LocalsStorageKey.whatsapp.key).then((v) => v.toBoolean); + final bool whatsapp = await StorageHelper() + .get(LocalsStorageKey.whatsapp.key) + .then((v) => v.toBoolean); if (whatsapp) return ModuleStatus.active.key; else @@ -69,7 +71,9 @@ class License { } static Future _processProvisional() async { - final bool provisional = await StorageHelper().get(LocalsStorageKey.provisional.key).then((v) => v.toBoolean); + final bool provisional = await StorageHelper() + .get(LocalsStorageKey.provisional.key) + .then((v) => v.toBoolean); if (provisional) return ModuleStatus.active.key; else @@ -77,7 +81,9 @@ class License { } static Future _processPets() async { - final bool pets = await StorageHelper().get(LocalsStorageKey.pets.key).then((v) => v.toBoolean); + final bool pets = await StorageHelper() + .get(LocalsStorageKey.pets.key) + .then((v) => v.toBoolean); if (pets) return ModuleStatus.active.key; else @@ -134,14 +140,18 @@ class License { ), Module( key: LicenseKeys.openedVisits.value, - display: isNewVersionWithModule ? ModuleStatus.active.key : ModuleStatus.inactive.key, + display: isNewVersionWithModule + ? ModuleStatus.active.key + : ModuleStatus.inactive.key, expirationDate: '', startDate: '', quantity: 0, ), Module( key: LicenseKeys.vehicles.value, - display: isNewVersionWithModule ? ModuleStatus.active.key : ModuleStatus.inactive.key, + display: isNewVersionWithModule + ? ModuleStatus.active.key + : ModuleStatus.inactive.key, expirationDate: '', startDate: '', quantity: 0, @@ -155,7 +165,9 @@ class License { ), Module( key: LicenseKeys.residents.value, - display: isNewVersionWithModule ? ModuleStatus.active.key : ModuleStatus.inactive.key, + display: isNewVersionWithModule + ? ModuleStatus.active.key + : ModuleStatus.inactive.key, expirationDate: '', startDate: '', quantity: 0, @@ -218,14 +230,18 @@ class License { ), Module( key: LicenseKeys.property.value, - display: isNewVersionWithModule ? ModuleStatus.active.key : ModuleStatus.inactive.key, + display: isNewVersionWithModule + ? ModuleStatus.active.key + : ModuleStatus.inactive.key, expirationDate: '', startDate: '', quantity: 0, ), Module( key: LicenseKeys.people.value, - display: isNewVersionWithModule ? ModuleStatus.inactive.key : ModuleStatus.active.key, + display: isNewVersionWithModule + ? ModuleStatus.inactive.key + : ModuleStatus.active.key, expirationDate: '', startDate: '', quantity: 0, diff --git a/lib/features/notification/deep_link_service.dart b/lib/features/notification/deep_link_service.dart index 374a8cd5..77792519 100644 --- a/lib/features/notification/deep_link_service.dart +++ b/lib/features/notification/deep_link_service.dart @@ -65,7 +65,8 @@ class DeepLinkService { ), ), isScrollControlled: true, - backgroundColor: FlutterFlowTheme.of(navigatorKey.currentContext!).primaryBackground, + backgroundColor: FlutterFlowTheme.of(navigatorKey.currentContext!) + .primaryBackground, showDragHandle: true, useSafeArea: true, enableDrag: true, diff --git a/lib/flutter_flow/nav/nav.dart b/lib/flutter_flow/nav/nav.dart index cadc837a..6da3a666 100644 --- a/lib/flutter_flow/nav/nav.dart +++ b/lib/flutter_flow/nav/nav.dart @@ -86,11 +86,20 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { builder: (context, _) { return FutureBuilder( future: () async { - final bool isLogged = await StorageHelper().get(SecureStorageKey.isLogged.value) == 'true'; - final bool haveLocal = await StorageHelper().get(SecureStorageKey.haveLocal.value) == 'true'; + final bool isLogged = + await StorageHelper().get(SecureStorageKey.isLogged.value) == + 'true'; + final bool haveLocal = + await StorageHelper().get(SecureStorageKey.haveLocal.value) == + 'true'; final bool haveUserUUID = - (await StorageHelper().get(ProfileStorageKey.userUUID.key))?.isNotEmpty ?? false; - final bool haveDevUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key))?.isNotEmpty ?? false; + (await StorageHelper().get(ProfileStorageKey.userUUID.key)) + ?.isNotEmpty ?? + false; + final bool haveDevUUID = + (await StorageHelper().get(ProfileStorageKey.devUUID.key)) + ?.isNotEmpty ?? + false; if (isLogged && haveDevUUID && haveUserUUID) { return haveLocal @@ -100,17 +109,20 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { create: (context) => MenuBloc( style: MenuView.list_grid, item: EnumMenuItem.button, - entries: MenuEntry.getEntriesByType(MenuEntryType.Home), + entries: MenuEntry.getEntriesByType( + MenuEntryType.Home), )..add(MenuEvent()), ), BlocProvider( create: (context) => HomeBloc()..add(HomeEvent()), ), BlocProvider( - create: (context) => LocalProfileBloc()..add(LocalProfileEvent()), + create: (context) => + LocalProfileBloc()..add(LocalProfileEvent()), ), ], - child: HomePageWidget(key: UniqueKey(), LocalsRepositoryImpl().update), + child: HomePageWidget( + key: UniqueKey(), LocalsRepositoryImpl().update), ) : const ReceptionPageWidget(); } else { @@ -134,8 +146,10 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { name: 'forgotPassword', path: '/forgotPassword', builder: (context, params) { - late final String email = params.getParam('email', ParamType.String); - late final String token = params.getParam('token', ParamType.String); + late final String email = + params.getParam('email', ParamType.String); + late final String token = + params.getParam('token', ParamType.String); return ForgotPasswordScreen( key: ValueKey('ForgotPasswordScreen'), @@ -152,7 +166,8 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { name: 'homePage', path: '/homePage', builder: (context, params) { - final Future Function(BuildContext context)? update = params.getParam('update', ParamType.Function); + final Future Function(BuildContext context)? update = + params.getParam('update', ParamType.Function); return MultiBlocProvider( providers: [ BlocProvider( @@ -166,7 +181,8 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { create: (context) => HomeBloc()..add(HomeEvent()), ), BlocProvider( - create: (context) => LocalProfileBloc()..add(LocalProfileEvent()), + create: (context) => + LocalProfileBloc()..add(LocalProfileEvent()), ), ], child: HomePageWidget(key: UniqueKey(), update), @@ -175,12 +191,16 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { FFRoute( name: 'petsOnThePropertyPage', path: '/petsOnThePropertyPage', - builder: (context, params) => Scaffold(body: const PetsHistoryScreen(isApp: true))), + builder: (context, params) => + Scaffold(body: const PetsHistoryScreen(isApp: true))), FFRoute( name: 'vehiclesOnThePropertyPage', path: '/vehiclesOnThePropertyPage', builder: (context, params) => const VehiclePage()), - FFRoute(name: 'receptionPage', path: '/receptionPage', builder: (context, params) => const ReceptionPageWidget()), + FFRoute( + name: 'receptionPage', + path: '/receptionPage', + builder: (context, params) => const ReceptionPageWidget()), FFRoute( name: 'messageHistoryPage', path: '/messageHistoryPage', @@ -192,19 +212,28 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { FFRoute( name: 'scheduleCompleteVisitPage', path: '/scheduleCompleteVisitPage', - builder: (context, params) => const ScheduleCompleteVisitPageWidget()), + builder: (context, params) => + const ScheduleCompleteVisitPageWidget()), FFRoute( - name: 'deliverySchedule', path: '/deliverySchedule', builder: (context, params) => const DeliverySchedule()), + name: 'deliverySchedule', + path: '/deliverySchedule', + builder: (context, params) => const DeliverySchedule()), FFRoute( name: 'provisionalSchedule', path: '/provisionalSchedule', builder: (context, params) => const ProvisionalSchedule()), - FFRoute(name: 'fastPassPage', path: '/fastPassPage', builder: (context, params) => FastPassPageWidget()), + FFRoute( + name: 'fastPassPage', + path: '/fastPassPage', + builder: (context, params) => FastPassPageWidget()), FFRoute( name: 'preferencesSettings', path: '/preferencesSettings', builder: (context, params) => PreferencesPageWidget()), - FFRoute(name: 'aboutProperty', path: '/aboutProperty', builder: (context, params) => AboutPropertyPage()), + FFRoute( + name: 'aboutProperty', + path: '/aboutProperty', + builder: (context, params) => AboutPropertyPage()), FFRoute( name: 'residentsOnThePropertyPage', path: '/residentsOnThePropertyPage', @@ -220,8 +249,11 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { FFRoute( name: 'acessHistoryPage', path: '/acessHistoryPage', - builder: (context, params) => - AccessHistoryScreen(opt: const {'personType': '.*', 'accessType': '.*', 'search': '.*'})), + builder: (context, params) => AccessHistoryScreen(opt: const { + 'personType': '.*', + 'accessType': '.*', + 'search': '.*' + })), FFRoute( name: 'provisionalHistoryPage', path: '/provisionalHistoryPage', @@ -230,13 +262,34 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { name: 'liberationHistory', path: '/liberationHistory', builder: (context, params) => const LiberationHistoryWidget()), - FFRoute(name: 'signInPage', path: '/signInPage', builder: (context, params) => const SignInPageWidget()), - FFRoute(name: 'signUpPage', path: '/signUpPage', builder: (context, params) => const SignUpPageWidget()), - FFRoute(name: 'welcomePage', path: '/welcomePage', builder: (context, params) => const WelcomePage()), - FFRoute(name: 'qrCodePage', path: '/qrCodePage', builder: (context, params) => const QrCodePageWidget()), - FFRoute(name: 'preferencesPage', path: '/preferencesPage', builder: (context, params) => PreferencesPageWidget()), - FFRoute(name: 'packageOrder', path: '/packageOrder', builder: (context, params) => const PackageOrderPage()), - FFRoute(name: 'reservation', path: '/reservation', builder: (context, params) => ReservationPageWidget()), + FFRoute( + name: 'signInPage', + path: '/signInPage', + builder: (context, params) => const SignInPageWidget()), + FFRoute( + name: 'signUpPage', + path: '/signUpPage', + builder: (context, params) => const SignUpPageWidget()), + FFRoute( + name: 'welcomePage', + path: '/welcomePage', + builder: (context, params) => const WelcomePage()), + FFRoute( + name: 'qrCodePage', + path: '/qrCodePage', + builder: (context, params) => const QrCodePageWidget()), + FFRoute( + name: 'preferencesPage', + path: '/preferencesPage', + builder: (context, params) => PreferencesPageWidget()), + FFRoute( + name: 'packageOrder', + path: '/packageOrder', + builder: (context, params) => const PackageOrderPage()), + FFRoute( + name: 'reservation', + path: '/reservation', + builder: (context, params) => ReservationPageWidget()), FFRoute( name: 'petsPage', path: '/petsPage', @@ -252,7 +305,9 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { extension NavParamExtensions on Map { Map get withoutNulls => Map.fromEntries( - entries.where((e) => e.value != null).map((e) => MapEntry(e.key, e.value!)), + entries + .where((e) => e.value != null) + .map((e) => MapEntry(e.key, e.value!)), ); } @@ -266,7 +321,8 @@ extension NavigationExtensions on BuildContext { } extension _GoRouterStateExtensions on GoRouterState { - Map get extraMap => extra != null ? extra as Map : {}; + Map get extraMap => + extra != null ? extra as Map : {}; Map get allParams => {} ..addAll(pathParameters) ..addAll(uri.queryParameters) @@ -279,8 +335,9 @@ extension _GoRouterStateExtensions on GoRouterState { extension GoRouterLocationExtension on GoRouter { String getCurrentLocation() { final RouteMatch lastMatch = routerDelegate.currentConfiguration.last; - final RouteMatchList matchList = - lastMatch is ImperativeRouteMatch ? lastMatch.matches : routerDelegate.currentConfiguration; + final RouteMatchList matchList = lastMatch is ImperativeRouteMatch + ? lastMatch.matches + : routerDelegate.currentConfiguration; return matchList.uri.toString(); } } @@ -293,13 +350,17 @@ class FFParameters { Map futureParamValues = {}; bool get isEmpty => - state.allParams.isEmpty || (state.allParams.length == 1 && state.extraMap.containsKey(kTransitionInfoKey)); - bool isAsyncParam(MapEntry param) => asyncParams.containsKey(param.key) && param.value is String; + state.allParams.isEmpty || + (state.allParams.length == 1 && + state.extraMap.containsKey(kTransitionInfoKey)); + bool isAsyncParam(MapEntry param) => + asyncParams.containsKey(param.key) && param.value is String; bool get hasFutures => state.allParams.entries.any(isAsyncParam); Future completeFutures() => Future.wait( state.allParams.entries.where(isAsyncParam).map( (param) async { - final doc = await asyncParams[param.key]!(param.value).onError((_, __) => null); + final doc = await asyncParams[param.key]!(param.value) + .onError((_, __) => null); if (doc != null) { futureParamValues[param.key] = doc; return true; @@ -309,12 +370,15 @@ class FFParameters { ), ).onError((_, __) => [false]).then((v) => v.every((e) => e)); - dynamic getParam(String paramName, ParamType type, {bool isList = false, StructBuilder? structBuilder}) { - if (futureParamValues.containsKey(paramName)) return futureParamValues[paramName]; + dynamic getParam(String paramName, ParamType type, + {bool isList = false, StructBuilder? structBuilder}) { + if (futureParamValues.containsKey(paramName)) + return futureParamValues[paramName]; if (!state.allParams.containsKey(paramName)) return null; final param = state.allParams[paramName]; if (param is! String) return param; - return deserializeParam(param, type, isList, structBuilder: structBuilder); + return deserializeParam(param, type, isList, + structBuilder: structBuilder); } } @@ -354,13 +418,16 @@ class FFRoute { key: state.pageKey, child: child, transitionDuration: transitionInfo.duration, - transitionsBuilder: (context, animation, secondaryAnimation, child) => PageTransition( + transitionsBuilder: + (context, animation, secondaryAnimation, child) => + PageTransition( type: transitionInfo.transitionType, duration: transitionInfo.duration, reverseDuration: transitionInfo.duration, alignment: transitionInfo.alignment, child: child, - ).buildTransitions(context, animation, secondaryAnimation, child), + ).buildTransitions( + context, animation, secondaryAnimation, child), ) : MaterialPage(key: state.pageKey, child: child); }, @@ -381,7 +448,8 @@ class TransitionInfo { final Duration duration; final Alignment? alignment; - static TransitionInfo appDefault() => const TransitionInfo(hasTransition: false); + static TransitionInfo appDefault() => + const TransitionInfo(hasTransition: false); } class RootPageContext { @@ -393,7 +461,9 @@ class RootPageContext { final rootPageContext = context.read(); final isRootPage = rootPageContext?.isRootPage ?? false; final location = GoRouterState.of(context).uri.toString(); - return isRootPage && location != '/' && location != rootPageContext?.errorRoute; + return isRootPage && + location != '/' && + location != rootPageContext?.errorRoute; } static Widget wrap(Widget child, {String? errorRoute}) => diff --git a/lib/initialization.dart b/lib/initialization.dart index 217044ec..3f780c8c 100644 --- a/lib/initialization.dart +++ b/lib/initialization.dart @@ -1,4 +1,3 @@ - import 'package:app_tracking_transparency/app_tracking_transparency.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_crashlytics/firebase_crashlytics.dart'; diff --git a/lib/main.dart b/lib/main.dart index 144a9fb5..3e98ba72 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -53,7 +53,8 @@ class App extends StatefulWidget { @override State createState() => _AppState(); - static _AppState of(BuildContext context) => context.findAncestorStateOfType<_AppState>()!; + static _AppState of(BuildContext context) => + context.findAncestorStateOfType<_AppState>()!; } class _AppState extends State { @@ -95,7 +96,8 @@ class _AppState extends State { }), ), ); - final Iterable>? localizationsDelegates = const [ + final Iterable>? localizationsDelegates = + const [ FFLocalizationsDelegate(), GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, @@ -137,7 +139,8 @@ class _AppState extends State { await StorageHelper().set(SecureStorageKey.haveLocal.value, true); log('onMessageOpenedApp'); } else { - onMessageReceived(message.data, message.notification!.body, message.data['click_action']); + onMessageReceived(message.data, message.notification!.body, + message.data['click_action']); } }); FirebaseMessaging.instance.getInitialMessage().then((message) async { @@ -171,7 +174,9 @@ class _AppState extends State { _router = createRouter(_appStateNotifier); Future.delayed( const Duration(milliseconds: 1000), - () => mounted ? setState(() => _appStateNotifier.stopShowingSplashImage()) : null, + () => mounted + ? setState(() => _appStateNotifier.stopShowingSplashImage()) + : null, ); _setupFirebaseMessaging(); diff --git a/lib/pages/forgot_password_page/forgot_password_screen.dart b/lib/pages/forgot_password_page/forgot_password_screen.dart index da97657c..99d0914d 100644 --- a/lib/pages/forgot_password_page/forgot_password_screen.dart +++ b/lib/pages/forgot_password_page/forgot_password_screen.dart @@ -15,7 +15,8 @@ import '../../flutter_flow/internationalization.dart'; import 'forgot_password_model.dart'; class ForgotPasswordScreen extends StatefulWidget { - const ForgotPasswordScreen({super.key, required this.email, required this.token}); + const ForgotPasswordScreen( + {super.key, required this.email, required this.token}); final String email; final String token; @@ -23,7 +24,8 @@ class ForgotPasswordScreen extends StatefulWidget { State createState() => _ForgotPasswordScreenState(); } -class _ForgotPasswordScreenState extends State with TickerProviderStateMixin { +class _ForgotPasswordScreenState extends State + with TickerProviderStateMixin { late ForgotPasswordScreenModel _model; final animationsMap = {}; @@ -148,7 +150,8 @@ class _ForgotPasswordScreenState extends State with Ticker width: MediaQuery.of(context).size.width, child: SingleChildScrollView( child: Padding( - padding: const EdgeInsets.only(left: 15.0, right: 15.0, top: 10.0, bottom: 0.0), + padding: const EdgeInsets.only( + left: 15.0, right: 15.0, top: 10.0, bottom: 0.0), child: Container( width: double.infinity, constraints: const BoxConstraints(maxWidth: 570.0), @@ -157,7 +160,8 @@ class _ForgotPasswordScreenState extends State with Ticker borderRadius: BorderRadius.circular(12.0), ), child: Padding( - padding: const EdgeInsets.only(left: 20.0, right: 20.0, top: 10.0, bottom: 0.0), + padding: const EdgeInsets.only( + left: 20.0, right: 20.0, top: 10.0, bottom: 0.0), child: Column( mainAxisSize: MainAxisSize.max, crossAxisAlignment: CrossAxisAlignment.center, @@ -171,21 +175,25 @@ class _ForgotPasswordScreenState extends State with Ticker fontSize: 24.0, fontWeight: FontWeight.bold, letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap().containsKey('Nunito'), + useGoogleFonts: + GoogleFonts.asMap().containsKey('Nunito'), ), )), Align( alignment: const AlignmentDirectional(-1.0, 0.0), child: Padding( - padding: const EdgeInsetsDirectional.fromSTEB(20.0, 24.0, 0.0, 30.0), + padding: const EdgeInsetsDirectional.fromSTEB( + 20.0, 24.0, 0.0, 30.0), child: Text( message, textAlign: TextAlign.start, style: FlutterFlowTheme.of(context).bodyMedium.override( - fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily, + fontFamily: + FlutterFlowTheme.of(context).bodyMediumFamily, fontWeight: FontWeight.bold, - useGoogleFonts: - GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).bodyMediumFamily), + useGoogleFonts: GoogleFonts.asMap().containsKey( + FlutterFlowTheme.of(context) + .bodyMediumFamily), ), ), ), @@ -201,32 +209,42 @@ class _ForgotPasswordScreenState extends State with Ticker controller: _model.passwordRegisterFormTextController, focusNode: _model.passwordRegisterFormFocusNode, visibility: _model.passwordRegisterFormVisibility, - onVisibilityToggle: () => setState( - () => _model.passwordRegisterFormVisibility = !_model.passwordRegisterFormVisibility), - label: - FFLocalizations.of(context).getVariableText(ptText: 'Nova Senha', enText: 'New Password'), - hint: FFLocalizations.of(context) - .getVariableText(ptText: 'Insira sua senha', enText: 'Enter your password'), - asValidator: _model.passwordRegisterFormTextControllerValidator.asValidator(context), + onVisibilityToggle: () => setState(() => + _model.passwordRegisterFormVisibility = + !_model.passwordRegisterFormVisibility), + label: FFLocalizations.of(context).getVariableText( + ptText: 'Nova Senha', enText: 'New Password'), + hint: FFLocalizations.of(context).getVariableText( + ptText: 'Insira sua senha', + enText: 'Enter your password'), + asValidator: _model + .passwordRegisterFormTextControllerValidator + .asValidator(context), ), _buildPasswordField( context, controller: _model.passwordConfirmFormTextController, focusNode: _model.passwordConfirmFormFocusNode, visibility: _model.passwordConfirmFormVisibility, - onVisibilityToggle: () => setState( - () => _model.passwordConfirmFormVisibility = !_model.passwordConfirmFormVisibility), - label: FFLocalizations.of(context) - .getVariableText(ptText: 'Confirme a Senha', enText: 'Confirm Password'), - hint: FFLocalizations.of(context) - .getVariableText(ptText: 'Confirme sua senha', enText: 'Confirm your password'), - asValidator: _model.passwordConfirmFormTextControllerValidator.asValidator(context), + onVisibilityToggle: () => setState(() => + _model.passwordConfirmFormVisibility = + !_model.passwordConfirmFormVisibility), + label: FFLocalizations.of(context).getVariableText( + ptText: 'Confirme a Senha', + enText: 'Confirm Password'), + hint: FFLocalizations.of(context).getVariableText( + ptText: 'Confirme sua senha', + enText: 'Confirm your password'), + asValidator: _model + .passwordConfirmFormTextControllerValidator + .asValidator(context), ), ], ), ), Padding( - padding: const EdgeInsetsDirectional.fromSTEB(0.0, 0.0, 0.0, 16.0), + padding: const EdgeInsetsDirectional.fromSTEB( + 0.0, 0.0, 0.0, 16.0), child: FFButtonWidget( key: const ValueKey('SubmitButtonWidget'), onPressed: _model.isFormInvalid() @@ -248,16 +266,22 @@ class _ForgotPasswordScreenState extends State with Ticker width: double.infinity, height: 44.0, color: FlutterFlowTheme.of(context).accent1, - textStyle: FlutterFlowTheme.of(context).titleSmall.override( - fontFamily: 'Plus Jakarta Sans', - color: FlutterFlowTheme.of(context).secondaryText, - fontSize: 16.0, - fontWeight: FontWeight.w500, - useGoogleFonts: GoogleFonts.asMap().containsKey('Plus Jakarta Sans')), + textStyle: FlutterFlowTheme.of(context) + .titleSmall + .override( + fontFamily: 'Plus Jakarta Sans', + color: + FlutterFlowTheme.of(context).secondaryText, + fontSize: 16.0, + fontWeight: FontWeight.w500, + useGoogleFonts: GoogleFonts.asMap() + .containsKey('Plus Jakarta Sans')), elevation: 3.0, - borderSide: const BorderSide(color: Colors.transparent, width: 1.0), + borderSide: const BorderSide( + color: Colors.transparent, width: 1.0), borderRadius: BorderRadius.circular(12.0), - disabledColor: FlutterFlowTheme.of(context).customColor5, + disabledColor: + FlutterFlowTheme.of(context).customColor5, disabledTextColor: Colors.white, ), showLoadingIndicator: true, @@ -305,22 +329,28 @@ class _ForgotPasswordScreenState extends State with Ticker color: FlutterFlowTheme.of(context).primaryText, fontSize: 16.0, fontWeight: FontWeight.w500, - useGoogleFonts: GoogleFonts.asMap().containsKey('Plus Jakarta Sans'), + useGoogleFonts: + GoogleFonts.asMap().containsKey('Plus Jakarta Sans'), ), enabledBorder: OutlineInputBorder( - borderSide: BorderSide(color: FlutterFlowTheme.of(context).customColor1, width: 0.25), + borderSide: BorderSide( + color: FlutterFlowTheme.of(context).customColor1, + width: 0.25), borderRadius: BorderRadius.circular(12.0), ), focusedBorder: OutlineInputBorder( - borderSide: const BorderSide(color: Color(0xFF1AAB5F), width: 0.25), + borderSide: + const BorderSide(color: Color(0xFF1AAB5F), width: 0.25), borderRadius: BorderRadius.circular(12.0), ), errorBorder: OutlineInputBorder( - borderSide: const BorderSide(color: Color(0xFFFF5963), width: 0.25), + borderSide: + const BorderSide(color: Color(0xFFFF5963), width: 0.25), borderRadius: BorderRadius.circular(12.0), ), focusedErrorBorder: OutlineInputBorder( - borderSide: const BorderSide(color: Color(0xFFFF5963), width: 0.25), + borderSide: + const BorderSide(color: Color(0xFFFF5963), width: 0.25), borderRadius: BorderRadius.circular(12.0), ), filled: true, @@ -330,7 +360,9 @@ class _ForgotPasswordScreenState extends State with Ticker onTap: onVisibilityToggle, focusNode: FocusNode(skipTraversal: true), child: Icon( - visibility ? Icons.visibility_outlined : Icons.visibility_off_outlined, + visibility + ? Icons.visibility_outlined + : Icons.visibility_off_outlined, color: FlutterFlowTheme.of(context).accent1, size: 24.0, ), @@ -341,7 +373,8 @@ class _ForgotPasswordScreenState extends State with Ticker color: FlutterFlowTheme.of(context).primaryText, fontSize: 16.0, fontWeight: FontWeight.w500, - useGoogleFonts: GoogleFonts.asMap().containsKey('Plus Jakarta Sans'), + useGoogleFonts: + GoogleFonts.asMap().containsKey('Plus Jakarta Sans'), ), validator: asValidator, ), diff --git a/lib/pages/pets_page/pets_page_model.dart b/lib/pages/pets_page/pets_page_model.dart index b24db31b..e7de27fe 100644 --- a/lib/pages/pets_page/pets_page_model.dart +++ b/lib/pages/pets_page/pets_page_model.dart @@ -504,7 +504,6 @@ class PetsPageModel extends FlutterFlowModel { ); }); }); - }, options: FFButtonOptions( height: 40, diff --git a/lib/pages/pets_page/pets_page_widget.dart b/lib/pages/pets_page/pets_page_widget.dart index a2aae357..8816c468 100644 --- a/lib/pages/pets_page/pets_page_widget.dart +++ b/lib/pages/pets_page/pets_page_widget.dart @@ -1049,6 +1049,4 @@ class _PetsPageWidgetState extends State ), ); } - - } diff --git a/lib/pages/reception_page/reception_page_widget.dart b/lib/pages/reception_page/reception_page_widget.dart index b56f8bfe..4fc8c064 100644 --- a/lib/pages/reception_page/reception_page_widget.dart +++ b/lib/pages/reception_page/reception_page_widget.dart @@ -1,4 +1,3 @@ - import 'package:awesome_notifications/awesome_notifications.dart'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; diff --git a/lib/pages/vehicles_on_the_property/vehicle_register_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_register_screen.dart index 07b786a3..c424aa3a 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_register_screen.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_register_screen.dart @@ -35,10 +35,13 @@ class _VehicleRegisterScreenState extends State { children: [ CustomInputUtil( controller: widget.model.textFieldControllerLicensePlate, - validator: widget.model.textControllerLicensePlateValidator.asValidator(context), + validator: widget.model.textControllerLicensePlateValidator + .asValidator(context), focusNode: widget.model.textFieldFocusLicensePlate, - labelText: FFLocalizations.of(context).getVariableText(ptText: 'Placa', enText: 'License Plate'), - hintText: FFLocalizations.of(context).getVariableText(ptText: 'Placa', enText: 'License Plate'), + labelText: FFLocalizations.of(context) + .getVariableText(ptText: 'Placa', enText: 'License Plate'), + hintText: FFLocalizations.of(context) + .getVariableText(ptText: 'Placa', enText: 'License Plate'), suffixIcon: Symbols.format_color_text, haveMaxLength: true, onChanged: (value) => setState(() {}), @@ -46,9 +49,11 @@ class _VehicleRegisterScreenState extends State { ), CustomInputUtil( controller: widget.model.textFieldControllerModel, - validator: widget.model.textControllerModelValidator.asValidator(context), + validator: widget.model.textControllerModelValidator + .asValidator(context), focusNode: widget.model.textFieldFocusModel, - labelText: FFLocalizations.of(context).getVariableText(ptText: 'Modelo', enText: 'Model'), + labelText: FFLocalizations.of(context) + .getVariableText(ptText: 'Modelo', enText: 'Model'), hintText: FFLocalizations.of(context).getVariableText( ptText: 'Ex: Voyage, Ford', enText: 'e.g. Voyage, Ford', @@ -60,9 +65,11 @@ class _VehicleRegisterScreenState extends State { ), CustomInputUtil( controller: widget.model.textFieldControllerColor, - validator: widget.model.textControllerColorValidator.asValidator(context), + validator: widget.model.textControllerColorValidator + .asValidator(context), focusNode: widget.model.textFieldFocusColor, - labelText: FFLocalizations.of(context).getVariableText(ptText: 'Cor', enText: 'Color'), + labelText: FFLocalizations.of(context) + .getVariableText(ptText: 'Cor', enText: 'Color'), hintText: FFLocalizations.of(context).getVariableText( ptText: 'Ex: Preto, Amarelo, Branco', enText: 'e.g. Black, Yellow, White', @@ -75,8 +82,11 @@ class _VehicleRegisterScreenState extends State { Padding( padding: const EdgeInsets.fromLTRB(70, 20, 70, 30), child: SubmitButtonUtil( - labelText: FFLocalizations.of(context).getVariableText(ptText: 'Cadastrar', enText: 'Register'), - onPressed: widget.model.isFormValid(context) ? widget.model.registerVehicle : null), + labelText: FFLocalizations.of(context) + .getVariableText(ptText: 'Cadastrar', enText: 'Register'), + onPressed: widget.model.isFormValid(context) + ? widget.model.registerVehicle + : null), ), ], )); @@ -84,7 +94,8 @@ class _VehicleRegisterScreenState extends State { Align _buildHeader(BuildContext context) { // double limitedInputFontSize = LimitedFontSizeUtil.getInputFontSize(context); - double limitedHeaderFontSize = LimitedFontSizeUtil.getHeaderFontSize(context); + double limitedHeaderFontSize = + LimitedFontSizeUtil.getHeaderFontSize(context); // double limitedSubHeaderFontSize = LimitedFontSizeUtil.getSubHeaderFontSize(context); return Align( @@ -93,14 +104,16 @@ class _VehicleRegisterScreenState extends State { padding: const EdgeInsetsDirectional.fromSTEB(24.0, 20, 0.0, 15), child: Text( FFLocalizations.of(context).getVariableText( - ptText: 'Preencha o formulário de cadastro com os dados do seu veículo', + ptText: + 'Preencha o formulário de cadastro com os dados do seu veículo', enText: 'Fill out the registration form with your vehicle data', ), textAlign: TextAlign.start, style: FlutterFlowTheme.of(context).bodyMedium.override( fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily, letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).bodyMediumFamily), + useGoogleFonts: GoogleFonts.asMap() + .containsKey(FlutterFlowTheme.of(context).bodyMediumFamily), fontSize: limitedHeaderFontSize, ), ), diff --git a/lib/pages/vehicles_on_the_property/vehicle_update_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_update_screen.dart index a9293149..534a9f58 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_update_screen.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_update_screen.dart @@ -24,14 +24,16 @@ class _VehicleUpdateScreenState extends State { padding: const EdgeInsetsDirectional.fromSTEB(24.0, 20, 0.0, 15), child: Text( FFLocalizations.of(context).getVariableText( - ptText: 'Preencha o formulário de alteração com os dados do seu veículo', + ptText: + 'Preencha o formulário de alteração com os dados do seu veículo', enText: 'Fill out the update form with your vehicle data', ), textAlign: TextAlign.start, style: FlutterFlowTheme.of(context).bodyMedium.override( fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily, letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).bodyMediumFamily), + useGoogleFonts: GoogleFonts.asMap().containsKey( + FlutterFlowTheme.of(context).bodyMediumFamily), ), ), ), @@ -45,10 +47,13 @@ class _VehicleUpdateScreenState extends State { children: [ CustomInputUtil( controller: widget.model.textFieldControllerLicensePlate, - validator: widget.model.textControllerLicensePlateValidator.asValidator(context), + validator: widget.model.textControllerLicensePlateValidator + .asValidator(context), focusNode: widget.model.textFieldFocusLicensePlate, - labelText: FFLocalizations.of(context).getVariableText(ptText: 'Placa', enText: 'License Plate'), - hintText: FFLocalizations.of(context).getVariableText(ptText: 'Placa', enText: 'License Plate'), + labelText: FFLocalizations.of(context).getVariableText( + ptText: 'Placa', enText: 'License Plate'), + hintText: FFLocalizations.of(context).getVariableText( + ptText: 'Placa', enText: 'License Plate'), suffixIcon: Symbols.format_color_text, haveMaxLength: true, onChanged: (value) => setState(() {}), @@ -58,9 +63,11 @@ class _VehicleUpdateScreenState extends State { padding: const EdgeInsets.fromLTRB(0, 0, 0, 15), child: CustomInputUtil( controller: widget.model.textFieldControllerModel, - validator: widget.model.textControllerModelValidator.asValidator(context), + validator: widget.model.textControllerModelValidator + .asValidator(context), focusNode: widget.model.textFieldFocusModel, - labelText: FFLocalizations.of(context).getVariableText(ptText: 'Modelo', enText: 'Model'), + labelText: FFLocalizations.of(context) + .getVariableText(ptText: 'Modelo', enText: 'Model'), hintText: FFLocalizations.of(context).getVariableText( ptText: 'Ex: Voyage, Ford', enText: 'e.g. Voyage, Ford', @@ -75,9 +82,11 @@ class _VehicleUpdateScreenState extends State { padding: const EdgeInsets.fromLTRB(0, 0, 0, 15), child: CustomInputUtil( controller: widget.model.textFieldControllerColor, - validator: widget.model.textControllerColorValidator.asValidator(context), + validator: widget.model.textControllerColorValidator + .asValidator(context), focusNode: widget.model.textFieldFocusColor, - labelText: FFLocalizations.of(context).getVariableText(ptText: 'Cor', enText: 'Color'), + labelText: FFLocalizations.of(context) + .getVariableText(ptText: 'Cor', enText: 'Color'), hintText: FFLocalizations.of(context).getVariableText( ptText: 'Ex: Preto, Amarelo, Branco', enText: 'e.g. Black, Yellow, White', @@ -91,8 +100,11 @@ class _VehicleUpdateScreenState extends State { Padding( padding: const EdgeInsets.fromLTRB(70, 20, 70, 30), child: SubmitButtonUtil( - labelText: FFLocalizations.of(context).getVariableText(ptText: 'Salvar', enText: 'Save'), - onPressed: widget.model.isFormValid(context) ? widget.model.updateVehicle : null), + labelText: FFLocalizations.of(context) + .getVariableText(ptText: 'Salvar', enText: 'Save'), + onPressed: widget.model.isFormValid(context) + ? widget.model.updateVehicle + : null), ), ], )), diff --git a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart index cd3b28a4..586aa3c4 100644 --- a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart +++ b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart @@ -1,4 +1,3 @@ - import 'dart:collection'; import 'package:flutter/material.dart'; @@ -31,7 +30,8 @@ class VehiclePage extends StatefulWidget { _VehiclePageState createState() => _VehiclePageState(); } -class _VehiclePageState extends State with TickerProviderStateMixin { +class _VehiclePageState extends State + with TickerProviderStateMixin { int count = 0; late final VehicleModel _model; @@ -99,7 +99,8 @@ class _VehiclePageState extends State with TickerProviderStateMixin Future _initializeModule() async { try { - final module = await LicenseRepositoryImpl().getModule('FRE-HUB-VEHICLES-MANAGER'); + final module = + await LicenseRepositoryImpl().getModule('FRE-HUB-VEHICLES-MANAGER'); return await LicenseUtil.processModule(module); } catch (e) { WidgetsBinding.instance.addPostFrameCallback((_) async { @@ -121,20 +122,25 @@ class _VehiclePageState extends State with TickerProviderStateMixin } Widget _buildVehicleManager(BuildContext context) { - final vehicleHistoryScreenLabel = - FFLocalizations.of(context).getVariableText(ptText: 'Consultar', enText: 'History'); - final vehicleRegisterScreenLabel = - FFLocalizations.of(context).getVariableText(ptText: 'Cadastrar', enText: 'Register'); - final vehicleUpdateScreenLabel = FFLocalizations.of(context).getVariableText(ptText: 'Editar', enText: 'Edit'); + final vehicleHistoryScreenLabel = FFLocalizations.of(context) + .getVariableText(ptText: 'Consultar', enText: 'History'); + final vehicleRegisterScreenLabel = FFLocalizations.of(context) + .getVariableText(ptText: 'Cadastrar', enText: 'Register'); + final vehicleUpdateScreenLabel = FFLocalizations.of(context) + .getVariableText(ptText: 'Editar', enText: 'Edit'); return TabViewUtil( context: context, model: _model, labelTab1: vehicleHistoryScreenLabel, - labelTab2: _model.isEditing ? vehicleUpdateScreenLabel : vehicleRegisterScreenLabel, + labelTab2: _model.isEditing + ? vehicleUpdateScreenLabel + : vehicleRegisterScreenLabel, controller: _model.tabBarController, widget1: VehicleHistoryScreen(_model), - widget2: _model.isEditing ? VehicleUpdateScreen(_model) : VehicleRegisterScreen(_model), + widget2: _model.isEditing + ? VehicleUpdateScreen(_model) + : VehicleRegisterScreen(_model), onEditingChanged: onEditingChanged, ); } @@ -145,14 +151,16 @@ class _VehiclePageState extends State with TickerProviderStateMixin final theme = FlutterFlowTheme.of(context); final backgroundColor = theme.primaryBackground; final primaryText = theme.primaryText; - final title = FFLocalizations.of(context).getVariableText(enText: 'Vehicles', ptText: 'Veículos'); + final title = FFLocalizations.of(context) + .getVariableText(enText: 'Vehicles', ptText: 'Veículos'); final titleStyle = theme.headlineMedium.override( fontFamily: theme.headlineMediumFamily, color: primaryText, fontSize: 16.0, fontWeight: FontWeight.bold, letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap().containsKey(theme.headlineMediumFamily), + useGoogleFonts: + GoogleFonts.asMap().containsKey(theme.headlineMediumFamily), ); final backButton = _backButton(context, theme); diff --git a/lib/pages/visits_on_the_property/model.dart b/lib/pages/visits_on_the_property/model.dart index 4e15ebef..b263e717 100644 --- a/lib/pages/visits_on_the_property/model.dart +++ b/lib/pages/visits_on_the_property/model.dart @@ -11,7 +11,8 @@ class VisitsModel extends FlutterFlowModel { VisitsModel._internal({this.onRefresh}); - factory VisitsModel({VoidCallback? onRefresh}) => _instance ??= VisitsModel._internal(onRefresh: onRefresh); + factory VisitsModel({VoidCallback? onRefresh}) => + _instance ??= VisitsModel._internal(onRefresh: onRefresh); static void resetInstance() => _instance = null; late final VoidCallback? onRefresh; @@ -33,7 +34,8 @@ class VisitsModel extends FlutterFlowModel { Future initAsync() async { devUUID = (await StorageHelper().get(ProfileStorageKey.devUUID.key)) ?? ''; - cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; + cliUUID = + (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; onRefresh?.call(); } @@ -87,7 +89,9 @@ class VisitsModel extends FlutterFlowModel { FFLocalizations.of(context).getVariableText( ptText: item['VTA_FIXA'] ? "Entrada Recorrente" : "Entrada Única", enText: item['VTA_FIXA'] ? "Recurrent Entry" : "Single Entry", - ): item['VTA_FIXA'] == false ? FlutterFlowTheme.of(context).success : FlutterFlowTheme.of(context).warning, + ): item['VTA_FIXA'] == false + ? FlutterFlowTheme.of(context).success + : FlutterFlowTheme.of(context).warning, }) ], ); diff --git a/lib/shared/constants/index.dart b/lib/shared/constants/index.dart index e69de29b..8b137891 100644 --- a/lib/shared/constants/index.dart +++ b/lib/shared/constants/index.dart @@ -0,0 +1 @@ + diff --git a/lib/shared/extensions/string_extensions.dart b/lib/shared/extensions/string_extensions.dart index 67cf03db..43d536ba 100644 --- a/lib/shared/extensions/string_extensions.dart +++ b/lib/shared/extensions/string_extensions.dart @@ -10,7 +10,7 @@ extension StringNullableExtensions on String? { return false; } - bool get isNotNullAndEmpty { + bool get isNotNullAndEmpty { if (this == null) return false; if (this == '') return false; return true; @@ -19,7 +19,6 @@ extension StringNullableExtensions on String? { extension StringExtensions on String { bool get toBoolean { - return toLowerCase() == 'true'; } } diff --git a/lib/shared/utils/license_util.dart b/lib/shared/utils/license_util.dart index 78e8bcb8..4959f1af 100644 --- a/lib/shared/utils/license_util.dart +++ b/lib/shared/utils/license_util.dart @@ -10,7 +10,8 @@ class LicenseUtil { final expirationDate = moduleMap['expirationDate'] ?? ''; final isStarted = await DateTimeUtil.processStartDate(startDate); final isExpired = await DateTimeUtil.processExpirationDate(expirationDate); - if (isStarted && !isExpired) return EnumDisplay.fromString(moduleMap["display"]) == EnumDisplay.active; + if (isStarted && !isExpired) + return EnumDisplay.fromString(moduleMap["display"]) == EnumDisplay.active; if (isExpired) return false; return false; } From 56cb5427a2712bda7d25ac7cda32729d435c4183 Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Mon, 3 Feb 2025 16:41:59 -0300 Subject: [PATCH 15/47] test --- integration_test/app_test.dart | 19 +- integration_test/vehicle_test.dart | 229 +++++++++++++----- .../backend/api_requests/api_calls.dart | 2 +- .../vehicle_model.dart | 4 +- 4 files changed, 181 insertions(+), 73 deletions(-) diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index 618ea42a..66966f1f 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -7,6 +7,7 @@ import 'package:firebase_crashlytics/firebase_crashlytics.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; +import 'package:hub/components/atomic_components/shared_components_atoms/submit_button.dart'; import 'package:hub/components/molecular_components/throw_exception/throw_exception_widget.dart'; import 'package:hub/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart'; import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart'; @@ -71,26 +72,26 @@ void main() { // setUp(() async {}); // tearDown(() async {}); - WelcomeTest.signInToSignUp(); - WelcomeTest.signUpToSignIn(); + // WelcomeTest.signInToSignUp(); + // WelcomeTest.signUpToSignIn(); // AuthenticationTest.signIn(); // AuthenticationTest.signUp(); // AuthenticationTest.signOut(); // AuthenticationTest.recovery(); - ModularizationTest.switchLicense(); - ModularizationTest.containLicense(); + // ModularizationTest.switchLicense(); + // ModularizationTest.containLicense(); - MenuTest.navToEntries(); - MenuTest.containEntries(); - MenuTest.labels2AppbarConsistency(); + // MenuTest.navToEntries(); + // MenuTest.containEntries(); + // MenuTest.labels2AppbarConsistency(); // LocalsTest.setLocal(); // LocalsTest.unlinkLocal(); - VehicleTest.vehiclePage(); + // VehicleTest.vehiclePage(); // VehicleTest.historyScreen(); - // VehicleTest.registerScreen(); + VehicleTest.registerScreen(); // VehicleTest.updateScreen(); } diff --git a/integration_test/vehicle_test.dart b/integration_test/vehicle_test.dart index 25796085..c3c5c0fb 100644 --- a/integration_test/vehicle_test.dart +++ b/integration_test/vehicle_test.dart @@ -1,6 +1,25 @@ part of 'app_test.dart'; class VehicleTest { + static Future _initVehicleModule() async { + final vehicleParam = { + 'display': 'VISIVEL', + 'expirationDate': '', + 'startDate': '', + 'quantity': 0, + }; + final vehicleManagerParam = { + 'display': 'VISIVEL', + 'expirationDate': '', + 'startDate': '', + 'quantity': 0, + }; + await LicenseRepositoryImpl() + .setModule(LicenseKeys.vehicles.value, vehicleParam); + await LicenseRepositoryImpl() + .setModule(LicenseKeys.vehiclesManager.value, vehicleManagerParam); + } + static Future vehiclePage() async { patrolWidgetTest( 'Vehicle Page', @@ -10,6 +29,8 @@ class VehicleTest { final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget); await _loggedWithMultiLocalsAccount(); + await _initVehicleModule(); + await $.pumpAndSettle(); await $.pumpWidgetAndSettle(const App()); ff.navigatorKey.currentContext!.go('/vehiclesOnThePropertyPage'); @@ -49,25 +70,26 @@ class VehicleTest { final int entriesCount = entriesFinder.evaluate().length; await $.pumpAndSettle(); - for (int i = 0; i < entriesCount; i++) { - await $(entriesFinder.at(i)).scrollTo(); + if (entriesCount > 0) + for (int i = 0; i < entriesCount; i++) { + await $(entriesFinder.at(i)).scrollTo(); - await $(entriesFinder.at(i)) - .waitUntilVisible(timeout: const Duration(seconds: 1)) - .tap( - settleTimeout: const Duration(seconds: 1), - settlePolicy: SettlePolicy.noSettle, - ); + await $(entriesFinder.at(i)) + .waitUntilVisible(timeout: const Duration(seconds: 1)) + .tap( + settleTimeout: const Duration(seconds: 1), + settlePolicy: SettlePolicy.noSettle, + ); - await $.pumpAndSettle(duration: Duration(milliseconds: 500)); - final PatrolFinder detailsFinder = - await $(DetailsComponentWidget).waitUntilVisible(); - expect(detailsFinder, findsOneWidget); + await $.pumpAndSettle(duration: Duration(milliseconds: 500)); + final PatrolFinder detailsFinder = + await $(DetailsComponentWidget).waitUntilVisible(); + expect(detailsFinder, findsOneWidget); - await _navigateBackUsingSystemGesture(); + await _navigateBackUsingSystemGesture(); - // await $.native.pressBack().then((_) => $.pumpAndSettle()); - } + // await $.native.pressBack().then((_) => $.pumpAndSettle()); + } }, ); patrolWidgetTest( @@ -77,29 +99,9 @@ class VehicleTest { $.tester.printToConsole('Vehicle Page'); await _loggedWithMultiLocalsAccount(); + await _initVehicleModule(); + await $.pumpAndSettle(); - // await StorageHelper().set( - // LicenseKeys.vehiclesManager.value, - // { - // 'display': 'VISIVEL', - // 'expirationDate': '', - // 'startDate': '', - // 'quantity': 0, - // }, - // ); - // // await $.pumpAndSettle(); - // ff.navigatorKey.currentContext!.go('/vehiclesOnThePropertyPage'); - // await Future.delayed(const Duration(milliseconds: 1000)); - - await StorageHelper().set( - LicenseKeys.vehiclesManager.value, - { - 'display': 'VISIVEL', - 'expirationDate': '', - 'startDate': '', - 'quantity': 0, - }, - ); await $.pumpWidgetAndSettle(const App()); ff.navigatorKey.currentContext!.go('/vehiclesOnThePropertyPage'); @@ -150,6 +152,8 @@ class VehicleTest { final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget); await _loggedWithMultiLocalsAccount(); + await _initVehicleModule(); + await $.pumpAndSettle(); await $.pumpWidgetAndSettle(const App()); ff.navigatorKey.currentContext!.go('/vehiclesOnThePropertyPage'); @@ -166,11 +170,116 @@ class VehicleTest { .waitUntilVisible(); expect(titleAppBar, findsOneWidget); + final PatrolFinder listViewFinder = await $(VehicleHistoryScreen) // + .$(ListView) + .waitUntilVisible(); + + expect(listViewFinder, findsOneWidget); + + final PatrolFinder entriesFinder = await $(listViewFinder) + .$(CardItemTemplateComponentWidget) + .waitUntilVisible(); + + expect(entriesFinder, findsWidgets); + await $.pumpAndSettle(); + await $(entriesFinder.first) + .waitUntilVisible(timeout: const Duration(seconds: 1)) + .tap( + settleTimeout: const Duration(seconds: 1), + settlePolicy: SettlePolicy.noSettle, + ); + + await $.pumpAndSettle(duration: Duration(milliseconds: 500)); + final PatrolFinder detailsFinder = + await $(DetailsComponentWidget).waitUntilVisible(); + expect(detailsFinder, findsOneWidget); + + await _navigateBackUsingSystemGesture(); + + /// Iterable Test + // final int entriesCount = entriesFinder.evaluate().length; + // for (int i = 0; i < entriesCount; i++) { + // // await $(entriesFinder.at(i)).scrollTo(); + + // await $(entriesFinder.at(i)) + // .waitUntilVisible(timeout: const Duration(seconds: 1)) + // .tap( + // settleTimeout: const Duration(seconds: 1), + // settlePolicy: SettlePolicy.noSettle, + // ); + + // await $.pumpAndSettle(duration: Duration(milliseconds: 500)); + // final PatrolFinder detailsFinder = + // await $(DetailsComponentWidget).waitUntilVisible(); + // expect(detailsFinder, findsOneWidget); + + // await _navigateBackUsingSystemGesture(); + + // // await $.native.pressBack().then((_) => $.pumpAndSettle()); + // } + }, + ); + } + + static Future registerScreen() async { + patrolWidgetTest( + 'registerScreen', + (PatrolTester tester) async { + $ = tester; + $.tester.printToConsole('Vehicle Register Page'); + + await _loggedWithMultiLocalsAccount(); + await _initVehicleModule(); + await $.pumpAndSettle(); + await $.pumpWidgetAndSettle(const App()); + + ff.navigatorKey.currentContext!.go('/vehiclesOnThePropertyPage'); + final PatrolFinder tab2 = await $(#TabView_Tab2) // .waitUntilExists(); await tab2.tap(); + final PatrolFinder licensePlateField = + await $(TextField).at(0).waitUntilVisible(); + final PatrolFinder modelField = + await $(TextField).at(1).waitUntilVisible(); + final PatrolFinder colorField = + await $(TextField).at(2).waitUntilVisible(); + final PatrolFinder submitButton = + await $(SubmitButtonUtil).waitUntilVisible(); + + await licensePlateField.enterText('ABC1234'); + await modelField.enterText('Voyage'); + await colorField.enterText('Black'); + await submitButton.tap(); + + await $.pumpAndSettle(); + final PatrolFinder successDialog = await $(Dialog).waitUntilVisible(); + expect(successDialog, findsOneWidget); + }, + ); + } + + static Future updateScreen() async { + patrolWidgetTest( + 'updateScreen', + (PatrolTester tester) async { + $ = tester; + $.tester.printToConsole('Vehicle Update Page'); + + await _loggedWithMultiLocalsAccount(); + await _initVehicleModule(); + await $.pumpAndSettle(); + await $.pumpWidgetAndSettle(const App()); + + ff.navigatorKey.currentContext!.go('/vehiclesOnThePropertyPage'); + + final PatrolFinder tab1 = await $(#TabView_Tab1) // + .waitUntilExists(); + + await tab1.tap(); + final PatrolFinder listViewFinder = await $(VehicleHistoryScreen) // .$(ListView) .waitUntilVisible(); @@ -182,32 +291,30 @@ class VehicleTest { .waitUntilVisible(); expect(entriesFinder, findsWidgets); - final int entriesCount = entriesFinder.evaluate().length; + await $(entriesFinder.at(0)).tap(); + + final PatrolFinder editButton = + await $(FFButtonWidget).$('Edit').waitUntilVisible(); + await editButton.tap(); + + final PatrolFinder licensePlateField = + await $(TextField).at(0).waitUntilVisible(); + final PatrolFinder modelField = + await $(TextField).at(1).waitUntilVisible(); + final PatrolFinder colorField = + await $(TextField).at(2).waitUntilVisible(); + final PatrolFinder submitButton = + await $(SubmitButtonUtil).waitUntilVisible(); + + await licensePlateField.enterText('XYZ5678'); + await modelField.enterText('Fiesta'); + await colorField.enterText('Red'); + await submitButton.tap(); + await $.pumpAndSettle(); - - for (int i = 0; i < entriesCount; i++) { - await $(entriesFinder.at(i)).scrollTo(); - - await $(entriesFinder.at(i)) - .waitUntilVisible(timeout: const Duration(seconds: 1)) - .tap( - settleTimeout: const Duration(seconds: 1), - settlePolicy: SettlePolicy.noSettle, - ); - - await $.pumpAndSettle(duration: Duration(milliseconds: 500)); - final PatrolFinder detailsFinder = - await $(DetailsComponentWidget).waitUntilVisible(); - expect(detailsFinder, findsOneWidget); - - await _navigateBackUsingSystemGesture(); - - // await $.native.pressBack().then((_) => $.pumpAndSettle()); - } + final PatrolFinder successDialog = await $(Dialog).waitUntilVisible(); + expect(successDialog, findsOneWidget); }, ); } - - static Future registerScreen() async {} - static Future updateScreen() async {} } diff --git a/lib/features/backend/api_requests/api_calls.dart b/lib/features/backend/api_requests/api_calls.dart index 44d4b7d7..75315b27 100644 --- a/lib/features/backend/api_requests/api_calls.dart +++ b/lib/features/backend/api_requests/api_calls.dart @@ -206,7 +206,7 @@ class RegisterVehicle { class UpdateVehicle { Future call({ - final String? vehicleId, + required final int vehicleId, final String? licensePlate, final String? color, final String? model, diff --git a/lib/pages/vehicles_on_the_property/vehicle_model.dart b/lib/pages/vehicles_on_the_property/vehicle_model.dart index 91afb7fe..079d9c92 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_model.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_model.dart @@ -82,10 +82,9 @@ class VehicleModel extends FlutterFlowModel /// [_BaseVehiclePage] is a mixin that contains the base logic of the vehicle page. mixin class _BaseVehiclePage { int count = 0; - late final VehicleModel model; late final TabController tabBarController; // dynamic item; - String? vehicleId; + late int vehicleId; BuildContext context = navigatorKey.currentContext!; bool isEditing = false; ApiCallResponse? vehicleResponse; @@ -161,6 +160,7 @@ mixin class _BaseVehiclePage { Future setEditForm(dynamic item) async { if (item != null) { + log('vehicleId: ${item['vehicleId']}'); vehicleId = item['vehicleId']; From 61e3effa597f5edf95a0b9bd789a85fcc28501e6 Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Mon, 3 Feb 2025 16:47:38 -0300 Subject: [PATCH 16/47] format --- lib/pages/vehicles_on_the_property/vehicle_model.dart | 5 +---- .../vehicles_on_the_property/vehicle_register_screen.dart | 3 ++- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/lib/pages/vehicles_on_the_property/vehicle_model.dart b/lib/pages/vehicles_on_the_property/vehicle_model.dart index 079d9c92..0e63ee31 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_model.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_model.dart @@ -73,7 +73,7 @@ class VehicleModel extends FlutterFlowModel await StorageHelper().get(LocalsStorageKey.vehicleAmountRegister.key); } - bool isFormValid(BuildContext context, GlobalKey formKey) { + bool isFormValid(BuildContext context, GlobalKey formKey) { if (formKey.currentState == null) return false; return formKey.currentState!.validate(); } @@ -163,7 +163,6 @@ mixin class _BaseVehiclePage { log('vehicleId: ${item['vehicleId']}'); vehicleId = item['vehicleId']; - textFieldControllerLicensePlate = TextEditingController( text: item != null ? item['licensePlate'] ?? '' : ''); textFieldControllerColor = @@ -320,10 +319,8 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { context.pop(); isEditing = true; - await switchTab(1); await setEditForm(item); - } final cancelText = FFLocalizations.of(context) diff --git a/lib/pages/vehicles_on_the_property/vehicle_register_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_register_screen.dart index 815b9b72..b11e0db7 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_register_screen.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_register_screen.dart @@ -72,7 +72,8 @@ class _VehicleRegisterScreenState extends State { child: SubmitButtonUtil( labelText: FFLocalizations.of(context) .getVariableText(ptText: 'Cadastrar', enText: 'Register'), - onPressed: widget.model.isFormValid(context, widget.model.registerFormKey) + onPressed: widget.model + .isFormValid(context, widget.model.registerFormKey) ? widget.model.registerVehicle : null, ), From 8e035e00aaac6b51d5a2935cd4206f5fcbbc53c7 Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Mon, 3 Feb 2025 16:51:02 -0300 Subject: [PATCH 17/47] WIP --- .../shared_components_atoms/media_upload_button.dart | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/components/atomic_components/shared_components_atoms/media_upload_button.dart b/lib/components/atomic_components/shared_components_atoms/media_upload_button.dart index c2424e70..ec1c5af3 100644 --- a/lib/components/atomic_components/shared_components_atoms/media_upload_button.dart +++ b/lib/components/atomic_components/shared_components_atoms/media_upload_button.dart @@ -33,7 +33,7 @@ class _MediaUploadButtonUtilState extends State { @override Widget build(BuildContext context) { double limitedInputTextSize = LimitedFontSizeUtil.getInputFontSize(context); - bool isLoading = false; + bool _isLoading = false; return Builder( builder: (context) { @@ -72,7 +72,7 @@ class _MediaUploadButtonUtilState extends State { child: GestureDetector( onTap: () async { setState(() { - isLoading = true; + _isLoading = true; }); final selectedMedia = await selectMediaWithSourceBottomSheet( @@ -120,7 +120,7 @@ class _MediaUploadButtonUtilState extends State { showUploadMessage(context, message); } else { setState(() { - isLoading = false; + _isLoading = false; }); final message = FFLocalizations.of(context) .getVariableText( @@ -131,7 +131,7 @@ class _MediaUploadButtonUtilState extends State { } } else { setState(() { - isLoading = false; + _isLoading = false; }); } }, @@ -150,7 +150,7 @@ class _MediaUploadButtonUtilState extends State { mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, children: [ - isLoading + _isLoading ? SizedBox( width: 30.0, height: 30.0, From 2e22045eeab47ea450158f766ae660a0a618452d Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Tue, 4 Feb 2025 10:17:31 -0300 Subject: [PATCH 18/47] hotfix's miscs --- .../backend/api_requests/api_calls.dart | 6 +++--- .../vehicle_history_screen.dart | 20 +++++-------------- .../vehicle_model.dart | 4 ++-- 3 files changed, 10 insertions(+), 20 deletions(-) diff --git a/lib/features/backend/api_requests/api_calls.dart b/lib/features/backend/api_requests/api_calls.dart index 75315b27..fd77fd3c 100644 --- a/lib/features/backend/api_requests/api_calls.dart +++ b/lib/features/backend/api_requests/api_calls.dart @@ -72,10 +72,10 @@ class PhpGroup extends Api { static RegisterVehicle registerVehicle = RegisterVehicle(); static UpdateVehicle updateVehicle = UpdateVehicle(); static DeleteVehicle deleteVehicle = DeleteVehicle(); - static CancelVehicle cancelVehicle = CancelVehicle(); + static CancelDeleteVehicle cancelDelete = CancelDeleteVehicle(); } -class CancelVehicle { +class CancelDeleteVehicle { Future call({ required final int vehicleId, required final String licensePlate, @@ -89,7 +89,7 @@ class CancelVehicle { (await StorageHelper().get(ProfileStorageKey.userUUID.key)) ?? ''; final String cliID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? ''; - const String atividade = 'cancelDeleteRequest'; + const String atividade = 'cancelDeleteVehicleRequest'; return await ApiManager.instance.makeApiCall( callName: atividade, diff --git a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart index e8bd53d4..5db71bf6 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart @@ -202,22 +202,12 @@ mixin _FetchingMixin on State { } void _showNoMoreDataSnackBar(BuildContext context) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - FFLocalizations.of(context).getVariableText( - ptText: "Não há mais dados.", - enText: "No more data.", - ), - style: TextStyle( - color: Colors.white, - fontSize: LimitedFontSizeUtil.getBodyFontSize(context), - ), - ), - duration: const Duration(seconds: 3), - backgroundColor: FlutterFlowTheme.of(context).primary, - ), + final message = FFLocalizations.of(context).getVariableText( + ptText: "Não há mais dados.", + enText: "No more data.", ); + + showSnackbar(context, message, true); } } diff --git a/lib/pages/vehicles_on_the_property/vehicle_model.dart b/lib/pages/vehicles_on_the_property/vehicle_model.dart index 0e63ee31..0adfe490 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_model.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_model.dart @@ -286,7 +286,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { }; if (!isDetail && isOwner && (status != 'ATI' && status != 'INA')) { - statusMap[byLanguage('My Vehicle', 'Meu Veículo')] = theme.primaryText; + statusMap[byLanguage('My Vehicle', 'Meu Veículo')] = theme.accent4; } return statusMap; @@ -517,7 +517,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { } Future processCancelCreateRequest(dynamic item) async { - return await PhpGroup.deleteVehicle.call( + return await PhpGroup.cancelDelete.call( vehicleId: item['vehicleId'], licensePlate: item['licensePlate'], model: item['model'], From b2df549066cfa10b27177aaa6721a4fbf0019826 Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Tue, 4 Feb 2025 10:48:37 -0300 Subject: [PATCH 19/47] finnish --- .../vehicle_history_screen.dart | 63 +++++++++++-------- .../vehicle_model.dart | 12 ++-- 2 files changed, 45 insertions(+), 30 deletions(-) diff --git a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart index 5db71bf6..773c4756 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart @@ -77,34 +77,44 @@ class _VehicleHistoryScreenState extends State child: FutureBuilder( future: widget._future, builder: (context, snapshot) { - return ListView.builder( - shrinkWrap: true, - physics: const BouncingScrollPhysics(), - controller: _scrollController, - itemCount: widget._wrap.length + 1, - itemBuilder: (context, index) { - if (index == 0) { - return _buildHeader(context, limitedBodyTextSize); - } else { - Map item = widget._wrap[index - 1]; - return FutureBuilder( - future: _item(context, item), - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.done) { - return snapshot.data ?? Container(); - } else { - return Center(child: CircularProgressIndicator()); - } - }, - ); - } - }, - ); + if (snapshot.connectionState == ConnectionState.waiting) { + return Center(child: CircularProgressIndicator()); + } else if (snapshot.hasError) { + return Center(child: Text('Error: ${snapshot.error}')); + } else { + return ListView.builder( + shrinkWrap: true, + physics: const BouncingScrollPhysics(), + controller: _scrollController, + itemCount: widget._wrap.length + 1, + itemBuilder: (context, index) { + if (index == 0) { + return _buildHeader(context, limitedBodyTextSize); + } else { + Map item = widget._wrap[index - 1]; + return _buildVehicleItem(context, item); + } + }, + ); + } }, ), ); } + Widget _buildVehicleItem(BuildContext context, Map item) { + return FutureBuilder( + future: _item(context, item), + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.done) { + return snapshot.data ?? Container(); + } else { + return Center(child: CircularProgressIndicator()); + } + }, + ); + } + Widget _buildHeader(BuildContext context, double limitedBodyTextSize) { log('amountRegister: ${widget.model.amountRegister}'); return Padding( @@ -215,8 +225,11 @@ mixin _FetchingMixin on State { mixin _CardItemMixin on _FetchingMixin { Future _item(BuildContext context, Map uItem) async { final bool? isOwner = uItem['isOwnerVehicle']; - final IconData iconData = - isOwner == true ? Symbols.no_crash : Symbols.directions_car; + final IconData? iconData = isOwner == null + ? null + : isOwner == true + ? Symbols.no_crash + : Symbols.directions_car; final FreCardIcon? cardIcon = isOwner != null ? FreCardIcon( height: 50, diff --git a/lib/pages/vehicles_on_the_property/vehicle_model.dart b/lib/pages/vehicles_on_the_property/vehicle_model.dart index 0adfe490..800b8c4a 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_model.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_model.dart @@ -237,15 +237,19 @@ mixin _VehicleUpdateScreenModel on _BaseVehiclePage { /// [_VehicleHistoryScreenModel] is a mixin that contains the business logic of the vehicle history page. mixin _VehicleHistoryScreenModel on _BaseVehiclePage { - Future?> generateStatusColorMap( + Future?>? generateStatusColorMap( dynamic uItem, bool isDetail) async { final autoApproval = await StorageHelper().get(LocalsStorageKey.vehicleAutoApproval.key); if (autoApproval.toBoolean == true) return null; - final theme = FlutterFlowTheme.of(context); final localization = FFLocalizations.of(context); + final status = uItem['status']; + final isOwner = uItem['isOwnerVehicle']; + + if (isOwner == null && status == null) return null; + String byLanguage(String en, String pt) => localization.getVariableText(enText: en, ptText: pt); @@ -276,9 +280,6 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { }, }; - final status = uItem['status']; - final isOwner = uItem['isOwnerVehicle']; - if (vehicleStatusMap.containsKey(status)) { final statusMap = { vehicleStatusMap[status]!['text'] as String: @@ -311,6 +312,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { width: 1, ), ); + if (item['status'] == null) return []; final updateText = FFLocalizations.of(context) .getVariableText(ptText: 'Editar', enText: 'Edit'); From 16f43bbab8d4d866def321e0bdc3f8c0c538a4ae Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Thu, 6 Feb 2025 18:01:47 -0300 Subject: [PATCH 20/47] WIP - paginacao --- .../vehicle_history_screen.dart | 195 ++++++++---------- 1 file changed, 91 insertions(+), 104 deletions(-) diff --git a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart index 773c4756..e20e6e36 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart @@ -6,24 +6,19 @@ part of 'vehicles_on_the_property.dart'; class VehicleHistoryScreen extends StatefulWidget { VehicleHistoryScreen(this.model, {super.key}); late VehicleModel model; - late Future _future; - List _wrap = []; - int _pageNumber = 1; - bool _hasData = false; - bool _loading = false; - int count = 0; + @override State createState() => _VehicleHistoryScreenState(); } class _VehicleHistoryScreenState extends State - with _FetchingMixin, _ScrollControllerMixin, _CardItemMixin { + with Remotable { @override void initState() { super.initState(); _initializeScrollController(); - widget._future = _fetch(); + _future = _fetch(); } @override @@ -37,13 +32,13 @@ class _VehicleHistoryScreenState extends State mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.start, children: [ - if (widget._hasData == false && - widget._pageNumber <= 1 && - widget._loading == false) + if (_hasData == false && + _pageNumber <= 1 && + _loading == false) _buildNoDataFound(context, limitedHeaderTextSize) - else if (widget._hasData == true || widget._pageNumber >= 1) - _buildVehicleList(context, limitedBodyTextSize), - if (widget._hasData == true && widget._loading == true) + else if (_hasData == true || _pageNumber >= 1) + _buildHistoryList(context, limitedBodyTextSize), + if (_hasData == true && _loading == true) _buildLoadingIndicator(context), ].addToStart(const SizedBox(height: 0)), ); @@ -72,10 +67,10 @@ class _VehicleHistoryScreenState extends State ); } - Widget _buildVehicleList(BuildContext context, double limitedBodyTextSize) { + Widget _buildHistoryList(BuildContext context, double limitedBodyTextSize) { return Expanded( - child: FutureBuilder( - future: widget._future, + child: FutureBuilder>( + future: _future, builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return Center(child: CircularProgressIndicator()); @@ -86,13 +81,13 @@ class _VehicleHistoryScreenState extends State shrinkWrap: true, physics: const BouncingScrollPhysics(), controller: _scrollController, - itemCount: widget._wrap.length + 1, + itemCount: _wrap.length + 1, itemBuilder: (context, index) { if (index == 0) { return _buildHeader(context, limitedBodyTextSize); } else { - Map item = widget._wrap[index - 1]; - return _buildVehicleItem(context, item); + Widget? item = _wrap[index - 1]; + return _wrap[index - 1] ?? SizedBox.shrink(); } }, ); @@ -102,19 +97,6 @@ class _VehicleHistoryScreenState extends State ); } - Widget _buildVehicleItem(BuildContext context, Map item) { - return FutureBuilder( - future: _item(context, item), - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.done) { - return snapshot.data ?? Container(); - } else { - return Center(child: CircularProgressIndicator()); - } - }, - ); - } - Widget _buildHeader(BuildContext context, double limitedBodyTextSize) { log('amountRegister: ${widget.model.amountRegister}'); return Padding( @@ -147,48 +129,36 @@ class _VehicleHistoryScreenState extends State } } -// Mixin for Scroll Controller -mixin _ScrollControllerMixin on _FetchingMixin { - late ScrollController _scrollController; - - void _initializeScrollController() { - _scrollController = ScrollController() - ..addListener(() { - if (_scrollController.position.atEdge && - _scrollController.position.pixels != 0) { - _loadMore(); - } - }); - } - - void _loadMore() { - if (widget._hasData == true) { - widget._pageNumber++; - widget._future = _fetch(); - } - } -} // Mixin for Fetch Visits -mixin _FetchingMixin on State { - Future _fetch() async { +mixin Remotable on State { + late Future> _future; + List _wrap = []; + int _pageNumber = 1; + bool _hasData = true; + bool _loading = true; + int count = 0; + + + Future> _fetch() async { + if (!widget._hasData || !widget._loading) return []; + + setState(() => widget._loading = true); + try { - setState(() => widget._loading = true); - - var response = await PhpGroup.getVehiclesByProperty - .call(widget._pageNumber.toString()); - - final List vehicles = response.jsonBody['vehicles'] ?? []; + var response = await PhpGroup.getVehiclesByProperty.call(widget._pageNumber.toString()); + final List vehicles = response.jsonBody['vehicles'] as List? ?? []; safeSetState(() => widget.count = response.jsonBody['total_rows'] ?? 0); if (vehicles.isNotEmpty) { setState(() { - widget._wrap.addAll(vehicles); + widget._hasData = true; widget._loading = false; }); - return response; + + return _generateItems(context, vehicles); } _showNoMoreDataSnackBar(context); @@ -198,17 +168,16 @@ mixin _FetchingMixin on State { widget._loading = false; }); - return null; + return []; } catch (e, s) { DialogUtil.errorDefault(context); - LogUtil.requestAPIFailed( - "proccessRequest.php", "", "Consulta de Veículo", e, s); + LogUtil.requestAPIFailed("proccessRequest.php", "", "Consulta de Veículo", e, s); setState(() { widget._hasData = false; widget._loading = false; }); + return []; } - return null; } void _showNoMoreDataSnackBar(BuildContext context) { @@ -219,47 +188,43 @@ mixin _FetchingMixin on State { showSnackbar(context, message, true); } -} -// Mixin for Card Item -mixin _CardItemMixin on _FetchingMixin { - Future _item(BuildContext context, Map uItem) async { - final bool? isOwner = uItem['isOwnerVehicle']; - final IconData? iconData = isOwner == null - ? null - : isOwner == true - ? Symbols.no_crash - : Symbols.directions_car; - final FreCardIcon? cardIcon = isOwner != null - ? FreCardIcon( - height: 50, - width: 100, - icon: Icon(iconData, size: 80, opticalSize: 10)) - : null; + Future> _generateItems(BuildContext context, List uItem) async { + if (!widget._hasData) return []; - final String? tag = uItem['tag']; - final bool containTag = tag.isNotNullAndEmpty; - final Map labelsHashMap = - _generateLabelsHashMap(context, uItem, tag, containTag); + List items = []; - final statusHashMapList = await _generateStatusHashMapList(uItem); + for (var uItem in uItem) { + final bool? isOwner = uItem['isOwnerVehicle']; + final IconData? iconData = isOwner == true ? Symbols.no_crash : Symbols.directions_car; + final FreCardIcon? cardIcon = isOwner != null + ? FreCardIcon(height: 50, width: 100, icon: Icon(iconData, size: 80, opticalSize: 10)) + : null; - Future onTapCardItemAction() async { - await _handleCardItemTap(context, cardIcon, uItem); + final String? tag = uItem['tag']; + final bool containTag = tag.isNotNullAndEmpty; + final Map labelsHashMap = _generateLabelsHashMap(context, uItem, tag, containTag); + + final statusHashMapList = await _generateStatusHashMapList(uItem); + + Future onTapCardItemAction() async { + await _handleCardItemTap(context, cardIcon, uItem); + } + + final statusLinkedHashMap = statusHashMapList.map((map) => LinkedHashMap.from(map)).toList(); + final length = statusLinkedHashMap.expand((e) => [e.length]); + + items.add(CardItemTemplateComponentWidget( + icon: cardIcon, + labelsHashMap: labelsHashMap, + statusHashMap: statusHashMapList, + onTapCardItemAction: onTapCardItemAction, + itemWidthFactor: length == 1 ? 0.25 : 0.50, + )); } - - final statusLinkedHashMap = statusHashMapList - .map((map) => LinkedHashMap.from(map)) - .toList(); - final length = statusLinkedHashMap.expand((e) => [e.length]); - - return CardItemTemplateComponentWidget( - icon: cardIcon, - labelsHashMap: labelsHashMap, - statusHashMap: statusHashMapList, - onTapCardItemAction: onTapCardItemAction, - itemWidthFactor: length == 1 ? 0.25 : 0.50, - ); + + widget._wrap.addAll(items); + return items; } Map _generateLabelsHashMap(BuildContext context, @@ -316,4 +281,26 @@ mixin _CardItemMixin on _FetchingMixin { }); } } + + late ScrollController _scrollController; + + void _initializeScrollController() { + _scrollController = ScrollController() + ..addListener(() { + print('ScrollController'); + if(!widget._hasData) return; + if (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent) { + print('ScrollController -> loadMore'); + _loadMore(); + } + }); + } + + void _loadMore() { + if (widget._hasData) { + widget._pageNumber++; + widget._loading = true; + widget._future = _fetch(); + } + } } From 906fbcaf24275b74522520f4cee795b1318ed1c4 Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Fri, 7 Feb 2025 16:50:45 -0300 Subject: [PATCH 21/47] WIP --- .../pages/acess_history_page_widget.dart | 1 + .../vehicle_history_screen.dart | 181 +++++++++--------- .../vehicle_model.dart | 37 ++-- scripts/httpie.sh | 30 +++ 4 files changed, 141 insertions(+), 108 deletions(-) create mode 100755 scripts/httpie.sh diff --git a/lib/features/history/presentation/pages/acess_history_page_widget.dart b/lib/features/history/presentation/pages/acess_history_page_widget.dart index 16708425..b855ec30 100644 --- a/lib/features/history/presentation/pages/acess_history_page_widget.dart +++ b/lib/features/history/presentation/pages/acess_history_page_widget.dart @@ -52,6 +52,7 @@ class _AccessHistoryState extends State { _model = createModel(context, () => AcessHistoryPageModel()); _accessFuture = fetchAccessHistoryService(); + _scrollController = ScrollController() ..addListener(() { if (_scrollController.position.atEdge && diff --git a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart index e20e6e36..f6878016 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart @@ -4,21 +4,24 @@ part of 'vehicles_on_the_property.dart'; // ignore: must_be_immutable class VehicleHistoryScreen extends StatefulWidget { + VehicleHistoryScreen(this.model, {super.key}); late VehicleModel model; - @override State createState() => _VehicleHistoryScreenState(); + } class _VehicleHistoryScreenState extends State with Remotable { + + + @override void initState() { super.initState(); _initializeScrollController(); - _future = _fetch(); } @override @@ -69,8 +72,8 @@ class _VehicleHistoryScreenState extends State Widget _buildHistoryList(BuildContext context, double limitedBodyTextSize) { return Expanded( - child: FutureBuilder>( - future: _future, + child: FutureBuilder>( + future: _fetch(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { return Center(child: CircularProgressIndicator()); @@ -79,17 +82,13 @@ class _VehicleHistoryScreenState extends State } else { return ListView.builder( shrinkWrap: true, + addAutomaticKeepAlives: true, + restorationId: '', physics: const BouncingScrollPhysics(), controller: _scrollController, - itemCount: _wrap.length + 1, - itemBuilder: (context, index) { - if (index == 0) { - return _buildHeader(context, limitedBodyTextSize); - } else { - Widget? item = _wrap[index - 1]; - return _wrap[index - 1] ?? SizedBox.shrink(); - } - }, + itemCount: snapshot.data!.length , + itemBuilder: (context, index) => _generateItems(context, snapshot.data![index], index), + ); } }, @@ -97,24 +96,6 @@ class _VehicleHistoryScreenState extends State ); } - Widget _buildHeader(BuildContext context, double limitedBodyTextSize) { - log('amountRegister: ${widget.model.amountRegister}'); - return Padding( - padding: const EdgeInsets.only(right: 30, top: 10), - child: Text( - (widget.model.amountRegister == '0' || - widget.model.amountRegister == null) - ? '' - : "${FFLocalizations.of(context).getVariableText(ptText: "Quantidade de Veículos: ", enText: "Amount of Vehicles: ")}${widget.model.amountRegister}/${widget.count}", - textAlign: TextAlign.right, - style: TextStyle( - fontFamily: 'Nunito', - fontSize: limitedBodyTextSize, - ), - ), - ); - } - Widget _buildLoadingIndicator(BuildContext context) { return Container( padding: const EdgeInsets.only(top: 15, bottom: 15), @@ -127,56 +108,59 @@ class _VehicleHistoryScreenState extends State ), ); } + + + } -// Mixin for Fetch Visits mixin Remotable on State { - late Future> _future; - List _wrap = []; + + late ScrollController _scrollController; + double offset = 0.0; + List _wrap = []; int _pageNumber = 1; bool _hasData = true; bool _loading = true; int count = 0; - - Future> _fetch() async { - if (!widget._hasData || !widget._loading) return []; - - setState(() => widget._loading = true); - + Future> _fetch() async { + if (!_hasData || !_loading) return _wrap; + print('hasHasData'); + setState(() => _loading = true); try { - var response = await PhpGroup.getVehiclesByProperty.call(widget._pageNumber.toString()); - final List vehicles = response.jsonBody['vehicles'] as List? ?? []; - safeSetState(() => widget.count = response.jsonBody['total_rows'] ?? 0); + var response = await PhpGroup.getVehiclesByProperty.call(_pageNumber.toString()); + final List vehicles = response.jsonBody['vehicles'] as List? ?? []; + safeSetState(() => count = response.jsonBody['total_rows'] ?? 0); if (vehicles.isNotEmpty) { setState(() { - - widget._hasData = true; - widget._loading = false; + _hasData = true; + _loading = false; }); - - - return _generateItems(context, vehicles); + print('vehicles.isNotEmpty'); + _wrap.addAll(vehicles); + return _wrap; } _showNoMoreDataSnackBar(context); setState(() { - widget._hasData = false; - widget._loading = false; + _hasData = false; + _loading = false; }); - return []; + print('hasEmpty: ${_wrap.length}'); + return _wrap; } catch (e, s) { DialogUtil.errorDefault(context); LogUtil.requestAPIFailed("proccessRequest.php", "", "Consulta de Veículo", e, s); setState(() { - widget._hasData = false; - widget._loading = false; + _hasData = false; + _loading = false; }); - return []; + print('hasError'); + return _wrap; } } @@ -189,43 +173,56 @@ mixin Remotable on State { showSnackbar(context, message, true); } - Future> _generateItems(BuildContext context, List uItem) async { - if (!widget._hasData) return []; + Widget _buildHeader(BuildContext context) { + double limitedBodyTextSize = LimitedFontSizeUtil.getBodyFontSize(context); + log('amountRegister: ${widget.model.amountRegister}'); + return Padding( + padding: const EdgeInsets.only(right: 30, top: 10), + child: Text( + (widget.model.amountRegister == '0' || + widget.model.amountRegister == null) + ? '' + : "${FFLocalizations.of(context).getVariableText(ptText: "Quantidade de Veículos: ", enText: "Amount of Vehicles: ")}${widget.model.amountRegister}/$count", + textAlign: TextAlign.right, + style: TextStyle( + fontFamily: 'Nunito', + fontSize: limitedBodyTextSize, + ), + ), + ); + } - List items = []; - - for (var uItem in uItem) { - final bool? isOwner = uItem['isOwnerVehicle']; - final IconData? iconData = isOwner == true ? Symbols.no_crash : Symbols.directions_car; + Widget? _generateItems(BuildContext context, dynamic snapshot, int index) { + if (index == 0) return _buildHeader(context); + + final bool? isOwner = snapshot['isOwnerVehicle']; + final IconData? iconData = isOwner == true ? Symbols.garage : Symbols.directions_car; final FreCardIcon? cardIcon = isOwner != null ? FreCardIcon(height: 50, width: 100, icon: Icon(iconData, size: 80, opticalSize: 10)) : null; - final String? tag = uItem['tag']; + final String? tag = snapshot['tag']; final bool containTag = tag.isNotNullAndEmpty; - final Map labelsHashMap = _generateLabelsHashMap(context, uItem, tag, containTag); + final Map labelsHashMap = _generateLabelsHashMap(context, snapshot, tag, containTag); - final statusHashMapList = await _generateStatusHashMapList(uItem); + final List> statusHashMapList = _generateStatusHashMapList(snapshot); Future onTapCardItemAction() async { - await _handleCardItemTap(context, cardIcon, uItem); + _handleCardItemTap(context, cardIcon, snapshot); } final statusLinkedHashMap = statusHashMapList.map((map) => LinkedHashMap.from(map)).toList(); final length = statusLinkedHashMap.expand((e) => [e.length]); - items.add(CardItemTemplateComponentWidget( + return CardItemTemplateComponentWidget( icon: cardIcon, labelsHashMap: labelsHashMap, statusHashMap: statusHashMapList, onTapCardItemAction: onTapCardItemAction, itemWidthFactor: length == 1 ? 0.25 : 0.50, - )); + ); } - - widget._wrap.addAll(items); - return items; - } + Map _generateLabelsHashMap(BuildContext context, Map uItem, String? tag, bool containTag) { @@ -242,17 +239,17 @@ mixin Remotable on State { }; } - Future>> _generateStatusHashMapList( - Map uItem) async { + List> _generateStatusHashMapList( + Map uItem) { final statusHashMap = - await widget.model.generateStatusColorMap(uItem, false); + widget.model.generateStatusColorMap(uItem, false); return statusHashMap != null ? [statusHashMap] : []; } Future _handleCardItemTap(BuildContext context, FreCardIcon? cardIcon, Map uItem) async { try { - final dialogContent = await widget.model.buildVehicleDetails( + final dialogContent = widget.model.buildVehicleDetails( icon: cardIcon, item: uItem, context: context, @@ -266,9 +263,8 @@ mixin Remotable on State { Dialog(alignment: Alignment.center, child: dialogContent), ).whenComplete(() { safeSetState(() { - widget._pageNumber = 1; - widget._wrap = []; - widget._future = _fetch(); + _pageNumber = 1; + _fetch(); }); }); } catch (e, s) { @@ -276,31 +272,34 @@ mixin Remotable on State { LogUtil.requestAPIFailed( "proccessRequest.php", "", "Consulta de Veículos", e, s); safeSetState(() { - widget._hasData = false; - widget._loading = false; + _hasData = false; + _loading = false; }); } } - late ScrollController _scrollController; - void _initializeScrollController() { - _scrollController = ScrollController() + _scrollController = ScrollController(keepScrollOffset: true, initialScrollOffset: offset) ..addListener(() { print('ScrollController'); - if(!widget._hasData) return; - if (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent) { + if(!_hasData) return; + if + // (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent) + (_scrollController.position.atEdge && _scrollController.position.pixels != 0) + { print('ScrollController -> loadMore'); + offset = _scrollController.offset; _loadMore(); } }); } - void _loadMore() { - if (widget._hasData) { - widget._pageNumber++; - widget._loading = true; - widget._future = _fetch(); + void _loadMore() async { + if (_hasData) { + _pageNumber+=1; + _loading = true; + _fetch(); } } + } diff --git a/lib/pages/vehicles_on_the_property/vehicle_model.dart b/lib/pages/vehicles_on_the_property/vehicle_model.dart index 800b8c4a..5bee0d41 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_model.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_model.dart @@ -71,6 +71,7 @@ class VehicleModel extends FlutterFlowModel Future initAsync() async { amountRegister = await StorageHelper().get(LocalsStorageKey.vehicleAmountRegister.key); + autoApproval= await StorageHelper().get(LocalsStorageKey.vehicleAutoApproval.key); } bool isFormValid(BuildContext context, GlobalKey formKey) { @@ -89,6 +90,8 @@ mixin class _BaseVehiclePage { bool isEditing = false; ApiCallResponse? vehicleResponse; String? amountRegister = '0'; + late final String? autoApproval; + VoidCallback? onUpdateVehicle; VoidCallback? onRegisterVehicle; @@ -237,10 +240,10 @@ mixin _VehicleUpdateScreenModel on _BaseVehiclePage { /// [_VehicleHistoryScreenModel] is a mixin that contains the business logic of the vehicle history page. mixin _VehicleHistoryScreenModel on _BaseVehiclePage { - Future?>? generateStatusColorMap( - dynamic uItem, bool isDetail) async { - final autoApproval = - await StorageHelper().get(LocalsStorageKey.vehicleAutoApproval.key); + + + Map? generateStatusColorMap(dynamic uItem, bool isDetail) { + if (autoApproval.toBoolean == true) return null; final theme = FlutterFlowTheme.of(context); final localization = FFLocalizations.of(context); @@ -296,7 +299,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { return {}; } - Future?> generateActionButtons(dynamic item) async { + List generateActionButtons(dynamic item) { final Color iconButtonColor = FlutterFlowTheme.of(context).primaryText; final FFButtonOptions buttonOptions = FFButtonOptions( height: 40, @@ -339,7 +342,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { ptText: 'Você tem certeza que deseja cancelar essa solicitação?', enText: 'Are you sure you want to delete this request?', ), - () async => await processCancelRequest(item['status'], item)); + () async => processCancelRequest(item['status'], item)); } final deleteText = FFLocalizations.of(context) @@ -356,7 +359,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { ptText: 'Você tem certeza que deseja excluir esse veículo?', enText: 'Are you sure you want to delete this vehicle?', ), - () async => await processDeleteRequest(item), + () async => processDeleteRequest(item), ); } @@ -401,7 +404,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { ]; } - Future processDeleteRequest(dynamic item) async { + void processDeleteRequest(dynamic item) async { log('processDeleteRequest -> item[$item]'); return await PhpGroup.deleteVehicle .call( @@ -448,7 +451,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { }); } - Future processCancelRequest(String status, dynamic item) async { + void processCancelRequest(String status, dynamic item) async { late final ApiCallResponse value; try { switch (status) { @@ -500,7 +503,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { } } - Future processCancelDeleteRequest(dynamic item) async { + Future processCancelDeleteRequest(dynamic item) async{ return await PhpGroup.deleteVehicle.call( vehicleId: item['vehicleId'], licensePlate: item['licensePlate'], @@ -509,7 +512,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { ); } - Future processCancelUpdateRequest(dynamic item) async { + Future processCancelUpdateRequest(dynamic item) async { return await PhpGroup.deleteVehicle.call( vehicleId: item['vehicleId'], licensePlate: item['licensePlate'], @@ -527,7 +530,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { ); } - Future> generateLabelsHashMap(dynamic item) async { + Map generateLabelsHashMap(dynamic item) { return { if (item['model'] != null && item['model'] != '') '${FFLocalizations.of(context).getVariableText(ptText: "Modelo", enText: "Model")}:': @@ -547,15 +550,15 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { }; } - Future buildVehicleDetails({ + DetailsComponentWidget buildVehicleDetails({ required dynamic item, required BuildContext context, required VehicleModel model, required FreCardIcon? icon, - }) async { - final status = await generateStatusColorMap(item, true); - final buttons = await generateActionButtons(item); - final labels = await generateLabelsHashMap(item); + }) { + final status = generateStatusColorMap(item, true); + final buttons = generateActionButtons(item); + final labels = generateLabelsHashMap(item); return DetailsComponentWidget( icon: icon, buttons: buttons, diff --git a/scripts/httpie.sh b/scripts/httpie.sh new file mode 100755 index 00000000..c9e4e2dc --- /dev/null +++ b/scripts/httpie.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# Define the base URL for the API endpoint +BASE_URL="https://freaccess.com.br/freaccess/processRequest.php" + +# Define common parameters +DEV_UUID="6b7b81849c115a8a" +USER_UUID="678aa05b0c2154.50583237" +CLI_ID="7" +ACTIVITY="getVehiclesByProperty" +PAGE_SIZE="10" + +# Function to perform the HTTP request +perform_request() { + local page=$1 + http --form POST "$BASE_URL" \ + devUUID="$DEV_UUID" \ + userUUID="$USER_UUID" \ + cliID="$CLI_ID" \ + atividade="$ACTIVITY" \ + page="$page" \ + pageSize="$PAGE_SIZE" \ + --check-status \ + --ignore-stdin \ + --timeout=10 +} + +# Perform requests for pages 1 and 2 +perform_request 1 +perform_request 2 From f193baebe721166c6a6e6ce7a9c59d4d886f9f71 Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Fri, 7 Feb 2025 17:37:43 -0300 Subject: [PATCH 22/47] backup --- .../pages/acess_history_page_widget.dart | 2 + .../vehicle_history_screen.dart | 62 +++++++++++-------- 2 files changed, 38 insertions(+), 26 deletions(-) diff --git a/lib/features/history/presentation/pages/acess_history_page_widget.dart b/lib/features/history/presentation/pages/acess_history_page_widget.dart index b855ec30..bb6a8891 100644 --- a/lib/features/history/presentation/pages/acess_history_page_widget.dart +++ b/lib/features/history/presentation/pages/acess_history_page_widget.dart @@ -46,6 +46,8 @@ class _AccessHistoryState extends State { selectedTypeSubject.listen((value) {}); } + + @override void initState() { super.initState(); diff --git a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart index f6878016..a53747a3 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart @@ -7,6 +7,8 @@ class VehicleHistoryScreen extends StatefulWidget { VehicleHistoryScreen(this.model, {super.key}); late VehicleModel model; + final scaffoldKey = GlobalKey(); + final builderKey = GlobalKey(); @override State createState() => _VehicleHistoryScreenState(); @@ -17,6 +19,11 @@ class _VehicleHistoryScreenState extends State with Remotable { + @override + void dispose() { + super.dispose(); + _scrollController.dispose(); + } @override void initState() { @@ -31,19 +38,22 @@ class _VehicleHistoryScreenState extends State late final double limitedBodyTextSize = LimitedFontSizeUtil.getBodyFontSize(context); - return Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - if (_hasData == false && - _pageNumber <= 1 && - _loading == false) - _buildNoDataFound(context, limitedHeaderTextSize) - else if (_hasData == true || _pageNumber >= 1) - _buildHistoryList(context, limitedBodyTextSize), - if (_hasData == true && _loading == true) - _buildLoadingIndicator(context), - ].addToStart(const SizedBox(height: 0)), + return Scaffold( + key: widget.scaffoldKey, + body: Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + if (_hasData == false && + _pageNumber <= 1 && + _loading == false) + _buildNoDataFound(context, limitedHeaderTextSize) + else if (_hasData == true || _pageNumber >= 1) + _buildHistoryList(context, limitedBodyTextSize), + if (_hasData == true && _loading == true) + _buildLoadingIndicator(context), + ].addToStart(const SizedBox(height: 0)), + ), ); } @@ -72,7 +82,7 @@ class _VehicleHistoryScreenState extends State Widget _buildHistoryList(BuildContext context, double limitedBodyTextSize) { return Expanded( - child: FutureBuilder>( + child: FutureBuilder( future: _fetch(), builder: (context, snapshot) { if (snapshot.connectionState == ConnectionState.waiting) { @@ -86,9 +96,9 @@ class _VehicleHistoryScreenState extends State restorationId: '', physics: const BouncingScrollPhysics(), controller: _scrollController, - itemCount: snapshot.data!.length , - itemBuilder: (context, index) => _generateItems(context, snapshot.data![index], index), - + itemCount: _wrap.length, + itemBuilder: (context, index) => _generateItems(context, _wrap[index], index), + ); } }, @@ -124,8 +134,8 @@ mixin Remotable on State { bool _loading = true; int count = 0; - Future> _fetch() async { - if (!_hasData || !_loading) return _wrap; + Future _fetch() async { + if (!_hasData || !_loading) return; print('hasHasData'); setState(() => _loading = true); try { @@ -137,10 +147,10 @@ mixin Remotable on State { setState(() { _hasData = true; _loading = false; + _wrap.addAll(vehicles); }); - print('vehicles.isNotEmpty'); - _wrap.addAll(vehicles); - return _wrap; + + return; } _showNoMoreDataSnackBar(context); @@ -151,7 +161,7 @@ mixin Remotable on State { }); print('hasEmpty: ${_wrap.length}'); - return _wrap; + return; } catch (e, s) { DialogUtil.errorDefault(context); LogUtil.requestAPIFailed("proccessRequest.php", "", "Consulta de Veículo", e, s); @@ -160,7 +170,7 @@ mixin Remotable on State { _loading = false; }); print('hasError'); - return _wrap; + return; } } @@ -291,10 +301,10 @@ mixin Remotable on State { offset = _scrollController.offset; _loadMore(); } - }); + },); } - void _loadMore() async { + void _loadMore() { if (_hasData) { _pageNumber+=1; _loading = true; From 05b3a612ba65931351d60ca79c584089cc751f73 Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Mon, 10 Feb 2025 11:22:48 -0300 Subject: [PATCH 23/47] paginetedListView --- lib/core/index.dart | 1 - lib/core/meta/anotations.dart | 5 - lib/core/meta/index.dart | 1 - lib/flutter_flow/flutter_flow_util.dart | 2 + lib/initialization.dart | 5 +- .../vehicle_history_screen.dart | 250 +++++++++--------- .../vehicles_on_the_property.dart | 1 + lib/shared/index.dart | 1 - pubspec.yaml | 19 ++ 9 files changed, 156 insertions(+), 129 deletions(-) delete mode 100644 lib/core/index.dart delete mode 100644 lib/core/meta/anotations.dart delete mode 100644 lib/core/meta/index.dart delete mode 100644 lib/shared/index.dart diff --git a/lib/core/index.dart b/lib/core/index.dart deleted file mode 100644 index 8b137891..00000000 --- a/lib/core/index.dart +++ /dev/null @@ -1 +0,0 @@ - diff --git a/lib/core/meta/anotations.dart b/lib/core/meta/anotations.dart deleted file mode 100644 index 842e5064..00000000 --- a/lib/core/meta/anotations.dart +++ /dev/null @@ -1,5 +0,0 @@ -class DeadCode { - final String? desc; - - const DeadCode([this.desc = '']); -} diff --git a/lib/core/meta/index.dart b/lib/core/meta/index.dart deleted file mode 100644 index 166d574c..00000000 --- a/lib/core/meta/index.dart +++ /dev/null @@ -1 +0,0 @@ -export 'anotations.dart'; diff --git a/lib/flutter_flow/flutter_flow_util.dart b/lib/flutter_flow/flutter_flow_util.dart index bcb34fe5..b86d9da4 100644 --- a/lib/flutter_flow/flutter_flow_util.dart +++ b/lib/flutter_flow/flutter_flow_util.dart @@ -785,3 +785,5 @@ double computeGradientAlignmentY(double evaluatedAngle) { } return double.parse(roundTo(y, 2)); } + + diff --git a/lib/initialization.dart b/lib/initialization.dart index d282e961..1d50273e 100644 --- a/lib/initialization.dart +++ b/lib/initialization.dart @@ -56,6 +56,8 @@ Future _initializeSystemSettings() async { if (kDebugMode) { //kDebugMode print('Debug mode'); + } else { + print('Release mode'); bool unsentReports = await FirebaseCrashlytics.instance.checkForUnsentReports(); if (unsentReports) { @@ -66,9 +68,6 @@ Future _initializeSystemSettings() async { // Não existem relatórios não enviados print('Todos os relatórios de falhas foram enviados.'); } - } else { - print('Release mode'); - await crashlyticsInstance.setCrashlyticsCollectionEnabled(true); // if (crashlyticsInstance.isCrashlyticsCollectionEnabled) { FlutterError.onError = await crashlyticsInstance.recordFlutterError; diff --git a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart index a53747a3..4f6c6bdf 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart @@ -4,7 +4,6 @@ part of 'vehicles_on_the_property.dart'; // ignore: must_be_immutable class VehicleHistoryScreen extends StatefulWidget { - VehicleHistoryScreen(this.model, {super.key}); late VehicleModel model; final scaffoldKey = GlobalKey(); @@ -12,23 +11,21 @@ class VehicleHistoryScreen extends StatefulWidget { @override State createState() => _VehicleHistoryScreenState(); - } class _VehicleHistoryScreenState extends State with Remotable { - - @override void dispose() { super.dispose(); - _scrollController.dispose(); + _pagingController.dispose(); } @override void initState() { super.initState(); _initializeScrollController(); + _pagingController.addPageRequestListener(_fetch); } @override @@ -38,22 +35,19 @@ class _VehicleHistoryScreenState extends State late final double limitedBodyTextSize = LimitedFontSizeUtil.getBodyFontSize(context); - return Scaffold( - key: widget.scaffoldKey, - body: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - if (_hasData == false && - _pageNumber <= 1 && - _loading == false) - _buildNoDataFound(context, limitedHeaderTextSize) - else if (_hasData == true || _pageNumber >= 1) - _buildHistoryList(context, limitedBodyTextSize), - if (_hasData == true && _loading == true) - _buildLoadingIndicator(context), - ].addToStart(const SizedBox(height: 0)), - ), + return Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + // if (_hasData == false && + // _pageNumber <= 1 && + // _loading == false) + // _buildNoDataFound(context, limitedHeaderTextSize) + // else if (_hasData == true || _pageNumber >= 1) + _buildHistoryList(context, limitedBodyTextSize), + // if (_hasData == true && _loading == true) + // _buildLoadingIndicator(context), + ].addToStart(const SizedBox(height: 0)), ); } @@ -82,30 +76,34 @@ class _VehicleHistoryScreenState extends State Widget _buildHistoryList(BuildContext context, double limitedBodyTextSize) { return Expanded( - child: FutureBuilder( - future: _fetch(), - builder: (context, snapshot) { - if (snapshot.connectionState == ConnectionState.waiting) { - return Center(child: CircularProgressIndicator()); - } else if (snapshot.hasError) { - return Center(child: Text('Error: ${snapshot.error}')); - } else { - return ListView.builder( - shrinkWrap: true, - addAutomaticKeepAlives: true, - restorationId: '', - physics: const BouncingScrollPhysics(), - controller: _scrollController, - itemCount: _wrap.length, - itemBuilder: (context, index) => _generateItems(context, _wrap[index], index), - - ); - } - }, + child: RefreshIndicator( + onRefresh: () async => _pagingController.refresh(), + child: PagedListView( + // separatorBuilder: (context, index) => const Divider(), + pagingController: _pagingController, + builderDelegate: PagedChildBuilderDelegate( + animateTransitions: true, + itemBuilder: (context, item, index) => + _generateItems(context, index, item), + firstPageErrorIndicatorBuilder: (context) => Placeholder(), + newPageErrorIndicatorBuilder: (context) => Placeholder(), + ), + ), ), ); } + // ListView.builder( + // shrinkWrap: true, + // addAutomaticKeepAlives: true, + // restorationId: '', + // physics: const BouncingScrollPhysics(), + // controller: _scrollController, + // itemCount: _wrap.length, + // itemBuilder: (context, index) => _generateItems(context, _wrap[index], index), + + // ), + Widget _buildLoadingIndicator(BuildContext context) { return Container( padding: const EdgeInsets.only(top: 15, bottom: 15), @@ -118,15 +116,13 @@ class _VehicleHistoryScreenState extends State ), ); } - - - } - mixin Remotable on State { + final PagingController _pagingController = + PagingController(firstPageKey: 1); - late ScrollController _scrollController; + // late ScrollController _scrollController; double offset = 0.0; List _wrap = []; int _pageNumber = 1; @@ -134,37 +130,46 @@ mixin Remotable on State { bool _loading = true; int count = 0; - Future _fetch() async { + Future _fetch(dynamic pageKey) async { if (!_hasData || !_loading) return; print('hasHasData'); - setState(() => _loading = true); + // setState(() => _loading = true); try { + var newItems = + await PhpGroup.getVehiclesByProperty.call(pageKey.toString()); + final bool isLastPage = newItems.jsonBody == null || + newItems.jsonBody == [] || + newItems.jsonBody == ''; - var response = await PhpGroup.getVehiclesByProperty.call(_pageNumber.toString()); - final List vehicles = response.jsonBody['vehicles'] as List? ?? []; - safeSetState(() => count = response.jsonBody['total_rows'] ?? 0); - if (vehicles.isNotEmpty) { + if (newItems.jsonBody == null) { + } else { + final List vehicles = + newItems.jsonBody['vehicles'] as List? ?? []; + _pagingController.nextPageKey = pageKey + 1; + + safeSetState(() => count = newItems.jsonBody['total_rows'] ?? 0); + if (vehicles.isNotEmpty) { + // setState(() { + // _hasData = true; + // _loading = false; + // _wrap.addAll(vehicles); + // }); + _pagingController.appendLastPage(vehicles); + + return; + } + _showNoMoreDataSnackBar(context); setState(() { - _hasData = true; + _hasData = false; _loading = false; - _wrap.addAll(vehicles); }); - + print('hasEmpty: ${_wrap.length}'); return; } - - _showNoMoreDataSnackBar(context); - - setState(() { - _hasData = false; - _loading = false; - }); - - print('hasEmpty: ${_wrap.length}'); - return; } catch (e, s) { DialogUtil.errorDefault(context); - LogUtil.requestAPIFailed("proccessRequest.php", "", "Consulta de Veículo", e, s); + LogUtil.requestAPIFailed( + "proccessRequest.php", "", "Consulta de Veículo", e, s); setState(() { _hasData = false; _loading = false; @@ -202,37 +207,48 @@ mixin Remotable on State { ); } - Widget? _generateItems(BuildContext context, dynamic snapshot, int index) { - if (index == 0) return _buildHeader(context); - - final bool? isOwner = snapshot['isOwnerVehicle']; - final IconData? iconData = isOwner == true ? Symbols.garage : Symbols.directions_car; - final FreCardIcon? cardIcon = isOwner != null - ? FreCardIcon(height: 50, width: 100, icon: Icon(iconData, size: 80, opticalSize: 10)) - : null; + Widget _generateItems(BuildContext context, int index, dynamic item) { + log('item: $item'); - final String? tag = snapshot['tag']; - final bool containTag = tag.isNotNullAndEmpty; - final Map labelsHashMap = _generateLabelsHashMap(context, snapshot, tag, containTag); + // return Placeholder(); - final List> statusHashMapList = _generateStatusHashMapList(snapshot); + // if (index == 0) return _buildHeader(context); - Future onTapCardItemAction() async { - _handleCardItemTap(context, cardIcon, snapshot); - } + final bool? isOwner = item['isOwnerVehicle']; + final IconData? iconData = + isOwner == true ? Symbols.garage : Symbols.directions_car; + final FreCardIcon? cardIcon = isOwner != null + ? FreCardIcon( + height: 50, + width: 100, + icon: Icon(iconData, size: 80, opticalSize: 10)) + : null; - final statusLinkedHashMap = statusHashMapList.map((map) => LinkedHashMap.from(map)).toList(); - final length = statusLinkedHashMap.expand((e) => [e.length]); + final String? tag = item['tag']; + final bool containTag = tag.isNotNullAndEmpty; + final Map labelsHashMap = + _generateLabelsHashMap(context, item, tag, containTag); - return CardItemTemplateComponentWidget( - icon: cardIcon, - labelsHashMap: labelsHashMap, - statusHashMap: statusHashMapList, - onTapCardItemAction: onTapCardItemAction, - itemWidthFactor: length == 1 ? 0.25 : 0.50, - ); + final List> statusHashMapList = + _generateStatusHashMapList(item); + + Future onTapCardItemAction() async { + _handleCardItemTap(context, cardIcon, item); } - + + final statusLinkedHashMap = statusHashMapList + .map((map) => LinkedHashMap.from(map)) + .toList(); + final length = statusLinkedHashMap.expand((e) => [e.length]); + + return CardItemTemplateComponentWidget( + icon: cardIcon, + labelsHashMap: labelsHashMap, + statusHashMap: statusHashMapList, + onTapCardItemAction: onTapCardItemAction, + itemWidthFactor: length == 1 ? 0.25 : 0.50, + ); + } Map _generateLabelsHashMap(BuildContext context, Map uItem, String? tag, bool containTag) { @@ -249,17 +265,16 @@ mixin Remotable on State { }; } - List> _generateStatusHashMapList( - Map uItem) { - final statusHashMap = - widget.model.generateStatusColorMap(uItem, false); + List> _generateStatusHashMapList( + Map uItem) { + final statusHashMap = widget.model.generateStatusColorMap(uItem, false); return statusHashMap != null ? [statusHashMap] : []; } Future _handleCardItemTap(BuildContext context, FreCardIcon? cardIcon, Map uItem) async { try { - final dialogContent = widget.model.buildVehicleDetails( + final dialogContent = widget.model.buildVehicleDetails( icon: cardIcon, item: uItem, context: context, @@ -274,7 +289,7 @@ mixin Remotable on State { ).whenComplete(() { safeSetState(() { _pageNumber = 1; - _fetch(); + _fetch(1); }); }); } catch (e, s) { @@ -289,27 +304,26 @@ mixin Remotable on State { } void _initializeScrollController() { - _scrollController = ScrollController(keepScrollOffset: true, initialScrollOffset: offset) - ..addListener(() { - print('ScrollController'); - if(!_hasData) return; - if - // (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent) - (_scrollController.position.atEdge && _scrollController.position.pixels != 0) - { - print('ScrollController -> loadMore'); - offset = _scrollController.offset; - _loadMore(); - } - },); - } - - void _loadMore() { - if (_hasData) { - _pageNumber+=1; - _loading = true; - _fetch(); - } + // _scrollController = ScrollController(keepScrollOffset: true, initialScrollOffset: offset) + // ..addListener(() { + // print('ScrollController'); + // if(!_hasData) return; + // if + // // (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent) + // (_scrollController.position.atEdge && _scrollController.position.pixels != 0) + // { + // print('ScrollController -> loadMore'); + // offset = _scrollController.offset; + // _loadMore(); + // } + // },); } + // void _loadMore() { + // if (_hasData) { + // _pageNumber+=1; + // _loading = true; + // _fetch(_pageNumber); + // } + // } } diff --git a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart index f23ccb38..174519fb 100644 --- a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart +++ b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart @@ -16,6 +16,7 @@ import 'package:hub/shared/utils/dialog_util.dart'; import 'package:hub/shared/utils/license_util.dart'; import 'package:hub/shared/utils/limited_text_size.dart'; import 'package:hub/shared/utils/log_util.dart'; +import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; import 'package:material_symbols_icons/symbols.dart'; part 'vehicle_history_screen.dart'; diff --git a/lib/shared/index.dart b/lib/shared/index.dart deleted file mode 100644 index 8b137891..00000000 --- a/lib/shared/index.dart +++ /dev/null @@ -1 +0,0 @@ - diff --git a/pubspec.yaml b/pubspec.yaml index 26ed4273..b78ebdf7 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -15,6 +15,7 @@ dependencies: sdk: flutter auto_size_text: 3.0.0 barcode_widget: ^2.0.4 + infinite_scroll_pagination: ^4.1.0 cached_network_image: ^3.4.0 firebase_core: ^3.4.0 flutter_inappwebview: ^6.0.0 @@ -103,7 +104,25 @@ dependencies: # crypto: ^3.0.5 freezed_annotation: ^2.4.4 package_info_plus: ^8.1.1 + sliver_tools: ^0.2.12 # json_annotation: ^4.9.0 + base: + git: + url: 'git@github.com:FRE-Informatica/flutter-freaccess-base.git' + path: 'packages/base' + components: + git: + url: 'git@github.com:FRE-Informatica/flutter-freaccess-base.git' + path: 'packages/components' + templates: + git: + url: 'git@github.com:FRE-Informatica/flutter-freaccess-base.git' + path: 'packages/templates' + theme: + git: + url: 'git@github.com:FRE-Informatica/flutter-freaccess-base.git' + path: 'packages/theme' + dependency_overrides: http: 1.2.1 From b0e4e86391c0939d1e78c4d3a6dc2e90fd051679 Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Mon, 10 Feb 2025 14:00:03 -0300 Subject: [PATCH 24/47] add infinite_scroll_View --- lib/flutter_flow/flutter_flow_util.dart | 45 +- .../liberation_history_widget.dart | 4 +- lib/pages/pets_page/pets_page_model.dart | 6 +- .../schedule_complete_visit_page_model.dart | 6 +- .../vehicle_history_screen.dart | 492 +++++++++--------- .../vehicle_model.dart | 41 +- .../vehicles_on_the_property.dart | 1 + 7 files changed, 310 insertions(+), 285 deletions(-) diff --git a/lib/flutter_flow/flutter_flow_util.dart b/lib/flutter_flow/flutter_flow_util.dart index b86d9da4..13308e5e 100644 --- a/lib/flutter_flow/flutter_flow_util.dart +++ b/lib/flutter_flow/flutter_flow_util.dart @@ -529,7 +529,7 @@ void setAppLanguage(BuildContext context, String language) => void setDarkModeSetting(BuildContext context, ThemeMode themeMode) => App.of(context).setThemeMode(themeMode); -void showSnackbar( +void showSnackbarMessenger( BuildContext context, String message, bool error, { @@ -573,6 +573,47 @@ void showSnackbar( ); } +SnackBar showSnackbar( + BuildContext context, + String message, + bool error, { + bool loading = false, + int duration = 4, +}) { + return SnackBar( + content: Row( + children: [ + if (loading) + Padding( + padding: const EdgeInsetsDirectional.only(end: 10.0), + child: SizedBox( + height: 20, + width: 20, + child: CircularProgressIndicator( + color: FlutterFlowTheme.of(context).info, + ), + ), + ), + Text( + message, + style: TextStyle( + color: FlutterFlowTheme.of(context).info, + fontSize: LimitedFontSizeUtil.getBodyFontSize(context), + ), + ), + ], + ), + duration: Duration(seconds: duration), + backgroundColor: error + ? FlutterFlowTheme.of(context).error + : FlutterFlowTheme.of(context).success, + behavior: SnackBarBehavior.floating, + shape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(30), + ), + ); +} + void showAlertDialog(BuildContext context, String title, String content, Future Function() action) { double limitedBodyFontSize = LimitedFontSizeUtil.getBodyFontSize(context); @@ -785,5 +826,3 @@ double computeGradientAlignmentY(double evaluatedAngle) { } return double.parse(roundTo(y, 2)); } - - diff --git a/lib/pages/liberation_history/liberation_history_widget.dart b/lib/pages/liberation_history/liberation_history_widget.dart index f69abdee..d4f4ce88 100644 --- a/lib/pages/liberation_history/liberation_history_widget.dart +++ b/lib/pages/liberation_history/liberation_history_widget.dart @@ -299,7 +299,7 @@ class _LiberationHistoryWidgetState extends State { ) .then((message) { if (message != null || message != '') { - showSnackbar( + showSnackbarMessenger( context, FFLocalizations.of(context).getVariableText( enText: 'Successfully resolved visit', @@ -308,7 +308,7 @@ class _LiberationHistoryWidgetState extends State { false, ); } else { - showSnackbar(context, message, true); + showSnackbarMessenger(context, message, true); } }).whenComplete(() { safeSetState(() { diff --git a/lib/pages/pets_page/pets_page_model.dart b/lib/pages/pets_page/pets_page_model.dart index e7de27fe..6671c468 100644 --- a/lib/pages/pets_page/pets_page_model.dart +++ b/lib/pages/pets_page/pets_page_model.dart @@ -474,7 +474,7 @@ class PetsPageModel extends FlutterFlowModel { context.pop(value); if (value == false) { - showSnackbar( + showSnackbarMessenger( context, FFLocalizations.of(context).getVariableText( ptText: 'Erro ao excluir pet', @@ -483,7 +483,7 @@ class PetsPageModel extends FlutterFlowModel { true, ); } else if (value == true) { - showSnackbar( + showSnackbarMessenger( context, FFLocalizations.of(context).getVariableText( enText: 'Success deleting pet', @@ -494,7 +494,7 @@ class PetsPageModel extends FlutterFlowModel { } }).catchError((err, stack) { context.pop(); - showSnackbar( + showSnackbarMessenger( context, FFLocalizations.of(context).getVariableText( enText: 'Error deleting pet', diff --git a/lib/pages/schedule_complete_visit_page/schedule_complete_visit_page_model.dart b/lib/pages/schedule_complete_visit_page/schedule_complete_visit_page_model.dart index f7248d93..f6c80364 100644 --- a/lib/pages/schedule_complete_visit_page/schedule_complete_visit_page_model.dart +++ b/lib/pages/schedule_complete_visit_page/schedule_complete_visit_page_model.dart @@ -472,7 +472,7 @@ class ScheduleCompleteVisitPageModel context.pop(value); if (value == false) { - showSnackbar( + showSnackbarMessenger( context, FFLocalizations.of(context).getVariableText( enText: 'Error blocking visit', @@ -481,7 +481,7 @@ class ScheduleCompleteVisitPageModel true, ); } else if (value == true) { - showSnackbar( + showSnackbarMessenger( context, FFLocalizations.of(context).getVariableText( enText: 'Success canceling visit', @@ -492,7 +492,7 @@ class ScheduleCompleteVisitPageModel } }).catchError((err, stack) { context.pop(); - showSnackbar( + showSnackbarMessenger( context, FFLocalizations.of(context).getVariableText( enText: 'Error blocking visit', diff --git a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart index 4f6c6bdf..a75000c3 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart @@ -1,13 +1,10 @@ part of 'vehicles_on_the_property.dart'; -/// [VehicleHistoryScreen] is a StatefulWidget that displays a list of vehicles. - -// ignore: must_be_immutable +/// Widget que exibe o histórico de veículos na propriedade. class VehicleHistoryScreen extends StatefulWidget { + final VehicleModel model; + VehicleHistoryScreen(this.model, {super.key}); - late VehicleModel model; - final scaffoldKey = GlobalKey(); - final builderKey = GlobalKey(); @override State createState() => _VehicleHistoryScreenState(); @@ -15,167 +12,268 @@ class VehicleHistoryScreen extends StatefulWidget { class _VehicleHistoryScreenState extends State with Remotable { - @override - void dispose() { - super.dispose(); - _pagingController.dispose(); - } + final apiCall = PhpGroup.getVehiclesByProperty; @override void initState() { super.initState(); - _initializeScrollController(); - _pagingController.addPageRequestListener(_fetch); + _pagingController.addPageRequestListener( + (dynamic pageKey) => _fetch( + hasData: () async { + final newItems = await apiCall.call(pageKey.toString()); + if (newItems.jsonBody == null) return (false, null); + final List vehicles = + (newItems.jsonBody['vehicles'] as List?) ?? []; + _pagingController.nextPageKey = pageKey + 1; + + safeSetState(() { + count = newItems.jsonBody['total_rows'] ?? 0; + }); + return (vehicles.isNotEmpty, vehicles); + }, + onNotHas: () { + _showNoMoreDataSnackBar(context); + setState(() { + // _hasData = false; + // _loading = false; + }); + }, + onHas: (vehicles) { + setState(() { + // _loading = false; + }); + _pagingController.appendLastPage(vehicles); + }, + onError: (e, s) { + DialogUtil.errorDefault(context); + LogUtil.requestAPIFailed( + "proccessRequest.php", "", "Consulta de Veículo", e, s); + setState(() { + // _hasData = false; + // _loading = false; + }); + }, + ), + ); + _pagingController.addStatusListener(_showError); + } + + @override + void dispose() { + _pagingController.dispose(); + super.dispose(); + } + + Future _showError(PagingStatus status) async { + if (status == PagingStatus.subsequentPageError) { + final message = FFLocalizations.of(context).getVariableText( + enText: 'Something went wrong while fetching a new page.', + ptText: 'Algo deu errado ao buscar uma nova página.', + ); + final retry = FFLocalizations.of(context).getVariableText( + enText: 'Retry', + ptText: 'Recarregar', + ); + + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text(message), + action: SnackBarAction( + label: retry, + onPressed: () => _pagingController.retryLastFailedRequest(), + ), + ), + ); + } } @override Widget build(BuildContext context) { - late final limitedHeaderTextSize = - LimitedFontSizeUtil.getHeaderFontSize(context); - late final double limitedBodyTextSize = - LimitedFontSizeUtil.getBodyFontSize(context); - return Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.start, children: [ - // if (_hasData == false && - // _pageNumber <= 1 && - // _loading == false) - // _buildNoDataFound(context, limitedHeaderTextSize) - // else if (_hasData == true || _pageNumber >= 1) - _buildHistoryList(context, limitedBodyTextSize), - // if (_hasData == true && _loading == true) - // _buildLoadingIndicator(context), - ].addToStart(const SizedBox(height: 0)), + _buildHeader(context), + _buildBody(), + ], ); } - Widget _buildNoDataFound(BuildContext context, double limitedHeaderTextSize) { - return Expanded( - child: Column( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.max, - children: [ - Center( - child: Text( - FFLocalizations.of(context).getVariableText( - ptText: "Nenhum veículo encontrado!", - enText: "No vehicle found", - ), - style: TextStyle( - fontFamily: 'Nunito', - fontSize: limitedHeaderTextSize, - ), - ), - ) - ], + Widget _buildHeader(BuildContext context) { + final bodyFontSize = LimitedFontSizeUtil.getBodyFontSize(context); + return SizedBox( + height: 30, + child: Center( + child: Text( + (widget.model.amountRegister == '0' || + widget.model.amountRegister == null) + ? '' + : "${FFLocalizations.of(context).getVariableText(ptText: "Quantidade de Veículos: ", enText: "Amount of Vehicles: ")}${widget.model.amountRegister}/$count", + textAlign: TextAlign.right, + style: TextStyle( + fontFamily: 'Nunito', + fontSize: bodyFontSize, + ), + ), ), ); } - Widget _buildHistoryList(BuildContext context, double limitedBodyTextSize) { + Expanded _buildBody() { + final noDataFound = FFLocalizations.of(context).getVariableText( + ptText: "Nenhum veículo encontrado!", + enText: "No vehicle found", + ); return Expanded( child: RefreshIndicator( onRefresh: () async => _pagingController.refresh(), child: PagedListView( - // separatorBuilder: (context, index) => const Divider(), pagingController: _pagingController, - builderDelegate: PagedChildBuilderDelegate( + builderDelegate: PagedChildBuilderDelegate( animateTransitions: true, itemBuilder: (context, item, index) => _generateItems(context, index, item), - firstPageErrorIndicatorBuilder: (context) => Placeholder(), - newPageErrorIndicatorBuilder: (context) => Placeholder(), + // noMoreItemsIndicatorBuilder: , + newPageProgressIndicatorBuilder: (context) => + _buildLoadingIndicator(context), + firstPageProgressIndicatorBuilder: (context) => + _buildLoadingIndicator(context), + noItemsFoundIndicatorBuilder: (context) => + _buildNoDataFound(context, noDataFound), + firstPageErrorIndicatorBuilder: (context) => const Placeholder(), + newPageErrorIndicatorBuilder: (context) => const Placeholder(), ), ), ), ); } - // ListView.builder( - // shrinkWrap: true, - // addAutomaticKeepAlives: true, - // restorationId: '', - // physics: const BouncingScrollPhysics(), - // controller: _scrollController, - // itemCount: _wrap.length, - // itemBuilder: (context, index) => _generateItems(context, _wrap[index], index), + Widget _generateItems(BuildContext context, int index, dynamic item) { + log('item: $item'); + final bool? isOwner = item['isOwnerVehicle']; + final IconData iconData = + isOwner == true ? Symbols.garage : Symbols.directions_car; - // ), + final FreCardIcon? cardIcon = isOwner != null + ? FreCardIcon( + height: 50, + width: 100, + icon: Icon(iconData, size: 80, opticalSize: 10), + ) + : null; - Widget _buildLoadingIndicator(BuildContext context) { - return Container( - padding: const EdgeInsets.only(top: 15, bottom: 15), - child: Center( - child: CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation( - FlutterFlowTheme.of(context).primary, - ), - ), - ), + final String? tag = item['tag']; + final bool containTag = tag.isNotNullAndEmpty; + final Map labelsHashMap = + _generateLabelsHashMap(context, item, tag, containTag); + + final List> statusHashMapList = + _generateStatusHashMapList(item); + + Future onTapCardItemAction() async { + await _handleCardItemTap(context, cardIcon, item); + } + + final statusLinkedHashMap = statusHashMapList + .map((map) => LinkedHashMap.from(map)) + .toList(); + final length = statusLinkedHashMap.expand((e) => [e.length]); + final double itemWidthFactor = length == 1 ? 0.25 : 0.50; + + return CardItemTemplateComponentWidget( + icon: cardIcon, + labelsHashMap: labelsHashMap, + statusHashMap: statusHashMapList, + onTapCardItemAction: onTapCardItemAction, + itemWidthFactor: itemWidthFactor, ); } + + Map _generateLabelsHashMap( + BuildContext context, + Map item, + String? tag, + bool containTag, + ) { + final localization = FFLocalizations.of(context); + return { + '${localization.getVariableText(ptText: "Placa", enText: "License Plate")}:': + item['licensePlate'] ?? '', + '${localization.getVariableText(ptText: "Modelo", enText: "Model")}:': + item['model'] ?? '', + '${localization.getVariableText(ptText: "Proprietário", enText: "Owner")}:': + item['personName'] ?? '', + if (containTag) + '${localization.getVariableText(ptText: "Tag", enText: "Tag")}:': + tag ?? '', + }; + } + + List> _generateStatusHashMapList( + Map item) { + final statusHashMap = widget.model.generateStatusColorMap(item, false); + return statusHashMap != null ? [statusHashMap] : []; + } + + Future _handleCardItemTap( + BuildContext context, + FreCardIcon? cardIcon, + Map item, + ) async { + try { + final dialogContent = widget.model.buildVehicleDetails( + icon: cardIcon, + item: item, + context: context, + model: widget.model, + ); + + await showDialog( + useSafeArea: true, + context: context, + builder: (context) => Dialog( + alignment: Alignment.center, + child: dialogContent, + ), + ).whenComplete(() { + safeSetState(() { + // _pagingController.refresh(); + }); + }); + } catch (e, s) { + DialogUtil.errorDefault(context); + LogUtil.requestAPIFailed( + "proccessRequest.php", "", "Consulta de Veículos", e, s); + safeSetState(() { + // _hasData = false; + // _loading = false; + }); + } + } } mixin Remotable on State { final PagingController _pagingController = PagingController(firstPageKey: 1); - // late ScrollController _scrollController; double offset = 0.0; - List _wrap = []; - int _pageNumber = 1; - bool _hasData = true; - bool _loading = true; + // bool _hasData = true; + // bool _loading = true; int count = 0; - Future _fetch(dynamic pageKey) async { - if (!_hasData || !_loading) return; - print('hasHasData'); - // setState(() => _loading = true); + Future _fetch({ + required Future<(bool, dynamic)> Function() hasData, + required void Function(dynamic) onHas, + required void Function() onNotHas, + required void Function(Object, StackTrace) onError, + }) async { + // if (!_hasData || !_loading) return; try { - var newItems = - await PhpGroup.getVehiclesByProperty.call(pageKey.toString()); - final bool isLastPage = newItems.jsonBody == null || - newItems.jsonBody == [] || - newItems.jsonBody == ''; - - if (newItems.jsonBody == null) { - } else { - final List vehicles = - newItems.jsonBody['vehicles'] as List? ?? []; - _pagingController.nextPageKey = pageKey + 1; - - safeSetState(() => count = newItems.jsonBody['total_rows'] ?? 0); - if (vehicles.isNotEmpty) { - // setState(() { - // _hasData = true; - // _loading = false; - // _wrap.addAll(vehicles); - // }); - _pagingController.appendLastPage(vehicles); - - return; - } - _showNoMoreDataSnackBar(context); - setState(() { - _hasData = false; - _loading = false; - }); - print('hasEmpty: ${_wrap.length}'); - return; - } + final (bool, dynamic) data = await hasData(); + if (data.$1) + onHas(data.$2); + else + onNotHas(); } catch (e, s) { - DialogUtil.errorDefault(context); - LogUtil.requestAPIFailed( - "proccessRequest.php", "", "Consulta de Veículo", e, s); - setState(() { - _hasData = false; - _loading = false; - }); - print('hasError'); - return; + onError(e, s); } } @@ -188,142 +286,32 @@ mixin Remotable on State { showSnackbar(context, message, true); } - Widget _buildHeader(BuildContext context) { - double limitedBodyTextSize = LimitedFontSizeUtil.getBodyFontSize(context); - log('amountRegister: ${widget.model.amountRegister}'); - return Padding( - padding: const EdgeInsets.only(right: 30, top: 10), - child: Text( - (widget.model.amountRegister == '0' || - widget.model.amountRegister == null) - ? '' - : "${FFLocalizations.of(context).getVariableText(ptText: "Quantidade de Veículos: ", enText: "Amount of Vehicles: ")}${widget.model.amountRegister}/$count", - textAlign: TextAlign.right, - style: TextStyle( - fontFamily: 'Nunito', - fontSize: limitedBodyTextSize, + Widget _buildNoDataFound(BuildContext context, String title) { + final headerFontSize = LimitedFontSizeUtil.getHeaderFontSize(context); + // final bodyFontSize = LimitedFontSizeUtil.getBodyFontSize(context); + return Expanded( + child: Center( + child: Text( + title, + style: TextStyle( + fontFamily: 'Nunito', + fontSize: headerFontSize, + ), ), ), ); } - Widget _generateItems(BuildContext context, int index, dynamic item) { - log('item: $item'); - - // return Placeholder(); - - // if (index == 0) return _buildHeader(context); - - final bool? isOwner = item['isOwnerVehicle']; - final IconData? iconData = - isOwner == true ? Symbols.garage : Symbols.directions_car; - final FreCardIcon? cardIcon = isOwner != null - ? FreCardIcon( - height: 50, - width: 100, - icon: Icon(iconData, size: 80, opticalSize: 10)) - : null; - - final String? tag = item['tag']; - final bool containTag = tag.isNotNullAndEmpty; - final Map labelsHashMap = - _generateLabelsHashMap(context, item, tag, containTag); - - final List> statusHashMapList = - _generateStatusHashMapList(item); - - Future onTapCardItemAction() async { - _handleCardItemTap(context, cardIcon, item); - } - - final statusLinkedHashMap = statusHashMapList - .map((map) => LinkedHashMap.from(map)) - .toList(); - final length = statusLinkedHashMap.expand((e) => [e.length]); - - return CardItemTemplateComponentWidget( - icon: cardIcon, - labelsHashMap: labelsHashMap, - statusHashMap: statusHashMapList, - onTapCardItemAction: onTapCardItemAction, - itemWidthFactor: length == 1 ? 0.25 : 0.50, + Widget _buildLoadingIndicator(BuildContext context) { + return Container( + padding: const EdgeInsets.symmetric(vertical: 15), + child: Center( + child: CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation( + FlutterFlowTheme.of(context).primary, + ), + ), + ), ); } - - Map _generateLabelsHashMap(BuildContext context, - Map uItem, String? tag, bool containTag) { - return { - '${FFLocalizations.of(context).getVariableText(ptText: "Placa", enText: "License Plate")}:': - uItem['licensePlate'] ?? '', - '${FFLocalizations.of(context).getVariableText(ptText: "Modelo", enText: "Model")}:': - uItem['model'] ?? '', - '${FFLocalizations.of(context).getVariableText(ptText: "Proprietário", enText: "Owner")}:': - uItem['personName'] ?? '', - if (containTag) - '${FFLocalizations.of(context).getVariableText(ptText: "Tag", enText: "Tag")}:': - tag ?? '', - }; - } - - List> _generateStatusHashMapList( - Map uItem) { - final statusHashMap = widget.model.generateStatusColorMap(uItem, false); - return statusHashMap != null ? [statusHashMap] : []; - } - - Future _handleCardItemTap(BuildContext context, FreCardIcon? cardIcon, - Map uItem) async { - try { - final dialogContent = widget.model.buildVehicleDetails( - icon: cardIcon, - item: uItem, - context: context, - model: widget.model, - ); - - await showDialog( - useSafeArea: true, - context: context, - builder: (context) => - Dialog(alignment: Alignment.center, child: dialogContent), - ).whenComplete(() { - safeSetState(() { - _pageNumber = 1; - _fetch(1); - }); - }); - } catch (e, s) { - DialogUtil.errorDefault(context); - LogUtil.requestAPIFailed( - "proccessRequest.php", "", "Consulta de Veículos", e, s); - safeSetState(() { - _hasData = false; - _loading = false; - }); - } - } - - void _initializeScrollController() { - // _scrollController = ScrollController(keepScrollOffset: true, initialScrollOffset: offset) - // ..addListener(() { - // print('ScrollController'); - // if(!_hasData) return; - // if - // // (_scrollController.position.pixels >= _scrollController.position.maxScrollExtent) - // (_scrollController.position.atEdge && _scrollController.position.pixels != 0) - // { - // print('ScrollController -> loadMore'); - // offset = _scrollController.offset; - // _loadMore(); - // } - // },); - } - - // void _loadMore() { - // if (_hasData) { - // _pageNumber+=1; - // _loading = true; - // _fetch(_pageNumber); - // } - // } } diff --git a/lib/pages/vehicles_on_the_property/vehicle_model.dart b/lib/pages/vehicles_on_the_property/vehicle_model.dart index 5bee0d41..39d24f0e 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_model.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_model.dart @@ -71,7 +71,8 @@ class VehicleModel extends FlutterFlowModel Future initAsync() async { amountRegister = await StorageHelper().get(LocalsStorageKey.vehicleAmountRegister.key); - autoApproval= await StorageHelper().get(LocalsStorageKey.vehicleAutoApproval.key); + autoApproval = + await StorageHelper().get(LocalsStorageKey.vehicleAutoApproval.key); } bool isFormValid(BuildContext context, GlobalKey formKey) { @@ -91,7 +92,6 @@ mixin class _BaseVehiclePage { ApiCallResponse? vehicleResponse; String? amountRegister = '0'; late final String? autoApproval; - VoidCallback? onUpdateVehicle; VoidCallback? onRegisterVehicle; @@ -240,10 +240,7 @@ mixin _VehicleUpdateScreenModel on _BaseVehiclePage { /// [_VehicleHistoryScreenModel] is a mixin that contains the business logic of the vehicle history page. mixin _VehicleHistoryScreenModel on _BaseVehiclePage { - - - Map? generateStatusColorMap(dynamic uItem, bool isDetail) { - + Map? generateStatusColorMap(dynamic uItem, bool isDetail) { if (autoApproval.toBoolean == true) return null; final theme = FlutterFlowTheme.of(context); final localization = FFLocalizations.of(context); @@ -299,7 +296,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { return {}; } - List generateActionButtons(dynamic item) { + List generateActionButtons(dynamic item) { final Color iconButtonColor = FlutterFlowTheme.of(context).primaryText; final FFButtonOptions buttonOptions = FFButtonOptions( height: 40, @@ -342,7 +339,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { ptText: 'Você tem certeza que deseja cancelar essa solicitação?', enText: 'Are you sure you want to delete this request?', ), - () async => processCancelRequest(item['status'], item)); + () async => processCancelRequest(item['status'], item)); } final deleteText = FFLocalizations.of(context) @@ -359,7 +356,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { ptText: 'Você tem certeza que deseja excluir esse veículo?', enText: 'Are you sure you want to delete this vehicle?', ), - () async => processDeleteRequest(item), + () async => processDeleteRequest(item), ); } @@ -420,7 +417,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { // ignore: unrelated_type_equality_checks if (value.jsonBody['error'] == true) { final String errorMsg = value.jsonBody['error_msg']; - return showSnackbar( + return showSnackbarMessenger( context, FFLocalizations.of(context).getVariableText( ptText: errorMsg, @@ -430,7 +427,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { ); // ignore: unrelated_type_equality_checks } - return showSnackbar( + return showSnackbarMessenger( context, FFLocalizations.of(context).getVariableText( enText: 'Success deleting vehicle', @@ -440,7 +437,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { ); }).catchError((err, stack) { context.pop(); - return showSnackbar( + return showSnackbarMessenger( context, FFLocalizations.of(context).getVariableText( enText: 'Error deleting vehicle', @@ -473,7 +470,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { if (value.jsonBody['error'] == true) { final String errorMsg = value.jsonBody['error_msg']; - return showSnackbar( + return showSnackbarMessenger( context, FFLocalizations.of(context).getVariableText( ptText: errorMsg, @@ -482,7 +479,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { true, ); } - return showSnackbar( + return showSnackbarMessenger( context, FFLocalizations.of(context).getVariableText( enText: 'Success canceling request', @@ -492,7 +489,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { ); } catch (err) { context.pop(); - return showSnackbar( + return showSnackbarMessenger( context, FFLocalizations.of(context).getVariableText( enText: 'Error canceling request', @@ -503,7 +500,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { } } - Future processCancelDeleteRequest(dynamic item) async{ + Future processCancelDeleteRequest(dynamic item) async { return await PhpGroup.deleteVehicle.call( vehicleId: item['vehicleId'], licensePlate: item['licensePlate'], @@ -512,7 +509,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { ); } - Future processCancelUpdateRequest(dynamic item) async { + Future processCancelUpdateRequest(dynamic item) async { return await PhpGroup.deleteVehicle.call( vehicleId: item['vehicleId'], licensePlate: item['licensePlate'], @@ -530,7 +527,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { ); } - Map generateLabelsHashMap(dynamic item) { + Map generateLabelsHashMap(dynamic item) { return { if (item['model'] != null && item['model'] != '') '${FFLocalizations.of(context).getVariableText(ptText: "Modelo", enText: "Model")}:': @@ -555,10 +552,10 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { required BuildContext context, required VehicleModel model, required FreCardIcon? icon, - }) { - final status = generateStatusColorMap(item, true); - final buttons = generateActionButtons(item); - final labels = generateLabelsHashMap(item); + }) { + final status = generateStatusColorMap(item, true); + final buttons = generateActionButtons(item); + final labels = generateLabelsHashMap(item); return DetailsComponentWidget( icon: icon, buttons: buttons, diff --git a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart index 174519fb..4a01ca63 100644 --- a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart +++ b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart @@ -1,6 +1,7 @@ import 'dart:collection'; import 'dart:developer'; +import 'package:auto_size_text/auto_size_text.dart'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:hub/components/atomic_components/shared_components_atoms/custom_input.dart'; From a4b7ee3cd0d47fe3d2c11d958ed25fc667dd3614 Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Mon, 10 Feb 2025 14:07:38 -0300 Subject: [PATCH 25/47] uncomment tests --- integration_test/app_test.dart | 31 +++++++++++---------- lib/flutter_flow/flutter_flow_util.dart | 36 ++----------------------- 2 files changed, 17 insertions(+), 50 deletions(-) diff --git a/integration_test/app_test.dart b/integration_test/app_test.dart index 66966f1f..0d832c65 100644 --- a/integration_test/app_test.dart +++ b/integration_test/app_test.dart @@ -32,7 +32,6 @@ import 'app_test.dart'; import 'fuzzer/fuzzer.dart'; import 'package:patrol_finders/patrol_finders.dart'; -import 'package:integration_test/integration_test.dart'; export 'package:flutter_test/flutter_test.dart'; export 'package:patrol/patrol.dart'; @@ -72,26 +71,26 @@ void main() { // setUp(() async {}); // tearDown(() async {}); - // WelcomeTest.signInToSignUp(); - // WelcomeTest.signUpToSignIn(); + WelcomeTest.signInToSignUp(); + WelcomeTest.signUpToSignIn(); - // AuthenticationTest.signIn(); - // AuthenticationTest.signUp(); - // AuthenticationTest.signOut(); + AuthenticationTest.signIn(); + AuthenticationTest.signUp(); + AuthenticationTest.signOut(); // AuthenticationTest.recovery(); - // ModularizationTest.switchLicense(); - // ModularizationTest.containLicense(); + ModularizationTest.switchLicense(); + ModularizationTest.containLicense(); - // MenuTest.navToEntries(); - // MenuTest.containEntries(); - // MenuTest.labels2AppbarConsistency(); + MenuTest.navToEntries(); + MenuTest.containEntries(); + MenuTest.labels2AppbarConsistency(); - // LocalsTest.setLocal(); - // LocalsTest.unlinkLocal(); + LocalsTest.setLocal(); + LocalsTest.unlinkLocal(); - // VehicleTest.vehiclePage(); - // VehicleTest.historyScreen(); + VehicleTest.vehiclePage(); + VehicleTest.historyScreen(); VehicleTest.registerScreen(); - // VehicleTest.updateScreen(); + VehicleTest.updateScreen(); } diff --git a/lib/flutter_flow/flutter_flow_util.dart b/lib/flutter_flow/flutter_flow_util.dart index 13308e5e..1aa2f180 100644 --- a/lib/flutter_flow/flutter_flow_util.dart +++ b/lib/flutter_flow/flutter_flow_util.dart @@ -537,40 +537,8 @@ void showSnackbarMessenger( int duration = 4, }) { ScaffoldMessenger.of(context).hideCurrentSnackBar(); - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Row( - children: [ - if (loading) - Padding( - padding: const EdgeInsetsDirectional.only(end: 10.0), - child: SizedBox( - height: 20, - width: 20, - child: CircularProgressIndicator( - color: FlutterFlowTheme.of(context).info, - ), - ), - ), - Text( - message, - style: TextStyle( - color: FlutterFlowTheme.of(context).info, - fontSize: LimitedFontSizeUtil.getBodyFontSize(context), - ), - ), - ], - ), - duration: Duration(seconds: duration), - backgroundColor: error - ? FlutterFlowTheme.of(context).error - : FlutterFlowTheme.of(context).success, - behavior: SnackBarBehavior.floating, - shape: RoundedRectangleBorder( - borderRadius: BorderRadius.circular(30), - ), - ), - ); + ScaffoldMessenger.of(context) + .showSnackBar(showSnackbar(context, message, error)); } SnackBar showSnackbar( From 7b0297a491133fd675848965e04aaf177ea68c05 Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Mon, 10 Feb 2025 15:13:35 -0300 Subject: [PATCH 26/47] wip pageable mixin --- .../vehicle_history_screen.dart | 132 ++++-------------- .../vehicles_on_the_property.dart | 1 + lib/shared/mixins/pageable_mixin.dart | 98 +++++++++++++ 3 files changed, 123 insertions(+), 108 deletions(-) create mode 100644 lib/shared/mixins/pageable_mixin.dart diff --git a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart index a75000c3..eabf3e37 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart @@ -11,15 +11,18 @@ class VehicleHistoryScreen extends StatefulWidget { } class _VehicleHistoryScreenState extends State - with Remotable { + with Pageable { final apiCall = PhpGroup.getVehiclesByProperty; + int count = 0; + final PagingController _pagingController = + PagingController(firstPageKey: 1); @override void initState() { super.initState(); _pagingController.addPageRequestListener( - (dynamic pageKey) => _fetch( - hasData: () async { + (dynamic pageKey) => fetchPage( + dataProvider: () async { final newItems = await apiCall.call(pageKey.toString()); if (newItems.jsonBody == null) return (false, null); final List vehicles = @@ -31,27 +34,19 @@ class _VehicleHistoryScreenState extends State }); return (vehicles.isNotEmpty, vehicles); }, - onNotHas: () { - _showNoMoreDataSnackBar(context); - setState(() { - // _hasData = false; - // _loading = false; - }); + onDataUnavailable: () { + setState(() {}); + showNoMoreDataSnackBar(context); }, - onHas: (vehicles) { - setState(() { - // _loading = false; - }); + onDataAvailable: (vehicles) { + setState(() {}); _pagingController.appendLastPage(vehicles); }, - onError: (e, s) { + onFetchError: (e, s) { DialogUtil.errorDefault(context); LogUtil.requestAPIFailed( "proccessRequest.php", "", "Consulta de Veículo", e, s); - setState(() { - // _hasData = false; - // _loading = false; - }); + setState(() {}); }, ), ); @@ -92,7 +87,7 @@ class _VehicleHistoryScreenState extends State return Column( children: [ _buildHeader(context), - _buildBody(), + _buildBody(context), ], ); } @@ -117,36 +112,23 @@ class _VehicleHistoryScreenState extends State ); } - Expanded _buildBody() { + Expanded _buildBody(BuildContext context) { final noDataFound = FFLocalizations.of(context).getVariableText( ptText: "Nenhum veículo encontrado!", enText: "No vehicle found", ); - return Expanded( - child: RefreshIndicator( - onRefresh: () async => _pagingController.refresh(), - child: PagedListView( - pagingController: _pagingController, - builderDelegate: PagedChildBuilderDelegate( - animateTransitions: true, - itemBuilder: (context, item, index) => - _generateItems(context, index, item), - // noMoreItemsIndicatorBuilder: , - newPageProgressIndicatorBuilder: (context) => - _buildLoadingIndicator(context), - firstPageProgressIndicatorBuilder: (context) => - _buildLoadingIndicator(context), - noItemsFoundIndicatorBuilder: (context) => - _buildNoDataFound(context, noDataFound), - firstPageErrorIndicatorBuilder: (context) => const Placeholder(), - newPageErrorIndicatorBuilder: (context) => const Placeholder(), - ), - ), - ), + return buildPaginatedListView( + noDataFound, + _pagingController, + _generateItems, ); } - Widget _generateItems(BuildContext context, int index, dynamic item) { + Widget _generateItems( + BuildContext context, + dynamic item, + int index, + ) { log('item: $item'); final bool? isOwner = item['isOwnerVehicle']; final IconData iconData = @@ -249,69 +231,3 @@ class _VehicleHistoryScreenState extends State } } } - -mixin Remotable on State { - final PagingController _pagingController = - PagingController(firstPageKey: 1); - - double offset = 0.0; - // bool _hasData = true; - // bool _loading = true; - int count = 0; - - Future _fetch({ - required Future<(bool, dynamic)> Function() hasData, - required void Function(dynamic) onHas, - required void Function() onNotHas, - required void Function(Object, StackTrace) onError, - }) async { - // if (!_hasData || !_loading) return; - try { - final (bool, dynamic) data = await hasData(); - if (data.$1) - onHas(data.$2); - else - onNotHas(); - } catch (e, s) { - onError(e, s); - } - } - - void _showNoMoreDataSnackBar(BuildContext context) { - final message = FFLocalizations.of(context).getVariableText( - ptText: "Não há mais dados.", - enText: "No more data.", - ); - - showSnackbar(context, message, true); - } - - Widget _buildNoDataFound(BuildContext context, String title) { - final headerFontSize = LimitedFontSizeUtil.getHeaderFontSize(context); - // final bodyFontSize = LimitedFontSizeUtil.getBodyFontSize(context); - return Expanded( - child: Center( - child: Text( - title, - style: TextStyle( - fontFamily: 'Nunito', - fontSize: headerFontSize, - ), - ), - ), - ); - } - - Widget _buildLoadingIndicator(BuildContext context) { - return Container( - padding: const EdgeInsets.symmetric(vertical: 15), - child: Center( - child: CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation( - FlutterFlowTheme.of(context).primary, - ), - ), - ), - ); - } -} diff --git a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart index 4a01ca63..eafe8305 100644 --- a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart +++ b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart @@ -13,6 +13,7 @@ import 'package:hub/features/module/index.dart'; import 'package:hub/flutter_flow/index.dart'; import 'package:hub/pages/vehicles_on_the_property/vehicle_model.dart'; import 'package:hub/shared/extensions/index.dart'; +import 'package:hub/shared/mixins/pageable_mixin.dart'; import 'package:hub/shared/utils/dialog_util.dart'; import 'package:hub/shared/utils/license_util.dart'; import 'package:hub/shared/utils/limited_text_size.dart'; diff --git a/lib/shared/mixins/pageable_mixin.dart b/lib/shared/mixins/pageable_mixin.dart new file mode 100644 index 00000000..e2cf1493 --- /dev/null +++ b/lib/shared/mixins/pageable_mixin.dart @@ -0,0 +1,98 @@ +import 'package:flutter/material.dart'; +import 'package:hub/flutter_flow/index.dart'; +import 'package:hub/shared/utils/limited_text_size.dart'; +import 'package:infinite_scroll_pagination/infinite_scroll_pagination.dart'; + +extension PagedListViewExtension + on PagedSliverList {} + +mixin Pageable on State { + Expanded buildPaginatedListView( + String noDataFound, + PagingController pg, + Widget Function(BuildContext, Y, int) itemBuilder) { + final theme = FlutterFlowTheme.of(context); + + return Expanded( + child: RefreshIndicator( + backgroundColor: theme.primaryBackground, + color: theme.primary, + onRefresh: () async => pg.refresh(), + child: PagedListView( + pagingController: pg, + builderDelegate: PagedChildBuilderDelegate( + animateTransitions: true, + + itemBuilder: (context, item, index) => + itemBuilder(context, item, index), + // noMoreItemsIndicatorBuilder: , + newPageProgressIndicatorBuilder: (context) => + buildLoadingIndicator(context), + firstPageProgressIndicatorBuilder: (context) => + buildLoadingIndicator(context), + noItemsFoundIndicatorBuilder: (context) => + buildNoDataFound(context, noDataFound), + firstPageErrorIndicatorBuilder: (context) => const Placeholder(), + newPageErrorIndicatorBuilder: (context) => const Placeholder(), + ), + ), + ), + ); + } + + Future fetchPage({ + required Future<(bool, dynamic)> Function() dataProvider, + required void Function(dynamic data) onDataAvailable, + required void Function() onDataUnavailable, + required void Function(Object error, StackTrace stackTrace) onFetchError, + }) async { + try { + final (bool isDataAvailable, dynamic data) = await dataProvider(); + if (isDataAvailable) { + onDataAvailable(data); + } else { + onDataUnavailable(); + } + } catch (error, stackTrace) { + onFetchError(error, stackTrace); + } + } + + void showNoMoreDataSnackBar(BuildContext context) { + final message = FFLocalizations.of(context).getVariableText( + ptText: "Não há mais dados.", + enText: "No more data.", + ); + + showSnackbar(context, message, true); + } + + Widget buildNoDataFound(BuildContext context, String title) { + final headerFontSize = LimitedFontSizeUtil.getHeaderFontSize(context); + // final bodyFontSize = LimitedFontSizeUtil.getBodyFontSize(context); + return Expanded( + child: Center( + child: Text( + title, + style: TextStyle( + fontFamily: 'Nunito', + fontSize: headerFontSize, + ), + ), + ), + ); + } + + Widget buildLoadingIndicator(BuildContext context) { + return Container( + padding: const EdgeInsets.symmetric(vertical: 15), + child: Center( + child: CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation( + FlutterFlowTheme.of(context).primary, + ), + ), + ), + ); + } +} From b1a09d999c382cc2503365d524e9fa5bccd9092f Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Thu, 13 Feb 2025 16:54:21 -0300 Subject: [PATCH 27/47] fix paginacao --- .../vehicle_history_screen.dart | 11 +++++++---- lib/shared/mixins/pageable_mixin.dart | 10 ++++++---- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart index eabf3e37..3cda31bb 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart @@ -20,27 +20,30 @@ class _VehicleHistoryScreenState extends State @override void initState() { super.initState(); + _pagingController.addPageRequestListener( - (dynamic pageKey) => fetchPage( + (int pageKey) => fetchPage( dataProvider: () async { final newItems = await apiCall.call(pageKey.toString()); if (newItems.jsonBody == null) return (false, null); final List vehicles = (newItems.jsonBody['vehicles'] as List?) ?? []; - _pagingController.nextPageKey = pageKey + 1; safeSetState(() { count = newItems.jsonBody['total_rows'] ?? 0; }); + return (vehicles.isNotEmpty, vehicles); }, - onDataUnavailable: () { + onDataUnavailable: (vehicles) { setState(() {}); + showNoMoreDataSnackBar(context); + _pagingController.appendLastPage(vehicles); }, onDataAvailable: (vehicles) { setState(() {}); - _pagingController.appendLastPage(vehicles); + _pagingController.appendPage(vehicles, pageKey + 1); }, onFetchError: (e, s) { DialogUtil.errorDefault(context); diff --git a/lib/shared/mixins/pageable_mixin.dart b/lib/shared/mixins/pageable_mixin.dart index e2cf1493..48c42c7c 100644 --- a/lib/shared/mixins/pageable_mixin.dart +++ b/lib/shared/mixins/pageable_mixin.dart @@ -32,8 +32,8 @@ mixin Pageable on State { buildLoadingIndicator(context), noItemsFoundIndicatorBuilder: (context) => buildNoDataFound(context, noDataFound), - firstPageErrorIndicatorBuilder: (context) => const Placeholder(), - newPageErrorIndicatorBuilder: (context) => const Placeholder(), + // firstPageErrorIndicatorBuilder: (context) => const Placeholder(), + // newPageErrorIndicatorBuilder: (context) => const Placeholder(), ), ), ), @@ -43,15 +43,17 @@ mixin Pageable on State { Future fetchPage({ required Future<(bool, dynamic)> Function() dataProvider, required void Function(dynamic data) onDataAvailable, - required void Function() onDataUnavailable, + required void Function(dynamic data) onDataUnavailable, required void Function(Object error, StackTrace stackTrace) onFetchError, }) async { try { + print('develop ->'); final (bool isDataAvailable, dynamic data) = await dataProvider(); + print('develop -> $isDataAvailable'); if (isDataAvailable) { onDataAvailable(data); } else { - onDataUnavailable(); + onDataUnavailable(data); } } catch (error, stackTrace) { onFetchError(error, stackTrace); From 70e81c0e347456903f360338a0eb2254484b3440 Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Thu, 13 Feb 2025 16:55:28 -0300 Subject: [PATCH 28/47] fix max length 80 --- lib/pages/vehicles_on_the_property/vehicle_update_screen.dart | 1 - lib/shared/mixins/pageable_mixin.dart | 2 -- 2 files changed, 3 deletions(-) diff --git a/lib/pages/vehicles_on_the_property/vehicle_update_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_update_screen.dart index a386f56c..f780c103 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_update_screen.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_update_screen.dart @@ -114,7 +114,6 @@ class _VehicleUpdateScreenState extends State { suffixIcon: suffixIcon, haveMaxLength: true, onChanged: (value) => setState(() {}), - maxLength: 80, ); } diff --git a/lib/shared/mixins/pageable_mixin.dart b/lib/shared/mixins/pageable_mixin.dart index 48c42c7c..a0ef3f89 100644 --- a/lib/shared/mixins/pageable_mixin.dart +++ b/lib/shared/mixins/pageable_mixin.dart @@ -47,9 +47,7 @@ mixin Pageable on State { required void Function(Object error, StackTrace stackTrace) onFetchError, }) async { try { - print('develop ->'); final (bool isDataAvailable, dynamic data) = await dataProvider(); - print('develop -> $isDataAvailable'); if (isDataAvailable) { onDataAvailable(data); } else { From a46181d2f4021e7319b1a41caa282e3c4cdb48e9 Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Thu, 13 Feb 2025 16:59:29 -0300 Subject: [PATCH 29/47] refresh listVIew after details --- .../vehicles_on_the_property/vehicle_history_screen.dart | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart index 3cda31bb..0b5b8d20 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart @@ -219,9 +219,9 @@ class _VehicleHistoryScreenState extends State child: dialogContent, ), ).whenComplete(() { - safeSetState(() { - // _pagingController.refresh(); - }); + _pagingController.refresh(); + + safeSetState(() {}); }); } catch (e, s) { DialogUtil.errorDefault(context); From 9edd350f1322b19d6c51eed18572fd90dec67ccd Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Thu, 13 Feb 2025 17:04:30 -0300 Subject: [PATCH 30/47] misc & --- .../vehicles_on_the_property/vehicle_history_screen.dart | 5 +---- lib/pages/vehicles_on_the_property/vehicle_model.dart | 6 +++--- lib/shared/mixins/pageable_mixin.dart | 2 +- 3 files changed, 5 insertions(+), 8 deletions(-) diff --git a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart index 0b5b8d20..8e75fe1c 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart @@ -1,10 +1,8 @@ part of 'vehicles_on_the_property.dart'; -/// Widget que exibe o histórico de veículos na propriedade. class VehicleHistoryScreen extends StatefulWidget { final VehicleModel model; - - VehicleHistoryScreen(this.model, {super.key}); + const VehicleHistoryScreen(this.model, {super.key}); @override State createState() => _VehicleHistoryScreenState(); @@ -20,7 +18,6 @@ class _VehicleHistoryScreenState extends State @override void initState() { super.initState(); - _pagingController.addPageRequestListener( (int pageKey) => fetchPage( dataProvider: () async { diff --git a/lib/pages/vehicles_on_the_property/vehicle_model.dart b/lib/pages/vehicles_on_the_property/vehicle_model.dart index 39d24f0e..b4da34cb 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_model.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_model.dart @@ -23,6 +23,9 @@ class VehicleModel extends FlutterFlowModel factory VehicleModel() => _instance ?? VehicleModel._internal(); static void resetInstance() => _instance = null; + final GlobalKey registerFormKey = GlobalKey(); + final GlobalKey updateFormKey = GlobalKey(); + @override void initState(BuildContext context) { log('VehicleModel -> initState'); @@ -65,9 +68,6 @@ class VehicleModel extends FlutterFlowModel textFieldControllerModel!.dispose(); } - final GlobalKey registerFormKey = GlobalKey(); - final GlobalKey updateFormKey = GlobalKey(); - Future initAsync() async { amountRegister = await StorageHelper().get(LocalsStorageKey.vehicleAmountRegister.key); diff --git a/lib/shared/mixins/pageable_mixin.dart b/lib/shared/mixins/pageable_mixin.dart index a0ef3f89..7e967cf8 100644 --- a/lib/shared/mixins/pageable_mixin.dart +++ b/lib/shared/mixins/pageable_mixin.dart @@ -64,7 +64,7 @@ mixin Pageable on State { enText: "No more data.", ); - showSnackbar(context, message, true); + showSnackbarMessenger(context, message, true); } Widget buildNoDataFound(BuildContext context, String title) { From 0b38538d2b0f4fd2a611517db1446638a98f1a5d Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Thu, 13 Feb 2025 17:54:29 -0300 Subject: [PATCH 31/47] keyboard uppercasse and max length for licensePlate --- .../shared_components_atoms/custom_input.dart | 43 ++++++++++++------- .../vehicle_register_screen.dart | 9 +++- .../vehicle_update_screen.dart | 8 ++++ .../vehicles_on_the_property.dart | 1 + 4 files changed, 45 insertions(+), 16 deletions(-) diff --git a/lib/components/atomic_components/shared_components_atoms/custom_input.dart b/lib/components/atomic_components/shared_components_atoms/custom_input.dart index cac159f4..cb02aba7 100644 --- a/lib/components/atomic_components/shared_components_atoms/custom_input.dart +++ b/lib/components/atomic_components/shared_components_atoms/custom_input.dart @@ -5,6 +5,15 @@ import 'package:google_fonts/google_fonts.dart'; import 'package:hub/flutter_flow/flutter_flow_theme.dart'; import 'package:hub/shared/utils/limited_text_size.dart'; +class UpperCaseTextFormatter extends TextInputFormatter { + @override + TextEditingValue formatEditUpdate( + TextEditingValue oldValue, TextEditingValue newValue) { + return TextEditingValue( + text: newValue.text.toUpperCase(), selection: newValue.selection); + } +} + // ignore: must_be_immutable class CustomInputUtil extends StatefulWidget { final TextEditingController? controller; @@ -20,22 +29,25 @@ class CustomInputUtil extends StatefulWidget { final String? Function(String?)? validator; final bool haveMaxLength; final void Function(String)? onChanged; + final List? inputFormatters; - CustomInputUtil( - {super.key, - this.controller, - required this.labelText, - required this.hintText, - required this.suffixIcon, - this.autoFocus = false, - required this.focusNode, - this.onChanged, - this.textInputAction = TextInputAction.next, - this.keyboardType = TextInputType.text, - this.maxLength = 80, - this.validator, - this.obscureText, - required this.haveMaxLength}); + CustomInputUtil({ + super.key, + this.controller, + required this.labelText, + required this.hintText, + required this.suffixIcon, + this.autoFocus = false, + required this.focusNode, + this.onChanged, + this.textInputAction = TextInputAction.next, + this.keyboardType = TextInputType.text, + this.maxLength = 80, + this.validator, + this.obscureText, + this.inputFormatters, + required this.haveMaxLength, + }); @override State createState() => _CustomInputUtilState(); @@ -152,6 +164,7 @@ class _CustomInputUtilState extends State { keyboardType: widget.keyboardType, inputFormatters: [ LengthLimitingTextInputFormatter(widget.maxLength), + if (widget.inputFormatters != null) ...widget.inputFormatters! ], ), ], diff --git a/lib/pages/vehicles_on_the_property/vehicle_register_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_register_screen.dart index b11e0db7..ff32d4ab 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_register_screen.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_register_screen.dart @@ -43,6 +43,8 @@ class _VehicleRegisterScreenState extends State { hintText: FFLocalizations.of(context) .getVariableText(ptText: 'Placa', enText: 'License Plate'), suffixIcon: Symbols.format_color_text, + inputFormatters: [UpperCaseTextFormatter()], + maxLength: 7, ), _buildCustomInput( context: context, @@ -54,6 +56,7 @@ class _VehicleRegisterScreenState extends State { hintText: FFLocalizations.of(context).getVariableText( ptText: 'Ex: Voyage, Ford', enText: 'e.g. Voyage, Ford'), suffixIcon: Symbols.car_repair, + inputFormatters: [], ), _buildCustomInput( context: context, @@ -66,6 +69,7 @@ class _VehicleRegisterScreenState extends State { ptText: 'Ex: Preto, Amarelo, Branco', enText: 'e.g. Black, Yellow, White'), suffixIcon: Symbols.palette, + inputFormatters: [], ), Padding( padding: const EdgeInsets.fromLTRB(70, 20, 70, 30), @@ -91,6 +95,8 @@ class _VehicleRegisterScreenState extends State { required String labelText, required String hintText, required IconData suffixIcon, + required final List? inputFormatters, + int maxLength = 80, }) { return CustomInputUtil( controller: controller, @@ -101,7 +107,8 @@ class _VehicleRegisterScreenState extends State { suffixIcon: suffixIcon, haveMaxLength: true, onChanged: (value) => setState(() {}), - maxLength: 80, + inputFormatters: inputFormatters, + maxLength: maxLength, ); } diff --git a/lib/pages/vehicles_on_the_property/vehicle_update_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_update_screen.dart index f780c103..1f746b50 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_update_screen.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_update_screen.dart @@ -43,6 +43,8 @@ class _VehicleUpdateScreenState extends State { hintText: FFLocalizations.of(context) .getVariableText(ptText: 'Placa', enText: 'License Plate'), suffixIcon: Symbols.format_color_text, + inputFormatters: [UpperCaseTextFormatter()], + maxLength: 7, ), _buildCustomInput( context: context, @@ -54,6 +56,7 @@ class _VehicleUpdateScreenState extends State { hintText: FFLocalizations.of(context).getVariableText( ptText: 'Ex: Voyage, Ford', enText: 'e.g. Voyage, Ford'), suffixIcon: Symbols.car_repair, + inputFormatters: [], ), _buildCustomInput( context: context, @@ -66,6 +69,7 @@ class _VehicleUpdateScreenState extends State { ptText: 'Ex: Preto, Amarelo, Branco', enText: 'e.g. Black, Yellow, White'), suffixIcon: Symbols.palette, + inputFormatters: [], ), _buildSubmitButton(context), ], @@ -104,6 +108,8 @@ class _VehicleUpdateScreenState extends State { required String labelText, required String hintText, required IconData suffixIcon, + required List? inputFormatters, + int maxLength = 80, }) { return CustomInputUtil( controller: controller, @@ -114,6 +120,8 @@ class _VehicleUpdateScreenState extends State { suffixIcon: suffixIcon, haveMaxLength: true, onChanged: (value) => setState(() {}), + inputFormatters: inputFormatters, + maxLength: maxLength, ); } diff --git a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart index eafe8305..7d5571d1 100644 --- a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart +++ b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart @@ -3,6 +3,7 @@ import 'dart:developer'; import 'package:auto_size_text/auto_size_text.dart'; import 'package:flutter/material.dart'; +import 'package:flutter/services.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:hub/components/atomic_components/shared_components_atoms/custom_input.dart'; import 'package:hub/components/atomic_components/shared_components_atoms/submit_button.dart'; From 49154d99459912cac37527be5c9aafcaf4bfff76 Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Fri, 14 Feb 2025 09:46:56 -0300 Subject: [PATCH 32/47] fix refresh --- .tool-versions | 2 +- .../backend/api_requests/api_manager.dart | 10 +-- .../vehicle_history_screen.dart | 21 +++-- .../vehicle_model.dart | 78 +++++++++---------- 4 files changed, 55 insertions(+), 56 deletions(-) diff --git a/.tool-versions b/.tool-versions index fc05c635..3e6df7d4 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1 +1 @@ -gradle 7.6.1 +gradle 8.10.2 diff --git a/lib/features/backend/api_requests/api_manager.dart b/lib/features/backend/api_requests/api_manager.dart index 72087153..d12c03dd 100644 --- a/lib/features/backend/api_requests/api_manager.dart +++ b/lib/features/backend/api_requests/api_manager.dart @@ -496,11 +496,11 @@ class ApiManager { result = ApiCallResponse(null, {}, -1, exception: e); } - log('API Call: $callName'); - log('URL: $apiUrl'); - log('Headers: $headers'); - log('Params: $params'); - log('Response: ${result.jsonBody}'); + print('API Call: $callName'); + print('URL: $apiUrl'); + print('Headers: $headers'); + print('Params: $params'); + print('Response: ${result.jsonBody}'); return result; } } diff --git a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart index 8e75fe1c..379a3c02 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart @@ -14,6 +14,7 @@ class _VehicleHistoryScreenState extends State int count = 0; final PagingController _pagingController = PagingController(firstPageKey: 1); + bool isSnackble = true; @override void initState() { @@ -34,8 +35,9 @@ class _VehicleHistoryScreenState extends State }, onDataUnavailable: (vehicles) { setState(() {}); + final bool isFirst = pageKey == 2; + if (!isFirst && isSnackble) showNoMoreDataSnackBar(context); - showNoMoreDataSnackBar(context); _pagingController.appendLastPage(vehicles); }, onDataAvailable: (vehicles) { @@ -208,18 +210,23 @@ class _VehicleHistoryScreenState extends State model: widget.model, ); - await showDialog( + await showDialog( useSafeArea: true, context: context, builder: (context) => Dialog( alignment: Alignment.center, child: dialogContent, ), - ).whenComplete(() { - _pagingController.refresh(); - - safeSetState(() {}); - }); + ) // + .then((response) async { + if (response == true) { + isSnackble = false; + _pagingController.refresh(); + } else { + isSnackble = true; + } + }) // + .whenComplete(() {}); } catch (e, s) { DialogUtil.errorDefault(context); LogUtil.requestAPIFailed( diff --git a/lib/pages/vehicles_on_the_property/vehicle_model.dart b/lib/pages/vehicles_on_the_property/vehicle_model.dart index b4da34cb..61a53dc5 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_model.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_model.dart @@ -339,7 +339,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { ptText: 'Você tem certeza que deseja cancelar essa solicitação?', enText: 'Are you sure you want to delete this request?', ), - () async => processCancelRequest(item['status'], item)); + () async => await processCancelRequest(item['status'], item)); } final deleteText = FFLocalizations.of(context) @@ -401,9 +401,9 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { ]; } - void processDeleteRequest(dynamic item) async { + Future processDeleteRequest(dynamic item) async { log('processDeleteRequest -> item[$item]'); - return await PhpGroup.deleteVehicle + bool result = await PhpGroup.deleteVehicle .call( vehicleId: item['vehicleId'], licensePlate: item['licensePlate'], @@ -411,13 +411,10 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { color: item['color'], ) .then((value) { - context.pop(value); - context.pop(value); - // ignore: unrelated_type_equality_checks if (value.jsonBody['error'] == true) { final String errorMsg = value.jsonBody['error_msg']; - return showSnackbarMessenger( + showSnackbarMessenger( context, FFLocalizations.of(context).getVariableText( ptText: errorMsg, @@ -425,9 +422,10 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { ), true, ); + return false; // ignore: unrelated_type_equality_checks } - return showSnackbarMessenger( + showSnackbarMessenger( context, FFLocalizations.of(context).getVariableText( enText: 'Success deleting vehicle', @@ -435,9 +433,10 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { ), false, ); - }).catchError((err, stack) { - context.pop(); - return showSnackbarMessenger( + return true; + }) // + .catchError((err, stack) { + showSnackbarMessenger( context, FFLocalizations.of(context).getVariableText( enText: 'Error deleting vehicle', @@ -445,12 +444,18 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { ), true, ); + return false; }); + + context.pop(result); + context.pop(result); + + return result; } - void processCancelRequest(String status, dynamic item) async { - late final ApiCallResponse value; + Future processCancelRequest(String status, dynamic item) async { try { + final ApiCallResponse value; switch (status) { case 'APR_CREATE': value = await processCancelDeleteRequest(item); @@ -462,41 +467,28 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage { value = await processCancelCreateRequest(item); break; default: - break; + throw ArgumentError('Status inválido: $status'); } - context.pop(value); - context.pop(value); - - if (value.jsonBody['error'] == true) { - final String errorMsg = value.jsonBody['error_msg']; - return showSnackbarMessenger( - context, - FFLocalizations.of(context).getVariableText( - ptText: errorMsg, - enText: 'Error canceling request', - ), - true, - ); - } - return showSnackbarMessenger( - context, - FFLocalizations.of(context).getVariableText( - enText: 'Success canceling request', - ptText: 'Succeso ao cancelar solicitação', - ), - false, + final bool isError = value.jsonBody['error'] == true; + final String message = FFLocalizations.of(context).getVariableText( + ptText: value.jsonBody['error_msg'] ?? 'Erro ao cancelar solicitação', + enText: + isError ? 'Error canceling request' : 'Success canceling request', ); + showSnackbarMessenger(context, message, isError); + context.pop(!isError); + context.pop(!isError); + return !isError; } catch (err) { - context.pop(); - return showSnackbarMessenger( - context, - FFLocalizations.of(context).getVariableText( - enText: 'Error canceling request', - ptText: 'Erro ao cancelar solicitação', - ), - true, + final String errorMessage = FFLocalizations.of(context).getVariableText( + ptText: 'Erro ao cancelar solicitação', + enText: 'Error canceling request', ); + showSnackbarMessenger(context, errorMessage, true); + context.pop(false); + context.pop(false); + return false; } } From fcf6af93b94750788fed3907f6dc371511d3d008 Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Fri, 14 Feb 2025 09:53:09 -0300 Subject: [PATCH 33/47] seState tabbar if isEditing --- .../vehicles_on_the_property/vehicle_history_screen.dart | 8 ++++---- .../vehicles_on_the_property.dart | 5 ++--- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart index 379a3c02..1e90cc84 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart @@ -14,7 +14,7 @@ class _VehicleHistoryScreenState extends State int count = 0; final PagingController _pagingController = PagingController(firstPageKey: 1); - bool isSnackble = true; + bool _isSnackble = true; @override void initState() { @@ -36,7 +36,7 @@ class _VehicleHistoryScreenState extends State onDataUnavailable: (vehicles) { setState(() {}); final bool isFirst = pageKey == 2; - if (!isFirst && isSnackble) showNoMoreDataSnackBar(context); + if (!isFirst && _isSnackble) showNoMoreDataSnackBar(context); _pagingController.appendLastPage(vehicles); }, @@ -220,10 +220,10 @@ class _VehicleHistoryScreenState extends State ) // .then((response) async { if (response == true) { - isSnackble = false; + _isSnackble = false; _pagingController.refresh(); } else { - isSnackble = true; + _isSnackble = true; } }) // .whenComplete(() {}); diff --git a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart index 7d5571d1..dfaade25 100644 --- a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart +++ b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart @@ -117,9 +117,8 @@ class _VehiclePageState extends State } void onEditingChanged(bool value) { - setState(() { - _model.handleEditingChanged(value); - }); + if (_model.isEditing) setState(() {}); + _model.handleEditingChanged(value); } Widget _buildVehicleHistory(BuildContext context) { From d42c6301a8617b203414fb99856fb255dc06cb9a Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Fri, 14 Feb 2025 10:34:15 -0300 Subject: [PATCH 34/47] wip - keyboard bugfix --- .../shared_components_atoms/tabview.dart | 4 ++-- lib/pages/pets_page/pets_page_widget.dart | 4 ++-- .../vehicles_on_the_property.dart | 15 ++++++++++++--- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/lib/components/atomic_components/shared_components_atoms/tabview.dart b/lib/components/atomic_components/shared_components_atoms/tabview.dart index 32114202..30348b8d 100644 --- a/lib/components/atomic_components/shared_components_atoms/tabview.dart +++ b/lib/components/atomic_components/shared_components_atoms/tabview.dart @@ -10,7 +10,7 @@ class TabViewUtil extends StatelessWidget { String labelTab1; String labelTab2; final TabController controller; - final Function(bool) onEditingChanged; + final Function([bool]) onEditingChanged; Widget widget1; Widget widget2; @@ -59,7 +59,7 @@ class TabViewUtil extends StatelessWidget { ], controller: controller, onTap: (i) async { - if (i == 1) onEditingChanged(false); + onEditingChanged(); [() async {}, () async {}][i](); }, ), diff --git a/lib/pages/pets_page/pets_page_widget.dart b/lib/pages/pets_page/pets_page_widget.dart index 8816c468..0fb09390 100644 --- a/lib/pages/pets_page/pets_page_widget.dart +++ b/lib/pages/pets_page/pets_page_widget.dart @@ -86,9 +86,9 @@ class _PetsPageWidgetState extends State ); } - void onEditingChanged(bool value) { + void onEditingChanged([bool? value]) { setState(() { - _model.handleEditingChanged(value); + _model.handleEditingChanged(value!); }); } diff --git a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart index dfaade25..180c672b 100644 --- a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart +++ b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart @@ -116,9 +116,18 @@ class _VehiclePageState extends State } } - void onEditingChanged(bool value) { - if (_model.isEditing) setState(() {}); - _model.handleEditingChanged(value); + void onEditingChanged([bool? value]) { + bool isFirst = _model.tabBarController.index == 0; + + if (_model.isEditing & isFirst) { + _model.handleEditingChanged(false); + setState(() {}); + } + // if (isFirst) FocusScope.of(context).unfocus(); + if (isFirst) { + FocusScope.of(context).unfocus(); + // FocusScope.of(context).nextFocus(); + } } Widget _buildVehicleHistory(BuildContext context) { From c7483d4676b492294d3660dab45608367e7de7aa Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Fri, 14 Feb 2025 10:41:58 -0300 Subject: [PATCH 35/47] fix keyboard focus --- .../vehicles_on_the_property/vehicles_on_the_property.dart | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart index 180c672b..edbd968b 100644 --- a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart +++ b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart @@ -121,12 +121,10 @@ class _VehiclePageState extends State if (_model.isEditing & isFirst) { _model.handleEditingChanged(false); - setState(() {}); } - // if (isFirst) FocusScope.of(context).unfocus(); if (isFirst) { - FocusScope.of(context).unfocus(); - // FocusScope.of(context).nextFocus(); + FocusScope.of(context).nextFocus(); + setState(() {}); } } From 5845538518a3dcd61e2297ac3027b968ba826eeb Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Fri, 14 Feb 2025 11:00:18 -0300 Subject: [PATCH 36/47] ? --- lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart index edbd968b..9e51e429 100644 --- a/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart +++ b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart @@ -123,7 +123,6 @@ class _VehiclePageState extends State _model.handleEditingChanged(false); } if (isFirst) { - FocusScope.of(context).nextFocus(); setState(() {}); } } From 75e4a98b178d7087947202dff8ccd750e0b1f96a Mon Sep 17 00:00:00 2001 From: Ivan Antunes Date: Mon, 17 Feb 2025 08:59:07 -0300 Subject: [PATCH 37/47] version 1.4.0 | build 25 --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index b78ebdf7..39dc466c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: A new Flutter project. publish_to: "none" -version: 1.3.5+24 +version: 1.4.0+25 environment: sdk: ">=3.0.0 <4.0.0" From b9f355cdbf5eaf2dc66564679a89854ac45b54ad Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Mon, 17 Feb 2025 09:23:01 -0300 Subject: [PATCH 38/47] firebase crashlytics fix --- lib/initialization.dart | 31 +++++++++++++++++-------------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/lib/initialization.dart b/lib/initialization.dart index 1d50273e..c3d32845 100644 --- a/lib/initialization.dart +++ b/lib/initialization.dart @@ -53,26 +53,29 @@ Future _initializeSystemSettings() async { final crashlyticsInstance = FirebaseCrashlytics.instance; await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); + if (kDebugMode) { - //kDebugMode print('Debug mode'); + await crashlyticsInstance.setCrashlyticsCollectionEnabled(false); } else { print('Release mode'); - bool unsentReports = - await FirebaseCrashlytics.instance.checkForUnsentReports(); - if (unsentReports) { - // Existem relatórios não enviados - await crashlyticsInstance.sendUnsentReports(); - print('Existem relatórios de falhas não enviados.'); - } else { - // Não existem relatórios não enviados - print('Todos os relatórios de falhas foram enviados.'); - } await crashlyticsInstance.setCrashlyticsCollectionEnabled(true); - // if (crashlyticsInstance.isCrashlyticsCollectionEnabled) { - FlutterError.onError = await crashlyticsInstance.recordFlutterError; + + // Verifica e envia relatórios não enviados de forma assíncrona + crashlyticsInstance.checkForUnsentReports().then((unsentReports) { + if (unsentReports) { + crashlyticsInstance.sendUnsentReports(); + print('Existem relatórios de falhas não enviados.'); + } else { + print('Todos os relatórios de falhas foram enviados.'); + } + }).catchError((error) { + print('Erro ao verificar ou enviar relatórios não enviados: $error'); + }); + + // Configura o tratamento de erros não capturados + FlutterError.onError = crashlyticsInstance.recordFlutterError; print('Crashlytics enabled'); - // } } } From 3a9772558fa1e9e0421315567f24842b70622919 Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Mon, 17 Feb 2025 12:08:27 -0300 Subject: [PATCH 39/47] FIX --- .../vehicle_history_screen.dart | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart index 1e90cc84..ddbf6271 100644 --- a/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart +++ b/lib/pages/vehicles_on_the_property/vehicle_history_screen.dart @@ -11,7 +11,7 @@ class VehicleHistoryScreen extends StatefulWidget { class _VehicleHistoryScreenState extends State with Pageable { final apiCall = PhpGroup.getVehiclesByProperty; - int count = 0; + int totalOwnerVehicles = 0; final PagingController _pagingController = PagingController(firstPageKey: 1); bool _isSnackble = true; @@ -28,7 +28,7 @@ class _VehicleHistoryScreenState extends State (newItems.jsonBody['vehicles'] as List?) ?? []; safeSetState(() { - count = newItems.jsonBody['total_rows'] ?? 0; + totalOwnerVehicles = newItems.jsonBody['total_owner_vehicles'] ?? 0; }); return (vehicles.isNotEmpty, vehicles); @@ -96,6 +96,12 @@ class _VehicleHistoryScreenState extends State Widget _buildHeader(BuildContext context) { final bodyFontSize = LimitedFontSizeUtil.getBodyFontSize(context); + final headerTitle = FFLocalizations.of(context).getVariableText( + ptText: "Meus Veículos: ", + enText: "My Vehicles: ", + ); + final totalRegisteredVehicles = widget.model.amountRegister; + return SizedBox( height: 30, child: Center( @@ -103,7 +109,7 @@ class _VehicleHistoryScreenState extends State (widget.model.amountRegister == '0' || widget.model.amountRegister == null) ? '' - : "${FFLocalizations.of(context).getVariableText(ptText: "Quantidade de Veículos: ", enText: "Amount of Vehicles: ")}${widget.model.amountRegister}/$count", + : "$headerTitle $totalOwnerVehicles/$totalRegisteredVehicles", textAlign: TextAlign.right, style: TextStyle( fontFamily: 'Nunito', From e08a049000daa2f56468c8066ae10c2c15a81a93 Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Mon, 17 Feb 2025 14:17:08 -0300 Subject: [PATCH 40/47] comment crashlytics 'fix' --- lib/initialization.dart | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/lib/initialization.dart b/lib/initialization.dart index c3d32845..939143ca 100644 --- a/lib/initialization.dart +++ b/lib/initialization.dart @@ -56,22 +56,22 @@ Future _initializeSystemSettings() async { if (kDebugMode) { print('Debug mode'); - await crashlyticsInstance.setCrashlyticsCollectionEnabled(false); + // await crashlyticsInstance.setCrashlyticsCollectionEnabled(false); } else { print('Release mode'); - await crashlyticsInstance.setCrashlyticsCollectionEnabled(true); + // await crashlyticsInstance.setCrashlyticsCollectionEnabled(true); // Verifica e envia relatórios não enviados de forma assíncrona - crashlyticsInstance.checkForUnsentReports().then((unsentReports) { - if (unsentReports) { - crashlyticsInstance.sendUnsentReports(); - print('Existem relatórios de falhas não enviados.'); - } else { - print('Todos os relatórios de falhas foram enviados.'); - } - }).catchError((error) { - print('Erro ao verificar ou enviar relatórios não enviados: $error'); - }); + // crashlyticsInstance.checkForUnsentReports().then((unsentReports) { + // if (unsentReports) { + // crashlyticsInstance.sendUnsentReports(); + // print('Existem relatórios de falhas não enviados.'); + // } else { + // print('Todos os relatórios de falhas foram enviados.'); + // } + // }).catchError((error) { + // print('Erro ao verificar ou enviar relatórios não enviados: $error'); + // }); // Configura o tratamento de erros não capturados FlutterError.onError = crashlyticsInstance.recordFlutterError; From 5b7ed354995de8ca27ad08cede5b46fe760883c9 Mon Sep 17 00:00:00 2001 From: Ivan Antunes Date: Mon, 17 Feb 2025 15:28:30 -0300 Subject: [PATCH 41/47] build 26 --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 39dc466c..1ae1e5f0 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: A new Flutter project. publish_to: "none" -version: 1.4.0+25 +version: 1.4.0+26 environment: sdk: ">=3.0.0 <4.0.0" From 6b724b3821f3a12dd03c1644d35999e7f0aa195d Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Tue, 18 Feb 2025 08:55:02 -0300 Subject: [PATCH 42/47] rollback firebase crashlytics --- lib/initialization.dart | 31 ++++++++++++++++--------------- 1 file changed, 16 insertions(+), 15 deletions(-) diff --git a/lib/initialization.dart b/lib/initialization.dart index 939143ca..d43766b5 100644 --- a/lib/initialization.dart +++ b/lib/initialization.dart @@ -50,7 +50,6 @@ void _initializeUrlStrategy() { Future _initializeSystemSettings() async { print('Initializing System Settings...'); - final crashlyticsInstance = FirebaseCrashlytics.instance; await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); @@ -59,22 +58,24 @@ Future _initializeSystemSettings() async { // await crashlyticsInstance.setCrashlyticsCollectionEnabled(false); } else { print('Release mode'); + final crashlyticsInstance = FirebaseCrashlytics.instance; + // await crashlyticsInstance.setCrashlyticsCollectionEnabled(true); + if (crashlyticsInstance.isCrashlyticsCollectionEnabled) { + // Configura o tratamento de erros não capturados + FlutterError.onError = crashlyticsInstance.recordFlutterError; - // Verifica e envia relatórios não enviados de forma assíncrona - // crashlyticsInstance.checkForUnsentReports().then((unsentReports) { - // if (unsentReports) { - // crashlyticsInstance.sendUnsentReports(); - // print('Existem relatórios de falhas não enviados.'); - // } else { - // print('Todos os relatórios de falhas foram enviados.'); - // } - // }).catchError((error) { - // print('Erro ao verificar ou enviar relatórios não enviados: $error'); - // }); - - // Configura o tratamento de erros não capturados - FlutterError.onError = crashlyticsInstance.recordFlutterError; + crashlyticsInstance.checkForUnsentReports().then((unsentReports) { + if (unsentReports) { + crashlyticsInstance.sendUnsentReports(); + print('Existem relatórios de falhas não enviados.'); + } else { + print('Todos os relatórios de falhas foram enviados.'); + } + }).catchError((error) { + print('Erro ao verificar ou enviar relatórios não enviados: $error'); + }); + } print('Crashlytics enabled'); } } From e21d5b5e53c17475fe868daeb8bc2e4748d38c81 Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Tue, 18 Feb 2025 08:56:42 -0300 Subject: [PATCH 43/47] WIP --- lib/initialization.dart | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/lib/initialization.dart b/lib/initialization.dart index d43766b5..aa43876c 100644 --- a/lib/initialization.dart +++ b/lib/initialization.dart @@ -65,16 +65,16 @@ Future _initializeSystemSettings() async { // Configura o tratamento de erros não capturados FlutterError.onError = crashlyticsInstance.recordFlutterError; - crashlyticsInstance.checkForUnsentReports().then((unsentReports) { - if (unsentReports) { - crashlyticsInstance.sendUnsentReports(); - print('Existem relatórios de falhas não enviados.'); - } else { - print('Todos os relatórios de falhas foram enviados.'); - } - }).catchError((error) { - print('Erro ao verificar ou enviar relatórios não enviados: $error'); - }); + // crashlyticsInstance.checkForUnsentReports().then((unsentReports) { + // if (unsentReports) { + // crashlyticsInstance.sendUnsentReports(); + // print('Existem relatórios de falhas não enviados.'); + // } else { + // print('Todos os relatórios de falhas foram enviados.'); + // } + // }).catchError((error) { + // print('Erro ao verificar ou enviar relatórios não enviados: $error'); + // }); } print('Crashlytics enabled'); } From 6ac6e150097416db734ec40a3ce5deceaf2c5e56 Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Tue, 18 Feb 2025 09:16:04 -0300 Subject: [PATCH 44/47] enable crashlyticsCOllection --- lib/initialization.dart | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/lib/initialization.dart b/lib/initialization.dart index aa43876c..cea6b80c 100644 --- a/lib/initialization.dart +++ b/lib/initialization.dart @@ -60,21 +60,21 @@ Future _initializeSystemSettings() async { print('Release mode'); final crashlyticsInstance = FirebaseCrashlytics.instance; - // await crashlyticsInstance.setCrashlyticsCollectionEnabled(true); + await crashlyticsInstance.setCrashlyticsCollectionEnabled(true); if (crashlyticsInstance.isCrashlyticsCollectionEnabled) { // Configura o tratamento de erros não capturados FlutterError.onError = crashlyticsInstance.recordFlutterError; - // crashlyticsInstance.checkForUnsentReports().then((unsentReports) { - // if (unsentReports) { - // crashlyticsInstance.sendUnsentReports(); - // print('Existem relatórios de falhas não enviados.'); - // } else { - // print('Todos os relatórios de falhas foram enviados.'); - // } - // }).catchError((error) { - // print('Erro ao verificar ou enviar relatórios não enviados: $error'); - // }); + crashlyticsInstance.checkForUnsentReports().then((unsentReports) { + if (unsentReports) { + crashlyticsInstance.sendUnsentReports(); + print('Existem relatórios de falhas não enviados.'); + } else { + print('Todos os relatórios de falhas foram enviados.'); + } + }).catchError((error) { + print('Erro ao verificar ou enviar relatórios não enviados: $error'); + }); } print('Crashlytics enabled'); } From 85f961076f56417f1c43e97ba7aa7d3f383a62a2 Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Tue, 18 Feb 2025 09:17:55 -0300 Subject: [PATCH 45/47] WIP --- lib/initialization.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/initialization.dart b/lib/initialization.dart index cea6b80c..bfcd8d97 100644 --- a/lib/initialization.dart +++ b/lib/initialization.dart @@ -52,13 +52,13 @@ Future _initializeSystemSettings() async { print('Initializing System Settings...'); await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); + final crashlyticsInstance = FirebaseCrashlytics.instance; if (kDebugMode) { print('Debug mode'); - // await crashlyticsInstance.setCrashlyticsCollectionEnabled(false); + await crashlyticsInstance.setCrashlyticsCollectionEnabled(false); } else { print('Release mode'); - final crashlyticsInstance = FirebaseCrashlytics.instance; await crashlyticsInstance.setCrashlyticsCollectionEnabled(true); if (crashlyticsInstance.isCrashlyticsCollectionEnabled) { From fb026fc22fda08e5c2eb5ec81a52bab2bfdfda92 Mon Sep 17 00:00:00 2001 From: Ivan Antunes Date: Tue, 18 Feb 2025 14:38:33 -0300 Subject: [PATCH 46/47] build 27 --- pubspec.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pubspec.yaml b/pubspec.yaml index 1ae1e5f0..f22f4ace 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -3,7 +3,7 @@ description: A new Flutter project. publish_to: "none" -version: 1.4.0+26 +version: 1.4.0+27 environment: sdk: ">=3.0.0 <4.0.0" From 7d6f7ecbc8a40cb0d7d38b8b0e8b376ea5342639 Mon Sep 17 00:00:00 2001 From: jantunesmessias Date: Wed, 19 Feb 2025 08:24:42 -0300 Subject: [PATCH 47/47] update app-tracking-transparency --- lib/initialization.dart | 1 + pubspec.yaml | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/initialization.dart b/lib/initialization.dart index bfcd8d97..eb72a67e 100644 --- a/lib/initialization.dart +++ b/lib/initialization.dart @@ -27,6 +27,7 @@ Future initializeApp() async { Future _initializeTracking() async { print('Requesting tracking authorization...'); await AppTrackingTransparency.requestTrackingAuthorization(); + print('Tracking authorization requested'); } diff --git a/pubspec.yaml b/pubspec.yaml index f22f4ace..f2c4bc5a 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -99,7 +99,7 @@ dependencies: permission_handler: ^11.3.1 firebase_crashlytics: ^4.0.1 awesome_notifications: ^0.10.0 - app_tracking_transparency: ^2.0.6 + app_tracking_transparency: ^2.0.6+1 # dio: ^5.7.0 # crypto: ^3.0.5 freezed_annotation: ^2.4.4