WIP
This commit is contained in:
parent
3b7a33801f
commit
7dd7ed7a32
|
@ -82,7 +82,7 @@ void main() {
|
|||
// LocalsTest.unlinkLocal();
|
||||
|
||||
VehicleTest.vehiclePage();
|
||||
VehicleTest.historyScreen();
|
||||
VehicleTest.registerScreen();
|
||||
VehicleTest.updateScreen();
|
||||
// VehicleTest.historyScreen();
|
||||
// VehicleTest.registerScreen();
|
||||
// VehicleTest.updateScreen();
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
part of 'app_test.dart';
|
||||
|
||||
Future<void> _loggedWithMultiLocalsAccount(PatrolIntegrationTester $,
|
||||
[bool forceLinkedLocal = true]) async {
|
||||
Future<void> _loggedWithMultiLocalsAccount(PatrolIntegrationTester $, [bool forceLinkedLocal = true]) async {
|
||||
await _init($);
|
||||
await StorageHelper() //
|
||||
.set(SecureStorageKey.isLogged.value, 'true');
|
||||
|
@ -19,18 +18,15 @@ Future<void> _loggedWithMultiLocalsAccount(PatrolIntegrationTester $,
|
|||
await StorageHelper() //
|
||||
.set(LocalsStorageKey.isNewVersion.key, true);
|
||||
if (forceLinkedLocal == true) {
|
||||
await StorageHelper() //
|
||||
.set(ProfileStorageKey.clientUUID.key, '7');
|
||||
await PhpGroup //
|
||||
.resopndeVinculo
|
||||
.call(tarefa: 'A');
|
||||
await LicenseRepositoryImpl() //
|
||||
.resetLicense();
|
||||
await StorageHelper().set(ProfileStorageKey.clientUUID.key, '7');
|
||||
await StorageHelper().set(ProfileStorageKey.ownerUUID.key, '7');
|
||||
await StorageHelper().set(ProfileStorageKey.clientName.key, 'FRE ACCESS DEMO');
|
||||
await PhpGroup.respondeVinculo.call(tarefa: 'A');
|
||||
await LicenseRepositoryImpl().resetLicense();
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _loggedWithSomeoneLocalAccount(PatrolIntegrationTester $,
|
||||
[bool forceLinkedLocal = true]) async {
|
||||
Future<void> _loggedWithSomeoneLocalAccount(PatrolIntegrationTester $, [bool forceLinkedLocal = true]) async {
|
||||
await _init($);
|
||||
await StorageHelper() //
|
||||
.set(SecureStorageKey.isLogged.value, 'true');
|
||||
|
@ -48,13 +44,11 @@ Future<void> _loggedWithSomeoneLocalAccount(PatrolIntegrationTester $,
|
|||
await StorageHelper() //
|
||||
.set(LocalsStorageKey.isNewVersion.key, true);
|
||||
if (forceLinkedLocal == true) {
|
||||
await StorageHelper() //
|
||||
.set(ProfileStorageKey.clientUUID.key, '7');
|
||||
await PhpGroup //
|
||||
.resopndeVinculo
|
||||
.call(tarefa: 'A');
|
||||
await LicenseRepositoryImpl() //
|
||||
.resetLicense();
|
||||
await StorageHelper().set(ProfileStorageKey.clientUUID.key, '7');
|
||||
await StorageHelper().set(ProfileStorageKey.ownerUUID.key, '7');
|
||||
await StorageHelper().set(ProfileStorageKey.clientName.key, 'FRE ACCESS DEMO');
|
||||
await PhpGroup.respondeVinculo.call(tarefa: 'A');
|
||||
await LicenseRepositoryImpl().resetLicense();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -101,8 +95,7 @@ Future<void> _navigateToSignUp(PatrolIntegrationTester $) async {
|
|||
}
|
||||
|
||||
Future<void> _navigateBackUsingSystemGesture() async =>
|
||||
IntegrationTestWidgetsFlutterBinding.instance.keyboard
|
||||
.isLogicalKeyPressed(LogicalKeyboardKey.escape);
|
||||
IntegrationTestWidgetsFlutterBinding.instance.keyboard.isLogicalKeyPressed(LogicalKeyboardKey.escape);
|
||||
|
||||
Future<void> _initializeTracking() async {
|
||||
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 {
|
||||
|
|
|
@ -19,12 +19,10 @@ class BottomArrowLinkedLocalsComponentWidget extends StatefulWidget {
|
|||
ApiCallResponse? response;
|
||||
|
||||
@override
|
||||
State<BottomArrowLinkedLocalsComponentWidget> createState() =>
|
||||
_BottomArrowLinkedLocalsComponentWidgetState();
|
||||
State<BottomArrowLinkedLocalsComponentWidget> createState() => _BottomArrowLinkedLocalsComponentWidgetState();
|
||||
}
|
||||
|
||||
class _BottomArrowLinkedLocalsComponentWidgetState
|
||||
extends State<BottomArrowLinkedLocalsComponentWidget> {
|
||||
class _BottomArrowLinkedLocalsComponentWidgetState extends State<BottomArrowLinkedLocalsComponentWidget> {
|
||||
late BottomArrowLinkedLocalsComponentModel _model;
|
||||
|
||||
bool _loading = false;
|
||||
|
@ -42,8 +40,7 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
|||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
_model =
|
||||
createModel(context, () => BottomArrowLinkedLocalsComponentModel());
|
||||
_model = createModel(context, () => BottomArrowLinkedLocalsComponentModel());
|
||||
_localsFuture = _fetchLocals();
|
||||
}
|
||||
|
||||
|
@ -109,14 +106,10 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
|||
if (isEnabled) {
|
||||
final local = locals[0];
|
||||
|
||||
await StorageHelper()
|
||||
.set(ProfileStorageKey.clientName.key, local['CLI_NOME']);
|
||||
await StorageHelper()
|
||||
.set(ProfileStorageKey.ownerName.key, local['CLU_OWNER_DSC']);
|
||||
await StorageHelper()
|
||||
.set(ProfileStorageKey.clientUUID.key, local['CLI_ID']);
|
||||
await StorageHelper()
|
||||
.set(ProfileStorageKey.ownerUUID.key, local['CLU_OWNER_ID']);
|
||||
await StorageHelper().set(ProfileStorageKey.clientName.key, local['CLI_NOME']);
|
||||
await StorageHelper().set(ProfileStorageKey.ownerName.key, local['CLU_OWNER_DSC']);
|
||||
await StorageHelper().set(ProfileStorageKey.clientUUID.key, local['CLI_ID']);
|
||||
await StorageHelper().set(ProfileStorageKey.ownerUUID.key, local['CLU_OWNER_ID']);
|
||||
|
||||
context.pop();
|
||||
return widget.response;
|
||||
|
@ -140,22 +133,20 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
|||
return null;
|
||||
}
|
||||
|
||||
static Future<void> _handleError(
|
||||
BuildContext context, String errorMsg) async {
|
||||
static Future<void> _handleError(BuildContext context, String errorMsg) async {
|
||||
await DialogUtil.error(context, errorMsg);
|
||||
}
|
||||
|
||||
Future<dynamic> _fetchResponseLink(String status, String cliID) async {
|
||||
try {
|
||||
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) {
|
||||
return {
|
||||
'error': false,
|
||||
'error_msg': FFLocalizations.of(context).getVariableText(
|
||||
ptText: "Vínculo Ativado com Sucesso",
|
||||
enText: "Link Activated Successfully")
|
||||
'error_msg': FFLocalizations.of(context)
|
||||
.getVariableText(ptText: "Vínculo Ativado com Sucesso", enText: "Link Activated Successfully")
|
||||
};
|
||||
} else {
|
||||
await StorageHelper().set(ProfileStorageKey.clientUUID.key, '');
|
||||
|
@ -163,8 +154,7 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
|||
}
|
||||
} catch (e, s) {
|
||||
await DialogUtil.errorDefault(context);
|
||||
LogUtil.requestAPIFailed(
|
||||
'responderVinculo.php', '', 'Responder Vínculo', e, s);
|
||||
LogUtil.requestAPIFailed('responderVinculo.php', '', 'Responder Vínculo', e, s);
|
||||
return {
|
||||
'error': true,
|
||||
'error_msg': FFLocalizations.of(context).getVariableText(
|
||||
|
@ -189,17 +179,14 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
|||
Map<String, Color> _statusHashMap(dynamic local) {
|
||||
return Map<String, Color>.from({
|
||||
if (local['CLU_STATUS'] == 'A')
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Ativo',
|
||||
enText: 'Active'): FlutterFlowTheme.of(context).success
|
||||
FFLocalizations.of(context).getVariableText(ptText: 'Ativo', enText: 'Active'):
|
||||
FlutterFlowTheme.of(context).success
|
||||
else if (local['CLU_STATUS'] == 'B')
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Bloqueado',
|
||||
enText: 'Blocked'): FlutterFlowTheme.of(context).error
|
||||
FFLocalizations.of(context).getVariableText(ptText: 'Bloqueado', enText: 'Blocked'):
|
||||
FlutterFlowTheme.of(context).error
|
||||
else
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Pendente',
|
||||
enText: 'Pending'): FlutterFlowTheme.of(context).warning
|
||||
FFLocalizations.of(context).getVariableText(ptText: 'Pendente', enText: 'Pending'):
|
||||
FlutterFlowTheme.of(context).warning
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -212,21 +199,16 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
|||
statusHashMap: [_statusHashMap(local)],
|
||||
onTapCardItemAction: () async {
|
||||
if (local['CLU_STATUS'] == 'A') {
|
||||
await StorageHelper()
|
||||
.set(ProfileStorageKey.clientUUID.key, local['CLI_ID']);
|
||||
await StorageHelper()
|
||||
.set(ProfileStorageKey.clientName.key, local['CLI_NOME']);
|
||||
await StorageHelper()
|
||||
.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.clientName.key, local['CLI_NOME']);
|
||||
await StorageHelper().set(ProfileStorageKey.ownerName.key, local['CLU_OWNER_DSC']);
|
||||
await StorageHelper().set(ProfileStorageKey.ownerUUID.key, local['CLU_OWNER_ID']);
|
||||
|
||||
context.pop(true);
|
||||
return true;
|
||||
} else if (local['CLU_STATUS'] == 'B') {
|
||||
String message = FFLocalizations.of(context).getVariableText(
|
||||
ptText:
|
||||
'Local Bloqueado para Acesso, Entre em Contato com Administração',
|
||||
ptText: 'Local Bloqueado para Acesso, Entre em Contato com Administração',
|
||||
enText: 'Location Blocked for Access, Contact Administration',
|
||||
);
|
||||
|
||||
|
@ -242,8 +224,7 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
|||
String localName = local['CLI_NOME'];
|
||||
showAlertDialog(
|
||||
context,
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Ativar Vínculo', enText: 'Activate Link'),
|
||||
FFLocalizations.of(context).getVariableText(ptText: 'Ativar Vínculo', enText: 'Activate Link'),
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Deseja aceitar o vínculo a $localName?',
|
||||
enText: 'Do you wish to accept the link to $localName?'),
|
||||
|
@ -300,8 +281,7 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
|||
height: height - (height * 0.5),
|
||||
decoration: BoxDecoration(
|
||||
color: FlutterFlowTheme.of(context).primaryBackground,
|
||||
borderRadius: const BorderRadius.only(
|
||||
topLeft: Radius.circular(25), topRight: Radius.circular(25))),
|
||||
borderRadius: const BorderRadius.only(topLeft: Radius.circular(25), topRight: Radius.circular(25))),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
|
@ -313,16 +293,13 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
|||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
Center(
|
||||
child: Text(FFLocalizations.of(context).getVariableText(
|
||||
ptText: "Nenhum Local Encontrado.",
|
||||
enText: "No local found")),
|
||||
child: Text(FFLocalizations.of(context)
|
||||
.getVariableText(ptText: "Nenhum Local Encontrado.", enText: "No local found")),
|
||||
)
|
||||
],
|
||||
),
|
||||
)
|
||||
else if (_hasData == true &&
|
||||
_loading == false &&
|
||||
_localsWrap.isNotEmpty)
|
||||
else if (_hasData == true && _loading == false && _localsWrap.isNotEmpty)
|
||||
Expanded(child: _listItems(context)),
|
||||
if (_loading == true)
|
||||
Container(
|
||||
|
@ -339,8 +316,7 @@ class _BottomArrowLinkedLocalsComponentWidgetState
|
|||
padding: const EdgeInsets.only(top: 10),
|
||||
child: Center(
|
||||
child: Text(
|
||||
FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Escolha um local', enText: 'Choose a location'),
|
||||
FFLocalizations.of(context).getVariableText(ptText: 'Escolha um local', enText: 'Choose a location'),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
)))),
|
||||
|
|
|
@ -47,7 +47,7 @@ class PhpGroup extends Api {
|
|||
static GetMessagesCall getMessagesCall = GetMessagesCall();
|
||||
static ChangeNotifica changeNotifica = ChangeNotifica();
|
||||
static UpdateIDE updateIDE = UpdateIDE();
|
||||
static RespondeVinculo resopndeVinculo = RespondeVinculo();
|
||||
static RespondeVinculo respondeVinculo = RespondeVinculo();
|
||||
static ChangePass changePass = ChangePass();
|
||||
static ChangePanic changePanic = ChangePanic();
|
||||
static DeleteAccount deleteAccount = DeleteAccount();
|
||||
|
|
|
@ -224,7 +224,7 @@ class LocalsRemoteDataSourceImpl implements LocalsRemoteDataSource {
|
|||
enText: 'Device unlinked successfully',
|
||||
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) {
|
||||
await StorageHelper().set(ProfileStorageKey.clientName.key, '');
|
||||
await StorageHelper().set(ProfileStorageKey.ownerName.key, '');
|
||||
|
|
|
@ -11,13 +11,10 @@ import 'package:hub/shared/utils/log_util.dart';
|
|||
|
||||
class LocalUtil {
|
||||
static void handleError(BuildContext context, String errorMsg) async {
|
||||
final String devUUID =
|
||||
await StorageHelper().get(ProfileStorageKey.devUUID.key) ?? '';
|
||||
final String userUUID =
|
||||
await StorageHelper().get(ProfileStorageKey.userUUID.key) ?? '';
|
||||
final String devUUID = await StorageHelper().get(ProfileStorageKey.devUUID.key) ?? '';
|
||||
final String userUUID = await StorageHelper().get(ProfileStorageKey.userUUID.key) ?? '';
|
||||
final bool isAuthenticated = userUUID.isNotEmpty && devUUID.isNotEmpty;
|
||||
final bool isDevLinked =
|
||||
!errorMsg.contains('Esse dispositivo nao pertence a esse usuario');
|
||||
final bool isDevLinked = !errorMsg.contains('Esse dispositivo nao pertence a esse usuario');
|
||||
log('() => isLinked: $errorMsg');
|
||||
if (!isAuthenticated) {
|
||||
errorMsg = FFLocalizations.of(context).getVariableText(
|
||||
|
@ -39,20 +36,15 @@ class LocalUtil {
|
|||
// await DialogUtil.error(context, errorMsg).whenComplete(() async => await LocalsRemoteDataSourceImpl().selectLocal(context, null));
|
||||
}
|
||||
|
||||
static Future<bool> handleUnavailable(
|
||||
BuildContext context, List<dynamic> locals) async {
|
||||
static Future<bool> handleUnavailable(BuildContext context, List<dynamic> locals) async {
|
||||
log('() => isUnavailable');
|
||||
try {
|
||||
await StorageHelper()
|
||||
.set(ProfileStorageKey.clientUUID.key, locals[0]['CLI_ID']);
|
||||
await StorageHelper()
|
||||
.set(ProfileStorageKey.ownerUUID.key, locals[0]['CLU_OWNER_ID']);
|
||||
await StorageHelper()
|
||||
.set(ProfileStorageKey.clientName.key, locals[0]['CLI_NOME']);
|
||||
await StorageHelper()
|
||||
.set(ProfileStorageKey.ownerName.key, locals[0]['CLU_OWNER_DSC']);
|
||||
await StorageHelper().set(ProfileStorageKey.clientUUID.key, locals[0]['CLI_ID']);
|
||||
await StorageHelper().set(ProfileStorageKey.ownerUUID.key, locals[0]['CLU_OWNER_ID']);
|
||||
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) {
|
||||
await StorageHelper().set(ProfileStorageKey.clientUUID.key, '');
|
||||
await StorageHelper().set(ProfileStorageKey.ownerUUID.key, '');
|
||||
|
@ -62,13 +54,10 @@ class LocalUtil {
|
|||
return false;
|
||||
}
|
||||
if (response.jsonBody['error'] == false)
|
||||
return await LocalsRemoteDataSourceImpl()
|
||||
.processProperty(context)
|
||||
.then((value) => value);
|
||||
return await LocalsRemoteDataSourceImpl().processProperty(context).then((value) => value);
|
||||
} catch (e, s) {
|
||||
await DialogUtil.errorDefault(context);
|
||||
LogUtil.requestAPIFailed(
|
||||
'responderVinculo.php', '', 'Responder Vínculo', e, s);
|
||||
LogUtil.requestAPIFailed('responderVinculo.php', '', 'Responder Vínculo', e, s);
|
||||
return false;
|
||||
}
|
||||
return false;
|
||||
|
@ -76,19 +65,12 @@ class LocalUtil {
|
|||
|
||||
static Future<bool> handleEnabled(BuildContext context, dynamic local) async {
|
||||
log('() => isEnabled');
|
||||
await StorageHelper()
|
||||
.set(ProfileStorageKey.clientUUID.key, local['CLI_ID']);
|
||||
await StorageHelper()
|
||||
.set(ProfileStorageKey.ownerUUID.key, local['CLU_OWNER_ID']);
|
||||
await StorageHelper()
|
||||
.set(ProfileStorageKey.clientName.key, local['CLI_NOME']);
|
||||
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 {
|
||||
await StorageHelper().set(ProfileStorageKey.clientUUID.key, local['CLI_ID']);
|
||||
await StorageHelper().set(ProfileStorageKey.ownerUUID.key, local['CLU_OWNER_ID']);
|
||||
await StorageHelper().set(ProfileStorageKey.clientName.key, local['CLI_NOME']);
|
||||
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();
|
||||
return v;
|
||||
});
|
||||
|
@ -111,10 +93,8 @@ class LocalUtil {
|
|||
|
||||
static Future<bool> updateStorageUtil(Map<String, dynamic> jsonBody) async {
|
||||
try {
|
||||
await StorageHelper()
|
||||
.set(LocalsStorageKey.whatsapp.key, jsonBody['whatsapp'] ?? false);
|
||||
await StorageHelper().set(
|
||||
LocalsStorageKey.provisional.key, jsonBody['provisional'] ?? false);
|
||||
await StorageHelper().set(LocalsStorageKey.whatsapp.key, jsonBody['whatsapp'] ?? false);
|
||||
await StorageHelper().set(LocalsStorageKey.provisional.key, jsonBody['provisional'] ?? false);
|
||||
await StorageHelper().set(
|
||||
LocalsStorageKey.pets.key,
|
||||
jsonBody['pet'] ?? false,
|
||||
|
@ -136,21 +116,14 @@ class LocalUtil {
|
|||
);
|
||||
}
|
||||
|
||||
await StorageHelper().set(
|
||||
LocalsStorageKey.petAmount.key,
|
||||
jsonBody['petAmountRegister']?.toString().isEmpty ?? true
|
||||
? '0'
|
||||
: jsonBody['petAmountRegister'].toString());
|
||||
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);
|
||||
await StorageHelper().set(LocalsStorageKey.petAmount.key,
|
||||
jsonBody['petAmountRegister']?.toString().isEmpty ?? true ? '0' : jsonBody['petAmountRegister'].toString());
|
||||
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;
|
||||
await StorageHelper()
|
||||
.set(LocalsStorageKey.isNewVersion.key, isNewVersion);
|
||||
await StorageHelper().set(LocalsStorageKey.isNewVersion.key, isNewVersion);
|
||||
return isNewVersion;
|
||||
} catch (e, s) {
|
||||
log('Error in _updateStorageUtil: $e', stackTrace: s);
|
||||
|
@ -163,44 +136,30 @@ class LocalUtil {
|
|||
}
|
||||
|
||||
static Future<bool> isInactived(List<dynamic> locals) async {
|
||||
String cliUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? '';
|
||||
return locals
|
||||
.where(
|
||||
(local) => local['CLI_ID'] != cliUUID && local['CLU_STATUS'] == 'A')
|
||||
.isNotEmpty;
|
||||
String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? '';
|
||||
return locals.where((local) => local['CLI_ID'] != cliUUID && local['CLU_STATUS'] == 'A').isNotEmpty;
|
||||
}
|
||||
|
||||
static bool isPending(List<dynamic> locals) {
|
||||
return locals
|
||||
.where(
|
||||
(local) => local['CLU_STATUS'] != 'B' && local['CLU_STATUS'] != 'A')
|
||||
.isNotEmpty;
|
||||
return locals.where((local) => local['CLU_STATUS'] != 'B' && local['CLU_STATUS'] != 'A').isNotEmpty;
|
||||
}
|
||||
|
||||
static Future<bool> isUnselected() async {
|
||||
String cliUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? '';
|
||||
String cliName =
|
||||
(await StorageHelper().get(ProfileStorageKey.clientName.key)) ?? '';
|
||||
String ownerUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.ownerUUID.key)) ?? '';
|
||||
String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? '';
|
||||
String cliName = (await StorageHelper().get(ProfileStorageKey.clientName.key)) ?? '';
|
||||
String ownerUUID = (await StorageHelper().get(ProfileStorageKey.ownerUUID.key)) ?? '';
|
||||
return cliUUID.isEmpty && cliName.isEmpty && ownerUUID.isEmpty;
|
||||
}
|
||||
|
||||
static Future<bool> isSelected(bool isInactived) async {
|
||||
String cliUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? '';
|
||||
String cliName =
|
||||
(await StorageHelper().get(ProfileStorageKey.clientName.key)) ?? '';
|
||||
String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? '';
|
||||
String cliName = (await StorageHelper().get(ProfileStorageKey.clientName.key)) ?? '';
|
||||
return cliUUID.isNotEmpty && cliName.isNotEmpty && isInactived;
|
||||
}
|
||||
|
||||
static Future<bool> isAvailable() async {
|
||||
String cliUUID =
|
||||
(await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? '';
|
||||
String cliName =
|
||||
(await StorageHelper().get(ProfileStorageKey.clientName.key)) ?? '';
|
||||
String cliUUID = (await StorageHelper().get(ProfileStorageKey.clientUUID.key)) ?? '';
|
||||
String cliName = (await StorageHelper().get(ProfileStorageKey.clientName.key)) ?? '';
|
||||
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';
|
||||
|
||||
abstract class MenuLocalDataSource {
|
||||
Future<MenuItem?> addMenuEntry(Key key, EnumMenuItem item,
|
||||
List<MenuItem?> entries, IconData icon, String text, Function() action);
|
||||
Future<MenuItem?> addMenuEntry(
|
||||
Key key, EnumMenuItem item, List<MenuItem?> entries, IconData icon, String text, Function() action);
|
||||
|
||||
Future<bool> processDisplayDefault(
|
||||
EnumMenuItem item, MenuEntry opt, List<MenuItem?> entries);
|
||||
Future<bool> processDisplayDefault(EnumMenuItem item, MenuEntry opt, List<MenuItem?> entries);
|
||||
|
||||
Future<void> handleMenu(EnumMenuItem item, EnumDisplay display, MenuEntry opt,
|
||||
List<MenuItem?> entries);
|
||||
|
||||
Future<bool> processStartDate(String startDate, MenuEntry entry);
|
||||
|
||||
Future<bool> processExpirationDate(String expirationDate, MenuEntry entry);
|
||||
Future<void> handleMenu(EnumMenuItem item, EnumDisplay display, MenuEntry opt, List<MenuItem?> entries);
|
||||
}
|
||||
|
||||
class MenuLocalDataSourceImpl implements MenuLocalDataSource {
|
||||
static final MenuLocalDataSourceImpl _instance =
|
||||
MenuLocalDataSourceImpl._internal();
|
||||
static final MenuLocalDataSourceImpl _instance = MenuLocalDataSourceImpl._internal();
|
||||
|
||||
factory MenuLocalDataSourceImpl() => _instance;
|
||||
|
||||
|
@ -52,12 +45,9 @@ class MenuLocalDataSourceImpl implements MenuLocalDataSource {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<bool> processDisplayDefault(
|
||||
EnumMenuItem item, MenuEntry opt, List<MenuItem?> entries) async {
|
||||
Future<bool> processDisplayDefault(EnumMenuItem item, MenuEntry opt, List<MenuItem?> entries) async {
|
||||
if (opt.key == 'FRE-HUB-LOGOUT') {
|
||||
await addMenuEntry(
|
||||
ValueKey<String>(opt.key), item, entries, opt.icon, opt.name,
|
||||
() async {
|
||||
await addMenuEntry(ValueKey<String>(opt.key), item, entries, opt.icon, opt.name, () async {
|
||||
await AuthenticationService.signOut(navigatorKey.currentContext!);
|
||||
});
|
||||
return true;
|
||||
|
@ -66,23 +56,17 @@ class MenuLocalDataSourceImpl implements MenuLocalDataSource {
|
|||
}
|
||||
|
||||
@override
|
||||
Future<void> handleMenu(EnumMenuItem item, EnumDisplay display, MenuEntry opt,
|
||||
List<MenuItem?> entries) async {
|
||||
Future<void> handleMenu(EnumMenuItem item, EnumDisplay display, MenuEntry opt, List<MenuItem?> entries) async {
|
||||
try {
|
||||
switch (display.value) {
|
||||
case 'VISIVEL':
|
||||
await addMenuEntry(
|
||||
ValueKey<String>(opt.key), item, entries, opt.icon, opt.name,
|
||||
() async {
|
||||
await addMenuEntry(ValueKey<String>(opt.key), item, entries, opt.icon, opt.name, () async {
|
||||
await PathUtil.nav(opt.route);
|
||||
});
|
||||
break;
|
||||
case 'DESABILITADO':
|
||||
await addMenuEntry(
|
||||
ValueKey<String>(opt.key), item, entries, opt.icon, opt.name,
|
||||
() async {
|
||||
await DialogUnavailable.unavailableFeature(
|
||||
navigatorKey.currentContext!);
|
||||
await addMenuEntry(ValueKey<String>(opt.key), item, entries, opt.icon, opt.name, () async {
|
||||
await DialogUnavailable.unavailableFeature(navigatorKey.currentContext!);
|
||||
});
|
||||
break;
|
||||
case 'INVISIVEL':
|
||||
|
@ -92,30 +76,4 @@ class MenuLocalDataSourceImpl implements MenuLocalDataSource {
|
|||
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/storage/index.dart';
|
||||
import 'package:hub/flutter_flow/custom_functions.dart';
|
||||
import 'package:hub/shared/utils/datetime_util.dart';
|
||||
|
||||
class MenuRepositoryImpl implements MenuRepository {
|
||||
final MenuLocalDataSource menuDataSource = MenuLocalDataSourceImpl();
|
||||
|
||||
@override
|
||||
Future<List<MenuItem?>> entries2Items(
|
||||
List<MenuEntry> menuEntries, EnumMenuItem menuItem) async {
|
||||
Future<List<MenuItem?>> entries2Items(List<MenuEntry> menuEntries, EnumMenuItem menuItem) async {
|
||||
List<MenuItem?> entries = [];
|
||||
// final bool isNewVersion = await StorageHelper().get(KeychainStorageKey.isNewVersion.value).then((v) => v.toBoolean());
|
||||
|
||||
try {
|
||||
for (var entry in menuEntries) {
|
||||
final bool isDefault = await menuDataSource.processDisplayDefault(
|
||||
menuItem, entry, entries);
|
||||
final bool isDefault = await menuDataSource.processDisplayDefault(menuItem, entry, entries);
|
||||
if (isDefault) continue;
|
||||
final licenseValue = await LicenseRepositoryImpl().getModule(entry.key);
|
||||
if (licenseValue != null) {
|
||||
|
@ -25,22 +24,18 @@ class MenuRepositoryImpl implements MenuRepository {
|
|||
final display = EnumDisplay.fromString(licenseMap['display']);
|
||||
final startDate = licenseMap['startDate'] ?? '';
|
||||
final expirationDate = licenseMap['expirationDate'] ?? '';
|
||||
final isStarted =
|
||||
await menuDataSource.processStartDate(startDate, entry);
|
||||
final isExpired =
|
||||
await menuDataSource.processExpirationDate(expirationDate, entry);
|
||||
final isStarted = await DateTimeUtil.processStartDate(startDate);
|
||||
final isExpired = await DateTimeUtil.processExpirationDate(expirationDate);
|
||||
if (isStarted && !isExpired) {
|
||||
await menuDataSource.handleMenu(menuItem, display, entry, entries);
|
||||
}
|
||||
if (isExpired) {
|
||||
log('Entry ${entry.key} is expired');
|
||||
await menuDataSource.handleMenu(
|
||||
menuItem, EnumDisplay.inactive, entry, entries);
|
||||
await menuDataSource.handleMenu(menuItem, EnumDisplay.inactive, entry, entries);
|
||||
}
|
||||
if (!isStarted) {
|
||||
log('Entry ${entry.key} is not started');
|
||||
await menuDataSource.handleMenu(
|
||||
menuItem, EnumDisplay.inactive, entry, entries);
|
||||
await menuDataSource.handleMenu(menuItem, EnumDisplay.inactive, entry, entries);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -50,11 +45,9 @@ class MenuRepositoryImpl implements MenuRepository {
|
|||
return entries;
|
||||
}
|
||||
|
||||
Future<EnumDisplay> processDisplay(
|
||||
Map<String, dynamic> module, bool isNewVersion) async {
|
||||
Future<EnumDisplay> processDisplay(Map<String, dynamic> module, bool isNewVersion) async {
|
||||
if (await _shouldUpdateDisplay(module, isNewVersion)) {
|
||||
final displayValue =
|
||||
module['display'] == EnumDisplay.active ? 'VISIVEL' : 'INVISIVEL';
|
||||
final displayValue = module['display'] == EnumDisplay.active ? 'VISIVEL' : 'INVISIVEL';
|
||||
await LicenseLocalDataSourceImpl(DatabaseService.database)
|
||||
.setDisplayByKey(['FRE-HUB-ABOUT-PROPERTY'], displayValue);
|
||||
return EnumDisplay.fromString(displayValue);
|
||||
|
@ -63,13 +56,8 @@ class MenuRepositoryImpl implements MenuRepository {
|
|||
return EnumDisplay.fromString(module['display']);
|
||||
}
|
||||
|
||||
Future<bool> _shouldUpdateDisplay(
|
||||
Map<String, dynamic> module, bool isNewVersion) async {
|
||||
const keysToCheck = [
|
||||
LicenseKeys.residents,
|
||||
LicenseKeys.vehicles,
|
||||
LicenseKeys.openedVisits
|
||||
];
|
||||
Future<bool> _shouldUpdateDisplay(Map<String, dynamic> module, bool isNewVersion) async {
|
||||
const keysToCheck = [LicenseKeys.residents, LicenseKeys.vehicles, LicenseKeys.openedVisits];
|
||||
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/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
|
||||
void initState(BuildContext context) {
|
||||
resetInstance();
|
||||
|
@ -36,25 +44,31 @@ class VehicleModel extends FlutterFlowModel<VehiclePage> {
|
|||
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> updateFormKey = GlobalKey<FormState>();
|
||||
|
||||
ApiCallResponse? vehicleResponse;
|
||||
bool isEditing = false;
|
||||
Future<void> initAsync() async {}
|
||||
|
||||
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!;
|
||||
bool isEditing = false;
|
||||
String? vehicleId;
|
||||
ApiCallResponse? vehicleResponse;
|
||||
|
||||
VoidCallback? onUpdateVehicle;
|
||||
VoidCallback? onRegisterVehicle;
|
||||
VoidCallback? safeSetState;
|
||||
|
||||
FocusNode? textFieldFocusLicensePlate;
|
||||
TextEditingController? textFieldControllerLicensePlate;
|
||||
|
@ -105,8 +119,35 @@ class VehicleModel extends FlutterFlowModel<VehiclePage> {
|
|||
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) {
|
||||
final statusMap = {
|
||||
"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 [
|
||||
if (item['status'].contains('AGU'))
|
||||
FFButtonWidget(
|
||||
text: FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Editar',
|
||||
enText: 'Edit',
|
||||
),
|
||||
icon: Icon(
|
||||
Icons.close,
|
||||
color: iconButtonColor,
|
||||
),
|
||||
onPressed: () async {
|
||||
context.pop();
|
||||
isEditing = true;
|
||||
item = item;
|
||||
|
||||
switchTab(1);
|
||||
setEditForm();
|
||||
},
|
||||
text: updateText,
|
||||
icon: updateIcon,
|
||||
onPressed: updateOnPressed,
|
||||
options: buttonOptions,
|
||||
),
|
||||
if (item['status'].contains('APR') || item['status'].contains('AGU'))
|
||||
FFButtonWidget(
|
||||
text: FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Cancelar',
|
||||
enText: 'Cancel',
|
||||
),
|
||||
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,
|
||||
);
|
||||
});
|
||||
});
|
||||
},
|
||||
text: cancelText,
|
||||
icon: cancelIcon,
|
||||
onPressed: cancelOnPressed,
|
||||
options: buttonOptions,
|
||||
),
|
||||
if (item['status'].contains('ATI'))
|
||||
FFButtonWidget(
|
||||
text: FFLocalizations.of(context).getVariableText(
|
||||
ptText: 'Excluir',
|
||||
enText: 'Delete',
|
||||
),
|
||||
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,
|
||||
);
|
||||
});
|
||||
});
|
||||
},
|
||||
text: deleteText,
|
||||
icon: deleteIcon,
|
||||
onPressed: deleteOnPressed,
|
||||
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) {
|
||||
return {
|
||||
if (item['model'] != null && item['model'] != '')
|
||||
|
@ -354,21 +431,42 @@ class VehicleModel extends FlutterFlowModel<VehiclePage> {
|
|||
statusHashMap: [status],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
void setEditForm() {
|
||||
if (item != null) {
|
||||
vehicleId = item['vehicleId'];
|
||||
textFieldControllerLicensePlate!.text = item['licensePlate'];
|
||||
textFieldControllerColor!.text = item['color'];
|
||||
textFieldControllerModel!.text = item['model'];
|
||||
/// [_VehicleRegisterScreenModel] is a mixin that contains the business logic of the vehicle register page.
|
||||
mixin _VehicleRegisterScreenModel on _BaseVehiclePage {
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool isFormValid(BuildContext context) {
|
||||
if (registerFormKey.currentState == null) return false;
|
||||
return registerFormKey.currentState!.validate();
|
||||
}
|
||||
|
||||
/// [_VehicleUpdateScreenModel] is a mixin that contains the business logic of the vehicle update page.
|
||||
mixin _VehicleUpdateScreenModel on _BaseVehiclePage {
|
||||
Future<void> updateVehicle() async {
|
||||
final response = await PhpGroup.updateVehicle.call(
|
||||
licensePlate: textFieldControllerLicensePlate!.text,
|
||||
|
@ -398,50 +496,4 @@ class VehicleModel extends FlutterFlowModel<VehiclePage> {
|
|||
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> {
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
double limitedInputFontSize = LimitedFontSizeUtil.getInputFontSize(context);
|
||||
double limitedHeaderFontSize = LimitedFontSizeUtil.getHeaderFontSize(context);
|
||||
double limitedSubHeaderFontSize = LimitedFontSizeUtil.getSubHeaderFontSize(context);
|
||||
|
||||
return SingleChildScrollView(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.max,
|
||||
children: [
|
||||
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,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
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),
|
||||
),
|
||||
],
|
||||
)),
|
||||
_buildHeader(context),
|
||||
_buildBody(context),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
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/pages/vehicles_on_the_property/vehicle_model.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/log_util.dart';
|
||||
import 'package:material_symbols_icons/symbols.dart';
|
||||
|
@ -27,6 +28,7 @@ class VehiclePage extends StatefulWidget {
|
|||
const VehiclePage({super.key});
|
||||
|
||||
@override
|
||||
// ignore: library_private_types_in_public_api
|
||||
_VehiclePageState createState() => _VehiclePageState();
|
||||
}
|
||||
|
||||
|
@ -55,24 +57,24 @@ class _VehiclePageState extends State<VehiclePage> with TickerProviderStateMixin
|
|||
};
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
super.dispose();
|
||||
}
|
||||
// @override
|
||||
// void dispose() {
|
||||
// super.dispose();
|
||||
// }
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
final backgroundColor = FlutterFlowTheme.of(context).primaryBackground;
|
||||
return Scaffold(
|
||||
backgroundColor: backgroundColor,
|
||||
appBar: _buildAppBar(context),
|
||||
body: buildBody(context),
|
||||
appBar: _buildHeader(context),
|
||||
body: _buildBody(context),
|
||||
);
|
||||
}
|
||||
|
||||
/// [Body] of the page.
|
||||
Widget buildBody(BuildContext context) {
|
||||
Widget progressEvent() {
|
||||
FutureBuilder<bool> _buildBody(BuildContext context) {
|
||||
Widget progressIndicator() {
|
||||
return CircularProgressIndicator(
|
||||
valueColor: AlwaysStoppedAnimation<Color>(
|
||||
FlutterFlowTheme.of(context).primary,
|
||||
|
@ -80,22 +82,14 @@ class _VehiclePageState extends State<VehiclePage> with TickerProviderStateMixin
|
|||
);
|
||||
}
|
||||
|
||||
Widget errorEvent() {
|
||||
WidgetsBinding.instance.addPostFrameCallback((_) async {
|
||||
context.pop();
|
||||
await DialogUtil.errorDefault(navigatorKey.currentContext!);
|
||||
});
|
||||
return progressEvent();
|
||||
}
|
||||
|
||||
return FutureBuilder<String?>(
|
||||
future: LicenseRepositoryImpl().getModule('FRE-HUB-VEHICLES-MANAGER'),
|
||||
return FutureBuilder<bool>(
|
||||
future: _initializeModule(),
|
||||
builder: (context, snapshot) {
|
||||
if (snapshot.connectionState == ConnectionState.waiting) {
|
||||
return progressEvent();
|
||||
return progressIndicator();
|
||||
} else if (snapshot.hasError) {
|
||||
return errorEvent();
|
||||
} else if (snapshot.hasData && snapshot.data!.isNotEmpty) {
|
||||
return progressIndicator();
|
||||
} else if (snapshot.hasData && snapshot.data == true) {
|
||||
return _buildVehicleManager(context);
|
||||
} else {
|
||||
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) {
|
||||
setState(() {
|
||||
_model.handleEditingChanged(value);
|
||||
|
@ -134,8 +141,8 @@ class _VehiclePageState extends State<VehiclePage> with TickerProviderStateMixin
|
|||
}
|
||||
|
||||
/// -----------------------------------
|
||||
/// [AppBar] with the title of the page.
|
||||
PreferredSizeWidget _buildAppBar(BuildContext context) {
|
||||
/// [Header] of the page.
|
||||
PreferredSizeWidget _buildHeader(BuildContext context) {
|
||||
final theme = FlutterFlowTheme.of(context);
|
||||
final backgroundColor = theme.primaryBackground;
|
||||
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