diff --git a/lib/components/organism_components/menu_component/menu_component_bloc.dart b/lib/components/organism_components/menu_component/menu_component_bloc.dart index b5f7876e..d714cf3f 100644 --- a/lib/components/organism_components/menu_component/menu_component_bloc.dart +++ b/lib/components/organism_components/menu_component/menu_component_bloc.dart @@ -1,3 +1,4 @@ +import 'dart:convert'; import 'dart:developer'; import 'package:flutter/material.dart'; import 'package:flutter_bloc/flutter_bloc.dart'; @@ -5,6 +6,7 @@ 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/custom_functions.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'; @@ -38,44 +40,92 @@ class MenuBloc extends Bloc { emit(state.copyWith(menuEntries: entries)); }); } + Future addMenuEntry(List entries, 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; + } 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; + try { + for (var opt in menuOptions) { + String? licenseValue = await LicenseHelper().g(opt.value); + if (licenseValue != null) { + Map licenseMap = await stringToMap(licenseValue); + if (opt == Module.aboutProperty) log('AboutProperty: $licenseMap'); + log('Module: ${opt.value} - License: ${licenseMap['display']}'); + final String display = licenseMap['display'] ?? 'INVISIVEL'; + final String startDate = licenseMap['startDate'] ?? ''; + final String expirationDate = licenseMap['expirationDate'] ?? ''; + final bool isStarted = await processStartDate(startDate, opt); + log('isStarted: $isStarted'); + final bool isExpired = await processExpirationDate(expirationDate, opt); + log('isExpired: $isExpired'); + if (isStarted && !isExpired) { + await processDisplay(display, opt, entries); + } + } + } + } catch (e) { + log('Error generating menu entries: $e'); } + return entries; + } - for (var opt in menuOptions) { - String? v = await LicenseHelper().g(opt.value); - log('Module: ${opt.value} - License: $v'); - switch (v) { + Future processDisplay(String display, Module opt, List entries) async { + try { + switch (display) { case 'VISIVEL': - await addMenuEntry(opt.icon, opt.name, () async { + await addMenuEntry(entries, opt.icon, opt.name, () async { await nav(opt.route); }); - continue; + break; case 'DESABILITADO': - await addMenuEntry(opt.icon, opt.name, () async { + await addMenuEntry(entries, opt.icon, opt.name, () async { await DialogUnavailable.unavailableFeature(key.currentContext!); }); - continue; + break; case 'INVISIVEL': - continue; default: - continue; + break; } + } catch (e) { + log('Error processing display for module ${opt.value}: $e'); } + } - return entries; + Future processStartDate(String startDate, Module opt) async { + try { + if (startDate.isEmpty) return true; + final DateTime? start = DateTime.tryParse(startDate); + if (start != null) { + return DateTime.now().isAfter(start); + } + } catch (e) { + log('Error processing start date for module ${opt.value}: $e'); + } + return false; + } + + Future processExpirationDate(String expirationDate, Module opt) async { + try { + if (expirationDate.isEmpty) return false; + final DateTime? expiration = DateTime.tryParse(expirationDate); + if (expiration != null) { + return DateTime.now().isAfter(expiration); + } + } catch (e) { + log('Error processing expiration date for module ${opt.value}: $e'); + } + return false; } Future nav(String link) async { @@ -88,16 +138,4 @@ class MenuBloc extends Bloc { ), }); } - - 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/flutter_flow/custom_functions.dart b/lib/flutter_flow/custom_functions.dart index ddd01694..642abd6d 100644 --- a/lib/flutter_flow/custom_functions.dart +++ b/lib/flutter_flow/custom_functions.dart @@ -33,6 +33,25 @@ String jsonListToStr(List visitorList) { return result.substring(0, result.length - 1); } +Future> stringToMap(String v) async { + try { + return Future.value(Map.fromEntries( + v.split(',').map((part) { + final keyValue = part.split(':'); + if (keyValue.length < 2) { + throw FormatException('Invalid key-value pair: $part of $v'); + } + final key = keyValue[0].trim(); + final value = keyValue.length > 1 ? keyValue[1].trim() : ''; + return MapEntry(key, value); + }), + )); + } catch (e) { + print('Error parsing string to map: $e'); + return Future.value({}); + } +} + List listStrJsonToJsonList( dynamic jsonList, List strList, diff --git a/lib/pages/about_property_page/about_property_screen.dart b/lib/pages/about_property_page/about_property_screen.dart index f36f7e97..a03227e1 100644 --- a/lib/pages/about_property_page/about_property_screen.dart +++ b/lib/pages/about_property_page/about_property_screen.dart @@ -27,7 +27,7 @@ extension AboutPropertyModulesExtension on AboutPropertyModules { case AboutPropertyModules.residents: return 'FRE-HUB-RESIDENTS'; case AboutPropertyModules.petsHistory: - return 'FRE-HUB-PETS-HISTORY'; + return 'FRE-HUB-PETS'; default: return ''; } @@ -85,7 +85,7 @@ class _AboutPropertyPageState extends State with SingleTicker child: Container( color: FlutterFlowTheme.of(context).primaryBackground, child: MenuComponentWidget(expandable: true, style: MenuView.list_grid, item: MenuItem.button, menuOptions: [ - Module.pets, + Module.petsHistory, Module.residents, Module.openedVisits, Module.vehicles, diff --git a/lib/shared/helpers/database/database_helper.dart b/lib/shared/helpers/database/database_helper.dart index 1a9d1513..15344451 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, false); isInitialized = true; } diff --git a/lib/shared/helpers/license/license_helper.dart b/lib/shared/helpers/license/license_helper.dart index 5a1f7dc7..9ce5c8b8 100644 --- a/lib/shared/helpers/license/license_helper.dart +++ b/lib/shared/helpers/license/license_helper.dart @@ -4,6 +4,7 @@ import 'package:flutter/material.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:sqflite/sqflite.dart'; enum InactiveModuleKey { @@ -11,6 +12,7 @@ enum InactiveModuleKey { vehicles, openedVisits, petsHistory, + aboutProperty, } extension InactiveModuleKeyExtension on InactiveModuleKey { @@ -24,6 +26,8 @@ extension InactiveModuleKeyExtension on InactiveModuleKey { return 'FRE-HUB-RESIDENTS'; case InactiveModuleKey.petsHistory: return 'FRE-HUB-PETS-HISTORY'; + case InactiveModuleKey.aboutProperty: + return 'FRE-HUB-PROPERTY'; default: return ''; } @@ -39,6 +43,7 @@ extension DisabledModuleKeyExtension on DisabledModuleKey { switch (this) { case DisabledModuleKey.fastPass: return 'FRE-HUB-FASTPASS'; + default: return ''; } @@ -385,6 +390,7 @@ class LicenseHelper { Future setByKey(final List key, final String display) async { for (var element in key) { + log('setByKey($element, $display)'); await s(element, { 'display': display, 'expirationDate': '', @@ -394,12 +400,21 @@ class LicenseHelper { } } + Future isNewVersion() async { + var response = await DatabaseStorage.database.query(tableLicense, where: 'key = ?', whereArgs: [KeychainStorageKey.isNewVersion.value], columns: ['display']); + if (response.isEmpty) { + return false; + } + log('isNewVersion(): ${response.first['display']}'); + return response.first['display'] == 'true'; + } + 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]); if (response.isEmpty) { return null; } - return response.first['display'].toString(); + return response.first.toString(); } Future s(String key, T value) async { diff --git a/lib/shared/services/license/license_service.dart b/lib/shared/services/license/license_service.dart index 57ba57f1..b6180934 100644 --- a/lib/shared/services/license/license_service.dart +++ b/lib/shared/services/license/license_service.dart @@ -19,19 +19,42 @@ class LicenseService { Stream> get licenseStream => _licenseSubject.stream; + Future processLicense() async { + if (body['key'] == Module.pets.value && body['display'] == 'VISIVEL') { + await LicenseHelper().s(Module.petsHistory.value, body); + } + final bool isAboutProperty = AboutPropertyModules.values.contains(body['key']); + final bool isVisible = body['display'] == 'VISIVEL'; + log('contains () => ${body['key']} - $isAboutProperty'); + if (isAboutProperty && isVisible) { + await LicenseHelper().s(Module.aboutProperty.value, body); + } + } + Future cleanLicense() async { _licenseSubject.add([]); } - Future setupLicense(Database database) async { + Future setupLicense(Database database, bool isNewVersion) async { + log('(B) => license'); + final List inactiveModuleKey = InactiveModuleKey.values.map((e) => e.value).toList(); final List activeModuleKey = ActiveModuleKey.values.map((e) => e.value).toList(); + final List disabledModuleKey = DisabledModuleKey.values.map((e) => e.value).toList(); + await LicenseHelper().setByKey(inactiveModuleKey, 'INVISIVEL'); await LicenseHelper().setByKey(activeModuleKey, 'VISIVEL'); + if (isNewVersion == true) { + await LicenseHelper().setByKey(disabledModuleKey, 'VISIVEL'); + await LicenseHelper().setByKey([Module.aboutProperty.value], 'VISIVEL'); + } else { + await LicenseHelper().setByKey(disabledModuleKey, 'DESABILITADO'); + } _licenseSubject.add([...activeModuleKey]); } - Future fetchLicenses() async { + Future fetchLicenses(bool isNewVersion) async { + log('(A) => license'); try { log('Obtendo licenças...'); final response = await PhpGroup.getLicense(); @@ -49,7 +72,7 @@ class LicenseService { } if (responseBody == []) { - await setupLicense(DatabaseStorage.database); + await setupLicense(DatabaseStorage.database, isNewVersion); _licenseSubject.add([]); return false; } @@ -63,7 +86,7 @@ class LicenseService { return true; } catch (e) { log('Erro ao obter licenças: $e'); - await setupLicense(DatabaseStorage.database); + await setupLicense(DatabaseStorage.database, isNewVersion); return false; } } @@ -73,16 +96,8 @@ class LicenseService { } static Future _saveModule(final dynamic body) async { - if (body is Map) { - log('Salvando módulo: ${body.toString()}'); - await LicenseHelper().s(body['key'], body); - 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); - } - } + if (body is! Map) return; + log('Salvando módulo: ${body.toString()}'); + await LicenseHelper().s(body['key'], body); } } diff --git a/lib/shared/services/localization/localization_service.dart b/lib/shared/services/localization/localization_service.dart index a53e2ba9..bf485699 100644 --- a/lib/shared/services/localization/localization_service.dart +++ b/lib/shared/services/localization/localization_service.dart @@ -153,13 +153,11 @@ class LocalizationService { return false; } else { final bool isNewVersion = await _updateStorageUtil(response.jsonBody); + await LicenseService().setupLicense(DatabaseStorage.database, isNewVersion); if (isNewVersion) { - return await LicenseService().fetchLicenses(); - } else { - await LicenseService().setupLicense(DatabaseStorage.database); + log('(A) => isNewVersion: $isNewVersion'); + return await LicenseService().fetchLicenses(isNewVersion); } - log('() => isNewVersion: $isNewVersion'); - return false; } } catch (e, s) {