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 ced0373e..d446d4a7 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 @@ -9,7 +9,6 @@ class MenuButtonWidget extends MenuEntry { required this.action, required this.title, required this.icon, - required super.safeSetState, }) : super(action: action, title: title, icon: icon); @override 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 5696f83a..c4c5cbaf 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,7 +9,6 @@ class MenuCardItem extends MenuEntry { required this.action, required this.title, required this.icon, - required super.safeSetState, }) : super(action: action, title: title, icon: icon); @override diff --git a/lib/components/molecular_components/menu_item/menu_item.dart b/lib/components/molecular_components/menu_item/menu_item.dart index fe97affd..77734bc1 100644 --- a/lib/components/molecular_components/menu_item/menu_item.dart +++ b/lib/components/molecular_components/menu_item/menu_item.dart @@ -28,11 +28,9 @@ abstract class MenuEntry extends StatefulWidget { required this.action, required this.title, required this.icon, - required this.safeSetState, }); final Function() action; final String title; final IconData icon; - final VoidCallback safeSetState; } diff --git a/lib/components/organism_components/local_profile_component/local_profile_bloc.dart b/lib/components/organism_components/local_profile_component/local_profile_bloc.dart new file mode 100644 index 00000000..5aacf75e --- /dev/null +++ b/lib/components/organism_components/local_profile_component/local_profile_bloc.dart @@ -0,0 +1,52 @@ +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:flutter/material.dart'; +import 'package:hub/components/organism_components/local_profile_component/local_profile_component_widget.dart'; +import 'package:hub/flutter_flow/flutter_flow_model.dart'; +import 'package:hub/shared/helpers/storage/base_storage.dart'; +import 'package:hub/shared/helpers/storage/storage_helper.dart'; + +class LocalProfileEvent {} + +class LocalProfileState { + final String cliName; + final String cliUUID; + + LocalProfileState({this.cliName = '', this.cliUUID = ''}); + + LocalProfileState copyWith({String? cliName, String? cliUUID}) { + return LocalProfileState( + cliName: cliName ?? this.cliName, + cliUUID: cliUUID ?? this.cliUUID, + ); + } +} + +class LocalProfileBloc extends Bloc { + LocalProfileBloc() : super(LocalProfileState()) { + on((event, emit) async { + final cliName = (await StorageHelper().g(KeychainStorageKey.clientName.value)) ?? ''; + final cliUUID = (await StorageHelper().g(KeychainStorageKey.clientUUID.value)) ?? ''; + emit(state.copyWith(cliName: cliName, cliUUID: cliUUID)); + }); + } +} + +class LocalProfileComponentModel extends FlutterFlowModel { + String cliName = ''; + String cliUUID = ''; + VoidCallback? setStateCallback; + + @override + void initState(BuildContext context) { + getData(); + } + + Future getData() async { + cliName = (await StorageHelper().g(KeychainStorageKey.clientName.value)) ?? ''; + cliUUID = (await StorageHelper().g(KeychainStorageKey.clientUUID.value)) ?? ''; + setStateCallback?.call(); + } + + @override + void dispose() {} +} diff --git a/lib/components/organism_components/local_profile_component/local_profile_component_model.dart b/lib/components/organism_components/local_profile_component/local_profile_component_model.dart deleted file mode 100644 index 300dae93..00000000 --- a/lib/components/organism_components/local_profile_component/local_profile_component_model.dart +++ /dev/null @@ -1,28 +0,0 @@ -import 'package:hub/shared/helpers/storage/base_storage.dart'; -import 'package:hub/shared/helpers/storage/storage_helper.dart'; - -import '/flutter_flow/flutter_flow_util.dart'; -import 'local_profile_component_widget.dart' show LocalProfileComponentWidget; -import 'package:flutter/material.dart'; - -/// - -class LocalProfileComponentModel extends FlutterFlowModel { - String cliName = ''; - String cliUUID = ''; - VoidCallback? setStateCallback; - - @override - void initState(BuildContext context) { - getData(); - } - - Future getData() async { - cliName = (await StorageHelper().g(KeychainStorageKey.clientName.value)) ?? ''; - cliUUID = (await StorageHelper().g(KeychainStorageKey.clientUUID.value)) ?? ''; - setStateCallback?.call(); - } - - @override - void dispose() {} -} diff --git a/lib/components/organism_components/local_profile_component/local_profile_component_widget.dart b/lib/components/organism_components/local_profile_component/local_profile_component_widget.dart index 144f440b..cfbe2109 100644 --- a/lib/components/organism_components/local_profile_component/local_profile_component_widget.dart +++ b/lib/components/organism_components/local_profile_component/local_profile_component_widget.dart @@ -1,18 +1,14 @@ -import 'dart:developer'; - import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:hub/components/organism_components/local_profile_component/local_profile_bloc.dart'; +import 'package:hub/flutter_flow/custom_functions.dart'; +import 'package:hub/flutter_flow/flutter_flow_theme.dart'; +import 'package:hub/flutter_flow/flutter_flow_util.dart'; import 'package:hub/shared/helpers/storage/base_storage.dart'; import 'package:hub/shared/helpers/storage/storage_helper.dart'; - -import '/flutter_flow/custom_functions.dart' as functions; -import '/flutter_flow/flutter_flow_theme.dart'; -import '/flutter_flow/flutter_flow_util.dart'; -import '../../../shared/services/localization/localization_service.dart'; -import 'local_profile_component_model.dart'; - -export 'local_profile_component_model.dart'; +import 'package:hub/shared/services/localization/localization_service.dart'; class LocalProfileComponentWidget extends StatefulWidget { const LocalProfileComponentWidget({super.key}); @@ -22,145 +18,115 @@ class LocalProfileComponentWidget extends StatefulWidget { } class _LocalProfileComponentWidgetState extends State { - late LocalProfileComponentModel _model; - - @override - void setState(VoidCallback callback) { - super.setState(callback); - callback(); - } - - @override - void initState() { - super.initState(); - _model = createModel(context, () => LocalProfileComponentModel()); - _model.setOnUpdate(onUpdate: () => safeSetState(() {})); - _model.setStateCallback = () => safeSetState(() {}); - - WidgetsBinding.instance.addPostFrameCallback((_) async { - bool initialized = false; - bool isDevLinked = _model.cliUUID.isNotEmpty; - if (!isDevLinked && !initialized) { - initialized = true; - await LocalizationService.processLocals(context).then((value) => value == true ? onUpdate() : null); - } - }); - } - - @override - void dispose() { - _model.maybeDispose(); - - super.dispose(); - } - - void onUpdate() async { - log('() => onUpdate()'); - await _model.getData(); - safeSetState(() {}); - } - @override Widget build(BuildContext context) { - final textScaler = MediaQuery.textScalerOf(context); - final double baseFontSize = 14.0; - final double scaledFontSize = baseFontSize * textScaler.scale(1); - final double limitedFontSize = scaledFontSize > 20 ? 12 : scaledFontSize; + return BlocProvider( + create: (context) => LocalProfileBloc()..add(LocalProfileEvent()), + child: BlocBuilder( + builder: (context, state) { + final textScaler = MediaQuery.textScalerOf(context); + final double baseFontSize = 14.0; + final double scaledFontSize = baseFontSize * textScaler.scale(1); + final double limitedFontSize = scaledFontSize > 20 ? 12 : scaledFontSize; - return Container( - decoration: const BoxDecoration(), - child: Align( - alignment: const AlignmentDirectional(0.0, -1.0), - child: Material( - color: Colors.transparent, - elevation: 0.0, - child: Container( - width: double.infinity, - height: 119.0, - decoration: BoxDecoration( - color: FlutterFlowTheme.of(context).primary, - border: Border.all( - color: FlutterFlowTheme.of(context).primary, - ), - ), - child: Row( - mainAxisSize: MainAxisSize.max, - children: [ - Align( - alignment: const AlignmentDirectional(-1.0, 0.0), - child: Padding( - padding: const EdgeInsets.all(2.0), - child: InkWell( - splashColor: Colors.transparent, - focusColor: Colors.transparent, - hoverColor: Colors.transparent, - highlightColor: Colors.transparent, - onTap: () async { - await StorageHelper().s(KeychainStorageKey.clientUUID.value, ''); - await LocalizationService.processLocals(context).whenComplete(() => onUpdate()); - }, - child: ClipRRect( - borderRadius: BorderRadius.circular(200.0), - child: CachedNetworkImage( - imageBuilder: (context, imageProvider) => Container( - decoration: BoxDecoration( - image: DecorationImage( - image: imageProvider, - fit: BoxFit.cover, - ), - ), - ), - imageUrl: valueOrDefault( - 'https://freaccess.com.br/freaccess/Images/Clients/${_model.cliUUID}.png', - 'assets/images/home.png'), - width: 80.0, - height: 80.0, - fit: BoxFit.cover, - alignment: const Alignment(0.0, 0.0), - placeholder: (context, url) => Image.asset('assets/images/home.png'), - errorListener: (_) => Image.asset('assets/images/home.png'), - errorWidget: (_, __, ___) => Image.asset('assets/images/home.png'), - ), - )), - ), - ), - Expanded( - child: Tooltip( - message: valueOrDefault( - functions.convertToUppercase(_model.cliName), - FFLocalizations.of(context).getVariableText( - ptText: 'SEM LOCAL VINCULADO', - enText: 'NO LINKED LOCAL', - ), + return Container( + decoration: const BoxDecoration(), + child: Align( + alignment: const AlignmentDirectional(0.0, -1.0), + child: Material( + color: Colors.transparent, + elevation: 0.0, + child: Container( + width: double.infinity, + height: 119.0, + decoration: BoxDecoration( + color: FlutterFlowTheme.of(context).primary, + border: Border.all( + color: FlutterFlowTheme.of(context).primary, ), - child: Text( - valueOrDefault( - functions.convertToUppercase(_model.cliName), - FFLocalizations.of(context).getVariableText( - ptText: 'SEM LOCAL VINCULADO', - enText: 'NO LINKED LOCAL', + ), + child: Row( + mainAxisSize: MainAxisSize.max, + children: [ + Align( + alignment: const AlignmentDirectional(-1.0, 0.0), + child: Padding( + padding: const EdgeInsets.all(2.0), + child: InkWell( + splashColor: Colors.transparent, + focusColor: Colors.transparent, + hoverColor: Colors.transparent, + highlightColor: Colors.transparent, + onTap: () async { + await StorageHelper().s(KeychainStorageKey.clientUUID.value, ''); + await LocalizationService.processLocals(context).whenComplete( + () async => context.read().add(LocalProfileEvent())); + }, + child: ClipRRect( + borderRadius: BorderRadius.circular(200.0), + child: CachedNetworkImage( + imageBuilder: (context, imageProvider) => Container( + decoration: BoxDecoration( + image: DecorationImage( + image: imageProvider, + fit: BoxFit.cover, + ), + ), + ), + imageUrl: valueOrDefault( + 'https://freaccess.com.br/freaccess/Images/Clients/${state.cliUUID}.png', + 'assets/images/home.png'), + width: 80.0, + height: 80.0, + fit: BoxFit.cover, + alignment: const Alignment(0.0, 0.0), + placeholder: (context, url) => Image.asset('assets/images/home.png'), + errorListener: (_) => Image.asset('assets/images/home.png'), + errorWidget: (_, __, ___) => Image.asset('assets/images/home.png'), + ), + )), ), ), - overflow: TextOverflow.ellipsis, - maxLines: 1, - style: FlutterFlowTheme.of(context).labelMedium.override( - fontFamily: 'Nunito', - color: FlutterFlowTheme.of(context).info, - fontSize: limitedFontSize, - letterSpacing: 0.0, - fontWeight: FontWeight.w500, - useGoogleFonts: GoogleFonts.asMap().containsKey('Nunito'), + Expanded( + child: Tooltip( + message: valueOrDefault( + convertToUppercase(state.cliName), + FFLocalizations.of(context).getVariableText( + ptText: 'SEM LOCAL VINCULADO', + enText: 'NO LINKED LOCAL', + ), ), - ), + child: Text( + valueOrDefault( + convertToUppercase(state.cliName), + FFLocalizations.of(context).getVariableText( + ptText: 'SEM LOCAL VINCULADO', + enText: 'NO LINKED LOCAL', + ), + ), + overflow: TextOverflow.ellipsis, + maxLines: 1, + style: FlutterFlowTheme.of(context).labelMedium.override( + fontFamily: 'Nunito', + color: FlutterFlowTheme.of(context).info, + fontSize: limitedFontSize, + letterSpacing: 0.0, + fontWeight: FontWeight.w500, + useGoogleFonts: GoogleFonts.asMap().containsKey('Nunito'), + ), + ), + ), + ), + ] + .divide(const SizedBox(width: 20.0)) + .addToStart(const SizedBox(width: 20.0)) + .addToEnd(const SizedBox(width: 20.0)), ), ), - ] - .divide(const SizedBox(width: 20.0)) - .addToStart(const SizedBox(width: 20.0)) - .addToEnd(const SizedBox(width: 20.0)), + ), ), - ), - ), + ); + }, ), ); } diff --git a/lib/components/organism_components/menu_component/menu_component_bloc.dart b/lib/components/organism_components/menu_component/menu_component_bloc.dart new file mode 100644 index 00000000..b5f7876e --- /dev/null +++ b/lib/components/organism_components/menu_component/menu_component_bloc.dart @@ -0,0 +1,103 @@ +import 'dart:developer'; +import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.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/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/helpers/license/license_helper.dart'; + +class MenuEvent {} + +class MenuState { + final List menuEntries; + final bool isGrid; + + MenuState({this.menuEntries = const [], this.isGrid = false}); + + MenuState copyWith({List? menuEntries, bool? isGrid}) { + return MenuState( + menuEntries: menuEntries ?? this.menuEntries, + isGrid: isGrid ?? this.isGrid, + ); + } +} + +class MenuBloc extends Bloc { + final MenuView style; + final MenuItem item; + final bool expandable; + final List menuOptions; + + MenuBloc({required this.style, required this.item, required this.expandable, required this.menuOptions}) : super(MenuState()) { + on((event, emit) async { + final entries = await generateMenuEntries(); + emit(state.copyWith(menuEntries: entries)); + }); + } + + Future> generateMenuEntries() async { + List entries = []; + Future addMenuEntry(IconData icon, String text, Function() action) async { + entries.add( + item == MenuItem.button + ? MenuButtonWidget(icon: icon, action: action, title: text) + : item == MenuItem.card + ? MenuCardItem(icon: icon, action: action, title: text) + : item == MenuItem.tile + ? MenuCardItem(icon: icon, action: action, title: text) + : null, + ); + return null; + } + + for (var opt in menuOptions) { + String? v = await LicenseHelper().g(opt.value); + log('Module: ${opt.value} - License: $v'); + switch (v) { + case 'VISIVEL': + await addMenuEntry(opt.icon, opt.name, () async { + await nav(opt.route); + }); + continue; + case 'DESABILITADO': + await addMenuEntry(opt.icon, opt.name, () async { + await DialogUnavailable.unavailableFeature(key.currentContext!); + }); + continue; + case 'INVISIVEL': + continue; + default: + continue; + } + } + + return entries; + } + + Future nav(String link) async { + log('Opening: $link'); + key.currentContext!.push(link, extra: { + kTransitionInfoKey: const TransitionInfo( + hasTransition: false, + transitionType: PageTransitionType.scale, + alignment: Alignment.bottomCenter, + ), + }); + } + + Future logout() async { + // Implement logout logic here + } + + Future settings() async { + // Implement settings navigation logic here + } + + Future about() async { + // Implement about navigation logic here + } +} diff --git a/lib/components/organism_components/menu_component/menu_component_model.dart b/lib/components/organism_components/menu_component/menu_component_model.dart deleted file mode 100644 index 2f3f66c9..00000000 --- a/lib/components/organism_components/menu_component/menu_component_model.dart +++ /dev/null @@ -1,175 +0,0 @@ -import 'dart:developer'; - -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/helpers/license/license_helper.dart'; -import 'package:hub/shared/helpers/storage/base_storage.dart'; -import 'package:hub/shared/helpers/storage/storage_helper.dart'; -import 'package:hub/shared/services/authentication/authentication_service.dart'; -import 'package:material_symbols_icons/symbols.dart'; - -import '/components/organism_components/menu_list_view_component/menu_list_view_component_widget.dart'; -import 'menu_component_widget.dart' show MenuComponentWidget; - -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; - List menuEntries = []; - - @override - void initState(BuildContext context) { - menuListViewComponentModel = - createModel(context, () => MenuListViewComponentModel()); - menuStaggeredViewComponentModel = - createModel(context, () => MenuStaggeredViewComponentModel()); - } - - @override - void dispose() { - menuListViewComponentModel.dispose(); - menuStaggeredViewComponentModel.dispose(); - } - - Future> generateMenuEntries( - BuildContext context, MenuItem item, List options) async { - List entries = []; - Future addMenuEntry( - IconData icon, String text, Function() action) async { - entries.add( - item == MenuItem.button - ? MenuButtonWidget( - icon: icon, - action: action, - title: text, - safeSetState: safeSetState) - : item == MenuItem.card - ? MenuCardItem( - icon: icon, - action: action, - title: text, - safeSetState: safeSetState) - : item == MenuItem.tile - ? MenuCardItem( - icon: icon, - action: action, - title: text, - safeSetState: safeSetState) - : null, - ); - return null; - } - - for (var opt in options) { - String? v = await LicenseHelper().g(opt.value); - log('Module: ${opt.value} - License: $v'); - switch (v) { - case 'VISIVEL': - await addMenuEntry(opt.icon, opt.name, () async { - await open(context, opt.route); - }); - break; - case 'BLOQUEADO': - await addMenuEntry(opt.icon, opt.name, () async { - await DialogUnavailable.unavailableFeature(context); - }); - break; - case 'INVISIVEL': - break; - default: - break; - } - safeSetState(); - } - - return entries; - } - - Future open(BuildContext context, String link) async { - context.push( - link, - extra: { - kTransitionInfoKey: const TransitionInfo( - hasTransition: false, - transitionType: PageTransitionType.scale, - alignment: Alignment.bottomCenter, - ), - }, - ); - } - - 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 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 settings(BuildContext context) async { - context.push( - '/preferencesSettings', - extra: { - kTransitionInfoKey: const TransitionInfo( - hasTransition: false, - transitionType: PageTransitionType.scale, - alignment: Alignment.bottomCenter, - ), - }, - ); - } - - Future about(BuildContext context) async { - context.push( - '/aboutProperty', - extra: { - kTransitionInfoKey: const TransitionInfo( - hasTransition: false, - transitionType: PageTransitionType.scale, - alignment: Alignment.bottomCenter, - ), - }, - ); - } -} 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 a687ba3f..6277c62a 100644 --- a/lib/components/organism_components/menu_component/menu_component_widget.dart +++ b/lib/components/organism_components/menu_component/menu_component_widget.dart @@ -1,78 +1,80 @@ +import 'package:hub/components/organism_components/menu_list_view_component/menu_list_view_component_widget.dart'; +import 'package:hub/flutter_flow/nav/nav.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; import 'package:hub/backend/schema/enums/enums.dart'; +import 'package:hub/components/organism_components/menu_component/menu_component_bloc.dart'; +import 'package:hub/components/organism_components/menu_staggered_view_component/menu_staggered_view_component_widget.dart'; +import 'package:hub/flutter_flow/flutter_flow_theme.dart'; +import 'package:hub/shared/helpers/license/license_helper.dart'; +import 'package:hub/shared/services/license/license_service.dart'; -import '/components/organism_components/menu_list_view_component/menu_list_view_component_widget.dart'; -import '/components/organism_components/menu_staggered_view_component/menu_staggered_view_component_widget.dart'; -import '/flutter_flow/flutter_flow_util.dart'; -import 'menu_component_model.dart'; +class MenuComponentWidget extends StatelessWidget { + final MenuView style; + final MenuItem item; + final bool expandable; + final List menuOptions; -export 'menu_component_model.dart'; - -class MenuComponentWidget extends StatefulWidget { - final MenuComponentModel model; - const MenuComponentWidget({super.key, required this.model}); - - @override - State createState() => _MenuComponentWidgetState(); -} - -class _MenuComponentWidgetState extends State { - @override - void setState(VoidCallback callback) { - super.setState(callback); - widget.model.onUpdate(); - } - - @override - void initState() { - super.initState(); - widget.model.safeSetState = () => safeSetState(() {}); - } - - @override - void didChangeDependencies() async { - super.didChangeDependencies(); - widget.model.menuEntries = await widget.model.generateMenuEntries( - context, widget.model.item, widget.model.menuOptions); - } - - @override - void dispose() { - widget.model.maybeDispose(); - super.dispose(); - } + const MenuComponentWidget({ + super.key, + required this.style, + required this.item, + required this.expandable, + required this.menuOptions, + }); @override Widget build(BuildContext context) { - return Builder( - builder: (context) { - if (widget.model.style == MenuView.list_grid) - return wrapWithModel( - 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, + return StreamBuilder>( + stream: LicenseService().licenseStream, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const Center( + child: CircularProgressIndicator(), + ); + } else if (snapshot.hasError) { + return Center( + child: Text('Error: ${snapshot.error}'), + ); + } else if (!snapshot.hasData || snapshot.data!.isEmpty) { + return Center( + child: Padding( + padding: EdgeInsets.only(top: MediaQuery.of(context).size.height / 10), + child: CircularProgressIndicator( + backgroundColor: FlutterFlowTheme.of(key.currentContext!).primaryBackground, + color: FlutterFlowTheme.of(key.currentContext!).primary), ), ); - if (widget.model.style == MenuView.list) - return wrapWithModel( - model: widget.model.menuListViewComponentModel, - updateCallback: () => setState(() {}), - updateOnChange: true, - child: MenuListViewComponentWidget( - options: widget.model.menuEntries, - expandable: widget.model.expandable, - item: widget.model.item, - changeMenuStyle: () async {}, - ), - ); - - return const SizedBox(); + } + return BlocProvider( + create: (context) => MenuBloc( + style: style, + item: item, + expandable: expandable, + menuOptions: menuOptions, + )..add(MenuEvent()), + child: BlocBuilder( + builder: (context, state) { + if (style == MenuView.list_grid) { + return MenuStaggeredViewComponentWidget( + options: state.menuEntries, + expandable: expandable, + item: item, + changeMenuStyle: () async {}, + isGrid: state.isGrid, + ); + } else if (style == MenuView.list) { + return MenuListViewComponentWidget( + options: state.menuEntries, + expandable: expandable, + item: item, + changeMenuStyle: () async {}, + ); + } + return const SizedBox(); + }, + ), + ); }, ); } diff --git a/lib/components/organism_components/up_arrow_linked_locals_component/up_arrow_linked_locals_component_model.dart b/lib/components/organism_components/up_arrow_linked_locals_component/up_arrow_linked_locals_component_model.dart index 67f2947d..746a34fe 100644 --- a/lib/components/organism_components/up_arrow_linked_locals_component/up_arrow_linked_locals_component_model.dart +++ b/lib/components/organism_components/up_arrow_linked_locals_component/up_arrow_linked_locals_component_model.dart @@ -4,7 +4,6 @@ import 'package:hub/flutter_flow/flutter_flow_model.dart'; import 'package:hub/shared/helpers/storage/base_storage.dart'; import 'package:hub/shared/helpers/storage/storage_helper.dart'; - class UpArrowLinkedLocalsComponentModel extends FlutterFlowModel { late final String devUUID; late final String userUUID; diff --git a/lib/components/templates_components/access_notification_modal_template_component/access_notification_modal_template_component_model.dart b/lib/components/templates_components/access_notification_modal_template_component/access_notification_modal_template_component_model.dart index d28b326c..114242ef 100644 --- a/lib/components/templates_components/access_notification_modal_template_component/access_notification_modal_template_component_model.dart +++ b/lib/components/templates_components/access_notification_modal_template_component/access_notification_modal_template_component_model.dart @@ -3,7 +3,6 @@ import 'package:hub/flutter_flow/nav/nav.dart'; import 'package:hub/shared/helpers/storage/base_storage.dart'; import 'package:hub/shared/helpers/storage/storage_helper.dart'; - import '/backend/api_requests/api_calls.dart'; import '/flutter_flow/flutter_flow_util.dart'; import 'access_notification_modal_template_component_widget.dart' show AccessNotificationModalTemplateComponentWidget; diff --git a/lib/components/templates_components/change_passs_qr_code_pass_key_template_component/change_pass_widget.dart b/lib/components/templates_components/change_passs_qr_code_pass_key_template_component/change_pass_widget.dart index d79132e3..0e52975f 100644 --- a/lib/components/templates_components/change_passs_qr_code_pass_key_template_component/change_pass_widget.dart +++ b/lib/components/templates_components/change_passs_qr_code_pass_key_template_component/change_pass_widget.dart @@ -6,7 +6,6 @@ import 'package:hub/flutter_flow/nav/nav.dart'; import 'package:hub/shared/helpers/storage/base_storage.dart'; import 'package:hub/shared/helpers/storage/storage_helper.dart'; - import '/flutter_flow/flutter_flow_theme.dart'; import '/flutter_flow/flutter_flow_util.dart'; import '/flutter_flow/flutter_flow_widgets.dart'; diff --git a/lib/components/templates_components/provisional_schedule_template/provisional_schedule_template_model.dart b/lib/components/templates_components/provisional_schedule_template/provisional_schedule_template_model.dart index 7a214573..b57237ad 100644 --- a/lib/components/templates_components/provisional_schedule_template/provisional_schedule_template_model.dart +++ b/lib/components/templates_components/provisional_schedule_template/provisional_schedule_template_model.dart @@ -7,7 +7,6 @@ import 'package:hub/flutter_flow/flutter_flow_util.dart'; import 'package:hub/shared/helpers/storage/base_storage.dart'; import 'package:hub/shared/helpers/storage/storage_helper.dart'; - class ScheduleProvisionalVisitPageModel extends FlutterFlowModel { String cliUUID = ''; String devUUID = ''; diff --git a/lib/components/templates_components/view_visit_detail/view_visit_detail_model.dart b/lib/components/templates_components/view_visit_detail/view_visit_detail_model.dart index 2a2aa5e6..58ea89e5 100644 --- a/lib/components/templates_components/view_visit_detail/view_visit_detail_model.dart +++ b/lib/components/templates_components/view_visit_detail/view_visit_detail_model.dart @@ -2,7 +2,6 @@ import 'package:flutter/material.dart'; import 'package:hub/shared/helpers/storage/base_storage.dart'; import 'package:hub/shared/helpers/storage/storage_helper.dart'; - import '/backend/api_requests/api_calls.dart'; import '/flutter_flow/flutter_flow_util.dart'; import 'view_visit_detail_widget.dart' show ViewVisitDetailWidget; diff --git a/lib/components/templates_components/visitor_search_modal_template_component/visitor_search_modal_template_component_model.dart b/lib/components/templates_components/visitor_search_modal_template_component/visitor_search_modal_template_component_model.dart index ff8624ea..ab8f9fc4 100644 --- a/lib/components/templates_components/visitor_search_modal_template_component/visitor_search_modal_template_component_model.dart +++ b/lib/components/templates_components/visitor_search_modal_template_component/visitor_search_modal_template_component_model.dart @@ -5,7 +5,6 @@ import 'package:hub/flutter_flow/flutter_flow_model.dart'; import 'package:hub/shared/helpers/storage/base_storage.dart'; import 'package:hub/shared/helpers/storage/storage_helper.dart'; - class VisitorSearchModalTemplateComponentModel extends FlutterFlowModel { late final String devUUID; late final String userUUID; diff --git a/lib/flutter_flow/nav/nav.dart b/lib/flutter_flow/nav/nav.dart index 6ff6dd73..112dfc6c 100644 --- a/lib/flutter_flow/nav/nav.dart +++ b/lib/flutter_flow/nav/nav.dart @@ -11,7 +11,7 @@ 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/home_page/home_page.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'; @@ -24,6 +24,7 @@ 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/residents_on_the_property/residents_on_the_property_screen.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'; @@ -84,25 +85,13 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { builder: (context, _) { return FutureBuilder( future: () async { - final bool isLogged = - await StorageHelper().g(SecureStorageKey.isLogged.value) == - 'true'; - final bool haveLocal = - await StorageHelper().g(SecureStorageKey.haveLocal.value) == - 'true'; - final bool haveUserUUID = - (await StorageHelper().g(KeychainStorageKey.userUUID.value)) - ?.isNotEmpty ?? - false; - final bool haveDevUUID = - (await StorageHelper().g(KeychainStorageKey.devUUID.value)) - ?.isNotEmpty ?? - false; + final bool isLogged = await StorageHelper().g(SecureStorageKey.isLogged.value) == 'true'; + final bool haveLocal = await StorageHelper().g(SecureStorageKey.haveLocal.value) == 'true'; + final bool haveUserUUID = (await StorageHelper().g(KeychainStorageKey.userUUID.value))?.isNotEmpty ?? false; + final bool haveDevUUID = (await StorageHelper().g(KeychainStorageKey.devUUID.value))?.isNotEmpty ?? false; if (isLogged && haveDevUUID && haveUserUUID) { - return haveLocal - ? const HomePageWidget() - : const ReceptionPageWidget(); + return haveLocal ? const HomePageWidget() : const ReceptionPageWidget(); } else { return const WelcomePageWidget(); } @@ -124,10 +113,8 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { name: 'forgotPassword', path: '/forgotPassword', builder: (context, params) { - late final String email = - params.getParam('email', ParamType.String); - late final String token = - params.getParam('token', ParamType.String); + late final String email = params.getParam('email', ParamType.String); + late final String token = params.getParam('token', ParamType.String); return ForgotPasswordScreen( key: UniqueKey(), @@ -135,100 +122,32 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { token: token, ); }), - FFRoute( - name: 'homePage', - path: '/homePage', - builder: (context, params) => HomePageWidget(key: UniqueKey())), - FFRoute( - name: 'petsOnThePropertyPage', - path: '/petsOnThePropertyPage', - builder: (context, params) => - Scaffold(body: const PetsHistoryScreen(isApp: true))), - FFRoute( - name: 'vehiclesOnThePropertyPage', - path: '/vehiclesOnThePropertyPage', - builder: (context, params) => const VehicleOnTheProperty()), - FFRoute( - name: 'receptionPage', - path: '/receptionPage', - builder: (context, params) => const ReceptionPageWidget()), - 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: 'homePage', path: '/homePage', builder: (context, params) => HomePageWidget(key: UniqueKey())), + FFRoute(name: 'petsOnThePropertyPage', path: '/petsOnThePropertyPage', builder: (context, params) => Scaffold(body: const PetsHistoryScreen(isApp: true))), + FFRoute(name: 'vehiclesOnThePropertyPage', path: '/vehiclesOnThePropertyPage', builder: (context, params) => const VehicleOnTheProperty()), + FFRoute(name: 'receptionPage', path: '/receptionPage', builder: (context, params) => const ReceptionPageWidget()), + 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: 'residentsOnThePropertyPage', path: '/residentsOnThePropertyPage', builder: (context, params) => ResidentsOnTheProperty()), + 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()), + 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', @@ -244,9 +163,7 @@ GoRouter createRouter(AppStateNotifier appStateNotifier) { extension NavParamExtensions on Map { Map get withoutNulls => Map.fromEntries( - entries - .where((e) => e.value != null) - .map((e) => MapEntry(e.key, e.value!)), + entries.where((e) => e.value != null).map((e) => MapEntry(e.key, e.value!)), ); } @@ -260,23 +177,18 @@ extension NavigationExtensions on BuildContext { } extension _GoRouterStateExtensions on GoRouterState { - Map get extraMap => - extra != null ? extra as Map : {}; + Map get extraMap => extra != null ? extra as Map : {}; Map get allParams => {} ..addAll(pathParameters) ..addAll(uri.queryParameters) ..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(); } } @@ -288,18 +200,13 @@ class FFParameters { final Map Function(String)> asyncParams; Map futureParamValues = {}; - bool get isEmpty => - state.allParams.isEmpty || - (state.allParams.length == 1 && - state.extraMap.containsKey(kTransitionInfoKey)); - bool isAsyncParam(MapEntry param) => - asyncParams.containsKey(param.key) && param.value is String; + 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; @@ -309,15 +216,12 @@ class FFParameters { ), ).onError((_, __) => [false]).then((v) => v.every((e) => e)); - dynamic getParam(String paramName, ParamType type, - {bool isList = false, StructBuilder? structBuilder}) { - if (futureParamValues.containsKey(paramName)) - return futureParamValues[paramName]; + dynamic getParam(String paramName, ParamType type, {bool isList = false, StructBuilder? structBuilder}) { + if (futureParamValues.containsKey(paramName)) return futureParamValues[paramName]; if (!state.allParams.containsKey(paramName)) return null; final param = state.allParams[paramName]; if (param is! String) return param; - return deserializeParam(param, type, isList, - structBuilder: structBuilder); + return deserializeParam(param, type, isList, structBuilder: structBuilder); } } @@ -357,16 +261,13 @@ class FFRoute { key: state.pageKey, child: child, transitionDuration: transitionInfo.duration, - transitionsBuilder: - (context, animation, secondaryAnimation, child) => - PageTransition( + transitionsBuilder: (context, animation, secondaryAnimation, child) => PageTransition( type: transitionInfo.transitionType, duration: transitionInfo.duration, reverseDuration: transitionInfo.duration, alignment: transitionInfo.alignment, child: child, - ).buildTransitions( - context, animation, secondaryAnimation, child), + ).buildTransitions(context, animation, secondaryAnimation, child), ) : MaterialPage(key: state.pageKey, child: child); }, @@ -387,8 +288,7 @@ class TransitionInfo { final Duration duration; final Alignment? alignment; - static TransitionInfo appDefault() => - const TransitionInfo(hasTransition: false); + static TransitionInfo appDefault() => const TransitionInfo(hasTransition: false); } class RootPageContext { @@ -400,11 +300,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/index.dart b/lib/index.dart index 73ea1557..bfe5bac8 100644 --- a/lib/index.dart +++ b/lib/index.dart @@ -1,12 +1,11 @@ export 'pages/acess_history_page/acess_history_page_widget.dart' show AccessHistoryScreen; -export 'pages/home_page/home_page_widget.dart' show HomePageWidget; +export 'pages/home_page/home_page.dart' show HomePageWidget; export 'pages/liberation_history/liberation_history_widget.dart' show LiberationHistoryWidget; -export 'pages/people_on_the_property_page/people_on_the_property_page_widget.dart' show PeopleOnThePropertyPageWidget; +export 'pages/people_on_the_property_page/people_on_the_property_page_widget.dart' show PeopleOnThePropertyPage; export 'pages/preferences_settings_page/preferences_settings_widget.dart' show PreferencesPageWidget; export 'pages/qr_code_page/qr_code_page_widget.dart' show QrCodePageWidget; export 'pages/register_visitor_page/register_visitor_page_widget.dart' show RegisterVisitorPageWidget; -export 'pages/schedule_complete_visit_page/schedule_complete_visit_page_widget.dart' - show ScheduleCompleteVisitPageWidget; +export 'pages/schedule_complete_visit_page/schedule_complete_visit_page_widget.dart' show ScheduleCompleteVisitPageWidget; export 'pages/sign_in_page/sign_in_page_widget.dart' show SignInPageWidget; export 'pages/sign_up_page/sign_up_page_widget.dart' show SignUpPageWidget; export 'pages/welcome_page/welcome_page_widget.dart' show WelcomePageWidget; diff --git a/lib/main.dart b/lib/main.dart index 16354664..ba520190 100644 --- a/lib/main.dart +++ b/lib/main.dart @@ -62,8 +62,7 @@ class App extends StatefulWidget { @override State createState() => _AppState(); - static _AppState of(BuildContext context) => - context.findAncestorStateOfType<_AppState>()!; + static _AppState of(BuildContext context) => context.findAncestorStateOfType<_AppState>()!; } class _AppState extends State with WidgetsBindingObserver { @@ -105,8 +104,7 @@ class _AppState extends State with WidgetsBindingObserver { }), ), ); - final Iterable>? localizationsDelegates = - const [ + final Iterable>? localizationsDelegates = const [ FFLocalizationsDelegate(), GlobalMaterialLocalizations.delegate, GlobalWidgetsLocalizations.delegate, @@ -148,8 +146,7 @@ class _AppState extends State with WidgetsBindingObserver { await StorageHelper().s(SecureStorageKey.haveLocal.value, true); log('onMessageOpenedApp'); } else { - onMessageReceived(message.data, message.notification!.body, - message.data['click_action']); + onMessageReceived(message.data, message.notification!.body, message.data['click_action']); } }); FirebaseMessaging.instance.getInitialMessage().then((message) async { diff --git a/lib/pages/about_property_page/about_property_model.dart b/lib/pages/about_property_page/about_property_model.dart index df559059..aefdc762 100644 --- a/lib/pages/about_property_page/about_property_model.dart +++ b/lib/pages/about_property_page/about_property_model.dart @@ -1,40 +1,20 @@ 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'; -import 'package:hub/shared/helpers/license/license_helper.dart'; class AboutPropertyModel extends FlutterFlowModel { dynamic item; VoidCallback? safeSetState; - 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: [ - Module.pets, - Module.residents, - Module.openedVisits, - Module.vehicles, - Module.orders, - ])); - initAsync(); } diff --git a/lib/pages/about_property_page/about_property_screen.dart b/lib/pages/about_property_page/about_property_screen.dart index 9a80615a..f36f7e97 100644 --- a/lib/pages/about_property_page/about_property_screen.dart +++ b/lib/pages/about_property_page/about_property_screen.dart @@ -1,5 +1,6 @@ // ignore: must_be_immutable import 'package:flutter/material.dart'; +import 'package:hub/backend/schema/enums/enums.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'; @@ -7,6 +8,31 @@ 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'; +import 'package:hub/shared/helpers/license/license_helper.dart'; + +enum AboutPropertyModules { + residents, + vehicles, + openedVisits, + petsHistory, +} + +extension AboutPropertyModulesExtension on AboutPropertyModules { + String get value { + switch (this) { + case AboutPropertyModules.openedVisits: + return 'FRE-HUB-OPENED-VISITS'; + case AboutPropertyModules.vehicles: + return 'FRE-HUB-VEHICLES'; + case AboutPropertyModules.residents: + return 'FRE-HUB-RESIDENTS'; + case AboutPropertyModules.petsHistory: + return 'FRE-HUB-PETS-HISTORY'; + default: + return ''; + } + } +} // ignore: must_be_immutable class AboutPropertyPage extends StatefulWidget { @@ -43,15 +69,11 @@ class _AboutPropertyPageState extends State with SingleTicker @override Widget build(BuildContext context) { - return Scaffold( - appBar: _buildAppBar(context), - backgroundColor: FlutterFlowTheme.of(context).primaryBackground, - body: _buildBody(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"); + final String title = FFLocalizations.of(context).getVariableText(ptText: "Sobre a Propriedade", enText: "About the Property"); return AppBarUtil( title: title, onBackButtonPressed: () => context.pop(), @@ -62,14 +84,13 @@ class _AboutPropertyPageState extends State with SingleTicker return SingleChildScrollView( child: 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), - ), - ), + child: MenuComponentWidget(expandable: true, style: MenuView.list_grid, item: MenuItem.button, menuOptions: [ + Module.pets, + Module.residents, + Module.openedVisits, + Module.vehicles, + Module.orders, + ]), ), ); } diff --git a/lib/pages/acess_history_page/acess_history_page_model.dart b/lib/pages/acess_history_page/acess_history_page_model.dart index 3bd7ff88..98a33bf6 100644 --- a/lib/pages/acess_history_page/acess_history_page_model.dart +++ b/lib/pages/acess_history_page/acess_history_page_model.dart @@ -7,7 +7,6 @@ import 'package:hub/pages/acess_history_page/acess_history_page_widget.dart'; import 'package:hub/shared/helpers/storage/base_storage.dart'; import 'package:hub/shared/helpers/storage/storage_helper.dart'; - class AcessHistoryPageModel extends FlutterFlowModel { late final String devUUID; late final String userUUID; diff --git a/lib/pages/home_page/home_bloc.dart b/lib/pages/home_page/home_bloc.dart new file mode 100644 index 00000000..b92d32b3 --- /dev/null +++ b/lib/pages/home_page/home_bloc.dart @@ -0,0 +1,25 @@ +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:hub/shared/helpers/storage/base_storage.dart'; +import 'package:hub/shared/helpers/storage/storage_helper.dart'; + +import 'index.dart'; + +class HomeBloc extends Bloc { + HomeBloc() : super(HomeState()) { + on((event, emit) async { + final devUUID = (await StorageHelper().g(KeychainStorageKey.devUUID.value)) ?? ''; + final userUUID = (await StorageHelper().g(KeychainStorageKey.userUUID.value)) ?? ''; + final cliUUID = (await StorageHelper().g(KeychainStorageKey.clientUUID.value)) ?? ''; + final userName = (await StorageHelper().g(KeychainStorageKey.userName.value)) ?? ''; + final userEmail = (await StorageHelper().g(SecureStorageKey.email.value)) ?? ''; + + emit(state.copyWith( + devUUID: devUUID, + userUUID: userUUID, + cliUUID: cliUUID, + userName: userName, + userEmail: userEmail, + )); + }); + } +} diff --git a/lib/pages/home_page/home_events.dart b/lib/pages/home_page/home_events.dart new file mode 100644 index 00000000..bb0442c1 --- /dev/null +++ b/lib/pages/home_page/home_events.dart @@ -0,0 +1 @@ +class HomeEvent {} diff --git a/lib/pages/home_page/home_page_widget.dart b/lib/pages/home_page/home_page.dart similarity index 69% rename from lib/pages/home_page/home_page_widget.dart rename to lib/pages/home_page/home_page.dart index 02deb34a..24516974 100644 --- a/lib/pages/home_page/home_page_widget.dart +++ b/lib/pages/home_page/home_page.dart @@ -1,15 +1,18 @@ import 'package:flutter/gestures.dart'; import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; +import 'package:flutter_bloc/flutter_bloc.dart'; +import 'package:hub/backend/schema/enums/enums.dart'; import 'package:hub/components/organism_components/local_profile_component/local_profile_component_widget.dart'; import 'package:hub/components/organism_components/menu_component/menu_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/home_page/home_page_model.dart'; -import 'package:hub/shared/helpers/storage/storage_helper.dart'; +import 'package:hub/shared/helpers/license/license_helper.dart'; import 'package:hub/shared/widgets/drawer_widget/drawer_widget.dart'; +import 'index.dart'; + class HomePageWidget extends StatefulWidget { const HomePageWidget({super.key}); @@ -18,43 +21,21 @@ class HomePageWidget extends StatefulWidget { } class _HomePageWidgetState extends State { - late HomePageModel _model; final scaffoldKey = GlobalKey(); - late LocalProfileComponentWidget _localProfileComponentWidget; - - _HomePageWidgetState() { - _localProfileComponentWidget = LocalProfileComponentWidget(); - } - - @override - void dispose() { - super.dispose(); - _model.dispose(); - } - - @override - void initState() { - super.initState(); - - _model = createModel(context, () => HomePageModel(safeSetState: () => safeSetState(() {}))); - - _model.textController ??= TextEditingController(); - _model.textFieldFocusNode ??= FocusNode(); - } - @override Widget build(BuildContext context) { - StorageHelper().context = context; - return Scaffold( - key: scaffoldKey, - backgroundColor: FlutterFlowTheme.of(context).primaryBackground, - // drawer: buildDrawer(context), - drawerEnableOpenDragGesture: true, - drawerDragStartBehavior: DragStartBehavior.start, - drawer: CustomDrawer(model: _model), - appBar: buildAppBar(context), - body: buildPage(context), + return BlocProvider( + create: (context) => HomeBloc()..add(HomeEvent()), + child: Scaffold( + key: scaffoldKey, + backgroundColor: FlutterFlowTheme.of(context).primaryBackground, + drawerEnableOpenDragGesture: true, + drawerDragStartBehavior: DragStartBehavior.start, + drawer: CustomDrawer(), + appBar: buildAppBar(context), + body: buildPage(context), + ), ); } @@ -139,25 +120,19 @@ class _HomePageWidgetState extends State { Widget buildBody() { return Container( color: FlutterFlowTheme.of(context).primaryBackground, - child: wrapWithModel( - model: _model.homeMenuComponentModel, - updateOnChange: true, - updateCallback: () => setState(() {}), - child: Padding( - padding: const EdgeInsets.only(bottom: 40), - child: MenuComponentWidget( - model: _model.homeMenuComponentModel, - ), + child: Padding( + padding: const EdgeInsets.only(bottom: 40), + child: MenuComponentWidget( + expandable: true, + style: MenuView.list_grid, + item: MenuItem.button, + menuOptions: Module.values.where((e) => e != Module.logout).toList(), ), ), ); } Widget buildLocal() { - return wrapWithModel( - model: _model.localComponentModel, - updateCallback: () => safeSetState(() {}), - child: _localProfileComponentWidget, - ); + return LocalProfileComponentWidget(); } } diff --git a/lib/pages/home_page/home_page_model.dart b/lib/pages/home_page/home_page_model.dart deleted file mode 100644 index e68faf34..00000000 --- a/lib/pages/home_page/home_page_model.dart +++ /dev/null @@ -1,105 +0,0 @@ -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'; -import 'package:hub/flutter_flow/flutter_flow_model.dart'; -import 'package:hub/pages/home_page/home_page_widget.dart'; -import 'package:hub/shared/helpers/license/license_helper.dart'; -import 'package:hub/shared/helpers/storage/base_storage.dart'; -import 'package:hub/shared/helpers/storage/storage_helper.dart'; - -class HomePageModel extends FlutterFlowModel { - HomePageModel({required this.safeSetState}); - late final VoidCallback safeSetState; - - bool isGrid = false; - late final String devUUID; - late final String cliUUID; - late final String userUUID; - late final String userName; - late final String userEmail; - - final unfocusNode = FocusNode(); - FocusNode? textFieldFocusNode; - TextEditingController? textController; - String? Function(BuildContext, String?)? textControllerValidator; - late LocalProfileComponentModel localComponentModel; - late MenuComponentModel homeMenuComponentModel; - late MenuComponentModel drawerMenuComponentModel; - late MessageWellComponentModel messageWellComponentModel; - - Future _initVariable() async { - devUUID = (await StorageHelper().g(KeychainStorageKey.devUUID.value)) ?? ''; - userUUID = - (await StorageHelper().g(KeychainStorageKey.userUUID.value)) ?? ''; - cliUUID = - (await StorageHelper().g(KeychainStorageKey.clientUUID.value)) ?? ''; - userName = - (await StorageHelper().g(KeychainStorageKey.userName.value)) ?? ''; - userEmail = (await StorageHelper().g(SecureStorageKey.email.value)) ?? ''; - } - - @override - void initState(BuildContext context) { - _initVariable(); - localComponentModel = - createModel(context, () => LocalProfileComponentModel()); - homeMenuComponentModel = createModel( - context, - () => MenuComponentModel( - expandable: true, - style: MenuView.list_grid, - item: MenuItem.button, - menuOptions: [ - Module.messages, - Module.access, - Module.pets, - Module.openedVisits, - Module.reservations, - Module.orders, - Module.providerSchedule, - Module.deliverySchedule, - Module.completeSchedule, - Module.fastPass, - Module.liberations, - Module.qrCode, - Module.settings, - ])); - drawerMenuComponentModel = createModel( - context, - () => MenuComponentModel( - expandable: false, - style: MenuView.list, - item: MenuItem.tile, - menuOptions: [ - Module.messages, - Module.access, - Module.pets, - Module.openedVisits, - Module.reservations, - Module.orders, - Module.providerSchedule, - Module.deliverySchedule, - Module.completeSchedule, - Module.fastPass, - Module.liberations, - Module.qrCode, - Module.logout, - ])); - messageWellComponentModel = - createModel(context, () => MessageWellComponentModel()); - } - - @override - void dispose() { - unfocusNode.dispose(); - textFieldFocusNode?.dispose(); - textController?.dispose(); - - localComponentModel.dispose(); - homeMenuComponentModel.dispose(); - messageWellComponentModel.dispose(); - } -} diff --git a/lib/pages/home_page/home_state.dart b/lib/pages/home_page/home_state.dart new file mode 100644 index 00000000..b2a0c708 --- /dev/null +++ b/lib/pages/home_page/home_state.dart @@ -0,0 +1,35 @@ +class HomeState { + final bool isGrid; + final String devUUID; + final String cliUUID; + final String userUUID; + final String userName; + final String userEmail; + + HomeState({ + this.isGrid = false, + this.devUUID = '', + this.cliUUID = '', + this.userUUID = '', + this.userName = '', + this.userEmail = '', + }); + + HomeState copyWith({ + bool? isGrid, + String? devUUID, + String? cliUUID, + String? userUUID, + String? userName, + String? userEmail, + }) { + return HomeState( + isGrid: isGrid ?? this.isGrid, + devUUID: devUUID ?? this.devUUID, + cliUUID: cliUUID ?? this.cliUUID, + userUUID: userUUID ?? this.userUUID, + userName: userName ?? this.userName, + userEmail: userEmail ?? this.userEmail, + ); + } +} diff --git a/lib/pages/home_page/index.dart b/lib/pages/home_page/index.dart new file mode 100644 index 00000000..d06783d6 --- /dev/null +++ b/lib/pages/home_page/index.dart @@ -0,0 +1,3 @@ +export 'home_bloc.dart'; +export 'home_events.dart'; +export 'home_state.dart'; diff --git a/lib/pages/liberation_history/liberation_history_model.dart b/lib/pages/liberation_history/liberation_history_model.dart index 9b107572..7c64039a 100644 --- a/lib/pages/liberation_history/liberation_history_model.dart +++ b/lib/pages/liberation_history/liberation_history_model.dart @@ -6,7 +6,6 @@ import 'package:hub/pages/liberation_history/liberation_history_widget.dart'; import 'package:hub/shared/helpers/storage/base_storage.dart'; import 'package:hub/shared/helpers/storage/storage_helper.dart'; - class LiberationHistoryModel extends FlutterFlowModel { late final String devUUID; late final String userUUID; 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 d706d938..de07033f 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 @@ -1,28 +1,14 @@ 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'; -import 'package:hub/shared/helpers/storage/base_storage.dart'; -import 'package:hub/shared/helpers/storage/storage_helper.dart'; - class PeopleOnThePropertyPageModel extends FlutterFlowModel { - PeopleOnThePropertyPageModel({this.onRefresh}); - late final VoidCallback? onRefresh; + /// State fields for stateful widgets in this page. final unfocusNode = FocusNode(); - late final String devUUID; - late final String cliUUID; @override - void initState(BuildContext context) { - initVariables(); - } - - void initVariables() async { - devUUID = (await StorageHelper().g(KeychainStorageKey.devUUID.value)) ?? ''; - cliUUID = (await StorageHelper().g(KeychainStorageKey.clientUUID.value)) ?? ''; - onRefresh?.call(); - } + void initState(BuildContext context) {} @override void dispose() { 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 be16c18d..a1146aeb 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,135 +1,68 @@ +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/limited_text_size.dart'; -import 'package:hub/shared/utils/log_util.dart'; + +import '../../shared/utils/log_util.dart'; class PeopleOnThePropertyPage extends StatefulWidget { const PeopleOnThePropertyPage({super.key}); @override - _PeopleOnThePropertyPageState createState() => _PeopleOnThePropertyPageState(); + State createState() => _PeopleOnThePropertyPageState(); } -class _PeopleOnThePropertyPageState extends State with TickerProviderStateMixin { - late ScrollController _scrollController; +class _PeopleOnThePropertyPageState extends State { + late PeopleOnThePropertyPageModel _model; - int _pageNumber = 1; - bool _hasData = false; - bool _loading = false; - int count = 0; - - late final PeopleOnThePropertyPageModel model; - - late Future _future; - List _wrap = []; + final scaffoldKey = GlobalKey(); @override void initState() { super.initState(); - model = createModel(context, () => PeopleOnThePropertyPageModel(onRefresh: () => safeSetState(() {}))); - _future = _fetchVisits(); - - _scrollController = ScrollController() - ..addListener(() { - if (_scrollController.position.atEdge && _scrollController.position.pixels != 0) { - _loadMore(); - } - }); + _model = createModel(context, () => PeopleOnThePropertyPageModel()); } @override void dispose() { - _scrollController.dispose(); + _model.dispose(); + super.dispose(); } @override Widget build(BuildContext context) { - late final limitedHeaderTextSize = LimitedFontSizeUtil.getHeaderFontSize(context); - return Scaffold( - appBar: _appBar(context), + key: scaffoldKey, 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: "Nenhum morador encontrado!", - enText: "No residents found!", - ), - style: TextStyle( - fontFamily: 'Nunito', - fontSize: limitedHeaderTextSize, - ), - ), - ) - ], - ), - ) - else if (_hasData == true || _pageNumber >= 1) - Expanded( - child: FutureBuilder( - future: _future, - builder: (context, snapshot) { - return ListView.builder( - shrinkWrap: true, - physics: const BouncingScrollPhysics(), - controller: _scrollController, - itemCount: _wrap.length + 1, - itemBuilder: (context, index) { - if (index == 0) { - // Add your item here - return Padding( - padding: const EdgeInsets.only(right: 30, top: 10), - child: Text( - '', - textAlign: TextAlign.right, - ), - ); - } else { - final item = _wrap[index - 1]; - return _item(context, item); - } - }); - }, - )), - if (_hasData == true && _loading == true) - Container( - padding: const EdgeInsets.only(top: 15, bottom: 15), - child: Center( - child: CircularProgressIndicator( - valueColor: AlwaysStoppedAnimation( - FlutterFlowTheme.of(context).primary, - ), - ), - ), - ) - ].addToStart(const SizedBox(height: 0)), - ), - ); - } - - PreferredSizeWidget _appBar(BuildContext context) { - return AppBar( - backgroundColor: FlutterFlowTheme.of(context).primaryBackground, - automaticallyImplyLeading: false, - title: Text(FFLocalizations.of(context).getVariableText(ptText: 'Moradores', enText: 'Residents'), + appBar: AppBar( + 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(); + }, + ), + title: Text( + FFLocalizations.of(context).getText( + 'nsu13r5d' /* Pessoas na Propriedade */, + ), style: FlutterFlowTheme.of(context).headlineMedium.override( fontFamily: 'Nunito', color: FlutterFlowTheme.of(context).primaryText, @@ -137,114 +70,103 @@ class _PeopleOnThePropertyPageState extends State with 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.getResidentsByProperty.call(_pageNumber.toString()); - - final List residents = response.jsonBody['residents'] ?? []; - safeSetState(() => count = response.jsonBody['total_rows'] ?? 0); - - if (residents.isNotEmpty) { - setState(() { - _wrap.addAll(residents); - _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 moradores", e, s); - setState(() { - _hasData = false; - _loading = false; - }); - } - return null; - } - - void _loadMore() { - if (_hasData == true) { - _pageNumber++; - - _future = _fetchVisits(); - } - } - - void _showNoMoreDataSnackBar(BuildContext context) { - ScaffoldMessenger.of(context).showSnackBar( - SnackBar( - content: Text( - FFLocalizations.of(context).getVariableText( - ptText: "Não há mais dados.", - enText: "No more data.", - ), - style: TextStyle( - color: Colors.white, - fontSize: LimitedFontSizeUtil.getBodyFontSize(context), - ), + ), ), - duration: const Duration(seconds: 3), - backgroundColor: FlutterFlowTheme.of(context).primary, + actions: const [], + centerTitle: true, + elevation: 0.0, ), - ); - } - - Widget _item(BuildContext context, dynamic uItem) { - return CardItemTemplateComponentWidget( - imagePath: - 'https://freaccess.com.br/freaccess/getImage.php?devUUID=${model.devUUID}&cliID=${model.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: "Possui App", enText: "Has App")}:': - uItem['statusweb'] == "A" - ? FFLocalizations.of(context).getVariableText( - ptText: 'Sim', - enText: 'Yes', - ) - : FFLocalizations.of(context).getVariableText( - ptText: 'Não', - enText: 'No', + 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, ), - }, - statusHashMap: [], - onTapCardItemAction: () async {}, + ), + ); + } + + 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!); + } + + 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, + ), + ), + ); + } + + final columnGetPessoasLocalResponse = snapshot.data!; + final getPoepleProperty = PhpGroup.getPessoasLocalCall + .pessoas( + columnGetPessoasLocalResponse.jsonBody, + ) + ?.toList() ?? + []; + + 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)), + ); + }, + ); + }, + ), + ), ); } } diff --git a/lib/pages/residents_on_the_property/residents_on_the_property_model.dart b/lib/pages/residents_on_the_property/residents_on_the_property_model.dart new file mode 100644 index 00000000..e5f1f84c --- /dev/null +++ b/lib/pages/residents_on_the_property/residents_on_the_property_model.dart @@ -0,0 +1,30 @@ +import 'package:flutter/material.dart'; +import 'package:hub/flutter_flow/flutter_flow_model.dart'; +import 'package:hub/pages/residents_on_the_property/residents_on_the_property_screen.dart'; +import 'package:hub/shared/helpers/storage/base_storage.dart'; +import 'package:hub/shared/helpers/storage/storage_helper.dart'; + +class ResidentsOnThePropertyModel extends FlutterFlowModel { + ResidentsOnThePropertyModel({this.onRefresh}); + late final VoidCallback? onRefresh; + + final unfocusNode = FocusNode(); + late final String devUUID; + late final String cliUUID; + + @override + void initState(BuildContext context) { + initVariables(); + } + + void initVariables() async { + devUUID = (await StorageHelper().g(KeychainStorageKey.devUUID.value)) ?? ''; + cliUUID = (await StorageHelper().g(KeychainStorageKey.clientUUID.value)) ?? ''; + onRefresh?.call(); + } + + @override + void dispose() { + unfocusNode.dispose(); + } +} diff --git a/lib/pages/residents_on_the_property/residents_on_the_property_screen.dart b/lib/pages/residents_on_the_property/residents_on_the_property_screen.dart new file mode 100644 index 00000000..fb3b4696 --- /dev/null +++ b/lib/pages/residents_on_the_property/residents_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/residents_on_the_property/residents_on_the_property_model.dart'; +import 'package:hub/shared/utils/dialog_util.dart'; +import 'package:hub/shared/utils/limited_text_size.dart'; +import 'package:hub/shared/utils/log_util.dart'; + +class ResidentsOnTheProperty extends StatefulWidget { + const ResidentsOnTheProperty({super.key}); + + @override + _ResidentsOnThePropertyState createState() => _ResidentsOnThePropertyState(); +} + +class _ResidentsOnThePropertyState extends State with TickerProviderStateMixin { + late ScrollController _scrollController; + + int _pageNumber = 1; + bool _hasData = false; + bool _loading = false; + int count = 0; + + late final ResidentsOnThePropertyModel model; + + late Future _future; + List _wrap = []; + + @override + void initState() { + super.initState(); + model = createModel(context, () => ResidentsOnThePropertyModel(onRefresh: () => safeSetState(() {}))); + _future = _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) { + late final limitedHeaderTextSize = LimitedFontSizeUtil.getHeaderFontSize(context); + + return 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: "Nenhum morador encontrado!", + enText: "No residents found!", + ), + style: TextStyle( + fontFamily: 'Nunito', + fontSize: limitedHeaderTextSize, + ), + ), + ) + ], + ), + ) + else if (_hasData == true || _pageNumber >= 1) + Expanded( + child: FutureBuilder( + future: _future, + builder: (context, snapshot) { + return ListView.builder( + shrinkWrap: true, + physics: const BouncingScrollPhysics(), + controller: _scrollController, + itemCount: _wrap.length + 1, + itemBuilder: (context, index) { + if (index == 0) { + // Add your item here + return Padding( + padding: const EdgeInsets.only(right: 30, top: 10), + child: Text( + '', + textAlign: TextAlign.right, + ), + ); + } else { + final item = _wrap[index - 1]; + return _item(context, item); + } + }); + }, + )), + if (_hasData == true && _loading == true) + Container( + padding: const EdgeInsets.only(top: 15, bottom: 15), + child: Center( + child: CircularProgressIndicator( + valueColor: AlwaysStoppedAnimation( + FlutterFlowTheme.of(context).primary, + ), + ), + ), + ) + ].addToStart(const SizedBox(height: 0)), + ), + ); + } + + PreferredSizeWidget _appBar(BuildContext context) { + return AppBar( + backgroundColor: FlutterFlowTheme.of(context).primaryBackground, + automaticallyImplyLeading: false, + title: Text(FFLocalizations.of(context).getVariableText(ptText: 'Moradores', enText: 'Residents'), + 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.getResidentsByProperty.call(_pageNumber.toString()); + + final List residents = response.jsonBody['residents'] ?? []; + safeSetState(() => count = response.jsonBody['total_rows'] ?? 0); + + if (residents.isNotEmpty) { + setState(() { + _wrap.addAll(residents); + _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 moradores", e, s); + setState(() { + _hasData = false; + _loading = false; + }); + } + return null; + } + + void _loadMore() { + if (_hasData == true) { + _pageNumber++; + + _future = _fetchVisits(); + } + } + + void _showNoMoreDataSnackBar(BuildContext context) { + ScaffoldMessenger.of(context).showSnackBar( + SnackBar( + content: Text( + FFLocalizations.of(context).getVariableText( + ptText: "Não há mais dados.", + enText: "No more data.", + ), + style: TextStyle( + color: Colors.white, + fontSize: LimitedFontSizeUtil.getBodyFontSize(context), + ), + ), + duration: const Duration(seconds: 3), + backgroundColor: FlutterFlowTheme.of(context).primary, + ), + ); + } + + Widget _item(BuildContext context, dynamic uItem) { + return CardItemTemplateComponentWidget( + imagePath: 'https://freaccess.com.br/freaccess/getImage.php?devUUID=${model.devUUID}&cliID=${model.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: "Possui App", enText: "Has App")}:': uItem['statusweb'] == "A" + ? FFLocalizations.of(context).getVariableText( + ptText: 'Sim', + enText: 'Yes', + ) + : FFLocalizations.of(context).getVariableText( + ptText: 'Não', + enText: 'No', + ), + }, + statusHashMap: [], + onTapCardItemAction: () async {}, + ); + } +} diff --git a/lib/shared/extensions/string_extensions.dart b/lib/shared/extensions/string_extensions.dart new file mode 100644 index 00000000..0538bb7c --- /dev/null +++ b/lib/shared/extensions/string_extensions.dart @@ -0,0 +1,11 @@ +extension StringNullableExtensions on String? { + bool toBoolean() { + return this!.toLowerCase() == 'true'; + } +} + +extension StringExtensions on String { + bool toBoolean() { + return this.toLowerCase() == 'true'; + } +} diff --git a/lib/shared/helpers/database/database_helper.dart b/lib/shared/helpers/database/database_helper.dart index 0166e34c..1a9d1513 100644 --- a/lib/shared/helpers/database/database_helper.dart +++ b/lib/shared/helpers/database/database_helper.dart @@ -32,7 +32,7 @@ class DatabaseStorage { onUpgrade: _onUpgrade, onDowngrade: _onDowngrade, ); - await LicenseService.setupLicense(database); + await LicenseService().setupLicense(database); isInitialized = true; } @@ -42,14 +42,12 @@ class DatabaseStorage { await database.execute(LicenseHelper.createTableQuery); } - Future _onUpgrade( - Database database, int oldVersion, int newVersion) async { + Future _onUpgrade(Database database, int oldVersion, int newVersion) async { log('Upgrading database from version $oldVersion to $newVersion...'); if (oldVersion < 2) { await database.execute(LicenseHelper.createTableQuery); } } - Future _onDowngrade( - Database database, int oldVersion, int newVersion) async {} + Future _onDowngrade(Database database, int oldVersion, int newVersion) async {} } diff --git a/lib/shared/helpers/license/license_helper.dart b/lib/shared/helpers/license/license_helper.dart index 827954b7..5a1f7dc7 100644 --- a/lib/shared/helpers/license/license_helper.dart +++ b/lib/shared/helpers/license/license_helper.dart @@ -10,6 +10,39 @@ enum InactiveModuleKey { residents, vehicles, openedVisits, + petsHistory, +} + +extension InactiveModuleKeyExtension on InactiveModuleKey { + String get value { + switch (this) { + case InactiveModuleKey.openedVisits: + return 'FRE-HUB-OPENED-VISITS'; + case InactiveModuleKey.vehicles: + return 'FRE-HUB-VEHICLES'; + case InactiveModuleKey.residents: + return 'FRE-HUB-RESIDENTS'; + case InactiveModuleKey.petsHistory: + return 'FRE-HUB-PETS-HISTORY'; + default: + return ''; + } + } +} + +enum DisabledModuleKey { + fastPass, +} + +extension DisabledModuleKeyExtension on DisabledModuleKey { + String get value { + switch (this) { + case DisabledModuleKey.fastPass: + return 'FRE-HUB-FASTPASS'; + default: + return ''; + } + } } enum ActiveModuleKey { @@ -17,27 +50,16 @@ enum ActiveModuleKey { liberations, reservations, access, + pets, orders, completeSchedule, providerSchedule, deliverySchedule, - fastPass, qrCode, -} - -extension InactiveModuleKeyExtension on InactiveModuleKey { - String get value { - switch (this) { - case InactiveModuleKey.residents: - return 'FRE-HUB-RESIDENTS'; - case InactiveModuleKey.vehicles: - return 'FRE-HUB-VEHICLES'; - case InactiveModuleKey.openedVisits: - return 'FRE-HUB-OPENED-VISITS'; - default: - return ''; - } - } + visitors, + peopleOnTheProperty, + settings, + logout, } extension ActiveModuleKeyExtension on ActiveModuleKey { @@ -51,6 +73,8 @@ extension ActiveModuleKeyExtension on ActiveModuleKey { return 'FRE-HUB-RESERVATIONS'; case ActiveModuleKey.access: return 'FRE-HUB-ACCESS'; + case ActiveModuleKey.pets: + return 'FRE-HUB-PETS'; case ActiveModuleKey.orders: return 'FRE-HUB-ORDERS'; case ActiveModuleKey.completeSchedule: @@ -59,10 +83,12 @@ extension ActiveModuleKeyExtension on ActiveModuleKey { return 'FRE-HUB-AGE-PROV-PRESTADOR'; case ActiveModuleKey.deliverySchedule: return 'FRE-HUB-AGE-PROV-DELIVERY'; - case ActiveModuleKey.fastPass: - return 'FRE-HUB-FASTPASS'; + case ActiveModuleKey.visitors: + return 'FRE-HUB-VISITORS'; case ActiveModuleKey.qrCode: return 'FRE-HUB-QRCODE'; + case ActiveModuleKey.peopleOnTheProperty: + return 'FRE-HUB-PEOPLE'; default: return ''; } @@ -70,20 +96,24 @@ extension ActiveModuleKeyExtension on ActiveModuleKey { } enum Module { - messages, - liberations, - reservations, - access, - openedVisits, - vehicles, - residents, - pets, - orders, - completeSchedule, providerSchedule, deliverySchedule, fastPass, + completeSchedule, + orders, + reservations, + visitors, + vehicles, + residents, + openedVisits, qrCode, + pets, + access, + liberations, + messages, + aboutProperty, + petsHistory, + peopleOnTheProperty, settings, logout, } @@ -115,10 +145,18 @@ extension LicenseKeyExtension on Module { return 'FRE-HUB-AGE-PROV-PRESTADOR'; case Module.deliverySchedule: return 'FRE-HUB-AGE-PROV-DELIVERY'; + case Module.aboutProperty: + return 'FRE-HUB-PROPERTY'; case Module.fastPass: return 'FRE-HUB-FASTPASS'; + case Module.visitors: + return 'FRE-HUB-VISITORS'; case Module.qrCode: return 'FRE-HUB-QRCODE'; + case Module.peopleOnTheProperty: + return 'FRE-HUB-PEOPLE'; + case Module.petsHistory: + return 'FRE-HUB-PETS-HISTORY'; default: return ''; } @@ -128,13 +166,13 @@ extension LicenseKeyExtension on Module { switch (this) { case Module.messages: return FFLocalizations.of(key.currentContext!).getVariableText( - ptText: 'Mensagens', - enText: 'Messages', + ptText: 'Consultar Mensagens', + enText: 'Messages History', ); case Module.liberations: return FFLocalizations.of(key.currentContext!).getVariableText( - ptText: 'Liberar', - enText: 'Liberations', + ptText: 'Consultar Liberações', + enText: 'Liberations History', ); case Module.reservations: return FFLocalizations.of(key.currentContext!).getVariableText( @@ -143,12 +181,12 @@ extension LicenseKeyExtension on Module { ); case Module.access: return FFLocalizations.of(key.currentContext!).getVariableText( - ptText: 'Acessos', - enText: 'Access', + ptText: 'Consultar Acessos', + enText: 'Access History', ); case Module.openedVisits: return FFLocalizations.of(key.currentContext!).getVariableText( - ptText: 'Visitas Abertas', + ptText: 'Visitas em Aberto', enText: 'Opened Visits', ); case Module.vehicles: @@ -166,10 +204,20 @@ extension LicenseKeyExtension on Module { ptText: 'Pets', enText: 'Pets', ); + case Module.petsHistory: + return FFLocalizations.of(key.currentContext!).getVariableText( + ptText: 'Pets', + enText: 'Pets', + ); + case Module.peopleOnTheProperty: + return FFLocalizations.of(key.currentContext!).getVariableText( + ptText: 'Pessoas na Propriedade', + enText: 'People on the Property', + ); case Module.orders: return FFLocalizations.of(key.currentContext!).getVariableText( - ptText: 'Encomendas', - enText: 'Orders', + ptText: 'Minhas Encomendas', + enText: 'My Orders', ); case Module.completeSchedule: return FFLocalizations.of(key.currentContext!).getVariableText( @@ -193,8 +241,18 @@ extension LicenseKeyExtension on Module { ); case Module.qrCode: return FFLocalizations.of(key.currentContext!).getVariableText( - ptText: 'QR Code', - enText: 'QR Code', + ptText: 'QRCode de Acesso', + enText: 'Access QRCode', + ); + case Module.visitors: + return FFLocalizations.of(key.currentContext!).getVariableText( + ptText: 'Cadastrar Visitantes', + enText: 'Register Visitors', + ); + case Module.aboutProperty: + return FFLocalizations.of(key.currentContext!).getVariableText( + ptText: 'Sobre a Propriedade', + enText: 'About the Property', ); case Module.settings: return FFLocalizations.of(key.currentContext!).getVariableText( @@ -212,33 +270,41 @@ extension LicenseKeyExtension on Module { IconData get icon { switch (this) { case Module.messages: - return Icons.message; + return Icons.chat_outlined; case Module.liberations: - return Icons.lock_open; + return Icons.how_to_reg_outlined; case Module.reservations: - return Icons.calendar_today; + return Icons.event_available; case Module.access: - return Icons.access_time; + return Icons.transfer_within_a_station_outlined; case Module.openedVisits: - return Icons.people; + return Icons.perm_contact_calendar; case Module.vehicles: return Icons.directions_car; case Module.residents: - return Icons.person; + return Icons.groups; case Module.pets: return Icons.pets; + case Module.petsHistory: + return Icons.pets; + case Module.peopleOnTheProperty: + return Icons.groups; case Module.orders: - return Icons.shopping_cart; + return Icons.inventory_2_outlined; case Module.completeSchedule: - return Icons.schedule; + return Icons.event; case Module.providerSchedule: return Icons.engineering_outlined; case Module.deliverySchedule: - return Icons.delivery_dining; + return Icons.sports_motorsports_outlined; case Module.fastPass: - return Icons.fastfood; + return Icons.attach_email_outlined; case Module.qrCode: return Icons.qr_code; + case Module.visitors: + return Icons.person_add_alt_1_outlined; + case Module.aboutProperty: + return Icons.home; case Module.settings: return Icons.settings; case Module.logout: @@ -257,23 +323,37 @@ extension LicenseKeyExtension on Module { case Module.access: return '/acessHistoryPage'; case Module.openedVisits: - return '/visitsOnTheProperty'; + return '/visitsOnThePropertyPage'; case Module.vehicles: return '/vehiclesOnThePropertyPage'; case Module.residents: - return '/peopleOnThePropertyPage'; + return '/residentsOnThePropertyPage'; case Module.pets: return '/petsPage'; + case Module.petsHistory: + return '/petsHistoryPage'; + case Module.peopleOnTheProperty: + return '/peopleOnThePropertyPage'; case Module.orders: return '/packageOrder'; case Module.completeSchedule: return '/scheduleCompleteVisitPage'; case Module.providerSchedule: return '/provisionalSchedule'; + case Module.aboutProperty: + return '/aboutProperty'; case Module.deliverySchedule: return '/deliverySchedule'; case Module.fastPass: return '/fastPassPage'; + case Module.qrCode: + return '/qrCodePage'; + case Module.visitors: + return '/registerVisitorPage'; + case Module.settings: + return '/preferencesSettings'; + case Module.logout: + return '/WelcomePage'; default: return ''; } @@ -303,27 +383,19 @@ class LicenseHelper { await DatabaseStorage.instance.init(); } - static Future insertLicenseFoo( - final List key, final String display) async { + Future setByKey(final List key, final String display) async { for (var element in key) { - log('insertLicenseFoo($element, $display)'); - DatabaseStorage.database.insert( - tableLicense, - { - 'key': element, - 'display': display, - 'expirationDate': '', - 'startDate': '', - 'quantity': '', - }, - conflictAlgorithm: ConflictAlgorithm.ignore, - ); + await s(element, { + 'display': display, + 'expirationDate': '', + 'startDate': '', + 'quantity': '', + }); } } Future g(String key) async { - var response = await DatabaseStorage.database.query(tableLicense, - where: 'key = ?', whereArgs: [key], columns: ['display']); + var response = await DatabaseStorage.database.query(tableLicense, where: 'key = ?', whereArgs: [key], columns: ['display']); if (response.isEmpty) { return null; } @@ -347,8 +419,7 @@ class LicenseHelper { } Future d(String key) async { - await DatabaseStorage.database - .delete(tableLicense, where: 'key = ?', whereArgs: [key]); + await DatabaseStorage.database.delete(tableLicense, where: 'key = ?', whereArgs: [key]); } Future c() async { diff --git a/lib/shared/helpers/storage/base_storage.dart b/lib/shared/helpers/storage/base_storage.dart index 972734bf..fa1d47c7 100644 --- a/lib/shared/helpers/storage/base_storage.dart +++ b/lib/shared/helpers/storage/base_storage.dart @@ -144,4 +144,3 @@ extension KeychainStorageKeyExtension on KeychainStorageKey { } } } - diff --git a/lib/shared/helpers/storage/keychain_storage.dart b/lib/shared/helpers/storage/keychain_storage.dart index e7116864..4ddd3587 100644 --- a/lib/shared/helpers/storage/keychain_storage.dart +++ b/lib/shared/helpers/storage/keychain_storage.dart @@ -1,3 +1,5 @@ +import 'dart:developer'; + import 'package:hub/shared/helpers/database/database_helper.dart'; import 'package:hub/shared/helpers/storage/base_storage.dart'; import 'package:sqflite/sqflite.dart'; @@ -30,8 +32,8 @@ class KeychainHelper implements BaseStorage { @override Future get(String key) async { - var response = await DatabaseStorage.database - .query(tableKeychain, where: 'key = ?', whereArgs: [key]); + log('KeychainHelper.get: $key'); + var response = await DatabaseStorage.database.query(tableKeychain, where: 'key = ?', whereArgs: [key]); if (response.isEmpty) { return null; } @@ -56,8 +58,7 @@ class KeychainHelper implements BaseStorage { @override Future delete(String key) async { - await DatabaseStorage.database - .delete(tableKeychain, where: 'key = ?', whereArgs: [key]); + await DatabaseStorage.database.delete(tableKeychain, where: 'key = ?', whereArgs: [key]); } @override diff --git a/lib/shared/helpers/storage/storage_helper.dart b/lib/shared/helpers/storage/storage_helper.dart index f5536d4b..cb5a3e1b 100644 --- a/lib/shared/helpers/storage/storage_helper.dart +++ b/lib/shared/helpers/storage/storage_helper.dart @@ -22,12 +22,10 @@ class StorageHelper { await SharedPreferencesStorage.instance.init(); await KeychainHelper.instance.init(); - String? isFirstRun = await SharedPreferencesStorage.instance - .get(SharedPreferencesKey.isFirstRun.value); + String? isFirstRun = await SharedPreferencesStorage.instance.get(SharedPreferencesKey.isFirstRun.value); if (isFirstRun != 'false') { - await SharedPreferencesStorage.instance - .set(SharedPreferencesKey.isFirstRun.value, false); + await SharedPreferencesStorage.instance.set(SharedPreferencesKey.isFirstRun.value, false); await SecureStorage.instance.set(SecureStorageKey.isLogged.value, false); } } @@ -46,10 +44,7 @@ class StorageHelper { static BaseStorage getInstanceByKey(String key) { if (SecureStorageKey.values.map((e) => e.value).toList().contains(key)) { return SecureStorage.instance; - } else if (SharedPreferencesKey.values - .map((e) => e.value) - .toList() - .contains(key)) { + } else if (SharedPreferencesKey.values.map((e) => e.value).toList().contains(key)) { return SharedPreferencesStorage.instance; } else { return KeychainHelper.instance; diff --git a/lib/shared/services/deeplink/deep_link_service.dart b/lib/shared/services/deeplink/deep_link_service.dart index 42cf083d..f24c6093 100644 --- a/lib/shared/services/deeplink/deep_link_service.dart +++ b/lib/shared/services/deeplink/deep_link_service.dart @@ -63,8 +63,7 @@ class DeepLinkService { child: ForgotPasswordScreen(email: email, token: token), ), isScrollControlled: true, - backgroundColor: - FlutterFlowTheme.of(key.currentContext!).primaryBackground, + backgroundColor: FlutterFlowTheme.of(key.currentContext!).primaryBackground, showDragHandle: true, useSafeArea: true, enableDrag: true, diff --git a/lib/shared/services/keychain/keychain_service.dart b/lib/shared/services/keychain/keychain_service.dart index 13fa5ceb..a5497f9d 100644 --- a/lib/shared/services/keychain/keychain_service.dart +++ b/lib/shared/services/keychain/keychain_service.dart @@ -1,5 +1,3 @@ - - class KeychainService { static final KeychainService _instance = KeychainService._internal(); factory KeychainService() => _instance; diff --git a/lib/shared/services/license/license_service.dart b/lib/shared/services/license/license_service.dart index b9d6693a..57ba57f1 100644 --- a/lib/shared/services/license/license_service.dart +++ b/lib/shared/services/license/license_service.dart @@ -3,12 +3,11 @@ import 'dart:developer'; import 'package:hub/backend/api_requests/api_calls.dart'; +import 'package:hub/pages/about_property_page/about_property_model.dart'; +import 'package:hub/pages/about_property_page/about_property_screen.dart'; import 'package:hub/shared/helpers/database/database_helper.dart'; - import 'package:hub/shared/helpers/license/license_helper.dart'; -import 'package:hub/shared/helpers/storage/base_storage.dart'; -import 'package:hub/shared/helpers/storage/storage_helper.dart'; - +import 'package:rxdart/rxdart.dart'; import 'package:sqflite/sqflite.dart'; class LicenseService { @@ -16,32 +15,23 @@ class LicenseService { factory LicenseService() => _instance; LicenseService._internal(); - static Future setupLicense(Database database) async { - await LicenseHelper.insertLicenseFoo( - InactiveModuleKey.values.map((e) => e.value).toList(), 'INVISIVEL'); - await LicenseHelper.insertLicenseFoo( - ActiveModuleKey.values.map((e) => e.value).toList(), 'VISIVEL'); + final _licenseSubject = BehaviorSubject>(); + + Stream> get licenseStream => _licenseSubject.stream; + + Future cleanLicense() async { + _licenseSubject.add([]); } - static Future initLicenseService() async { - // for (var element in LicenseStorageKey.values.map((e) => e.value)) { - // await SQLiteStorage.database.insert( - // SQLiteStorage.tableLicense, - // { - // 'key': element, - // 'display': 'VISIVEL', - // 'expirationDate': '', - // 'startDate': '', - // 'quantity': '', - // }, - // conflictAlgorithm: ConflictAlgorithm.ignore, - // ); - // } + Future setupLicense(Database database) async { + final List inactiveModuleKey = InactiveModuleKey.values.map((e) => e.value).toList(); + final List activeModuleKey = ActiveModuleKey.values.map((e) => e.value).toList(); + await LicenseHelper().setByKey(inactiveModuleKey, 'INVISIVEL'); + await LicenseHelper().setByKey(activeModuleKey, 'VISIVEL'); + _licenseSubject.add([...activeModuleKey]); } - static Future processLicense() async {} - - static Future fetchLicenses() async { + Future fetchLicenses() async { try { log('Obtendo licenças...'); final response = await PhpGroup.getLicense(); @@ -60,7 +50,8 @@ class LicenseService { if (responseBody == []) { await setupLicense(DatabaseStorage.database); - return true; + _licenseSubject.add([]); + return false; } for (var element in responseBody) { @@ -68,11 +59,12 @@ class LicenseService { _saveModule(element); } } + _licenseSubject.add(responseBody); return true; } catch (e) { log('Erro ao obter licenças: $e'); await setupLicense(DatabaseStorage.database); - return true; + return false; } } @@ -81,15 +73,16 @@ class LicenseService { } static Future _saveModule(final dynamic body) async { - if (body is Map) + if (body is Map) { log('Salvando módulo: ${body.toString()}'); - // if (body is Map) await StorageHelper().s(body['key'], ''); - if (body is Map) await LicenseHelper().s(body['key'], body); - // StorageHelper.getInstance(Storage.SQLiteStorage).set(key, value); + log('body[key]: ${body['key']}'); + if (body['key'] == Module.pets.value) if (body['display'] == 'VISIVEL') { + await LicenseHelper().s(Module.petsHistory.value, body); + } + if (AboutPropertyModules.values.any((e) => e.value == body['key']) && body['display'] == 'VISIVEL') { + await LicenseHelper().s(Module.aboutProperty.value, body); + } + } } - - static Future updateLicense(final dynamic body) async {} - - static Future catchLicense() async {} } diff --git a/lib/shared/services/localization/localization_service.dart b/lib/shared/services/localization/localization_service.dart index 019133fa..a53e2ba9 100644 --- a/lib/shared/services/localization/localization_service.dart +++ b/lib/shared/services/localization/localization_service.dart @@ -3,20 +3,21 @@ import 'dart:developer'; import 'package:flutter/material.dart'; -import 'package:hub/backend/api_requests/api_manager.dart'; +import 'package:hub/backend/api_requests/api_calls.dart'; +import 'package:hub/components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart'; +import 'package:hub/flutter_flow/flutter_flow_util.dart'; +import 'package:hub/flutter_flow/internationalization.dart'; import 'package:hub/flutter_flow/nav/nav.dart'; import 'package:hub/shared/helpers/database/database_helper.dart'; + import 'package:hub/shared/helpers/storage/base_storage.dart'; import 'package:hub/shared/helpers/storage/storage_helper.dart'; +import 'package:hub/shared/services/authentication/authentication_service.dart'; import 'package:hub/shared/services/license/license_service.dart'; import 'package:hub/shared/utils/dialog_util.dart'; - -import '../../../backend/api_requests/api_calls.dart'; -import '../../../components/organism_components/bottom_arrow_linked_locals_component/bottom_arrow_linked_locals_component_widget.dart'; -import '../../../flutter_flow/flutter_flow_util.dart'; -import '../../utils/log_util.dart'; -import '../../utils/snackbar_util.dart'; -import '../authentication/authentication_service.dart'; +import 'package:hub/shared/utils/log_util.dart'; +import 'package:hub/shared/utils/snackbar_util.dart'; +import 'package:hub/shared/extensions/string_extensions.dart'; class LocalizationService { static Future checkLocals(BuildContext context) async { @@ -34,15 +35,13 @@ class LocalizationService { enText: 'Verify your connection', ptText: 'Verifique sua conexão', ); - await DialogUtil.error(context, errorMsg) - .whenComplete(() => selectLocal(context, response)); + await DialogUtil.error(context, errorMsg).whenComplete(() => selectLocal(context, response)); return; } final List locals = response.jsonBody['locais'] ?? []; final bool isEmpty = locals.isEmpty; - final bool isActive = - locals.where((local) => local['CLU_STATUS'] != 'B').isNotEmpty; + final bool isActive = locals.where((local) => local['CLU_STATUS'] != 'B').isNotEmpty; final bool isEnable = !isEmpty && isActive; if (isEnable) { @@ -60,6 +59,7 @@ class LocalizationService { static Future processLocals(BuildContext context) async { try { + await LicenseService().cleanLicense(); final GetLocalsCall callback = PhpGroup.getLocalsCall; final ApiCallResponse response = await callback.call(); final bool? isError = response.jsonBody['error']; @@ -74,8 +74,7 @@ class LocalizationService { enText: 'Verify your connection', ptText: 'Verifique sua conexão', ); - await DialogUtil.error(context, errorMsg) - .whenComplete(() => selectLocal(context, response)); + await DialogUtil.error(context, errorMsg).whenComplete(() => selectLocal(context, response)); return false; } @@ -86,8 +85,7 @@ class LocalizationService { final bool isInactived = await _isInactived(locals); final bool isPending = _isPending(locals); final bool isUnique = locals.length == 1; - final bool isBlocked = - locals.where((local) => local['CLU_STATUS'] == 'B').isNotEmpty; + final bool isBlocked = locals.where((local) => local['CLU_STATUS'] == 'B').isNotEmpty; final bool isEnabled = isUnique && isActive; final bool isDisabled = isUnique && isBlocked; final bool isUnselected = await _isUnselected(); @@ -127,8 +125,7 @@ class LocalizationService { enText: 'Error getting locals, verify your connection', ptText: 'Erro ao obter locais, verifique sua conexão', ); - await DialogUtil.error(context, errorMsg) - .whenComplete(() => selectLocal(context, null)); + await DialogUtil.error(context, errorMsg).whenComplete(() => selectLocal(context, null)); return false; } } @@ -143,8 +140,7 @@ class LocalizationService { final GetLocalsCall callback = PhpGroup.getLocalsCall; response = await callback.call(); final String errorMsg = response.jsonBody['error_msg']; - await DialogUtil.error(context, errorMsg) - .whenComplete(() => selectLocal(context, response)); + await DialogUtil.error(context, errorMsg).whenComplete(() => selectLocal(context, response)); return false; } else if (response.jsonBody == null) { final GetLocalsCall callback = PhpGroup.getLocalsCall; @@ -153,16 +149,18 @@ class LocalizationService { enText: 'Verify your connection', ptText: 'Verifique sua conexão', ); - await DialogUtil.error(context, errorMsg) - .whenComplete(() => selectLocal(context, response)); + await DialogUtil.error(context, errorMsg).whenComplete(() => selectLocal(context, response)); return false; } else { - // final bool isNewVersion = await _updateStorageUtil(response.jsonBody); - // if (!isNewVersion) { - await LicenseService.setupLicense(DatabaseStorage.database); + final bool isNewVersion = await _updateStorageUtil(response.jsonBody); + if (isNewVersion) { + return await LicenseService().fetchLicenses(); + } else { + await LicenseService().setupLicense(DatabaseStorage.database); + } + log('() => isNewVersion: $isNewVersion'); + return false; - // } - // return await LicenseService.fetchLicenses(); } } catch (e, s) { log('() => stack processData: $s'); @@ -171,14 +169,12 @@ class LocalizationService { enText: 'Error getting data, verify your connection', ptText: 'Erro ao obter dados, verifique sua conexão', ); - await DialogUtil.error(context, errorMsg) - .whenComplete(() => selectLocal(context, null)); + await DialogUtil.error(context, errorMsg).whenComplete(() => selectLocal(context, null)); return false; } } - static Future selectLocal( - BuildContext context, ApiCallResponse? response) async { + static Future selectLocal(BuildContext context, ApiCallResponse? response) async { return await showModalBottomSheet( isScrollControlled: true, backgroundColor: Colors.transparent, @@ -242,13 +238,10 @@ class LocalizationService { } static void _handleError(BuildContext context, String errorMsg) async { - final String devUUID = - await StorageHelper().g(KeychainStorageKey.devUUID.value) ?? ''; - final String userUUID = - await StorageHelper().g(KeychainStorageKey.userUUID.value) ?? ''; + final String devUUID = await StorageHelper().g(KeychainStorageKey.devUUID.value) ?? ''; + final String userUUID = await StorageHelper().g(KeychainStorageKey.userUUID.value) ?? ''; final bool isAuthenticated = userUUID.isNotEmpty && devUUID.isNotEmpty; - final bool isDevLinked = - !errorMsg.contains('Esse dispositivo nao pertence a esse usuario'); + final bool isDevLinked = !errorMsg.contains('Esse dispositivo nao pertence a esse usuario'); log('() => isLinked: $errorMsg'); log('() => isLinked: $errorMsg'); if (!isAuthenticated) { @@ -268,20 +261,15 @@ class LocalizationService { await DialogUtil.warning(context, errorMsg); return; } - await DialogUtil.error(context, errorMsg) - .whenComplete(() async => await selectLocal(context, null)); + await DialogUtil.error(context, errorMsg).whenComplete(() async => await selectLocal(context, null)); } - static Future _handleUnavailable( - BuildContext context, List locals) async { + static Future _handleUnavailable(BuildContext context, List locals) async { log('() => isUnavailable'); try { - await StorageHelper() - .s(KeychainStorageKey.clientUUID.value, locals[0]['CLI_ID']); - await StorageHelper() - .s(KeychainStorageKey.ownerUUID.value, locals[0]['CLU_OWNER_ID']); - await StorageHelper() - .s(KeychainStorageKey.clientName.value, locals[0]['CLI_NOME']); + await StorageHelper().s(KeychainStorageKey.clientUUID.value, locals[0]['CLI_ID']); + await StorageHelper().s(KeychainStorageKey.ownerUUID.value, locals[0]['CLU_OWNER_ID']); + await StorageHelper().s(KeychainStorageKey.clientName.value, locals[0]['CLI_NOME']); var response = await PhpGroup.resopndeVinculo.call(tarefa: 'A'); if (response.jsonBody['error'] == true) { await StorageHelper().s(KeychainStorageKey.clientUUID.value, ''); @@ -289,28 +277,21 @@ class LocalizationService { await StorageHelper().s(KeychainStorageKey.clientName.value, ''); return false; } - if (response.jsonBody['error'] == false) - return await processData(context).then((value) => value); + if (response.jsonBody['error'] == false) return await processData(context).then((value) => value); } catch (e, s) { await DialogUtil.errorDefault(context); - LogUtil.requestAPIFailed( - 'responderVinculo.php', '', 'Responder Vínculo', e, s); + LogUtil.requestAPIFailed('responderVinculo.php', '', 'Responder Vínculo', e, s); return false; } return false; } - static Future _handleEnabled( - BuildContext context, dynamic local) async { + static Future _handleEnabled(BuildContext context, dynamic local) async { log('() => isEnabled'); - await StorageHelper() - .s(KeychainStorageKey.clientUUID.value, local['CLI_ID']); - await StorageHelper() - .s(KeychainStorageKey.ownerUUID.value, local['CLU_OWNER_ID']); - await StorageHelper() - .s(KeychainStorageKey.clientName.value, local['CLI_NOME']); - await StorageHelper() - .s(KeychainStorageKey.userName.value, local['USU_NOME']); + await StorageHelper().s(KeychainStorageKey.clientUUID.value, local['CLI_ID']); + await StorageHelper().s(KeychainStorageKey.ownerUUID.value, local['CLU_OWNER_ID']); + await StorageHelper().s(KeychainStorageKey.clientName.value, local['CLI_NOME']); + await StorageHelper().s(KeychainStorageKey.userName.value, local['USU_NOME']); return await processData(context); } @@ -322,24 +303,21 @@ class LocalizationService { } static Future _updateStorageUtil(Map jsonBody) async { - await StorageHelper().s(KeychainStorageKey.whatsapp.value, - jsonBody['whatsapp'] != null && jsonBody['whatsapp']); - await StorageHelper().s(KeychainStorageKey.provisional.value, - jsonBody['provisional'] != null && jsonBody['provisional']); - await StorageHelper().s(KeychainStorageKey.pets.value, - jsonBody['pet'] != null && jsonBody['pet']); - await StorageHelper().s( - KeychainStorageKey.petAmount.value, - jsonBody['petAmountRegister'] != null && - jsonBody['petAmountRegister'].toString().isEmpty - ? '0' - : jsonBody['petAmountRegister'].toString()); - await StorageHelper() - .s(KeychainStorageKey.userName.value, jsonBody['visitado']['VDO_NOME']); - await StorageHelper().s(KeychainStorageKey.isNewVersion.value, - jsonBody['newVersion'] != null && jsonBody['newVersion']); + await StorageHelper().s(KeychainStorageKey.whatsapp.value, jsonBody['whatsapp'] != null && jsonBody['whatsapp']); + await StorageHelper().s(KeychainStorageKey.provisional.value, jsonBody['provisional'] != null && jsonBody['provisional']); + await StorageHelper().s(KeychainStorageKey.pets.value, jsonBody['pet'] != null && jsonBody['pet']); + await StorageHelper().s(KeychainStorageKey.petAmount.value, + jsonBody['petAmountRegister'] != null && jsonBody['petAmountRegister'].toString().isEmpty ? '0' : jsonBody['petAmountRegister'].toString()); + await StorageHelper().s(KeychainStorageKey.userName.value, jsonBody['visitado']['VDO_NOME']); + + late final bool isNewVersion; + if (jsonBody['newVersion'] != null) + isNewVersion = jsonBody['newVersion']; + else + isNewVersion = false; log('() => isNewVersion: ${jsonBody['newVersion']}'); - return jsonBody['newVersion'] == true; + await StorageHelper().s(KeychainStorageKey.isNewVersion.value, isNewVersion); + return isNewVersion; } static bool _isActive(List locals) { @@ -347,44 +325,30 @@ class LocalizationService { } static Future _isInactived(List locals) async { - String cliUUID = - (await StorageHelper().g(KeychainStorageKey.clientUUID.value)) ?? ''; - return locals - .where( - (local) => local['CLI_ID'] != cliUUID && local['CLU_STATUS'] == 'A') - .isNotEmpty; + String cliUUID = (await StorageHelper().g(KeychainStorageKey.clientUUID.value)) ?? ''; + return locals.where((local) => local['CLI_ID'] != cliUUID && local['CLU_STATUS'] == 'A').isNotEmpty; } static bool _isPending(List locals) { - return locals - .where( - (local) => local['CLU_STATUS'] != 'B' && local['CLU_STATUS'] != 'A') - .isNotEmpty; + return locals.where((local) => local['CLU_STATUS'] != 'B' && local['CLU_STATUS'] != 'A').isNotEmpty; } static Future _isUnselected() async { - String cliUUID = - (await StorageHelper().g(KeychainStorageKey.clientUUID.value)) ?? ''; - String cliName = - (await StorageHelper().g(KeychainStorageKey.clientName.value)) ?? ''; - String ownerUUID = - (await StorageHelper().g(KeychainStorageKey.ownerUUID.value)) ?? ''; + String cliUUID = (await StorageHelper().g(KeychainStorageKey.clientUUID.value)) ?? ''; + String cliName = (await StorageHelper().g(KeychainStorageKey.clientName.value)) ?? ''; + String ownerUUID = (await StorageHelper().g(KeychainStorageKey.ownerUUID.value)) ?? ''; return cliUUID.isEmpty && cliName.isEmpty && ownerUUID.isEmpty; } static Future _isSelected(bool isInactived) async { - String cliUUID = - (await StorageHelper().g(KeychainStorageKey.clientUUID.value)) ?? ''; - String cliName = - (await StorageHelper().g(KeychainStorageKey.clientName.value)) ?? ''; + String cliUUID = (await StorageHelper().g(KeychainStorageKey.clientUUID.value)) ?? ''; + String cliName = (await StorageHelper().g(KeychainStorageKey.clientName.value)) ?? ''; return cliUUID.isNotEmpty && cliName.isNotEmpty && isInactived; } static Future _isAvailable() async { - String cliUUID = - (await StorageHelper().g(KeychainStorageKey.clientUUID.value)) ?? ''; - String cliName = - (await StorageHelper().g(KeychainStorageKey.clientName.value)) ?? ''; + String cliUUID = (await StorageHelper().g(KeychainStorageKey.clientUUID.value)) ?? ''; + String cliName = (await StorageHelper().g(KeychainStorageKey.clientName.value)) ?? ''; return cliUUID.isNotEmpty && cliName.isNotEmpty; } } diff --git a/lib/shared/widgets/drawer_widget/drawer_widget.dart b/lib/shared/widgets/drawer_widget/drawer_widget.dart index 0e43594b..ddd81a47 100644 --- a/lib/shared/widgets/drawer_widget/drawer_widget.dart +++ b/lib/shared/widgets/drawer_widget/drawer_widget.dart @@ -1,37 +1,70 @@ import 'package:cached_network_image/cached_network_image.dart'; import 'package:flutter/material.dart'; +import 'package:flutter_bloc/flutter_bloc.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 'package:hub/pages/home_page/home_bloc.dart'; +import 'package:hub/pages/home_page/home_state.dart'; +import 'package:hub/shared/helpers/license/license_helper.dart'; +import 'package:hub/shared/services/license/license_service.dart'; class CustomDrawer extends StatelessWidget { - const CustomDrawer({super.key, required this.model}); - final HomePageModel model; + const CustomDrawer({super.key}); @override Widget build(BuildContext context) { - return SafeArea( - child: SizedBox( - width: MediaQuery.of(context).size.width * 0.8, - child: Drawer( - elevation: 16.0, - child: Container( - color: FlutterFlowTheme.of(context).primaryBackground, - child: Column( - children: [ - _buildDrawerHeader(context), - // _buildSearchBar(context), - _buildDrawerBody(), - ].addToStart(const SizedBox(height: 20)), + return StreamBuilder>( + stream: LicenseService().licenseStream, + builder: (context, snapshot) { + if (snapshot.connectionState == ConnectionState.waiting) { + return const Center( + child: CircularProgressIndicator(), + ); + } else if (snapshot.hasError) { + return Center( + child: Text('Error: ${snapshot.error}'), + ); + } else if (!snapshot.hasData || snapshot.data!.isEmpty) { + return Center( + child: Padding( + padding: EdgeInsets.only(top: MediaQuery.of(context).size.height / 10), + child: CircularProgressIndicator( + backgroundColor: FlutterFlowTheme.of(context).primaryBackground, + color: FlutterFlowTheme.of(context).primary, + ), ), - ), - ), - ), + ); + } + return BlocBuilder( + builder: (context, state) { + return SafeArea( + child: SizedBox( + width: MediaQuery.of(context).size.width * 0.8, + child: Drawer( + elevation: 16.0, + child: Container( + color: FlutterFlowTheme.of(context).primaryBackground, + child: Column( + children: [ + _buildDrawerHeader(context, state), + // _buildSearchBar(context, state), + _buildDrawerBody(context), + ].addToStart(const SizedBox(height: 20)), + ), + ), + ), + ), + ); + }, + ); + }, ); } - Container _buildDrawerHeader(BuildContext context) { + Container _buildDrawerHeader(BuildContext context, HomeState state) { return Container( decoration: const BoxDecoration( borderRadius: BorderRadius.only( @@ -56,7 +89,7 @@ class CustomDrawer extends StatelessWidget { child: CachedNetworkImage( imageUrl: valueOrDefault( 'assets/images/person.jpg', - 'https://freaccess.com.br/freaccess/Images/Clients/${model.cliUUID}.png', + 'https://freaccess.com.br/freaccess/Images/Clients/${state.cliUUID}.png', ), width: 80.0, height: 80.0, @@ -75,7 +108,7 @@ class CustomDrawer extends StatelessWidget { crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( - model.userName, + state.userName, style: FlutterFlowTheme.of(context).bodyLarge.override( fontFamily: 'Nunito Sans', color: FlutterFlowTheme.of(context).primaryText, @@ -85,7 +118,7 @@ class CustomDrawer extends StatelessWidget { ), ), Text( - model.userEmail, + state.userEmail, style: FlutterFlowTheme.of(context).bodySmall.override( fontFamily: 'Nunito Sans', color: FlutterFlowTheme.of(context).primaryText, @@ -102,7 +135,7 @@ class CustomDrawer extends StatelessWidget { ); } - Padding _buildSearchBar(BuildContext context) { + Padding _buildSearchBar(BuildContext context, HomeState state) { final theme = FlutterFlowTheme.of(context); final errorColor = theme.error; final primaryColor = theme.primary; @@ -111,8 +144,8 @@ class CustomDrawer extends StatelessWidget { return Padding( padding: const EdgeInsets.symmetric(vertical: 10.0), child: TextFormField( - controller: model.textController, - focusNode: model.textFieldFocusNode, + controller: TextEditingController(), // Replace with appropriate controller + focusNode: FocusNode(), // Replace with appropriate focus node autofocus: false, obscureText: false, decoration: InputDecoration( @@ -153,16 +186,17 @@ class CustomDrawer extends StatelessWidget { fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily, letterSpacing: 0.0, ), - validator: model.textControllerValidator.asValidator(context), + // validator: model.textControllerValidator.asValidator(context), ), ); } - Widget _buildDrawerBody() { - return wrapWithModel( - model: model.drawerMenuComponentModel, - updateCallback: () {}, - child: MenuComponentWidget(model: model.drawerMenuComponentModel), + Widget _buildDrawerBody(BuildContext context) { + return MenuComponentWidget( + style: MenuView.list, + item: MenuItem.tile, + expandable: false, + menuOptions: Module.values.where((e) => e != Module.settings).toList(), ); } } diff --git a/test/integration_test/app_test.dart b/test/integration_test/app_test.dart index fd6b3520..f5a03e8c 100644 --- a/test/integration_test/app_test.dart +++ b/test/integration_test/app_test.dart @@ -1,210 +1,210 @@ -import 'package:flutter/material.dart'; -import 'package:flutter/services.dart'; -import 'package:flutter_test/flutter_test.dart'; -import 'package:hub/flutter_flow/random_data_util.dart'; -import 'package:hub/main.dart'; -import 'package:hub/shared/helpers/storage/base_storage.dart'; -import 'package:hub/shared/helpers/storage/storage_helper.dart'; -import 'package:integration_test/integration_test.dart'; +// import 'package:flutter/material.dart'; +// import 'package:flutter/services.dart'; +// import 'package:flutter_test/flutter_test.dart'; +// import 'package:hub/flutter_flow/random_data_util.dart'; +// import 'package:hub/main.dart'; +// import 'package:hub/shared/helpers/storage/base_storage.dart'; +// import 'package:hub/shared/helpers/storage/storage_helper.dart'; +// import 'package:integration_test/integration_test.dart'; -late WidgetTester widget; +// late WidgetTester widget; -void main() { - IntegrationTestWidgetsFlutterBinding.ensureInitialized(); +// void main() { +// IntegrationTestWidgetsFlutterBinding.ensureInitialized(); - group('Initialization', () { - group('Navigation', () { - setUpAll(() async => - await initializeApp().then((_) async => await StorageHelper().s(SecureStorageKey.isLogged.value, 'false'))); - testWidgets('Test Welcome', (WidgetTester tester) async { - widget = tester; - await _testWelcome(); - }); - }); +// group('Initialization', () { +// group('Navigation', () { +// setUpAll(() async => +// await initializeApp().then((_) async => await StorageHelper().s(SecureStorageKey.isLogged.value, 'false'))); +// testWidgets('Test Welcome', (WidgetTester tester) async { +// widget = tester; +// await _testWelcome(); +// }); +// }); - group('Terms of Use', () {}); - }); - group('Authentication', () { - group('Sign in', () { - setUpAll(() async => - await initializeApp().then((_) async => await StorageHelper().s(SecureStorageKey.isLogged.value, 'false'))); - testWidgets('Test Sign In', (WidgetTester tester) async { - widget = tester; - await _testSignIn(); - }); - }); - group('Sign up', () { - setUpAll(() async => - await initializeApp().then((_) async => await StorageHelper().s(SecureStorageKey.isLogged.value, 'false'))); - testWidgets('Test Sign Up', (WidgetTester tester) async { - widget = tester; - await _testSignUp(); - }); - }); - group('Sign Out', () { - // Add tests for Sign Out here - }); - group('Forgot Password', () { - // setUpAll(() async => await initializeApp().then((_) => StorageUtil().isLogged = false)); - // testWidgets('Test Forgot Password', (WidgetTester tester) async { - // widget = tester; - // await _testForgotPassword(); - // }); - }); - }); - group('Localization', () { - // Add tests for Localization here - }); - group('Networking', () { - // Add tests for Networking here - }); - group('Functionality', () { - // Add tests for Functionality here - }); - group('Usability', () { - // Add tests for Usability here - }); - group('Performance', () { - // Add tests for Performance here - }); - group('Security', () { - // Add tests for Security here - }); - group('Accessibility', () { - // Add tests for Accessibility here - }); - group('Compatibility', () { - // Add tests for Compatibility here - }); - group('Internationalization', () { - // Add tests for Internationalization here - }); -} +// group('Terms of Use', () {}); +// }); +// group('Authentication', () { +// group('Sign in', () { +// setUpAll(() async => +// await initializeApp().then((_) async => await StorageHelper().s(SecureStorageKey.isLogged.value, 'false'))); +// testWidgets('Test Sign In', (WidgetTester tester) async { +// widget = tester; +// await _testSignIn(); +// }); +// }); +// group('Sign up', () { +// setUpAll(() async => +// await initializeApp().then((_) async => await StorageHelper().s(SecureStorageKey.isLogged.value, 'false'))); +// testWidgets('Test Sign Up', (WidgetTester tester) async { +// widget = tester; +// await _testSignUp(); +// }); +// }); +// group('Sign Out', () { +// // Add tests for Sign Out here +// }); +// group('Forgot Password', () { +// // setUpAll(() async => await initializeApp().then((_) => StorageUtil().isLogged = false)); +// // testWidgets('Test Forgot Password', (WidgetTester tester) async { +// // widget = tester; +// // await _testForgotPassword(); +// // }); +// }); +// }); +// group('Localization', () { +// // Add tests for Localization here +// }); +// group('Networking', () { +// // Add tests for Networking here +// }); +// group('Functionality', () { +// // Add tests for Functionality here +// }); +// group('Usability', () { +// // Add tests for Usability here +// }); +// group('Performance', () { +// // Add tests for Performance here +// }); +// group('Security', () { +// // Add tests for Security here +// }); +// group('Accessibility', () { +// // Add tests for Accessibility here +// }); +// group('Compatibility', () { +// // Add tests for Compatibility here +// }); +// group('Internationalization', () { +// // Add tests for Internationalization here +// }); +// } -Future _testWelcome() async { - await widget.pumpWidget(const App()); - await widget.pumpAndSettle(); - await _navigateToSignIn(); - await _navigateToSignUp(); - await widget.pumpAndSettle(); - await widget.pumpWidget(const App()); - await widget.pumpAndSettle(); - await _navigateToSignUp(); - await _navigateToSignIn(); - await widget.pumpAndSettle(); -} +// Future _testWelcome() async { +// await widget.pumpWidget(const App()); +// await widget.pumpAndSettle(); +// await _navigateToSignIn(); +// await _navigateToSignUp(); +// await widget.pumpAndSettle(); +// await widget.pumpWidget(const App()); +// await widget.pumpAndSettle(); +// await _navigateToSignUp(); +// await _navigateToSignIn(); +// await widget.pumpAndSettle(); +// } -Future _testSignIn() async { - await widget.pumpWidget(const App()); - await _navigateToSignIn(); - await _auth({'emailTextFormField': 'erro@exemplo.com', 'passwordTextFormField': '12345678'}); - await _auth({'emailTextFormField': 'email_app@exemplo.com', 'passwordTextFormField': '12345678'}); -} +// Future _testSignIn() async { +// await widget.pumpWidget(const App()); +// await _navigateToSignIn(); +// await _auth({'emailTextFormField': 'erro@exemplo.com', 'passwordTextFormField': '12345678'}); +// await _auth({'emailTextFormField': 'email_app@exemplo.com', 'passwordTextFormField': '12345678'}); +// } -Future _testSignUp() async { - await widget.pumpWidget(const App()); - await _navigateToSignUp(); +// Future _testSignUp() async { +// await widget.pumpWidget(const App()); +// await _navigateToSignUp(); - var credentials = { - 'nameTextFormField': 'app', - 'emailTextFormField': 'email_app@exemplo.com', - 'passwordTextFormField': '12345678' - }; - await _auth(credentials); +// var credentials = { +// 'nameTextFormField': 'app', +// 'emailTextFormField': 'email_app@exemplo.com', +// 'passwordTextFormField': '12345678' +// }; +// await _auth(credentials); - var name = randomString(7, 7, true, true, true); - var email = '$name@example.com'; - var password = '12345678'; - credentials = {'nameTextFormField': name, 'emailTextFormField': email, 'passwordTextFormField': password}; - await _navigateToSignUp(); - await _auth(credentials); - credentials = {'emailTextFormField': email, 'passwordTextFormField': password}; - await _auth(credentials); -} +// var name = randomString(7, 7, true, true, true); +// var email = '$name@example.com'; +// var password = '12345678'; +// credentials = {'nameTextFormField': name, 'emailTextFormField': email, 'passwordTextFormField': password}; +// await _navigateToSignUp(); +// await _auth(credentials); +// credentials = {'emailTextFormField': email, 'passwordTextFormField': password}; +// await _auth(credentials); +// } -Future _testForgotPassword() async { - await widget.pumpWidget(const App()); - await _navigateToSignIn(); - await _recoveryPassword(); +// Future _testForgotPassword() async { +// await widget.pumpWidget(const App()); +// await _navigateToSignIn(); +// await _recoveryPassword(); - var addr = randomString(5, 5, true, true, true); - var credentials = {'recoveryTextFormField': '$addr@exemple.com'}; - await _send(credentials); +// var addr = randomString(5, 5, true, true, true); +// var credentials = {'recoveryTextFormField': '$addr@exemple.com'}; +// await _send(credentials); - await Future.delayed(const Duration(seconds: 2)); +// await Future.delayed(const Duration(seconds: 2)); - await _recoveryPassword(); - credentials = {'recoveryTextFormField': 'email_app@exemple.com'}; - await _send(credentials); -} +// await _recoveryPassword(); +// credentials = {'recoveryTextFormField': 'email_app@exemple.com'}; +// await _send(credentials); +// } -Future _recoveryPassword() async { - await widget.pumpAndSettle(); - final Finder forgotPassword = find.byKey(const ValueKey('ForgotPassword')); - if (forgotPassword.evaluate().isNotEmpty) await widget.tap(forgotPassword); - await widget.ensureVisible(forgotPassword); - await widget.pumpAndSettle(); -} +// Future _recoveryPassword() async { +// await widget.pumpAndSettle(); +// final Finder forgotPassword = find.byKey(const ValueKey('ForgotPassword')); +// if (forgotPassword.evaluate().isNotEmpty) await widget.tap(forgotPassword); +// await widget.ensureVisible(forgotPassword); +// await widget.pumpAndSettle(); +// } -Future _navigateBackUsingSystemGesture() async => - IntegrationTestWidgetsFlutterBinding.instance.keyboard.isLogicalKeyPressed(LogicalKeyboardKey.escape); -Future _navigateToSignUp() async { - await widget.pumpAndSettle(); - final Finder navToSignUp = find.byKey(const ValueKey('toggleSignUpPage')); - if (navToSignUp.evaluate().isNotEmpty) { - await widget.tap(navToSignUp); - await widget.pumpAndSettle(); - } -} +// Future _navigateBackUsingSystemGesture() async => +// IntegrationTestWidgetsFlutterBinding.instance.keyboard.isLogicalKeyPressed(LogicalKeyboardKey.escape); +// Future _navigateToSignUp() async { +// await widget.pumpAndSettle(); +// final Finder navToSignUp = find.byKey(const ValueKey('toggleSignUpPage')); +// if (navToSignUp.evaluate().isNotEmpty) { +// await widget.tap(navToSignUp); +// await widget.pumpAndSettle(); +// } +// } -Future _navigateToSignIn() async { - await widget.pumpAndSettle(); - final Finder navToSignIn = find.byKey(const ValueKey('toggleSignInPage')); - expect(navToSignIn, findsOneWidget); - if (navToSignIn.evaluate().isNotEmpty) { - await widget.tap(navToSignIn); - await widget.pumpAndSettle(); - } -} +// Future _navigateToSignIn() async { +// await widget.pumpAndSettle(); +// final Finder navToSignIn = find.byKey(const ValueKey('toggleSignInPage')); +// expect(navToSignIn, findsOneWidget); +// if (navToSignIn.evaluate().isNotEmpty) { +// await widget.tap(navToSignIn); +// await widget.pumpAndSettle(); +// } +// } -Future _auth(Map credentials) async { - await _enterCredentials(credentials); - await _submit('SubmitButtonWidget'); -} +// Future _auth(Map credentials) async { +// await _enterCredentials(credentials); +// await _submit('SubmitButtonWidget'); +// } -Future _send(Map credentials) async { - await _enterCredentials(credentials); - await _submit('SendButtonWidget'); -} +// Future _send(Map credentials) async { +// await _enterCredentials(credentials); +// await _submit('SendButtonWidget'); +// } -Future _enterCredentials(Map credentials) async { - await widget.pumpAndSettle(); - for (var entry in credentials.entries) { - final Finder field = find.byKey(ValueKey(entry.key)); - await widget.pumpAndSettle(); - expect(field, findsOneWidget); - await widget.enterText(field, entry.value); - await widget.pumpAndSettle(); - } - await widget.pumpAndSettle(); -} +// Future _enterCredentials(Map credentials) async { +// await widget.pumpAndSettle(); +// for (var entry in credentials.entries) { +// final Finder field = find.byKey(ValueKey(entry.key)); +// await widget.pumpAndSettle(); +// expect(field, findsOneWidget); +// await widget.enterText(field, entry.value); +// await widget.pumpAndSettle(); +// } +// await widget.pumpAndSettle(); +// } -Future _submit(String key) async { - await widget.pumpAndSettle(); - final Finder submitButton = find.byKey(ValueKey(key)); - await widget.pumpAndSettle(); - if (submitButton.evaluate().isNotEmpty) { - await widget.tap(submitButton); - await widget.pumpAndSettle(); - } +// Future _submit(String key) async { +// await widget.pumpAndSettle(); +// final Finder submitButton = find.byKey(ValueKey(key)); +// await widget.pumpAndSettle(); +// if (submitButton.evaluate().isNotEmpty) { +// await widget.tap(submitButton); +// await widget.pumpAndSettle(); +// } - final Finder throwExceptionWidget = find.byKey(const ValueKey('ThrowExceptionWidget')); - await widget.pumpAndSettle(); - if (throwExceptionWidget.evaluate().isNotEmpty) { - await widget.ensureVisible(throwExceptionWidget); - await widget.tap(throwExceptionWidget); - await widget.pumpAndSettle(); - } else { - await _navigateBackUsingSystemGesture(); - } -} +// final Finder throwExceptionWidget = find.byKey(const ValueKey('ThrowExceptionWidget')); +// await widget.pumpAndSettle(); +// if (throwExceptionWidget.evaluate().isNotEmpty) { +// await widget.ensureVisible(throwExceptionWidget); +// await widget.tap(throwExceptionWidget); +// await widget.pumpAndSettle(); +// } else { +// await _navigateBackUsingSystemGesture(); +// } +// }