WIP
This commit is contained in:
parent
3b7a33801f
commit
7dd7ed7a32
|
@ -82,7 +82,7 @@ void main() {
|
||||||
// LocalsTest.unlinkLocal();
|
// LocalsTest.unlinkLocal();
|
||||||
|
|
||||||
VehicleTest.vehiclePage();
|
VehicleTest.vehiclePage();
|
||||||
VehicleTest.historyScreen();
|
// VehicleTest.historyScreen();
|
||||||
VehicleTest.registerScreen();
|
// VehicleTest.registerScreen();
|
||||||
VehicleTest.updateScreen();
|
// VehicleTest.updateScreen();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
part of 'app_test.dart';
|
part of 'app_test.dart';
|
||||||
|
|
||||||
Future<void> _loggedWithMultiLocalsAccount(PatrolIntegrationTester $,
|
Future<void> _loggedWithMultiLocalsAccount(PatrolIntegrationTester $, [bool forceLinkedLocal = true]) async {
|
||||||
[bool forceLinkedLocal = true]) async {
|
|
||||||
await _init($);
|
await _init($);
|
||||||
await StorageHelper() //
|
await StorageHelper() //
|
||||||
.set(SecureStorageKey.isLogged.value, 'true');
|
.set(SecureStorageKey.isLogged.value, 'true');
|
||||||
|
@ -19,18 +18,15 @@ Future<void> _loggedWithMultiLocalsAccount(PatrolIntegrationTester $,
|
||||||
await StorageHelper() //
|
await StorageHelper() //
|
||||||
.set(LocalsStorageKey.isNewVersion.key, true);
|
.set(LocalsStorageKey.isNewVersion.key, true);
|
||||||
if (forceLinkedLocal == true) {
|
if (forceLinkedLocal == true) {
|
||||||
await StorageHelper() //
|
await StorageHelper().set(ProfileStorageKey.clientUUID.key, '7');
|
||||||
.set(ProfileStorageKey.clientUUID.key, '7');
|
await StorageHelper().set(ProfileStorageKey.ownerUUID.key, '7');
|
||||||
await PhpGroup //
|
await StorageHelper().set(ProfileStorageKey.clientName.key, 'FRE ACCESS DEMO');
|
||||||
.resopndeVinculo
|
await PhpGroup.respondeVinculo.call(tarefa: 'A');
|
||||||
.call(tarefa: 'A');
|
await LicenseRepositoryImpl().resetLicense();
|
||||||
await LicenseRepositoryImpl() //
|
|
||||||
.resetLicense();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _loggedWithSomeoneLocalAccount(PatrolIntegrationTester $,
|
Future<void> _loggedWithSomeoneLocalAccount(PatrolIntegrationTester $, [bool forceLinkedLocal = true]) async {
|
||||||
[bool forceLinkedLocal = true]) async {
|
|
||||||
await _init($);
|
await _init($);
|
||||||
await StorageHelper() //
|
await StorageHelper() //
|
||||||
.set(SecureStorageKey.isLogged.value, 'true');
|
.set(SecureStorageKey.isLogged.value, 'true');
|
||||||
|
@ -48,13 +44,11 @@ Future<void> _loggedWithSomeoneLocalAccount(PatrolIntegrationTester $,
|
||||||
await StorageHelper() //
|
await StorageHelper() //
|
||||||
.set(LocalsStorageKey.isNewVersion.key, true);
|
.set(LocalsStorageKey.isNewVersion.key, true);
|
||||||
if (forceLinkedLocal == true) {
|
if (forceLinkedLocal == true) {
|
||||||
await StorageHelper() //
|
await StorageHelper().set(ProfileStorageKey.clientUUID.key, '7');
|
||||||
.set(ProfileStorageKey.clientUUID.key, '7');
|
await StorageHelper().set(ProfileStorageKey.ownerUUID.key, '7');
|
||||||
await PhpGroup //
|
await StorageHelper().set(ProfileStorageKey.clientName.key, 'FRE ACCESS DEMO');
|
||||||
.resopndeVinculo
|
await PhpGroup.respondeVinculo.call(tarefa: 'A');
|
||||||
.call(tarefa: 'A');
|
await LicenseRepositoryImpl().resetLicense();
|
||||||
await LicenseRepositoryImpl() //
|
|
||||||
.resetLicense();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,8 +95,7 @@ Future<void> _navigateToSignUp(PatrolIntegrationTester $) async {
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> _navigateBackUsingSystemGesture() async =>
|
Future<void> _navigateBackUsingSystemGesture() async =>
|
||||||
IntegrationTestWidgetsFlutterBinding.instance.keyboard
|
IntegrationTestWidgetsFlutterBinding.instance.keyboard.isLogicalKeyPressed(LogicalKeyboardKey.escape);
|
||||||
.isLogicalKeyPressed(LogicalKeyboardKey.escape);
|
|
||||||
|
|
||||||
Future<void> _initializeTracking() async {
|
Future<void> _initializeTracking() async {
|
||||||
print('Requesting tracking authorization...');
|
print('Requesting tracking authorization...');
|
||||||
|
|
|
@ -64,6 +64,74 @@ class VehicleTest {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
patrol(
|
||||||
|
'License',
|
||||||
|
(PatrolIntegrationTester tester) async {
|
||||||
|
$ = tester;
|
||||||
|
$.tester.printToConsole('Vehicle Page');
|
||||||
|
|
||||||
|
await _loggedWithMultiLocalsAccount($);
|
||||||
|
|
||||||
|
// await StorageHelper().set(
|
||||||
|
// LicenseKeys.vehiclesManager.value,
|
||||||
|
// <String, dynamic>{
|
||||||
|
// 'display': 'VISIVEL',
|
||||||
|
// 'expirationDate': '',
|
||||||
|
// 'startDate': '',
|
||||||
|
// 'quantity': 0,
|
||||||
|
// },
|
||||||
|
// );
|
||||||
|
// // await $.pumpAndSettle();
|
||||||
|
// ff.navigatorKey.currentContext!.go('/vehiclesOnThePropertyPage');
|
||||||
|
// await Future.delayed(const Duration(milliseconds: 1000));
|
||||||
|
|
||||||
|
await StorageHelper().set(
|
||||||
|
LicenseKeys.vehiclesManager.value,
|
||||||
|
<String, dynamic>{
|
||||||
|
'display': 'VISIVEL',
|
||||||
|
'expirationDate': '',
|
||||||
|
'startDate': '',
|
||||||
|
'quantity': 0,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
await $.pumpWidgetAndSettle(const App());
|
||||||
|
|
||||||
|
ff.navigatorKey.currentContext!.go('/vehiclesOnThePropertyPage');
|
||||||
|
final String title = MenuEntry.entries //
|
||||||
|
.where((entry) => entry.key == 'FRE-HUB-VEHICLES') //
|
||||||
|
.map((entry) => entry.name)
|
||||||
|
.first;
|
||||||
|
|
||||||
|
final PatrolFinder appBar = await $(AppBar) //
|
||||||
|
.waitUntilExists();
|
||||||
|
final PatrolFinder titleAppBar = await appBar //
|
||||||
|
.$(title)
|
||||||
|
.waitUntilVisible();
|
||||||
|
expect(titleAppBar, findsOneWidget);
|
||||||
|
|
||||||
|
final PatrolFinder tab1 = await $(#TabView_Tab1) //
|
||||||
|
.waitUntilExists();
|
||||||
|
final PatrolFinder tab2 = await $(#TabView_Tab2) //
|
||||||
|
.waitUntilExists();
|
||||||
|
|
||||||
|
await tab2.tap();
|
||||||
|
await Future.delayed(const Duration(milliseconds: 500));
|
||||||
|
await tab1.tap();
|
||||||
|
|
||||||
|
final PatrolFinder listViewFinder = await $(VehicleHistoryScreen) //
|
||||||
|
.$(ListView)
|
||||||
|
.waitUntilVisible();
|
||||||
|
|
||||||
|
expect(listViewFinder, findsOneWidget);
|
||||||
|
|
||||||
|
final PatrolFinder entriesFinder =
|
||||||
|
await $(listViewFinder).$(CardItemTemplateComponentWidget).waitUntilVisible();
|
||||||
|
|
||||||
|
expect(entriesFinder, findsWidgets);
|
||||||
|
await $.pumpAndSettle();
|
||||||
|
await Future.delayed(const Duration(milliseconds: 1000));
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<void> historyScreen() async {
|
static Future<void> historyScreen() async {
|
||||||
|
|
|
@ -19,12 +19,10 @@ class BottomArrowLinkedLocalsComponentWidget extends StatefulWidget {
|
||||||
ApiCallResponse? response;
|
ApiCallResponse? response;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
State<BottomArrowLinkedLocalsComponentWidget> createState() =>
|
State<BottomArrowLinkedLocalsComponentWidget> createState() => _BottomArrowLinkedLocalsComponentWidgetState();
|
||||||
_BottomArrowLinkedLocalsComponentWidgetState();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class _BottomArrowLinkedLocalsComponentWidgetState
|
class _BottomArrowLinkedLocalsComponentWidgetState extends State<BottomArrowLinkedLocalsComponentWidget> {
|
||||||
extends State<BottomArrowLinkedLocalsComponentWidget> {
|
|
||||||
late BottomArrowLinkedLocalsComponentModel _model;
|
late BottomArrowLinkedLocalsComponentModel _model;
|
||||||
|
|
||||||
bool _loading = false;
|
bool _loading = false;
|
||||||
|
@ -42,8 +40,7 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
||||||
@override
|
@override
|
||||||
void initState() {
|
void initState() {
|
||||||
super.initState();
|
super.initState();
|
||||||
_model =
|
_model = createModel(context, () => BottomArrowLinkedLocalsComponentModel());
|
||||||
createModel(context, () => BottomArrowLinkedLocalsComponentModel());
|
|
||||||
_localsFuture = _fetchLocals();
|
_localsFuture = _fetchLocals();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,14 +106,10 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
||||||
if (isEnabled) {
|
if (isEnabled) {
|
||||||
final local = locals[0];
|
final local = locals[0];
|
||||||
|
|
||||||
await StorageHelper()
|
await StorageHelper().set(ProfileStorageKey.clientName.key, local['CLI_NOME']);
|
||||||
.set(ProfileStorageKey.clientName.key, local['CLI_NOME']);
|
await StorageHelper().set(ProfileStorageKey.ownerName.key, local['CLU_OWNER_DSC']);
|
||||||
await StorageHelper()
|
await StorageHelper().set(ProfileStorageKey.clientUUID.key, local['CLI_ID']);
|
||||||
.set(ProfileStorageKey.ownerName.key, local['CLU_OWNER_DSC']);
|
await StorageHelper().set(ProfileStorageKey.ownerUUID.key, local['CLU_OWNER_ID']);
|
||||||
await StorageHelper()
|
|
||||||
.set(ProfileStorageKey.clientUUID.key, local['CLI_ID']);
|
|
||||||
await StorageHelper()
|
|
||||||
.set(ProfileStorageKey.ownerUUID.key, local['CLU_OWNER_ID']);
|
|
||||||
|
|
||||||
context.pop();
|
context.pop();
|
||||||
return widget.response;
|
return widget.response;
|
||||||
|
@ -140,22 +133,20 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<void> _handleError(
|
static Future<void> _handleError(BuildContext context, String errorMsg) async {
|
||||||
BuildContext context, String errorMsg) async {
|
|
||||||
await DialogUtil.error(context, errorMsg);
|
await DialogUtil.error(context, errorMsg);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<dynamic> _fetchResponseLink(String status, String cliID) async {
|
Future<dynamic> _fetchResponseLink(String status, String cliID) async {
|
||||||
try {
|
try {
|
||||||
await StorageHelper().set(ProfileStorageKey.clientUUID.key, cliID);
|
await StorageHelper().set(ProfileStorageKey.clientUUID.key, cliID);
|
||||||
var response = await PhpGroup.resopndeVinculo.call(tarefa: status);
|
var response = await PhpGroup.respondeVinculo.call(tarefa: status);
|
||||||
|
|
||||||
if (response.jsonBody['error'] == false) {
|
if (response.jsonBody['error'] == false) {
|
||||||
return {
|
return {
|
||||||
'error': false,
|
'error': false,
|
||||||
'error_msg': FFLocalizations.of(context).getVariableText(
|
'error_msg': FFLocalizations.of(context)
|
||||||
ptText: "Vínculo Ativado com Sucesso",
|
.getVariableText(ptText: "Vínculo Ativado com Sucesso", enText: "Link Activated Successfully")
|
||||||
enText: "Link Activated Successfully")
|
|
||||||
};
|
};
|
||||||
} else {
|
} else {
|
||||||
await StorageHelper().set(ProfileStorageKey.clientUUID.key, '');
|
await StorageHelper().set(ProfileStorageKey.clientUUID.key, '');
|
||||||
|
@ -163,8 +154,7 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
||||||
}
|
}
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
await DialogUtil.errorDefault(context);
|
await DialogUtil.errorDefault(context);
|
||||||
LogUtil.requestAPIFailed(
|
LogUtil.requestAPIFailed('responderVinculo.php', '', 'Responder Vínculo', e, s);
|
||||||
'responderVinculo.php', '', 'Responder Vínculo', e, s);
|
|
||||||
return {
|
return {
|
||||||
'error': true,
|
'error': true,
|
||||||
'error_msg': FFLocalizations.of(context).getVariableText(
|
'error_msg': FFLocalizations.of(context).getVariableText(
|
||||||
|
@ -189,17 +179,14 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
||||||
Map<String, Color> _statusHashMap(dynamic local) {
|
Map<String, Color> _statusHashMap(dynamic local) {
|
||||||
return Map<String, Color>.from({
|
return Map<String, Color>.from({
|
||||||
if (local['CLU_STATUS'] == 'A')
|
if (local['CLU_STATUS'] == 'A')
|
||||||
FFLocalizations.of(context).getVariableText(
|
FFLocalizations.of(context).getVariableText(ptText: 'Ativo', enText: 'Active'):
|
||||||
ptText: 'Ativo',
|
FlutterFlowTheme.of(context).success
|
||||||
enText: 'Active'): FlutterFlowTheme.of(context).success
|
|
||||||
else if (local['CLU_STATUS'] == 'B')
|
else if (local['CLU_STATUS'] == 'B')
|
||||||
FFLocalizations.of(context).getVariableText(
|
FFLocalizations.of(context).getVariableText(ptText: 'Bloqueado', enText: 'Blocked'):
|
||||||
ptText: 'Bloqueado',
|
FlutterFlowTheme.of(context).error
|
||||||
enText: 'Blocked'): FlutterFlowTheme.of(context).error
|
|
||||||
else
|
else
|
||||||
FFLocalizations.of(context).getVariableText(
|
FFLocalizations.of(context).getVariableText(ptText: 'Pendente', enText: 'Pending'):
|
||||||
ptText: 'Pendente',
|
FlutterFlowTheme.of(context).warning
|
||||||
enText: 'Pending'): FlutterFlowTheme.of(context).warning
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -212,21 +199,16 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
||||||
statusHashMap: [_statusHashMap(local)],
|
statusHashMap: [_statusHashMap(local)],
|
||||||
onTapCardItemAction: () async {
|
onTapCardItemAction: () async {
|
||||||
if (local['CLU_STATUS'] == 'A') {
|
if (local['CLU_STATUS'] == 'A') {
|
||||||
await StorageHelper()
|
await StorageHelper().set(ProfileStorageKey.clientUUID.key, local['CLI_ID']);
|
||||||
.set(ProfileStorageKey.clientUUID.key, local['CLI_ID']);
|
await StorageHelper().set(ProfileStorageKey.clientName.key, local['CLI_NOME']);
|
||||||
await StorageHelper()
|
await StorageHelper().set(ProfileStorageKey.ownerName.key, local['CLU_OWNER_DSC']);
|
||||||
.set(ProfileStorageKey.clientName.key, local['CLI_NOME']);
|
await StorageHelper().set(ProfileStorageKey.ownerUUID.key, local['CLU_OWNER_ID']);
|
||||||
await StorageHelper()
|
|
||||||
.set(ProfileStorageKey.ownerName.key, local['CLU_OWNER_DSC']);
|
|
||||||
await StorageHelper()
|
|
||||||
.set(ProfileStorageKey.ownerUUID.key, local['CLU_OWNER_ID']);
|
|
||||||
|
|
||||||
context.pop(true);
|
context.pop(true);
|
||||||
return true;
|
return true;
|
||||||
} else if (local['CLU_STATUS'] == 'B') {
|
} else if (local['CLU_STATUS'] == 'B') {
|
||||||
String message = FFLocalizations.of(context).getVariableText(
|
String message = FFLocalizations.of(context).getVariableText(
|
||||||
ptText:
|
ptText: 'Local Bloqueado para Acesso, Entre em Contato com Administração',
|
||||||
'Local Bloqueado para Acesso, Entre em Contato com Administração',
|
|
||||||
enText: 'Location Blocked for Access, Contact Administration',
|
enText: 'Location Blocked for Access, Contact Administration',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -242,8 +224,7 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
||||||
String localName = local['CLI_NOME'];
|
String localName = local['CLI_NOME'];
|
||||||
showAlertDialog(
|
showAlertDialog(
|
||||||
context,
|
context,
|
||||||
FFLocalizations.of(context).getVariableText(
|
FFLocalizations.of(context).getVariableText(ptText: 'Ativar Vínculo', enText: 'Activate Link'),
|
||||||
ptText: 'Ativar Vínculo', enText: 'Activate Link'),
|
|
||||||
FFLocalizations.of(context).getVariableText(
|
FFLocalizations.of(context).getVariableText(
|
||||||
ptText: 'Deseja aceitar o vínculo a $localName?',
|
ptText: 'Deseja aceitar o vínculo a $localName?',
|
||||||
enText: 'Do you wish to accept the link to $localName?'),
|
enText: 'Do you wish to accept the link to $localName?'),
|
||||||
|
@ -300,8 +281,7 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
||||||
height: height - (height * 0.5),
|
height: height - (height * 0.5),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: FlutterFlowTheme.of(context).primaryBackground,
|
color: FlutterFlowTheme.of(context).primaryBackground,
|
||||||
borderRadius: const BorderRadius.only(
|
borderRadius: const BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25))),
|
||||||
topLeft: Radius.circular(25), topRight: Radius.circular(25))),
|
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
mainAxisAlignment: MainAxisAlignment.start,
|
mainAxisAlignment: MainAxisAlignment.start,
|
||||||
|
@ -313,16 +293,13 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
children: [
|
children: [
|
||||||
Center(
|
Center(
|
||||||
child: Text(FFLocalizations.of(context).getVariableText(
|
child: Text(FFLocalizations.of(context)
|
||||||
ptText: "Nenhum Local Encontrado.",
|
.getVariableText(ptText: "Nenhum Local Encontrado.", enText: "No local found")),
|
||||||
enText: "No local found")),
|
|
||||||
)
|
)
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
else if (_hasData == true &&
|
else if (_hasData == true && _loading == false && _localsWrap.isNotEmpty)
|
||||||
_loading == false &&
|
|
||||||
_localsWrap.isNotEmpty)
|
|
||||||
Expanded(child: _listItems(context)),
|
Expanded(child: _listItems(context)),
|
||||||
if (_loading == true)
|
if (_loading == true)
|
||||||
Container(
|
Container(
|
||||||
|
@ -339,8 +316,7 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
||||||
padding: const EdgeInsets.only(top: 10),
|
padding: const EdgeInsets.only(top: 10),
|
||||||
child: Center(
|
child: Center(
|
||||||
child: Text(
|
child: Text(
|
||||||
FFLocalizations.of(context).getVariableText(
|
FFLocalizations.of(context).getVariableText(ptText: 'Escolha um local', enText: 'Choose a location'),
|
||||||
ptText: 'Escolha um local', enText: 'Choose a location'),
|
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||||
)))),
|
)))),
|
||||||
|
|
|
@ -47,7 +47,7 @@ class PhpGroup extends Api {
|
||||||
static GetMessagesCall getMessagesCall = GetMessagesCall();
|
static GetMessagesCall getMessagesCall = GetMessagesCall();
|
||||||
static ChangeNotifica changeNotifica = ChangeNotifica();
|
static ChangeNotifica changeNotifica = ChangeNotifica();
|
||||||
static UpdateIDE updateIDE = UpdateIDE();
|
static UpdateIDE updateIDE = UpdateIDE();
|
||||||
static RespondeVinculo resopndeVinculo = RespondeVinculo();
|
static RespondeVinculo respondeVinculo = RespondeVinculo();
|
||||||
static ChangePass changePass = ChangePass();
|
static ChangePass changePass = ChangePass();
|
||||||
static ChangePanic changePanic = ChangePanic();
|
static ChangePanic changePanic = ChangePanic();
|
||||||
static DeleteAccount deleteAccount = DeleteAccount();
|
static DeleteAccount deleteAccount = DeleteAccount();
|
||||||
|
|
|
@ -224,7 +224,7 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource {
|
||||||
enText: 'Device unlinked successfully',
|
enText: 'Device unlinked successfully',
|
||||||
ptText: 'Dispositivo desvinculado com sucesso',
|
ptText: 'Dispositivo desvinculado com sucesso',
|
||||||
);
|
);
|
||||||
final bool status = await PhpGroup.resopndeVinculo.call(tarefa: 'I').then((value) async {
|
final bool status = await PhpGroup.respondeVinculo.call(tarefa: 'I').then((value) async {
|
||||||
if (value.jsonBody['error'] == false) {
|
if (value.jsonBody['error'] == false) {
|
||||||
await StorageHelper().set(ProfileStorageKey.clientName.key, '');
|
await StorageHelper().set(ProfileStorageKey.clientName.key, '');
|
||||||
await StorageHelper().set(ProfileStorageKey.ownerName.key, '');
|
await StorageHelper().set(ProfileStorageKey.ownerName.key, '');
|
||||||
|
|
|
@ -11,13 +11,10 @@ import 'package:hub/shared/utils/log_util.dart';
|
||||||
|
|
||||||
class LocalUtil {
|
class LocalUtil {
|
||||||
static void handleError(BuildContext context, String errorMsg) async {
|
static void handleError(BuildContext context, String errorMsg) async {
|
||||||
final String devUUID =
|
final String devUUID = await StorageHelper().get(ProfileStorageKey.devUUID.key) ?? '';
|
||||||
await StorageHelper().get(ProfileStorageKey.devUUID.key) ?? '';
|
final String userUUID = await StorageHelper().get(ProfileStorageKey.userUUID.key) ?? '';
|
||||||
final String userUUID =
|
|
||||||
await StorageHelper().get(ProfileStorageKey.userUUID.key) ?? '';
|
|
||||||
final bool isAuthenticated = userUUID.isNotEmpty && devUUID.isNotEmpty;
|
final bool isAuthenticated = userUUID.isNotEmpty && devUUID.isNotEmpty;
|
||||||
final bool isDevLinked =
|
final bool isDevLinked = !errorMsg.contains('Esse dispositivo nao pertence a esse usuario');
|
||||||
!errorMsg.contains('Esse dispositivo nao pertence a esse usuario');
|
|
||||||
log('() => isLinked: $errorMsg');
|
log('() => isLinked: $errorMsg');
|
||||||
if (!isAuthenticated) {
|
if (!isAuthenticated) {
|
||||||
errorMsg = FFLocalizations.of(context).getVariableText(
|
errorMsg = FFLocalizations.of(context).getVariableText(
|
||||||
|
@ -39,20 +36,15 @@ class LocalUtil {
|
||||||
// await DialogUtil.error(context, errorMsg).whenComplete(() async => await LocalsRemoteDataSourceImpl().selectLocal(context, null));
|
// await DialogUtil.error(context, errorMsg).whenComplete(() async => await LocalsRemoteDataSourceImpl().selectLocal(context, null));
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<bool> handleUnavailable(
|
static Future<bool> handleUnavailable(BuildContext context, List<dynamic> locals) async {
|
||||||
BuildContext context, List<dynamic> locals) async {
|
|
||||||
log('() => isUnavailable');
|
log('() => isUnavailable');
|
||||||
try {
|
try {
|
||||||
await StorageHelper()
|
await StorageHelper().set(ProfileStorageKey.clientUUID.key, locals[0]['CLI_ID']);
|
||||||
.set(ProfileStorageKey.clientUUID.key, locals[0]['CLI_ID']);
|
await StorageHelper().set(ProfileStorageKey.ownerUUID.key, locals[0]['CLU_OWNER_ID']);
|
||||||
await StorageHelper()
|
await StorageHelper().set(ProfileStorageKey.clientName.key, locals[0]['CLI_NOME']);
|
||||||
.set(ProfileStorageKey.ownerUUID.key, locals[0]['CLU_OWNER_ID']);
|
await StorageHelper().set(ProfileStorageKey.ownerName.key, locals[0]['CLU_OWNER_DSC']);
|
||||||
await StorageHelper()
|
|
||||||
.set(ProfileStorageKey.clientName.key, locals[0]['CLI_NOME']);
|
|
||||||
await StorageHelper()
|
|
||||||
.set(ProfileStorageKey.ownerName.key, locals[0]['CLU_OWNER_DSC']);
|
|
||||||
|
|
||||||
var response = await PhpGroup.resopndeVinculo.call(tarefa: 'A');
|
var response = await PhpGroup.respondeVinculo.call(tarefa: 'A');
|
||||||
if (response.jsonBody['error'] == true) {
|
if (response.jsonBody['error'] == true) {
|
||||||
await StorageHelper().set(ProfileStorageKey.clientUUID.key, '');
|
await StorageHelper().set(ProfileStorageKey.clientUUID.key, '');
|
||||||
await StorageHelper().set(ProfileStorageKey.ownerUUID.key, '');
|
await StorageHelper().set(ProfileStorageKey.ownerUUID.key, '');
|
||||||
|
@ -62,13 +54,10 @@ class LocalUtil {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (response.jsonBody['error'] == false)
|
if (response.jsonBody['error'] == false)
|
||||||
return await LocalsRemoteDataSourceImpl()
|
return await LocalsRemoteDataSourceImpl().processProperty(context).then((value) => value);
|
||||||
.processProperty(context)
|
|
||||||
.then((value) => value);
|
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
await DialogUtil.errorDefault(context);
|
await DialogUtil.errorDefault(context);
|
||||||
LogUtil.requestAPIFailed(
|
LogUtil.requestAPIFailed('responderVinculo.php', '', 'Responder Vínculo', e, s);
|
||||||
'responderVinculo.php', '', 'Responder Vínculo', e, s);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -76,19 +65,12 @@ class LocalUtil {
|
||||||
|
|
||||||
static Future<bool> handleEnabled(BuildContext context, dynamic local) async {
|
static Future<bool> handleEnabled(BuildContext context, dynamic local) async {
|
||||||
log('() => isEnabled');
|
log('() => isEnabled');
|
||||||
await StorageHelper()
|
await StorageHelper().set(ProfileStorageKey.clientUUID.key, local['CLI_ID']);
|
||||||
.set(ProfileStorageKey.clientUUID.key, local['CLI_ID']);
|
await StorageHelper().set(ProfileStorageKey.ownerUUID.key, local['CLU_OWNER_ID']);
|
||||||
await StorageHelper()
|
await StorageHelper().set(ProfileStorageKey.clientName.key, local['CLI_NOME']);
|
||||||
.set(ProfileStorageKey.ownerUUID.key, local['CLU_OWNER_ID']);
|
await StorageHelper().set(ProfileStorageKey.ownerName.key, local['CLU_OWNER_DSC']);
|
||||||
await StorageHelper()
|
await StorageHelper().set(ProfileStorageKey.userName.key, local['USU_NOME']);
|
||||||
.set(ProfileStorageKey.clientName.key, local['CLI_NOME']);
|
return await LocalsRemoteDataSourceImpl().processProperty(context).then((v) async {
|
||||||
await StorageHelper()
|
|
||||||
.set(ProfileStorageKey.ownerName.key, local['CLU_OWNER_DSC']);
|
|
||||||
await StorageHelper()
|
|
||||||
.set(ProfileStorageKey.userName.key, local['USU_NOME']);
|
|
||||||
return await LocalsRemoteDataSourceImpl()
|
|
||||||
.processProperty(context)
|
|
||||||
.then((v) async {
|
|
||||||
if (v == true) return await LicenseRepositoryImpl().updateLicense();
|
if (v == true) return await LicenseRepositoryImpl().updateLicense();
|
||||||
return v;
|
return v;
|
||||||
});
|
});
|
||||||
|
@ -111,10 +93,8 @@ class LocalUtil {
|
||||||
|
|
||||||
static Future<bool> updateStorageUtil(Map<String, dynamic> jsonBody) async {
|
static Future<bool> updateStorageUtil(Map<String, dynamic> jsonBody) async {
|
||||||
try {
|
try {
|
||||||
await StorageHelper()
|
await StorageHelper().set(LocalsStorageKey.whatsapp.key, jsonBody['whatsapp'] ?? false);
|
||||||
.set(LocalsStorageKey.whatsapp.key, jsonBody['whatsapp'] ?? false);
|
await StorageHelper().set(LocalsStorageKey.provisional.key, jsonBody['provisional'] ?? false);
|
||||||
await StorageHelper().set(
|
|
||||||
LocalsStorageKey.provisional.key, jsonBody['provisional'] ?? false);
|
|
||||||
await StorageHelper().set(
|
await StorageHelper().set(
|
||||||
LocalsStorageKey.pets.key,
|
LocalsStorageKey.pets.key,
|
||||||
jsonBody['pet'] ?? false,
|
jsonBody['pet'] ?? false,
|
||||||
|
@ -136,21 +116,14 @@ class LocalUtil {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
await StorageHelper().set(
|
await StorageHelper().set(LocalsStorageKey.petAmount.key,
|
||||||
LocalsStorageKey.petAmount.key,
|
jsonBody['petAmountRegister']?.toString().isEmpty ?? true ? '0' : jsonBody['petAmountRegister'].toString());
|
||||||
jsonBody['petAmountRegister']?.toString().isEmpty ?? true
|
await StorageHelper().set(ProfileStorageKey.userName.key, jsonBody['visitado']['VDO_NOME'] ?? '');
|
||||||
? '0'
|
await StorageHelper().set(ProfileStorageKey.userEmail.key, jsonBody['visitado']['VDO_EMAIL'] ?? '');
|
||||||
: jsonBody['petAmountRegister'].toString());
|
await StorageHelper().set(LocalsStorageKey.provisional.key, jsonBody['provisional'] ?? false);
|
||||||
await StorageHelper().set(ProfileStorageKey.userName.key,
|
|
||||||
jsonBody['visitado']['VDO_NOME'] ?? '');
|
|
||||||
await StorageHelper().set(ProfileStorageKey.userEmail.key,
|
|
||||||
jsonBody['visitado']['VDO_EMAIL'] ?? '');
|
|
||||||
await StorageHelper().set(
|
|
||||||
LocalsStorageKey.provisional.key, jsonBody['provisional'] ?? false);
|
|
||||||
|
|
||||||
final bool isNewVersion = jsonBody['newVersion'] ?? false;
|
final bool isNewVersion = jsonBody['newVersion'] ?? false;
|
||||||
await StorageHelper()
|
await StorageHelper().set(LocalsStorageKey.isNewVersion.key, isNewVersion);
|
||||||
.set(LocalsStorageKey.isNewVersion.key, isNewVersion);
|
|
||||||
return isNewVersion;
|
return isNewVersion;
|
||||||
} catch (e, s) {
|
} catch (e, s) {
|
||||||
log('Error in _updateStorageUtil: $e', stackTrace: s);
|
log('Error in _updateStorageUtil: $e', stackTrace: s);
|
||||||
|
@ -163,44 +136,30 @@ class LocalUtil {
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<bool> isInactived(List<dynamic> locals) async {
|
static Future<bool> isInactived(List<dynamic> locals) async {
|
||||||
String cliUUID =
|
String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? '';
|
||||||
(await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? '';
|
return locals.where((local) => local['CLI_ID'] != cliUUID && local['CLU_STATUS'] == 'A').isNotEmpty;
|
||||||
return locals
|
|
||||||
.where(
|
|
||||||
(local) => local['CLI_ID'] != cliUUID && local['CLU_STATUS'] == 'A')
|
|
||||||
.isNotEmpty;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool isPending(List<dynamic> locals) {
|
static bool isPending(List<dynamic> locals) {
|
||||||
return locals
|
return locals.where((local) => local['CLU_STATUS'] != 'B' && local['CLU_STATUS'] != 'A').isNotEmpty;
|
||||||
.where(
|
|
||||||
(local) => local['CLU_STATUS'] != 'B' && local['CLU_STATUS'] != 'A')
|
|
||||||
.isNotEmpty;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<bool> isUnselected() async {
|
static Future<bool> isUnselected() async {
|
||||||
String cliUUID =
|
String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? '';
|
||||||
(await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? '';
|
String cliName = (await StorageHelper().get(ProfileStorageKey.clientName.key)) ?? '';
|
||||||
String cliName =
|
String ownerUUID = (await StorageHelper().get(ProfileStorageKey.ownerUUID.key)) ?? '';
|
||||||
(await StorageHelper().get(ProfileStorageKey.clientName.key)) ?? '';
|
|
||||||
String ownerUUID =
|
|
||||||
(await StorageHelper().get(ProfileStorageKey.ownerUUID.key)) ?? '';
|
|
||||||
return cliUUID.isEmpty && cliName.isEmpty && ownerUUID.isEmpty;
|
return cliUUID.isEmpty && cliName.isEmpty && ownerUUID.isEmpty;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<bool> isSelected(bool isInactived) async {
|
static Future<bool> isSelected(bool isInactived) async {
|
||||||
String cliUUID =
|
String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? '';
|
||||||
(await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? '';
|
String cliName = (await StorageHelper().get(ProfileStorageKey.clientName.key)) ?? '';
|
||||||
String cliName =
|
|
||||||
(await StorageHelper().get(ProfileStorageKey.clientName.key)) ?? '';
|
|
||||||
return cliUUID.isNotEmpty && cliName.isNotEmpty && isInactived;
|
return cliUUID.isNotEmpty && cliName.isNotEmpty && isInactived;
|
||||||
}
|
}
|
||||||
|
|
||||||
static Future<bool> isAvailable() async {
|
static Future<bool> isAvailable() async {
|
||||||
String cliUUID =
|
String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? '';
|
||||||
(await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? '';
|
String cliName = (await StorageHelper().get(ProfileStorageKey.clientName.key)) ?? '';
|
||||||
String cliName =
|
|
||||||
(await StorageHelper().get(ProfileStorageKey.clientName.key)) ?? '';
|
|
||||||
return cliUUID.isNotEmpty && cliName.isNotEmpty;
|
return cliUUID.isNotEmpty && cliName.isNotEmpty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,23 +9,16 @@ import 'package:hub/shared/extensions/dialog_extensions.dart';
|
||||||
import 'package:hub/shared/utils/path_util.dart';
|
import 'package:hub/shared/utils/path_util.dart';
|
||||||
|
|
||||||
abstract class MenuLocalDataSource {
|
abstract class MenuLocalDataSource {
|
||||||
Future<MenuItem?> addMenuEntry(Key key, EnumMenuItem item,
|
Future<MenuItem?> addMenuEntry(
|
||||||
List<MenuItem?> entries, IconData icon, String text, Function() action);
|
Key key, EnumMenuItem item, List<MenuItem?> entries, IconData icon, String text, Function() action);
|
||||||
|
|
||||||
Future<bool> processDisplayDefault(
|
Future<bool> processDisplayDefault(EnumMenuItem item, MenuEntry opt, List<MenuItem?> entries);
|
||||||
EnumMenuItem item, MenuEntry opt, List<MenuItem?> entries);
|
|
||||||
|
|
||||||
Future<void> handleMenu(EnumMenuItem item, EnumDisplay display, MenuEntry opt,
|
Future<void> handleMenu(EnumMenuItem item, EnumDisplay display, MenuEntry opt, List<MenuItem?> entries);
|
||||||
List<MenuItem?> entries);
|
|
||||||
|
|
||||||
Future<bool> processStartDate(String startDate, MenuEntry entry);
|
|
||||||
|
|
||||||
Future<bool> processExpirationDate(String expirationDate, MenuEntry entry);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class MenuLocalDataSourceImpl implements MenuLocalDataSource {
|
class MenuLocalDataSourceImpl implements MenuLocalDataSource {
|
||||||
static final MenuLocalDataSourceImpl _instance =
|
static final MenuLocalDataSourceImpl _instance = MenuLocalDataSourceImpl._internal();
|
||||||
MenuLocalDataSourceImpl._internal();
|
|
||||||
|
|
||||||
factory MenuLocalDataSourceImpl() => _instance;
|
factory MenuLocalDataSourceImpl() => _instance;
|
||||||
|
|
||||||
|
@ -52,12 +45,9 @@ class MenuLocalDataSourceImpl implements MenuLocalDataSource {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<bool> processDisplayDefault(
|
Future<bool> processDisplayDefault(EnumMenuItem item, MenuEntry opt, List<MenuItem?> entries) async {
|
||||||
EnumMenuItem item, MenuEntry opt, List<MenuItem?> entries) async {
|
|
||||||
if (opt.key == 'FRE-HUB-LOGOUT') {
|
if (opt.key == 'FRE-HUB-LOGOUT') {
|
||||||
await addMenuEntry(
|
await addMenuEntry(ValueKey<String>(opt.key), item, entries, opt.icon, opt.name, () async {
|
||||||
ValueKey<String>(opt.key), item, entries, opt.icon, opt.name,
|
|
||||||
() async {
|
|
||||||
await AuthenticationService.signOut(navigatorKey.currentContext!);
|
await AuthenticationService.signOut(navigatorKey.currentContext!);
|
||||||
});
|
});
|
||||||
return true;
|
return true;
|
||||||
|
@ -66,23 +56,17 @@ class MenuLocalDataSourceImpl implements MenuLocalDataSource {
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<void> handleMenu(EnumMenuItem item, EnumDisplay display, MenuEntry opt,
|
Future<void> handleMenu(EnumMenuItem item, EnumDisplay display, MenuEntry opt, List<MenuItem?> entries) async {
|
||||||
List<MenuItem?> entries) async {
|
|
||||||
try {
|
try {
|
||||||
switch (display.value) {
|
switch (display.value) {
|
||||||
case 'VISIVEL':
|
case 'VISIVEL':
|
||||||
await addMenuEntry(
|
await addMenuEntry(ValueKey<String>(opt.key), item, entries, opt.icon, opt.name, () async {
|
||||||
ValueKey<String>(opt.key), item, entries, opt.icon, opt.name,
|
|
||||||
() async {
|
|
||||||
await PathUtil.nav(opt.route);
|
await PathUtil.nav(opt.route);
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 'DESABILITADO':
|
case 'DESABILITADO':
|
||||||
await addMenuEntry(
|
await addMenuEntry(ValueKey<String>(opt.key), item, entries, opt.icon, opt.name, () async {
|
||||||
ValueKey<String>(opt.key), item, entries, opt.icon, opt.name,
|
await DialogUnavailable.unavailableFeature(navigatorKey.currentContext!);
|
||||||
() async {
|
|
||||||
await DialogUnavailable.unavailableFeature(
|
|
||||||
navigatorKey.currentContext!);
|
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
case 'INVISIVEL':
|
case 'INVISIVEL':
|
||||||
|
@ -92,30 +76,4 @@ class MenuLocalDataSourceImpl implements MenuLocalDataSource {
|
||||||
log('Error processing display for module ${opt.key}: $e');
|
log('Error processing display for module ${opt.key}: $e');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
|
||||||
Future<bool> processStartDate(String startDate, MenuEntry opt) async {
|
|
||||||
try {
|
|
||||||
if (startDate.isEmpty) return true;
|
|
||||||
final start = DateTime.tryParse(startDate);
|
|
||||||
if (start == null) return false;
|
|
||||||
return DateTime.now().isAfter(start);
|
|
||||||
} catch (e) {
|
|
||||||
log('Error processing start date for module ${opt.key}: $e');
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
@override
|
|
||||||
Future<bool> processExpirationDate(
|
|
||||||
String expirationDate, MenuEntry opt) async {
|
|
||||||
try {
|
|
||||||
if (expirationDate.isEmpty) return false;
|
|
||||||
final expiration = DateTime.tryParse(expirationDate);
|
|
||||||
return expiration != null && DateTime.now().isAfter(expiration);
|
|
||||||
} catch (e) {
|
|
||||||
log('Error processing expiration date for module ${opt.key}: $e');
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,20 +4,19 @@ import 'package:hub/features/menu/index.dart';
|
||||||
import 'package:hub/features/module/index.dart';
|
import 'package:hub/features/module/index.dart';
|
||||||
import 'package:hub/features/storage/index.dart';
|
import 'package:hub/features/storage/index.dart';
|
||||||
import 'package:hub/flutter_flow/custom_functions.dart';
|
import 'package:hub/flutter_flow/custom_functions.dart';
|
||||||
|
import 'package:hub/shared/utils/datetime_util.dart';
|
||||||
|
|
||||||
class MenuRepositoryImpl implements MenuRepository {
|
class MenuRepositoryImpl implements MenuRepository {
|
||||||
final MenuLocalDataSource menuDataSource = MenuLocalDataSourceImpl();
|
final MenuLocalDataSource menuDataSource = MenuLocalDataSourceImpl();
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Future<List<MenuItem?>> entries2Items(
|
Future<List<MenuItem?>> entries2Items(List<MenuEntry> menuEntries, EnumMenuItem menuItem) async {
|
||||||
List<MenuEntry> menuEntries, EnumMenuItem menuItem) async {
|
|
||||||
List<MenuItem?> entries = [];
|
List<MenuItem?> entries = [];
|
||||||
// final bool isNewVersion = await StorageHelper().get(KeychainStorageKey.isNewVersion.value).then((v) => v.toBoolean());
|
// final bool isNewVersion = await StorageHelper().get(KeychainStorageKey.isNewVersion.value).then((v) => v.toBoolean());
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (var entry in menuEntries) {
|
for (var entry in menuEntries) {
|
||||||
final bool isDefault = await menuDataSource.processDisplayDefault(
|
final bool isDefault = await menuDataSource.processDisplayDefault(menuItem, entry, entries);
|
||||||
menuItem, entry, entries);
|
|
||||||
if (isDefault) continue;
|
if (isDefault) continue;
|
||||||
final licenseValue = await LicenseRepositoryImpl().getModule(entry.key);
|
final licenseValue = await LicenseRepositoryImpl().getModule(entry.key);
|
||||||
if (licenseValue != null) {
|
if (licenseValue != null) {
|
||||||
|
@ -25,22 +24,18 @@ class MenuRepositoryImpl implements MenuRepository {
|
||||||
final display = EnumDisplay.fromString(licenseMap['display']);
|
final display = EnumDisplay.fromString(licenseMap['display']);
|
||||||
final startDate = licenseMap['startDate'] ?? '';
|
final startDate = licenseMap['startDate'] ?? '';
|
||||||
final expirationDate = licenseMap['expirationDate'] ?? '';
|
final expirationDate = licenseMap['expirationDate'] ?? '';
|
||||||
final isStarted =
|
final isStarted = await DateTimeUtil.processStartDate(startDate);
|
||||||
await menuDataSource.processStartDate(startDate, entry);
|
final isExpired = await DateTimeUtil.processExpirationDate(expirationDate);
|
||||||
final isExpired =
|
|
||||||
await menuDataSource.processExpirationDate(expirationDate, entry);
|
|
||||||
if (isStarted && !isExpired) {
|
if (isStarted && !isExpired) {
|
||||||
await menuDataSource.handleMenu(menuItem, display, entry, entries);
|
await menuDataSource.handleMenu(menuItem, display, entry, entries);
|
||||||
}
|
}
|
||||||
if (isExpired) {
|
if (isExpired) {
|
||||||
log('Entry ${entry.key} is expired');
|
log('Entry ${entry.key} is expired');
|
||||||
await menuDataSource.handleMenu(
|
await menuDataSource.handleMenu(menuItem, EnumDisplay.inactive, entry, entries);
|
||||||
menuItem, EnumDisplay.inactive, entry, entries);
|
|
||||||
}
|
}
|
||||||
if (!isStarted) {
|
if (!isStarted) {
|
||||||
log('Entry ${entry.key} is not started');
|
log('Entry ${entry.key} is not started');
|
||||||
await menuDataSource.handleMenu(
|
await menuDataSource.handleMenu(menuItem, EnumDisplay.inactive, entry, entries);
|
||||||
menuItem, EnumDisplay.inactive, entry, entries);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,11 +45,9 @@ class MenuRepositoryImpl implements MenuRepository {
|
||||||
return entries;
|
return entries;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<EnumDisplay> processDisplay(
|
Future<EnumDisplay> processDisplay(Map<String, dynamic> module, bool isNewVersion) async {
|
||||||
Map<String, dynamic> module, bool isNewVersion) async {
|
|
||||||
if (await _shouldUpdateDisplay(module, isNewVersion)) {
|
if (await _shouldUpdateDisplay(module, isNewVersion)) {
|
||||||
final displayValue =
|
final displayValue = module['display'] == EnumDisplay.active ? 'VISIVEL' : 'INVISIVEL';
|
||||||
module['display'] == EnumDisplay.active ? 'VISIVEL' : 'INVISIVEL';
|
|
||||||
await LicenseLocalDataSourceImpl(DatabaseService.database)
|
await LicenseLocalDataSourceImpl(DatabaseService.database)
|
||||||
.setDisplayByKey(['FRE-HUB-ABOUT-PROPERTY'], displayValue);
|
.setDisplayByKey(['FRE-HUB-ABOUT-PROPERTY'], displayValue);
|
||||||
return EnumDisplay.fromString(displayValue);
|
return EnumDisplay.fromString(displayValue);
|
||||||
|
@ -63,13 +56,8 @@ class MenuRepositoryImpl implements MenuRepository {
|
||||||
return EnumDisplay.fromString(module['display']);
|
return EnumDisplay.fromString(module['display']);
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<bool> _shouldUpdateDisplay(
|
Future<bool> _shouldUpdateDisplay(Map<String, dynamic> module, bool isNewVersion) async {
|
||||||
Map<String, dynamic> module, bool isNewVersion) async {
|
const keysToCheck = [LicenseKeys.residents, LicenseKeys.vehicles, LicenseKeys.openedVisits];
|
||||||
const keysToCheck = [
|
|
||||||
LicenseKeys.residents,
|
|
||||||
LicenseKeys.vehicles,
|
|
||||||
LicenseKeys.openedVisits
|
|
||||||
];
|
|
||||||
return isNewVersion && keysToCheck.any((key) => module['key'] == key.value);
|
return isNewVersion && keysToCheck.any((key) => module['key'] == key.value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,15 @@ import 'package:hub/flutter_flow/index.dart';
|
||||||
import 'package:hub/pages/vehicles_on_the_property/vehicles_on_the_property.dart';
|
import 'package:hub/pages/vehicles_on_the_property/vehicles_on_the_property.dart';
|
||||||
import 'package:hub/shared/utils/index.dart';
|
import 'package:hub/shared/utils/index.dart';
|
||||||
|
|
||||||
class VehicleModel extends FlutterFlowModel<VehiclePage> {
|
/// [VehicleModel] is a class that contains the business logic of the vehicle page.
|
||||||
|
class VehicleModel extends FlutterFlowModel<VehiclePage>
|
||||||
|
with _BaseVehiclePage, _VehicleHistoryScreenModel, _VehicleRegisterScreenModel, _VehicleUpdateScreenModel {
|
||||||
|
/// [VehicleModel] is a singleton class that contains the business logic of the vehicle page.
|
||||||
|
static VehicleModel? _instance = VehicleModel._internal();
|
||||||
|
VehicleModel._internal();
|
||||||
|
factory VehicleModel() => _instance ?? VehicleModel._internal();
|
||||||
|
static void resetInstance() => _instance = null;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void initState(BuildContext context) {
|
void initState(BuildContext context) {
|
||||||
resetInstance();
|
resetInstance();
|
||||||
|
@ -36,25 +44,31 @@ class VehicleModel extends FlutterFlowModel<VehiclePage> {
|
||||||
textFieldControllerModel!.dispose();
|
textFieldControllerModel!.dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
static VehicleModel? _instance = VehicleModel._internal();
|
|
||||||
VehicleModel._internal();
|
|
||||||
factory VehicleModel() => _instance ?? VehicleModel._internal();
|
|
||||||
static void resetInstance() => _instance = null;
|
|
||||||
|
|
||||||
dynamic item;
|
|
||||||
String? vehicleId;
|
|
||||||
|
|
||||||
late final TabController tabBarController;
|
|
||||||
VoidCallback? onUpdateVehicle;
|
|
||||||
VoidCallback? onRegisterVehicle;
|
|
||||||
VoidCallback? safeSetState;
|
|
||||||
|
|
||||||
final GlobalKey<FormState> registerFormKey = GlobalKey<FormState>();
|
final GlobalKey<FormState> registerFormKey = GlobalKey<FormState>();
|
||||||
final GlobalKey<FormState> updateFormKey = GlobalKey<FormState>();
|
final GlobalKey<FormState> updateFormKey = GlobalKey<FormState>();
|
||||||
|
|
||||||
ApiCallResponse? vehicleResponse;
|
Future<void> initAsync() async {}
|
||||||
bool isEditing = false;
|
|
||||||
|
bool isFormValid(BuildContext context) {
|
||||||
|
if (registerFormKey.currentState == null) return false;
|
||||||
|
return registerFormKey.currentState!.validate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [_BaseVehiclePage] is a mixin that contains the base logic of the vehicle page.
|
||||||
|
mixin class _BaseVehiclePage {
|
||||||
|
int count = 0;
|
||||||
|
late final VehicleModel model;
|
||||||
|
late final TabController tabBarController;
|
||||||
|
dynamic item;
|
||||||
BuildContext context = navigatorKey.currentContext!;
|
BuildContext context = navigatorKey.currentContext!;
|
||||||
|
bool isEditing = false;
|
||||||
|
String? vehicleId;
|
||||||
|
ApiCallResponse? vehicleResponse;
|
||||||
|
|
||||||
|
VoidCallback? onUpdateVehicle;
|
||||||
|
VoidCallback? onRegisterVehicle;
|
||||||
|
VoidCallback? safeSetState;
|
||||||
|
|
||||||
FocusNode? textFieldFocusLicensePlate;
|
FocusNode? textFieldFocusLicensePlate;
|
||||||
TextEditingController? textFieldControllerLicensePlate;
|
TextEditingController? textFieldControllerLicensePlate;
|
||||||
|
@ -105,8 +119,35 @@ class VehicleModel extends FlutterFlowModel<VehiclePage> {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> initAsync() async {}
|
void switchTab(int index) {
|
||||||
|
tabBarController.animateTo(index);
|
||||||
|
if (index == 0) handleEditingChanged(false);
|
||||||
|
safeSetState?.call();
|
||||||
|
}
|
||||||
|
|
||||||
|
void clearFields() async {
|
||||||
|
textFieldControllerLicensePlate!.clear();
|
||||||
|
textFieldControllerColor!.clear();
|
||||||
|
textFieldControllerModel!.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleEditingChanged(bool editing) {
|
||||||
|
isEditing = editing;
|
||||||
|
clearFields();
|
||||||
|
}
|
||||||
|
|
||||||
|
void setEditForm() {
|
||||||
|
if (item != null) {
|
||||||
|
vehicleId = item['vehicleId'];
|
||||||
|
textFieldControllerLicensePlate!.text = item['licensePlate'];
|
||||||
|
textFieldControllerColor!.text = item['color'];
|
||||||
|
textFieldControllerModel!.text = item['model'];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// [_VehicleHistoryScreenModel] is a mixin that contains the business logic of the vehicle history page.
|
||||||
|
mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
|
||||||
Map<String, Color>? generateStatusColorMap(dynamic uItem) {
|
Map<String, Color>? generateStatusColorMap(dynamic uItem) {
|
||||||
final statusMap = {
|
final statusMap = {
|
||||||
"ATI": {
|
"ATI": {
|
||||||
|
@ -179,147 +220,183 @@ class VehicleModel extends FlutterFlowModel<VehiclePage> {
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
final updateText = FFLocalizations.of(context).getVariableText(ptText: 'Editar', enText: 'Edit');
|
||||||
|
final updateIcon = Icon(Icons.edit, color: iconButtonColor);
|
||||||
|
Future updateOnPressed() async {
|
||||||
|
context.pop();
|
||||||
|
isEditing = true;
|
||||||
|
item = item;
|
||||||
|
|
||||||
|
switchTab(1);
|
||||||
|
setEditForm();
|
||||||
|
}
|
||||||
|
|
||||||
|
final cancelText = FFLocalizations.of(context).getVariableText(ptText: 'Cancelar', enText: 'Cancel');
|
||||||
|
final cancelIcon = Icon(Icons.close, color: iconButtonColor);
|
||||||
|
Future cancelOnPressed() async {
|
||||||
|
showAlertDialog(
|
||||||
|
context,
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Cancelar Solicitação',
|
||||||
|
enText: 'Cancel Request',
|
||||||
|
),
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Você tem certeza que deseja cancelar essa solicitação?',
|
||||||
|
enText: 'Are you sure you want to delete this request?',
|
||||||
|
),
|
||||||
|
() async => await processCancelRequest(item['status']),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
final deleteText = FFLocalizations.of(context).getVariableText(ptText: 'Excluir', enText: 'Delete');
|
||||||
|
final deleteIcon = Icon(Icons.delete, color: iconButtonColor);
|
||||||
|
Future deleteOnPressed() async {
|
||||||
|
showAlertDialog(
|
||||||
|
context,
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Excluir Veículo',
|
||||||
|
enText: 'Delete Vehicle',
|
||||||
|
),
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Você tem certeza que deseja excluir esse veículo?',
|
||||||
|
enText: 'Are you sure you want to delete this vehicle?',
|
||||||
|
),
|
||||||
|
() async => await processDeleteRequest(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return [
|
return [
|
||||||
if (item['status'].contains('AGU'))
|
if (item['status'].contains('AGU'))
|
||||||
FFButtonWidget(
|
FFButtonWidget(
|
||||||
text: FFLocalizations.of(context).getVariableText(
|
text: updateText,
|
||||||
ptText: 'Editar',
|
icon: updateIcon,
|
||||||
enText: 'Edit',
|
onPressed: updateOnPressed,
|
||||||
),
|
|
||||||
icon: Icon(
|
|
||||||
Icons.close,
|
|
||||||
color: iconButtonColor,
|
|
||||||
),
|
|
||||||
onPressed: () async {
|
|
||||||
context.pop();
|
|
||||||
isEditing = true;
|
|
||||||
item = item;
|
|
||||||
|
|
||||||
switchTab(1);
|
|
||||||
setEditForm();
|
|
||||||
},
|
|
||||||
options: buttonOptions,
|
options: buttonOptions,
|
||||||
),
|
),
|
||||||
if (item['status'].contains('APR') || item['status'].contains('AGU'))
|
if (item['status'].contains('APR') || item['status'].contains('AGU'))
|
||||||
FFButtonWidget(
|
FFButtonWidget(
|
||||||
text: FFLocalizations.of(context).getVariableText(
|
text: cancelText,
|
||||||
ptText: 'Cancelar',
|
icon: cancelIcon,
|
||||||
enText: 'Cancel',
|
onPressed: cancelOnPressed,
|
||||||
),
|
|
||||||
icon: Icon(Icons.close, color: iconButtonColor),
|
|
||||||
onPressed: () async {
|
|
||||||
showAlertDialog(
|
|
||||||
context,
|
|
||||||
FFLocalizations.of(context).getVariableText(
|
|
||||||
ptText: 'Cancelar Solicitação',
|
|
||||||
enText: 'Cancel Request',
|
|
||||||
),
|
|
||||||
FFLocalizations.of(context).getVariableText(
|
|
||||||
ptText: 'Você tem certeza que deseja cancelar essa solicitação?',
|
|
||||||
enText: 'Are you sure you want to delete this request?',
|
|
||||||
), () async {
|
|
||||||
int id = item['vehicleId'];
|
|
||||||
await PhpGroup.deleteVehicle.call(vehicleId: id).then((value) {
|
|
||||||
context.pop(value);
|
|
||||||
context.pop(value);
|
|
||||||
|
|
||||||
if (value.jsonBody['error'] == false) {
|
|
||||||
showSnackbar(
|
|
||||||
context,
|
|
||||||
FFLocalizations.of(context).getVariableText(
|
|
||||||
ptText: 'Erro ao cancelar solicitação',
|
|
||||||
enText: 'Error canceling request',
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
} else if (value.jsonBody['error'] == true) {
|
|
||||||
showSnackbar(
|
|
||||||
context,
|
|
||||||
FFLocalizations.of(context).getVariableText(
|
|
||||||
enText: 'Success canceling request',
|
|
||||||
ptText: 'Succeso ao cancelar solicitação',
|
|
||||||
),
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}).catchError((err, stack) {
|
|
||||||
context.pop();
|
|
||||||
showSnackbar(
|
|
||||||
context,
|
|
||||||
FFLocalizations.of(context).getVariableText(
|
|
||||||
enText: 'Error canceling request',
|
|
||||||
ptText: 'Erro ao cancelar solicitação',
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
options: buttonOptions,
|
options: buttonOptions,
|
||||||
),
|
),
|
||||||
if (item['status'].contains('ATI'))
|
if (item['status'].contains('ATI'))
|
||||||
FFButtonWidget(
|
FFButtonWidget(
|
||||||
text: FFLocalizations.of(context).getVariableText(
|
text: deleteText,
|
||||||
ptText: 'Excluir',
|
icon: deleteIcon,
|
||||||
enText: 'Delete',
|
onPressed: deleteOnPressed,
|
||||||
),
|
|
||||||
icon: Icon(
|
|
||||||
Icons.close,
|
|
||||||
color: iconButtonColor,
|
|
||||||
),
|
|
||||||
onPressed: () async {
|
|
||||||
showAlertDialog(
|
|
||||||
context,
|
|
||||||
FFLocalizations.of(context).getVariableText(
|
|
||||||
ptText: 'Excluir Veículo',
|
|
||||||
enText: 'Delete Vehicle',
|
|
||||||
),
|
|
||||||
FFLocalizations.of(context).getVariableText(
|
|
||||||
ptText: 'Você tem certeza que deseja excluir esse veículo?',
|
|
||||||
enText: 'Are you sure you want to delete this vehicle?',
|
|
||||||
), () async {
|
|
||||||
int id = item['vehicleId'];
|
|
||||||
await PhpGroup.deleteVehicle.call(vehicleId: id).then((value) {
|
|
||||||
context.pop(value);
|
|
||||||
context.pop(value);
|
|
||||||
|
|
||||||
if (value == false) {
|
|
||||||
showSnackbar(
|
|
||||||
context,
|
|
||||||
FFLocalizations.of(context).getVariableText(
|
|
||||||
ptText: 'Erro ao excluir veículo',
|
|
||||||
enText: 'Error deleting vehicle',
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
} else if (value == true) {
|
|
||||||
showSnackbar(
|
|
||||||
context,
|
|
||||||
FFLocalizations.of(context).getVariableText(
|
|
||||||
enText: 'Success deleting vehicle',
|
|
||||||
ptText: 'Succeso ao excluir veículo',
|
|
||||||
),
|
|
||||||
false,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}).catchError((err, stack) {
|
|
||||||
context.pop();
|
|
||||||
showSnackbar(
|
|
||||||
context,
|
|
||||||
FFLocalizations.of(context).getVariableText(
|
|
||||||
enText: 'Error deleting vehicle',
|
|
||||||
ptText: 'Erro ao excluir veículo',
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
});
|
|
||||||
});
|
|
||||||
},
|
|
||||||
options: buttonOptions,
|
options: buttonOptions,
|
||||||
),
|
),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<void> processDeleteRequest() async {
|
||||||
|
int id = item['vehicleId'];
|
||||||
|
await PhpGroup.deleteVehicle.call(vehicleId: id).then((value) {
|
||||||
|
context.pop(value);
|
||||||
|
context.pop(value);
|
||||||
|
|
||||||
|
// ignore: unrelated_type_equality_checks
|
||||||
|
if (value == false) {
|
||||||
|
showSnackbar(
|
||||||
|
context,
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Erro ao excluir veículo',
|
||||||
|
enText: 'Error deleting vehicle',
|
||||||
|
),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
// ignore: unrelated_type_equality_checks
|
||||||
|
} else if (value == true) {
|
||||||
|
showSnackbar(
|
||||||
|
context,
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
enText: 'Success deleting vehicle',
|
||||||
|
ptText: 'Succeso ao excluir veículo',
|
||||||
|
),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}).catchError((err, stack) {
|
||||||
|
context.pop();
|
||||||
|
showSnackbar(
|
||||||
|
context,
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
enText: 'Error deleting vehicle',
|
||||||
|
ptText: 'Erro ao excluir veículo',
|
||||||
|
),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<void> processCancelRequest(String status) async {
|
||||||
|
late final ApiCallResponse value;
|
||||||
|
try {
|
||||||
|
switch (status) {
|
||||||
|
case 'APR_CREATE':
|
||||||
|
value = await processCancelDeleteRequest();
|
||||||
|
break;
|
||||||
|
case 'AGU_CHANGE':
|
||||||
|
value = await processCancelUpdateRequest();
|
||||||
|
break;
|
||||||
|
case 'APR_DELETE':
|
||||||
|
value = await processCancelCreateRequest();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
context.pop(value);
|
||||||
|
context.pop(value);
|
||||||
|
|
||||||
|
if (value.jsonBody['error'] == false) {
|
||||||
|
showSnackbar(
|
||||||
|
context,
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Erro ao cancelar solicitação',
|
||||||
|
enText: 'Error canceling request',
|
||||||
|
),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
} else if (value.jsonBody['error'] == true) {
|
||||||
|
showSnackbar(
|
||||||
|
context,
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
enText: 'Success canceling request',
|
||||||
|
ptText: 'Succeso ao cancelar solicitação',
|
||||||
|
),
|
||||||
|
false,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
} catch (err) {
|
||||||
|
context.pop();
|
||||||
|
showSnackbar(
|
||||||
|
context,
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
enText: 'Error canceling request',
|
||||||
|
ptText: 'Erro ao cancelar solicitação',
|
||||||
|
),
|
||||||
|
true,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<ApiCallResponse> processCancelDeleteRequest() async {
|
||||||
|
final int id = item['vehicleId'];
|
||||||
|
return await PhpGroup.deleteVehicle.call(vehicleId: id);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<ApiCallResponse> processCancelUpdateRequest() async {
|
||||||
|
final int id = item['vehicleId'];
|
||||||
|
return await PhpGroup.deleteVehicle.call(vehicleId: id);
|
||||||
|
}
|
||||||
|
|
||||||
|
Future<ApiCallResponse> processCancelCreateRequest() async {
|
||||||
|
final int id = item['vehicleId'];
|
||||||
|
return await PhpGroup.deleteVehicle.call(vehicleId: id);
|
||||||
|
}
|
||||||
|
|
||||||
Map<String, String> generateLabelsHashMap(dynamic item) {
|
Map<String, String> generateLabelsHashMap(dynamic item) {
|
||||||
return {
|
return {
|
||||||
if (item['model'] != null && item['model'] != '')
|
if (item['model'] != null && item['model'] != '')
|
||||||
|
@ -354,21 +431,42 @@ class VehicleModel extends FlutterFlowModel<VehiclePage> {
|
||||||
statusHashMap: [status],
|
statusHashMap: [status],
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void setEditForm() {
|
/// [_VehicleRegisterScreenModel] is a mixin that contains the business logic of the vehicle register page.
|
||||||
if (item != null) {
|
mixin _VehicleRegisterScreenModel on _BaseVehiclePage {
|
||||||
vehicleId = item['vehicleId'];
|
Future<void> registerVehicle() async {
|
||||||
textFieldControllerLicensePlate!.text = item['licensePlate'];
|
final response = await PhpGroup.registerVehicle.call(
|
||||||
textFieldControllerColor!.text = item['color'];
|
licensePlate: textFieldControllerLicensePlate!.text,
|
||||||
textFieldControllerModel!.text = item['model'];
|
color: textFieldControllerColor!.text,
|
||||||
|
model: textFieldControllerModel!.text,
|
||||||
|
);
|
||||||
|
if (response.jsonBody['error'] == false) {
|
||||||
|
await DialogUtil.success(
|
||||||
|
context,
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Veículo cadastrado com sucesso',
|
||||||
|
enText: 'Vehicle registered successfully',
|
||||||
|
)).then((_) async {
|
||||||
|
switchTab(0);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
String errorMessage;
|
||||||
|
try {
|
||||||
|
errorMessage = response.jsonBody['message'];
|
||||||
|
} catch (e) {
|
||||||
|
errorMessage = FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Erro ao cadastrar veículo',
|
||||||
|
enText: 'Error registering vehicle',
|
||||||
|
);
|
||||||
|
}
|
||||||
|
await DialogUtil.error(context, errorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
bool isFormValid(BuildContext context) {
|
/// [_VehicleUpdateScreenModel] is a mixin that contains the business logic of the vehicle update page.
|
||||||
if (registerFormKey.currentState == null) return false;
|
mixin _VehicleUpdateScreenModel on _BaseVehiclePage {
|
||||||
return registerFormKey.currentState!.validate();
|
|
||||||
}
|
|
||||||
|
|
||||||
Future<void> updateVehicle() async {
|
Future<void> updateVehicle() async {
|
||||||
final response = await PhpGroup.updateVehicle.call(
|
final response = await PhpGroup.updateVehicle.call(
|
||||||
licensePlate: textFieldControllerLicensePlate!.text,
|
licensePlate: textFieldControllerLicensePlate!.text,
|
||||||
|
@ -398,50 +496,4 @@ class VehicleModel extends FlutterFlowModel<VehiclePage> {
|
||||||
await DialogUtil.error(context, errorMessage);
|
await DialogUtil.error(context, errorMessage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> registerVehicle() async {
|
|
||||||
final response = await PhpGroup.registerVehicle.call(
|
|
||||||
licensePlate: textFieldControllerLicensePlate!.text,
|
|
||||||
color: textFieldControllerColor!.text,
|
|
||||||
model: textFieldControllerModel!.text,
|
|
||||||
);
|
|
||||||
if (response.jsonBody['error'] == false) {
|
|
||||||
await DialogUtil.success(
|
|
||||||
context,
|
|
||||||
FFLocalizations.of(context).getVariableText(
|
|
||||||
ptText: 'Veículo cadastrado com sucesso',
|
|
||||||
enText: 'Vehicle registered successfully',
|
|
||||||
)).then((_) async {
|
|
||||||
switchTab(0);
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
String errorMessage;
|
|
||||||
try {
|
|
||||||
errorMessage = response.jsonBody['message'];
|
|
||||||
} catch (e) {
|
|
||||||
errorMessage = FFLocalizations.of(context).getVariableText(
|
|
||||||
ptText: 'Erro ao cadastrar veículo',
|
|
||||||
enText: 'Error registering vehicle',
|
|
||||||
);
|
|
||||||
}
|
|
||||||
await DialogUtil.error(context, errorMessage);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void switchTab(int index) {
|
|
||||||
tabBarController.animateTo(index);
|
|
||||||
if (index == 0) handleEditingChanged(false);
|
|
||||||
safeSetState?.call();
|
|
||||||
}
|
|
||||||
|
|
||||||
void clearFields() async {
|
|
||||||
textFieldControllerLicensePlate!.clear();
|
|
||||||
textFieldControllerColor!.clear();
|
|
||||||
textFieldControllerModel!.clear();
|
|
||||||
}
|
|
||||||
|
|
||||||
void handleEditingChanged(bool editing) {
|
|
||||||
isEditing = editing;
|
|
||||||
clearFields();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,89 +14,97 @@ class VehicleRegisterScreen extends StatefulWidget {
|
||||||
class _VehicleRegisterScreenState extends State<VehicleRegisterScreen> {
|
class _VehicleRegisterScreenState extends State<VehicleRegisterScreen> {
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
double limitedInputFontSize = LimitedFontSizeUtil.getInputFontSize(context);
|
|
||||||
double limitedHeaderFontSize = LimitedFontSizeUtil.getHeaderFontSize(context);
|
|
||||||
double limitedSubHeaderFontSize = LimitedFontSizeUtil.getSubHeaderFontSize(context);
|
|
||||||
|
|
||||||
return SingleChildScrollView(
|
return SingleChildScrollView(
|
||||||
child: Column(
|
child: Column(
|
||||||
mainAxisSize: MainAxisSize.max,
|
mainAxisSize: MainAxisSize.max,
|
||||||
children: [
|
children: [
|
||||||
Align(
|
_buildHeader(context),
|
||||||
alignment: const AlignmentDirectional(-1.0, 0.0),
|
_buildBody(context),
|
||||||
child: Padding(
|
|
||||||
padding: const EdgeInsetsDirectional.fromSTEB(24.0, 20, 0.0, 15),
|
|
||||||
child: Text(
|
|
||||||
FFLocalizations.of(context).getVariableText(
|
|
||||||
ptText: 'Preencha o formulário de cadastro com os dados do seu veículo',
|
|
||||||
enText: 'Fill out the registration form with your vehicle data',
|
|
||||||
),
|
|
||||||
textAlign: TextAlign.start,
|
|
||||||
style: FlutterFlowTheme.of(context).bodyMedium.override(
|
|
||||||
fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily,
|
|
||||||
letterSpacing: 0.0,
|
|
||||||
useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).bodyMediumFamily),
|
|
||||||
fontSize: limitedHeaderFontSize,
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
|
||||||
Form(
|
|
||||||
key: widget.model.registerFormKey,
|
|
||||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
|
||||||
child: Column(
|
|
||||||
mainAxisSize: MainAxisSize.max,
|
|
||||||
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
|
||||||
children: [
|
|
||||||
CustomInputUtil(
|
|
||||||
controller: widget.model.textFieldControllerLicensePlate,
|
|
||||||
validator: widget.model.textControllerLicensePlateValidator.asValidator(context),
|
|
||||||
focusNode: widget.model.textFieldFocusLicensePlate,
|
|
||||||
labelText: FFLocalizations.of(context).getVariableText(ptText: 'Placa', enText: 'License Plate'),
|
|
||||||
hintText: FFLocalizations.of(context).getVariableText(ptText: 'Placa', enText: 'License Plate'),
|
|
||||||
suffixIcon: Symbols.format_color_text,
|
|
||||||
haveMaxLength: true,
|
|
||||||
onChanged: (value) => setState(() {}),
|
|
||||||
maxLength: 80,
|
|
||||||
),
|
|
||||||
CustomInputUtil(
|
|
||||||
controller: widget.model.textFieldControllerModel,
|
|
||||||
validator: widget.model.textControllerModelValidator.asValidator(context),
|
|
||||||
focusNode: widget.model.textFieldFocusModel,
|
|
||||||
labelText: FFLocalizations.of(context).getVariableText(ptText: 'Modelo', enText: 'Model'),
|
|
||||||
hintText: FFLocalizations.of(context).getVariableText(
|
|
||||||
ptText: 'Ex: Voyage, Ford',
|
|
||||||
enText: 'e.g. Voyage, Ford',
|
|
||||||
),
|
|
||||||
suffixIcon: Symbols.car_repair,
|
|
||||||
haveMaxLength: true,
|
|
||||||
onChanged: (value) => setState(() {}),
|
|
||||||
maxLength: 80,
|
|
||||||
),
|
|
||||||
CustomInputUtil(
|
|
||||||
controller: widget.model.textFieldControllerColor,
|
|
||||||
validator: widget.model.textControllerColorValidator.asValidator(context),
|
|
||||||
focusNode: widget.model.textFieldFocusColor,
|
|
||||||
labelText: FFLocalizations.of(context).getVariableText(ptText: 'Cor', enText: 'Color'),
|
|
||||||
hintText: FFLocalizations.of(context).getVariableText(
|
|
||||||
ptText: 'Ex: Preto, Amarelo, Branco',
|
|
||||||
enText: 'e.g. Black, Yellow, White',
|
|
||||||
),
|
|
||||||
suffixIcon: Symbols.palette,
|
|
||||||
haveMaxLength: true,
|
|
||||||
onChanged: (value) => setState(() {}),
|
|
||||||
maxLength: 80,
|
|
||||||
),
|
|
||||||
Padding(
|
|
||||||
padding: const EdgeInsets.fromLTRB(70, 20, 70, 30),
|
|
||||||
child: SubmitButtonUtil(
|
|
||||||
labelText: FFLocalizations.of(context).getVariableText(ptText: 'Cadastrar', enText: 'Register'),
|
|
||||||
onPressed: widget.model.isFormValid(context) ? widget.model.registerVehicle : null),
|
|
||||||
),
|
|
||||||
],
|
|
||||||
)),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Form _buildBody(BuildContext context) {
|
||||||
|
return Form(
|
||||||
|
key: widget.model.registerFormKey,
|
||||||
|
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||||
|
child: Column(
|
||||||
|
mainAxisSize: MainAxisSize.max,
|
||||||
|
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
|
||||||
|
children: [
|
||||||
|
CustomInputUtil(
|
||||||
|
controller: widget.model.textFieldControllerLicensePlate,
|
||||||
|
validator: widget.model.textControllerLicensePlateValidator.asValidator(context),
|
||||||
|
focusNode: widget.model.textFieldFocusLicensePlate,
|
||||||
|
labelText: FFLocalizations.of(context).getVariableText(ptText: 'Placa', enText: 'License Plate'),
|
||||||
|
hintText: FFLocalizations.of(context).getVariableText(ptText: 'Placa', enText: 'License Plate'),
|
||||||
|
suffixIcon: Symbols.format_color_text,
|
||||||
|
haveMaxLength: true,
|
||||||
|
onChanged: (value) => setState(() {}),
|
||||||
|
maxLength: 80,
|
||||||
|
),
|
||||||
|
CustomInputUtil(
|
||||||
|
controller: widget.model.textFieldControllerModel,
|
||||||
|
validator: widget.model.textControllerModelValidator.asValidator(context),
|
||||||
|
focusNode: widget.model.textFieldFocusModel,
|
||||||
|
labelText: FFLocalizations.of(context).getVariableText(ptText: 'Modelo', enText: 'Model'),
|
||||||
|
hintText: FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Ex: Voyage, Ford',
|
||||||
|
enText: 'e.g. Voyage, Ford',
|
||||||
|
),
|
||||||
|
suffixIcon: Symbols.car_repair,
|
||||||
|
haveMaxLength: true,
|
||||||
|
onChanged: (value) => setState(() {}),
|
||||||
|
maxLength: 80,
|
||||||
|
),
|
||||||
|
CustomInputUtil(
|
||||||
|
controller: widget.model.textFieldControllerColor,
|
||||||
|
validator: widget.model.textControllerColorValidator.asValidator(context),
|
||||||
|
focusNode: widget.model.textFieldFocusColor,
|
||||||
|
labelText: FFLocalizations.of(context).getVariableText(ptText: 'Cor', enText: 'Color'),
|
||||||
|
hintText: FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Ex: Preto, Amarelo, Branco',
|
||||||
|
enText: 'e.g. Black, Yellow, White',
|
||||||
|
),
|
||||||
|
suffixIcon: Symbols.palette,
|
||||||
|
haveMaxLength: true,
|
||||||
|
onChanged: (value) => setState(() {}),
|
||||||
|
maxLength: 80,
|
||||||
|
),
|
||||||
|
Padding(
|
||||||
|
padding: const EdgeInsets.fromLTRB(70, 20, 70, 30),
|
||||||
|
child: SubmitButtonUtil(
|
||||||
|
labelText: FFLocalizations.of(context).getVariableText(ptText: 'Cadastrar', enText: 'Register'),
|
||||||
|
onPressed: widget.model.isFormValid(context) ? widget.model.registerVehicle : null),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
Align _buildHeader(BuildContext context) {
|
||||||
|
// double limitedInputFontSize = LimitedFontSizeUtil.getInputFontSize(context);
|
||||||
|
double limitedHeaderFontSize = LimitedFontSizeUtil.getHeaderFontSize(context);
|
||||||
|
// double limitedSubHeaderFontSize = LimitedFontSizeUtil.getSubHeaderFontSize(context);
|
||||||
|
|
||||||
|
return Align(
|
||||||
|
alignment: const AlignmentDirectional(-1.0, 0.0),
|
||||||
|
child: Padding(
|
||||||
|
padding: const EdgeInsetsDirectional.fromSTEB(24.0, 20, 0.0, 15),
|
||||||
|
child: Text(
|
||||||
|
FFLocalizations.of(context).getVariableText(
|
||||||
|
ptText: 'Preencha o formulário de cadastro com os dados do seu veículo',
|
||||||
|
enText: 'Fill out the registration form with your vehicle data',
|
||||||
|
),
|
||||||
|
textAlign: TextAlign.start,
|
||||||
|
style: FlutterFlowTheme.of(context).bodyMedium.override(
|
||||||
|
fontFamily: FlutterFlowTheme.of(context).bodyMediumFamily,
|
||||||
|
letterSpacing: 0.0,
|
||||||
|
useGoogleFonts: GoogleFonts.asMap().containsKey(FlutterFlowTheme.of(context).bodyMediumFamily),
|
||||||
|
fontSize: limitedHeaderFontSize,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,6 +14,7 @@ import 'package:hub/flutter_flow/flutter_flow_util.dart';
|
||||||
import 'package:hub/flutter_flow/index.dart';
|
import 'package:hub/flutter_flow/index.dart';
|
||||||
import 'package:hub/pages/vehicles_on_the_property/vehicle_model.dart';
|
import 'package:hub/pages/vehicles_on_the_property/vehicle_model.dart';
|
||||||
import 'package:hub/shared/utils/dialog_util.dart';
|
import 'package:hub/shared/utils/dialog_util.dart';
|
||||||
|
import 'package:hub/shared/utils/license_util.dart';
|
||||||
import 'package:hub/shared/utils/limited_text_size.dart';
|
import 'package:hub/shared/utils/limited_text_size.dart';
|
||||||
import 'package:hub/shared/utils/log_util.dart';
|
import 'package:hub/shared/utils/log_util.dart';
|
||||||
import 'package:material_symbols_icons/symbols.dart';
|
import 'package:material_symbols_icons/symbols.dart';
|
||||||
|
@ -27,6 +28,7 @@ class VehiclePage extends StatefulWidget {
|
||||||
const VehiclePage({super.key});
|
const VehiclePage({super.key});
|
||||||
|
|
||||||
@override
|
@override
|
||||||
|
// ignore: library_private_types_in_public_api
|
||||||
_VehiclePageState createState() => _VehiclePageState();
|
_VehiclePageState createState() => _VehiclePageState();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,24 +57,24 @@ class _VehiclePageState extends State<VehiclePage> with TickerProviderStateMixin
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@override
|
// @override
|
||||||
void dispose() {
|
// void dispose() {
|
||||||
super.dispose();
|
// super.dispose();
|
||||||
}
|
// }
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
final backgroundColor = FlutterFlowTheme.of(context).primaryBackground;
|
final backgroundColor = FlutterFlowTheme.of(context).primaryBackground;
|
||||||
return Scaffold(
|
return Scaffold(
|
||||||
backgroundColor: backgroundColor,
|
backgroundColor: backgroundColor,
|
||||||
appBar: _buildAppBar(context),
|
appBar: _buildHeader(context),
|
||||||
body: buildBody(context),
|
body: _buildBody(context),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// [Body] of the page.
|
/// [Body] of the page.
|
||||||
Widget buildBody(BuildContext context) {
|
FutureBuilder<bool> _buildBody(BuildContext context) {
|
||||||
Widget progressEvent() {
|
Widget progressIndicator() {
|
||||||
return CircularProgressIndicator(
|
return CircularProgressIndicator(
|
||||||
valueColor: AlwaysStoppedAnimation<Color>(
|
valueColor: AlwaysStoppedAnimation<Color>(
|
||||||
FlutterFlowTheme.of(context).primary,
|
FlutterFlowTheme.of(context).primary,
|
||||||
|
@ -80,22 +82,14 @@ class _VehiclePageState extends State<VehiclePage> with TickerProviderStateMixin
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
Widget errorEvent() {
|
return FutureBuilder<bool>(
|
||||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
future: _initializeModule(),
|
||||||
context.pop();
|
|
||||||
await DialogUtil.errorDefault(navigatorKey.currentContext!);
|
|
||||||
});
|
|
||||||
return progressEvent();
|
|
||||||
}
|
|
||||||
|
|
||||||
return FutureBuilder<String?>(
|
|
||||||
future: LicenseRepositoryImpl().getModule('FRE-HUB-VEHICLES-MANAGER'),
|
|
||||||
builder: (context, snapshot) {
|
builder: (context, snapshot) {
|
||||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||||
return progressEvent();
|
return progressIndicator();
|
||||||
} else if (snapshot.hasError) {
|
} else if (snapshot.hasError) {
|
||||||
return errorEvent();
|
return progressIndicator();
|
||||||
} else if (snapshot.hasData && snapshot.data!.isNotEmpty) {
|
} else if (snapshot.hasData && snapshot.data == true) {
|
||||||
return _buildVehicleManager(context);
|
return _buildVehicleManager(context);
|
||||||
} else {
|
} else {
|
||||||
return _buildVehicleHistory(context);
|
return _buildVehicleHistory(context);
|
||||||
|
@ -104,6 +98,19 @@ class _VehiclePageState extends State<VehiclePage> with TickerProviderStateMixin
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Future<bool> _initializeModule() async {
|
||||||
|
try {
|
||||||
|
final module = await LicenseRepositoryImpl().getModule('FRE-HUB-VEHICLES-MANAGER');
|
||||||
|
return await LicenseUtil.processModule(module);
|
||||||
|
} catch (e) {
|
||||||
|
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||||
|
context.pop();
|
||||||
|
await DialogUtil.errorDefault(navigatorKey.currentContext!);
|
||||||
|
});
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void onEditingChanged(bool value) {
|
void onEditingChanged(bool value) {
|
||||||
setState(() {
|
setState(() {
|
||||||
_model.handleEditingChanged(value);
|
_model.handleEditingChanged(value);
|
||||||
|
@ -134,8 +141,8 @@ class _VehiclePageState extends State<VehiclePage> with TickerProviderStateMixin
|
||||||
}
|
}
|
||||||
|
|
||||||
/// -----------------------------------
|
/// -----------------------------------
|
||||||
/// [AppBar] with the title of the page.
|
/// [Header] of the page.
|
||||||
PreferredSizeWidget _buildAppBar(BuildContext context) {
|
PreferredSizeWidget _buildHeader(BuildContext context) {
|
||||||
final theme = FlutterFlowTheme.of(context);
|
final theme = FlutterFlowTheme.of(context);
|
||||||
final backgroundColor = theme.primaryBackground;
|
final backgroundColor = theme.primaryBackground;
|
||||||
final primaryText = theme.primaryText;
|
final primaryText = theme.primaryText;
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
import 'dart:developer';
|
||||||
|
|
||||||
|
class DateTimeUtil {
|
||||||
|
static Future<bool> processStartDate(String startDate) async {
|
||||||
|
try {
|
||||||
|
if (startDate.isEmpty) return true;
|
||||||
|
final start = DateTime.tryParse(startDate);
|
||||||
|
if (start == null) return false;
|
||||||
|
return DateTime.now().isAfter(start);
|
||||||
|
} catch (e) {
|
||||||
|
log('Error processing start date for module: $e');
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Future<bool> processExpirationDate(String expirationDate) async {
|
||||||
|
try {
|
||||||
|
if (expirationDate.isEmpty) return false;
|
||||||
|
final expiration = DateTime.tryParse(expirationDate);
|
||||||
|
return expiration != null && DateTime.now().isAfter(expiration);
|
||||||
|
} catch (e) {
|
||||||
|
log('Error processing expiration date for module: $e');
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,17 @@
|
||||||
|
import 'package:hub/features/module/index.dart';
|
||||||
|
import 'package:hub/flutter_flow/index.dart';
|
||||||
|
import 'package:hub/shared/utils/datetime_util.dart';
|
||||||
|
|
||||||
|
class LicenseUtil {
|
||||||
|
static Future<bool> processModule(String? module) async {
|
||||||
|
if (module == null) return false;
|
||||||
|
final moduleMap = await stringToMap(module);
|
||||||
|
final startDate = moduleMap['startDate'] ?? '';
|
||||||
|
final expirationDate = moduleMap['expirationDate'] ?? '';
|
||||||
|
final isStarted = await DateTimeUtil.processStartDate(startDate);
|
||||||
|
final isExpired = await DateTimeUtil.processExpirationDate(expirationDate);
|
||||||
|
if (isStarted && !isExpired) return EnumDisplay.fromString(moduleMap["display"]) == EnumDisplay.active;
|
||||||
|
if (isExpired) return false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue