diff --git a/lib/shared/components/molecules/modules/data/data_sources/index.dart b/lib/shared/components/molecules/modules/data/data_sources/index.dart new file mode 100644 index 00000000..1d1649f7 --- /dev/null +++ b/lib/shared/components/molecules/modules/data/data_sources/index.dart @@ -0,0 +1,2 @@ +export 'license_local_data_source.dart'; +export 'license_remote_data_source.dart'; diff --git a/lib/shared/components/molecules/modules/data/data_sources/license_local_data_source.dart b/lib/shared/components/molecules/modules/data/data_sources/license_local_data_source.dart new file mode 100644 index 00000000..9f4dfdf2 --- /dev/null +++ b/lib/shared/components/molecules/modules/data/data_sources/license_local_data_source.dart @@ -0,0 +1,121 @@ +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'; + +abstract class LicenseLocalDataSource { + Future init(); + Future setByKey(final List key, final String display); + Future isNewVersion(); + Future g(String key); + Future s(String key, T value); + Future d(String key); + Future c(); +} + +class LicenseLocalDataSourceImpl implements LicenseLocalDataSource { + static final LicenseLocalDataSourceImpl _instance = LicenseLocalDataSourceImpl._internal(); + factory LicenseLocalDataSourceImpl() => _instance; + LicenseLocalDataSourceImpl._internal(); + + static const String tableLicense = 'license'; + + static String get createLicenseTable => ''' + CREATE TABLE IF NOT EXISTS $tableLicense ( + key TEXT UNIQUE, + display TEXT, + expirationDate TEXT, + startDate TEXT, + quantity TEXT + ); + '''; + + static String get deleteLicenseTable => 'DROP TABLE IF EXISTS $tableLicense;'; + + static String get updatePetsHistoryTrigger => ''' + CREATE TRIGGER update_fre_hub_pets_history + AFTER INSERT ON $tableLicense + WHEN NEW.key = 'FRE-HUB-PETS' + BEGIN + INSERT OR REPLACE INTO $tableLicense (key, display, expirationDate, startDate, quantity) + VALUES ('FRE-HUB-PETS-HISTORY', NEW.display, NEW.expirationDate, NEW.startDate, NEW.quantity); + END; + '''; + + static String get dropPetsHistoryTrigger => 'DROP TRIGGER IF EXISTS update_fre_hub_pets_history;'; + + static String get updateDisplayTrigger => ''' + CREATE TRIGGER update_display_trigger + AFTER UPDATE ON $tableLicense + WHEN NEW.key IN ('FRE-HUB-OPENED-VISITS', 'FRE-HUB-VEHICLES', 'FRE-HUB-RESIDENTS', 'FRE-HUB-PETS') + BEGIN + UPDATE $tableLicense + SET display = CASE + WHEN (SELECT COUNT(*) FROM $tableLicense WHERE key IN ('FRE-HUB-OPENED-VISITS', 'FRE-HUB-VEHICLES', 'FRE-HUB-RESIDENTS', 'FRE-HUB-PETS') AND display = 'VISIVEL') > 0 + THEN 'VISIVEL' + ELSE 'INVISIVEL' + END + WHERE key = 'FRE-HUB-ABOUT-PROPERTY'; + END; + '''; + + static String get dropDisplayTrigger => 'DROP TRIGGER IF EXISTS update_display_trigger;'; + + Future init() async { + await DatabaseStorage.instance.init(); + } + + Future setByKey(final List key, final String display) async { + for (var element in key) { + log('setByKey($element, $display)'); + await s(element, { + 'display': display, + 'expirationDate': '', + 'startDate': '', + 'quantity': '', + }); + } + } + + 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]); + if (response.isEmpty) { + return null; + } + return response.first.toString(); + } + + Future s(String key, T value) async { + log('setLicense($key, $value)'); + value as Map; + + await DatabaseStorage.database.insert( + tableLicense, + { + 'key': key, + 'display': value['display'], + 'expirationDate': value['expirationDate'], + 'startDate': value['startDate'], + 'quantity': value['quantity'], + }, + conflictAlgorithm: ConflictAlgorithm.replace); + } + + Future d(String key) async { + await DatabaseStorage.database.delete(tableLicense, where: 'key = ?', whereArgs: [key]); + } + + Future c() async { + await DatabaseStorage.database.delete(tableLicense); + } +} diff --git a/lib/shared/components/molecules/modules/data/data_sources/license_remote_data_source.dart b/lib/shared/components/molecules/modules/data/data_sources/license_remote_data_source.dart new file mode 100644 index 00000000..cc6aa0df --- /dev/null +++ b/lib/shared/components/molecules/modules/data/data_sources/license_remote_data_source.dart @@ -0,0 +1,109 @@ +// ignore_for_file: curly_braces_in_flow_control_structures, prefer_is_empty + +import 'dart:developer'; + +import 'package:hub/backend/api_requests/api_calls.dart'; +import 'package:hub/shared/components/molecules/modules/index.dart'; +import 'package:hub/shared/helpers/database/database_helper.dart'; + +import 'package:rxdart/rxdart.dart'; +import 'package:sqflite/sqflite.dart'; + +abstract class LicenseRemoteDataSource { + Future fetchLicenses(bool isNewVersion); + Future cleanLicense(); + Future processLicense(); + Future setupLicense(Database database, bool isNewVersion); +} + +class LicenseRemoteDataSourceImpl implements LicenseRemoteDataSource { + static final LicenseRemoteDataSourceImpl _instance = LicenseRemoteDataSourceImpl._internal(); + factory LicenseRemoteDataSourceImpl() => _instance; + LicenseRemoteDataSourceImpl._internal(); + + final _licenseSubject = BehaviorSubject>(); + + 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, 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 LicenseLocalDataSourceImpl().setByKey(inactiveModuleKey, 'INVISIVEL'); + await LicenseLocalDataSourceImpl().setByKey(activeModuleKey, 'VISIVEL'); + if (isNewVersion == true) { + await LicenseLocalDataSourceImpl().setByKey(disabledModuleKey, 'VISIVEL'); + await LicenseLocalDataSourceImpl().setByKey([ModuleEnum.aboutProperty.value], 'VISIVEL'); + } else { + await LicenseLocalDataSourceImpl().setByKey(disabledModuleKey, 'DESABILITADO'); + } + _licenseSubject.add([...activeModuleKey]); + } + + Future fetchLicenses(bool isNewVersion) async { + log('(A) => license'); + try { + log('Obtendo licenças...'); + final response = await PhpGroup.getLicense(); + final dynamic responseBody = response.jsonBody; + log('Licenças obtidas: $responseBody'); + + if (response.jsonBody is! List) { + late final String error; + if (response.jsonBody is Map) + error = response.jsonBody['error_msg']; + else + error = 'Erro desconhecido'; + + throw Exception('Erro ao consultar licenças: $error'); + } + + if (responseBody == []) { + await setupLicense(DatabaseStorage.database, isNewVersion); + _licenseSubject.add([]); + return false; + } + + for (var element in responseBody) { + if (licenseContainsKey(element['key'])) { + _saveModule(element); + } + } + _licenseSubject.add(responseBody); + return true; + } catch (e) { + log('Erro ao obter licenças: $e'); + await setupLicense(DatabaseStorage.database, isNewVersion); + return false; + } + } + + static bool licenseContainsKey(final String key) { + return ModuleEnum.values.map((e) => e.value).toList().contains(key); + } + + static Future _saveModule(final dynamic body) async { + if (body is! Map) return; + log('Salvando módulo: ${body.toString()}'); + await LicenseLocalDataSourceImpl().s(body['key'], body); + } +} diff --git a/lib/shared/components/molecules/modules/data/index.dart b/lib/shared/components/molecules/modules/data/index.dart new file mode 100644 index 00000000..186dfac9 --- /dev/null +++ b/lib/shared/components/molecules/modules/data/index.dart @@ -0,0 +1,3 @@ +export 'data_sources/index.dart'; +export 'repositories/index.dart'; +export 'models/index.dart'; diff --git a/lib/shared/components/molecules/modules/data/models/index.dart b/lib/shared/components/molecules/modules/data/models/index.dart new file mode 100644 index 00000000..2ce303b5 --- /dev/null +++ b/lib/shared/components/molecules/modules/data/models/index.dart @@ -0,0 +1,2 @@ +export 'license_model.dart'; +export 'module_model.dart'; diff --git a/lib/shared/components/molecules/modules/data/models/license_model.dart b/lib/shared/components/molecules/modules/data/models/license_model.dart new file mode 100644 index 00000000..1bbf5d3f --- /dev/null +++ b/lib/shared/components/molecules/modules/data/models/license_model.dart @@ -0,0 +1,15 @@ +import 'package:flutter/material.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; +import 'module_model.dart'; + +part 'license_model.freezed.dart'; +part 'license_model.g.dart'; + +@freezed +class LicenseModel with _$LicenseModel { + const factory LicenseModel({ + required List modules, + }) = _LicenseModel; + + factory LicenseModel.fromJson(Map json) => _$LicenseModelFromJson(json); +} diff --git a/lib/shared/components/molecules/modules/data/models/license_model.freezed.dart b/lib/shared/components/molecules/modules/data/models/license_model.freezed.dart new file mode 100644 index 00000000..8481cf6f --- /dev/null +++ b/lib/shared/components/molecules/modules/data/models/license_model.freezed.dart @@ -0,0 +1,172 @@ +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'license_model.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); + +LicenseModel _$LicenseModelFromJson(Map json) { + return _LicenseModel.fromJson(json); +} + +/// @nodoc +mixin _$LicenseModel { + List get modules => throw _privateConstructorUsedError; + + /// Serializes this LicenseModel to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of LicenseModel + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $LicenseModelCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $LicenseModelCopyWith<$Res> { + factory $LicenseModelCopyWith( + LicenseModel value, $Res Function(LicenseModel) then) = + _$LicenseModelCopyWithImpl<$Res, LicenseModel>; + @useResult + $Res call({List modules}); +} + +/// @nodoc +class _$LicenseModelCopyWithImpl<$Res, $Val extends LicenseModel> + implements $LicenseModelCopyWith<$Res> { + _$LicenseModelCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of LicenseModel + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? modules = null, + }) { + return _then(_value.copyWith( + modules: null == modules + ? _value.modules + : modules // ignore: cast_nullable_to_non_nullable + as List, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$LicenseModelImplCopyWith<$Res> + implements $LicenseModelCopyWith<$Res> { + factory _$$LicenseModelImplCopyWith( + _$LicenseModelImpl value, $Res Function(_$LicenseModelImpl) then) = + __$$LicenseModelImplCopyWithImpl<$Res>; + @override + @useResult + $Res call({List modules}); +} + +/// @nodoc +class __$$LicenseModelImplCopyWithImpl<$Res> + extends _$LicenseModelCopyWithImpl<$Res, _$LicenseModelImpl> + implements _$$LicenseModelImplCopyWith<$Res> { + __$$LicenseModelImplCopyWithImpl( + _$LicenseModelImpl _value, $Res Function(_$LicenseModelImpl) _then) + : super(_value, _then); + + /// Create a copy of LicenseModel + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? modules = null, + }) { + return _then(_$LicenseModelImpl( + modules: null == modules + ? _value._modules + : modules // ignore: cast_nullable_to_non_nullable + as List, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$LicenseModelImpl implements _LicenseModel { + const _$LicenseModelImpl({required final List modules}) + : _modules = modules; + + factory _$LicenseModelImpl.fromJson(Map json) => + _$$LicenseModelImplFromJson(json); + + final List _modules; + @override + List get modules { + if (_modules is EqualUnmodifiableListView) return _modules; + // ignore: implicit_dynamic_type + return EqualUnmodifiableListView(_modules); + } + + @override + String toString() { + return 'LicenseModel(modules: $modules)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$LicenseModelImpl && + const DeepCollectionEquality().equals(other._modules, _modules)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => + Object.hash(runtimeType, const DeepCollectionEquality().hash(_modules)); + + /// Create a copy of LicenseModel + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$LicenseModelImplCopyWith<_$LicenseModelImpl> get copyWith => + __$$LicenseModelImplCopyWithImpl<_$LicenseModelImpl>(this, _$identity); + + @override + Map toJson() { + return _$$LicenseModelImplToJson( + this, + ); + } +} + +abstract class _LicenseModel implements LicenseModel { + const factory _LicenseModel({required final List modules}) = + _$LicenseModelImpl; + + factory _LicenseModel.fromJson(Map json) = + _$LicenseModelImpl.fromJson; + + @override + List get modules; + + /// Create a copy of LicenseModel + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$LicenseModelImplCopyWith<_$LicenseModelImpl> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/lib/shared/components/molecules/modules/data/models/license_model.g.dart b/lib/shared/components/molecules/modules/data/models/license_model.g.dart new file mode 100644 index 00000000..2689837b --- /dev/null +++ b/lib/shared/components/molecules/modules/data/models/license_model.g.dart @@ -0,0 +1,19 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'license_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_$LicenseModelImpl _$$LicenseModelImplFromJson(Map json) => + _$LicenseModelImpl( + modules: (json['modules'] as List) + .map((e) => ModuleModel.fromJson(e as Map)) + .toList(), + ); + +Map _$$LicenseModelImplToJson(_$LicenseModelImpl instance) => + { + 'modules': instance.modules, + }; diff --git a/lib/shared/components/molecules/modules/data/models/module_model.dart b/lib/shared/components/molecules/modules/data/models/module_model.dart new file mode 100644 index 00000000..c45efffe --- /dev/null +++ b/lib/shared/components/molecules/modules/data/models/module_model.dart @@ -0,0 +1,18 @@ +import 'package:flutter/material.dart'; +import 'package:freezed_annotation/freezed_annotation.dart'; + +part 'module_model.freezed.dart'; +part 'module_model.g.dart'; + +@freezed +class ModuleModel with _$ModuleModel { + const factory ModuleModel({ + required String key, + required String display, + required String expirationDate, + required String startDate, + required int quantity, + }) = _ModuleModel; + + factory ModuleModel.fromJson(Map json) => _$ModuleModelFromJson(json); +} diff --git a/lib/shared/components/molecules/modules/data/models/module_model.freezed.dart b/lib/shared/components/molecules/modules/data/models/module_model.freezed.dart new file mode 100644 index 00000000..5b26bcdb --- /dev/null +++ b/lib/shared/components/molecules/modules/data/models/module_model.freezed.dart @@ -0,0 +1,252 @@ +// coverage:ignore-file +// GENERATED CODE - DO NOT MODIFY BY HAND +// ignore_for_file: type=lint +// ignore_for_file: unused_element, deprecated_member_use, deprecated_member_use_from_same_package, use_function_type_syntax_for_parameters, unnecessary_const, avoid_init_to_null, invalid_override_different_default_values_named, prefer_expression_function_bodies, annotate_overrides, invalid_annotation_target, unnecessary_question_mark + +part of 'module_model.dart'; + +// ************************************************************************** +// FreezedGenerator +// ************************************************************************** + +T _$identity(T value) => value; + +final _privateConstructorUsedError = UnsupportedError( + 'It seems like you constructed your class using `MyClass._()`. This constructor is only meant to be used by freezed and you are not supposed to need it nor use it.\nPlease check the documentation here for more information: https://github.com/rrousselGit/freezed#adding-getters-and-methods-to-our-models'); + +ModuleModel _$ModuleModelFromJson(Map json) { + return _ModuleModel.fromJson(json); +} + +/// @nodoc +mixin _$ModuleModel { + String get key => throw _privateConstructorUsedError; + String get display => throw _privateConstructorUsedError; + String get expirationDate => throw _privateConstructorUsedError; + String get startDate => throw _privateConstructorUsedError; + int get quantity => throw _privateConstructorUsedError; + + /// Serializes this ModuleModel to a JSON map. + Map toJson() => throw _privateConstructorUsedError; + + /// Create a copy of ModuleModel + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + $ModuleModelCopyWith get copyWith => + throw _privateConstructorUsedError; +} + +/// @nodoc +abstract class $ModuleModelCopyWith<$Res> { + factory $ModuleModelCopyWith( + ModuleModel value, $Res Function(ModuleModel) then) = + _$ModuleModelCopyWithImpl<$Res, ModuleModel>; + @useResult + $Res call( + {String key, + String display, + String expirationDate, + String startDate, + int quantity}); +} + +/// @nodoc +class _$ModuleModelCopyWithImpl<$Res, $Val extends ModuleModel> + implements $ModuleModelCopyWith<$Res> { + _$ModuleModelCopyWithImpl(this._value, this._then); + + // ignore: unused_field + final $Val _value; + // ignore: unused_field + final $Res Function($Val) _then; + + /// Create a copy of ModuleModel + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? key = null, + Object? display = null, + Object? expirationDate = null, + Object? startDate = null, + Object? quantity = null, + }) { + return _then(_value.copyWith( + key: null == key + ? _value.key + : key // ignore: cast_nullable_to_non_nullable + as String, + display: null == display + ? _value.display + : display // ignore: cast_nullable_to_non_nullable + as String, + expirationDate: null == expirationDate + ? _value.expirationDate + : expirationDate // ignore: cast_nullable_to_non_nullable + as String, + startDate: null == startDate + ? _value.startDate + : startDate // ignore: cast_nullable_to_non_nullable + as String, + quantity: null == quantity + ? _value.quantity + : quantity // ignore: cast_nullable_to_non_nullable + as int, + ) as $Val); + } +} + +/// @nodoc +abstract class _$$ModuleModelImplCopyWith<$Res> + implements $ModuleModelCopyWith<$Res> { + factory _$$ModuleModelImplCopyWith( + _$ModuleModelImpl value, $Res Function(_$ModuleModelImpl) then) = + __$$ModuleModelImplCopyWithImpl<$Res>; + @override + @useResult + $Res call( + {String key, + String display, + String expirationDate, + String startDate, + int quantity}); +} + +/// @nodoc +class __$$ModuleModelImplCopyWithImpl<$Res> + extends _$ModuleModelCopyWithImpl<$Res, _$ModuleModelImpl> + implements _$$ModuleModelImplCopyWith<$Res> { + __$$ModuleModelImplCopyWithImpl( + _$ModuleModelImpl _value, $Res Function(_$ModuleModelImpl) _then) + : super(_value, _then); + + /// Create a copy of ModuleModel + /// with the given fields replaced by the non-null parameter values. + @pragma('vm:prefer-inline') + @override + $Res call({ + Object? key = null, + Object? display = null, + Object? expirationDate = null, + Object? startDate = null, + Object? quantity = null, + }) { + return _then(_$ModuleModelImpl( + key: null == key + ? _value.key + : key // ignore: cast_nullable_to_non_nullable + as String, + display: null == display + ? _value.display + : display // ignore: cast_nullable_to_non_nullable + as String, + expirationDate: null == expirationDate + ? _value.expirationDate + : expirationDate // ignore: cast_nullable_to_non_nullable + as String, + startDate: null == startDate + ? _value.startDate + : startDate // ignore: cast_nullable_to_non_nullable + as String, + quantity: null == quantity + ? _value.quantity + : quantity // ignore: cast_nullable_to_non_nullable + as int, + )); + } +} + +/// @nodoc +@JsonSerializable() +class _$ModuleModelImpl implements _ModuleModel { + const _$ModuleModelImpl( + {required this.key, + required this.display, + required this.expirationDate, + required this.startDate, + required this.quantity}); + + factory _$ModuleModelImpl.fromJson(Map json) => + _$$ModuleModelImplFromJson(json); + + @override + final String key; + @override + final String display; + @override + final String expirationDate; + @override + final String startDate; + @override + final int quantity; + + @override + String toString() { + return 'ModuleModel(key: $key, display: $display, expirationDate: $expirationDate, startDate: $startDate, quantity: $quantity)'; + } + + @override + bool operator ==(Object other) { + return identical(this, other) || + (other.runtimeType == runtimeType && + other is _$ModuleModelImpl && + (identical(other.key, key) || other.key == key) && + (identical(other.display, display) || other.display == display) && + (identical(other.expirationDate, expirationDate) || + other.expirationDate == expirationDate) && + (identical(other.startDate, startDate) || + other.startDate == startDate) && + (identical(other.quantity, quantity) || + other.quantity == quantity)); + } + + @JsonKey(includeFromJson: false, includeToJson: false) + @override + int get hashCode => Object.hash( + runtimeType, key, display, expirationDate, startDate, quantity); + + /// Create a copy of ModuleModel + /// with the given fields replaced by the non-null parameter values. + @JsonKey(includeFromJson: false, includeToJson: false) + @override + @pragma('vm:prefer-inline') + _$$ModuleModelImplCopyWith<_$ModuleModelImpl> get copyWith => + __$$ModuleModelImplCopyWithImpl<_$ModuleModelImpl>(this, _$identity); + + @override + Map toJson() { + return _$$ModuleModelImplToJson( + this, + ); + } +} + +abstract class _ModuleModel implements ModuleModel { + const factory _ModuleModel( + {required final String key, + required final String display, + required final String expirationDate, + required final String startDate, + required final int quantity}) = _$ModuleModelImpl; + + factory _ModuleModel.fromJson(Map json) = + _$ModuleModelImpl.fromJson; + + @override + String get key; + @override + String get display; + @override + String get expirationDate; + @override + String get startDate; + @override + int get quantity; + + /// Create a copy of ModuleModel + /// with the given fields replaced by the non-null parameter values. + @override + @JsonKey(includeFromJson: false, includeToJson: false) + _$$ModuleModelImplCopyWith<_$ModuleModelImpl> get copyWith => + throw _privateConstructorUsedError; +} diff --git a/lib/shared/components/molecules/modules/data/models/module_model.g.dart b/lib/shared/components/molecules/modules/data/models/module_model.g.dart new file mode 100644 index 00000000..b2ab688f --- /dev/null +++ b/lib/shared/components/molecules/modules/data/models/module_model.g.dart @@ -0,0 +1,25 @@ +// GENERATED CODE - DO NOT MODIFY BY HAND + +part of 'module_model.dart'; + +// ************************************************************************** +// JsonSerializableGenerator +// ************************************************************************** + +_$ModuleModelImpl _$$ModuleModelImplFromJson(Map json) => + _$ModuleModelImpl( + key: json['key'] as String, + display: json['display'] as String, + expirationDate: json['expirationDate'] as String, + startDate: json['startDate'] as String, + quantity: (json['quantity'] as num).toInt(), + ); + +Map _$$ModuleModelImplToJson(_$ModuleModelImpl instance) => + { + 'key': instance.key, + 'display': instance.display, + 'expirationDate': instance.expirationDate, + 'startDate': instance.startDate, + 'quantity': instance.quantity, + }; diff --git a/lib/shared/components/molecules/modules/data/repositories/index.dart b/lib/shared/components/molecules/modules/data/repositories/index.dart new file mode 100644 index 00000000..8474837b --- /dev/null +++ b/lib/shared/components/molecules/modules/data/repositories/index.dart @@ -0,0 +1 @@ +export 'license_repository_impl.dart'; diff --git a/lib/shared/components/molecules/modules/data/repositories/license_repository_impl.dart b/lib/shared/components/molecules/modules/data/repositories/license_repository_impl.dart new file mode 100644 index 00000000..240d8733 --- /dev/null +++ b/lib/shared/components/molecules/modules/data/repositories/license_repository_impl.dart @@ -0,0 +1,35 @@ +import 'package:hub/shared/components/molecules/modules/data/data_sources/license_local_data_source.dart'; +import 'package:hub/shared/components/molecules/modules/data/data_sources/license_remote_data_source.dart'; +import 'package:hub/shared/components/molecules/modules/domain/respositories/license_repository.dart'; +import 'package:hub/shared/helpers/database/database_helper.dart'; +import 'package:sqflite/sqflite.dart'; + +class LicenseRepositoryImpl implements LicenseRepository { + final LicenseLocalDataSource localDataSource = LicenseLocalDataSourceImpl(); + final LicenseRemoteDataSource remoteDataSource = LicenseRemoteDataSourceImpl(); + final Database database = DatabaseStorage.database; + + LicenseRepositoryImpl(); + + static get stream => LicenseRemoteDataSourceImpl().licenseStream; + + Future fetchLicense(bool isNewVersion) async { + return await remoteDataSource.fetchLicenses(isNewVersion); + } + + Future setupLicense(bool isNewVersion) async { + return await remoteDataSource.setupLicense(database, isNewVersion); + } + + Future cleanLicense() async { + return await remoteDataSource.cleanLicense(); + } + + Future g(String key) async { + return await localDataSource.g(key); + } + + Future s(String key, T value) async { + return await localDataSource.s(key, value); + } +} diff --git a/lib/shared/components/molecules/modules/domain/entities/index.dart b/lib/shared/components/molecules/modules/domain/entities/index.dart new file mode 100644 index 00000000..ccb3a9d2 --- /dev/null +++ b/lib/shared/components/molecules/modules/domain/entities/index.dart @@ -0,0 +1,2 @@ +export 'license.dart'; +export 'module.dart'; diff --git a/lib/shared/components/molecules/modules/domain/entities/license.dart b/lib/shared/components/molecules/modules/domain/entities/license.dart new file mode 100644 index 00000000..743580fa --- /dev/null +++ b/lib/shared/components/molecules/modules/domain/entities/license.dart @@ -0,0 +1,26 @@ +import 'package:equatable/equatable.dart'; +import 'module.dart'; + +enum ModuleStatus { active, inactive, disabled } + +extension ModuleStatusExtension on ModuleStatus { + String get value { + switch (this) { + case ModuleStatus.active: + return 'VISIVEL'; + case ModuleStatus.inactive: + return 'INVISIVEL'; + case ModuleStatus.disabled: + return 'DESABILITADO'; + } + } +} + +class License extends Equatable { + final List modules; + + const License({required this.modules}); + + @override + List get props => [modules]; +} diff --git a/lib/shared/components/molecules/modules/domain/entities/module.dart b/lib/shared/components/molecules/modules/domain/entities/module.dart new file mode 100644 index 00000000..f2821e54 --- /dev/null +++ b/lib/shared/components/molecules/modules/domain/entities/module.dart @@ -0,0 +1,37 @@ +import 'package:hub/shared/components/molecules/modules/data/models/module_model.dart'; + +class Module { + final String key; + final String display; + final String expirationDate; + final String startDate; + final int quantity; + + Module({ + required this.key, + required this.display, + required this.expirationDate, + required this.startDate, + required this.quantity, + }); + + factory Module.fromModel(ModuleModel model) { + return Module( + key: model.key, + display: model.display, + expirationDate: model.expirationDate, + startDate: model.startDate, + quantity: model.quantity, + ); + } + + ModuleModel toModel() { + return ModuleModel( + key: key, + display: display, + expirationDate: expirationDate, + startDate: startDate, + quantity: quantity, + ); + } +} diff --git a/lib/shared/components/molecules/modules/domain/index.dart b/lib/shared/components/molecules/modules/domain/index.dart new file mode 100644 index 00000000..00b76d59 --- /dev/null +++ b/lib/shared/components/molecules/modules/domain/index.dart @@ -0,0 +1,3 @@ +export 'entities/index.dart'; +export 'respositories/index.dart'; +export 'usecases/index.dart'; diff --git a/lib/shared/components/molecules/modules/domain/respositories/index.dart b/lib/shared/components/molecules/modules/domain/respositories/index.dart new file mode 100644 index 00000000..7f6be535 --- /dev/null +++ b/lib/shared/components/molecules/modules/domain/respositories/index.dart @@ -0,0 +1 @@ +export 'license_repository.dart'; diff --git a/lib/shared/components/molecules/modules/domain/respositories/license_repository.dart b/lib/shared/components/molecules/modules/domain/respositories/license_repository.dart new file mode 100644 index 00000000..877ed320 --- /dev/null +++ b/lib/shared/components/molecules/modules/domain/respositories/license_repository.dart @@ -0,0 +1,8 @@ +abstract class LicenseRepository { + Future fetchLicense(bool isNewVersion); + Future setupLicense(bool isNewVersion); + Future cleanLicense(); + + Future g(String key); + Future s(String key, T value); +} diff --git a/lib/shared/components/molecules/modules/domain/usecases/index.dart b/lib/shared/components/molecules/modules/domain/usecases/index.dart new file mode 100644 index 00000000..e69de29b diff --git a/lib/shared/components/molecules/modules/enums/active_modules.dart b/lib/shared/components/molecules/modules/enums/active_modules.dart new file mode 100644 index 00000000..81c81234 --- /dev/null +++ b/lib/shared/components/molecules/modules/enums/active_modules.dart @@ -0,0 +1,60 @@ +import 'package:flutter/material.dart'; +import 'package:hub/shared/components/molecules/modules/index.dart'; + +enum ActiveModuleKey implements BaseModule { + messages, + liberations, + reservations, + access, + pets, + orders, + completeSchedule, + providerSchedule, + deliverySchedule, + qrCode, + visitors, + peopleOnTheProperty, + settings, + logout; + + @override + IconData get icon => throw UnimplementedError(); + + @override + String get name => throw UnimplementedError(); + + @override + String get route => throw UnimplementedError(); + + @override + String get value { + switch (this) { + case ActiveModuleKey.messages: + return 'FRE-HUB-MESSAGES'; + case ActiveModuleKey.liberations: + return 'FRE-HUB-LIBERATIONS'; + case ActiveModuleKey.reservations: + 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: + return 'FRE-HUB-COMPLETE-SCHEDULE'; + case ActiveModuleKey.providerSchedule: + return 'FRE-HUB-AGE-PROV-PRESTADOR'; + case ActiveModuleKey.deliverySchedule: + return 'FRE-HUB-AGE-PROV-DELIVERY'; + case ActiveModuleKey.visitors: + return 'FRE-HUB-VISITORS'; + case ActiveModuleKey.qrCode: + return 'FRE-HUB-QRCODE'; + case ActiveModuleKey.peopleOnTheProperty: + return 'FRE-HUB-PEOPLE'; + default: + return ''; + } + } +} diff --git a/lib/shared/components/molecules/modules/enums/disabled_modules.dart b/lib/shared/components/molecules/modules/enums/disabled_modules.dart new file mode 100644 index 00000000..f773cc4e --- /dev/null +++ b/lib/shared/components/molecules/modules/enums/disabled_modules.dart @@ -0,0 +1,26 @@ +import 'package:flutter/material.dart'; +import 'package:hub/shared/components/molecules/modules/index.dart'; + +enum DisabledModuleKey implements BaseModule { + fastPass; + + @override + IconData get icon => throw UnimplementedError(); + + @override + String get name => throw UnimplementedError(); + + @override + String get route => throw UnimplementedError(); + + @override + String get value { + switch (this) { + case DisabledModuleKey.fastPass: + return 'FRE-HUB-FASTPASS'; + + default: + return ''; + } + } +} diff --git a/lib/shared/components/molecules/modules/enums/enum_modules.dart b/lib/shared/components/molecules/modules/enums/enum_modules.dart new file mode 100644 index 00000000..107a0e98 --- /dev/null +++ b/lib/shared/components/molecules/modules/enums/enum_modules.dart @@ -0,0 +1,277 @@ +import 'package:flutter/material.dart'; +import 'package:hub/flutter_flow/internationalization.dart'; +import 'package:hub/flutter_flow/nav/nav.dart'; + +abstract class BaseModule { + String get value; + String get name; + IconData get icon; + String get route; +} + +enum ModuleEnum implements BaseModule { + providerSchedule, + deliverySchedule, + fastPass, + completeSchedule, + orders, + reservations, + visitors, + vehicles, + residents, + openedVisits, + qrCode, + pets, + access, + liberations, + messages, + aboutProperty, + petsHistory, + peopleOnTheProperty, + settings, + logout; + + @override + String get value { + switch (this) { + case ModuleEnum.messages: + return 'FRE-HUB-MESSAGES'; + case ModuleEnum.liberations: + return 'FRE-HUB-LIBERATIONS'; + case ModuleEnum.reservations: + return 'FRE-HUB-RESERVATIONS'; + case ModuleEnum.access: + return 'FRE-HUB-ACCESS'; + case ModuleEnum.openedVisits: + return 'FRE-HUB-OPENED-VISITS'; + case ModuleEnum.vehicles: + return 'FRE-HUB-VEHICLES'; + case ModuleEnum.residents: + return 'FRE-HUB-RESIDENTS'; + case ModuleEnum.pets: + return 'FRE-HUB-PETS'; + case ModuleEnum.orders: + return 'FRE-HUB-ORDERS'; + case ModuleEnum.completeSchedule: + return 'FRE-HUB-COMPLETE-SCHEDULE'; + case ModuleEnum.providerSchedule: + return 'FRE-HUB-AGE-PROV-PRESTADOR'; + case ModuleEnum.deliverySchedule: + return 'FRE-HUB-AGE-PROV-DELIVERY'; + case ModuleEnum.aboutProperty: + return 'FRE-HUB-PROPERTY'; + case ModuleEnum.fastPass: + return 'FRE-HUB-FASTPASS'; + case ModuleEnum.visitors: + return 'FRE-HUB-VISITORS'; + case ModuleEnum.qrCode: + return 'FRE-HUB-QRCODE'; + case ModuleEnum.peopleOnTheProperty: + return 'FRE-HUB-PEOPLE'; + case ModuleEnum.petsHistory: + return 'FRE-HUB-PETS-HISTORY'; + default: + return ''; + } + } + + @override + String get name { + switch (this) { + case ModuleEnum.messages: + return FFLocalizations.of(navigatorKey.currentContext!).getVariableText( + ptText: 'Consultar Mensagens', + enText: 'Messages History', + ); + case ModuleEnum.liberations: + return FFLocalizations.of(navigatorKey.currentContext!).getVariableText( + ptText: 'Consultar Liberações', + enText: 'Liberations History', + ); + case ModuleEnum.reservations: + return FFLocalizations.of(navigatorKey.currentContext!).getVariableText( + ptText: 'Reservas', + enText: 'Reservations', + ); + case ModuleEnum.access: + return FFLocalizations.of(navigatorKey.currentContext!).getVariableText( + ptText: 'Consultar Acessos', + enText: 'Access History', + ); + case ModuleEnum.openedVisits: + return FFLocalizations.of(navigatorKey.currentContext!).getVariableText( + ptText: 'Visitas em Aberto', + enText: 'Opened Visits', + ); + case ModuleEnum.vehicles: + return FFLocalizations.of(navigatorKey.currentContext!).getVariableText( + ptText: 'Veículos', + enText: 'Vehicles', + ); + case ModuleEnum.residents: + return FFLocalizations.of(navigatorKey.currentContext!).getVariableText( + ptText: 'Moradores', + enText: 'Residents', + ); + case ModuleEnum.pets: + return FFLocalizations.of(navigatorKey.currentContext!).getVariableText( + ptText: 'Pets', + enText: 'Pets', + ); + case ModuleEnum.petsHistory: + return FFLocalizations.of(navigatorKey.currentContext!).getVariableText( + ptText: 'Pets', + enText: 'Pets', + ); + case ModuleEnum.peopleOnTheProperty: + return FFLocalizations.of(navigatorKey.currentContext!).getVariableText( + ptText: 'Pessoas na Propriedade', + enText: 'People on the Property', + ); + case ModuleEnum.orders: + return FFLocalizations.of(navigatorKey.currentContext!).getVariableText( + ptText: 'Minhas Encomendas', + enText: 'My Orders', + ); + case ModuleEnum.completeSchedule: + return FFLocalizations.of(navigatorKey.currentContext!).getVariableText( + ptText: 'Agenda Completa', + enText: 'Complete Schedule', + ); + case ModuleEnum.providerSchedule: + return FFLocalizations.of(navigatorKey.currentContext!).getVariableText( + ptText: 'Agendar Prestadores', + enText: 'Schedule Providers', + ); + case ModuleEnum.deliverySchedule: + return FFLocalizations.of(navigatorKey.currentContext!).getVariableText( + ptText: 'Agendar Delivery', + enText: 'Schedule Delivery', + ); + case ModuleEnum.fastPass: + return FFLocalizations.of(navigatorKey.currentContext!).getVariableText( + ptText: 'Fast Pass', + enText: 'Fast Pass', + ); + case ModuleEnum.qrCode: + return FFLocalizations.of(navigatorKey.currentContext!).getVariableText( + ptText: 'QRCode de Acesso', + enText: 'Access QRCode', + ); + case ModuleEnum.visitors: + return FFLocalizations.of(navigatorKey.currentContext!).getVariableText( + ptText: 'Cadastrar Visitantes', + enText: 'Register Visitors', + ); + case ModuleEnum.aboutProperty: + return FFLocalizations.of(navigatorKey.currentContext!).getVariableText( + ptText: 'Sobre a Propriedade', + enText: 'About the Property', + ); + case ModuleEnum.settings: + return FFLocalizations.of(navigatorKey.currentContext!).getVariableText( + ptText: 'Configurações', + enText: 'Settings', + ); + case ModuleEnum.logout: + return FFLocalizations.of(navigatorKey.currentContext!).getVariableText( + ptText: 'Sair', + enText: 'Logout', + ); + } + } + + @override + IconData get icon { + switch (this) { + case ModuleEnum.messages: + return Icons.chat_outlined; + case ModuleEnum.liberations: + return Icons.how_to_reg_outlined; + case ModuleEnum.reservations: + return Icons.event_available; + case ModuleEnum.access: + return Icons.transfer_within_a_station_outlined; + case ModuleEnum.openedVisits: + return Icons.perm_contact_calendar; + case ModuleEnum.vehicles: + return Icons.directions_car; + case ModuleEnum.residents: + return Icons.groups; + case ModuleEnum.pets: + return Icons.pets; + case ModuleEnum.petsHistory: + return Icons.pets; + case ModuleEnum.peopleOnTheProperty: + return Icons.groups; + case ModuleEnum.orders: + return Icons.inventory_2_outlined; + case ModuleEnum.completeSchedule: + return Icons.event; + case ModuleEnum.providerSchedule: + return Icons.engineering_outlined; + case ModuleEnum.deliverySchedule: + return Icons.sports_motorsports_outlined; + case ModuleEnum.fastPass: + return Icons.attach_email_outlined; + case ModuleEnum.qrCode: + return Icons.qr_code; + case ModuleEnum.visitors: + return Icons.person_add_alt_1_outlined; + case ModuleEnum.aboutProperty: + return Icons.home; + case ModuleEnum.settings: + return Icons.settings; + case ModuleEnum.logout: + return Icons.logout; + } + } + + @override + String get route { + switch (this) { + case ModuleEnum.messages: + return '/messageHistoryPage'; + case ModuleEnum.liberations: + return '/liberationHistory'; + case ModuleEnum.reservations: + return '/reservation'; + case ModuleEnum.access: + return '/acessHistoryPage'; + case ModuleEnum.openedVisits: + return '/visitsOnThePropertyPage'; + case ModuleEnum.vehicles: + return '/vehiclesOnThePropertyPage'; + case ModuleEnum.residents: + return '/residentsOnThePropertyPage'; + case ModuleEnum.pets: + return '/petsPage'; + case ModuleEnum.petsHistory: + return '/petsHistoryPage'; + case ModuleEnum.peopleOnTheProperty: + return '/peopleOnThePropertyPage'; + case ModuleEnum.orders: + return '/packageOrder'; + case ModuleEnum.completeSchedule: + return '/scheduleCompleteVisitPage'; + case ModuleEnum.providerSchedule: + return '/provisionalSchedule'; + case ModuleEnum.aboutProperty: + return '/aboutProperty'; + case ModuleEnum.deliverySchedule: + return '/deliverySchedule'; + case ModuleEnum.fastPass: + return '/fastPassPage'; + case ModuleEnum.qrCode: + return '/qrCodePage'; + case ModuleEnum.visitors: + return '/registerVisitorPage'; + case ModuleEnum.settings: + return '/preferencesSettings'; + case ModuleEnum.logout: + return '/WelcomePage'; + default: + return ''; + } + } +} diff --git a/lib/shared/components/molecules/modules/enums/inactive_modules.dart b/lib/shared/components/molecules/modules/enums/inactive_modules.dart new file mode 100644 index 00000000..ff2dbaa5 --- /dev/null +++ b/lib/shared/components/molecules/modules/enums/inactive_modules.dart @@ -0,0 +1,38 @@ +import 'package:flutter/material.dart'; +import 'package:hub/shared/components/molecules/modules/enums/enum_modules.dart'; +import 'package:hub/shared/components/molecules/modules/index.dart'; + +enum InactiveModuleKey implements BaseModule { + residents, + vehicles, + openedVisits, + petsHistory, + aboutProperty; + + @override + IconData get icon => throw UnimplementedError(); + + @override + String get name => throw UnimplementedError(); + + @override + String get route => throw UnimplementedError(); + + @override + 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'; + case InactiveModuleKey.aboutProperty: + return 'FRE-HUB-PROPERTY'; + default: + return ''; + } + } +} diff --git a/lib/shared/components/molecules/modules/enums/index.dart b/lib/shared/components/molecules/modules/enums/index.dart new file mode 100644 index 00000000..77515664 --- /dev/null +++ b/lib/shared/components/molecules/modules/enums/index.dart @@ -0,0 +1,4 @@ +export 'active_modules.dart'; +export 'disabled_modules.dart'; +export 'enum_modules.dart'; +export 'inactive_modules.dart'; diff --git a/lib/shared/components/molecules/modules/index.dart b/lib/shared/components/molecules/modules/index.dart new file mode 100644 index 00000000..d58702fc --- /dev/null +++ b/lib/shared/components/molecules/modules/index.dart @@ -0,0 +1,4 @@ +export 'data/index.dart'; +export 'domain/index.dart'; +export 'presentation/index.dart'; +export 'enums/index.dart'; diff --git a/lib/shared/components/molecules/modules/presentation/blocs/index.dart b/lib/shared/components/molecules/modules/presentation/blocs/index.dart new file mode 100644 index 00000000..e69de29b diff --git a/lib/shared/components/molecules/modules/presentation/index.dart b/lib/shared/components/molecules/modules/presentation/index.dart new file mode 100644 index 00000000..48b6447a --- /dev/null +++ b/lib/shared/components/molecules/modules/presentation/index.dart @@ -0,0 +1,3 @@ +export 'blocs/index.dart'; +export 'pages/index.dart'; +export 'widgets/index.dart'; diff --git a/lib/shared/components/molecules/modules/presentation/pages/index.dart b/lib/shared/components/molecules/modules/presentation/pages/index.dart new file mode 100644 index 00000000..e69de29b diff --git a/lib/shared/components/molecules/modules/presentation/widgets/index.dart b/lib/shared/components/molecules/modules/presentation/widgets/index.dart new file mode 100644 index 00000000..e69de29b