diff --git a/analysis_options.yaml b/analysis_options.yaml index 78e77505..4934b3e6 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -28,8 +28,10 @@ linter: # Additional information about this file can be found at # https://dart.dev/guides/language/analysis-options - analyzer: + errors: + curly_braces_in_flow_control_structures: ignore + use_build_context_synchronously: ignore exclude: - lib/custom_code/** - lib/flutter_flow/custom_functions.dart diff --git a/lib/backend/api_requests/api_calls.dart b/lib/backend/api_requests/api_calls.dart index 4665a13e..7b8c30e2 100644 --- a/lib/backend/api_requests/api_calls.dart +++ b/lib/backend/api_requests/api_calls.dart @@ -24,20 +24,17 @@ class PhpGroup { 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(); @@ -54,6 +51,103 @@ class PhpGroup { static GetPets getPets = GetPets(); static GetPetPhoto getPetPhoto = GetPetPhoto(); static UnregisterDevice unregisterDevice = UnregisterDevice(); + static GetVehiclesByProperty getVehiclesByProperty = GetVehiclesByProperty(); + static GetResidentsByProperty getResidentsByProperty = GetResidentsByProperty(); + static GetOpenedVisits getOpenedVisits = GetOpenedVisits(); +} + +class GetOpenedVisits { + Future call(final String page) async { + final String baseUrl = PhpGroup.getBaseUrl(); + final String devUUID = StorageUtil().devUUID; + final String userUUID = StorageUtil().userUUID; + final String cliID = StorageUtil().cliUUID; + const String atividade = 'getOpenedVisits'; + const String pageSize = '10'; + return ApiManager.instance.makeApiCall( + callName: 'getOpenedVisits', + apiUrl: '$baseUrl/processRequest.php', + callType: ApiCallType.POST, + headers: {'Content-Type': 'application/x-www-form-urlencoded'}, + params: { + 'devUUID': devUUID, + 'userUUID': userUUID, + 'cliID': cliID, + 'atividade': atividade, + 'page': page, + 'pageSize': pageSize, + }, + bodyType: BodyType.X_WWW_FORM_URL_ENCODED, + returnBody: true, + encodeBodyUtf8: false, + decodeUtf8: false, + cache: false, + isStreamingApi: false, + alwaysAllowBody: false, + ); + } +} + +class GetResidentsByProperty { + Future call(final String page) async { + final String baseUrl = PhpGroup.getBaseUrl(); + final String devUUID = StorageUtil().devUUID; + final String userUUID = StorageUtil().userUUID; + final String cliID = StorageUtil().cliUUID; + const String atividade = 'getResidentsByProperty'; + const String pageSize = '10'; + return ApiManager.instance.makeApiCall( + callName: 'getResidentsByProperty', + apiUrl: '$baseUrl/processRequest.php', + callType: ApiCallType.POST, + headers: {'Content-Type': 'application/x-www-form-urlencoded'}, + params: { + 'devUUID': devUUID, + 'userUUID': userUUID, + 'cliID': cliID, + 'atividade': atividade, + 'page': page, + 'pageSize': pageSize, + }, + bodyType: BodyType.X_WWW_FORM_URL_ENCODED, + returnBody: true, + encodeBodyUtf8: false, + decodeUtf8: false, + cache: false, + alwaysAllowBody: false, + ); + } +} + +class GetVehiclesByProperty { + Future call(final String page) async { + final String baseUrl = PhpGroup.getBaseUrl(); + final String devUUID = StorageUtil().devUUID; + final String userUUID = StorageUtil().userUUID; + final String cliID = StorageUtil().cliUUID; + const String atividade = 'getVehiclesByProperty'; + const String pageSize = '10'; + return ApiManager.instance.makeApiCall( + callName: 'getVehiclesByProperty', + apiUrl: '$baseUrl/processRequest.php', + callType: ApiCallType.POST, + headers: {'Content-Type': 'application/x-www-form-urlencoded'}, + params: { + 'devUUID': devUUID, + 'userUUID': userUUID, + 'cliID': cliID, + 'atividade': atividade, + 'page': page, + 'pageSize': pageSize, + }, + bodyType: BodyType.X_WWW_FORM_URL_ENCODED, + returnBody: true, + encodeBodyUtf8: false, + decodeUtf8: false, + cache: false, + alwaysAllowBody: false, + ); + } } class UnregisterDevice { @@ -155,9 +249,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, @@ -174,7 +266,10 @@ class UpdatePet { } class GetPets { - Future call({final int? page, final int? pageSize,}) async { + Future call({ + final int? page, + final int? pageSize, + }) async { final String baseUrl = PhpGroup.getBaseUrl(); final String devUUID = StorageUtil().devUUID; @@ -276,9 +371,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, @@ -652,7 +745,6 @@ class RegisterCall { } } - class ChangePasswordCall { Future call({ required final String email, @@ -696,7 +788,6 @@ class ForgotPasswordCall { }) async { final String baseUrl = PhpGroup.getBaseUrl(); - return ApiManager.instance.makeApiCall( callName: 'forgotPassword', apiUrl: '$baseUrl/iforgot.php', @@ -1181,8 +1272,7 @@ class GetDadosCall { response, r'''$.error_msg''', )); - String? visitedDesNomeStr(dynamic response) => - castToType(getJsonField( + String? visitedDesNomeStr(dynamic response) => castToType(getJsonField( response, r'''$.visitado.DES_NOME''', )); @@ -1190,33 +1280,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''', )); @@ -1264,8 +1348,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''', )); @@ -1334,8 +1417,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, @@ -1353,8 +1435,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, @@ -1944,7 +2025,6 @@ class RespondeSolicitacaoCall { )); } - class GetAccessCall { Future call({ final String? pageSize, @@ -2195,6 +2275,7 @@ class GetAccessCall { .withoutNulls .toList(); } + class GetLiberationsCall { Stream call() { final String baseUrl = PhpGroup.getBaseUrl(); @@ -2384,6 +2465,7 @@ class GetLiberationsCall { .withoutNulls .toList(); } + class GetMessagesCall { Future call({ final String? pageSize, @@ -2438,8 +2520,7 @@ class ApiPagingParams { }); @override - String toString() => - 'PagingParams(nextPageNumber: $nextPageNumber, numItems: $numItems, lastResponse: $lastResponse,)'; + String toString() => 'PagingParams(nextPageNumber: $nextPageNumber, numItems: $numItems, lastResponse: $lastResponse,)'; } String _toEncodable(dynamic item) { diff --git a/lib/backend/schema/enums/enums.dart b/lib/backend/schema/enums/enums.dart index 029e9293..3013905b 100644 --- a/lib/backend/schema/enums/enums.dart +++ b/lib/backend/schema/enums/enums.dart @@ -22,8 +22,7 @@ extension FFEnumExtensions on T { } extension FFEnumListExtensions on Iterable { - T? deserialize(String? value) => - firstWhereOrNull((e) => e.serialize() == value); + T? deserialize(String? value) => firstWhereOrNull((e) => e.serialize() == value); } T? deserializeEnum(String? value) { diff --git a/lib/components/atomic_components/menu_button_item/menu_button_item_widget.dart b/lib/components/atomic_components/menu_button_item/menu_button_item_widget.dart index 44724d64..ecdd1d31 100644 --- a/lib/components/atomic_components/menu_button_item/menu_button_item_widget.dart +++ b/lib/components/atomic_components/menu_button_item/menu_button_item_widget.dart @@ -2,27 +2,24 @@ import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:hub/components/molecular_components/menu_item/menu_item.dart'; import 'package:hub/flutter_flow/flutter_flow_theme.dart'; -import 'package:hub/shared/utils/dialog_util.dart'; -import 'package:hub/shared/utils/storage_util.dart'; - -import '../../../shared/extensions/dialog_extensions.dart'; -import '../../../shared/services/localization/localization_service.dart'; - +import 'package:hub/shared/extensions/dialog_extensions.dart'; +import 'package:hub/shared/services/localization/localization_service.dart'; class MenuButtonWidget extends MenuEntry { const MenuButtonWidget({ super.key, - this.action, - this.title, - this.icon, - }); + required this.action, + required this.title, + required this.icon, + required super.safeSetState, + }) : super(action: action, title: title, icon: icon); @override - final Function()? action; + final Function() action; @override - final String? title; + final String title; @override - final IconData? icon; + final IconData icon; @override _MenuButtonWidgetState createState() => _MenuButtonWidgetState(); @@ -32,7 +29,6 @@ class _MenuButtonWidgetState extends State { get action => action; bool _isProcessing = false; - @override Widget build(BuildContext context) { return InkWell( @@ -40,21 +36,23 @@ class _MenuButtonWidgetState extends State { focusColor: Colors.transparent, hoverColor: Colors.transparent, highlightColor: Colors.transparent, - onTap: _isProcessing ? null : () async { - setState(() { - _isProcessing = true; - }); - await LocalizationService.processLocals(context).then((value) async { - if (value) { - await widget.action?.call(); - } else { - DialogUnavailable.unavailableCredentials(context); - } - }); - setState(() { - _isProcessing = false; - }); - }, + onTap: _isProcessing + ? null + : () async { + setState(() { + _isProcessing = true; + }); + await LocalizationService.processLocals(context).then((value) async { + if (value) { + await widget.action.call(); + } else { + DialogUnavailable.unavailableCredentials(context); + } + }); + setState(() { + _isProcessing = false; + }); + }, child: Padding( padding: const EdgeInsets.symmetric(horizontal: 0, vertical: 0), child: Container( @@ -110,8 +108,7 @@ class _MenuButtonWidgetState extends State { fontSize: 14.0, letterSpacing: 0.0, fontWeight: FontWeight.w500, - useGoogleFonts: - GoogleFonts.asMap().containsKey('Nunito'), + useGoogleFonts: GoogleFonts.asMap().containsKey('Nunito'), ), ), ), diff --git a/lib/components/atomic_components/menu_card_item/menu_card_item.dart b/lib/components/atomic_components/menu_card_item/menu_card_item.dart index 04398e5c..0bd0b0f3 100644 --- a/lib/components/atomic_components/menu_card_item/menu_card_item.dart +++ b/lib/components/atomic_components/menu_card_item/menu_card_item.dart @@ -9,17 +9,18 @@ import '../../../shared/services/localization/localization_service.dart'; class MenuCardItem extends MenuEntry { const MenuCardItem({ super.key, - this.action, - this.title, - this.icon, - }); + required this.action, + required this.title, + required this.icon, + required super.safeSetState, + }) : super(action: action, title: title, icon: icon); @override - final Function()? action; + final Function() action; @override - final String? title; + final String title; @override - final IconData? icon; + final IconData icon; @override _MenuCardItemState createState() => _MenuCardItemState(); @@ -36,21 +37,23 @@ class _MenuCardItemState extends State { focusColor: Colors.transparent, hoverColor: Colors.transparent, highlightColor: Colors.transparent, - onTap: _isProcessing ? null : () async { - setState(() { - _isProcessing = true; - }); - await LocalizationService.processLocals(context).then((value) async { - if (value) { - await widget.action?.call(); - } else { - DialogUnavailable.unavailableCredentials(context); - } - }); - setState(() { - _isProcessing = false; - }); - }, + onTap: _isProcessing + ? null + : () async { + setState(() { + _isProcessing = true; + }); + await LocalizationService.processLocals(context).then((value) async { + if (value) { + await widget.action.call(); + } else { + DialogUnavailable.unavailableCredentials(context); + } + }); + setState(() { + _isProcessing = false; + }); + }, child: Card( elevation: 0, color: FlutterFlowTheme.of(context).primaryBackground, @@ -61,8 +64,7 @@ class _MenuCardItemState extends State { Align( alignment: const AlignmentDirectional(-1.0, 0.0), child: Padding( - padding: - const EdgeInsetsDirectional.fromSTEB(8.0, 0.0, 10.0, 0.0), + padding: const EdgeInsetsDirectional.fromSTEB(8.0, 0.0, 10.0, 0.0), child: Container( width: 30.0, height: 30.0, diff --git a/lib/components/molecular_components/menu_item/menu_item.dart b/lib/components/molecular_components/menu_item/menu_item.dart index ce3aac0a..fe97affd 100644 --- a/lib/components/molecular_components/menu_item/menu_item.dart +++ b/lib/components/molecular_components/menu_item/menu_item.dart @@ -1,14 +1,38 @@ import 'package:flutter/material.dart'; +enum MenuOption { + CompleteSchedule, + DeliverySchedule, + WorkersOnTheProperty, + FastPassSchedule, + QRCodeAccessInProperty, + AccessOnTheProperty, + LiberationsOnTheProperty, + MessagesOnTheProperty, + ReservationsOnTheLocal, + PackagesOnTheProperty, + VehiclesOnTheProperty, + PetsOnTheProperty, + PetsRegister, + VisitorsRegister, + VisitsOnTheProperty, + ResidentsOnTheProperty, + SettingsOnTheApp, + AboutProperty, + LogoutOnTheApp, +} + abstract class MenuEntry extends StatefulWidget { const MenuEntry({ super.key, - this.action, - this.title, - this.icon, + required this.action, + required this.title, + required this.icon, + required this.safeSetState, }); - final Function()? action; - final String? title; - final IconData? icon; + final Function() action; + final String title; + final IconData icon; + final VoidCallback safeSetState; } diff --git a/lib/components/organism_components/menu_component/menu_component_model.dart b/lib/components/organism_components/menu_component/menu_component_model.dart index 7b4934f1..0d98e9f0 100644 --- a/lib/components/organism_components/menu_component/menu_component_model.dart +++ b/lib/components/organism_components/menu_component/menu_component_model.dart @@ -1,52 +1,195 @@ import 'package:flutter/material.dart'; +import 'package:hub/backend/schema/enums/enums.dart'; +import 'package:hub/components/atomic_components/menu_button_item/menu_button_item_widget.dart'; +import 'package:hub/components/atomic_components/menu_card_item/menu_card_item.dart'; +import 'package:hub/components/molecular_components/menu_item/menu_item.dart'; +import 'package:hub/components/molecular_components/option_selection_modal/option_selection_modal_widget.dart'; +import 'package:hub/components/organism_components/menu_component/menu_component_widget.dart'; +import 'package:hub/components/organism_components/menu_list_view_component/menu_list_view_component_model.dart'; import 'package:hub/components/organism_components/menu_staggered_view_component/menu_staggered_view_component_model.dart'; +import 'package:hub/flutter_flow/flutter_flow_util.dart'; import 'package:hub/flutter_flow/nav/nav.dart'; import 'package:hub/shared/extensions/dialog_extensions.dart'; import 'package:hub/shared/services/authentication/authentication_service.dart'; import 'package:hub/shared/utils/storage_util.dart'; - -import '../../../shared/services/localization/localization_service.dart'; -import '/components/molecular_components/option_selection_modal/option_selection_modal_widget.dart'; -import '/components/organism_components/menu_list_view_component/menu_list_view_component_widget.dart'; -import '/flutter_flow/flutter_flow_util.dart'; -import 'menu_component_widget.dart' show MenuComponentWidget; +import 'package:material_symbols_icons/symbols.dart'; class MenuComponentModel extends FlutterFlowModel { + final MenuView style; + final MenuItem item; + final bool expandable; + final List menuOptions; + + MenuComponentModel({required this.style, required this.item, required this.expandable, required this.menuOptions}); bool isGrid = false; late MenuListViewComponentModel menuListViewComponentModel; late MenuStaggeredViewComponentModel menuStaggeredViewComponentModel; + late VoidCallback safeSetState; + late List menuEntries; - @override void initState(BuildContext context) { - menuListViewComponentModel = - createModel(context, () => MenuListViewComponentModel()); - menuStaggeredViewComponentModel = - createModel(context, () => MenuStaggeredViewComponentModel()); + @override + void initState(BuildContext context) { + menuListViewComponentModel = createModel(context, () => MenuListViewComponentModel()); + menuStaggeredViewComponentModel = createModel(context, () => MenuStaggeredViewComponentModel()); } - @override void dispose() { + + @override + void dispose() { menuListViewComponentModel.dispose(); menuStaggeredViewComponentModel.dispose(); } - Future changeMenuStyle(BuildContext context) async { - isGrid = !isGrid; + List generateMenuEntries(BuildContext context, MenuItem item, List options) { + List entries = []; + MenuEntry? addMenuEntry(IconData icon, String enText, String ptText, Function() action) { + entries.add( + item == MenuItem.button + ? MenuButtonWidget(icon: icon, action: action, title: FFLocalizations.of(context).getVariableText(enText: enText, ptText: ptText), safeSetState: safeSetState) + : item == MenuItem.card + ? MenuCardItem(icon: icon, action: action, title: FFLocalizations.of(context).getVariableText(enText: enText, ptText: ptText), safeSetState: safeSetState) + : item == MenuItem.tile + ? MenuCardItem(icon: icon, action: action, title: FFLocalizations.of(context).getVariableText(enText: enText, ptText: ptText), safeSetState: safeSetState) + : null, + ); + return null; + } + + /// ABOUT THE VISITORS + if (options.contains(MenuOption.VisitorsRegister)) + addMenuEntry(Icons.person_add_alt_1_outlined, 'Register Visitor', 'Cadastrar Visitante', () async { + await open(context, '/registerVisitorPage'); + safeSetState; + }); + if (options.contains(MenuOption.WorkersOnTheProperty)) + addMenuEntry(Icons.engineering_outlined, 'Schedule Providers', 'Agendar Prestadores', () async { + if (StorageUtil().provisional) + await open(context, '/provisionalSchedule'); + else + DialogUnavailable.unavailableFeature(context); + safeSetState; + }); + if (options.contains(MenuOption.DeliverySchedule)) + addMenuEntry(Icons.sports_motorsports_outlined, 'Schedule Deliveries', 'Agendar Entregas', () async { + if (StorageUtil().provisional) + await open(context, '/deliverySchedule'); + else + DialogUnavailable.unavailableFeature(context); + safeSetState; + }); + if (options.contains(MenuOption.FastPassSchedule)) + addMenuEntry(Icons.attach_email_outlined, 'Invite Visitor', 'Convidar Visitante', () async { + if (StorageUtil().whatsapp) + await open(context, '/fastPassPage'); + else + DialogUnavailable.unavailableFeature(context); + safeSetState; + }); + if (options.contains(MenuOption.CompleteSchedule)) + addMenuEntry(Icons.event, 'Complete Schedule', 'Agenda Completa', () async { + await open(context, '/scheduleCompleteVisitPage'); + safeSetState; + }); + + /// ABOUT THE PROPERTY + if (options.contains(MenuOption.AboutProperty)) + addMenuEntry(Icons.home, 'About Property', 'Sobre a Propriedade', () async { + if (StorageUtil().whatsapp) + await open(context, '/aboutProperty'); + else + DialogUnavailable.unavailableFeature(context); + safeSetState; + }); + if (options.contains(MenuOption.PetsOnTheProperty)) + addMenuEntry(Icons.pets, 'My Pets', 'Meus Pets', () async { + if (StorageUtil().pets) + await open(context, '/petsOnThePropertyPage'); + else + DialogUnavailable.unavailableFeature(context); + safeSetState; + }); + if (options.contains(MenuOption.ResidentsOnTheProperty)) + addMenuEntry(Icons.groups, 'Live With Me', 'Moram Comigo', () async { + await open(context, '/peopleOnThePropertyPage'); + safeSetState; + }); + if (options.contains(MenuOption.VehiclesOnTheProperty)) + addMenuEntry(Symbols.directions_car, 'My Vehicles', 'Meus Veículos', () async { + await open(context, '/vehiclesOnThePropertyPage'); + safeSetState; + }); + if (options.contains(MenuOption.VisitsOnTheProperty)) + addMenuEntry(Symbols.perm_contact_calendar, 'Opened Visits', 'Visitas em Aberto', () async { + await open(context, '/visitsOnThePropertyPage'); + safeSetState; + }); + if (options.contains(MenuOption.PackagesOnTheProperty)) + addMenuEntry(Icons.inventory_2_outlined, 'My Orders', 'Minhas Encomendas', () async { + if (StorageUtil().whatsapp) + await open(context, '/packageOrder'); + else + DialogUnavailable.unavailableFeature(context); + safeSetState; + }); + + /// ABOUT THE RESIDENTS + if (options.contains(MenuOption.PetsRegister)) + addMenuEntry(Icons.pets, 'Pets Register', 'Cadastrar Pet', () async { + if (StorageUtil().pets) + await open(context, '/petsPage'); + else + DialogUnavailable.unavailableFeature(context); + safeSetState; + }); + if (options.contains(MenuOption.ReservationsOnTheLocal)) + addMenuEntry(Icons.event_available, 'Reservations', 'Reservas', () async { + if (StorageUtil().whatsapp) + await open(context, '/reservation'); + else + DialogUnavailable.unavailableFeature(context); + + safeSetState; + }); + if (options.contains(MenuOption.QRCodeAccessInProperty)) + addMenuEntry(Icons.qr_code, 'QRCode Access', 'QRCode de Acesso', () async { + await open(context, '/qrCodePage'); + safeSetState; + }); + if (options.contains(MenuOption.AccessOnTheProperty)) + addMenuEntry(Icons.transfer_within_a_station_outlined, 'Access History', 'Consultar Acessos', () async { + await open(context, '/acessHistoryPage'); + safeSetState; + }); + if (options.contains(MenuOption.LiberationsOnTheProperty)) + addMenuEntry(Icons.how_to_reg_outlined, 'Liberations History', 'Consultar Liberações', () async { + await open(context, '/liberationHistory'); + safeSetState; + }); + if (options.contains(MenuOption.MessagesOnTheProperty)) + addMenuEntry(Icons.chat_outlined, 'Message History', 'Consultar Mensagens', () async { + await open(context, '/messageHistoryPage'); + safeSetState; + }); + + /// ABOUT THE SYSTEM + if (options.contains(MenuOption.SettingsOnTheApp)) + addMenuEntry(Icons.settings, 'System Settings', 'Opções do Sistema', () async { + await open(context, '/preferencesSettings'); + safeSetState; + }); + if (options.contains(MenuOption.LogoutOnTheApp)) + addMenuEntry(Icons.logout, 'Logout', 'Sair', () async { + await out(context); + safeSetState; + }); + + return entries; } - Future openQRCodeScanner(BuildContext context) async { - context.push( - '/qrCodePage', - extra: { - kTransitionInfoKey: const TransitionInfo( - hasTransition: true, - transitionType: PageTransitionType.scale, - alignment: Alignment.bottomCenter, - ), - }, - ); - } - Future openCompleteSchedule(BuildContext context) async { + + Future open(BuildContext context, String link) async { context.push( - '/scheduleCompleteVisitPage', + link, extra: { kTransitionInfoKey: const TransitionInfo( hasTransition: true, @@ -56,57 +199,20 @@ class MenuComponentModel extends FlutterFlowModel { }, ); } - Future openDeliverySchedule(BuildContext context) async { - final bool isProvisional = StorageUtil().provisional; - if (isProvisional == true) { - context.push( - '/deliverySchedule', - extra: { - kTransitionInfoKey: const TransitionInfo( - hasTransition: true, - transitionType: PageTransitionType.scale, - alignment: Alignment.bottomCenter, - ), - }, - ); - } else { - DialogUnavailable.unavailableFeature(context); - } - } - Future openProvisionalSchedule(BuildContext context) async { - final isProvisional = StorageUtil().provisional; - if (isProvisional == true) { - context.push( - '/provisionalSchedule', - extra: { - kTransitionInfoKey: const TransitionInfo( - hasTransition: true, - transitionType: PageTransitionType.scale, - alignment: Alignment.bottomCenter, - ), - }, - ); - } else { - DialogUnavailable.unavailableFeature(context); - } + + Future out(BuildContext context) async { + final String title = FFLocalizations.of(context).getVariableText( + ptText: 'Sair', + enText: 'Logout', + ); + final String content = FFLocalizations.of(context).getVariableText( + ptText: 'Tem certeza que deseja sair?', + enText: 'Are you sure you want to logout?', + ); + showAlertDialog(context, title, content, () async => await AuthenticationService.signOut(context)); } - Future openFastPassSchedule(BuildContext context) async { - final isWpp = StorageUtil().whatsapp; - if (isWpp) { - context.push( - '/fastPassPage', - extra: { - kTransitionInfoKey: const TransitionInfo( - hasTransition: true, - transitionType: PageTransitionType.scale, - alignment: Alignment.bottomCenter, - ), - }, - ); - } else { - DialogUnavailable.unavailableFeature(context); - } - } + + /// LEGACY FEATURES Future showSchedules(BuildContext context) async { final routesListStr = [ 'scheduleProvisionalVisitPage', @@ -146,91 +252,7 @@ class MenuComponentModel extends FlutterFlowModel { }, ); } - Future openVisitorsRegister(BuildContext context) async { - context.push( - '/registerVisitorPage', - extra: { - kTransitionInfoKey: const TransitionInfo( - hasTransition: true, - transitionType: PageTransitionType.scale, - alignment: Alignment.bottomCenter, - ), - }, - ); - } - Future openPoepleOnTheProperty(BuildContext context) async { - context.push( - '/peopleOnThePropertyPage', - extra: { - kTransitionInfoKey: const TransitionInfo( - hasTransition: true, - transitionType: PageTransitionType.scale, - alignment: Alignment.bottomCenter, - ), - }, - ); - } - Future Logout(BuildContext context) async { - final String title = FFLocalizations.of(context).getVariableText( - ptText: 'Sair', - enText: 'Logout', - ); - final String content = FFLocalizations.of(context).getVariableText( - ptText: 'Tem certeza que deseja sair?', - enText: 'Are you sure you want to logout?', - ); - showAlertDialog( - context, - title, - content, - () async => await AuthenticationService.signOut(context)); - } - Future openPreferencesSettings(BuildContext context) async { - context.push( - '/preferencesSettings', - extra: { - kTransitionInfoKey: const TransitionInfo( - hasTransition: true, - transitionType: PageTransitionType.scale, - alignment: Alignment.bottomCenter, - ), - }, - ); - } - Future openMyOrders(BuildContext context) async { - final isWpp = StorageUtil().whatsapp; - if (isWpp) { - context.push( - '/packageOrder', - extra: { - kTransitionInfoKey: const TransitionInfo( - hasTransition: true, - transitionType: PageTransitionType.scale, - alignment: Alignment.bottomCenter, - ), - }, - ); - } else { - DialogUnavailable.unavailableFeature(context); - } - } - Future openReservations(BuildContext context) async { - final isWpp = StorageUtil().whatsapp; - if (isWpp) { - context.push( - '/reservation', - extra: { - kTransitionInfoKey: const TransitionInfo( - hasTransition: true, - transitionType: PageTransitionType.scale, - alignment: Alignment.bottomCenter, - ), - }, - ); - } else { - DialogUnavailable.unavailableFeature(context); - } - } + Future showHistories(BuildContext context) async { await showAdaptiveDialog( // isScrollControlled: true, @@ -241,12 +263,7 @@ class MenuComponentModel extends FlutterFlowModel { return Padding( padding: MediaQuery.viewInsetsOf(context), child: OptionSelectionModalWidget( - routesListStr: const [ - 'liberationHistory', - 'acessHistoryPage', - 'scheduleCompleteVisitPage', - 'messageHistoryPage' - ], + routesListStr: const ['liberationHistory', 'acessHistoryPage', 'scheduleCompleteVisitPage', 'messageHistoryPage'], iconsListIcon: const [ Icons.history_rounded, Icons.history_rounded, @@ -276,72 +293,4 @@ class MenuComponentModel extends FlutterFlowModel { }, ); } - Future openLiberationsHistory(BuildContext context) async { - context.push( - '/liberationHistory', - extra: { - kTransitionInfoKey: const TransitionInfo( - hasTransition: true, - transitionType: PageTransitionType.scale, - alignment: Alignment.bottomCenter, - ), - }, - ); - } - Future openAccessHistory(BuildContext context) async { - context.push( - '/acessHistoryPage', - extra: { - kTransitionInfoKey: const TransitionInfo( - hasTransition: true, - transitionType: PageTransitionType.scale, - alignment: Alignment.bottomCenter, - ), - }, - ); - } - Future openVisitsHistory(BuildContext context) async { - context.push( - '/scheduleCompleteVisitPage', - extra: { - kTransitionInfoKey: const TransitionInfo( - hasTransition: true, - transitionType: PageTransitionType.scale, - alignment: Alignment.bottomCenter, - ), - }, - ); - } - Future openMessagesHistory(BuildContext context) async { - context.push( - '/messageHistoryPage', - extra: { - kTransitionInfoKey: const TransitionInfo( - hasTransition: true, - transitionType: PageTransitionType.scale, - alignment: Alignment.bottomCenter, - ), - }, - ); - } - Future openPetsRegister(BuildContext context) async { - bool isPet = StorageUtil().pets; - if (isPet) { - context.push( - '/petsPage', - extra: { - kTransitionInfoKey: const TransitionInfo( - hasTransition: true, - transitionType: PageTransitionType.scale, - alignment: Alignment.bottomCenter, - ), - }, - ); - } else { - DialogUnavailable.unavailableFeature(context); - } - } - - } - diff --git a/lib/components/organism_components/menu_component/menu_component_widget.dart b/lib/components/organism_components/menu_component/menu_component_widget.dart index cd940d59..50e1a7c7 100644 --- a/lib/components/organism_components/menu_component/menu_component_widget.dart +++ b/lib/components/organism_components/menu_component/menu_component_widget.dart @@ -12,617 +12,68 @@ import 'menu_component_model.dart'; export 'menu_component_model.dart'; class MenuComponentWidget extends StatefulWidget { - const MenuComponentWidget({ - Key? key, - required this.style, - required this.item, - required this.expandable, - }); - final MenuView style; - final MenuItem item; - final bool expandable; + final MenuComponentModel model; + const MenuComponentWidget({super.key, required this.model}); + @override State createState() => _MenuComponentWidgetState(); } class _MenuComponentWidgetState extends State { - late MenuComponentModel _model; - @override void setState(VoidCallback callback) { super.setState(callback); - _model.onUpdate(); + widget.model.onUpdate(); } @override void initState() { super.initState(); - _model = createModel(context, () => MenuComponentModel()); + widget.model.safeSetState = () => safeSetState(() {}); + } + + @override + void didChangeDependencies() { + super.didChangeDependencies(); + widget.model.menuEntries = widget.model.generateMenuEntries(context, widget.model.item, widget.model.menuOptions); } @override void dispose() { - _model.maybeDispose(); - + widget.model.maybeDispose(); super.dispose(); } - // MenuButtonWidget(icon: FFIcons.kvector2, action: () async {setState(() {});}, title: FFLocalizations.of(context).getVariableText(enText:'Link\nCondominum' , ptText:'' ,),), - // MenuButtonWidget(icon: FFIcons.kpets, action: () async {setState(() {});}, title: FFLocalizations.of(context).getVariableText(enText:'Register\Pet' , ptText:'' ,),), - @override Widget build(BuildContext context) { - final options = () { - if (widget.item == MenuItem.button) { - if (_model.isGrid == true) - return [ - MenuButtonWidget( - icon: FFIcons.kvector1, - action: () async { - await _model.showSchedules(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Schedule\nVisit', - ptText: 'Agendar\nVisita', - ), - ), - MenuButtonWidget( - icon: FFIcons.khome, - action: () async { - await _model.openVisitorsRegister(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Register\nVisitor', - ptText: 'Cadastro\nde Visitante', - ), - ), - MenuButtonWidget( - icon: Icons.qr_code, - action: () async { - await _model.openQRCodeScanner(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'QRCode\nAccess', - ptText: 'QRCode\nde Acesso', - ), - ), - MenuButtonWidget( - icon: Icons.pets, - action: () async { - await _model.openPetsRegister(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Pets\nRegister', - ptText: 'Cadastro\nde Pet', - ), - ), - MenuButtonWidget( - icon: Icons.people, - action: () async { - await _model.openPoepleOnTheProperty(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'People on\nthe Property', - ptText: 'Pessoas na\nPropriedade', - ), - ), - MenuButtonWidget( - icon: Icons.history_sharp, - action: () async { - await _model.showHistories(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Consult\nHistories', - ptText: 'Consultar\nHistóricos', - ), - ), - MenuButtonWidget( - icon: Icons.settings, - action: () async { - await _model.openPreferencesSettings(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Preferences\nSettings', - ptText: 'Opções\ndo Sistema', - ), - ), - ]; - else - return [ - MenuButtonWidget( - icon: Icons.engineering_outlined, - action: () async { - await _model.openProvisionalSchedule(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Schedule\nProviders', - ptText: 'Agendar\nPrestadores', - ), - ), - MenuButtonWidget( - icon: Icons.sports_motorsports_outlined, - action: () async { - await _model.openDeliverySchedule(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Schedule\nDeliveries', - ptText: 'Agendar\nEntregas', - ), - ), - MenuButtonWidget( - icon: Icons.attach_email_outlined, - action: () async { - await _model.openFastPassSchedule(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - ptText: 'Convidar\nVisitante', - enText: 'Invite\nVisitor', - ), - ), - MenuButtonWidget( - icon: Icons.event, - action: () async { - await _model.openCompleteSchedule(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Complete\nSchedule', - ptText: 'Agenda\nCompleta', - ), - ), - MenuButtonWidget( - icon: Icons.inventory_2_outlined, - action: () async { - await _model.openMyOrders(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - ptText: 'Minhas\nEncomendas', - enText: 'My\nOrders', - ), - ), - MenuButtonWidget( - icon: Icons.event_available, - action: () async { - await _model.openReservations(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - ptText: 'Reservas', - enText: 'Reservations', - ), - ), - MenuButtonWidget( - icon: Icons.person_add_alt_1_outlined, - action: () async { - await _model.openVisitorsRegister(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Register\nVisitor', - ptText: 'Cadastrar\nVisitante', - ), - ), - MenuButtonWidget( - icon: Icons.qr_code, - action: () async { - await _model.openQRCodeScanner(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'QRCode\nAccess', - ptText: 'QRCode\nde Acesso', - ), - ), - MenuButtonWidget( - icon: Icons.pets, - action: () async { - await _model.openPetsRegister(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Pets\nRegister', - ptText: 'Cadastrar\nPet', - ), - ), - MenuButtonWidget( - icon: Icons.transfer_within_a_station_outlined, - action: () async { - await _model.openAccessHistory(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Access\nHistory', - ptText: 'Consultar\nAcessos', - ), - ), - MenuButtonWidget( - icon: Icons.how_to_reg_outlined, - action: () async { - await _model.openLiberationsHistory(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Liberations\nHistory', - ptText: 'Consultar\nLiberações', - ), - ), - MenuButtonWidget( - icon: Icons.chat_outlined, - action: () async { - await _model.openMessagesHistory(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Message\nHistory', - ptText: 'Consultar\nMensagens', - ), - ), - MenuButtonWidget( - icon: Icons.groups, - action: () async { - await _model.openPoepleOnTheProperty(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'People on\nthe Property', - ptText: 'Pessoas na\nPropriedade', - ), - ), - MenuButtonWidget( - icon: Icons.settings, - action: () async { - await _model.openPreferencesSettings(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'System\n Settings', - ptText: 'Opções\ndo Sistema', - ), - ), - ]; - } - if (widget.item == MenuItem.card) { - return [ - MenuCardItem( - icon: FFIcons.kvector1, - action: () async { - await _model.showSchedules(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Schedule\nVisit', - ptText: 'Agendar\nVisita', - ), - ), - MenuCardItem( - icon: FFIcons.khome, - action: () async { - await _model.openVisitorsRegister(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Register\nVisitor', - ptText: 'Cadastro\nde Visitante', - ), - ), - MenuCardItem( - icon: Icons.qr_code, - action: () async { - await _model.openQRCodeScanner(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'QRCode\nAccess', - ptText: 'QRCode\nde Acesso', - ), - ), - MenuCardItem( - icon: Icons.people, - action: () async { - await _model.openPoepleOnTheProperty(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'People on\nthe Property', - ptText: 'Pessoas\nna Propriedade', - ), - ), - MenuCardItem( - icon: Icons.history_sharp, - action: () async { - await _model.showHistories(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Consult\nHistories', - ptText: 'Consultar\nHistoricos', - ), - ), - MenuCardItem( - icon: Icons.inventory_2_rounded, - action: () async { - await _model.openMyOrders(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Orders', - ptText: 'Encomendas', - ), - ), - MenuButtonWidget( - icon: Icons.pets, - action: () async { - await _model.openPetsRegister(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Pets\nRegister', - ptText: 'Cadastrar\nPet', - ), - ), - MenuCardItem( - icon: Icons.event_available, - action: () async { - await _model.openReservations(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Reservations', - ptText: 'Reservas', - ), - ), - MenuCardItem( - icon: Icons.settings, - action: () async { - await _model.openPreferencesSettings(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Preferences\nSettings', - ptText: 'Preferências\nde Configuração', - ), - ), - ]; - } - // if (MenuItem.tile) - return [ - MenuCardItem( - icon: Icons.engineering_outlined, - action: () async { - await _model.openProvisionalSchedule(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Schedule Providers', - ptText: 'Agendar Prestadores', - ), - ), - MenuCardItem( - icon: Icons.sports_motorsports_outlined, - action: () async { - await _model.openDeliverySchedule(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Schedule Deliveries', - ptText: 'Agendar Entregas', - ), - ), - MenuCardItem( - icon: Icons.attach_email_outlined, - action: () async { - await _model.openFastPassSchedule(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - ptText: 'Convidar Visitante', - enText: 'Invite Visitor', - ), - ), - MenuCardItem( - icon: Icons.event, - action: () async { - await _model.openCompleteSchedule(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Complete Schedule', - ptText: 'Agenda Completa', - ), - ), - MenuCardItem( - icon: Icons.inventory_2_outlined, - action: () async { - await _model.openMyOrders(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - ptText: 'Minhas Encomendas', - enText: 'My Orders', - ), - ), - MenuCardItem( - icon: Icons.event_available, - action: () async { - await _model.openReservations(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - ptText: 'Reservas', - enText: 'Reservations', - ), - ), - MenuCardItem( - icon: Icons.person_add_alt_1_outlined, - action: () async { - await _model.openVisitorsRegister(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Register Visitor', - ptText: 'Cadastrar Visitante', - ), - ), - MenuCardItem( - icon: Icons.qr_code, - action: () async { - await _model.openQRCodeScanner(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'QRCode Access', - ptText: 'QRCode de Acesso', - ), - ), - MenuCardItem( - icon: Icons.pets, - action: () async { - await _model.openPetsRegister(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Pets Register', - ptText: 'Cadastro de Pet', - ), - ), - MenuCardItem( - icon: Icons.transfer_within_a_station_outlined, - action: () async { - await _model.openAccessHistory(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Access History', - ptText: 'Consultar Acessos', - ), - ), - MenuCardItem( - icon: Icons.how_to_reg_outlined, - action: () async { - await _model.openLiberationsHistory(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Liberations History', - ptText: 'Consultar Liberações', - ), - ), - MenuCardItem( - icon: Icons.chat_outlined, - action: () async { - await _model.openMessagesHistory(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Message History', - ptText: 'Consultar Mensagens', - ), - ), - MenuCardItem( - icon: Icons.groups, - action: () async { - await _model.openPoepleOnTheProperty(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'People on the Property', - ptText: 'Pessoas na Propriedade', - ), - ), - MenuCardItem( - icon: Icons.settings, - action: () async { - await _model.openPreferencesSettings(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'System Settings', - ptText: 'Opções do Sistema', - ), - ), - MenuCardItem( - icon: Icons.logout, - action: () async { - await _model.Logout(context); - setState(() {}); - }, - title: FFLocalizations.of(context).getVariableText( - enText: 'Logout Account', - ptText: 'Sair da Conta', - ), - ), - MenuCardItem(icon: null, action: () {}, title: ''), - ]; - }(); - return Builder( builder: (context) { - if (widget.style == MenuView.list_grid && - widget.expandable == true && - widget.item == MenuItem.button) { - if (_model.isGrid == true) { - return wrapWithModel( - model: _model.menuStaggeredViewComponentModel, - updateCallback: () => setState(() {}), - updateOnChange: true, - child: MenuStaggeredViewComponentWidget( - options: options, - expandable: widget.expandable, - item: widget.item, - changeMenuStyle: () async { - await _model.changeMenuStyle(context); - setState(() {}); - }, - isGrid: _model.isGrid, - ), - ); - } else { - return wrapWithModel( - model: _model.menuStaggeredViewComponentModel, - updateCallback: () => setState(() {}), - updateOnChange: true, - child: MenuStaggeredViewComponentWidget( - options: options, - expandable: widget.expandable, - item: widget.item, - changeMenuStyle: () async { - await _model.changeMenuStyle(context); - setState(() {}); - }, - isGrid: _model.isGrid, - ), - ); - } - } - if (widget.style == MenuView.list && - widget.expandable == false && - widget.item == MenuItem.tile) { + if (widget.model.style == MenuView.list_grid) return wrapWithModel( - model: _model.menuListViewComponentModel, + model: widget.model.menuStaggeredViewComponentModel, + updateCallback: () => setState(() {}), + updateOnChange: true, + child: MenuStaggeredViewComponentWidget( + options: widget.model.menuEntries, + expandable: widget.model.expandable, + item: widget.model.item, + changeMenuStyle: () async {}, + isGrid: widget.model.isGrid, + ), + ); + if (widget.model.style == MenuView.list) + return wrapWithModel( + model: widget.model.menuListViewComponentModel, updateCallback: () => setState(() {}), updateOnChange: true, child: MenuListViewComponentWidget( - options: options, - expandable: widget.expandable, - item: widget.item, - changeMenuStyle: () async { - await _model.changeMenuStyle(context); - setState(() {}); - }, + options: widget.model.menuEntries, + expandable: widget.model.expandable, + item: widget.model.item, + changeMenuStyle: () async {}, ), ); - } + return const SizedBox(); }, ); diff --git a/lib/components/organism_components/menu_list_view_component/menu_list_view_component_model.dart b/lib/components/organism_components/menu_list_view_component/menu_list_view_component_model.dart index 027278ab..d15273ee 100644 --- a/lib/components/organism_components/menu_list_view_component/menu_list_view_component_model.dart +++ b/lib/components/organism_components/menu_list_view_component/menu_list_view_component_model.dart @@ -2,13 +2,10 @@ import '/flutter_flow/flutter_flow_util.dart'; import 'menu_list_view_component_widget.dart' show MenuListViewComponentWidget; import 'package:flutter/material.dart'; - - -class MenuListViewComponentModel - extends FlutterFlowModel { +class MenuListViewComponentModel extends FlutterFlowModel { @override void initState(BuildContext context) {} @override void dispose() {} -} \ No newline at end of file +} diff --git a/lib/components/organism_components/menu_list_view_component/menu_list_view_component_widget.dart b/lib/components/organism_components/menu_list_view_component/menu_list_view_component_widget.dart index c16e3669..88f6153e 100644 --- a/lib/components/organism_components/menu_list_view_component/menu_list_view_component_widget.dart +++ b/lib/components/organism_components/menu_list_view_component/menu_list_view_component_widget.dart @@ -23,16 +23,14 @@ class MenuListViewComponentWidget extends StatefulWidget { final bool expandable; final MenuItem item; - final List options; + final List options; final Future Function()? changeMenuStyle; @override - State createState() => - _MenuListViewComponentWidgetState(); + State createState() => _MenuListViewComponentWidgetState(); } -class _MenuListViewComponentWidgetState - extends State { +class _MenuListViewComponentWidgetState extends State { late MenuListViewComponentModel _model; @override @@ -75,8 +73,7 @@ class _MenuListViewComponentWidgetState itemBuilder: (context, index) { return Padding( padding: const EdgeInsets.all(8.0), - child: SizedBox( - height: 115, width: 115, child: widget.options[index]), + child: SizedBox(height: 115, width: 115, child: widget.options[index]), ); }, ), @@ -95,8 +92,7 @@ class _MenuListViewComponentWidgetState itemBuilder: (context, index) { return Padding( padding: const EdgeInsets.all(8.0), - child: SizedBox( - height: 115, width: 115, child: widget.options[index]), + child: SizedBox(height: 115, width: 115, child: widget.options[index]), ); }, ), diff --git a/lib/components/organism_components/menu_staggered_view_component/menu_staggered_view_component_model.dart b/lib/components/organism_components/menu_staggered_view_component/menu_staggered_view_component_model.dart index 4ee29584..cb0efe51 100644 --- a/lib/components/organism_components/menu_staggered_view_component/menu_staggered_view_component_model.dart +++ b/lib/components/organism_components/menu_staggered_view_component/menu_staggered_view_component_model.dart @@ -4,12 +4,10 @@ import '/flutter_flow/flutter_flow_util.dart'; import 'package:flutter/material.dart'; - -class MenuStaggeredViewComponentModel - extends FlutterFlowModel { +class MenuStaggeredViewComponentModel extends FlutterFlowModel { @override void initState(BuildContext context) {} @override void dispose() {} -} \ No newline at end of file +} diff --git a/lib/components/organism_components/menu_staggered_view_component/menu_staggered_view_component_widget.dart b/lib/components/organism_components/menu_staggered_view_component/menu_staggered_view_component_widget.dart index ef9d3f46..4adbb83d 100644 --- a/lib/components/organism_components/menu_staggered_view_component/menu_staggered_view_component_widget.dart +++ b/lib/components/organism_components/menu_staggered_view_component/menu_staggered_view_component_widget.dart @@ -7,28 +7,20 @@ import 'package:hub/flutter_flow/flutter_flow_theme.dart'; import 'package:hub/flutter_flow/flutter_flow_util.dart'; class MenuStaggeredViewComponentWidget extends StatefulWidget { - const MenuStaggeredViewComponentWidget( - {super.key, - required this.changeMenuStyle, - required this.expandable, - required this.item, - required this.options, - required this.isGrid}); + const MenuStaggeredViewComponentWidget({super.key, required this.changeMenuStyle, required this.expandable, required this.item, required this.options, required this.isGrid}); final bool expandable; final MenuItem item; final bool isGrid; - final List options; + final List options; final Future Function()? changeMenuStyle; @override - State createState() => - _MenuStaggeredViewComponentWidgetState(); + State createState() => _MenuStaggeredViewComponentWidgetState(); } -class _MenuStaggeredViewComponentWidgetState - extends State { +class _MenuStaggeredViewComponentWidgetState extends State { late MenuStaggeredViewComponentModel _model; @override @@ -87,9 +79,7 @@ class _MenuStaggeredViewComponentWidgetState ); }, ), - ] - .addToStart(const SizedBox(height: 30)) - .addToEnd(const SizedBox(height: 30)), + ].addToStart(const SizedBox(height: 30)).addToEnd(const SizedBox(height: 30)), ); } diff --git a/lib/flutter_flow/nav/nav.dart b/lib/flutter_flow/nav/nav.dart index 3fcf2daf..bbcd1463 100644 --- a/lib/flutter_flow/nav/nav.dart +++ b/lib/flutter_flow/nav/nav.dart @@ -2,32 +2,43 @@ import 'dart:async'; import 'dart:developer'; import 'package:flutter/material.dart'; +import 'package:hub/backend/schema/util/schema_util.dart'; +import 'package:hub/flutter_flow/flutter_flow_util.dart'; import 'package:hub/flutter_flow/nav/nav.dart'; +import 'package:hub/pages/about_property_page/about_property_screen.dart'; +import 'package:hub/pages/acess_history_page/acess_history_page_widget.dart'; import 'package:hub/pages/delivery_schedule_page/delivery_schedule_widget.dart'; import 'package:hub/pages/fast_pass_page/fast_pass_page_widget.dart'; import 'package:hub/pages/forgot_password_page/forgot_password_screen.dart'; +import 'package:hub/pages/home_page/home_page_widget.dart'; +import 'package:hub/pages/liberation_history/liberation_history_widget.dart'; import 'package:hub/pages/message_history_page/message_history_page_widget.dart'; import 'package:hub/pages/package_order_page/package_order_page.dart'; +import 'package:hub/pages/people_on_the_property_page/people_on_the_property_page_widget.dart'; +import 'package:hub/pages/pets_on_the_property_page/pets_history_screen.dart'; import 'package:hub/pages/pets_page/pets_page_widget.dart'; +import 'package:hub/pages/preferences_settings_page/preferences_settings_widget.dart'; import 'package:hub/pages/provisional_schedule_page/provisional_schedule_widget.dart'; +import 'package:hub/pages/qr_code_page/qr_code_page_widget.dart'; import 'package:hub/pages/reception_page/reception_page_widget.dart'; +import 'package:hub/pages/register_visitor_page/register_visitor_page_widget.dart'; import 'package:hub/pages/reservation_page/reservation_page_widget.dart'; - +import 'package:hub/pages/schedule_complete_visit_page/schedule_complete_visit_page_widget.dart'; +import 'package:hub/pages/sign_in_page/sign_in_page_widget.dart'; +import 'package:hub/pages/sign_up_page/sign_up_page_widget.dart'; +import 'package:hub/pages/vehicles_on_the_property/vehicles_on_the_property.dart'; +import 'package:hub/pages/visits_on_the_property/visits_on_the_property_screen.dart'; +import 'package:hub/pages/welcome_page/welcome_page_widget.dart'; +import 'package:hub/shared/utils/dialog_util.dart'; import 'package:hub/shared/utils/storage_util.dart'; + import 'package:provider/provider.dart'; - -import '../../shared/utils/dialog_util.dart'; -import '/backend/schema/structs/index.dart'; -import '/flutter_flow/flutter_flow_util.dart'; -import '/index.dart'; - export 'package:go_router/go_router.dart'; export 'serialization_util.dart'; const kTransitionInfoKey = '__transition_info__'; - class AppStateNotifier extends ChangeNotifier { AppStateNotifier._(); @@ -47,40 +58,18 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { final bool? haveLocal = StorageUtil().haveLocal; final bool haveUserUUID = StorageUtil().userUUID.isNotEmpty; final bool haveDevUUID = StorageUtil().devUUID.isNotEmpty; - final bool isRecovered = StorageUtil().isRecovered; - - log('() => isLogged: $isLogged'); - log('() => haveLocal: $haveLocal'); + // final bool isRecovered = StorageUtil().isRecovered; return GoRouter( initialLocation: '/', debugLogDiagnostics: true, refreshListenable: appStateNotifier, // errorBuilder: (context, state) => appStateNotifier.showSplashImage - // ? Builder( - // builder: (context) => Container( - // color: FlutterFlowTheme.of(context).primary, - // child: Image.asset( - // 'assets/images/logo.svg', - // fit: BoxFit.cover, - // ), - // ), - // ) + // ? Builder( builder: (context) => Container(color: FlutterFlowTheme.of(context).primary, child: Image.asset( 'assets/images/logo.svg', fit: BoxFit.cover))) // : const PeopleOnThePropertyPageWidget(), routes: [ - // FFRoute( - // name: '_initialize', - // path: '/', - // builder: (context, _) => appStateNotifier.showSplashImage - // ? Builder( - // builder: (context) => Container( - // color: FlutterFlowTheme.of(context).primary, - // child: Image.asset( - // 'assets/images/favicon.png', - // fit: BoxFit.cover, - // ), - // ), - // ) + // FFRoute(name: '_initialize', path: '/',builder: (context, _) => appStateNotifier.showSplashImage + // ? Builder(builder: (context) => Container(color: FlutterFlowTheme.of(context).primary, child: Image.asset('assets/images/favicon.png', fit: BoxFit.cover))) // : const OnBoardingPageWidget(), // ), FFRoute( @@ -90,8 +79,8 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { try { return isLogged && haveDevUUID && haveUserUUID ? haveLocal == true - ? const HomePageWidget() - : const ReceptionPageWidget() + ? const HomePageWidget() + : const ReceptionPageWidget() : const WelcomePageWidget(); } catch (e) { DialogUtil.error(context, e.toString()); @@ -99,237 +88,107 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { } }, ), - FFRoute( - 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); - - return ForgotPasswordScreen( - key: UniqueKey(), - email: email, - token: token, - ); - } - ), - FFRoute( - name: 'homePage', - path: '/homePage', - builder: (context, params) => HomePageWidget(key: UniqueKey()), - ), - FFRoute( - name: 'receptionPage', - path: '/receptionPage', - builder: (context, params) => const ReceptionPageWidget()), - FFRoute( - name: 'messageHistoryPage', - path: '/messageHistoryPage', - builder: (context, params) => const MessageHistoryPageWidget()), - FFRoute( - name: 'registerVisitorPage', - path: '/registerVisitorPage', - builder: (context, params) => const RegisterVisitorPageWidget(), - ), - FFRoute( - name: 'scheduleCompleteVisitPage', - path: '/scheduleCompleteVisitPage', - builder: (context, params) { - return const ScheduleCompleteVisitPageWidget(); - }), - FFRoute( - 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) => /*const*/ FastPassPageWidget(), - ), - FFRoute( - name: 'preferencesSettings', - path: '/preferencesSettings', - builder: (context, params) => PreferencesPageWidget()), - FFRoute( - name: 'peopleOnThePropertyPage', - path: '/peopleOnThePropertyPage', - builder: (context, params) => const PeopleOnThePropertyPageWidget(), - ), - FFRoute( - name: 'acessHistoryPage', - path: '/acessHistoryPage', - builder: (context, params) => AccessHistoryScreen(opt: const { - 'personType': '.*', - 'accessType': '.*', - 'search': '.*', - })), - FFRoute( - 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 WelcomePageWidget(), - ), - 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: 'forgotPassword', path: '/forgotPassword', builder: (context, params) => ForgotPasswordScreen(key: UniqueKey(), email: params.getParam('email', ParamType.String), token: params.getParam('token', ParamType.String))), + FFRoute(name: 'homePage', path: '/homePage', builder: (context, params) => HomePageWidget(key: UniqueKey())), + FFRoute(name: 'petsOnThePropertyPage', path: '/petsOnThePropertyPage', builder: (context, params) => Scaffold(body: const PetsHistoryScreen())), + FFRoute(name: 'vehiclesOnThePropertyPage', path: '/vehiclesOnThePropertyPage', builder: (context, params) => const VehicleOnTheProperty()), + FFRoute(name: 'visitsOnThePropertyPage', path: '/visitsOnThePropertyPage', builder: (context, params) => const VisitsOnTheProperty()), + FFRoute(name: 'receptionPage', path: '/receptionPage', builder: (context, params) => const ReceptionPageWidget()), + FFRoute(name: 'messageHistoryPage', path: '/messageHistoryPage', builder: (context, params) => const MessageHistoryPageWidget()), + FFRoute(name: 'registerVisitorPage', path: '/registerVisitorPage', builder: (context, params) => const RegisterVisitorPageWidget()), + FFRoute(name: 'scheduleCompleteVisitPage', path: '/scheduleCompleteVisitPage', builder: (context, params) => const ScheduleCompleteVisitPageWidget()), + FFRoute(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) => /*const*/ FastPassPageWidget()), + FFRoute(name: 'preferencesSettings', path: '/preferencesSettings', builder: (context, params) => PreferencesPageWidget()), + FFRoute(name: 'aboutProperty', path: '/aboutProperty', builder: (context, params) => AboutPropertyPage()), + FFRoute(name: 'peopleOnThePropertyPage', path: '/peopleOnThePropertyPage', builder: (context, params) => PeopleOnThePropertyPage()), + FFRoute(name: 'acessHistoryPage', path: '/acessHistoryPage', builder: (context, params) => AccessHistoryScreen(opt: const {'personType': '.*', 'accessType': '.*', 'search': '.*'})), + FFRoute(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 WelcomePageWidget()), + 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', builder: (context, params) { - final pet = params.getParam( - 'pet', - ParamType.JSON, - ); - - return PetsPageWidget( - pet: pet, - ); + final pet = params.getParam('pet', ParamType.JSON); + return PetsPageWidget(pet: pet); }, ), - // FFRoute( - // name: 'settingsPage', - // path: '/settingsPage', - // builder: (context, params) => params.isEmpty - // ? const NavBarPage(initialPage: 'settingsPage') - // : const SettingsPageWidget(), - // ) + // FFRoute(name: 'settingsPage', path: '/settingsPage', builder: (context, params) => params.isEmpty ? const NavBarPage(initialPage: 'settingsPage') : const SettingsPageWidget()) ].map((r) => r.toRoute(appStateNotifier)).toList(), ); } 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!)), ); } + extension NavigationExtensions on BuildContext { void safePop() { - // If there is only one route on the stack, navigate to the initial - // page instead of popping. - if (canPop()) { + if (canPop()) pop(); - } else { + else go('/'); - } } } + 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) ..addAll(extraMap); - TransitionInfo get transitionInfo => extraMap.containsKey(kTransitionInfoKey) - ? extraMap[kTransitionInfoKey] as TransitionInfo - : TransitionInfo.appDefault(); + TransitionInfo get transitionInfo => extraMap.containsKey(kTransitionInfoKey) ? extraMap[kTransitionInfoKey] as TransitionInfo : TransitionInfo.appDefault(); } + 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(); } } class FFParameters { FFParameters(this.state, [this.asyncParams = const {}]); - final GoRouterState state; - final Map Function(String)> asyncParams; + final Map Function(String)> asyncParams; Map futureParamValues = {}; - // Parameters are empty if the params map is empty or if the only parameter - // present is the special extra parameter reserved for the transition info. - 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; + 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; 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; - } - return false; + } else + return false; }, ), ).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]; - } - if (!state.allParams.containsKey(paramName)) { - return null; - } + 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]; - // Got parameter from `extras`, so just directly return it. - if (param is! String) { - return param; - } - // Return serialized value. - return deserializeParam( - param, - type, - isList, - structBuilder: structBuilder, - ); + if (param is! String) return param; + return deserializeParam(param, type, isList, structBuilder: structBuilder); } } + class FFRoute { const FFRoute({ required this.name, @@ -360,33 +219,26 @@ class FFRoute { ) : builder(context, ffParams); final child = page; - final transitionInfo = state.transitionInfo; return transitionInfo.hasTransition ? CustomTransitionPage( 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); }, routes: routes, ); } + class TransitionInfo { const TransitionInfo({ required this.hasTransition, @@ -400,9 +252,9 @@ class TransitionInfo { final Duration duration; final Alignment? alignment; - static TransitionInfo appDefault() => - const TransitionInfo(hasTransition: false); + static TransitionInfo appDefault() => const TransitionInfo(hasTransition: false); } + class RootPageContext { const RootPageContext(this.isRootPage, [this.errorRoute]); final bool isRootPage; @@ -412,13 +264,8 @@ 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}) => Provider.value( - value: RootPageContext(true, errorRoute), - child: child, - ); -} + static Widget wrap(Widget child, {String? errorRoute}) => Provider.value(value: RootPageContext(true, errorRoute), child: child); +} diff --git a/lib/main.dart b/lib/main.dart index 9ebf0b17..2f3b9dd5 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -36,7 +36,6 @@ Future initializeApp() async { WidgetsFlutterBinding.ensureInitialized(); await _initializeTracking(); await _initializeStorageHelpers(); - await _initializeFirebase(); await _initializeNotificationService(); _initializeUrlStrategy(); @@ -45,9 +44,6 @@ Future initializeApp() async { } Future _initializeStorageHelpers() async { - log('Initializing SharedPreferencesStorageHelper'); - await SharedPreferencesStorageHelper().initialize(); - log('Initializing SharedPreferencesStorageHelper'); await StorageUtil().ensureInitialization(); } @@ -92,10 +88,7 @@ Future _foregroundHandlerMessage(RemoteMessage message) async { StorageUtil().context?.go('/homePage'); } if (!Platform.isIOS) { - NotificationService.show( - title: message.notification!.title!, - body: message.notification!.body!, - payload: Map.from(message.data)); + NotificationService.show(title: message.notification!.title!, body: message.notification!.body!, payload: Map.from(message.data)); } } @@ -113,11 +106,10 @@ 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 with WidgetsBindingObserver { +class _AppState extends State with WidgetsBindingObserver { Locale? _locale = FFLocalizations.getStoredLocale(); ThemeMode _themeMode = FlutterFlowTheme.themeMode; late AppStateNotifier _appStateNotifier; @@ -158,8 +150,7 @@ class _AppState extends State with WidgetsBindingObserver { }), ), ); - final Iterable>? localizationsDelegates = - const [ + final Iterable>? localizationsDelegates = const [ FFLocalizationsDelegate(), GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, @@ -211,8 +202,7 @@ class _AppState extends State with WidgetsBindingObserver { builder(context) => screen; showModalBottomSheet( context: context, - builder: (context) => Padding( - padding: MediaQuery.viewInsetsOf(context), child: builder(context)), + builder: (context) => Padding(padding: MediaQuery.viewInsetsOf(context), child: builder(context)), isScrollControlled: true, // barrierColor: theme.primaryBackground.withOpacity(0.2), backgroundColor: theme.primaryBackground, @@ -238,8 +228,7 @@ class _AppState extends State with WidgetsBindingObserver { StorageUtil().haveLocal = 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) { @@ -264,7 +253,8 @@ class _AppState extends State with WidgetsBindingObserver { }); } - @override void initState() { + @override + void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); @@ -273,25 +263,27 @@ class _AppState extends State with WidgetsBindingObserver { FirebaseCrashlytics.instance.setCrashlyticsCollectionEnabled(true); _appStateNotifier = AppStateNotifier.instance; _router = createRouter(_appStateNotifier); - Future.delayed(const Duration(milliseconds: 1000), - () => setState(() => _appStateNotifier.stopShowingSplashImage())); + Future.delayed(const Duration(milliseconds: 1000), () => setState(() => _appStateNotifier.stopShowingSplashImage())); _setupFirebaseMessaging(); WidgetsBinding.instance.addPersistentFrameCallback((_) => initDeepLinks()); } - @override void dispose() { + @override + void dispose() { WidgetsBinding.instance.removeObserver(this); _linkSubscription?.cancel(); super.dispose(); } - @override void didChangeAppLifecycleState(AppLifecycleState state) async { + @override + void didChangeAppLifecycleState(AppLifecycleState state) async { bool initialize = await StorageUtil().ensureInitialization(); - if(initialize) await LocalizationService.processLocals(context); + if (initialize) await LocalizationService.processLocals(context); } - @override Widget build(BuildContext context) { + @override + Widget build(BuildContext context) { return MaterialApp.router( key: navigatorKey, title: 'FRE ACCESS HUB', diff --git a/lib/pages/about_property_page/about_property_model.dart b/lib/pages/about_property_page/about_property_model.dart new file mode 100644 index 00000000..1af57767 --- /dev/null +++ b/lib/pages/about_property_page/about_property_model.dart @@ -0,0 +1,41 @@ +import 'package:flutter/material.dart'; + +import 'package:hub/backend/schema/enums/enums.dart'; +import 'package:hub/components/molecular_components/menu_item/menu_item.dart'; +import 'package:hub/components/organism_components/menu_component/menu_component_model.dart'; +import 'package:hub/flutter_flow/flutter_flow_model.dart'; + +import 'package:hub/pages/about_property_page/about_property_screen.dart'; + +class AboutPropertyModel extends FlutterFlowModel { + dynamic item; + + VoidCallback? safeSetState; + + final GlobalKey registerFormKey = GlobalKey(); + final GlobalKey updateFormKey = GlobalKey(); + + late MenuComponentModel menuComponentModel; + + Future initAsync() async { + safeSetState?.call(); + } + + @override + void initState(BuildContext context) { + menuComponentModel = createModel( + context, + () => MenuComponentModel(expandable: true, style: MenuView.list_grid, item: MenuItem.button, menuOptions: [ + MenuOption.PetsOnTheProperty, + MenuOption.ResidentsOnTheProperty, + MenuOption.VisitsOnTheProperty, + MenuOption.VehiclesOnTheProperty, + MenuOption.PackagesOnTheProperty, + ])); + + initAsync(); + } + + @override + void dispose() {} +} diff --git a/lib/pages/about_property_page/about_property_screen.dart b/lib/pages/about_property_page/about_property_screen.dart new file mode 100644 index 00000000..7fb40e0f --- /dev/null +++ b/lib/pages/about_property_page/about_property_screen.dart @@ -0,0 +1,70 @@ +// ignore: must_be_immutable +import 'package:flutter/material.dart'; +import 'package:hub/components/atomic_components/shared_components_atoms/appbar.dart'; +import 'package:hub/components/organism_components/menu_component/menu_component_widget.dart'; +import 'package:hub/flutter_flow/flutter_flow_model.dart'; +import 'package:hub/flutter_flow/flutter_flow_theme.dart'; +import 'package:hub/flutter_flow/flutter_flow_util.dart'; +import 'package:hub/flutter_flow/nav/nav.dart'; +import 'package:hub/pages/about_property_page/about_property_model.dart'; + +// ignore: must_be_immutable +class AboutPropertyPage extends StatefulWidget { + dynamic pet; + + AboutPropertyPage({ + super.key, + this.pet, + }); + + @override + State createState() => _AboutPropertyPageState(); +} + +class _AboutPropertyPageState extends State with SingleTickerProviderStateMixin { + late AboutPropertyModel _model; + + @override + void initState() { + super.initState(); + _model = createModel(context, () => AboutPropertyModel()); + _model.updateOnChange = true; + + _model.safeSetState = () { + safeSetState(() {}); + }; + } + + @override + void dispose() { + super.dispose(); + _model.dispose(); + } + + @override + Widget build(BuildContext context) { + return Scaffold(appBar: _buildAppBar(context), backgroundColor: FlutterFlowTheme.of(context).primaryBackground, body: _buildBody(context)); + } + + PreferredSizeWidget _buildAppBar(BuildContext context) { + final String title = FFLocalizations.of(context).getVariableText(ptText: "Sobre a Propriedade", enText: "About the Property"); + return AppBarUtil( + title: title, + onBackButtonPressed: () => context.pop(), + ); + } + + Widget _buildBody(BuildContext context) { + return Container( + color: FlutterFlowTheme.of(context).primaryBackground, + child: wrapWithModel( + model: _model.menuComponentModel, + updateCallback: () => setState(() {}), + child: Padding( + padding: EdgeInsets.only(bottom: 40), + child: MenuComponentWidget(model: _model.menuComponentModel), + ), + ), + ); + } +} diff --git a/lib/pages/home_page/home_page_model.dart b/lib/pages/home_page/home_page_model.dart index a648e58b..8f2f44d3 100644 --- a/lib/pages/home_page/home_page_model.dart +++ b/lib/pages/home_page/home_page_model.dart @@ -1,4 +1,6 @@ import 'package:flutter/material.dart'; +import 'package:hub/backend/schema/enums/enums.dart'; +import 'package:hub/components/molecular_components/menu_item/menu_item.dart'; import 'package:hub/components/organism_components/local_profile_component/local_profile_component_model.dart'; import 'package:hub/components/organism_components/menu_component/menu_component_model.dart'; import 'package:hub/components/organism_components/message_well_component/message_well_component_model.dart'; @@ -19,7 +21,8 @@ class HomePageModel extends FlutterFlowModel { TextEditingController? textController; String? Function(BuildContext, String?)? textControllerValidator; late LocalProfileComponentModel localComponentModel; - late MenuComponentModel menuComponentModel; + late MenuComponentModel homeMenuComponentModel; + late MenuComponentModel drawerMenuComponentModel; late MessageWellComponentModel messageWellComponentModel; Future _initVariable() async { @@ -33,11 +36,45 @@ class HomePageModel extends FlutterFlowModel { @override void initState(BuildContext context) { _initVariable(); - localComponentModel = - createModel(context, () => LocalProfileComponentModel()); - menuComponentModel = createModel(context, () => MenuComponentModel()); - messageWellComponentModel = - createModel(context, () => MessageWellComponentModel()); + localComponentModel = createModel(context, () => LocalProfileComponentModel()); + homeMenuComponentModel = createModel( + context, + () => MenuComponentModel(expandable: true, style: MenuView.list_grid, item: MenuItem.button, menuOptions: [ + MenuOption.SettingsOnTheApp, + MenuOption.MessagesOnTheProperty, + MenuOption.AccessOnTheProperty, + MenuOption.PetsRegister, + MenuOption.VisitorsRegister, + MenuOption.ReservationsOnTheLocal, + MenuOption.PackagesOnTheProperty, + MenuOption.DeliverySchedule, + MenuOption.WorkersOnTheProperty, + MenuOption.AboutProperty, + MenuOption.CompleteSchedule, + MenuOption.FastPassSchedule, + MenuOption.LiberationsOnTheProperty, + MenuOption.QRCodeAccessInProperty, + ])); + drawerMenuComponentModel = createModel( + context, + () => MenuComponentModel(expandable: false, style: MenuView.list, item: MenuItem.tile, menuOptions: [ + MenuOption.SettingsOnTheApp, + MenuOption.MessagesOnTheProperty, + MenuOption.AccessOnTheProperty, + MenuOption.PetsRegister, + MenuOption.VisitorsRegister, + MenuOption.ReservationsOnTheLocal, + MenuOption.PackagesOnTheProperty, + MenuOption.DeliverySchedule, + MenuOption.WorkersOnTheProperty, + MenuOption.AboutProperty, + MenuOption.CompleteSchedule, + MenuOption.FastPassSchedule, + MenuOption.LiberationsOnTheProperty, + MenuOption.QRCodeAccessInProperty, + MenuOption.LogoutOnTheApp, + ])); + messageWellComponentModel = createModel(context, () => MessageWellComponentModel()); } @override @@ -47,7 +84,7 @@ class HomePageModel extends FlutterFlowModel { textController?.dispose(); localComponentModel.dispose(); - menuComponentModel.dispose(); + homeMenuComponentModel.dispose(); messageWellComponentModel.dispose(); } } diff --git a/lib/pages/home_page/home_page_widget.dart b/lib/pages/home_page/home_page_widget.dart index 93ee9cfd..e0204dd4 100644 --- a/lib/pages/home_page/home_page_widget.dart +++ b/lib/pages/home_page/home_page_widget.dart @@ -1,4 +1,3 @@ - import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; @@ -20,7 +19,7 @@ class HomePageWidget extends StatefulWidget { State createState() => _HomePageWidgetState(); } -class _HomePageWidgetState extends State { +class _HomePageWidgetState extends State { late HomePageModel _model; final scaffoldKey = GlobalKey(); @@ -30,13 +29,14 @@ class _HomePageWidgetState extends State { _localProfileComponentWidget = LocalProfileComponentWidget(); } - @override void dispose() { - + @override + void dispose() { super.dispose(); _model.dispose(); } - @override void initState() { + @override + void initState() { super.initState(); _model = createModel(context, () => HomePageModel()); @@ -48,9 +48,8 @@ class _HomePageWidgetState extends State { _model.textFieldFocusNode ??= FocusNode(); } - - - @override Widget build(BuildContext context) { + @override + Widget build(BuildContext context) { StorageUtil().context = context; return Scaffold( key: scaffoldKey, @@ -95,8 +94,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)), @@ -109,10 +107,6 @@ class _HomePageWidgetState extends State { ); } - - - - Container buildPage(BuildContext context) { return Container( decoration: BoxDecoration( @@ -147,14 +141,13 @@ class _HomePageWidgetState extends State { return Container( color: FlutterFlowTheme.of(context).primaryBackground, child: wrapWithModel( - model: _model.menuComponentModel, + model: _model.homeMenuComponentModel, + updateOnChange: true, updateCallback: () => setState(() {}), - child: const Padding( - padding: EdgeInsets.only(bottom: 40), + child: Padding( + padding: const EdgeInsets.only(bottom: 40), child: MenuComponentWidget( - expandable: true, - style: MenuView.list_grid, - item: MenuItem.button, + model: _model.homeMenuComponentModel, ), ), ), diff --git a/lib/pages/people_on_the_property_page/people_on_the_property_page_model.dart b/lib/pages/people_on_the_property_page/people_on_the_property_page_model.dart index b33ee6b3..ed14c919 100644 --- a/lib/pages/people_on_the_property_page/people_on_the_property_page_model.dart +++ b/lib/pages/people_on_the_property_page/people_on_the_property_page_model.dart @@ -2,10 +2,7 @@ import 'package:flutter/material.dart'; import 'package:hub/flutter_flow/flutter_flow_model.dart'; import 'package:hub/pages/people_on_the_property_page/people_on_the_property_page_widget.dart'; -class PeopleOnThePropertyPageModel - extends FlutterFlowModel { - /// State fields for stateful widgets in this page. - +class PeopleOnThePropertyPageModel extends FlutterFlowModel { final unfocusNode = FocusNode(); @override diff --git a/lib/pages/people_on_the_property_page/people_on_the_property_page_widget.dart b/lib/pages/people_on_the_property_page/people_on_the_property_page_widget.dart index c6852f85..a9be6c49 100644 --- a/lib/pages/people_on_the_property_page/people_on_the_property_page_widget.dart +++ b/lib/pages/people_on_the_property_page/people_on_the_property_page_widget.dart @@ -1,70 +1,122 @@ -import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; -import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:hub/backend/api_requests/api_calls.dart'; +import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.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/nav/nav.dart'; import 'package:hub/pages/people_on_the_property_page/people_on_the_property_page_model.dart'; +import 'package:hub/shared/utils/dialog_util.dart'; +import 'package:hub/shared/utils/log_util.dart'; +import 'package:hub/shared/utils/storage_util.dart'; -import '../../shared/utils/log_util.dart'; - -class PeopleOnThePropertyPageWidget extends StatefulWidget { - const PeopleOnThePropertyPageWidget({super.key}); +class PeopleOnThePropertyPage extends StatefulWidget { + const PeopleOnThePropertyPage({super.key}); @override - State createState() => - _PeopleOnThePropertyPageWidgetState(); + _PeopleOnThePropertyPageState createState() => _PeopleOnThePropertyPageState(); } -class _PeopleOnThePropertyPageWidgetState - extends State { - late PeopleOnThePropertyPageModel _model; +class _PeopleOnThePropertyPageState extends State with TickerProviderStateMixin { + late ScrollController _scrollController; - final scaffoldKey = GlobalKey(); + int _pageNumber = 1; + bool _hasData = false; + bool _loading = false; + int count = 0; + late final PeopleOnThePropertyPageModel model; + + late Future _petsFuture; + List _petsWrap = []; @override void initState() { super.initState(); - _model = createModel(context, () => PeopleOnThePropertyPageModel()); + model = createModel(context, () => PeopleOnThePropertyPageModel()); + _petsFuture = _fetchVisits(); + + _scrollController = ScrollController() + ..addListener(() { + if (_scrollController.position.atEdge && _scrollController.position.pixels != 0) { + _loadMore(); + } + }); } @override void dispose() { - _model.dispose(); - + _scrollController.dispose(); super.dispose(); } @override - Widget build(BuildContext context) { - return Scaffold( - key: scaffoldKey, - backgroundColor: FlutterFlowTheme.of(context).primaryBackground, - appBar: AppBar( + Widget build(BuildContext context) => Scaffold( + appBar: _appBar(context), backgroundColor: FlutterFlowTheme.of(context).primaryBackground, - automaticallyImplyLeading: false, - forceMaterialTransparency: true, - leading: FlutterFlowIconButton( - borderColor: Colors.transparent, - borderRadius: 30.0, - borderWidth: 1.0, - buttonSize: 60.0, - icon: Icon( - Icons.keyboard_arrow_left, - color: FlutterFlowTheme.of(context).primaryText, - size: 30.0, - ), - onPressed: () async { - context.pop(); - }, + 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")), + ) + ], + ), + ) + else if (_hasData == true || _pageNumber >= 1) + Expanded( + child: FutureBuilder( + future: _petsFuture, + builder: (context, snapshot) { + return ListView.builder( + shrinkWrap: true, + physics: const BouncingScrollPhysics(), + controller: _scrollController, + itemCount: _petsWrap.length + 1, + itemBuilder: (context, index) { + if (index == 0) { + // Add your item here + return Padding( + padding: const EdgeInsets.only(right: 30, top: 10), + child: Text( + // model.petAmountRegister == '0' ? FFLocalizations.of(context).getVariableText(ptText: "Ilimitado", enText: "Unlimited") : "${FFLocalizations.of(context).getVariableText(ptText: "Quantidade de Pets: ", enText: "Amount of Pets: ")}$count/${model.petAmountRegister}", + '', + textAlign: TextAlign.right, + ), + ); + } else { + final item = _petsWrap[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)), ), - title: Text( - FFLocalizations.of(context).getText( - 'nsu13r5d' /* Pessoas na Propriedade */, - ), + ); + + PreferredSizeWidget _appBar(BuildContext context) { + return AppBar( + backgroundColor: FlutterFlowTheme.of(context).primaryBackground, + automaticallyImplyLeading: false, + title: Text(FFLocalizations.of(context).getVariableText(ptText: 'Moram Comigo', enText: 'People on the property'), style: FlutterFlowTheme.of(context).headlineMedium.override( fontFamily: 'Nunito', color: FlutterFlowTheme.of(context).primaryText, @@ -72,114 +124,103 @@ class _PeopleOnThePropertyPageWidgetState letterSpacing: 0.0, fontWeight: FontWeight.bold, useGoogleFonts: GoogleFonts.asMap().containsKey('Nunito'), - ), - ), - actions: const [], - centerTitle: true, - elevation: 0.0, + )), + leading: _backButton(context, FlutterFlowTheme.of(context)), + centerTitle: true, + elevation: 0.0, + actions: [], + ); + } + + Widget _backButton(BuildContext context, FlutterFlowTheme theme) { + return FlutterFlowIconButton( + borderColor: Colors.transparent, + borderRadius: 30.0, + borderWidth: 1.0, + buttonSize: 60.0, + icon: Icon( + Icons.keyboard_arrow_left, + color: theme.primaryText, + size: 30.0, ), - body: SafeArea( - top: true, - child: FutureBuilder( - future: PhpGroup.getPessoasLocalCall.call(), - builder: (context, snapshot) { - // Customize what your widget looks like when it's loading. - if (!snapshot.hasData) { - return Center( - child: SizedBox( - width: 50.0, - height: 50.0, - child: SpinKitCircle( - color: FlutterFlowTheme.of(context).primary, - size: 50.0, - ), - ), - ); - } + onPressed: () => Navigator.of(context).pop(), + ); + } - if (snapshot.hasError || snapshot.data?.exception != null) { - if (snapshot.error != null && snapshot.stackTrace != null) { - LogUtil.requestAPIFailed( - 'getPessoasLocal.php', - "", - 'Busca Pessoas no Local', - snapshot.error, - snapshot.stackTrace!); - } + Future _fetchVisits() async { + try { + setState(() => _loading = true); - return Center( - child: SizedBox( - width: double.infinity, - height: 100, - child: Text( - FFLocalizations.of(context).getVariableText( - ptText: "Pessoas não encontradas", - enText: "Persons not found"), - textAlign: TextAlign.center, - ), - ), - ); - } + var response = await PhpGroup.getResidentsByProperty.call(_pageNumber.toString()); - final columnGetPessoasLocalResponse = snapshot.data!; - final getPoepleProperty = PhpGroup.getPessoasLocalCall - .pessoas( - columnGetPessoasLocalResponse.jsonBody, - ) - ?.toList() ?? - []; + final List pets = response.jsonBody['residents'] ?? []; + safeSetState(() => count = response.jsonBody['total_rows'] ?? 0); - return ListView.builder( - physics: const AlwaysScrollableScrollPhysics(), - shrinkWrap: true, - itemCount: getPoepleProperty.length, - itemBuilder: (context, index) { - final getPoeplePropertyItem = getPoepleProperty[index]; - return Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.start, - children: [ - Padding( - padding: const EdgeInsets.all(4.0), - child: Container( - width: 50.0, - height: 50.0, - clipBehavior: Clip.antiAlias, - decoration: const BoxDecoration( - shape: BoxShape.circle, - ), - child: CachedNetworkImage( - fadeInDuration: const Duration(milliseconds: 500), - fadeOutDuration: const Duration(milliseconds: 500), - imageUrl: - 'https://storage.googleapis.com/flutterflow-io-6f20.appspot.com/projects/flutter-freaccess-hub-0xgz9q/assets/7ftdetkzc3s0/360_F_64676383_LdbmhiNM6Ypzb3FM4PPuFP9rHe7ri8Ju.jpg', - fit: BoxFit.cover, - ), - ), - ), - Text( - getJsonField( - getPoeplePropertyItem, - r'''$.USU_NOME''', - ).toString(), - style: FlutterFlowTheme.of(context).bodyMedium.override( - fontFamily: - FlutterFlowTheme.of(context).bodyMediumFamily, - fontSize: 14.0, - letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap().containsKey( - FlutterFlowTheme.of(context).bodyMediumFamily), - ), - ), - ] - .divide(const SizedBox(width: 20.0)) - .addToStart(const SizedBox(width: 40.0)), - ); - }, - ); - }, - ), + if (pets.isNotEmpty) { + setState(() { + _petsWrap.addAll(pets); + _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 Pets", e, s); + setState(() { + _hasData = false; + _loading = false; + }); + } + return null; + } + + void _loadMore() { + if (_hasData == true) { + _pageNumber++; + + _petsFuture = _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.")), + duration: const Duration(seconds: 3), + backgroundColor: FlutterFlowTheme.of(context).primary, ), ); } + + Widget _item(BuildContext context, dynamic uItem) { + return CardItemTemplateComponentWidget( + imagePath: 'https://freaccess.com.br/freaccess/getImage.php?devUUID=${StorageUtil().devUUID}&cliID=${StorageUtil().cliUUID}&atividade=getFoto&Documento=${uItem['documento']}&tipo=Z', + labelsHashMap: { + '${FFLocalizations.of(context).getVariableText(ptText: "Nome", enText: "Name")}:': uItem['nome'] ?? '', + //statusweb + '${FFLocalizations.of(context).getVariableText(ptText: "Status", enText: "Status")}:': uItem['statusweb'] == "A" + ? FFLocalizations.of(context).getVariableText( + ptText: 'Ativo', + enText: 'Active', + ) + : FFLocalizations.of(context).getVariableText( + ptText: 'Inativo', + enText: 'Inactive', + ), + }, + statusHashMap: [], + onTapCardItemAction: () async {}, + ); + } } diff --git a/lib/pages/pets_on_the_property_page/pets_history_screen.dart b/lib/pages/pets_on_the_property_page/pets_history_screen.dart new file mode 100644 index 00000000..95626cc2 --- /dev/null +++ b/lib/pages/pets_on_the_property_page/pets_history_screen.dart @@ -0,0 +1,309 @@ +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:hub/backend/api_requests/api_calls.dart'; +import 'package:hub/backend/api_requests/api_manager.dart'; +import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.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/pages/pets_page/pets_page_model.dart'; + +import 'package:hub/shared/utils/dialog_util.dart'; +import 'package:hub/shared/utils/log_util.dart'; +import 'package:hub/shared/utils/storage_util.dart'; + +class PetsHistoryScreen extends StatefulWidget { + const PetsHistoryScreen({super.key, this.model}); + final PetsPageModel? model; + + @override + _PetsHistoryScreenState createState() => _PetsHistoryScreenState(); +} + +class _PetsHistoryScreenState extends State with TickerProviderStateMixin { + late ScrollController _scrollController; + + int _pageNumber = 1; + final int _pageSize = 10; + bool _hasData = false; + bool _loading = false; + int count = 0; + late final PetsPageModel model; + + late Future _petsFuture; + List _petsWrap = []; + + @override + void initState() { + super.initState(); + model = widget.model ?? createModel(context, () => PetsPageModel()); + _petsFuture = _fetchVisits(); + + _scrollController = ScrollController() + ..addListener(() { + if (_scrollController.position.atEdge && _scrollController.position.pixels != 0) { + _loadMore(); + } + }); + } + + @override + void dispose() { + _scrollController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) => 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 Pet encontrado!", enText: "No pets found")), + ) + ], + ), + ) + else if (_hasData == true || _pageNumber >= 1) + Expanded( + child: FutureBuilder( + future: _petsFuture, + builder: (context, snapshot) { + return ListView.builder( + shrinkWrap: true, + physics: const BouncingScrollPhysics(), + controller: _scrollController, + itemCount: _petsWrap.length + 1, + itemBuilder: (context, index) { + if (index == 0) { + // Add your item here + return Padding( + padding: const EdgeInsets.only(right: 30, top: 10), + child: Text( + model.petAmountRegister == '0' ? FFLocalizations.of(context).getVariableText(ptText: "Ilimitado", enText: "Unlimited") : "${FFLocalizations.of(context).getVariableText(ptText: "Quantidade de Pets: ", enText: "Amount of Pets: ")}$count/${model.petAmountRegister}", + textAlign: TextAlign.right, + ), + ); + } else { + final item = _petsWrap[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)), + ), + ); + + PreferredSizeWidget _appBar(BuildContext context) { + return AppBar( + backgroundColor: FlutterFlowTheme.of(context).primaryBackground, + automaticallyImplyLeading: false, + title: Text(FFLocalizations.of(context).getVariableText(enText: 'My Pets', ptText: 'Meus Pets'), + style: FlutterFlowTheme.of(context).headlineMedium.override( + fontFamily: 'Nunito', + color: FlutterFlowTheme.of(context).primaryText, + fontSize: 15.0, + letterSpacing: 0.0, + fontWeight: FontWeight.bold, + useGoogleFonts: GoogleFonts.asMap().containsKey('Nunito'), + )), + leading: _backButton(context, FlutterFlowTheme.of(context)), + centerTitle: true, + elevation: 0.0, + actions: [], + ); + } + + Widget _backButton(BuildContext context, FlutterFlowTheme theme) { + return FlutterFlowIconButton( + 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(), + ); + } + + Future _fetchVisits() async { + try { + setState(() => _loading = true); + + var response = await PhpGroup.getPets.call( + pageSize: _pageSize, + page: _pageNumber, + ); + + final List pets = response.jsonBody['pets']['list'] ?? []; + safeSetState(() => count = response.jsonBody['pets']['count'] ?? 0); + + if (pets.isNotEmpty) { + setState(() { + _petsWrap.addAll(pets); + _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 Pets", e, s); + setState(() { + _hasData = false; + _loading = false; + }); + } + return null; + } + + void _loadMore() { + if (_hasData == true) { + _pageNumber++; + + _petsFuture = _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.")), + duration: const Duration(seconds: 3), + backgroundColor: FlutterFlowTheme.of(context).primary, + ), + ); + } + + Widget _item(BuildContext context, dynamic uItem) { + return CardItemTemplateComponentWidget( + imagePath: 'https://freaccess.com.br/freaccess/getImage.php?devUUID=${model.devUUID}&userUUID=${model.userUUID}&cliID=${model.cliUUID}&atividade=consultaFotoPet&petId=${uItem['id'] ?? ''}', + labelsHashMap: { + '${FFLocalizations.of(context).getVariableText(ptText: "Nome", enText: "Name")}:': uItem['name'] ?? '', + '${FFLocalizations.of(context).getVariableText(ptText: "Espécie", enText: "Species")}:': uItem['species'] ?? '', + '${FFLocalizations.of(context).getVariableText(ptText: "Raça", enText: "Breed")}:': uItem['breed'] ?? '', + }, + statusHashMap: [ + if (uItem['size'] == "MIN") + { + FFLocalizations.of(context).getVariableText( + ptText: 'Mini', + enText: 'Mini', + ): FlutterFlowTheme.of(context).accent4, + }, + if (uItem['size'] == "PEQ") + { + FFLocalizations.of(context).getVariableText( + ptText: 'Pequeno', + enText: 'Small', + ): FlutterFlowTheme.of(context).accent4, + }, + if (uItem['size'] == "MED") + { + FFLocalizations.of(context).getVariableText( + ptText: 'Medio', + enText: 'Medium', + ): FlutterFlowTheme.of(context).accent4, + }, + if (uItem['size'] == "GRA") + { + FFLocalizations.of(context).getVariableText( + ptText: 'Grande', + enText: 'Big', + ): FlutterFlowTheme.of(context).accent4, + }, + if (uItem['size'] == "GIG") + { + FFLocalizations.of(context).getVariableText( + ptText: 'Gigante', + enText: 'Giant', + ): FlutterFlowTheme.of(context).accent4, + }, + if (uItem['gender'] == "MAC") + { + FFLocalizations.of(context).getVariableText(ptText: 'Macho', enText: 'Male'): const Color(0xFF094CB0), + }, + if (uItem['gender'] == "FEM") + { + FFLocalizations.of(context).getVariableText( + ptText: 'Femêa', + enText: 'Female', + ): const Color(0xFFE463E7), + } + ], + onTapCardItemAction: () async { + final cliUUID = StorageUtil().cliUUID; + final cliName = StorageUtil().cliName; + final devUUID = StorageUtil().devUUID; + final userUUID = StorageUtil().userUUID; + await showDialog( + useSafeArea: true, + context: context, + builder: (context) { + return Dialog( + alignment: Alignment.center, + child: model.buildPetDetails( + item: uItem, + context: context, + devUUID: devUUID, + userUUID: userUUID, + cliUUID: cliUUID, + cliName: cliName, + model: model, + isInteractive: false, + ), + ); + }, + ).whenComplete(() { + safeSetState(() { + _pageNumber = 1; + _petsWrap = []; + _petsFuture = _fetchVisits().then((value) => value!.jsonBody['pets'] ?? []); + }); + }).catchError((e, s) { + DialogUtil.errorDefault(context); + LogUtil.requestAPIFailed("proccessRequest.php", "", "Consulta de Pets", e, s); + safeSetState(() { + _hasData = false; + _loading = false; + }); + }); + }, + ); + } +} diff --git a/lib/pages/pets_page/pets_history_screen.dart b/lib/pages/pets_page/pets_history_screen.dart deleted file mode 100644 index a1d9cdf0..00000000 --- a/lib/pages/pets_page/pets_history_screen.dart +++ /dev/null @@ -1,284 +0,0 @@ -import 'package:flutter/material.dart'; -import 'package:hub/backend/api_requests/api_calls.dart'; -import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart'; -import 'package:hub/flutter_flow/flutter_flow_theme.dart'; -import 'package:hub/flutter_flow/flutter_flow_util.dart'; -import 'package:hub/pages/pets_page/pets_page_model.dart'; -import 'package:hub/shared/utils/dialog_util.dart'; -import 'package:hub/shared/utils/log_util.dart'; -import 'package:hub/shared/utils/storage_util.dart'; - -class PetsHistoryScreen extends StatefulWidget { - const PetsHistoryScreen({super.key, required this.model}); - - final PetsPageModel model; - - @override - _PetsHistoryScreenState createState() => _PetsHistoryScreenState(); -} - -class _PetsHistoryScreenState extends State - with TickerProviderStateMixin { - late ScrollController _scrollController; - - int _pageNumber = 1; - final int _pageSize = 10; - bool _hasData = false; - bool _loading = false; - int count = 0; - - late Future _petsFuture; - List _petsWrap = []; - - @override - void initState() { - super.initState(); - - _petsFuture = _fetchVisits(); - - _scrollController = ScrollController() - ..addListener(() { - if (_scrollController.position.atEdge && - _scrollController.position.pixels != 0) { - _loadMore(); - } - }); - } - - @override - void dispose() { - _scrollController.dispose(); - super.dispose(); - } - - Future _fetchVisits() async { - try { - setState(() => _loading = true); - - var response = await PhpGroup.getPets.call( - pageSize: _pageSize, - page: _pageNumber, - ); - - final List pets = response.jsonBody['pets']['list'] ?? []; - safeSetState(() => count = response.jsonBody['pets']['count'] ?? 0); - - if (pets.isNotEmpty) { - setState(() { - _petsWrap.addAll(pets); - _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 Pets", e, s); - setState(() { - _hasData = false; - _loading = false; - }); - } - return null; - } - - void _loadMore() { - if (_hasData == true) { - _pageNumber++; - - _petsFuture = _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."), - ), - duration: const Duration(seconds: 3), - backgroundColor: FlutterFlowTheme.of(context).primary, - ), - ); - } - - @override - Widget build(BuildContext 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 Pet encontrado!", - enText: "No pets found")), - ) - ], - ), - ) - else if (_hasData == true || _pageNumber >= 1) - Expanded( - child: FutureBuilder( - future: _petsFuture, - builder: (context, snapshot) { - return ListView.builder( - shrinkWrap: true, - physics: const BouncingScrollPhysics(), - controller: _scrollController, - itemCount: _petsWrap.length + 1, - itemBuilder: (context, index) { - if (index == 0) { - // Add your item here - return Padding( - padding: const EdgeInsets.only(right: 30, top: 10), - child: Text( - widget.model.petAmountRegister == '0' - ? FFLocalizations.of(context).getVariableText( - ptText: "Ilimitado", enText: "Unlimited") - : "${FFLocalizations.of(context).getVariableText(ptText: "Quantidade de Pets: ", enText: "Amount of Pets: ")}$count/${widget.model.petAmountRegister}", - textAlign: TextAlign.right, - ), - ); - } else { - final item = _petsWrap[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)), - ); - } - - Widget _item(BuildContext context, dynamic uItem) { - return CardItemTemplateComponentWidget( - imagePath: - 'https://freaccess.com.br/freaccess/getImage.php?devUUID=${widget.model.devUUID}&userUUID=${widget.model.userUUID}&cliID=${widget.model.cliUUID}&atividade=consultaFotoPet&petId=${uItem['id'] ?? ''}', - labelsHashMap: { - '${FFLocalizations.of(context).getVariableText(ptText: "Nome", enText: "Name")}:': - uItem['name'] ?? '', - '${FFLocalizations.of(context).getVariableText(ptText: "Espécie", enText: "Species")}:': - uItem['species'] ?? '', - '${FFLocalizations.of(context).getVariableText(ptText: "Raça", enText: "Breed")}:': - uItem['breed'] ?? '', - }, - statusHashMap: [ - if (uItem['size'] == "MIN") - { - FFLocalizations.of(context).getVariableText( - ptText: 'Mini', - enText: 'Mini', - ): FlutterFlowTheme.of(context).accent4, - }, - if (uItem['size'] == "PEQ") - { - FFLocalizations.of(context).getVariableText( - ptText: 'Pequeno', - enText: 'Small', - ): FlutterFlowTheme.of(context).accent4, - }, - if (uItem['size'] == "MED") - { - FFLocalizations.of(context).getVariableText( - ptText: 'Medio', - enText: 'Medium', - ): FlutterFlowTheme.of(context).accent4, - }, - if (uItem['size'] == "GRA") - { - FFLocalizations.of(context).getVariableText( - ptText: 'Grande', - enText: 'Big', - ): FlutterFlowTheme.of(context).accent4, - }, - if (uItem['size'] == "GIG") - { - FFLocalizations.of(context).getVariableText( - ptText: 'Gigante', - enText: 'Giant', - ): FlutterFlowTheme.of(context).accent4, - }, - if (uItem['gender'] == "MAC") - { - FFLocalizations.of(context).getVariableText( - ptText: 'Macho', enText: 'Male'): const Color(0xFF094CB0), - }, - if (uItem['gender'] == "FEM") - { - FFLocalizations.of(context).getVariableText( - ptText: 'Femêa', - enText: 'Female', - ): const Color(0xFFE463E7), - } - ], - onTapCardItemAction: () async { - final cliUUID = StorageUtil().cliUUID; - final cliName = StorageUtil().cliName; - final devUUID = StorageUtil().devUUID; - final userUUID = StorageUtil().userUUID; - await showDialog( - useSafeArea: true, - context: context, - builder: (context) { - return Dialog( - alignment: Alignment.center, - child: widget.model.buildPetDetails( - item: uItem, - context: context, - devUUID: devUUID, - userUUID: userUUID, - cliUUID: cliUUID, - cliName: cliName, - model: widget.model, - ), - ); - }, - ).whenComplete(() { - safeSetState(() { - _pageNumber = 1; - _petsWrap = []; - _petsFuture = - _fetchVisits().then((value) => value!.jsonBody['pets'] ?? []); - }); - }).catchError((e, s) { - DialogUtil.errorDefault(context); - LogUtil.requestAPIFailed( - "proccessRequest.php", "", "Consulta de Pets", e, s); - safeSetState(() { - _hasData = false; - _loading = false; - }); - }); - }, - ); - } -} diff --git a/lib/pages/pets_page/pets_page_model.dart b/lib/pages/pets_page/pets_page_model.dart index 958c5f09..3ea09c9f 100644 --- a/lib/pages/pets_page/pets_page_model.dart +++ b/lib/pages/pets_page/pets_page_model.dart @@ -18,6 +18,11 @@ import 'package:hub/shared/utils/storage_util.dart'; import 'package:hub/shared/utils/validator_util.dart'; class PetsPageModel extends FlutterFlowModel { + static PetsPageModel? _instance = PetsPageModel._internal(); + PetsPageModel._internal(); + factory PetsPageModel() => _instance ?? PetsPageModel._internal(); + static void resetInstance() => _instance = null; + late final String devUUID; late final String userUUID; late final String cliUUID; @@ -100,17 +105,9 @@ class PetsPageModel extends FlutterFlowModel { TextEditingController? textControllerObservation; String? Function(BuildContext, String?)? textControllerObservationValidator; - Future initAsync() async { - devUUID = StorageUtil().devUUID; - userUUID = StorageUtil().userUUID; - cliUUID = StorageUtil().cliUUID; - petAmountRegister = StorageUtil().petAmountRegister.toString(); - - safeSetState?.call(); - } - @override void initState(BuildContext context) { + resetInstance(); tabBarController = TabController( vsync: Navigator.of(context), length: 2, @@ -134,67 +131,13 @@ class PetsPageModel extends FlutterFlowModel { textFieldFocusObservation = FocusNode(); textControllerObservation = TextEditingController(); - dropDownValueController1 = - FormFieldController(dropDownValue1 ??= 'Selecione uma opção'); + dropDownValueController1 = FormFieldController(dropDownValue1 ??= 'Selecione uma opção'); - dropDownValueController2 = - FormFieldController(dropDownValue2 ??= 'Selecione uma opção'); + dropDownValueController2 = FormFieldController(dropDownValue2 ??= 'Selecione uma opção'); initAsync(); } - void setEditForm() { - log('item: $item'); - - if (item != null) petId = item['id']; - - // updateImage!(); - (() async { - Response response = await get(Uri.parse( - 'https://freaccess.com.br/freaccess/getImage.php?devUUID=$devUUID&userUUID=$userUUID&cliID=$cliUUID&atividade=consultaFotoPet&petId=$petId')); - String base64 = base64Encode(response.bodyBytes); - uploadedTempFile = await ImageUtils.convertToUploadFile(base64); - updateImage?.call(); - })(); - - textControllerName = - TextEditingController(text: item != null ? item['name'] ?? '' : ''); - textFieldFocusName = FocusNode(); - - textControllerSpecies = - TextEditingController(text: item != null ? item['species'] ?? '' : ''); - textFieldFocusSpecies = FocusNode(); - - textControllerRace = - TextEditingController(text: item != null ? item['breed'] ?? '' : ''); - textFieldFocusRace = FocusNode(); - - textControllerColor = - TextEditingController(text: item != null ? item['color'] ?? '' : ''); - textFieldFocusColor = FocusNode(); - - textControllerData = TextEditingController( - text: item != null - ? item['birthdayDate'] != null - ? ValidatorUtil.formatDateTimePicker(item['birthdayDate']) - : '' - : ''); - - textFieldFocusData = FocusNode(); - - textControllerObservation = - TextEditingController(text: item != null ? item['notes'] ?? '' : ''); - textFieldFocusObservation = FocusNode(); - - item != null ? dropDownValue1 = item['gender'] ?? '' : dropDownValue1 = ''; - - item != null ? dropDownValue2 = item['size'] ?? '' : dropDownValue2 = ''; - - dropDownValueController1 = FormFieldController(dropDownValue1); - - dropDownValueController2 = FormFieldController(dropDownValue2); - } - @override void dispose() { tabBarController.dispose(); @@ -221,31 +164,79 @@ class PetsPageModel extends FlutterFlowModel { dropDownValueController2?.dispose(); } + Future initAsync() async { + devUUID = StorageUtil().devUUID; + userUUID = StorageUtil().userUUID; + cliUUID = StorageUtil().cliUUID; + petAmountRegister = StorageUtil().petAmountRegister.toString(); + + safeSetState?.call(); + } + + void setEditForm() { + log('item: $item'); + + if (item != null) petId = item['id']; + + // updateImage!(); + (() async { + Response response = await get(Uri.parse('https://freaccess.com.br/freaccess/getImage.php?devUUID=$devUUID&userUUID=$userUUID&cliID=$cliUUID&atividade=consultaFotoPet&petId=$petId')); + String base64 = base64Encode(response.bodyBytes); + uploadedTempFile = await ImageUtils.convertToUploadFile(base64); + updateImage?.call(); + })(); + + textControllerName = TextEditingController(text: item != null ? item['name'] ?? '' : ''); + textFieldFocusName = FocusNode(); + + textControllerSpecies = TextEditingController(text: item != null ? item['species'] ?? '' : ''); + textFieldFocusSpecies = FocusNode(); + + textControllerRace = TextEditingController(text: item != null ? item['breed'] ?? '' : ''); + textFieldFocusRace = FocusNode(); + + textControllerColor = TextEditingController(text: item != null ? item['color'] ?? '' : ''); + textFieldFocusColor = FocusNode(); + + textControllerData = TextEditingController( + text: item != null + ? item['birthdayDate'] != null + ? ValidatorUtil.formatDateTimePicker(item['birthdayDate']) + : '' + : ''); + + textFieldFocusData = FocusNode(); + + textControllerObservation = TextEditingController(text: item != null ? item['notes'] ?? '' : ''); + textFieldFocusObservation = FocusNode(); + + item != null ? dropDownValue1 = item['gender'] ?? '' : dropDownValue1 = ''; + + item != null ? dropDownValue2 = item['size'] ?? '' : dropDownValue2 = ''; + + dropDownValueController1 = FormFieldController(dropDownValue1); + + dropDownValueController2 = FormFieldController(dropDownValue2); + } + bool isFormValid(BuildContext context) { if (uploadedLocalFile == null || uploadedLocalFile!.bytes!.isEmpty) { return false; } - if (textControllerName.text.isEmpty || - textControllerName.text.length > 80 || - textControllerName.text == '') { + if (textControllerName!.text.isEmpty || textControllerName!.text.length > 80 || textControllerName!.text == '') { return false; } - if (textControllerSpecies.text.isEmpty || - textControllerSpecies.text == '') { + if (textControllerSpecies!.text.isEmpty || textControllerSpecies!.text == '') { return false; } - if (textControllerRace.text.isEmpty || textControllerRace.text == '') { + if (textControllerRace!.text.isEmpty || textControllerRace!.text == '') { return false; } - if (dropDownValue1 == null || - dropDownValue1!.isEmpty || - dropDownValue1 == '') { + if (dropDownValue1 == null || dropDownValue1!.isEmpty || dropDownValue1 == '') { return false; } - if (dropDownValue2 == null || - dropDownValue2!.isEmpty || - dropDownValue2 == '') { + if (dropDownValue2 == null || dropDownValue2!.isEmpty || dropDownValue2 == '') { return false; } return true; @@ -254,8 +245,7 @@ class PetsPageModel extends FlutterFlowModel { Future updatePet() async { var img = await ImageUtils.convertImageFileToBase64(uploadedLocalFile!); img = "base64;jpeg,$img"; - final url = - 'https://freaccess.com.br/freaccess/getImage.php?devUUID=$devUUID&userUUID=$userUUID&cliID=$cliUUID&atividade=consultaFotoPet&petId=$petId'; + final url = 'https://freaccess.com.br/freaccess/getImage.php?devUUID=$devUUID&userUUID=$userUUID&cliID=$cliUUID&atividade=consultaFotoPet&petId=$petId'; final response = await PhpGroup.updatePet.call( petID: petId, image: img, @@ -284,8 +274,7 @@ class PetsPageModel extends FlutterFlowModel { } else { String errorMessage; try { - errorMessage = - jsonDecode(response.jsonBody['error_msg'])[0]['message'].toString(); + errorMessage = jsonDecode(response.jsonBody['error_msg'])[0]['message'].toString(); } catch (e) { errorMessage = FFLocalizations.of(buildContext!).getVariableText( enText: 'Failed to update pet', @@ -323,11 +312,9 @@ class PetsPageModel extends FlutterFlowModel { } else { String errorMessage; try { - errorMessage = - jsonDecode(response.jsonBody['error_msg'])[0]['message'].toString(); + errorMessage = jsonDecode(response.jsonBody['error_msg'])[0]['message'].toString(); } catch (e) { - if (response.jsonBody['error_msg'] == - "Limite de Cadastro de Pet Atingido.") { + if (response.jsonBody['error_msg'] == "Limite de Cadastro de Pet Atingido.") { errorMessage = FFLocalizations.of(buildContext!).getVariableText( enText: 'Pet registration limit reached', ptText: 'Limite de cadastro de pets atingido', @@ -388,162 +375,142 @@ class PetsPageModel extends FlutterFlowModel { required String cliUUID, required String cliName, required PetsPageModel model, + bool isInteractive = true, }) { return DetailsComponentWidget( buttons: [ // EDIT ACTION - FFButtonWidget( - text: FFLocalizations.of(context).getVariableText( - ptText: 'Editar', - enText: 'Edit', - ), - icon: const Icon(Icons.edit), - onPressed: () async { - context.pop(); + if (isInteractive) + FFButtonWidget( + text: FFLocalizations.of(context).getVariableText( + ptText: 'Editar', + enText: 'Edit', + ), + icon: const Icon(Icons.edit), + onPressed: () async { + context.pop(); - model.isEditing = true; - model.item = item; - model.switchTab(0); - model.setEditForm(); - // model.safeSetState!(); - }, - options: FFButtonOptions( - width: 130, - height: 40, - color: FlutterFlowTheme.of(context).primaryBackground, - elevation: 0, - textStyle: TextStyle( - color: FlutterFlowTheme.of(context).primaryText, - ), - borderSide: BorderSide( + model.isEditing = true; + model.item = item; + model.switchTab(0); + model.setEditForm(); + // model.safeSetState!(); + }, + options: FFButtonOptions( + width: 130, + height: 40, color: FlutterFlowTheme.of(context).primaryBackground, - width: 1, + elevation: 0, + textStyle: TextStyle( + color: FlutterFlowTheme.of(context).primaryText, + ), + borderSide: BorderSide( + color: FlutterFlowTheme.of(context).primaryBackground, + width: 1, + ), + // borderRadius: 12, ), - // borderRadius: 12, ), - ), // DELETE ACTION - FFButtonWidget( - text: FFLocalizations.of(context).getVariableText( - ptText: 'Excluir', - enText: 'Delete', - ), - icon: const Icon(Icons.close), - onPressed: () async { - showAlertDialog( - context, - FFLocalizations.of(context).getVariableText( - ptText: 'Excluir Pet', - enText: 'Delete Pet', - ), - FFLocalizations.of(context).getVariableText( - ptText: 'Você tem certeza que deseja excluir esse pet?', - enText: 'Are you sure you want to delete this pet?', - ), () async { - int id = item['id']; - await PhpGroup.deletePet - .call( - petID: id, - ) - .then((value) { - // Navigator.pop(context, value); - context.pop(value); - context.pop(value); + if (isInteractive) + FFButtonWidget( + text: FFLocalizations.of(context).getVariableText( + ptText: 'Excluir', + enText: 'Delete', + ), + icon: const Icon(Icons.close), + onPressed: () async { + showAlertDialog( + context, + FFLocalizations.of(context).getVariableText( + ptText: 'Excluir Pet', + enText: 'Delete Pet', + ), + FFLocalizations.of(context).getVariableText( + ptText: 'Você tem certeza que deseja excluir esse pet?', + enText: 'Are you sure you want to delete this pet?', + ), () async { + int id = item['id']; + await PhpGroup.deletePet + .call( + petID: id, + ) + .then((value) { + // Navigator.pop(context, value); + context.pop(value); + context.pop(value); - if (value == false) { + if (value == false) { + showSnackbar( + context, + FFLocalizations.of(context).getVariableText( + ptText: 'Erro ao excluir pet', + enText: 'Error deleting pet', + ), + true, + ); + } else if (value == true) { + showSnackbar( + context, + FFLocalizations.of(context).getVariableText( + enText: 'Success deleting pet', + ptText: 'Succeso ao excluir pet', + ), + false, + ); + } + }).catchError((err, stack) { + context.pop(); showSnackbar( context, FFLocalizations.of(context).getVariableText( - ptText: 'Erro ao excluir pet', enText: 'Error deleting pet', + ptText: 'Erro ao excluir pet', ), true, ); - } else if (value == true) { - showSnackbar( - context, - FFLocalizations.of(context).getVariableText( - enText: 'Success deleting pet', - ptText: 'Succeso ao excluir pet', - ), - false, - ); - } - }).catchError((err, stack) { - context.pop(); - showSnackbar( - context, - FFLocalizations.of(context).getVariableText( - enText: 'Error deleting pet', - ptText: 'Erro ao excluir pet', - ), - true, - ); + }); }); - }); - }, - options: FFButtonOptions( - width: 130, - height: 40, - color: FlutterFlowTheme.of(context).primaryBackground, - elevation: 0, - textStyle: TextStyle( - color: FlutterFlowTheme.of(context).primaryText, - ), - borderSide: BorderSide( + }, + options: FFButtonOptions( + width: 130, + height: 40, color: FlutterFlowTheme.of(context).primaryBackground, - width: 1, + elevation: 0, + textStyle: TextStyle( + color: FlutterFlowTheme.of(context).primaryText, + ), + borderSide: BorderSide( + color: FlutterFlowTheme.of(context).primaryBackground, + width: 1, + ), + // borderRadius: 12, ), - // borderRadius: 12, ), - ), ], // 'MIN', 'PEQ', 'MED', 'GRA', 'GIG' labelsHashMap: Map.from({ - if (item['species'] != null && item['species'] != '') - '${FFLocalizations.of(context).getVariableText(ptText: "Espécie", enText: "Species")}:': - item['species'].toString().toUpperCase(), - if (item['breed'] != null && item['breed'] != '') - '${FFLocalizations.of(context).getVariableText(ptText: "Raça", enText: "Breed")}:': - item['breed'].toString().toUpperCase(), - if (item['color'] != null && item['color'] != '') - '${FFLocalizations.of(context).getVariableText(ptText: "Cor", enText: "Color")}:': - item['color'].toString().toUpperCase(), - if (item['birthdayDate'] != null && item['birthdayDate'] != '') - '${FFLocalizations.of(context).getVariableText(ptText: "Data de Nascimento", enText: "Date of Birth")}:': - ValidatorUtil.formatDateTimePicker(item['birthdayDate']), - if (item['gender'] != null && item['gender'] != '') - '${FFLocalizations.of(context).getVariableText(ptText: "Gênero", enText: "Gender")}:': - item['gender'] == 'MAC' - ? FFLocalizations.of(context) - .getVariableText(ptText: 'MACHO', enText: 'MALE') - : FFLocalizations.of(context) - .getVariableText(enText: 'FEMALE', ptText: 'FÊMEA'), + if (item['species'] != null && item['species'] != '') '${FFLocalizations.of(context).getVariableText(ptText: "Espécie", enText: "Species")}:': item['species'].toString().toUpperCase(), + if (item['breed'] != null && item['breed'] != '') '${FFLocalizations.of(context).getVariableText(ptText: "Raça", enText: "Breed")}:': item['breed'].toString().toUpperCase(), + if (item['color'] != null && item['color'] != '') '${FFLocalizations.of(context).getVariableText(ptText: "Cor", enText: "Color")}:': item['color'].toString().toUpperCase(), + if (item['birthdayDate'] != null && item['birthdayDate'] != '') '${FFLocalizations.of(context).getVariableText(ptText: "Data de Nascimento", enText: "Date of Birth")}:': ValidatorUtil.formatDateTimePicker(item['birthdayDate']), + if (item['gender'] != null && item['gender'] != '') '${FFLocalizations.of(context).getVariableText(ptText: "Gênero", enText: "Gender")}:': item['gender'] == 'MAC' ? FFLocalizations.of(context).getVariableText(ptText: 'MACHO', enText: 'MALE') : FFLocalizations.of(context).getVariableText(enText: 'FEMALE', ptText: 'FÊMEA'), if (item['size'] != null && item['size'] != '') - '${FFLocalizations.of(context).getVariableText(ptText: "Porte", enText: "Size")}:': - item['size'] == 'MIN' - ? FFLocalizations.of(context) - .getVariableText(ptText: 'MINI', enText: 'MINI') - : item['size'] == 'PEQ' - ? FFLocalizations.of(context) - .getVariableText(ptText: 'PEQUENO', enText: 'SMALL') - : item['size'] == 'MED' - ? FFLocalizations.of(context).getVariableText( - ptText: 'MÉDIO', enText: 'MEDIUM') - : item['size'] == 'GRD' - ? FFLocalizations.of(context).getVariableText( - ptText: 'GRANDE', enText: 'LARGE') - : item['size'] == 'GIG' - ? FFLocalizations.of(context).getVariableText( - ptText: 'GIGANTE', enText: 'GIANT') - : '', - if (item['notes'] != null && item['notes'] != '') - '${FFLocalizations.of(context).getVariableText(ptText: "Observação", enText: "Notes")}:': - item['notes'] ?? '', + '${FFLocalizations.of(context).getVariableText(ptText: "Porte", enText: "Size")}:': item['size'] == 'MIN' + ? FFLocalizations.of(context).getVariableText(ptText: 'MINI', enText: 'MINI') + : item['size'] == 'PEQ' + ? FFLocalizations.of(context).getVariableText(ptText: 'PEQUENO', enText: 'SMALL') + : item['size'] == 'MED' + ? FFLocalizations.of(context).getVariableText(ptText: 'MÉDIO', enText: 'MEDIUM') + : item['size'] == 'GRD' + ? FFLocalizations.of(context).getVariableText(ptText: 'GRANDE', enText: 'LARGE') + : item['size'] == 'GIG' + ? FFLocalizations.of(context).getVariableText(ptText: 'GIGANTE', enText: 'GIANT') + : '', + if (item['notes'] != null && item['notes'] != '') '${FFLocalizations.of(context).getVariableText(ptText: "Observação", enText: "Notes")}:': item['notes'] ?? '', }), - imagePath: - 'https://freaccess.com.br/freaccess/getImage.php?devUUID=$devUUID&userUUID=$userUUID&cliID=$cliUUID&atividade=consultaFotoPet&petId=${item['id'] ?? ''}', + imagePath: 'https://freaccess.com.br/freaccess/getImage.php?devUUID=$devUUID&userUUID=$userUUID&cliID=$cliUUID&atividade=consultaFotoPet&petId=${item['id'] ?? ''}', statusHashMap: [ if (item['gender'] == "MAC") Map.from({ diff --git a/lib/pages/pets_page/pets_page_widget.dart b/lib/pages/pets_page/pets_page_widget.dart index c965d7ef..21664cf9 100644 --- a/lib/pages/pets_page/pets_page_widget.dart +++ b/lib/pages/pets_page/pets_page_widget.dart @@ -1,4 +1,3 @@ - import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:hub/components/atomic_components/shared_components_atoms/appbar.dart'; @@ -11,7 +10,7 @@ import 'package:hub/flutter_flow/flutter_flow_theme.dart'; import 'package:hub/flutter_flow/flutter_flow_util.dart'; import 'package:hub/flutter_flow/form_field_controller.dart'; import 'package:hub/flutter_flow/nav/nav.dart'; -import 'package:hub/pages/pets_page/pets_history_screen.dart'; +import 'package:hub/pages/pets_on_the_property_page/pets_history_screen.dart'; import 'package:hub/pages/pets_page/pets_page_model.dart'; import 'package:material_symbols_icons/symbols.dart'; @@ -28,8 +27,7 @@ class PetsPageWidget extends StatefulWidget { State createState() => _PetsPageWidgetState(); } -class _PetsPageWidgetState extends State - with SingleTickerProviderStateMixin { +class _PetsPageWidgetState extends State with SingleTickerProviderStateMixin { late PetsPageModel _model; @override @@ -67,10 +65,7 @@ class _PetsPageWidgetState extends State Widget build(BuildContext context) { _model.buildContext = context; - return Scaffold( - appBar: _buildAppBar(context), - backgroundColor: FlutterFlowTheme.of(context).primaryBackground, - body: _buildTabView(context)); + return Scaffold(appBar: _buildAppBar(context), backgroundColor: FlutterFlowTheme.of(context).primaryBackground, body: _buildTabView(context)); } PreferredSizeWidget _buildAppBar(BuildContext context) { @@ -90,17 +85,10 @@ class _PetsPageWidgetState extends State return TabViewUtil( context: context, model: _model, - labelTab1: _model.isEditing - ? FFLocalizations.of(context) - .getVariableText(ptText: 'Editar', enText: 'Edit') - : FFLocalizations.of(context) - .getVariableText(ptText: 'Cadastrar', enText: 'Register'), - labelTab2: FFLocalizations.of(context) - .getVariableText(ptText: 'Consultar', enText: 'History'), + labelTab1: _model.isEditing ? FFLocalizations.of(context).getVariableText(ptText: 'Editar', enText: 'Edit') : FFLocalizations.of(context).getVariableText(ptText: 'Cadastrar', enText: 'Register'), + labelTab2: FFLocalizations.of(context).getVariableText(ptText: 'Consultar', enText: 'History'), controller: _model.tabBarController, - widget1: _model.isEditing - ? _buildEditForm(context) - : _buildRegisterForm(context), + widget1: _model.isEditing ? _buildEditForm(context) : _buildRegisterForm(context), widget2: PetsHistoryScreen(model: _model), onEditingChanged: onEditingChanged, ); @@ -124,8 +112,7 @@ class _PetsPageWidgetState extends State 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), ), ), ), @@ -133,437 +120,305 @@ class _PetsPageWidgetState extends State Form( key: _model.registerFormKey, autovalidateMode: AutovalidateMode.onUserInteraction, - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Padding( - padding: const EdgeInsets.fromLTRB(0, 10, 0, 20), - child: MediaUploadButtonUtil( - onUploadComplete: _model.handleUploadComplete, - isUploading: _model.isDataUploading, - uploadedFiles: _model.uploadedLocalFile, - labelText: FFLocalizations.of(context).getVariableText( - ptText: 'Clique para adicionar a foto de seu Pet', - enText: 'Click to add your Pet\'s photo'), - ), - ), - CustomInputUtil( - controller: _model.textControllerName, - validator: _model.textControllerNameValidator - .asValidator(context), - focusNode: _model.textFieldFocusName, - labelText: FFLocalizations.of(context) - .getVariableText(ptText: 'Nome', enText: 'Name'), - hintText: FFLocalizations.of(context) - .getVariableText(ptText: 'Nome', enText: 'Name'), - suffixIcon: Symbols.format_color_text, - haveMaxLength: true, - onChanged: (value) => setState(() {}), - maxLength: 80, - ), - CustomInputUtil( - controller: _model.textControllerSpecies, - validator: _model.textControllerSpeciesValidator - .asValidator(context), - focusNode: _model.textFieldFocusSpecies, - labelText: FFLocalizations.of(context).getVariableText( - ptText: 'Espécie', enText: 'Species'), - hintText: FFLocalizations.of(context).getVariableText( - ptText: 'Ex: Cachorro, Gato, Papagaio', - enText: 'e.g. Dog, Cat, Parrot'), - suffixIcon: Symbols.sound_detection_dog_barking, - haveMaxLength: true, - onChanged: (value) => setState(() {}), - maxLength: 80, - ), - Padding( - padding: const EdgeInsets.fromLTRB(0, 0, 0, 15), - child: CustomInputUtil( - controller: _model.textControllerRace, - validator: _model.textControllerRaceValidator - .asValidator(context), - focusNode: _model.textFieldFocusRace, - labelText: FFLocalizations.of(context) - .getVariableText(ptText: 'Raça', enText: 'Race'), - hintText: FFLocalizations.of(context).getVariableText( - ptText: 'Ex: Labrador, Poodle, Siamês, Persa', - enText: 'e.g. Labrador, Poodle, Siamese, Persian'), - suffixIcon: Icons.pets_outlined, - haveMaxLength: true, - onChanged: (value) => setState(() {}), - maxLength: 80, - ), - ), - Padding( - padding: const EdgeInsets.fromLTRB(0, 0, 0, 15), - child: CustomInputUtil( - controller: _model.textControllerColor, - validator: _model.textControllerColorValidator - .asValidator(context), - focusNode: _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(0, 0, 0, 15), - child: Row( - mainAxisSize: MainAxisSize.max, - children: [ - SizedBox( - width: MediaQuery.of(context).size.width, - height: 60.0, - child: Stack( - children: [ - Padding( - padding: const EdgeInsetsDirectional.fromSTEB( - 24.0, 0.0, 24.0, 0.0), - child: TextFormField( - controller: _model.textControllerData, - focusNode: _model.textFieldFocusData, - cursorColor: - FlutterFlowTheme.of(context).primary, - readOnly: true, - autovalidateMode: - AutovalidateMode.onUserInteraction, - autofocus: false, - obscureText: false, - decoration: InputDecoration( - isDense: true, - labelStyle: FlutterFlowTheme.of(context) - .labelMedium - .override( - fontFamily: - FlutterFlowTheme.of(context) - .labelMediumFamily, - color: FlutterFlowTheme.of(context) - .primaryText, - letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap() - .containsKey( - FlutterFlowTheme.of(context) - .labelMediumFamily), - ), - hintText: FFLocalizations.of(context) - .getVariableText( - ptText: 'Data de Nascimento', - enText: 'Date of Birth', + child: Column(mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 10, 0, 20), + child: MediaUploadButtonUtil( + onUploadComplete: _model.handleUploadComplete, + isUploading: _model.isDataUploading, + uploadedFiles: _model.uploadedLocalFile, + labelText: FFLocalizations.of(context).getVariableText(ptText: 'Clique para adicionar a foto de seu Pet', enText: 'Click to add your Pet\'s photo'), + ), + ), + CustomInputUtil( + controller: _model.textControllerName, + validator: _model.textControllerNameValidator.asValidator(context), + focusNode: _model.textFieldFocusName, + labelText: FFLocalizations.of(context).getVariableText(ptText: 'Nome', enText: 'Name'), + hintText: FFLocalizations.of(context).getVariableText(ptText: 'Nome', enText: 'Name'), + suffixIcon: Symbols.format_color_text, + haveMaxLength: true, + onChanged: (value) => setState(() {}), + maxLength: 80, + ), + CustomInputUtil( + controller: _model.textControllerSpecies, + validator: _model.textControllerSpeciesValidator.asValidator(context), + focusNode: _model.textFieldFocusSpecies, + labelText: FFLocalizations.of(context).getVariableText(ptText: 'Espécie', enText: 'Species'), + hintText: FFLocalizations.of(context).getVariableText(ptText: 'Ex: Cachorro, Gato, Papagaio', enText: 'e.g. Dog, Cat, Parrot'), + suffixIcon: Symbols.sound_detection_dog_barking, + haveMaxLength: true, + onChanged: (value) => setState(() {}), + maxLength: 80, + ), + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 15), + child: CustomInputUtil( + controller: _model.textControllerRace, + validator: _model.textControllerRaceValidator.asValidator(context), + focusNode: _model.textFieldFocusRace, + labelText: FFLocalizations.of(context).getVariableText(ptText: 'Raça', enText: 'Race'), + hintText: FFLocalizations.of(context).getVariableText(ptText: 'Ex: Labrador, Poodle, Siamês, Persa', enText: 'e.g. Labrador, Poodle, Siamese, Persian'), + suffixIcon: Icons.pets_outlined, + haveMaxLength: true, + onChanged: (value) => setState(() {}), + maxLength: 80, + ), + ), + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 15), + child: CustomInputUtil( + controller: _model.textControllerColor, + validator: _model.textControllerColorValidator.asValidator(context), + focusNode: _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(0, 0, 0, 15), + child: Row( + mainAxisSize: MainAxisSize.max, + children: [ + SizedBox( + width: MediaQuery.of(context).size.width, + height: 60.0, + child: Stack( + children: [ + Padding( + padding: const EdgeInsetsDirectional.fromSTEB(24.0, 0.0, 24.0, 0.0), + child: TextFormField( + controller: _model.textControllerData, + focusNode: _model.textFieldFocusData, + cursorColor: FlutterFlowTheme.of(context).primary, + readOnly: true, + autovalidateMode: AutovalidateMode.onUserInteraction, + autofocus: false, + obscureText: false, + decoration: InputDecoration( + isDense: true, + labelStyle: FlutterFlowTheme.of(context).labelMedium.override( + fontFamily: FlutterFlowTheme.of(context).labelMediumFamily, + color: FlutterFlowTheme.of(context).primaryText, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).labelMediumFamily), ), - hintStyle: FlutterFlowTheme.of(context) - .labelMedium - .override( - fontFamily: - FlutterFlowTheme.of(context) - .labelMediumFamily, - color: FlutterFlowTheme.of(context) - .primaryText, - letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap() - .containsKey( - FlutterFlowTheme.of(context) - .labelMediumFamily), - lineHeight: 1.0, - ), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - color: FlutterFlowTheme.of(context) - .customColor6, - width: 0.5, - ), - borderRadius: - BorderRadius.circular(10.0), - ), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - color: FlutterFlowTheme.of(context) - .primary, - width: 0.5, - ), - borderRadius: - BorderRadius.circular(10.0), - ), - errorBorder: OutlineInputBorder( - borderSide: BorderSide( - color: FlutterFlowTheme.of(context) - .error, - width: 0.5, - ), - borderRadius: - BorderRadius.circular(10.0), - ), - focusedErrorBorder: OutlineInputBorder( - borderSide: BorderSide( - color: FlutterFlowTheme.of(context) - .error, - width: 0.5, - ), - borderRadius: - BorderRadius.circular(10.0), - ), - suffixIcon: Icon( - Icons.date_range, - color: FlutterFlowTheme.of(context) - .accent1, + hintText: FFLocalizations.of(context).getVariableText( + ptText: 'Data de Nascimento', + enText: 'Date of Birth', + ), + hintStyle: FlutterFlowTheme.of(context).labelMedium.override( + fontFamily: FlutterFlowTheme.of(context).labelMediumFamily, + color: FlutterFlowTheme.of(context).primaryText, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).labelMediumFamily), + lineHeight: 1.0, ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: FlutterFlowTheme.of(context).customColor6, + width: 0.5, ), - style: FlutterFlowTheme.of(context) - .bodyMedium - .override( - fontFamily: - FlutterFlowTheme.of(context) - .bodyMediumFamily, - letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap() - .containsKey( - FlutterFlowTheme.of(context) - .bodyMediumFamily), - lineHeight: 1.8, - ), - textAlign: TextAlign.start, - validator: _model - .textControllerDataValidator - .asValidator(context), + borderRadius: BorderRadius.circular(10.0), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: FlutterFlowTheme.of(context).primary, + width: 0.5, + ), + borderRadius: BorderRadius.circular(10.0), + ), + errorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: FlutterFlowTheme.of(context).error, + width: 0.5, + ), + borderRadius: BorderRadius.circular(10.0), + ), + focusedErrorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: FlutterFlowTheme.of(context).error, + width: 0.5, + ), + borderRadius: BorderRadius.circular(10.0), + ), + suffixIcon: Icon( + Icons.date_range, + color: FlutterFlowTheme.of(context).accent1, ), ), - Padding( - padding: const EdgeInsetsDirectional.fromSTEB( - 24.0, 0.0, 24.0, 0.0), - child: InkWell( - splashColor: Colors.transparent, - focusColor: Colors.transparent, - hoverColor: Colors.transparent, - highlightColor: Colors.transparent, - onTap: () async { - final pickedDate = await showDatePicker( - context: context, - initialDate: getCurrentTimestamp, - firstDate: DateTime(1990), - lastDate: DateTime.now(), - builder: (context, child) { - return wrapInMaterialDatePickerTheme( - context, - child!, - headerBackgroundColor: - FlutterFlowTheme.of(context) - .primary, - headerForegroundColor: - FlutterFlowTheme.of(context) - .info, - headerTextStyle: - FlutterFlowTheme.of(context) - .headlineLarge - .override( - fontFamily: FlutterFlowTheme - .of(context) - .headlineLargeFamily, - fontSize: 32.0, - letterSpacing: 0.0, - fontWeight: - FontWeight.w600, - useGoogleFonts: GoogleFonts - .asMap() - .containsKey( - FlutterFlowTheme.of( - context) - .headlineLargeFamily), - ), - pickerBackgroundColor: - FlutterFlowTheme.of(context) - .primaryBackground, - pickerForegroundColor: - FlutterFlowTheme.of(context) - .primaryText, - selectedDateTimeBackgroundColor: - FlutterFlowTheme.of(context) - .primary, - selectedDateTimeForegroundColor: - FlutterFlowTheme.of(context) - .info, - actionButtonForegroundColor: - FlutterFlowTheme.of(context) - .primaryText, - iconSize: 24.0, - ); - }, + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).bodyMediumFamily), + lineHeight: 1.8, + ), + textAlign: TextAlign.start, + validator: _model.textControllerDataValidator.asValidator(context), + ), + ), + Padding( + padding: const EdgeInsetsDirectional.fromSTEB(24.0, 0.0, 24.0, 0.0), + child: InkWell( + splashColor: Colors.transparent, + focusColor: Colors.transparent, + hoverColor: Colors.transparent, + highlightColor: Colors.transparent, + onTap: () async { + final pickedDate = await showDatePicker( + context: context, + initialDate: getCurrentTimestamp, + firstDate: DateTime(1990), + lastDate: DateTime.now(), + builder: (context, child) { + return wrapInMaterialDatePickerTheme( + context, + child!, + headerBackgroundColor: FlutterFlowTheme.of(context).primary, + headerForegroundColor: FlutterFlowTheme.of(context).info, + headerTextStyle: FlutterFlowTheme.of(context).headlineLarge.override( + fontFamily: FlutterFlowTheme.of(context).headlineLargeFamily, + fontSize: 32.0, + letterSpacing: 0.0, + fontWeight: FontWeight.w600, + useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).headlineLargeFamily), + ), + pickerBackgroundColor: FlutterFlowTheme.of(context).primaryBackground, + pickerForegroundColor: FlutterFlowTheme.of(context).primaryText, + selectedDateTimeBackgroundColor: FlutterFlowTheme.of(context).primary, + selectedDateTimeForegroundColor: FlutterFlowTheme.of(context).info, + actionButtonForegroundColor: FlutterFlowTheme.of(context).primaryText, + iconSize: 24.0, + ); + }, + ); + + if (pickedDate != null) { + setState(() { + _model.selectedDate = DateTime( + pickedDate.year, + pickedDate.month, + pickedDate.day, ); - if (pickedDate != null) { - setState(() { - _model.selectedDate = DateTime( - pickedDate.year, - pickedDate.month, - pickedDate.day, - ); - - _model.textControllerData = - TextEditingController( - text: dateTimeFormat( - 'dd/MM/yyyy', - _model.selectedDate, - locale: FFLocalizations.of(context) - .languageCode, - )); - _model.textControllerData?.selection = - TextSelection.collapsed( - offset: _model.textControllerData! - .text.length, - ); - }); - } - }, - child: Container( - width: double.infinity, - height: 80.0, - decoration: BoxDecoration( - borderRadius: - BorderRadius.circular(10.0), - ), - ), + _model.textControllerData = TextEditingController( + text: dateTimeFormat( + 'dd/MM/yyyy', + _model.selectedDate, + locale: FFLocalizations.of(context).languageCode, + )); + _model.textControllerData?.selection = TextSelection.collapsed( + offset: _model.textControllerData!.text.length, + ); + }); + } + }, + child: Container( + width: double.infinity, + height: 80.0, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.0), ), ), - ], + ), ), - ), - ], - ), - ), - Align( - alignment: const AlignmentDirectional(-1.0, 0.0), - child: Padding( - padding: const EdgeInsetsDirectional.fromSTEB( - 24.0, 0, 0.0, 15), - child: Text( - FFLocalizations.of(context).getVariableText( - ptText: 'Selecione as opções disponíveis', - enText: 'Select the available options', - ), - textAlign: TextAlign.start, - style: FlutterFlowTheme.of(context) - .bodySmall - .override( - fontFamily: FlutterFlowTheme.of(context) - .bodySmallFamily, - letterSpacing: 0.0, - fontWeight: FontWeight.w600, - useGoogleFonts: GoogleFonts.asMap().containsKey( - FlutterFlowTheme.of(context) - .bodyMediumFamily), - ), + ], ), ), - ), - Padding( - padding: const EdgeInsets.fromLTRB(0, 0, 0, 15), - child: CustomSelect( - options: const ['MAC', 'FEM'], - controller: _model.dropDownValueController1 ??= - FormFieldController( - _model.dropDownValue1 ??= ''), - isRequired: true, - changed: (val) => safeSetState(() { - _model.dropDownValue1 = val; - }), - dropDownValue: _model.dropDownValue1, - optionsLabel: [ - FFLocalizations.of(context).getVariableText( - ptText: 'Macho', enText: 'Male'), - FFLocalizations.of(context).getVariableText( - ptText: 'Fêmea', enText: 'Female') - ], - hintText: FFLocalizations.of(context).getVariableText( - ptText: 'Selecione o gênero do Pet', - enText: 'Select the gender of the Pet')), - ), - Padding( - padding: const EdgeInsets.fromLTRB(0, 0, 0, 15), - child: CustomSelect( - options: const ['MIN', 'PEQ', 'MED', 'GRA', 'GIG'], - controller: _model.dropDownValueController2 ??= - FormFieldController( - _model.dropDownValue2 ??= ''), - isRequired: true, - changed: (val) => safeSetState(() { - _model.dropDownValue2 = val; - }), - dropDownValue: _model.dropDownValue2, - optionsLabel: [ - FFLocalizations.of(context).getVariableText( - ptText: 'Mini', enText: 'Mini'), - FFLocalizations.of(context).getVariableText( - ptText: 'Pequeno', enText: 'Small'), - FFLocalizations.of(context).getVariableText( - ptText: 'Médio', enText: 'Medium'), - FFLocalizations.of(context).getVariableText( - ptText: 'Grande', enText: 'Big'), - FFLocalizations.of(context).getVariableText( - ptText: 'Gigante', enText: 'Giant'), - ], - hintText: FFLocalizations.of(context).getVariableText( - ptText: 'Selecione o porte do Pet', - enText: 'Select the size of the Pet')), - ), - Align( - alignment: const AlignmentDirectional(-1.0, 0.0), - child: Padding( - padding: const EdgeInsetsDirectional.fromSTEB( - 24.0, 0, 0.0, 15), - child: Text( - FFLocalizations.of(context).getVariableText( - ptText: - 'Você tem alguma observação sobre o seu Pet?', - enText: - 'Do you have any observations about your Pet?', - ), - textAlign: TextAlign.start, - style: FlutterFlowTheme.of(context) - .bodySmall - .override( - fontFamily: FlutterFlowTheme.of(context) - .bodySmallFamily, - letterSpacing: 0.0, - fontWeight: FontWeight.w600, - useGoogleFonts: GoogleFonts.asMap().containsKey( - FlutterFlowTheme.of(context) - .bodyMediumFamily), - ), - ), + ], + ), + ), + Align( + alignment: const AlignmentDirectional(-1.0, 0.0), + child: Padding( + padding: const EdgeInsetsDirectional.fromSTEB(24.0, 0, 0.0, 15), + child: Text( + FFLocalizations.of(context).getVariableText( + ptText: 'Selecione as opções disponíveis', + enText: 'Select the available options', ), + textAlign: TextAlign.start, + style: FlutterFlowTheme.of(context).bodySmall.override( + fontFamily: FlutterFlowTheme.of(context).bodySmallFamily, + letterSpacing: 0.0, + fontWeight: FontWeight.w600, + useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).bodyMediumFamily), + ), ), - CustomInputUtil( - controller: _model.textControllerObservation, - validator: _model.textControllerObservationValidator - .asValidator(context), - focusNode: _model.textFieldFocusObservation, - labelText: FFLocalizations.of(context).getVariableText( - ptText: 'Escreva as suas observações aqui...', - enText: 'Write your observations here...'), - hintText: FFLocalizations.of(context).getVariableText( - ptText: 'Escreva as suas observações aqui...', - enText: 'Write your observations here...'), - suffixIcon: Icons.text_fields, - haveMaxLength: true, - onChanged: (value) => setState(() {}), - maxLength: 250, + ), + ), + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 15), + child: CustomSelect( + options: const ['MAC', 'FEM'], + controller: _model.dropDownValueController1 ??= FormFieldController(_model.dropDownValue1 ??= ''), + isRequired: true, + changed: (val) => safeSetState(() { + _model.dropDownValue1 = val; + }), + dropDownValue: _model.dropDownValue1, + optionsLabel: [FFLocalizations.of(context).getVariableText(ptText: 'Macho', enText: 'Male'), FFLocalizations.of(context).getVariableText(ptText: 'Fêmea', enText: 'Female')], + hintText: FFLocalizations.of(context).getVariableText(ptText: 'Selecione o gênero do Pet', enText: 'Select the gender of the Pet')), + ), + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 15), + child: CustomSelect( + options: const ['MIN', 'PEQ', 'MED', 'GRA', 'GIG'], + controller: _model.dropDownValueController2 ??= FormFieldController(_model.dropDownValue2 ??= ''), + isRequired: true, + changed: (val) => safeSetState(() { + _model.dropDownValue2 = val; + }), + dropDownValue: _model.dropDownValue2, + optionsLabel: [ + FFLocalizations.of(context).getVariableText(ptText: 'Mini', enText: 'Mini'), + FFLocalizations.of(context).getVariableText(ptText: 'Pequeno', enText: 'Small'), + FFLocalizations.of(context).getVariableText(ptText: 'Médio', enText: 'Medium'), + FFLocalizations.of(context).getVariableText(ptText: 'Grande', enText: 'Big'), + FFLocalizations.of(context).getVariableText(ptText: 'Gigante', enText: 'Giant'), + ], + hintText: FFLocalizations.of(context).getVariableText(ptText: 'Selecione o porte do Pet', enText: 'Select the size of the Pet')), + ), + Align( + alignment: const AlignmentDirectional(-1.0, 0.0), + child: Padding( + padding: const EdgeInsetsDirectional.fromSTEB(24.0, 0, 0.0, 15), + child: Text( + FFLocalizations.of(context).getVariableText( + ptText: 'Você tem alguma observação sobre o seu Pet?', + enText: 'Do you have any observations about your Pet?', + ), + textAlign: TextAlign.start, + style: FlutterFlowTheme.of(context).bodySmall.override( + fontFamily: FlutterFlowTheme.of(context).bodySmallFamily, + letterSpacing: 0.0, + fontWeight: FontWeight.w600, + useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).bodyMediumFamily), + ), ), - Padding( - padding: const EdgeInsets.fromLTRB(70, 20, 70, 30), - child: SubmitButtonUtil( - labelText: FFLocalizations.of(context) - .getVariableText( - ptText: 'Cadastrar', enText: 'Register'), - onPressed: _model.isFormValid(context) - ? _model.registerPet - : null), - ), - ])), + ), + ), + CustomInputUtil( + controller: _model.textControllerObservation, + validator: _model.textControllerObservationValidator.asValidator(context), + focusNode: _model.textFieldFocusObservation, + labelText: FFLocalizations.of(context).getVariableText(ptText: 'Escreva as suas observações aqui...', enText: 'Write your observations here...'), + hintText: FFLocalizations.of(context).getVariableText(ptText: 'Escreva as suas observações aqui...', enText: 'Write your observations here...'), + suffixIcon: Icons.text_fields, + haveMaxLength: true, + onChanged: (value) => setState(() {}), + maxLength: 250, + ), + Padding( + padding: const EdgeInsets.fromLTRB(70, 20, 70, 30), + child: SubmitButtonUtil(labelText: FFLocalizations.of(context).getVariableText(ptText: 'Cadastrar', enText: 'Register'), onPressed: _model.isFormValid(context) ? _model.registerPet : null), + ), + ])), ], ), ); @@ -587,8 +442,7 @@ class _PetsPageWidgetState extends State 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), ), ), ), @@ -596,442 +450,308 @@ class _PetsPageWidgetState extends State Form( key: _model.updateFormKey, autovalidateMode: AutovalidateMode.onUserInteraction, - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceEvenly, - children: [ - Padding( - padding: const EdgeInsets.fromLTRB(0, 10, 0, 20), - child: MediaUploadButtonUtil( - onUploadComplete: _model.handleUploadComplete, - isUploading: _model.isDataUploading, - uploadedFiles: _model.uploadedLocalFile, - labelText: FFLocalizations.of(context).getVariableText( - ptText: 'Clique para adicionar a foto de seu Pet', - enText: 'Click to add your Pet\'s photo'), - ), - ), - CustomInputUtil( - controller: _model.textControllerName, - validator: _model.textControllerNameValidator - .asValidator(context), - focusNode: _model.textFieldFocusName, - labelText: FFLocalizations.of(context) - .getVariableText(ptText: 'Nome', enText: 'Name'), - hintText: FFLocalizations.of(context) - .getVariableText(ptText: 'Nome', enText: 'Name'), - suffixIcon: Symbols.format_color_text, - haveMaxLength: true, - onChanged: (value) => setState(() {}), - maxLength: 80, - ), - Padding( - padding: const EdgeInsets.fromLTRB(0, 0, 0, 15), - child: CustomInputUtil( - controller: _model.textControllerSpecies, - validator: _model.textControllerSpeciesValidator - .asValidator(context), - focusNode: _model.textFieldFocusSpecies, - labelText: FFLocalizations.of(context).getVariableText( - ptText: 'Espécie', enText: 'Species'), - hintText: FFLocalizations.of(context).getVariableText( - ptText: 'Ex: Cachorro, Gato, Papagaio', - enText: 'e.g. Dog, Cat, Parrot'), - suffixIcon: Symbols.sound_detection_dog_barking, - haveMaxLength: true, - onChanged: (value) => setState(() {}), - maxLength: 80, - ), - ), - Padding( - padding: const EdgeInsets.fromLTRB(0, 0, 0, 15), - child: CustomInputUtil( - controller: _model.textControllerRace, - validator: _model.textControllerRaceValidator - .asValidator(context), - focusNode: _model.textFieldFocusRace, - labelText: FFLocalizations.of(context) - .getVariableText(ptText: 'Raça', enText: 'Race'), - hintText: FFLocalizations.of(context).getVariableText( - ptText: 'Ex: Labrador, Poodle, Siamês, Persa', - enText: 'e.g. Labrador, Poodle, Siamese, Persian'), - suffixIcon: Icons.pets_outlined, - haveMaxLength: true, - onChanged: (value) => setState(() {}), - maxLength: 80, - ), - ), - Padding( - padding: const EdgeInsets.fromLTRB(0, 0, 0, 15), - child: CustomInputUtil( - controller: _model.textControllerColor, - validator: _model.textControllerColorValidator - .asValidator(context), - focusNode: _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(0, 0, 0, 15), - child: Row( - mainAxisSize: MainAxisSize.max, - children: [ - SizedBox( - width: MediaQuery.of(context).size.width, - height: 60.0, - child: Stack( - children: [ - Padding( - padding: const EdgeInsetsDirectional.fromSTEB( - 24.0, 0.0, 24.0, 0.0), - child: TextFormField( - controller: _model.textControllerData, - focusNode: _model.textFieldFocusData, - cursorColor: - FlutterFlowTheme.of(context).primary, - readOnly: true, - autovalidateMode: - AutovalidateMode.onUserInteraction, - autofocus: false, - obscureText: false, - decoration: InputDecoration( - isDense: true, - labelStyle: FlutterFlowTheme.of(context) - .labelMedium - .override( - fontFamily: - FlutterFlowTheme.of(context) - .labelMediumFamily, - color: FlutterFlowTheme.of(context) - .primaryText, - letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap() - .containsKey( - FlutterFlowTheme.of(context) - .labelMediumFamily), - ), - hintText: FFLocalizations.of(context) - .getVariableText( - ptText: 'Data de Nascimento', - enText: 'Date of Birth', + child: Column(mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 10, 0, 20), + child: MediaUploadButtonUtil( + onUploadComplete: _model.handleUploadComplete, + isUploading: _model.isDataUploading, + uploadedFiles: _model.uploadedLocalFile, + labelText: FFLocalizations.of(context).getVariableText(ptText: 'Clique para adicionar a foto de seu Pet', enText: 'Click to add your Pet\'s photo'), + ), + ), + CustomInputUtil( + controller: _model.textControllerName, + validator: _model.textControllerNameValidator.asValidator(context), + focusNode: _model.textFieldFocusName, + labelText: FFLocalizations.of(context).getVariableText(ptText: 'Nome', enText: 'Name'), + hintText: FFLocalizations.of(context).getVariableText(ptText: 'Nome', enText: 'Name'), + suffixIcon: Symbols.format_color_text, + haveMaxLength: true, + onChanged: (value) => setState(() {}), + maxLength: 80, + ), + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 15), + child: CustomInputUtil( + controller: _model.textControllerSpecies, + validator: _model.textControllerSpeciesValidator.asValidator(context), + focusNode: _model.textFieldFocusSpecies, + labelText: FFLocalizations.of(context).getVariableText(ptText: 'Espécie', enText: 'Species'), + hintText: FFLocalizations.of(context).getVariableText(ptText: 'Ex: Cachorro, Gato, Papagaio', enText: 'e.g. Dog, Cat, Parrot'), + suffixIcon: Symbols.sound_detection_dog_barking, + haveMaxLength: true, + onChanged: (value) => setState(() {}), + maxLength: 80, + ), + ), + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 15), + child: CustomInputUtil( + controller: _model.textControllerRace, + validator: _model.textControllerRaceValidator.asValidator(context), + focusNode: _model.textFieldFocusRace, + labelText: FFLocalizations.of(context).getVariableText(ptText: 'Raça', enText: 'Race'), + hintText: FFLocalizations.of(context).getVariableText(ptText: 'Ex: Labrador, Poodle, Siamês, Persa', enText: 'e.g. Labrador, Poodle, Siamese, Persian'), + suffixIcon: Icons.pets_outlined, + haveMaxLength: true, + onChanged: (value) => setState(() {}), + maxLength: 80, + ), + ), + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 15), + child: CustomInputUtil( + controller: _model.textControllerColor, + validator: _model.textControllerColorValidator.asValidator(context), + focusNode: _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(0, 0, 0, 15), + child: Row( + mainAxisSize: MainAxisSize.max, + children: [ + SizedBox( + width: MediaQuery.of(context).size.width, + height: 60.0, + child: Stack( + children: [ + Padding( + padding: const EdgeInsetsDirectional.fromSTEB(24.0, 0.0, 24.0, 0.0), + child: TextFormField( + controller: _model.textControllerData, + focusNode: _model.textFieldFocusData, + cursorColor: FlutterFlowTheme.of(context).primary, + readOnly: true, + autovalidateMode: AutovalidateMode.onUserInteraction, + autofocus: false, + obscureText: false, + decoration: InputDecoration( + isDense: true, + labelStyle: FlutterFlowTheme.of(context).labelMedium.override( + fontFamily: FlutterFlowTheme.of(context).labelMediumFamily, + color: FlutterFlowTheme.of(context).primaryText, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).labelMediumFamily), ), - hintStyle: FlutterFlowTheme.of(context) - .labelMedium - .override( - fontFamily: - FlutterFlowTheme.of(context) - .labelMediumFamily, - color: FlutterFlowTheme.of(context) - .primaryText, - letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap() - .containsKey( - FlutterFlowTheme.of(context) - .labelMediumFamily), - lineHeight: 1.0, - ), - enabledBorder: OutlineInputBorder( - borderSide: BorderSide( - color: FlutterFlowTheme.of(context) - .customColor6, - width: 0.5, - ), - borderRadius: - BorderRadius.circular(10.0), - ), - focusedBorder: OutlineInputBorder( - borderSide: BorderSide( - color: FlutterFlowTheme.of(context) - .primary, - width: 0.5, - ), - borderRadius: - BorderRadius.circular(10.0), - ), - errorBorder: OutlineInputBorder( - borderSide: BorderSide( - color: FlutterFlowTheme.of(context) - .error, - width: 0.5, - ), - borderRadius: - BorderRadius.circular(10.0), - ), - focusedErrorBorder: OutlineInputBorder( - borderSide: BorderSide( - color: FlutterFlowTheme.of(context) - .error, - width: 0.5, - ), - borderRadius: - BorderRadius.circular(10.0), - ), - suffixIcon: Icon( - Icons.date_range, - color: FlutterFlowTheme.of(context) - .accent1, + hintText: FFLocalizations.of(context).getVariableText( + ptText: 'Data de Nascimento', + enText: 'Date of Birth', + ), + hintStyle: FlutterFlowTheme.of(context).labelMedium.override( + fontFamily: FlutterFlowTheme.of(context).labelMediumFamily, + color: FlutterFlowTheme.of(context).primaryText, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).labelMediumFamily), + lineHeight: 1.0, ), + enabledBorder: OutlineInputBorder( + borderSide: BorderSide( + color: FlutterFlowTheme.of(context).customColor6, + width: 0.5, ), - style: FlutterFlowTheme.of(context) - .bodyMedium - .override( - fontFamily: - FlutterFlowTheme.of(context) - .bodyMediumFamily, - letterSpacing: 0.0, - useGoogleFonts: GoogleFonts.asMap() - .containsKey( - FlutterFlowTheme.of(context) - .bodyMediumFamily), - lineHeight: 1.8, - ), - textAlign: TextAlign.start, - validator: _model - .textControllerDataValidator - .asValidator(context), + borderRadius: BorderRadius.circular(10.0), + ), + focusedBorder: OutlineInputBorder( + borderSide: BorderSide( + color: FlutterFlowTheme.of(context).primary, + width: 0.5, + ), + borderRadius: BorderRadius.circular(10.0), + ), + errorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: FlutterFlowTheme.of(context).error, + width: 0.5, + ), + borderRadius: BorderRadius.circular(10.0), + ), + focusedErrorBorder: OutlineInputBorder( + borderSide: BorderSide( + color: FlutterFlowTheme.of(context).error, + width: 0.5, + ), + borderRadius: BorderRadius.circular(10.0), + ), + suffixIcon: Icon( + Icons.date_range, + color: FlutterFlowTheme.of(context).accent1, ), ), - Padding( - padding: const EdgeInsetsDirectional.fromSTEB( - 24.0, 0.0, 24.0, 0.0), - child: InkWell( - splashColor: Colors.transparent, - focusColor: Colors.transparent, - hoverColor: Colors.transparent, - highlightColor: Colors.transparent, - onTap: () async { - final pickedDate = await showDatePicker( - context: context, - initialDate: DateFormat('dd/MM/yyyy') - .tryParse( - _model.textControllerData.text), - firstDate: DateTime(1990), - lastDate: DateTime.now(), - builder: (context, child) { - return wrapInMaterialDatePickerTheme( - context, - child!, - headerBackgroundColor: - FlutterFlowTheme.of(context) - .primary, - headerForegroundColor: - FlutterFlowTheme.of(context) - .info, - headerTextStyle: - FlutterFlowTheme.of(context) - .headlineLarge - .override( - fontFamily: FlutterFlowTheme - .of(context) - .headlineLargeFamily, - fontSize: 32.0, - letterSpacing: 0.0, - fontWeight: - FontWeight.w600, - useGoogleFonts: GoogleFonts - .asMap() - .containsKey( - FlutterFlowTheme.of( - context) - .headlineLargeFamily), - ), - pickerBackgroundColor: - FlutterFlowTheme.of(context) - .primaryBackground, - pickerForegroundColor: - FlutterFlowTheme.of(context) - .primaryText, - selectedDateTimeBackgroundColor: - FlutterFlowTheme.of(context) - .primary, - selectedDateTimeForegroundColor: - FlutterFlowTheme.of(context) - .info, - actionButtonForegroundColor: - FlutterFlowTheme.of(context) - .primaryText, - iconSize: 24.0, - ); - }, + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).bodyMediumFamily), + lineHeight: 1.8, + ), + textAlign: TextAlign.start, + validator: _model.textControllerDataValidator.asValidator(context), + ), + ), + Padding( + padding: const EdgeInsetsDirectional.fromSTEB(24.0, 0.0, 24.0, 0.0), + child: InkWell( + splashColor: Colors.transparent, + focusColor: Colors.transparent, + hoverColor: Colors.transparent, + highlightColor: Colors.transparent, + onTap: () async { + final pickedDate = await showDatePicker( + context: context, + initialDate: DateFormat('dd/MM/yyyy').tryParse(_model.textControllerData.text), + firstDate: DateTime(1990), + lastDate: DateTime.now(), + builder: (context, child) { + return wrapInMaterialDatePickerTheme( + context, + child!, + headerBackgroundColor: FlutterFlowTheme.of(context).primary, + headerForegroundColor: FlutterFlowTheme.of(context).info, + headerTextStyle: FlutterFlowTheme.of(context).headlineLarge.override( + fontFamily: FlutterFlowTheme.of(context).headlineLargeFamily, + fontSize: 32.0, + letterSpacing: 0.0, + fontWeight: FontWeight.w600, + useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).headlineLargeFamily), + ), + pickerBackgroundColor: FlutterFlowTheme.of(context).primaryBackground, + pickerForegroundColor: FlutterFlowTheme.of(context).primaryText, + selectedDateTimeBackgroundColor: FlutterFlowTheme.of(context).primary, + selectedDateTimeForegroundColor: FlutterFlowTheme.of(context).info, + actionButtonForegroundColor: FlutterFlowTheme.of(context).primaryText, + iconSize: 24.0, + ); + }, + ); + + if (pickedDate != null) { + setState(() { + _model.selectedDate = DateTime( + pickedDate.year, + pickedDate.month, + pickedDate.day, ); - if (pickedDate != null) { - setState(() { - _model.selectedDate = DateTime( - pickedDate.year, - pickedDate.month, - pickedDate.day, - ); - - _model.textControllerData = - TextEditingController( - text: dateTimeFormat( - 'dd/MM/yyyy', - _model.selectedDate, - locale: FFLocalizations.of(context) - .languageCode, - )); - _model.textControllerData?.selection = - TextSelection.collapsed( - offset: _model.textControllerData! - .text.length, - ); - }); - } - }, - child: Container( - width: double.infinity, - height: 80.0, - decoration: BoxDecoration( - borderRadius: - BorderRadius.circular(10.0), - ), - ), + _model.textControllerData = TextEditingController( + text: dateTimeFormat( + 'dd/MM/yyyy', + _model.selectedDate, + locale: FFLocalizations.of(context).languageCode, + )); + _model.textControllerData?.selection = TextSelection.collapsed( + offset: _model.textControllerData!.text.length, + ); + }); + } + }, + child: Container( + width: double.infinity, + height: 80.0, + decoration: BoxDecoration( + borderRadius: BorderRadius.circular(10.0), ), ), - ], + ), ), - ), - ], - ), - ), - Align( - alignment: const AlignmentDirectional(-1.0, 0.0), - child: Padding( - padding: const EdgeInsetsDirectional.fromSTEB( - 24.0, 0, 0.0, 15), - child: Text( - FFLocalizations.of(context).getVariableText( - ptText: 'Selecione as opções disponíveis', - enText: 'Select the available options', - ), - textAlign: TextAlign.start, - style: FlutterFlowTheme.of(context) - .bodySmall - .override( - fontFamily: FlutterFlowTheme.of(context) - .bodySmallFamily, - letterSpacing: 0.0, - fontWeight: FontWeight.w600, - useGoogleFonts: GoogleFonts.asMap().containsKey( - FlutterFlowTheme.of(context) - .bodyMediumFamily), - ), + ], ), ), - ), - Padding( - padding: const EdgeInsets.fromLTRB(0, 0, 0, 15), - child: CustomSelect( - options: const ['MAC', 'FEM'], - controller: _model.dropDownValueController1 ??= - FormFieldController( - _model.dropDownValue1 ??= ''), - isRequired: true, - changed: (val) => safeSetState(() { - _model.dropDownValue1 = val; - }), - dropDownValue: _model.dropDownValue1, - optionsLabel: [ - FFLocalizations.of(context).getVariableText( - ptText: 'Macho', enText: 'Male'), - FFLocalizations.of(context).getVariableText( - ptText: 'Fêmea', enText: 'Female') - ], - hintText: FFLocalizations.of(context).getVariableText( - ptText: 'Selecione o gênero do Pet', - enText: 'Select the gender of the Pet')), - ), - Padding( - padding: const EdgeInsets.fromLTRB(0, 0, 0, 15), - child: CustomSelect( - options: const ['MIN', 'PEQ', 'MED', 'GRA', 'GIG'], - controller: _model.dropDownValueController2 ??= - FormFieldController( - _model.dropDownValue2 ??= ''), - isRequired: true, - changed: (val) => safeSetState(() { - _model.dropDownValue2 = val; - }), - dropDownValue: _model.dropDownValue1, - optionsLabel: [ - FFLocalizations.of(context).getVariableText( - ptText: 'Mini', enText: 'Mini'), - FFLocalizations.of(context).getVariableText( - ptText: 'Pequeno', enText: 'Small'), - FFLocalizations.of(context).getVariableText( - ptText: 'Médio', enText: 'Medium'), - FFLocalizations.of(context).getVariableText( - ptText: 'Grande', enText: 'Big'), - FFLocalizations.of(context).getVariableText( - ptText: 'Gigante', enText: 'Giant'), - ], - hintText: FFLocalizations.of(context).getVariableText( - ptText: 'Selecione o porte do Pet', - enText: 'Select the size of the Pet')), - ), - Align( - alignment: const AlignmentDirectional(-1.0, 0.0), - child: Padding( - padding: const EdgeInsetsDirectional.fromSTEB( - 24.0, 0, 0.0, 15), - child: Text( - FFLocalizations.of(context).getVariableText( - ptText: - 'Você tem alguma observação sobre o seu Pet?', - enText: - 'Do you have any observations about your Pet?', - ), - textAlign: TextAlign.start, - style: FlutterFlowTheme.of(context) - .bodySmall - .override( - fontFamily: FlutterFlowTheme.of(context) - .bodySmallFamily, - letterSpacing: 0.0, - fontWeight: FontWeight.w600, - useGoogleFonts: GoogleFonts.asMap().containsKey( - FlutterFlowTheme.of(context) - .bodyMediumFamily), - ), - ), + ], + ), + ), + Align( + alignment: const AlignmentDirectional(-1.0, 0.0), + child: Padding( + padding: const EdgeInsetsDirectional.fromSTEB(24.0, 0, 0.0, 15), + child: Text( + FFLocalizations.of(context).getVariableText( + ptText: 'Selecione as opções disponíveis', + enText: 'Select the available options', ), + textAlign: TextAlign.start, + style: FlutterFlowTheme.of(context).bodySmall.override( + fontFamily: FlutterFlowTheme.of(context).bodySmallFamily, + letterSpacing: 0.0, + fontWeight: FontWeight.w600, + useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).bodyMediumFamily), + ), ), - CustomInputUtil( - controller: _model.textControllerObservation, - validator: _model.textControllerObservationValidator - .asValidator(context), - focusNode: _model.textFieldFocusObservation, - labelText: FFLocalizations.of(context).getVariableText( - ptText: 'Escreva as suas observações aqui...', - enText: 'Write your observations here...'), - hintText: FFLocalizations.of(context).getVariableText( - ptText: 'Escreva as suas observações aqui...', - enText: 'Write your observations here...'), - suffixIcon: Icons.text_fields, - haveMaxLength: true, - maxLength: 250, - onChanged: (value) => setState(() {}), + ), + ), + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 15), + child: CustomSelect( + options: const ['MAC', 'FEM'], + controller: _model.dropDownValueController1 ??= FormFieldController(_model.dropDownValue1 ??= ''), + isRequired: true, + changed: (val) => safeSetState(() { + _model.dropDownValue1 = val; + }), + dropDownValue: _model.dropDownValue1, + optionsLabel: [FFLocalizations.of(context).getVariableText(ptText: 'Macho', enText: 'Male'), FFLocalizations.of(context).getVariableText(ptText: 'Fêmea', enText: 'Female')], + hintText: FFLocalizations.of(context).getVariableText(ptText: 'Selecione o gênero do Pet', enText: 'Select the gender of the Pet')), + ), + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 0, 15), + child: CustomSelect( + options: const ['MIN', 'PEQ', 'MED', 'GRA', 'GIG'], + controller: _model.dropDownValueController2 ??= FormFieldController(_model.dropDownValue2 ??= ''), + isRequired: true, + changed: (val) => safeSetState(() { + _model.dropDownValue2 = val; + }), + dropDownValue: _model.dropDownValue1, + optionsLabel: [ + FFLocalizations.of(context).getVariableText(ptText: 'Mini', enText: 'Mini'), + FFLocalizations.of(context).getVariableText(ptText: 'Pequeno', enText: 'Small'), + FFLocalizations.of(context).getVariableText(ptText: 'Médio', enText: 'Medium'), + FFLocalizations.of(context).getVariableText(ptText: 'Grande', enText: 'Big'), + FFLocalizations.of(context).getVariableText(ptText: 'Gigante', enText: 'Giant'), + ], + hintText: FFLocalizations.of(context).getVariableText(ptText: 'Selecione o porte do Pet', enText: 'Select the size of the Pet')), + ), + Align( + alignment: const AlignmentDirectional(-1.0, 0.0), + child: Padding( + padding: const EdgeInsetsDirectional.fromSTEB(24.0, 0, 0.0, 15), + child: Text( + FFLocalizations.of(context).getVariableText( + ptText: 'Você tem alguma observação sobre o seu Pet?', + enText: 'Do you have any observations about your Pet?', + ), + textAlign: TextAlign.start, + style: FlutterFlowTheme.of(context).bodySmall.override( + fontFamily: FlutterFlowTheme.of(context).bodySmallFamily, + letterSpacing: 0.0, + fontWeight: FontWeight.w600, + useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).bodyMediumFamily), + ), ), - Padding( - padding: const EdgeInsets.fromLTRB(70, 20, 70, 30), - child: SubmitButtonUtil( - labelText: FFLocalizations.of(context) - .getVariableText( - ptText: 'Salvar', enText: 'Save'), - onPressed: _model.isFormValid(context) - ? _model.updatePet - : null), - ), - ])), + ), + ), + CustomInputUtil( + controller: _model.textControllerObservation, + validator: _model.textControllerObservationValidator.asValidator(context), + focusNode: _model.textFieldFocusObservation, + labelText: FFLocalizations.of(context).getVariableText(ptText: 'Escreva as suas observações aqui...', enText: 'Write your observations here...'), + hintText: FFLocalizations.of(context).getVariableText(ptText: 'Escreva as suas observações aqui...', enText: 'Write your observations here...'), + suffixIcon: Icons.text_fields, + haveMaxLength: true, + maxLength: 250, + onChanged: (value) => setState(() {}), + ), + Padding( + padding: const EdgeInsets.fromLTRB(70, 20, 70, 30), + child: SubmitButtonUtil(labelText: FFLocalizations.of(context).getVariableText(ptText: 'Salvar', enText: 'Save'), onPressed: _model.isFormValid(context) ? _model.updatePet : null), + ), + ])), ], ), ); diff --git a/lib/pages/reception_page/reception_page_widget.dart b/lib/pages/reception_page/reception_page_widget.dart index e5eca1f6..10529ad4 100644 --- a/lib/pages/reception_page/reception_page_widget.dart +++ b/lib/pages/reception_page/reception_page_widget.dart @@ -11,6 +11,7 @@ import 'package:hub/flutter_flow/flutter_flow_util.dart'; import 'package:hub/flutter_flow/flutter_flow_widgets.dart'; import 'package:hub/flutter_flow/nav/nav.dart'; import 'package:hub/pages/reception_page/reception_page_model.dart'; +import 'package:hub/shared/services/authentication/authentication_service.dart'; import 'package:hub/shared/services/localization/localization_service.dart'; import 'package:hub/shared/utils/storage_util.dart'; import 'package:provider/provider.dart'; @@ -23,7 +24,8 @@ class ReceptionPageWidget extends StatefulWidget { } class _ReceptionPageWidgetState extends State with WidgetsBindingObserver { - @override void initState() { + @override + void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); () async { @@ -35,13 +37,14 @@ class _ReceptionPageWidgetState extends State with WidgetsB LocalizationService.checkLocals(context); } - @override void dispose() { + @override + void dispose() { WidgetsBinding.instance.removeObserver(this); super.dispose(); } - - @override void didChangeAppLifecycleState(AppLifecycleState state) { + @override + void didChangeAppLifecycleState(AppLifecycleState state) { log('() => state: $state'); if (state == AppLifecycleState.resumed) { setState(() { @@ -68,46 +71,31 @@ class _ReceptionPageWidgetState extends State with WidgetsB Padding( padding: const EdgeInsets.fromLTRB(45, 0, 45, 15.0), child: Text( - FFLocalizations.of(context).getVariableText( - ptText: - 'Falta pouco para você utilizar o FRE Access Hub...', - enText: - 'You are close to using the FRE Access Hub...'), + FFLocalizations.of(context).getVariableText(ptText: 'Falta pouco para você utilizar o FRE Access Hub...', enText: 'You are close to using the FRE Access Hub...'), textAlign: TextAlign.center, - style: FlutterFlowTheme.of(context) - .displayLarge - .override( + style: FlutterFlowTheme.of(context).displayLarge.override( fontFamily: 'Plus Jakarta Sans', color: FlutterFlowTheme.of(context).accent1, fontSize: 20.0, letterSpacing: 0.0, fontWeight: FontWeight.w700, - useGoogleFonts: GoogleFonts.asMap() - .containsKey('Plus Jakarta Sans'), + useGoogleFonts: GoogleFonts.asMap().containsKey('Plus Jakarta Sans'), ), ), ), - const AtomImageSvgTheme( - filename: 'reception', width: 180, height: 180), + const AtomImageSvgTheme(filename: 'reception', width: 180, height: 180), Padding( padding: const EdgeInsets.fromLTRB(70, 30, 70.0, 60), child: Text( - FFLocalizations.of(context).getVariableText( - ptText: - 'Envie seu identificador para seu condomínio para vincularem sua conta aos nossos sistemas.', - enText: - 'Send your identifier to your condominium to link your account to our systems.'), + FFLocalizations.of(context).getVariableText(ptText: 'Envie seu identificador para seu condomínio para vincularem sua conta aos nossos sistemas.', enText: 'Send your identifier to your condominium to link your account to our systems.'), textAlign: TextAlign.center, - style: FlutterFlowTheme.of(context) - .displaySmall - .override( + style: FlutterFlowTheme.of(context).displaySmall.override( fontFamily: 'Nunito Sans', color: FlutterFlowTheme.of(context).primaryText, fontSize: 14.0, letterSpacing: 0.0, fontWeight: FontWeight.w600, - useGoogleFonts: GoogleFonts.asMap() - .containsKey('Plus Jakarta Sans'), + useGoogleFonts: GoogleFonts.asMap().containsKey('Plus Jakarta Sans'), ), ), ), @@ -118,48 +106,31 @@ class _ReceptionPageWidgetState extends State with WidgetsB Padding( padding: const EdgeInsets.fromLTRB(60, 0, 60, 10), child: Tooltip( - message: FFLocalizations.of(context).getVariableText( - ptText: - 'Seu identificador é utilizado para efetuar\no vínculo do seu APP com o condominio.', - enText: 'My Identifier'), - textStyle: FlutterFlowTheme.of(context) - .labelSmall - .override( + message: FFLocalizations.of(context).getVariableText(ptText: 'Seu identificador é utilizado para efetuar\no vínculo do seu APP com o condominio.', enText: 'My Identifier'), + textStyle: FlutterFlowTheme.of(context).labelSmall.override( fontFamily: 'Nunito Sans', - color: FlutterFlowTheme.of(context) - .secondaryText, + color: FlutterFlowTheme.of(context).secondaryText, fontSize: 10.0, letterSpacing: 0.0, fontWeight: FontWeight.w500, - useGoogleFonts: GoogleFonts.asMap() - .containsKey('Plus Jakarta Sans'), + useGoogleFonts: GoogleFonts.asMap().containsKey('Plus Jakarta Sans'), ), child: FFButtonWidget( onPressed: () => model.getIdenfifier(context), - text: FFLocalizations.of(context) - .getVariableText( - ptText: 'Meu Identificador', - enText: 'My Identifier'), + text: FFLocalizations.of(context).getVariableText(ptText: 'Meu Identificador', enText: 'My Identifier'), options: FFButtonOptions( width: double.infinity, height: 44.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), + 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( + textStyle: FlutterFlowTheme.of(context).titleSmall.override( fontFamily: 'Nunito Sans', - color: - FlutterFlowTheme.of(context).info, + color: FlutterFlowTheme.of(context).info, fontSize: 14.0, letterSpacing: 0.0, fontWeight: FontWeight.w500, - useGoogleFonts: GoogleFonts.asMap() - .containsKey('Plus Jakarta Sans'), + useGoogleFonts: GoogleFonts.asMap().containsKey('Plus Jakarta Sans'), ), elevation: 3.0, borderSide: const BorderSide( @@ -177,44 +148,23 @@ class _ReceptionPageWidgetState extends State with WidgetsB child: FFButtonWidget( onPressed: () async { PhpGroup.unregisterDevice(); - - StorageUtil.purge(); + AuthenticationService.signOut(context); setState(() {}); - - context.go( - '/welcomePage', - extra: { - kTransitionInfoKey: const TransitionInfo( - hasTransition: true, - transitionType: PageTransitionType.scale, - alignment: Alignment.bottomCenter, - ), - }, - ); }, - text: FFLocalizations.of(context).getVariableText( - ptText: 'Sair da Conta', enText: 'Logout'), + text: FFLocalizations.of(context).getVariableText(ptText: 'Sair da Conta', enText: 'Logout'), options: FFButtonOptions( width: double.infinity, height: 44.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( + 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: 'Nunito Sans', - color: FlutterFlowTheme.of(context) - .primaryBackground, + color: FlutterFlowTheme.of(context).primaryBackground, fontSize: 14.0, letterSpacing: 0.0, fontWeight: FontWeight.w500, - useGoogleFonts: GoogleFonts.asMap() - .containsKey('Plus Jakarta Sans'), + useGoogleFonts: GoogleFonts.asMap().containsKey('Plus Jakarta Sans'), ), elevation: 3.0, borderSide: const BorderSide( diff --git a/lib/pages/vehicles_on_the_property/vehicle_model.dart b/lib/pages/vehicles_on_the_property/vehicle_model.dart new file mode 100644 index 00000000..47672d20 --- /dev/null +++ b/lib/pages/vehicles_on_the_property/vehicle_model.dart @@ -0,0 +1,53 @@ +import 'package:flutter/material.dart'; +import 'package:hub/backend/api_requests/api_manager.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/flutter_flow_theme.dart'; +import 'package:hub/flutter_flow/internationalization.dart'; +import 'package:hub/pages/vehicles_on_the_property/vehicles_on_the_property.dart'; +import 'package:hub/shared/utils/storage_util.dart'; + +class VehicleModel extends FlutterFlowModel { + static VehicleModel? _instance = VehicleModel._internal(); + VehicleModel._internal(); + factory VehicleModel() => _instance ?? VehicleModel._internal(); + static void resetInstance() => _instance = null; + + dynamic item; + + final GlobalKey registerFormKey = GlobalKey(); + final GlobalKey updateFormKey = GlobalKey(); + + @override + void initState(BuildContext context) { + resetInstance(); + + initAsync(); + } + + @override + void dispose() {} + + Future initAsync() async {} + + Widget buildVehicleDetails({ + required dynamic item, + required BuildContext context, + required VehicleModel model, + }) { + return DetailsComponentWidget( + buttons: [], + labelsHashMap: Map.from({ + 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['model'] != null && item['model'] != '') '${FFLocalizations.of(context).getVariableText(ptText: "Modelo", enText: "Model")}:': item['model'].toString().toUpperCase(), + if (item['tag'] != null && item['tag'] != '') '${FFLocalizations.of(context).getVariableText(ptText: "Tag", enText: "Tag")}:': item['tag'].toString().toUpperCase(), + if (item['personName'] != null && item['personName'] != '') '${FFLocalizations.of(context).getVariableText(ptText: "Proprietário", enText: "Owner")}:': item['personName'].toString().toUpperCase(), + }), + imagePath: 'https://freaccess.com.br/freaccess/Images/Clients/${StorageUtil().cliUUID}.png', + statusHashMap: [ + if (item['model'] != null) Map.from({item['model']: 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 new file mode 100644 index 00000000..3bfb5704 --- /dev/null +++ b/lib/pages/vehicles_on_the_property/vehicles_on_the_property.dart @@ -0,0 +1,245 @@ +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:hub/backend/api_requests/api_calls.dart'; +import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.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/pages/vehicles_on_the_property/vehicle_model.dart'; +import 'package:hub/shared/utils/dialog_util.dart'; +import 'package:hub/shared/utils/log_util.dart'; + +class VehicleOnTheProperty extends StatefulWidget { + const VehicleOnTheProperty({super.key}); + + @override + _VehicleOnThePropertyState createState() => _VehicleOnThePropertyState(); +} + +class _VehicleOnThePropertyState extends State with TickerProviderStateMixin { + late ScrollController _scrollController; + + int _pageNumber = 1; + bool _hasData = false; + bool _loading = false; + int count = 0; + late final VehicleModel model; + + late Future _petsFuture; + List _petsWrap = []; + + @override + void initState() { + super.initState(); + model = createModel(context, () => VehicleModel()); + _petsFuture = _fetchVisits(); + + _scrollController = ScrollController() + ..addListener(() { + if (_scrollController.position.atEdge && _scrollController.position.pixels != 0) { + _loadMore(); + } + }); + } + + @override + void dispose() { + _scrollController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) => 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")), + ) + ], + ), + ) + else if (_hasData == true || _pageNumber >= 1) + Expanded( + child: FutureBuilder( + future: _petsFuture, + builder: (context, snapshot) { + return ListView.builder( + shrinkWrap: true, + physics: const BouncingScrollPhysics(), + controller: _scrollController, + itemCount: _petsWrap.length + 1, + itemBuilder: (context, index) { + if (index == 0) { + // Add your item here + return Padding( + padding: const EdgeInsets.only(right: 30, top: 10), + child: Text( + // model.petAmountRegister == '0' ? FFLocalizations.of(context).getVariableText(ptText: "Ilimitado", enText: "Unlimited") : "${FFLocalizations.of(context).getVariableText(ptText: "Quantidade de Pets: ", enText: "Amount of Pets: ")}$count/${model.petAmountRegister}", + '', + textAlign: TextAlign.right, + ), + ); + } else { + final item = _petsWrap[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)), + ), + ); + + PreferredSizeWidget _appBar(BuildContext context) { + return AppBar( + backgroundColor: FlutterFlowTheme.of(context).primaryBackground, + automaticallyImplyLeading: false, + title: Text(FFLocalizations.of(context).getVariableText(enText: 'My Vehicles', ptText: 'Meus Veículos'), + style: FlutterFlowTheme.of(context).headlineMedium.override( + fontFamily: 'Nunito', + color: FlutterFlowTheme.of(context).primaryText, + fontSize: 15.0, + letterSpacing: 0.0, + fontWeight: FontWeight.bold, + useGoogleFonts: GoogleFonts.asMap().containsKey('Nunito'), + )), + leading: _backButton(context, FlutterFlowTheme.of(context)), + centerTitle: true, + elevation: 0.0, + actions: [], + ); + } + + Widget _backButton(BuildContext context, FlutterFlowTheme theme) { + return FlutterFlowIconButton( + 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(), + ); + } + + Future _fetchVisits() async { + try { + setState(() => _loading = true); + + var response = await PhpGroup.getVehiclesByProperty.call(_pageNumber.toString()); + + final List pets = response.jsonBody['vehicles'] ?? []; + safeSetState(() => count = response.jsonBody['total_rows'] ?? 0); + + if (pets.isNotEmpty) { + setState(() { + _petsWrap.addAll(pets); + _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 Pets", e, s); + setState(() { + _hasData = false; + _loading = false; + }); + } + return null; + } + + void _loadMore() { + if (_hasData == true) { + _pageNumber++; + + _petsFuture = _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.")), + duration: const Duration(seconds: 3), + backgroundColor: FlutterFlowTheme.of(context).primary, + ), + ); + } + + Widget _item(BuildContext context, dynamic uItem) { + return CardItemTemplateComponentWidget( + imagePath: '', + 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; + _petsWrap = []; + _petsFuture = _fetchVisits().then((value) => value!.jsonBody['pets'] ?? []); + }); + }).catchError((e, s) { + DialogUtil.errorDefault(context); + LogUtil.requestAPIFailed("proccessRequest.php", "", "Consulta de Pets", e, s); + safeSetState(() { + _hasData = false; + _loading = false; + }); + }); + }, + ); + } +} diff --git a/lib/pages/visits_on_the_property/visits_on_the_property_screen.dart b/lib/pages/visits_on_the_property/visits_on_the_property_screen.dart new file mode 100644 index 00000000..9c234488 --- /dev/null +++ b/lib/pages/visits_on_the_property/visits_on_the_property_screen.dart @@ -0,0 +1,248 @@ +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:hub/backend/api_requests/api_calls.dart'; +import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.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/pages/vehicles_on_the_property/vehicle_model.dart'; +import 'package:hub/shared/utils/dialog_util.dart'; +import 'package:hub/shared/utils/log_util.dart'; +import 'package:hub/shared/utils/storage_util.dart'; + +class VisitsOnTheProperty extends StatefulWidget { + const VisitsOnTheProperty({super.key}); + + @override + _VisitsOnThePropertyState createState() => _VisitsOnThePropertyState(); +} + +class _VisitsOnThePropertyState extends State with TickerProviderStateMixin { + late ScrollController _scrollController; + + int _pageNumber = 1; + bool _hasData = false; + bool _loading = false; + int count = 0; + late final VehicleModel model; + + late Future _visitsFuture; + List _visitsList = []; + + @override + void initState() { + super.initState(); + model = createModel(context, () => VehicleModel()); + _visitsFuture = _fetchVisits(); + + _scrollController = ScrollController() + ..addListener(() { + if (_scrollController.position.atEdge && _scrollController.position.pixels != 0) { + _loadMore(); + } + }); + } + + @override + void dispose() { + _scrollController.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) => Scaffold( + appBar: _appBar(context), + backgroundColor: FlutterFlowTheme.of(context).primaryBackground, + 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: "Nenhuma visita em aberto encontrada!", enText: "No opened visits found")), + ) + ], + ), + ) + else if (_hasData == true || _pageNumber >= 1) + Expanded( + child: FutureBuilder( + future: _visitsFuture, + builder: (context, snapshot) { + return ListView.builder( + shrinkWrap: true, + physics: const BouncingScrollPhysics(), + controller: _scrollController, + itemCount: _visitsList.length + 1, + itemBuilder: (context, index) { + if (index == 0) { + // Add your item here + return Padding( + padding: const EdgeInsets.only(right: 30, top: 10), + child: Text( + // model.petAmountRegister == '0' ? FFLocalizations.of(context).getVariableText(ptText: "Ilimitado", enText: "Unlimited") : "${FFLocalizations.of(context).getVariableText(ptText: "Quantidade de Pets: ", enText: "Amount of Pets: ")}$count/${model.petAmountRegister}", + '', + textAlign: TextAlign.right, + ), + ); + } else { + final item = _visitsList[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)), + ), + ); + + PreferredSizeWidget _appBar(BuildContext context) { + return AppBar( + backgroundColor: FlutterFlowTheme.of(context).primaryBackground, + automaticallyImplyLeading: false, + title: Text(FFLocalizations.of(context).getVariableText(enText: 'Visitas em aberto', ptText: 'Opened visits'), + style: FlutterFlowTheme.of(context).headlineMedium.override( + fontFamily: 'Nunito', + color: FlutterFlowTheme.of(context).primaryText, + fontSize: 15.0, + letterSpacing: 0.0, + fontWeight: FontWeight.bold, + useGoogleFonts: GoogleFonts.asMap().containsKey('Nunito'), + )), + leading: _backButton(context, FlutterFlowTheme.of(context)), + centerTitle: true, + elevation: 0.0, + actions: [], + ); + } + + Widget _backButton(BuildContext context, FlutterFlowTheme theme) { + return FlutterFlowIconButton( + 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(), + ); + } + + Future _fetchVisits() async { + try { + setState(() => _loading = true); + + var response = await PhpGroup.getOpenedVisits.call(_pageNumber.toString()); + + final List pets = response.jsonBody['visitas'] ?? []; + safeSetState(() => count = response.jsonBody['total_rows'] ?? 0); + + if (pets.isNotEmpty) { + setState(() { + _visitsList.addAll(pets); + _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 Pets", e, s); + setState(() { + _hasData = false; + _loading = false; + }); + } + return null; + } + + void _loadMore() { + if (_hasData == true) { + _pageNumber++; + + _visitsFuture = _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.")), + duration: const Duration(seconds: 3), + backgroundColor: FlutterFlowTheme.of(context).primary, + ), + ); + } + + Widget _item(BuildContext context, dynamic uItem) { + return CardItemTemplateComponentWidget( + imagePath: 'https://freaccess.com.br/freaccess/getImage.php?devUUID=${StorageUtil().devUUID}&cliID=${StorageUtil().cliUUID}&atividade=getFoto&Documento=${uItem['VDO_DOCUMENTO']}&tipo=E', + labelsHashMap: { + '${FFLocalizations.of(context).getVariableText(ptText: "Nome", enText: "Name")}:': uItem['VTA_NOME'] ?? '', + '${FFLocalizations.of(context).getVariableText(ptText: "Validade", enText: "Valids")}:': uItem['VTA_VALIDADE'] ?? '', + '${FFLocalizations.of(context).getVariableText(ptText: "Entrada", enText: "Entrada")}:': uItem['VTA_DTINICIO'] ?? '', + if (uItem['VTA_DTFIM'] != '') '${FFLocalizations.of(context).getVariableText(ptText: "Saída", enText: "Exit")}:': uItem['VTA_DTFIM'] ?? '', + }, + statusHashMap: [ + if (uItem['VTA_UNICA'] == "N") + { + FFLocalizations.of(context).getVariableText( + ptText: 'Recorrente', + enText: 'Recurrent', + ): FlutterFlowTheme.of(context).warning, + }, + if (uItem['VTA_UNICA'] == "S") + { + FFLocalizations.of(context).getVariableText( + ptText: 'Única', + enText: 'Unique', + ): FlutterFlowTheme.of(context).success, + }, + if (uItem['VTA_DTFIM'] != '') + { + FFLocalizations.of(context).getVariableText( + ptText: 'Finalizada', + enText: 'Finished', + ): FlutterFlowTheme.of(context).success, + }, + if (uItem['VTA_DTFIM'] == '') + { + FFLocalizations.of(context).getVariableText( + ptText: 'Em aberto', + enText: 'Opened', + ): FlutterFlowTheme.of(context).warning, + }, + ], + onTapCardItemAction: () async {}, + ); + } +} diff --git a/lib/shared/helpers/sqlite_storage_helper.dart b/lib/shared/helpers/sqlite_storage_helper.dart index 402413ba..3deda5a5 100644 --- a/lib/shared/helpers/sqlite_storage_helper.dart +++ b/lib/shared/helpers/sqlite_storage_helper.dart @@ -143,27 +143,7 @@ class SQLiteStorageHelper implements Storage { log('Setting up local variables'); try { await _database?.transaction((txn) async { - final keys = [ - 'devUUID', - 'userUUID', - 'userDevUUID', - 'status', - 'userName', - 'cliUUID', - 'ownerUUID', - 'cliName', - 'petAmountRegister', - 'whatsapp', - 'provisional', - 'pets', - 'local', - 'notify', - 'fingerprint', - 'access', - 'panic', - 'person', - 'requestOSnotification' - ]; + final keys = ['devUUID', 'userUUID', 'userDevUUID', 'status', 'userName', 'cliUUID', 'ownerUUID', 'cliName', 'petAmountRegister', 'whatsapp', 'provisional', 'pets', 'local', 'notify', 'fingerprint', 'access', 'panic', 'person', 'requestOSnotification']; for (var key in keys) { log('Fetching value for key: $key'); @@ -220,8 +200,7 @@ class SQLiteStorageHelper implements Storage { } @override - Future set( - String key, dynamic value, Function(dynamic) cacheSetter) async { + Future set(String key, dynamic value, Function(dynamic) cacheSetter) async { log('Setting value for key: $key to $value'); CacheUtil().set(key, value); final db = await database; @@ -260,7 +239,6 @@ class SQLiteStorageHelper implements Storage { Future purge() async { log('Purging SQLite storage'); await deleteDatabaseDB(); - await database; log('Database purged'); } diff --git a/lib/shared/services/authentication/authentication_service.dart b/lib/shared/services/authentication/authentication_service.dart index 11821a73..07545d83 100644 --- a/lib/shared/services/authentication/authentication_service.dart +++ b/lib/shared/services/authentication/authentication_service.dart @@ -1,5 +1,3 @@ - - import 'package:flutter/material.dart'; import 'package:hub/flutter_flow/nav/nav.dart'; import 'package:hub/shared/utils/snackbar_util.dart'; @@ -13,9 +11,6 @@ import '../../utils/log_util.dart'; import '../../utils/storage_util.dart'; class AuthenticationService { - - - static Future login(BuildContext context) async { final GetLocalsCall callback = PhpGroup.getLocalsCall; @@ -35,10 +30,14 @@ class AuthenticationService { context.go('/homePage'); } StorageUtil().isLogged = true; - } - static Future signIn(BuildContext context, FlutterFlowModel model, {String? emailAdress, String? password,}) async { + static Future signIn( + BuildContext context, + FlutterFlowModel model, { + String? emailAdress, + String? password, + }) async { try { final ApiCallResponse? response; final LoginCall callback = PhpGroup.loginCall; @@ -84,8 +83,7 @@ class AuthenticationService { if (response.jsonBody['error'] == null) { DialogUtil.errorDefault(context); } else { - DialogUtil.error( - context, response.jsonBody['error_msg'].toString()); + DialogUtil.error(context, response.jsonBody['error_msg'].toString()); } } } @@ -93,12 +91,17 @@ class AuthenticationService { return; } catch (e, s) { DialogUtil.errorDefault(context); - LogUtil.requestAPIFailed( - 'login.php', emailAdress.toString(), "Login", e, s); + LogUtil.requestAPIFailed('login.php', emailAdress.toString(), "Login", e, s); } } - static Future signUp(BuildContext context, {required String? name, String? passwd, required String? email, String? device,}) async { + static Future signUp( + BuildContext context, { + required String? name, + String? passwd, + required String? email, + String? device, + }) async { try { ApiCallResponse? response; if ((email != null && email != '') && (passwd != null && passwd != '' && passwd.length > 7) && (name != null && name != '')) { @@ -127,25 +130,24 @@ class AuthenticationService { } static Future signOut(BuildContext context) async { - await PhpGroup.unregisterDevice.call(); - final Map extra = { - kTransitionInfoKey: const TransitionInfo( - hasTransition: true, - transitionType: PageTransitionType.scale, - alignment: Alignment.bottomCenter, - ), - }; - await StorageUtil.purge(); - context.go( '/welcomePage', extra: extra); - } + await PhpGroup.unregisterDevice.call(); + await StorageUtil().purge(); + await StorageUtil().ensureInitialization(); + final Map extra = { + kTransitionInfoKey: const TransitionInfo( + hasTransition: true, + transitionType: PageTransitionType.scale, + alignment: Alignment.bottomCenter, + ), + }; + context.go('/welcomePage', extra: extra); + } static Future forgotPassword(BuildContext context, String email) async { try { final ApiCallResponse? response; final ForgotPasswordCall callback = PhpGroup.forgotPasswordCall; - final String message = FFLocalizations.of(context).getVariableText( - enText: "Send E-mail Successful!", - ptText: "E-mail Enviado com Sucesso!"); + final String message = FFLocalizations.of(context).getVariableText(enText: "Send E-mail Successful!", ptText: "E-mail Enviado com Sucesso!"); response = await callback.call(email: email); @@ -156,31 +158,28 @@ class AuthenticationService { } } catch (e, s) { DialogUtil.errorDefault(context); - LogUtil.requestAPIFailed( - 'forgotPassword.php', email, "Forgot Password", e, s); + LogUtil.requestAPIFailed('forgotPassword.php', email, "Forgot Password", e, s); } } static Future changePassword(BuildContext context, String email, String password, String token) async { try { - final ApiCallResponse response = await PhpGroup.changePasswordCall.call(email: email, psswd: password, token: token); + final ApiCallResponse response = await PhpGroup.changePasswordCall.call(email: email, psswd: password, token: token); - if (response.jsonBody['error'] == false) { - final String message = FFLocalizations.of(context).getVariableText( - enText: "Password changed successfully!", - ptText: "Senha alterada com sucesso!", - ); - DialogUtil.success(context, message).then((_) => context.pop); - } else { - final String message = response.jsonBody['error_msg']; - DialogUtil.error(context, message); - } } catch (e, s) { + if (response.jsonBody['error'] == false) { + final String message = FFLocalizations.of(context).getVariableText( + enText: "Password changed successfully!", + ptText: "Senha alterada com sucesso!", + ); + DialogUtil.success(context, message).then((_) => context.pop); + } else { + final String message = response.jsonBody['error_msg']; + DialogUtil.error(context, message); + } + } catch (e, s) { DialogUtil.errorDefault(context); - LogUtil.requestAPIFailed( - 'changePassword.php', email, "Change Password", e, s); + LogUtil.requestAPIFailed('changePassword.php', email, "Change Password", e, s); } - - } static Future deleteAccount(BuildContext context) async { @@ -199,7 +198,7 @@ class AuthenticationService { enText: 'Account deleted successfully', ptText: 'Conta deletada com sucesso', ); - StorageUtil.purge(); + StorageUtil().purge(); context.pop(); context.go('/welcomePage', extra: extra); } @@ -220,5 +219,4 @@ class AuthenticationService { SnackBarUtil.showSnackBar(context, content, isError: true); } } - -} \ No newline at end of file +} diff --git a/lib/shared/services/localization/localization_service.dart b/lib/shared/services/localization/localization_service.dart index 089e005b..aede3570 100644 --- a/lib/shared/services/localization/localization_service.dart +++ b/lib/shared/services/localization/localization_service.dart @@ -13,8 +13,6 @@ import '../../utils/snackbar_util.dart'; import '../authentication/authentication_service.dart'; class LocalizationService { - - static Future checkLocals(BuildContext context) async { try { final GetLocalsCall callback = PhpGroup.getLocalsCall; @@ -43,6 +41,7 @@ class LocalizationService { log(e.toString(), stackTrace: s); } } + static Future processLocals(BuildContext context) async { try { await StorageUtil().ensureInitialization(); @@ -87,12 +86,12 @@ class LocalizationService { } else if (isAvailable) { log('() => isAvailable'); return await processData(context); - } else { - if (!isUnique && !isActive) log('() => not unique and not active'); - if (!isUnique && isInactived) log('() => not unique and inactived'); - if (!isUnique && isPending) log('() => not unique and pending'); - if (!isUnique && isBlocked) log('() => not unique and blocked'); - log('() => else'); + } else { + if (!isUnique && !isActive) log('() => not unique and not active'); + if (!isUnique && isInactived) log('() => not unique and inactived'); + if (!isUnique && isPending) log('() => not unique and pending'); + if (!isUnique && isBlocked) log('() => not unique and blocked'); + log('() => else'); return await selectLocal(context); } } catch (e, s) { @@ -107,6 +106,7 @@ class LocalizationService { return false; } } + static Future processData(BuildContext context) async { try { await StorageUtil().ensureInitialization(); @@ -118,8 +118,7 @@ class LocalizationService { final String errorMsg = response.jsonBody['error_msg']; DialogUtil.error(context, errorMsg).whenComplete(() => selectLocal(context)); return false; - } - else { + } else { _updateStorageUtil(response.jsonBody); return true; } @@ -134,6 +133,7 @@ class LocalizationService { return false; } } + static Future selectLocal(BuildContext context) async { return await showModalBottomSheet( isScrollControlled: true, @@ -152,6 +152,7 @@ class LocalizationService { ), ).then((_) async => await processData(context)); } + static Future unlinkLocal(BuildContext context) async { String content; try { @@ -196,11 +197,16 @@ class LocalizationService { } } - static void _handleError(BuildContext context, String errorMsg) { - AuthenticationService.signOut(context); + static void _handleError(BuildContext context, String errorMsg) async { + await StorageUtil().ensureInitialization(); + final bool isNotAuthenticated = StorageUtil().userUUID.isEmpty && StorageUtil().devUUID.isEmpty; + final bool isLinked = errorMsg.contains('Esse dispositivo nao pertence a esse usuario'); + log('() => isLinked: $errorMsg'); + if (isNotAuthenticated || isLinked) AuthenticationService.signOut(context); DialogUtil.error(context, errorMsg); LogUtil.requestAPIFailed('getLocals.php', '{devUUID: ${StorageUtil().devUUID}, cliUUID: ${StorageUtil().userUUID}}', 'Get Locals', errorMsg, StackTrace.current); } + static Future _handleUnavailable(BuildContext context, List locals) async { log('() => isUnavailable'); try { @@ -222,6 +228,7 @@ class LocalizationService { } return false; } + static Future _handleEnabled(BuildContext context, dynamic local) async { log('() => isEnabled'); StorageUtil().cliName = local['CLI_NOME']; @@ -237,24 +244,31 @@ class LocalizationService { log('() => CLU_STATUS: $status'); } } + static bool _isActive(List locals) { return locals.where((local) => local['CLU_STATUS'] == 'A').isNotEmpty; } + static bool _isInactived(List locals) { return locals.where((local) => local['CLI_ID'] != StorageUtil().cliUUID && local['CLU_STATUS'] == 'A').isNotEmpty; } + static bool _isPending(List locals) { return locals.where((local) => local['CLU_STATUS'] != 'B' && local['CLU_STATUS'] != 'A').isNotEmpty; } + static bool _isUnselected() { return StorageUtil().cliUUID.isEmpty && StorageUtil().cliName.isEmpty && StorageUtil().ownerUUID.isEmpty; } + static bool _isSelected(bool isInactived) { return StorageUtil().cliUUID.isNotEmpty && StorageUtil().cliName.isNotEmpty && isInactived; } + static bool _isAvailable() { return StorageUtil().cliUUID.isNotEmpty && StorageUtil().cliName.isNotEmpty; } + static void _updateStorageUtil(Map jsonBody) { StorageUtil().whatsapp = jsonBody['whatsapp'] ?? false; StorageUtil().provisional = jsonBody['provisional'] ?? false; @@ -262,6 +276,4 @@ class LocalizationService { StorageUtil().petAmountRegister = jsonBody['petAmountRegister'].toString().isEmpty ? '0' : jsonBody['petAmountRegister'].toString(); StorageUtil().userName = jsonBody['visitado']['VDO_NOME']; } - - -} \ No newline at end of file +} diff --git a/lib/shared/utils/storage_util.dart b/lib/shared/utils/storage_util.dart index 43839dfe..f59af57e 100644 --- a/lib/shared/utils/storage_util.dart +++ b/lib/shared/utils/storage_util.dart @@ -1,12 +1,10 @@ import 'dart:developer'; -import 'dart:ffi'; import 'package:flutter/material.dart'; import 'package:hub/shared/helpers/secure_storage_helper.dart'; import 'package:hub/shared/helpers/shared_preferences_storage_helper.dart'; import 'package:hub/shared/helpers/sqlite_storage_helper.dart'; import 'package:hub/shared/utils/cache_util.dart'; -import 'package:hub/shared/utils/dialog_util.dart'; import 'package:hub/shared/utils/log_util.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -53,8 +51,7 @@ class StorageUtil { await SecureStorageHelper().set(data.key, data.value, (v) {}); break; case StorageType.sharedPreferences: - await SharedPreferencesStorageHelper() - .set(data.key, data.value, (v) {}); + await SharedPreferencesStorageHelper().set(data.key, data.value, (v) {}); break; case StorageType.dbSQLite3: await SQLiteStorageHelper().set(data.key, data.value, (v) {}); @@ -109,10 +106,11 @@ class StorageUtil { } } - static Future purge() async { + Future purge() async { try { await SecureStorageHelper().purge(); await SQLiteStorageHelper().purge(); + _initialized = true; // await SharedPreferencesStorageHelper().purge(); } catch (e) { log('Error purging data: $e'); @@ -122,12 +120,13 @@ class StorageUtil { Future ensureInitialization() async { try { log('StorageUtil: Starting initialization'); - if(!_initialized) return true; - await initSharedPreferences(); + if (!_initialized) return true; + if (_initialized) await SharedPreferencesStorageHelper().initialize(); await initSecureStorage(); + await initSharedPreferences(); await initSQLiteStorage(); - if(_initialized) _initialized = false; - if(_initialized) return true; + if (_initialized) _initialized = false; + if (_initialized) return true; return false; } catch (e, s) { log('Error initializing storage: $e'); @@ -138,10 +137,9 @@ class StorageUtil { Future initSharedPreferences() async { try { - if(_initialized) _sharedPreferences = SharedPreferencesStorageHelper(); + if (_initialized) _sharedPreferences = SharedPreferencesStorageHelper(); _sharedPreferences.prefs ??= await SharedPreferences.getInstance(); - final bool milestone = - _sharedPreferences.prefs?.getBool('fre_isFirstRun') ?? true; + final bool milestone = _sharedPreferences.prefs?.getBool('fre_isFirstRun') ?? true; if (milestone) { isFirstRun = false; await _sharedPreferences.prefs?.setBool('fre_isFirstRun', false); @@ -153,15 +151,14 @@ class StorageUtil { } } catch (e, s) { log('SharedPreferencesStorageHelper: Error during initialization'); - LogUtil.requestAPIFailed( - '$UniqueKey', '$UniqueKey', 'SharedPreferencesStorageHelper', e, s); + LogUtil.requestAPIFailed('$UniqueKey', '$UniqueKey', 'SharedPreferencesStorageHelper', e, s); } } Future initSecureStorage() async { log('SecureStorageHelper: Starting initialization'); try { - if(_initialized) _secureStorage = SecureStorageHelper(); + if (_initialized) _secureStorage = SecureStorageHelper(); _email = await _secureStorage.getString('fre_email'); _passwd = await _secureStorage.getString('fre_passwd'); _deviceType = await _secureStorage.getString('fre_deviceType'); @@ -171,12 +168,10 @@ class StorageUtil { _panicPass = await _secureStorage.getString('fre_panicPass'); _fingerprintPass = await _secureStorage.getString('fre_fingerprintPass'); _haveLocal = await _secureStorage.getBool('fre_have_local') ?? false; - _deviceDescription = - await _secureStorage.getString('fre_deviceDescription'); + _deviceDescription = await _secureStorage.getString('fre_deviceDescription'); } catch (e, s) { log('SecureStorageHelper: Error during initialization: $e'); - LogUtil.requestAPIFailed( - '$UniqueKey', '$UniqueKey', 'SecureStorageHelper', e, s); + LogUtil.requestAPIFailed('$UniqueKey', '$UniqueKey', 'SecureStorageHelper', e, s); } log('SecureStorageHelper: Initialization complete'); } @@ -184,7 +179,7 @@ class StorageUtil { Future initSQLiteStorage() async { log('SQLiteStorageHelper: Starting initialization'); try { - if(_initialized) _sqliteStorage = SQLiteStorageHelper(); + if (_initialized) _sqliteStorage = SQLiteStorageHelper(); await _sqliteStorage.database; _devUUID = await _sqliteStorage.get('fre_devUUID') ?? ''; _userUUID = await _sqliteStorage.get('fre_userUUID') ?? ''; @@ -204,12 +199,10 @@ class StorageUtil { _access = await _sqliteStorage.getBoolean('fre_access'); _panic = await _sqliteStorage.getBoolean('fre_panic'); _person = await _sqliteStorage.getBoolean('fre_person'); - _requestOSnotification = - await _sqliteStorage.getBoolean('fre_requestOSnotification'); + _requestOSnotification = await _sqliteStorage.getBoolean('fre_requestOSnotification'); } catch (e, s) { log('SQLiteStorageHelper: Error during initialization: $e'); - LogUtil.requestAPIFailed( - '$UniqueKey', '$UniqueKey', 'SQLiteStorageHelper', e, s); + LogUtil.requestAPIFailed('$UniqueKey', '$UniqueKey', 'SQLiteStorageHelper', e, s); } log('SQLiteStorageHelper: Initialization complete'); } diff --git a/lib/shared/widgets/drawer_widget/drawer_widget.dart b/lib/shared/widgets/drawer_widget/drawer_widget.dart index 5636717f..0e43594b 100644 --- a/lib/shared/widgets/drawer_widget/drawer_widget.dart +++ b/lib/shared/widgets/drawer_widget/drawer_widget.dart @@ -1,12 +1,10 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; -import 'package:hub/backend/schema/enums/enums.dart'; +import 'package:hub/components/organism_components/menu_component/menu_component_widget.dart'; +import 'package:hub/flutter_flow/flutter_flow_theme.dart'; import 'package:hub/flutter_flow/flutter_flow_util.dart'; import 'package:hub/pages/home_page/home_page_model.dart'; -import '../../../components/organism_components/menu_component/menu_component_widget.dart'; -import '../../../flutter_flow/flutter_flow_theme.dart'; - class CustomDrawer extends StatelessWidget { const CustomDrawer({super.key, required this.model}); final HomePageModel model; @@ -64,11 +62,9 @@ class CustomDrawer extends StatelessWidget { height: 80.0, fit: BoxFit.cover, alignment: Alignment.center, - placeholder: (context, url) => - Image.asset('assets/images/person.jpg'), + placeholder: (context, url) => Image.asset('assets/images/person.jpg'), errorListener: (_) => Image.asset('assets/images/person.jpg'), - errorWidget: (_, __, ___) => - Image.asset('assets/images/person.jpg'), + errorWidget: (_, __, ___) => Image.asset('assets/images/person.jpg'), ), ), ), @@ -164,13 +160,9 @@ class CustomDrawer extends StatelessWidget { Widget _buildDrawerBody() { return wrapWithModel( - model: model.menuComponentModel, + model: model.drawerMenuComponentModel, updateCallback: () {}, - child: const MenuComponentWidget( - expandable: false, - style: MenuView.list, - item: MenuItem.tile, - ), + child: MenuComponentWidget(model: model.drawerMenuComponentModel), ); } }