From f883326f797bc81f7f12bf52a6d18b021480daad Mon Sep 17 00:00:00 2001 From: Ivan Antunes Date: Fri, 23 Aug 2024 17:01:23 -0300 Subject: [PATCH 1/4] fet: Adicionado Encomendas --- lib/backend/api_requests/api_calls.dart | 51 ++- .../message_opt_modal/opt_modal_widget.dart | 10 +- .../order_filter_modal_model.dart | 32 ++ .../order_filter_modal_widget.dart | 223 ++++++++++ .../menu_component/menu_component_model.dart | 13 + .../menu_component/menu_component_widget.dart | 34 ++ .../card_item_template_component_widget.dart | 325 +++++++------- lib/flutter_flow/nav/nav.dart | 6 + .../acess_history_page_widget.dart | 21 +- .../package_order_page.dart | 410 ++++++++++++++++++ pubspec.lock | 2 +- 11 files changed, 925 insertions(+), 202 deletions(-) create mode 100644 lib/components/molecular_components/order_filter_modal/order_filter_modal_model.dart create mode 100644 lib/components/molecular_components/order_filter_modal/order_filter_modal_widget.dart create mode 100644 lib/pages/package_order_page/package_order_page.dart diff --git a/lib/backend/api_requests/api_calls.dart b/lib/backend/api_requests/api_calls.dart index 2ffe5045..898ce7c5 100644 --- a/lib/backend/api_requests/api_calls.dart +++ b/lib/backend/api_requests/api_calls.dart @@ -16,7 +16,7 @@ const _kPrivateApiFunctionName = 'ffPrivateApiCall'; class PhpGroup { static String getBaseUrl() => 'https://freaccess.com.br/freaccess'; - // static String getBaseUrl() => 'http://192.168.2.250:8080'; + // static String getBaseUrl() => 'http://192.168.2.204:8080'; static Map headers = {}; static LoginCall loginCall = LoginCall(); static UpdToken updToken = UpdToken(); @@ -49,6 +49,55 @@ class PhpGroup { static ChangePanic changePanic = ChangePanic(); static DeleteAccount deleteAccount = DeleteAccount(); static CancelaVisita cancelaVisita = CancelaVisita(); + static BuscaEnconcomendas buscaEnconcomendas = BuscaEnconcomendas(); +} + + +class BuscaEnconcomendas { + Future call({ + String? devUUID = '', + String? userUUID = '', + String? cliID = '', + String? atividade = '', + + String? page = '', + String? pageSize = '', + String? adresseeType = '', + String? status = '', + }) async { + final baseUrl = PhpGroup.getBaseUrl(); + + return ApiManager.instance.makeApiCall( + callName: 'getEncomendas', + apiUrl: '$baseUrl/processRequest.php', + callType: ApiCallType.POST, + headers: { + 'Content-Type': 'application/x-www-form-urlencoded', + }, + params: { + 'devUUID': devUUID, + 'userUUID': userUUID, + 'atividade': atividade, + 'cliID': cliID, + + 'page': page, + 'pageSize': pageSize, + 'adresseeType': adresseeType, + 'status': status, + }, + bodyType: BodyType.X_WWW_FORM_URL_ENCODED, + returnBody: true, + encodeBodyUtf8: false, + decodeUtf8: false, + cache: false, + alwaysAllowBody: false, + ); + } + + bool? error(dynamic response) => castToType(getJsonField( + response, + r'''$.error''', + )); } class CancelaVisita { diff --git a/lib/components/molecular_components/message_opt_modal/opt_modal_widget.dart b/lib/components/molecular_components/message_opt_modal/opt_modal_widget.dart index bd40eb5a..6bf0fd72 100644 --- a/lib/components/molecular_components/message_opt_modal/opt_modal_widget.dart +++ b/lib/components/molecular_components/message_opt_modal/opt_modal_widget.dart @@ -85,8 +85,7 @@ class _OptModalWidgetState extends State { Navigator.pop(context, filterResult); } - Widget _buildCheckboxListTile( - String key, List> options, double fontsize) { + Widget _buildCheckboxListTile(String key, List> options, double fontsize) { return Column( children: [ Row( @@ -152,8 +151,7 @@ class _OptModalWidgetState extends State { width: 5, color: FlutterFlowTheme.of(context).secondaryText, ), - controlAffinity: - ListTileControlAffinity.leading, // Adiciona esta linha + controlAffinity: ListTileControlAffinity.leading, // Adiciona esta linha ); }, ), @@ -182,8 +180,8 @@ class _OptModalWidgetState extends State { return Center( child: Container( - width: screenWidth * 0.75, - height: screenHeight * 0.35, + width: screenWidth - (screenWidth * 0.35), + height: 250, decoration: BoxDecoration( color: FlutterFlowTheme.of(context).primaryBackground, borderRadius: BorderRadius.circular(24.0), diff --git a/lib/components/molecular_components/order_filter_modal/order_filter_modal_model.dart b/lib/components/molecular_components/order_filter_modal/order_filter_modal_model.dart new file mode 100644 index 00000000..e1f99286 --- /dev/null +++ b/lib/components/molecular_components/order_filter_modal/order_filter_modal_model.dart @@ -0,0 +1,32 @@ +import '/flutter_flow/flutter_flow_util.dart'; +import '/flutter_flow/form_field_controller.dart'; +import 'order_filter_modal_widget.dart' show OrderFilterModalWidget; +import 'package:flutter/material.dart'; + + + +class OrderFilterModalModel extends FlutterFlowModel { + + // State field(s) for TextField widget. + FocusNode? textFieldFocusNode; + TextEditingController? textController; + String? Function(BuildContext, String?)? textControllerValidator; + // State field(s) for Checkbox widget. + bool? checkboxValue1; + // State field(s) for Checkbox widget. + bool? checkboxValue2; + // State field(s) for CheckboxGroup widget. + FormFieldController>? checkboxGroupValueController; + List? get checkboxGroupValues => checkboxGroupValueController?.value; + set checkboxGroupValues(List? v) => + checkboxGroupValueController?.value = v; + + @override + void initState(BuildContext context) {} + + @override + void dispose() { + textFieldFocusNode?.dispose(); + textController?.dispose(); + } +} \ No newline at end of file diff --git a/lib/components/molecular_components/order_filter_modal/order_filter_modal_widget.dart b/lib/components/molecular_components/order_filter_modal/order_filter_modal_widget.dart new file mode 100644 index 00000000..5951ef8a --- /dev/null +++ b/lib/components/molecular_components/order_filter_modal/order_filter_modal_widget.dart @@ -0,0 +1,223 @@ + +import 'package:flutter/material.dart'; +import 'package:google_fonts/google_fonts.dart'; +import 'package:hub/components/molecular_components/order_filter_modal/order_filter_modal_model.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'; + +class OrderFilterModalWidget extends StatefulWidget { + final String defaultAdresseeType; + final String defaultStatus; + + const OrderFilterModalWidget({ + Key? key, + this.defaultAdresseeType = '.*', + this.defaultStatus = '.*', + }) : super(key: key); + + @override + _OrderFilterModalWidgetState createState() => _OrderFilterModalWidgetState(); +} + +class _OrderFilterModalWidgetState extends State { + late OrderFilterModalModel _model; + + late Map selected; + final List> adresseeTypeOptions = [ + {'title': 'Morador', 'value': 'MOR'}, + {'title': 'Propriedade', 'value': 'PRO'}, + ]; + final List> statusOptions = [ + {'title': 'Aguardando Retirada', 'value': 'notPickedUp'}, + {'title': 'Retirado', 'value': 'pickedUp'}, + ]; + + @override + void setState(VoidCallback callback) { + super.setState(callback); + _model.onUpdate(); + } + + @override + void initState() { + super.initState(); + + _model = createModel(context, () => OrderFilterModalModel()); + + selected = { + 'adresseeType': widget.defaultAdresseeType == '.*' ? ['MOR', 'PRO'] : [widget.defaultAdresseeType], + 'status': widget.defaultStatus == '.*' ? ['notPickedUp', 'pickedUp'] : [widget.defaultStatus], + }; + } + + void _applyFilter() { + Map filterResult = { + 'adresseeType': '', + 'status': '', + }; + + if (selected['adresseeType']!.isEmpty) { + filterResult['adresseeType'] = '.*'; + } else if (selected['adresseeType']!.length > 1) { + filterResult['adresseeType'] = '.*'; + } else { + filterResult['adresseeType'] = selected['adresseeType']!.first; + } + + if (selected['status']!.isEmpty) { + filterResult['status'] = '.*'; + } else if (selected['status']!.length > 1) { + filterResult['status'] = '.*'; + } else { + filterResult['status'] = selected['status']!.first; + } + + Navigator.pop(context, filterResult); + } + + Widget _buildCheckboxListTile(String key, List> options, double fontsize) { + return Column( + children: [ + Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsetsDirectional.fromSTEB(0.0, 3.0, 0.0, 0.0), + child: Text( + key == 'status' ? 'Status' : 'Destinátario', + textAlign: TextAlign.left, + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily, + fontSize: fontsize, + letterSpacing: 0.0, + useGoogleFonts: GoogleFonts.asMap().containsKey( + FlutterFlowTheme.of(context).bodyMediumFamily), + color: FlutterFlowTheme.of(context).primaryText, + ), + ), + ), + ], + ), + ListView.builder( + physics: const NeverScrollableScrollPhysics(), + shrinkWrap: true, + itemCount: options.length, + itemBuilder: (context, index) { + final option = options[index]; + return CheckboxListTile( + title: Text( + option['title']!, + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily, + letterSpacing: 0.0, + fontSize: fontsize, + useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).bodyMediumFamily), + color: FlutterFlowTheme.of(context).primaryText, + ), + ), + dense: true, + value: selected[key]!.contains(option['value']), + onChanged: (bool? value) { + setState(() { + if (value == true) { + if (!selected[key]!.contains(option['value'])) { + selected[key]!.add(option['value']); + } + } else { + selected[key]!.remove(option['value']); + } + }); + }, + activeColor: FlutterFlowTheme.of(context).primary, + checkColor: FlutterFlowTheme.of(context).info, + checkboxShape: RoundedRectangleBorder( + borderRadius: BorderRadius.circular(100), + ), + + enableFeedback: true, + side: BorderSide( + width: 5, + color: FlutterFlowTheme.of(context).secondaryText, + ), + controlAffinity: ListTileControlAffinity.leading, // Adiciona esta linha + ); + }, + ), + ], + ); + } + + @override + Widget build(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; + double screenHeight = MediaQuery.of(context).size.height; + + return Center( + child: Container( + width: screenWidth - (screenWidth * 0.35), + height: 420, + decoration: BoxDecoration( + color: FlutterFlowTheme.of(context).primaryBackground, + borderRadius: BorderRadius.circular(24.0), + ), + child: Padding( + padding: const EdgeInsets.all(4.0), + child: Column( + children: [ + Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.start, + children: [ + Padding( + padding: const EdgeInsetsDirectional.fromSTEB( + 10.0, 10.0, 0.0, 10.0), + child: Text( + FFLocalizations.of(context) + .getText('yfj9pd6k'), // Filtros + style: + FlutterFlowTheme.of(context).headlineMedium.override( + fontFamily: FlutterFlowTheme.of(context) + .headlineMediumFamily, + color: FlutterFlowTheme.of(context).primaryText, + fontSize: 18.0, + letterSpacing: 0.0, + fontWeight: FontWeight.bold, + useGoogleFonts: GoogleFonts.asMap().containsKey( + FlutterFlowTheme.of(context) + .headlineMediumFamily), + ), + ), + ), + ], + ), + Expanded( + child: SingleChildScrollView( + child: Container( + padding: const EdgeInsets.all(10), + child: Column( + mainAxisSize: MainAxisSize.min, + children: [ + _buildCheckboxListTile('adresseeType', adresseeTypeOptions, 14), + _buildCheckboxListTile('status', statusOptions, 14), + ], + ), + ), + ), + ), + ElevatedButton( + onPressed: _applyFilter, + style: ElevatedButton.styleFrom( + foregroundColor: FlutterFlowTheme.of(context).info, + backgroundColor: FlutterFlowTheme.of(context).primary, + ), + child: Text(FFLocalizations.of(context).getText('88kshkph')), + ), + ], + ), + ), + ), + ); + } +} \ No newline at end of file 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 1dd63013..96c92010 100644 --- a/lib/components/organism_components/menu_component/menu_component_model.dart +++ b/lib/components/organism_components/menu_component/menu_component_model.dart @@ -150,6 +150,19 @@ class MenuComponentModel extends FlutterFlowModel { ).then((value) => true); } + Future packageOrder(BuildContext context) async { + context.pushNamed( + 'packageOrder', + extra: { + kTransitionInfoKey: const TransitionInfo( + hasTransition: true, + transitionType: PageTransitionType.scale, + alignment: Alignment.bottomCenter, + ), + }, + ).then((value) => true); + } + Future liberationHistoryOptAction(BuildContext context) async { await showAdaptiveDialog( // isScrollControlled: true, 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 c3870251..a30ffa13 100644 --- a/lib/components/organism_components/menu_component/menu_component_widget.dart +++ b/lib/components/organism_components/menu_component/menu_component_widget.dart @@ -111,6 +111,17 @@ class _MenuComponentWidgetState extends State { ptText: 'Consultar\nHistóricos', ), ), + MenuButtonWidget( + icon: Icons.inventory_2_rounded, + action: () async { + await _model.packageOrder(context); + setState(() {}); + }, + title: FFLocalizations.of(context).getVariableText( + enText: 'Orders', + ptText: 'Encomendas', + ), + ), MenuButtonWidget( icon: Icons.settings, action: () async { @@ -122,6 +133,7 @@ class _MenuComponentWidgetState extends State { ptText: 'Preferências \nde Configurações', ), ), + ]; } if (widget.item == MenuItem.card) { @@ -181,6 +193,17 @@ class _MenuComponentWidgetState extends State { ptText: 'Consultar\nHistoricos', ), ), + MenuCardItem( + icon: Icons.inventory_2_rounded, + action: () async { + await _model.packageOrder(context); + setState(() {}); + }, + title: FFLocalizations.of(context).getVariableText( + enText: 'Orders', + ptText: 'Encomendas', + ), + ), MenuCardItem( icon: Icons.settings, action: () async { @@ -262,6 +285,17 @@ class _MenuComponentWidgetState extends State { ptText: 'Sair da Conta', ), ), + MenuCardItem( + icon: Icons.inventory_2_rounded, + action: () async { + await _model.packageOrder(context); + setState(() {}); + }, + title: FFLocalizations.of(context).getVariableText( + enText: 'Orders', + ptText: 'Encomendas', + ), + ), MenuCardItem( icon: Icons.settings, action: () async { diff --git a/lib/components/templates_components/card_item_template_component/card_item_template_component_widget.dart b/lib/components/templates_components/card_item_template_component/card_item_template_component_widget.dart index dbc1d87e..ecaa7b34 100644 --- a/lib/components/templates_components/card_item_template_component/card_item_template_component_widget.dart +++ b/lib/components/templates_components/card_item_template_component/card_item_template_component_widget.dart @@ -2,6 +2,7 @@ import 'dart:collection'; import 'dart:developer'; import 'package:auto_size_text/auto_size_text.dart'; +import 'package:flutter/cupertino.dart'; import '/flutter_flow/flutter_flow_theme.dart'; import '/flutter_flow/flutter_flow_util.dart'; @@ -29,20 +30,13 @@ class CardItemTemplateComponentWidget extends StatefulWidget { final Future Function()? onTapCardItemAction; @override - State createState() => - _CardItemTemplateComponentWidgetState(); + State createState() => _CardItemTemplateComponentWidgetState(); } -class _CardItemTemplateComponentWidgetState - extends State { +class _CardItemTemplateComponentWidgetState extends State { late CardItemTemplateComponentModel _model; - LinkedHashMap get labelsLinkedHashMap => - LinkedHashMap.from(widget.labelsHashMap ?? {}); - - List> get statusLinkedHashMap => - widget.statusHashMap - .map((map) => LinkedHashMap.from(map ?? {})) - .toList(); + LinkedHashMap get labelsLinkedHashMap => LinkedHashMap.from(widget.labelsHashMap ?? {}); + List> get statusLinkedHashMap => widget.statusHashMap.map((map) => LinkedHashMap.from(map ?? {})).toList(); @override void setState(VoidCallback callback) { @@ -58,42 +52,165 @@ class _CardItemTemplateComponentWidgetState @override void dispose() { - _model.maybeDispose(); - super.dispose(); + _model.maybeDispose(); } - Color _getColorForStatus(String status) { - if (status.length % 3 == 0) { - return FlutterFlowTheme.of(context).success; - } else if (status.length % 3 == 1) { - return FlutterFlowTheme.of(context).error; - } else { - return FlutterFlowTheme.of(context).primary; + String truncate(int cutoff, String text) { + return (text.length <= cutoff) ? text : '${text.substring(0, cutoff)}...'; + } + + List _generateLabels() { + List labels = []; + + for (var key in labelsLinkedHashMap.keys) { + String text = labelsLinkedHashMap[key].toString(); + + Widget widget = Row( + children: [ + Text( + key, + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily, + letterSpacing: 0.0, + fontWeight: FontWeight.bold, + useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).bodyMediumFamily), + color: FlutterFlowTheme.of(context).primaryText, + ), + ), + const SizedBox(width: 2.5), + Text( + text, + overflow: TextOverflow.ellipsis, + style: FlutterFlowTheme.of(context).bodyMedium.override( + fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily, + fontSize: 12.5, + letterSpacing: 0.0, + fontWeight: FontWeight.bold, + useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).bodyMediumFamily), + ), + ) + ], + ); + + labels.add(widget); } + + return labels; } - String truncate(int cutoff, String mytext) { - return (mytext.length <= cutoff) - ? mytext - : '${mytext.substring(0, cutoff)}...'; + Widget _generateImage() { + return Container( + width: 100, + height: 100, + decoration: BoxDecoration( + color: FlutterFlowTheme.of(context).primaryBackground, + ), + child: ClipRRect( + borderRadius: BorderRadius.circular(20), + child: CachedNetworkImage( + fadeInDuration: const Duration(milliseconds: 500), + fadeOutDuration: const Duration(milliseconds: 500), + imageUrl: widget.imagePath ?? '', + fit: BoxFit.cover, + ), + ), + ); + } + + List _generateStatus() { + List status = []; + + statusLinkedHashMap.expand((statusLinked) { + statusLinked.forEach((text, color) { + Widget widget = Container( + padding: const EdgeInsets.all(5), + decoration: BoxDecoration( + color: color, + borderRadius: BorderRadius.circular(5) + ), + child: Text( + text, + overflow: TextOverflow.ellipsis, + style: TextStyle( + color: FlutterFlowTheme.of(context).info, + fontSize: 12, + fontWeight: FontWeight.bold + ), + ), + ); + + status.add(widget); + }); + + return []; + }).toList(); + + return status; + } + + Widget _smallScreen() { + return Column( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + _generateImage(), + const SizedBox(height: 5), + Column( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ..._generateLabels(), + const SizedBox(height: 5), + Wrap( + spacing: 8, + runSpacing: 8, + children: _generateStatus(), + ) + ] + ), + ], + ); + } + + Widget _largeScreen() { + return Row( + mainAxisSize: MainAxisSize.max, + mainAxisAlignment: MainAxisAlignment.spaceBetween, + children: [ + Column( + mainAxisSize: MainAxisSize.max, + crossAxisAlignment: CrossAxisAlignment.start, + children: [ + ..._generateLabels(), + const SizedBox(height: 5), + Wrap( + spacing: 8, + runSpacing: 8, + children: _generateStatus(), + ) + ] + ), + _generateImage() + ], + ); } @override Widget build(BuildContext context) { double screenWidth = MediaQuery.of(context).size.width; double screenHeight = MediaQuery.of(context).size.height; + context.watch(); + return InkWell( splashColor: Colors.transparent, focusColor: Colors.transparent, hoverColor: Colors.transparent, highlightColor: Colors.transparent, - onTap: () async { - await widget.onTapCardItemAction?.call(); - }, + onTap: () async => await widget.onTapCardItemAction?.call(), child: Padding( - padding: const EdgeInsets.fromLTRB(10, 0, 10, 0), + padding: const EdgeInsets.all(8), child: Card( clipBehavior: Clip.antiAliasWithSaveLayer, color: FlutterFlowTheme.of(context).primaryBackground, @@ -102,158 +219,16 @@ class _CardItemTemplateComponentWidgetState borderRadius: BorderRadius.circular(8.0), ), child: Container( - width: 350, - height: 125, + width: double.infinity, decoration: BoxDecoration( color: FlutterFlowTheme.of(context).primaryBackground, ), - child: Row( + padding: const EdgeInsets.all(8), + child: Column( mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.spaceBetween, + crossAxisAlignment: CrossAxisAlignment.start, children: [ - Expanded( - child: Container( - width: MediaQuery.of(context).size.width, - height: MediaQuery.of(context).size.height, - decoration: const BoxDecoration(), - child: Padding( - padding: const EdgeInsets.all(8.0), - child: Column( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: MainAxisAlignment.center, - children: [ - Expanded( - child: ListView.builder( - shrinkWrap: true, - itemCount: labelsLinkedHashMap.length, - physics: const NeverScrollableScrollPhysics(), - itemBuilder: (context, index) { - String key = - labelsLinkedHashMap.keys.elementAt(index); - String value = labelsLinkedHashMap[key]!; - return Padding( - padding: - const EdgeInsets.fromLTRB(20, 0, 0, 5), - child: Row( - mainAxisSize: MainAxisSize.max, - mainAxisAlignment: - MainAxisAlignment.start, - children: [ - Text( - key, - style: FlutterFlowTheme.of(context) - .bodyMedium - .override( - fontFamily: - FlutterFlowTheme.of(context) - .bodyMediumFamily, - letterSpacing: 0.0, - fontWeight: FontWeight.bold, - useGoogleFonts: GoogleFonts - .asMap() - .containsKey( - FlutterFlowTheme.of( - context) - .bodyMediumFamily), - color: - FlutterFlowTheme.of(context) - .primaryText, - ), - ), - const SizedBox(width: 3.0), // Espaçamento entre o label e o valor - Flexible( - child: Text( - value, - overflow: TextOverflow.ellipsis, - style: FlutterFlowTheme.of(context) - .bodyMedium - .override( - fontFamily: - FlutterFlowTheme.of( - context) - .bodyMediumFamily, - fontSize: 12.5, - letterSpacing: 0.0, - fontWeight: FontWeight.bold, - useGoogleFonts: GoogleFonts - .asMap() - .containsKey( - FlutterFlowTheme.of( - context) - .bodyMediumFamily), - ), - ), - ), - ], - ), - ); - }, - ), - ), - Row( - mainAxisAlignment: MainAxisAlignment.center, - mainAxisSize: MainAxisSize.max, - children: - statusLinkedHashMap.expand((linkedHashMap) { - return linkedHashMap.entries - .map((MapEntry item) { - return Container( - child: Row( - mainAxisAlignment: - MainAxisAlignment.spaceBetween, - children: [ - Padding( - padding: const EdgeInsets.symmetric( - horizontal: 1.0, vertical: 3.0), - child: Container( - width: 100.0, - height: 27.0, - decoration: BoxDecoration( - color: item - .value, // Usa a cor do item atual - borderRadius: - BorderRadius.circular(5.0), - ), - child: Align( - alignment: Alignment.center, - child: Text( - item.key, // Usa a chave do item atual como texto - style: TextStyle( - color: FlutterFlowTheme.of( - context) - .info, // Ajuste conforme necessário - ), - ), - ), - ), - ), - ], - ), - ); - }).toList(); - }).toList(), - ), - ]), - ), - ), - ), - Padding( - padding: const EdgeInsetsDirectional.fromSTEB( - 10.0, 10.0, 10.0, 10.0), - child: ClipRRect( - borderRadius: BorderRadius.circular(22.0), - child: AspectRatio( - aspectRatio: - 1.0, // Define a proporção desejada (1:1 neste caso) - child: CachedNetworkImage( - fadeInDuration: const Duration(milliseconds: 500), - fadeOutDuration: const Duration(milliseconds: 500), - imageUrl: widget.imagePath ?? '', - fit: BoxFit.cover, - ), - ), - ), - ) + screenWidth > 360 ? _largeScreen() : _smallScreen(), ], ), ), diff --git a/lib/flutter_flow/nav/nav.dart b/lib/flutter_flow/nav/nav.dart index 53a62a9a..1d21afff 100644 --- a/lib/flutter_flow/nav/nav.dart +++ b/lib/flutter_flow/nav/nav.dart @@ -5,6 +5,7 @@ import 'package:hub/flutter_flow/nav/nav.dart'; import 'package:hub/pages/fast_pass_page/fast_pass_page_widget.dart'; import 'package:hub/pages/message_history_page/message_history_page_widget.dart'; import 'package:hub/pages/no_connection_page/no_connection_page.dart'; +import 'package:hub/pages/package_order_page/package_order_page.dart'; import 'package:provider/provider.dart'; import '/backend/schema/structs/index.dart'; @@ -171,6 +172,11 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) => GoRouter( path: '/preferencesPage', builder: (context, params) => const PreferencesPageWidget(), ), + FFRoute( + name: 'packageOrder', + path: '/packageOrder', + builder: (context, params) => const PackageOrderPage(), + ), // FFRoute( // name: 'settingsPage', // path: '/settingsPage', diff --git a/lib/pages/acess_history_page/acess_history_page_widget.dart b/lib/pages/acess_history_page/acess_history_page_widget.dart index 81dac80f..3e415874 100644 --- a/lib/pages/acess_history_page/acess_history_page_widget.dart +++ b/lib/pages/acess_history_page/acess_history_page_widget.dart @@ -30,23 +30,7 @@ class AcessHistoryPageWidget extends StatefulWidget { }; AcessHistoryPageWidget({super.key, required this.opt}); @override - State createState() => - _AcessHistoryPageWidgetState(opt); -} - -class AccessHistoryItemWidget extends StatelessWidget { - final dynamic accessHistoryItem; - - const AccessHistoryItemWidget({Key? key, required this.accessHistoryItem}) - : super(key: key); - - @override - Widget build(BuildContext context) { - return const Padding( - padding: EdgeInsets.all(8.0), - child: Column(), - ); - } + State createState() => _AcessHistoryPageWidgetState(opt); } class _AcessHistoryPageWidgetState extends State { @@ -66,8 +50,7 @@ class _AcessHistoryPageWidgetState extends State { late Future _accessFuture; List _accessWrap = []; - _AcessHistoryPageWidgetState(Map opt) - : selectedTypeSubject = BehaviorSubject.seeded(opt) { + _AcessHistoryPageWidgetState(Map opt) : selectedTypeSubject = BehaviorSubject.seeded(opt) { selectedTypeSubject.listen((value) {}); } diff --git a/lib/pages/package_order_page/package_order_page.dart b/lib/pages/package_order_page/package_order_page.dart new file mode 100644 index 00000000..9d8def5c --- /dev/null +++ b/lib/pages/package_order_page/package_order_page.dart @@ -0,0 +1,410 @@ +import 'dart:async'; +import 'dart:developer'; + +import 'package:flutter/cupertino.dart'; +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/molecular_components/order_filter_modal/order_filter_modal_widget.dart'; +import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart'; +import 'package:hub/components/templates_components/details_component/details_component_widget.dart'; +import 'package:hub/flutter_flow/flutter_flow_icon_button.dart'; +import 'package:hub/flutter_flow/flutter_flow_theme.dart'; +import 'package:hub/flutter_flow/flutter_flow_util.dart'; +import 'package:hub/shared/utils/dialog_util.dart'; +import 'package:hub/shared/utils/log_util.dart'; +import 'package:hub/shared/utils/validator_util.dart'; +import 'package:rxdart/rxdart.dart'; + +class PackageOrderPage extends StatefulWidget { + const PackageOrderPage({super.key}); + + @override + State createState() => _PackageOrderPage(); +} + +class _PackageOrderPage extends State { + + late ScrollController _scrollController; + int _pageNumber = 1; + final int _pageSize = 10; + bool _hasData = false; + bool _loading = false; + + late Future _orderFuture; + List _orderList = []; + + final Map filter = { + 'adresseeType': '.*', + 'status': 'notPickedUp', + }; + + String _adresseeType = '.*'; + String _status = 'notPickedUp'; + + late BehaviorSubject> _selectedTypeSubject; + bool _isSubjectClosed = false; + + @override + void initState() { + super.initState(); + _selectedTypeSubject = BehaviorSubject.seeded(filter); + _selectedTypeSubject.listen((value) {}); + + _orderFuture = _fetchOrders(); + + _scrollController = ScrollController()..addListener(() { + if (_scrollController.position.atEdge && _scrollController.position.pixels != 0) { + _loadMoreOrders(); + } + }); + } + + @override + void dispose() { + super.dispose(); + _selectedTypeSubject.close(); + _isSubjectClosed = true; + _scrollController.dispose(); + } + + 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, + ), + ); + } + + Future _fetchOrders() async { + try { + setState(() => _loading = true); + + var response = await PhpGroup.buscaEnconcomendas.call( + devUUID: AppState().devUUID, + userUUID: AppState().userUUID, + cliID: AppState().cliUUID, + atividade: 'getEncomendas', + pageSize: _pageSize.toString(), + page: _pageNumber.toString(), + adresseeType: _adresseeType == '.*' ? 'TOD' : _adresseeType, + status: _status == '.*' ? 'all' : _status + ); + + final List orders = response.jsonBody['value']['list'] ?? []; + + if (orders != null && orders.isNotEmpty) { + setState(() { + _orderList.addAll(orders); + _hasData = true; + _loading = false; + }); + + return response; + } + + _showNoMoreDataSnackbar(context); + + setState(() { + _hasData = false; + _loading = false; + }); + + return null; + } catch (e, s) { + DialogUtil.errorDefault(context); + LogUtil.requestAPIFailed('processRequest', "", "Busca Encomendas", e, s); + setState(() { + _hasData = false; + _loading = false; + }); + } + } + + void _loadMoreOrders() { + if (_hasData == true) { + _pageNumber++; + _orderFuture = _fetchOrders(); + } + } + + 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(), + ); + } + + Widget _filterButton(BuildContext context) { + return Row( + mainAxisAlignment: MainAxisAlignment.end, + children: [ + Padding( + padding: const EdgeInsets.fromLTRB(0, 0, 10, 0), + child: IconButton( + icon: const Icon(Icons.filter_list), + onPressed: () async { + final Map? selectedFilter = + await showModalBottomSheet>( + isScrollControlled: true, + backgroundColor: Colors.transparent, + context: context, + builder: (context) { + return GestureDetector( + onTap: () => Navigator.of(context).pop(), + child: Container( + color: Colors.transparent, + child: GestureDetector( + onTap: () {}, + child: OrderFilterModalWidget( + defaultAdresseeType: _selectedTypeSubject.value['adresseeType'] ?? '.*', + defaultStatus: _selectedTypeSubject.value['status'] ?? '.*', + ), + ), + ), + ); + }); + + if (selectedFilter != null) { + _updateFilterAction(selectedFilter); + } + }, + ), + ), + ], + ); + } + + void _updateFilterAction(Map newType) { + if (!_isSubjectClosed) { + final currentType = _selectedTypeSubject.value; + final updatedType = Map.from(currentType); + bool needsUpdate = false; + newType.forEach((key, newValue) { + if (currentType[key] != newValue) { + updatedType[key] = newValue; + needsUpdate = true; + } + }); + if (needsUpdate) { + _selectedTypeSubject.add(updatedType); + _fetchFilterOrder(updatedType); + safeSetState(() {}); + } + } + } + + void _fetchFilterOrder(Map select) { + _adresseeType = select['adresseeType']!; + _status = select['status']!; + _orderList = []; + _pageNumber = 1; + _orderFuture = _fetchOrders(); + } + + PreferredSizeWidget _appBar(BuildContext context) { + double screenWidth = MediaQuery.of(context).size.width; + double screenHeight = MediaQuery.of(context).size.height; + + return AppBar( + backgroundColor: FlutterFlowTheme.of(context).primaryBackground, + automaticallyImplyLeading: false, + title: Text( + FFLocalizations.of(context).getVariableText(enText: 'Orders', ptText: 'Encomendas'), + 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: [_filterButton(context)], + ); + } + + Widget _appBody(BuildContext context) { + return SafeArea( + top: true, + child: 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 encomenda encontrada!", + enText: "No orders found!"), + )), + ], + ), + ) + else if (_hasData || _pageNumber >= 1) + Expanded(child: _itemList()), + if (_hasData == true && _loading == true) + Container( + padding: const EdgeInsets.only(top: 15, bottom: 15), + child: Center( + child: CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation( + FlutterFlowTheme.of(context).primary, + ), + ), + ), + ) + ], + ), + ); + } + + Widget _itemList() { + return FutureBuilder( + future: _orderFuture, + builder: (context, snapshot) { + return ListView.builder( + shrinkWrap: true, + physics: const BouncingScrollPhysics(), + controller: _scrollController, + itemCount: _orderList.length, + itemBuilder: (context, index) { + final order = _orderList[index]; + return _item(context, order); + }, + ); + } + ); + } + + String _imagePath(dynamic order) { + return '${PhpGroup.getBaseUrl()}/getImage.php?cliID=${AppState().cliUUID}&atividade=getFotoEncomenda&orderId=${order['id'] ?? ''}'; + } + + Map _labelsHashMap(dynamic order) { + return Map.from({ + if (order['isPending'] == true) + '${FFLocalizations.of(context).getVariableText(ptText: 'Cód. Retirada', enText: 'Pickup Code')}:': order['id'].toString(), + '${FFLocalizations.of(context).getVariableText(ptText: 'Categoria', enText: 'Category')}:': order['customCategory'], + '${FFLocalizations.of(context).getVariableText(ptText: 'Recebido em', enText: 'Received on')}:': ValidatorUtil.toLocalDateTime('yyyy-MM-dd HH:mm:ss', order['dtReceive']), + if (order['isPending'] == false) + '${FFLocalizations.of(context).getVariableText(ptText: 'Retirado em', enText: 'Picked up on')}:': ValidatorUtil.toLocalDateTime('yyyy-MM-dd HH:mm:ss', order['dtPickUp']), + }); + } + + Map _labelsHashMapDialog(dynamic order) { + return Map.from({ + if (order['isPending'] == true) + '${FFLocalizations.of(context).getVariableText(ptText: 'Cód. Retirada', enText: 'Pickup Code')}:': order['id'].toString(), + + '${FFLocalizations.of(context).getVariableText(ptText: 'Categoria', enText: 'Category')}:': order['customCategory'], + + if (order['code'] != null) + '${FFLocalizations.of(context).getVariableText(ptText: 'Cód. Objeto', enText: 'Object Code')}:': order['code'], + + '${FFLocalizations.of(context).getVariableText(ptText: 'Entregue por', enText: 'Delivered by')}:': order['sendedBy'], + + '${FFLocalizations.of(context).getVariableText(ptText: 'Recebido por', enText: 'Received by')}:': order['receivedBy'], + '${FFLocalizations.of(context).getVariableText(ptText: 'Recebido em', enText: 'Received on')}:': ValidatorUtil.toLocalDateTime('yyyy-MM-dd HH:mm:ss', order['dtReceive']), + + if (order['isPending'] == false) + '${FFLocalizations.of(context).getVariableText(ptText: 'Retirado por', enText: 'Picked up by')}:': order['pickedUpBy'], + if (order['isPending'] == false) + '${FFLocalizations.of(context).getVariableText(ptText: 'Retirado em', enText: 'Picked up on')}:': ValidatorUtil.toLocalDateTime('yyyy-MM-dd HH:mm:ss', order['dtPickUp']), + + if (order['message'] != null) + '${FFLocalizations.of(context).getVariableText(ptText: 'Mensagem', enText: 'Message')}:': order['message'] + }); + } + + List> _statusHashMap(dynamic order) { + return [ + if (order['isPending'] == true) + Map.from({ + FFLocalizations.of(context).getVariableText(ptText: 'Aguardando Retirada', enText: 'Waiting Pick up'): FlutterFlowTheme.of(context).warning, + }) + else + Map.from({ + FFLocalizations.of(context).getVariableText(ptText: 'Retirado', enText: 'Picked up'): FlutterFlowTheme.of(context).primary, + }), + + if (order['adresseeType'] == 'PRO') + Map.from({ + FFLocalizations.of(context).getVariableText( + ptText: 'Propriedade', + enText: 'Property', + ): FlutterFlowTheme.of(context).alternate2, + }) + else if (order['adresseeType'] == 'MOR') + Map.from({ + FFLocalizations.of(context).getVariableText( + ptText: 'Morador', + enText: 'Resident', + ): FlutterFlowTheme.of(context).alternate2, + }) + ]; + } + + Widget _item(BuildContext context, dynamic order) { + return CardItemTemplateComponentWidget( + imagePath: _imagePath(order), + labelsHashMap: _labelsHashMap(order), + statusHashMap: _statusHashMap(order), + onTapCardItemAction: () async { + showDialog( + useSafeArea: true, + context: context, + builder: (context) { + return Dialog( + child: DetailsComponentWidget( + imagePath: _imagePath(order), + labelsHashMap: _labelsHashMapDialog(order), + statusHashMap: [ + if (order['isPending'] == true) + Map.from({ + FFLocalizations.of(context).getVariableText(ptText: 'Aguardando Retirada', enText: 'Waiting Pick up'): FlutterFlowTheme.of(context).warning, + }) + else + Map.from({ + FFLocalizations.of(context).getVariableText(ptText: 'Retirado', enText: 'Picked up'): FlutterFlowTheme.of(context).primary, + }), + ], + buttons: [], + ), + ); + } + ); + }, + ); + } + + @override + Widget build(BuildContext context) { + return Scaffold( + appBar: _appBar(context), + body: _appBody(context), + ); + } +} \ No newline at end of file diff --git a/pubspec.lock b/pubspec.lock index ab70e828..49fbc8b6 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -66,7 +66,7 @@ packages: source: hosted version: "2.0.3" bloc: - dependency: "direct main" + dependency: transitive description: name: bloc sha256: "106842ad6569f0b60297619e9e0b1885c2fb9bf84812935490e6c5275777804e" From ee973ad74934ff80e99151aafe90e8a232a64a31 Mon Sep 17 00:00:00 2001 From: Ivan Antunes Date: Fri, 23 Aug 2024 18:02:17 -0300 Subject: [PATCH 2/4] fet: Reservas --- .../menu_component/menu_component_model.dart | 5 + .../menu_component/menu_component_widget.dart | 33 ++++++ lib/flutter_flow/nav/nav.dart | 6 ++ .../fast_pass_page/fast_pass_page_widget.dart | 3 - .../reservation_page_widget.dart | 101 ++++++++++++++++++ 5 files changed, 145 insertions(+), 3 deletions(-) create mode 100644 lib/pages/reservation_page/reservation_page_widget.dart 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 96c92010..808b44bd 100644 --- a/lib/components/organism_components/menu_component/menu_component_model.dart +++ b/lib/components/organism_components/menu_component/menu_component_model.dart @@ -3,6 +3,7 @@ import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:hub/components/organism_components/menu_staggered_view_component/menu_staggered_view_component_model.dart'; import 'package:hub/flutter_flow/nav/nav.dart'; +import 'package:hub/pages/reservation_page/reservation_page_widget.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'; @@ -163,6 +164,10 @@ class MenuComponentModel extends FlutterFlowModel { ).then((value) => true); } + Future reservation(BuildContext context) async { + Navigator.push(context, MaterialPageRoute(builder: (context) => ReservationPageWidget())); + } + Future liberationHistoryOptAction(BuildContext context) async { await showAdaptiveDialog( // isScrollControlled: true, 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 a30ffa13..ddbdda9a 100644 --- a/lib/components/organism_components/menu_component/menu_component_widget.dart +++ b/lib/components/organism_components/menu_component/menu_component_widget.dart @@ -122,6 +122,17 @@ class _MenuComponentWidgetState extends State { ptText: 'Encomendas', ), ), + MenuButtonWidget( + icon: Icons.event_available, + action: () async { + await _model.reservation(context); + setState(() {}); + }, + title: FFLocalizations.of(context).getVariableText( + enText: 'Reservations', + ptText: 'Reservas', + ), + ), MenuButtonWidget( icon: Icons.settings, action: () async { @@ -204,6 +215,17 @@ class _MenuComponentWidgetState extends State { ptText: 'Encomendas', ), ), + MenuCardItem( + icon: Icons.event_available, + action: () async { + await _model.reservation(context); + setState(() {}); + }, + title: FFLocalizations.of(context).getVariableText( + enText: 'Reservations', + ptText: 'Reservas', + ), + ), MenuCardItem( icon: Icons.settings, action: () async { @@ -296,6 +318,17 @@ class _MenuComponentWidgetState extends State { ptText: 'Encomendas', ), ), + MenuCardItem( + icon: Icons.event_available, + action: () async { + await _model.reservation(context); + setState(() {}); + }, + title: FFLocalizations.of(context).getVariableText( + enText: 'Reservations', + ptText: 'Reservas', + ), + ), MenuCardItem( icon: Icons.settings, action: () async { diff --git a/lib/flutter_flow/nav/nav.dart b/lib/flutter_flow/nav/nav.dart index 1d21afff..3c88ce9c 100644 --- a/lib/flutter_flow/nav/nav.dart +++ b/lib/flutter_flow/nav/nav.dart @@ -6,6 +6,7 @@ import 'package:hub/pages/fast_pass_page/fast_pass_page_widget.dart'; import 'package:hub/pages/message_history_page/message_history_page_widget.dart'; import 'package:hub/pages/no_connection_page/no_connection_page.dart'; import 'package:hub/pages/package_order_page/package_order_page.dart'; +import 'package:hub/pages/reservation_page/reservation_page_widget.dart'; import 'package:provider/provider.dart'; import '/backend/schema/structs/index.dart'; @@ -177,6 +178,11 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) => GoRouter( path: '/packageOrder', builder: (context, params) => const PackageOrderPage(), ), + FFRoute( + name: 'reservation', + path: '/reservation', + builder: (context, params) => ReservationPageWidget(), + ), // FFRoute( // name: 'settingsPage', // path: '/settingsPage', diff --git a/lib/pages/fast_pass_page/fast_pass_page_widget.dart b/lib/pages/fast_pass_page/fast_pass_page_widget.dart index 1b918bcb..bd2bfb8e 100644 --- a/lib/pages/fast_pass_page/fast_pass_page_widget.dart +++ b/lib/pages/fast_pass_page/fast_pass_page_widget.dart @@ -1,7 +1,4 @@ -import 'dart:developer'; - import 'package:hub/app_state.dart'; -import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; import 'package:url_launcher/url_launcher_string.dart'; diff --git a/lib/pages/reservation_page/reservation_page_widget.dart b/lib/pages/reservation_page/reservation_page_widget.dart new file mode 100644 index 00000000..87eab3f6 --- /dev/null +++ b/lib/pages/reservation_page/reservation_page_widget.dart @@ -0,0 +1,101 @@ +import 'package:hub/app_state.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter_inappwebview/flutter_inappwebview.dart'; +import 'package:url_launcher/url_launcher_string.dart'; +import 'package:webview_flutter/webview_flutter.dart'; +import 'dart:io' show Platform; + +class ReservationPageWidget extends StatefulWidget { + final String freToken = AppState().userUUID; + final String freUserData = "{\"name\": \"${AppState().name}\", " + + "\"email\": \"${AppState().email}\"," + + "\"dev_id\": \"${AppState().devUUID}\"," + + "\"created_at\": \"${AppState().createdAt}\"," + + "\"updated_at\": \"0000-00-00 00:00:00\"," + + "\"status\": \"A\" }"; + + final String clientId = AppState().cliUUID; + + @override + _ReservationPageWidgetState createState() => _ReservationPageWidgetState(); +} + +class _ReservationPageWidgetState extends State { + late InAppWebViewController _controllerIOS; + late WebViewController _controllerAll; + late String url; + late String name; + late String email; + late String userUUID; + late String created_at; + + @override + void initState() { + super.initState(); + name = AppState().name; + email = AppState().email; + userUUID = AppState().userUUID; + created_at = AppState().createdAt; + url = 'https://hub.freaccess.com.br/hub/reservation/${widget.clientId}'; + } + + @override + Widget build(BuildContext context) { + return SafeArea( + child: Scaffold( + body: Platform.isIOS + ? InAppWebView( + initialUrlRequest: URLRequest(url: WebUri(url)), + initialSettings: InAppWebViewSettings( + allowsBackForwardNavigationGestures: true, + javaScriptEnabled: true, + ), + onWebViewCreated: (controller) async { + _controllerIOS = controller; + }, + onLoadStop: (controller, url) async { + await controller.evaluateJavascript( + source: + "window.localStorage.setItem('fre-token', '\"${widget.freToken}\"')"); + await controller.evaluateJavascript( + source: + "window.localStorage.setItem('fre-user-data', '${widget.freUserData}')"); + }, + + ) + : WebViewWidget( + controller: _controllerAll = WebViewController() + ..clearCache() + ..clearLocalStorage() + ..setJavaScriptMode(JavaScriptMode.unrestricted) + ..setBackgroundColor(const Color(0x00000000)) + ..setNavigationDelegate( + NavigationDelegate( + onProgress: (int progress) {}, + onPageStarted: (String url) { + final String token = + "localStorage.setItem('fre-token', '\"${widget.freToken}\"');"; + final String data = + "localStorage.setItem('fre-user-data', '${widget.freUserData}');"; + + _controllerAll.runJavaScript(token); + _controllerAll.runJavaScript(data); + }, + onNavigationRequest: (NavigationRequest request) { + if (request.url.startsWith('http') || + request.url + .startsWith('https://api.whatsapp.com/send') || + request.url.startsWith('https://wa.me')) { + launchUrlString(request.url); + return NavigationDecision.prevent; + } + return NavigationDecision.prevent; + }, + ), + ) + ..loadRequest(Uri.parse(url)), + ), + ), + ); + } +} From 305a6cf9dff8d86cab92c2ca7d2ca3ff92eb985c Mon Sep 17 00:00:00 2001 From: Ivan Antunes Date: Mon, 26 Aug 2024 08:44:06 -0300 Subject: [PATCH 3/4] =?UTF-8?q?fet:=20Adicinado=20Flag=20para=20habilitar?= =?UTF-8?q?=20o=20bot=C3=A3o=20de=20voltar=20no=20hub?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- android/app/src/main/AndroidManifest.xml | 3 +- lib/backend/api_requests/api_calls.dart | 1 - .../fast_pass_page/fast_pass_page_widget.dart | 17 +++++------ .../reservation_page_widget.dart | 30 ++++++++++++------- 4 files changed, 28 insertions(+), 23 deletions(-) diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index bc60e9ce..66407cbd 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -14,7 +14,8 @@ android:label="FREHub" tools:replace="android:label" android:icon="@mipmap/ic_launcher" - android:requestLegacyExternalStorage="true"> + android:requestLegacyExternalStorage="true" + android:usesCleartextTraffic="true"> 'https://freaccess.com.br/freaccess'; - // static String getBaseUrl() => 'http://192.168.2.204:8080'; static Map headers = {}; static LoginCall loginCall = LoginCall(); static UpdToken updToken = UpdToken(); diff --git a/lib/pages/fast_pass_page/fast_pass_page_widget.dart b/lib/pages/fast_pass_page/fast_pass_page_widget.dart index bd2bfb8e..91130bc2 100644 --- a/lib/pages/fast_pass_page/fast_pass_page_widget.dart +++ b/lib/pages/fast_pass_page/fast_pass_page_widget.dart @@ -54,12 +54,9 @@ class _FastPassPageWidgetState extends State { _controllerIOS = controller; }, onLoadStop: (controller, url) async { - await controller.evaluateJavascript( - source: - "window.localStorage.setItem('fre-token', '\"${widget.freToken}\"')"); - await controller.evaluateJavascript( - source: - "window.localStorage.setItem('fre-user-data', '${widget.freUserData}')"); + await controller.evaluateJavascript(source: "window.localStorage.setItem('fre-token', '\"${widget.freToken}\"')"); + await controller.evaluateJavascript(source: "window.localStorage.setItem('fre-user-data', '${widget.freUserData}')"); + await controller.evaluateJavascript(source: "window.localStorage.setItem('enableBackButton', 'true')"); }, ) : WebViewWidget( @@ -72,13 +69,13 @@ class _FastPassPageWidgetState extends State { NavigationDelegate( onProgress: (int progress) {}, onPageStarted: (String url) { - final String token = - "localStorage.setItem('fre-token', '\"${widget.freToken}\"');"; - final String data = - "localStorage.setItem('fre-user-data', '${widget.freUserData}');"; + final String token = "localStorage.setItem('fre-token', '\"${widget.freToken}\"');"; + final String data = "localStorage.setItem('fre-user-data', '${widget.freUserData}');"; + const String backNavigation = "localStorage.setItem('enableBackButton', 'true');"; _controllerAll.runJavaScript(token); _controllerAll.runJavaScript(data); + _controllerAll.runJavaScript(backNavigation); }, onNavigationRequest: (NavigationRequest request) { if (request.url.startsWith('http') || diff --git a/lib/pages/reservation_page/reservation_page_widget.dart b/lib/pages/reservation_page/reservation_page_widget.dart index 87eab3f6..ec8dd7f5 100644 --- a/lib/pages/reservation_page/reservation_page_widget.dart +++ b/lib/pages/reservation_page/reservation_page_widget.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:hub/app_state.dart'; import 'package:flutter/material.dart'; import 'package:flutter_inappwebview/flutter_inappwebview.dart'; @@ -54,14 +56,15 @@ class _ReservationPageWidgetState extends State { _controllerIOS = controller; }, onLoadStop: (controller, url) async { - await controller.evaluateJavascript( - source: - "window.localStorage.setItem('fre-token', '\"${widget.freToken}\"')"); - await controller.evaluateJavascript( - source: - "window.localStorage.setItem('fre-user-data', '${widget.freUserData}')"); + await controller.evaluateJavascript(source: "window.localStorage.setItem('fre-token', '\"${widget.freToken}\"')"); + await controller.evaluateJavascript(source: "window.localStorage.setItem('fre-user-data', '${widget.freUserData}')"); + await controller.evaluateJavascript(source: "window.localStorage.setItem('enableBackButton', 'true')"); + }, + onUpdateVisitedHistory: (controller, uri, isVisited) { + if (uri.toString().contains('/hub/home')) { + Navigator.pop(context); + } }, - ) : WebViewWidget( controller: _controllerAll = WebViewController() @@ -73,13 +76,13 @@ class _ReservationPageWidgetState extends State { NavigationDelegate( onProgress: (int progress) {}, onPageStarted: (String url) { - final String token = - "localStorage.setItem('fre-token', '\"${widget.freToken}\"');"; - final String data = - "localStorage.setItem('fre-user-data', '${widget.freUserData}');"; + final String token = "localStorage.setItem('fre-token', '\"${widget.freToken}\"');"; + final String data = "localStorage.setItem('fre-user-data', '${widget.freUserData}');"; + const String backNavigation = "localStorage.setItem('enableBackButton', 'true');"; _controllerAll.runJavaScript(token); _controllerAll.runJavaScript(data); + _controllerAll.runJavaScript(backNavigation); }, onNavigationRequest: (NavigationRequest request) { if (request.url.startsWith('http') || @@ -91,6 +94,11 @@ class _ReservationPageWidgetState extends State { } return NavigationDecision.prevent; }, + onUrlChange: (url) { + if (url.url.toString().contains('/hub/home')) { + Navigator.pop(context); + } + } ), ) ..loadRequest(Uri.parse(url)), From 4cb88b5759bb9e804c1fecadebe3c70f0713df98 Mon Sep 17 00:00:00 2001 From: Ivan Antunes Date: Mon, 26 Aug 2024 11:03:37 -0300 Subject: [PATCH 4/4] fux --- .../card_item_template_component_widget.dart | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/lib/components/templates_components/card_item_template_component/card_item_template_component_widget.dart b/lib/components/templates_components/card_item_template_component/card_item_template_component_widget.dart index ecaa7b34..894ebe84 100644 --- a/lib/components/templates_components/card_item_template_component/card_item_template_component_widget.dart +++ b/lib/components/templates_components/card_item_template_component/card_item_template_component_widget.dart @@ -79,15 +79,17 @@ class _CardItemTemplateComponentWidgetState extends State