refinamento e modularização

This commit is contained in:
jantunemesssias 2025-02-03 11:35:07 -03:00
commit f64d65425f
34 changed files with 860 additions and 18284 deletions

3
.gitignore vendored
View File

@ -29,6 +29,9 @@
.pub-cache/ .pub-cache/
.pub/ .pub/
/build/ /build/
/coverage
.crashlytics
pubspec.lock
# Web related # Web related
lib/generated_plugin_registrant.dart lib/generated_plugin_registrant.dart

View File

@ -1,2 +1,2 @@
gradle 8.10.2 gradle 8.10.2
kotlin 1.8.22 kotlin 2.0.20

View File

@ -1,6 +1,7 @@
plugins { plugins {
id 'com.android.application' id 'com.android.application'
id 'com.android.library' apply false id 'com.android.library' apply false
id 'com.google.firebase.crashlytics'
id 'org.jetbrains.kotlin.android' id 'org.jetbrains.kotlin.android'
id "kotlin-android" id "kotlin-android"
@ -35,6 +36,7 @@ android {
namespace 'com.freaccess.hub' namespace 'com.freaccess.hub'
compileSdkVersion 34 compileSdkVersion 34
compileSdk 35 compileSdk 35
// ndkVersion "25.1.8937393" // Example version
sourceSets { sourceSets {
main.java.srcDirs += 'src/main/kotlin' main.java.srcDirs += 'src/main/kotlin'
@ -96,6 +98,15 @@ android {
minifyEnabled true minifyEnabled true
shrinkResources true shrinkResources true
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro' proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
firebaseCrashlytics {
mappingFileUploadEnabled true
nativeSymbolUploadEnabled false // Disable NDK symbol upload
unstrippedNativeLibsDir "build/intermediates/merged_native_libs/release/out/lib" // Add this
strippedNativeLibsDir "build/intermediates/stripped_native_libs/release/out/lib"
// Point to your google-services.json location
// googleServicesResourceRoot "${project.projectDir}/../../android/app"
}
} }
debug { debug {
signingConfig signingConfigs.debug signingConfig signingConfigs.debug
@ -129,3 +140,4 @@ dependencies {
} }
apply plugin: 'com.google.gms.google-services' apply plugin: 'com.google.gms.google-services'
// id 'com.google.firebase.crashlytics'

View File

@ -3,7 +3,7 @@
"project_number": "187064172787", "project_number": "187064172787",
"firebase_url": "https://accessmoblie-da839.firebaseio.com", "firebase_url": "https://accessmoblie-da839.firebaseio.com",
"project_id": "accessmoblie-da839", "project_id": "accessmoblie-da839",
"storage_bucket": "accessmoblie-da839.appspot.com" "storage_bucket": "accessmoblie-da839.firebasestorage.app"
}, },
"client": [ "client": [
{ {

View File

@ -1,8 +1,8 @@
// Top-level build file where you can add configuration options common to all sub-projects/modules. // Top-level build file where you can add configuration options common to all sub-projects/modules.
buildscript { buildscript {
ext.kotlin_version = '1.8.22' ext.kotlin_version = '2.0.20'
ext.gradle_version = '8.6.0' // Replace with the latest version ext.gradle_version = '8.8.0' // Replace with the latest version
ext.google_services_version = '4.4.2' // Replace with the latest version ext.google_services_version = '4.4.1' // Replace with the latest version
repositories { repositories {
google() google()
mavenCentral() mavenCentral()
@ -12,6 +12,7 @@ buildscript {
// Use a versão do Gradle que corresponde à sua configuração // Use a versão do Gradle que corresponde à sua configuração
classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version"
classpath "com.google.gms:google-services:$google_services_version" classpath "com.google.gms:google-services:$google_services_version"
classpath 'com.google.firebase:firebase-crashlytics-gradle:2.9.9'
// Google Services plugin // Google Services plugin
} }
} }

View File

@ -18,13 +18,13 @@ pluginManagement {
plugins { plugins {
id "dev.flutter.flutter-plugin-loader" version "1.0.0" id "dev.flutter.flutter-plugin-loader" version "1.0.0"
id 'com.android.application' version '8.6.0' apply false id 'com.android.application' version '8.8.0' apply false
id 'com.android.library' version '8.6.0' apply false id 'com.android.library' version '8.8.0' apply false
id 'org.jetbrains.kotlin.android' version '1.8.22' apply false id 'org.jetbrains.kotlin.android' version '2.0.20' apply false
// START: FlutterFire Configuration // START: FlutterFire Configuration
id "com.google.gms.google-services" version "4.3.15" apply false id "com.google.gms.google-services" version "4.4.1" apply false
// END: FlutterFire Configuration // END: FlutterFire Configuration
// id "org.jetbrains.kotlin.android" version "1.7.10" apply false // id "org.jetbrains.kotlin.android" version "1.7.10" apply false
// id "org.jetbrains.kotlin.android" version "1.8.10" apply false // id "org.jetbrains.kotlin.android" version "1.8.10" apply false

File diff suppressed because it is too large Load Diff

View File

@ -25,29 +25,44 @@ import 'package:hub/pages/vehicles_on_the_property/vehicles_on_the_property.dart
import 'package:integration_test/integration_test.dart'; import 'package:integration_test/integration_test.dart';
import 'package:material_symbols_icons/symbols.dart'; import 'package:material_symbols_icons/symbols.dart';
import 'package:flutter_web_plugins/url_strategy.dart'; import 'package:flutter_web_plugins/url_strategy.dart';
import 'package:patrol/patrol.dart';
import 'app_test.dart'; import 'app_test.dart';
import 'fuzzer/fuzzer.dart'; import 'fuzzer/fuzzer.dart';
import 'package:patrol_finders/patrol_finders.dart';
import 'package:integration_test/integration_test.dart';
export 'package:flutter_test/flutter_test.dart'; export 'package:flutter_test/flutter_test.dart';
export 'package:patrol/patrol.dart'; export 'package:patrol/patrol.dart';
part 'auth_test.dart'; part 'auth_test.dart';
part 'common.dart'; part 'common.dart';
part 'home_test.dart'; part 'home_test.dart';
part 'locals_test.dart'; part 'locals_test.dart';
part 'menu_test.dart'; part 'menu_test.dart';
part 'module_test.dart'; part 'module_test.dart';
part 'notify_test.dart'; part 'notify_test.dart';
part 'profile_test.dart'; part 'profile_test.dart';
part 'property_test.dart'; part 'property_test.dart';
part 'setting_test.dart'; part 'setting_test.dart';
part 'storage_test.dart'; part 'storage_test.dart';
part 'utils_test.dart'; part 'utils_test.dart';
part 'welcome_test.dart'; part 'welcome_test.dart';
part 'vehicle_test.dart'; part 'vehicle_test.dart';
late PatrolIntegrationTester $; late PatrolTester $;
void main() { void main() {
//init integration test //init integration test
@ -56,20 +71,20 @@ void main() {
// setUp(() async {}); // setUp(() async {});
// tearDown(() async {}); // tearDown(() async {});
// WelcomeTest.signInToSignUp(); WelcomeTest.signInToSignUp();
// WelcomeTest.signUpToSignIn(); WelcomeTest.signUpToSignIn();
// AuthenticationTest.signIn(); // AuthenticationTest.signIn();
// AuthenticationTest.signUp(); // AuthenticationTest.signUp();
// AuthenticationTest.signOut(); // AuthenticationTest.signOut();
// AuthenticationTest.recovery(); // AuthenticationTest.recovery();
// ModularizationTest.switchLicense(); ModularizationTest.switchLicense();
// ModularizationTest.containLicense(); ModularizationTest.containLicense();
// MenuTest.navToEntries(); MenuTest.navToEntries();
// MenuTest.containEntries(); MenuTest.containEntries();
// MenuTest.labels2AppbarConsistency(); MenuTest.labels2AppbarConsistency();
// LocalsTest.setLocal(); // LocalsTest.setLocal();
// LocalsTest.unlinkLocal(); // LocalsTest.unlinkLocal();

View File

@ -2,9 +2,9 @@ part of 'app_test.dart';
class AuthenticationTest { class AuthenticationTest {
static Future<void> signIn() async { static Future<void> signIn() async {
patrol( patrolWidgetTest(
'Sign-In with fuzzed emails', 'Sign-In with fuzzed emails',
(PatrolIntegrationTester tester) async { (PatrolTester tester) async {
$ = tester; $ = tester;
$.tester $.tester
.printToConsole('Authentication Test - Sign-In with fuzzed emails'); .printToConsole('Authentication Test - Sign-In with fuzzed emails');
@ -43,7 +43,7 @@ class AuthenticationTest {
final credentials = fuzzer.fuzz(concat); final credentials = fuzzer.fuzz(concat);
await _unlogged($); await _unlogged();
await $.pumpWidgetAndSettle(const App()); await $.pumpWidgetAndSettle(const App());
await _navigateToSignIn($); await _navigateToSignIn($);
@ -59,9 +59,9 @@ class AuthenticationTest {
}, },
); );
patrol( patrolWidgetTest(
'Sign-In with email_app@exemplo.com', 'Sign-In with email_app@exemplo.com',
(PatrolIntegrationTester tester) async { (PatrolTester tester) async {
$ = tester; $ = tester;
$.tester.printToConsole( $.tester.printToConsole(
'Authentication Test - Sign-In with email_app@exemplo.com'); 'Authentication Test - Sign-In with email_app@exemplo.com');
@ -72,7 +72,7 @@ class AuthenticationTest {
'passwordTextFormField': '12345678', 'passwordTextFormField': '12345678',
}; };
await _unlogged($); await _unlogged();
await $.pumpWidgetAndSettle(const App()); await $.pumpWidgetAndSettle(const App());
await _navigateToSignIn($); await _navigateToSignIn($);
await _auth(credentials, $, throwsException); await _auth(credentials, $, throwsException);
@ -81,9 +81,9 @@ class AuthenticationTest {
} }
static Future<void> signUp() async { static Future<void> signUp() async {
patrol( patrolWidgetTest(
'Sign Up - credenciais já registradas', 'Sign Up - credenciais já registradas',
(PatrolIntegrationTester tester) async { (PatrolTester tester) async {
$ = tester; $ = tester;
$.tester.printToConsole( $.tester.printToConsole(
'Authentication Test - Sign-Up: credenciais já registradas'); 'Authentication Test - Sign-Up: credenciais já registradas');
@ -94,7 +94,7 @@ class AuthenticationTest {
'emailTextFormField': 'email_app@exemplo.com', 'emailTextFormField': 'email_app@exemplo.com',
'passwordTextFormField': '12345678', 'passwordTextFormField': '12345678',
}; };
await _unlogged($); await _unlogged();
await $.pumpWidgetAndSettle(const App()); await $.pumpWidgetAndSettle(const App());
await _navigateToSignUp($); await _navigateToSignUp($);
await _auth(credentials, $, throwsException); await _auth(credentials, $, throwsException);
@ -102,9 +102,9 @@ class AuthenticationTest {
}, },
); );
patrol( patrolWidgetTest(
'Sign Up - credenciais novas', 'Sign Up - credenciais novas',
(PatrolIntegrationTester tester) async { (PatrolTester tester) async {
$ = tester; $ = tester;
$.tester $.tester
.printToConsole('Authentication Test - Sign-Up: credenciais novas'); .printToConsole('Authentication Test - Sign-Up: credenciais novas');
@ -151,7 +151,7 @@ class AuthenticationTest {
final credentials = fuzzer.fuzz(concat); final credentials = fuzzer.fuzz(concat);
await _unlogged($); await _unlogged();
await $.pumpWidgetAndSettle(const App()); await $.pumpWidgetAndSettle(const App());
@ -170,14 +170,14 @@ class AuthenticationTest {
} }
static Future<void> signOut() async { static Future<void> signOut() async {
patrol( patrolWidgetTest(
'Deslogar da Conta', 'Deslogar da Conta',
(PatrolIntegrationTester tester) async { (PatrolTester tester) async {
$ = tester; $ = tester;
$.tester.printToConsole( $.tester.printToConsole(
'Authentication Test - Sign-Out: Deslogar da Conta'); 'Authentication Test - Sign-Out: Deslogar da Conta');
await _loggedWithMultiLocalsAccount($); await _loggedWithMultiLocalsAccount();
await $.pumpWidget(const App()); await $.pumpWidget(const App());
await $.waitUntilVisible($(MenuStaggeredView)); await $.waitUntilVisible($(MenuStaggeredView));
@ -197,7 +197,7 @@ class AuthenticationTest {
static void recovery() async { static void recovery() async {
patrol('Open url in the app', ($) async { patrol('Open url in the app', ($) async {
await _loggedWithMultiLocalsAccount($); await _loggedWithMultiLocalsAccount();
await $.pumpWidget(const App()); await $.pumpWidget(const App());
await $.waitUntilVisible($(MenuStaggeredView)); await $.waitUntilVisible($(MenuStaggeredView));
@ -221,7 +221,7 @@ class AuthenticationTest {
Future<void> _auth( Future<void> _auth(
Map<String, String> credentials, Map<String, String> credentials,
PatrolIntegrationTester $, PatrolTester $,
PatrolFinder throwsException, PatrolFinder throwsException,
) async { ) async {
await _enterCredentials(credentials, $); await _enterCredentials(credentials, $);
@ -230,7 +230,7 @@ Future<void> _auth(
Future<void> _enterCredentials( Future<void> _enterCredentials(
Map<String, String> credentials, Map<String, String> credentials,
PatrolIntegrationTester $, PatrolTester $,
) async { ) async {
for (var entry in credentials.entries) { for (var entry in credentials.entries) {
await $(ValueKey(entry.key)) // await $(ValueKey(entry.key)) //
@ -241,7 +241,7 @@ Future<void> _enterCredentials(
} }
Future<void> _submit( Future<void> _submit(
String key, PatrolIntegrationTester $, PatrolFinder throwsException) async { String key, PatrolTester $, PatrolFinder throwsException) async {
await $(ValueKey(key)) // await $(ValueKey(key)) //
.waitUntilVisible() .waitUntilVisible()
.tap(); .tap();

View File

@ -1,11 +1,11 @@
part of 'app_test.dart'; part of 'app_test.dart';
final _patrolTesterConfig = PatrolTesterConfig(printLogs: true); final _PatrolTesterConfig = PatrolTesterConfig(printLogs: true);
final _nativeAutomatorConfig = NativeAutomatorConfig( final _nativeAutomatorConfig = NativeAutomatorConfig(
findTimeout: Duration(seconds: 20), // 10 seconds is too short for some CIs findTimeout: Duration(seconds: 20), // 10 seconds is too short for some CIs
); );
// Future<void> createApp(PatrolIntegrationTester $) async { // Future<void> createApp(PatrolTester $) async {
// await app_main.main(); // await app_main.main();
// await $.pumpAndSettle(); // await $.pumpAndSettle();
// } // }
@ -21,7 +21,7 @@ void patrol(
}) { }) {
patrolTest( patrolTest(
description, description,
config: _patrolTesterConfig, config: _PatrolTesterConfig,
nativeAutomatorConfig: nativeAutomatorConfig ?? _nativeAutomatorConfig, nativeAutomatorConfig: nativeAutomatorConfig ?? _nativeAutomatorConfig,
framePolicy: framePolicy, framePolicy: framePolicy,
skip: skip, skip: skip,

View File

@ -46,13 +46,13 @@ class LocalsTest {
// } // }
// }, // },
// ); // );
patrol( patrolWidgetTest(
'Selecionar um local disponível com somente um local disponivel', // 'Selecionar um local disponível com somente um local disponivel', //
(PatrolIntegrationTester tester) async { (PatrolTester tester) async {
$ = tester; $ = tester;
$.tester.printToConsole('Locals Test - Selecionar um local disponível'); $.tester.printToConsole('Locals Test - Selecionar um local disponível');
await _loggedWithSomeoneLocalAccount($, false); await _loggedWithSomeoneLocalAccount(false);
await $.pumpWidgetAndSettle(const App()); await $.pumpWidgetAndSettle(const App());
await $.waitUntilVisible($(MenuStaggeredView)); await $.waitUntilVisible($(MenuStaggeredView));
await $.waitUntilVisible($(LocalProfileComponentWidget)); await $.waitUntilVisible($(LocalProfileComponentWidget));
@ -184,14 +184,14 @@ class LocalsTest {
// // } // // }
// }, // },
// ); // );
patrol( patrolWidgetTest(
'Desvincular do local selecionado com somente um local disponivel', // 'Desvincular do local selecionado com somente um local disponivel', //
(PatrolIntegrationTester tester) async { (PatrolTester tester) async {
$ = tester; $ = tester;
$.tester.printToConsole( $.tester.printToConsole(
'Locals Test - Desvincular do local selecionado com multiplos locais disponiveis'); 'Locals Test - Desvincular do local selecionado com multiplos locais disponiveis');
await _loggedWithSomeoneLocalAccount($); await _loggedWithSomeoneLocalAccount();
await $.pumpWidgetAndSettle(const App()); await $.pumpWidgetAndSettle(const App());
await $.waitUntilVisible($(MenuStaggeredView)); await $.waitUntilVisible($(MenuStaggeredView));
@ -247,13 +247,13 @@ class LocalsTest {
expect(entriesFinder, findsWidgets); expect(entriesFinder, findsWidgets);
}); });
patrol( patrolWidgetTest(
'Vincular um local desvinculado com somente um local disponivel', // 'Vincular um local desvinculado com somente um local disponivel', //
(PatrolIntegrationTester tester) async { (PatrolTester tester) async {
$ = tester; $ = tester;
$.tester.printToConsole('Locals Test - Vincular um local desvinculado'); $.tester.printToConsole('Locals Test - Vincular um local desvinculado');
await _loggedWithSomeoneLocalAccount($, false); await _loggedWithSomeoneLocalAccount(false);
await $.pumpWidget(const App()); await $.pumpWidget(const App());
final PatrolFinder bottomSheetFinder = final PatrolFinder bottomSheetFinder =
@ -302,74 +302,62 @@ class LocalsTest {
} }
static Future attachLocal() async { static Future attachLocal() async {
patrol( patrolWidgetTest(
'Selecionar um local disponível com multíplos locais disponíveis', // 'Auto-Validação de Locais com Multiplos Locais', //
(PatrolIntegrationTester tester) async { (PatrolTester tester) async {
$ = tester; $ = tester;
await _loggedWithMultiLocalsAccount($); $.tester.printToConsole('Locals Test - Vincular um local desvinculado');
await _loggedWithMultiLocalsAccount(false);
await $.pumpWidget(const App()); await $.pumpWidget(const App());
late Map<String, String> credentials;
final PatrolFinder throwsException = $('');
var name = ff.randomString(7, 7, true, true, true); final PatrolFinder bottomSheetFinder =
var email = '$name@example.com'; await $(BottomArrowLinkedLocalsComponentWidget) //
var password = '12345678'; .waitUntilVisible();
credentials = { expect(bottomSheetFinder, findsOneWidget);
'nameTextFormField': name,
'emailTextFormField': email,
'passwordTextFormField': password
};
await $.pumpWidget(const App()); await $.pump(const Duration(milliseconds: 500));
await _navigateToSignUp($);
await _auth(credentials, $, throwsException); final PatrolFinder listViewFinder = $(bottomSheetFinder) //
credentials = { .$(ListView);
'emailTextFormField': email, expect(listViewFinder, findsOneWidget);
'passwordTextFormField': password
}; await $.pump(const Duration(milliseconds: 500));
await _auth(credentials, $, throwsException);
final PatrolFinder entriesFinder = $(listViewFinder) //
.$(CardItemTemplateComponentWidget);
expect(entriesFinder, findsWidgets);
await $.pumpAndSettle();
await StorageHelper() //
.set(ProfileStorageKey.clientUUID.key, '7');
await $.pumpAndSettle();
await Future.delayed(const Duration(milliseconds: 500)); await Future.delayed(const Duration(milliseconds: 500));
return;
}, },
); );
patrol( patrolWidgetTest(
'Selecionar um local disponível com somente um local disponível', // 'Auto-Validação de Locais com local unico', //
(PatrolIntegrationTester tester) async { (PatrolTester tester) async {
$ = tester; $ = tester;
await _loggedWithSomeoneLocalAccount($); $.tester.printToConsole('Locals Test - Vincular um local desvinculado');
await _loggedWithSomeoneLocalAccount(false);
await $.pumpWidget(const App()); await $.pumpWidget(const App());
late Map<String, String> credentials;
final PatrolFinder throwsException = $('');
var name = ff.randomString(7, 7, true, true, true); final PatrolFinder bottomSheetFinder =
var email = '$name@example.com'; await $(BottomArrowLinkedLocalsComponentWidget) //
var password = '12345678'; .waitUntilVisible();
credentials = { expect(bottomSheetFinder, findsOneWidget);
'nameTextFormField': name,
'emailTextFormField': email,
'passwordTextFormField': password
};
await $.pumpWidget(const App()); await $.pump(const Duration(milliseconds: 500));
await _navigateToSignUp($);
await _auth(credentials, $, throwsException); final PatrolFinder listViewFinder = $(bottomSheetFinder) //
credentials = { .$(ListView);
'emailTextFormField': email, expect(listViewFinder, findsOneWidget);
'passwordTextFormField': password
}; await $.pump(const Duration(milliseconds: 500));
await _auth(credentials, $, throwsException);
final PatrolFinder entriesFinder = $(listViewFinder) //
.$(CardItemTemplateComponentWidget);
expect(entriesFinder, findsWidgets);
await $.pumpAndSettle();
await StorageHelper() //
.set(ProfileStorageKey.clientUUID.key, '7');
await $.pumpAndSettle();
await Future.delayed(const Duration(milliseconds: 500)); await Future.delayed(const Duration(milliseconds: 500));
return;
}, },
); );
} }

View File

@ -2,15 +2,15 @@ part of 'app_test.dart';
class MenuTest { class MenuTest {
static Future labels2AppbarConsistency() async { static Future labels2AppbarConsistency() async {
patrol( patrolWidgetTest(
'As labels dos menuItems correspondem aos títulos das AppBars? (MultiLocais)', 'As labels dos menuItems correspondem aos títulos das AppBars? (MultiLocais)',
// //
(PatrolIntegrationTester tester) async { (PatrolTester tester) async {
$ = tester; $ = tester;
$.tester.printToConsole( $.tester.printToConsole(
'Menu Test - As labels dos menuItems correspondem aos títulos das AppBars?'); 'Menu Test - As labels dos menuItems correspondem aos títulos das AppBars?');
await _loggedWithMultiLocalsAccount($); await _loggedWithMultiLocalsAccount();
await $.pumpWidgetAndSettle(const App()); await $.pumpWidgetAndSettle(const App());
await $.waitUntilVisible($(MenuStaggeredView)); await $.waitUntilVisible($(MenuStaggeredView));
@ -96,13 +96,13 @@ class MenuTest {
} }
static Future containEntries() async { static Future containEntries() async {
patrol( patrolWidgetTest(
'HomeMenu contém seus itens? (MultiLocais)', // 'HomeMenu contém seus itens? (MultiLocais)', //
(PatrolIntegrationTester tester) async { (PatrolTester tester) async {
$ = tester; $ = tester;
$.tester.printToConsole('Menu Test - HomeMenu contém seus itens?'); $.tester.printToConsole('Menu Test - HomeMenu contém seus itens?');
await _loggedWithMultiLocalsAccount($); await _loggedWithMultiLocalsAccount();
await $.pumpWidgetAndSettle(const App()); await $.pumpWidgetAndSettle(const App());
await $.waitUntilVisible($(MenuStaggeredView)); await $.waitUntilVisible($(MenuStaggeredView));
@ -135,13 +135,13 @@ class MenuTest {
expect(entriesKey, containsAll(menuKeys)); expect(entriesKey, containsAll(menuKeys));
}, },
); );
patrol( patrolWidgetTest(
'HomeMenu contém seus itens? (MonoLocal)', // 'HomeMenu contém seus itens? (MonoLocal)', //
(PatrolIntegrationTester tester) async { (PatrolTester tester) async {
$ = tester; $ = tester;
$.tester.printToConsole('Menu Test - HomeMenu contém seus itens?'); $.tester.printToConsole('Menu Test - HomeMenu contém seus itens?');
await _loggedWithSomeoneLocalAccount($); await _loggedWithSomeoneLocalAccount();
await $.pumpWidgetAndSettle(const App()); await $.pumpWidgetAndSettle(const App());
await $.waitUntilVisible($(MenuStaggeredView)); await $.waitUntilVisible($(MenuStaggeredView));
@ -175,13 +175,13 @@ class MenuTest {
}, },
); );
patrol( patrolWidgetTest(
'DrawerMenu contém seus itens? (MultiLocais)', // 'DrawerMenu contém seus itens? (MultiLocais)', //
(PatrolIntegrationTester tester) async { (PatrolTester tester) async {
$ = tester; $ = tester;
$.tester.printToConsole('Menu Test - DrawerMenu contém seus itens?'); $.tester.printToConsole('Menu Test - DrawerMenu contém seus itens?');
await _loggedWithMultiLocalsAccount($); await _loggedWithMultiLocalsAccount();
await $.pumpWidgetAndSettle(const App()); await $.pumpWidgetAndSettle(const App());
await $.waitUntilVisible($(MenuStaggeredView)); await $.waitUntilVisible($(MenuStaggeredView));
@ -222,13 +222,13 @@ class MenuTest {
await Future.delayed(const Duration(milliseconds: 500)); await Future.delayed(const Duration(milliseconds: 500));
}, },
); );
patrol( patrolWidgetTest(
'DrawerMenu contém seus itens? (MonoLocal)', // 'DrawerMenu contém seus itens? (MonoLocal)', //
(PatrolIntegrationTester tester) async { (PatrolTester tester) async {
$ = tester; $ = tester;
$.tester.printToConsole('Menu Test - DrawerMenu contém seus itens?'); $.tester.printToConsole('Menu Test - DrawerMenu contém seus itens?');
await _loggedWithSomeoneLocalAccount($); await _loggedWithSomeoneLocalAccount();
await $.pumpWidgetAndSettle(const App()); await $.pumpWidgetAndSettle(const App());
await $.waitUntilVisible($(MenuStaggeredView)); await $.waitUntilVisible($(MenuStaggeredView));
@ -272,13 +272,13 @@ class MenuTest {
} }
static Future navToEntries() async { static Future navToEntries() async {
patrol( patrolWidgetTest(
'Navegação entre items do Menu (MultiLocais)', 'Navegação entre items do Menu (MultiLocais)',
(PatrolIntegrationTester tester) async { (PatrolTester tester) async {
$ = tester; $ = tester;
$.tester.printToConsole('Menu Test - Navegação entre items do Menu'); $.tester.printToConsole('Menu Test - Navegação entre items do Menu');
await _loggedWithMultiLocalsAccount($); await _loggedWithMultiLocalsAccount();
await $.pumpWidgetAndSettle(const App()); await $.pumpWidgetAndSettle(const App());
await $.waitUntilVisible($(MenuStaggeredView)); await $.waitUntilVisible($(MenuStaggeredView));

View File

@ -2,13 +2,14 @@ part of 'app_test.dart';
class ModularizationTest { class ModularizationTest {
static Future containLicense() async { static Future containLicense() async {
patrol('Os modulos de licença está sendo processados? (MultiLocais)', patrolWidgetTest(
(PatrolIntegrationTester tester) async { 'Os modulos de licença está sendo processados? (MultiLocais)',
(PatrolTester tester) async {
$ = tester; $ = tester;
$.tester.printToConsole( $.tester.printToConsole(
'Modularization Test - Os modulos de licença está sendo processados?'); 'Modularization Test - Os modulos de licença está sendo processados?');
await _loggedWithMultiLocalsAccount($); await _loggedWithMultiLocalsAccount();
await $.pumpWidgetAndSettle(const App()); await $.pumpWidgetAndSettle(const App());
await $.waitUntilVisible($(MenuStaggeredView)); await $.waitUntilVisible($(MenuStaggeredView));
@ -27,13 +28,14 @@ class ModularizationTest {
return; return;
}); });
patrol('Os modulos de licença está sendo processados? (MonoLocal)', patrolWidgetTest(
(PatrolIntegrationTester tester) async { 'Os modulos de licença está sendo processados? (MonoLocal)',
(PatrolTester tester) async {
$ = tester; $ = tester;
$.tester.printToConsole( $.tester.printToConsole(
'Modularization Test - Os modulos de licença está sendo processados?'); 'Modularization Test - Os modulos de licença está sendo processados?');
await _loggedWithSomeoneLocalAccount($); await _loggedWithSomeoneLocalAccount();
await $.pumpWidgetAndSettle(const App()); await $.pumpWidgetAndSettle(const App());
await $.waitUntilVisible($(MenuStaggeredView)); await $.waitUntilVisible($(MenuStaggeredView));
@ -55,13 +57,13 @@ class ModularizationTest {
} }
static Future switchLicense() async { static Future switchLicense() async {
patrol( patrolWidgetTest(
'Licença está sendo atualizada?', 'Licença está sendo atualizada?',
(PatrolIntegrationTester tester) async { (PatrolTester tester) async {
$ = tester; $ = tester;
$.tester.printToConsole('Licença está sendo atualizada?'); $.tester.printToConsole('Licença está sendo atualizada?');
await _loggedWithMultiLocalsAccount($); await _loggedWithMultiLocalsAccount();
await $.pumpWidgetAndSettle(const App()); await $.pumpWidgetAndSettle(const App());
await $.waitUntilVisible($(MenuStaggeredView)); await $.waitUntilVisible($(MenuStaggeredView));

View File

@ -1,8 +1,8 @@
part of 'app_test.dart'; part of 'app_test.dart';
Future<void> _loggedWithMultiLocalsAccount(PatrolIntegrationTester $, Future<void> _loggedWithMultiLocalsAccount(
[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');
await StorageHelper() // await StorageHelper() //
@ -19,18 +19,23 @@ 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().set(ProfileStorageKey.clientUUID.key, '7'); await StorageHelper() //
await StorageHelper().set(ProfileStorageKey.ownerUUID.key, '7'); .set(ProfileStorageKey.clientUUID.key, '7');
await StorageHelper() await StorageHelper() //
.set(ProfileStorageKey.ownerUUID.key, '7');
await StorageHelper() //
.set(ProfileStorageKey.clientName.key, 'FRE ACCESS DEMO'); .set(ProfileStorageKey.clientName.key, 'FRE ACCESS DEMO');
await PhpGroup.resopndeVinculo.call(tarefa: 'A'); await PhpGroup //
await LicenseRepositoryImpl().resetLicense(); .resopndeVinculo
.call(tarefa: 'A');
await LicenseRepositoryImpl() //
.resetLicense();
} }
} }
Future<void> _loggedWithSomeoneLocalAccount(PatrolIntegrationTester $, Future<void> _loggedWithSomeoneLocalAccount(
[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');
await StorageHelper() // await StorageHelper() //
@ -47,17 +52,22 @@ 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().set(ProfileStorageKey.clientUUID.key, '7'); await StorageHelper() //
await StorageHelper().set(ProfileStorageKey.ownerUUID.key, '7'); .set(ProfileStorageKey.clientUUID.key, '7');
await StorageHelper() await StorageHelper() //
.set(ProfileStorageKey.ownerUUID.key, '7');
await StorageHelper() //
.set(ProfileStorageKey.clientName.key, 'FRE ACCESS DEMO'); .set(ProfileStorageKey.clientName.key, 'FRE ACCESS DEMO');
await PhpGroup.resopndeVinculo.call(tarefa: 'A'); await PhpGroup //
await LicenseRepositoryImpl().resetLicense(); .resopndeVinculo
.call(tarefa: 'A');
await LicenseRepositoryImpl() //
.resetLicense();
} }
} }
Future<void> _unlogged(PatrolIntegrationTester $) async { Future<void> _unlogged() async {
await _init($); await _init();
await StorageHelper() // await StorageHelper() //
.set(SecureStorageKey.isLogged.value, 'false'); .set(SecureStorageKey.isLogged.value, 'false');
await StorageHelper() // await StorageHelper() //
@ -76,7 +86,7 @@ Future<void> _unlogged(PatrolIntegrationTester $) async {
.set(LocalsStorageKey.isNewVersion.key, true); .set(LocalsStorageKey.isNewVersion.key, true);
} }
Future<void> _init(PatrolIntegrationTester $) async { Future<void> _init() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
await _initializeTracking(); await _initializeTracking();
await _initializeStorage(); await _initializeStorage();
@ -88,12 +98,12 @@ Future<void> _init(PatrolIntegrationTester $) async {
await _initializeNav(); await _initializeNav();
} }
Future<void> _navigateToSignIn(PatrolIntegrationTester $) async { Future<void> _navigateToSignIn(PatrolTester $) async {
final signInButton = $(#toggleSignInPage).waitUntilVisible(); final signInButton = $(#toggleSignInPage).waitUntilVisible();
await signInButton.tap(); await signInButton.tap();
} }
Future<void> _navigateToSignUp(PatrolIntegrationTester $) async { Future<void> _navigateToSignUp(PatrolTester $) async {
final signUpButton = $(#toggleSignUpPage).waitUntilVisible(); final signUpButton = $(#toggleSignUpPage).waitUntilVisible();
await signUpButton.tap(); await signUpButton.tap();
} }

View File

@ -2,14 +2,14 @@ part of 'app_test.dart';
class VehicleTest { class VehicleTest {
static Future<void> vehiclePage() async { static Future<void> vehiclePage() async {
patrol( patrolWidgetTest(
'Vehicle Page', 'Vehicle Page',
(PatrolIntegrationTester tester) async { (PatrolTester tester) async {
$ = tester; $ = tester;
$.tester.printToConsole('Vehicle Page'); $.tester.printToConsole('Vehicle Page');
final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget); final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget);
await _loggedWithMultiLocalsAccount($); await _loggedWithMultiLocalsAccount();
await $.pumpWidgetAndSettle(const App()); await $.pumpWidgetAndSettle(const App());
ff.navigatorKey.currentContext!.go('/vehiclesOnThePropertyPage'); ff.navigatorKey.currentContext!.go('/vehiclesOnThePropertyPage');
@ -64,17 +64,19 @@ class VehicleTest {
await $(DetailsComponentWidget).waitUntilVisible(); await $(DetailsComponentWidget).waitUntilVisible();
expect(detailsFinder, findsOneWidget); expect(detailsFinder, findsOneWidget);
await $.native.pressBack().then((_) => $.pumpAndSettle()); await _navigateBackUsingSystemGesture();
// await $.native.pressBack().then((_) => $.pumpAndSettle());
} }
}, },
); );
patrol( patrolWidgetTest(
'License', 'License',
(PatrolIntegrationTester tester) async { (PatrolTester tester) async {
$ = tester; $ = tester;
$.tester.printToConsole('Vehicle Page'); $.tester.printToConsole('Vehicle Page');
await _loggedWithMultiLocalsAccount($); await _loggedWithMultiLocalsAccount();
// await StorageHelper().set( // await StorageHelper().set(
// LicenseKeys.vehiclesManager.value, // LicenseKeys.vehiclesManager.value,
@ -140,14 +142,14 @@ class VehicleTest {
} }
static Future<void> historyScreen() async { static Future<void> historyScreen() async {
patrol( patrolWidgetTest(
'historyScreen', 'historyScreen',
(PatrolIntegrationTester tester) async { (PatrolTester tester) async {
$ = tester; $ = tester;
$.tester.printToConsole('Vehicle Page'); $.tester.printToConsole('Vehicle Page');
final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget); final PatrolFinder throwsException = $(Dialog).$(ThrowExceptionWidget);
await _loggedWithMultiLocalsAccount($); await _loggedWithMultiLocalsAccount();
await $.pumpWidgetAndSettle(const App()); await $.pumpWidgetAndSettle(const App());
ff.navigatorKey.currentContext!.go('/vehiclesOnThePropertyPage'); ff.navigatorKey.currentContext!.go('/vehiclesOnThePropertyPage');
@ -198,7 +200,9 @@ class VehicleTest {
await $(DetailsComponentWidget).waitUntilVisible(); await $(DetailsComponentWidget).waitUntilVisible();
expect(detailsFinder, findsOneWidget); expect(detailsFinder, findsOneWidget);
await $.native.pressBack().then((_) => $.pumpAndSettle()); await _navigateBackUsingSystemGesture();
// await $.native.pressBack().then((_) => $.pumpAndSettle());
} }
}, },
); );

View File

@ -2,12 +2,12 @@ part of 'app_test.dart';
class WelcomeTest { class WelcomeTest {
static Future signInToSignUp() async { static Future signInToSignUp() async {
patrol( patrolWidgetTest(
'Sign-In to Sign-Up', 'Sign-In to Sign-Up',
(PatrolIntegrationTester tester) async { (PatrolTester tester) async {
$ = tester; $ = tester;
$.tester.printToConsole('Welcome Test - Sign-In to Sign-Up'); $.tester.printToConsole('Welcome Test - Sign-In to Sign-Up');
await _unlogged($); await _unlogged();
await $.pumpWidgetAndSettle(const App()); await $.pumpWidgetAndSettle(const App());
await _navigateToSignIn($); await _navigateToSignIn($);
@ -17,12 +17,12 @@ class WelcomeTest {
} }
static Future signUpToSignIn() async { static Future signUpToSignIn() async {
patrol( patrolWidgetTest(
'Sign-Up to Sign-In', 'Sign-Up to Sign-In',
(PatrolIntegrationTester tester) async { (PatrolTester tester) async {
$ = tester; $ = tester;
$.tester.printToConsole('Welcome Test - Sign-Up to Sign-In'); $.tester.printToConsole('Welcome Test - Sign-Up to Sign-In');
await _unlogged($); await _unlogged();
await $.pumpWidgetAndSettle(const App()); await $.pumpWidgetAndSettle(const App());
await _navigateToSignUp($); await _navigateToSignUp($);
await _navigateToSignIn($); await _navigateToSignIn($);

View File

@ -396,19 +396,19 @@ EXTERNAL SOURCES:
:path: ".symlinks/plugins/webview_flutter_wkwebview/darwin" :path: ".symlinks/plugins/webview_flutter_wkwebview/darwin"
SPEC CHECKSUMS: SPEC CHECKSUMS:
app_links: e7a6750a915a9e161c58d91bc610e8cd1d4d0ad0 app_links: 3da4c36b46cac3bf24eb897f1a6ce80bda109874
app_tracking_transparency: e169b653478da7bb15a6c61209015378ca73e375 app_tracking_transparency: 3d84f147f67ca82d3c15355c36b1fa6b66ca7c92
awesome_notifications: dd5518ff1c80be03d4f1c40f04da9d9cc2a37af5 awesome_notifications: 0f432b28098d193920b11a44cfa9d2d9313a3888
CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99 CocoaAsyncSocket: 065fd1e645c7abab64f7a6a2007a48038fdc6a99
device_info_plus: 97af1d7e84681a90d0693e63169a5d50e0839a0d device_info_plus: 71ffc6ab7634ade6267c7a93088ed7e4f74e5896
DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c DKImagePickerController: 946cec48c7873164274ecc4624d19e3da4c1ef3c
DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60 DKPhotoGallery: b3834fecb755ee09a593d7c9e389d8b5d6deed60
file_picker: 09aa5ec1ab24135ccd7a1621c46c84134bfd6655 file_picker: 9b3292d7c8bc68c8a7bf8eb78f730e49c8efc517
Firebase: 9f574c08c2396885b5e7e100ed4293d956218af9 Firebase: 9f574c08c2396885b5e7e100ed4293d956218af9
firebase_analytics: 1a66fe8d4375eccff44671ea37897683a78b2675 firebase_analytics: 2090f32a7f5364b03cdf11aa7e904f4610309563
firebase_core: ceec591a66629daaee82d3321551692c4a871493 firebase_core: 53cecb83c72fea329b267bb0accb06a33e9f036a
firebase_crashlytics: e4f04180f443d5a8b56fbc0685bdbd7d90dd26f0 firebase_crashlytics: 4a35a15cbb0d9ba176f9bb2dfd3aa44c762c434f
firebase_messaging: 15d8b557010f3bb7b98d0302e1c7c8fbcd244425 firebase_messaging: 62c8a01f1ee118754d01dd4fd83ba670980326a3
FirebaseAnalytics: 27eb78b97880ea4a004839b9bac0b58880f5a92a FirebaseAnalytics: 27eb78b97880ea4a004839b9bac0b58880f5a92a
FirebaseCore: 3cf438f431f18c12cdf2aaf64434648b63f7e383 FirebaseCore: 3cf438f431f18c12cdf2aaf64434648b63f7e383
FirebaseCoreExtension: 30bb063476ef66cd46925243d64ad8b2c8ac3264 FirebaseCoreExtension: 30bb063476ef66cd46925243d64ad8b2c8ac3264
@ -419,42 +419,42 @@ SPEC CHECKSUMS:
FirebaseRemoteConfigInterop: c3a5c31b3c22079f41ba1dc645df889d9ce38cb9 FirebaseRemoteConfigInterop: c3a5c31b3c22079f41ba1dc645df889d9ce38cb9
FirebaseSessions: 655ff17f3cc1a635cbdc2d69b953878001f9e25b FirebaseSessions: 655ff17f3cc1a635cbdc2d69b953878001f9e25b
Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7 Flutter: e0871f40cf51350855a761d2e70bf5af5b9b5de7
flutter_inappwebview_ios: 6f63631e2c62a7c350263b13fa5427aedefe81d4 flutter_inappwebview_ios: b89ba3482b96fb25e00c967aae065701b66e9b99
flutter_secure_storage_darwin: 12d2375c690785d97a4e586f15f11be5ae35d5b0 flutter_secure_storage_darwin: ce237a8775b39723566dc72571190a3769d70468
fluttertoast: e9a18c7be5413da53898f660530c56f35edfba9c fluttertoast: 76fea30fcf04176325f6864c87306927bd7d2038
google_mlkit_commons: 384e4e206e122b6dad430d3158205e0b2fac6789 google_mlkit_commons: 92c769cc2e0a2bfdeb3c38091a36e8a9cc8c63d4
google_mlkit_face_detection: ff627695d8eba051db7e0f13f7b20d802df1f84c google_mlkit_face_detection: 76f493a9ffcb1aeb0ad4abd13ea58403e092ab84
GoogleAppMeasurement: 6e49ffac7d3f2c3ded9cc663f912a13b67bbd0de GoogleAppMeasurement: 6e49ffac7d3f2c3ded9cc663f912a13b67bbd0de
GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7 GoogleDataTransport: aae35b7ea0c09004c3797d53c8c41f66f219d6a7
GoogleMLKit: eff9e23ec1d90ea4157a1ee2e32a4f610c5b3318 GoogleMLKit: eff9e23ec1d90ea4157a1ee2e32a4f610c5b3318
GoogleToolboxForMac: d1a2cbf009c453f4d6ded37c105e2f67a32206d8 GoogleToolboxForMac: d1a2cbf009c453f4d6ded37c105e2f67a32206d8
GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d GoogleUtilities: 26a3abef001b6533cf678d3eb38fd3f614b7872d
GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6 GTMSessionFetcher: 5aea5ba6bd522a239e236100971f10cb71b96ab6
image_picker_ios: c560581cceedb403a6ff17f2f816d7fea1421fc1 image_picker_ios: 7fe1ff8e34c1790d6fff70a32484959f563a928a
integration_test: 252f60fa39af5e17c3aa9899d35d908a0721b573 integration_test: 4a889634ef21a45d28d50d622cf412dc6d9f586e
IosAwnCore: 653786a911089012092ce831f2945cd339855a89 IosAwnCore: 653786a911089012092ce831f2945cd339855a89
local_auth_darwin: 66e40372f1c29f383a314c738c7446e2f7fdadc3 local_auth_darwin: 553ce4f9b16d3fdfeafce9cf042e7c9f77c1c391
MLImage: 0ad1c5f50edd027672d8b26b0fee78a8b4a0fc56 MLImage: 0ad1c5f50edd027672d8b26b0fee78a8b4a0fc56
MLKitCommon: 07c2c33ae5640e5380beaaa6e4b9c249a205542d MLKitCommon: 07c2c33ae5640e5380beaaa6e4b9c249a205542d
MLKitFaceDetection: 2a593db4837db503ad3426b565e7aab045cefea5 MLKitFaceDetection: 2a593db4837db503ad3426b565e7aab045cefea5
MLKitVision: 45e79d68845a2de77e2dd4d7f07947f0ed157b0e MLKitVision: 45e79d68845a2de77e2dd4d7f07947f0ed157b0e
nanopb: fad817b59e0457d11a5dfbde799381cd727c1275 nanopb: fad817b59e0457d11a5dfbde799381cd727c1275
OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94 OrderedSet: e539b66b644ff081c73a262d24ad552a69be3a94
package_info_plus: c0502532a26c7662a62a356cebe2692ec5fe4ec4 package_info_plus: af8e2ca6888548050f16fa2f1938db7b5a5df499
path_provider_foundation: 2b6b4c569c0fb62ec74538f866245ac84301af46 path_provider_foundation: 080d55be775b7414fd5a5ef3ac137b97b097e564
patrol: 0564cee315ff6c86fb802b3647db05cc2d3d0624 patrol: dd82ffedfee3aba87c1d0ed2daad0b77bfb8ee1f
permission_handler_apple: 9878588469a2b0d0fc1e048d9f43605f92e6cec2 permission_handler_apple: 4ed2196e43d0651e8ff7ca3483a069d469701f2d
PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47 PromisesObjC: f5707f49cb48b9636751c5b2e7d227e43fba9f47
PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851 PromisesSwift: 9d77319bbe72ebf6d872900551f7eeba9bce2851
SDWebImage: 8a6b7b160b4d710e2a22b6900e25301075c34cb3 SDWebImage: 8a6b7b160b4d710e2a22b6900e25301075c34cb3
share_plus: 8875f4f2500512ea181eef553c3e27dba5135aad share_plus: 011d6fb4f9d2576b83179a3a5c5e323202cdabcf
shared_preferences_foundation: fcdcbc04712aee1108ac7fda236f363274528f78 shared_preferences_foundation: 9e1978ff2562383bd5676f64ec4e9aa8fa06a6f7
sqflite_darwin: 5a7236e3b501866c1c9befc6771dfd73ffb8702d sqflite_darwin: 20b2a3a3b70e43edae938624ce550a3cbf66a3d0
SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4 SwiftyGif: 706c60cf65fa2bc5ee0313beece843c8eb8194d4
Toast: 1f5ea13423a1e6674c4abdac5be53587ae481c4e Toast: 1f5ea13423a1e6674c4abdac5be53587ae481c4e
url_launcher_ios: 5334b05cef931de560670eeae103fd3e431ac3fe url_launcher_ios: 694010445543906933d732453a59da0a173ae33d
webview_flutter_wkwebview: 0982481e3d9c78fd5c6f62a002fcd24fc791f1e4 webview_flutter_wkwebview: 1821ceac936eba6f7984d89a9f3bcb4dea99ebb2
PODFILE CHECKSUM: 1214504d483029dbea12c83e130a53cc7299687f PODFILE CHECKSUM: 1214504d483029dbea12c83e130a53cc7299687f
COCOAPODS: 1.15.2 COCOAPODS: 1.16.2

View File

@ -216,6 +216,7 @@
9705A1C41CF9048500538489 /* Embed Frameworks */, 9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */, 3B06AD1E1E4923F5004D2608 /* Thin Binary */,
DB4ADAD93A6C1B6E82A2FDA3 /* [CP] Copy Pods Resources */, DB4ADAD93A6C1B6E82A2FDA3 /* [CP] Copy Pods Resources */,
106EFC912B39433BCC0D0CA9 /* FlutterFire: "flutterfire upload-crashlytics-symbols" */,
); );
buildRules = ( buildRules = (
); );
@ -290,6 +291,24 @@
/* End PBXResourcesBuildPhase section */ /* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */ /* Begin PBXShellScriptBuildPhase section */
106EFC912B39433BCC0D0CA9 /* FlutterFire: "flutterfire upload-crashlytics-symbols" */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputFileListPaths = (
);
inputPaths = (
);
name = "FlutterFire: \"flutterfire upload-crashlytics-symbols\"";
outputFileListPaths = (
);
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "\n#!/bin/bash\nPATH=\"${PATH}:$FLUTTER_ROOT/bin:$HOME/.pub-cache/bin\"\nflutterfire upload-crashlytics-symbols --upload-symbols-script-path=\"$PODS_ROOT/FirebaseCrashlytics/upload-symbols\" --platform=ios --apple-project-path=\"${SRCROOT}\" --env-platform-name=\"${PLATFORM_NAME}\" --env-configuration=\"${CONFIGURATION}\" --env-project-dir=\"${PROJECT_DIR}\" --env-built-products-dir=\"${BUILT_PRODUCTS_DIR}\" --env-dwarf-dsym-folder-path=\"${DWARF_DSYM_FOLDER_PATH}\" --env-dwarf-dsym-file-name=\"${DWARF_DSYM_FILE_NAME}\" --env-infoplist-path=\"${INFOPLIST_PATH}\" --default-config=default\n";
};
35A087622D3ED1C700BEE419 /* xcode_backend build */ = { 35A087622D3ED1C700BEE419 /* xcode_backend build */ = {
isa = PBXShellScriptBuildPhase; isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;

View File

@ -19,7 +19,7 @@
<key>PROJECT_ID</key> <key>PROJECT_ID</key>
<string>accessmoblie-da839</string> <string>accessmoblie-da839</string>
<key>STORAGE_BUCKET</key> <key>STORAGE_BUCKET</key>
<string>accessmoblie-da839.appspot.com</string> <string>accessmoblie-da839.firebasestorage.app</string>
<key>IS_ADS_ENABLED</key> <key>IS_ADS_ENABLED</key>
<false></false> <false></false>
<key>IS_ANALYTICS_ENABLED</key> <key>IS_ANALYTICS_ENABLED</key>

View File

@ -235,6 +235,7 @@ class UpdateVehicle {
'licensePlate': licensePlate, 'licensePlate': licensePlate,
'color': color, 'color': color,
'model': model, 'model': model,
'vehicleId': vehicleId
}, },
bodyType: BodyType.X_WWW_FORM_URL_ENCODED, bodyType: BodyType.X_WWW_FORM_URL_ENCODED,
returnBody: true, returnBody: true,

View File

@ -1,4 +1,5 @@
import 'dart:async'; import 'dart:async';
import 'dart:developer';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_spinkit/flutter_spinkit.dart'; import 'package:flutter_spinkit/flutter_spinkit.dart';
@ -364,8 +365,8 @@ class ProvisionalHistoryState extends State<ProvisionalHistoryPage> {
enText: 'Name:', enText: 'Name:',
): historyItem['AGP_NOME'] ?? '', ): historyItem['AGP_NOME'] ?? '',
FFLocalizations.of(context).getVariableText( FFLocalizations.of(context).getVariableText(
ptText: 'Data:', ptText: 'Vencimento',
enText: 'Data:', enText: 'Expiration',
): formatDate(historyItem['AGP_DT_VISITA']), ): formatDate(historyItem['AGP_DT_VISITA']),
FFLocalizations.of(context).getVariableText( FFLocalizations.of(context).getVariableText(
ptText: 'Observação:', ptText: 'Observação:',
@ -398,19 +399,34 @@ class ProvisionalHistoryState extends State<ProvisionalHistoryPage> {
enText: 'Visitor', enText: 'Visitor',
): FlutterFlowTheme.of(context).alternate2, ): FlutterFlowTheme.of(context).alternate2,
}, },
_getStatusMap(context, historyItem['AGP_STATUS']) _getStatusMap(context, historyItem)
]; ];
} }
Map<String, Color> _getStatusMap(BuildContext context, String status) { Map<String, Color> _getStatusMap(BuildContext context, dynamic json) {
switch (status) { late Map<String, Color> statusColorMap;
log(DateTime.parse(json['AGP_DT_VISITA']).toString());
log(DateTime.now().toString());
final DateTime now = DateTime.now();
final DateTime date = DateTime.parse(json['AGP_DT_VISITA']);
final bool isExpired = now.isAfter(date);
final String statusMap = json['AGP_STATUS'];
switch (statusMap) {
case 'AT': case 'AT':
return { return isExpired
FFLocalizations.of(context).getVariableText( ? {
ptText: 'Ativo', FFLocalizations.of(context).getVariableText(
enText: 'Active', ptText: 'Vencido',
): FlutterFlowTheme.of(context).success, enText: 'Expired',
}; ): FlutterFlowTheme.of(context).error,
}
: {
FFLocalizations.of(context).getVariableText(
ptText: 'Ativo',
enText: 'Active',
): FlutterFlowTheme.of(context).success,
};
case 'CO': case 'CO':
return { return {
FFLocalizations.of(context).getVariableText( FFLocalizations.of(context).getVariableText(

View File

@ -1,5 +1,6 @@
import 'dart:developer'; import 'dart:developer';
import 'package:firebase_crashlytics/firebase_crashlytics.dart';
import 'package:flutter/gestures.dart'; import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
@ -7,6 +8,8 @@ import 'package:hub/flutter_flow/flutter_flow_icon_button.dart';
import 'package:hub/flutter_flow/flutter_flow_theme.dart'; import 'package:hub/flutter_flow/flutter_flow_theme.dart';
import 'package:hub/flutter_flow/flutter_flow_util.dart'; import 'package:hub/flutter_flow/flutter_flow_util.dart';
import 'package:hub/flutter_flow/internationalization.dart'; import 'package:hub/flutter_flow/internationalization.dart';
import 'package:hub/shared/utils/log_util.dart';
import 'package:stack_trace/stack_trace.dart';
import 'package:package_info_plus/package_info_plus.dart'; import 'package:package_info_plus/package_info_plus.dart';
import 'package:url_launcher/url_launcher.dart'; import 'package:url_launcher/url_launcher.dart';
@ -132,6 +135,20 @@ class _AboutSystemPageState extends State<AboutSystemPage> {
width: 100, width: 100,
child: Image.asset('assets/images/fre.png'), child: Image.asset('assets/images/fre.png'),
); );
// return GestureDetector(
// onTap: () {
// final exception = Exception('Crashando');
// final stackTrace = Trace.current();
// LogUtil.requestAPIFailed("proccessRequest.php", "", "Consulta de Pets",
// exception, stackTrace);
// FirebaseCrashlytics.instance.crash();
// },
// child: SizedBox(
// height: 100,
// width: 100,
// child: Image.asset('assets/images/fre.png'),
// ),
// );
} }
Widget _buildLaunch() { Widget _buildLaunch() {

View File

@ -53,7 +53,7 @@ class DefaultFirebaseOptions {
projectId: 'accessmoblie-da839', projectId: 'accessmoblie-da839',
authDomain: 'accessmoblie-da839.firebaseapp.com', authDomain: 'accessmoblie-da839.firebaseapp.com',
databaseURL: 'https://accessmoblie-da839.firebaseio.com', databaseURL: 'https://accessmoblie-da839.firebaseio.com',
storageBucket: 'accessmoblie-da839.appspot.com', storageBucket: 'accessmoblie-da839.firebasestorage.app',
measurementId: 'G-L4BQGX2WLZ', measurementId: 'G-L4BQGX2WLZ',
); );
@ -63,7 +63,7 @@ class DefaultFirebaseOptions {
messagingSenderId: '187064172787', messagingSenderId: '187064172787',
projectId: 'accessmoblie-da839', projectId: 'accessmoblie-da839',
databaseURL: 'https://accessmoblie-da839.firebaseio.com', databaseURL: 'https://accessmoblie-da839.firebaseio.com',
storageBucket: 'accessmoblie-da839.appspot.com', storageBucket: 'accessmoblie-da839.firebasestorage.app',
); );
static const FirebaseOptions ios = FirebaseOptions( static const FirebaseOptions ios = FirebaseOptions(
@ -72,7 +72,7 @@ class DefaultFirebaseOptions {
messagingSenderId: '187064172787', messagingSenderId: '187064172787',
projectId: 'accessmoblie-da839', projectId: 'accessmoblie-da839',
databaseURL: 'https://accessmoblie-da839.firebaseio.com', databaseURL: 'https://accessmoblie-da839.firebaseio.com',
storageBucket: 'accessmoblie-da839.appspot.com', storageBucket: 'accessmoblie-da839.firebasestorage.app',
androidClientId: androidClientId:
'187064172787-7et0qu5p2qtmisvqgndn3kfi1b7u9ifl.apps.googleusercontent.com', '187064172787-7et0qu5p2qtmisvqgndn3kfi1b7u9ifl.apps.googleusercontent.com',
iosClientId: iosClientId:

View File

@ -48,18 +48,32 @@ void _initializeUrlStrategy() {
print('URL Strategy initialized'); print('URL Strategy initialized');
} }
void _initializeSystemSettings() { Future<void> _initializeSystemSettings() async {
print('Initializing System Settings...'); print('Initializing System Settings...');
SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]); final crashlyticsInstance = FirebaseCrashlytics.instance;
await SystemChrome.setPreferredOrientations([DeviceOrientation.portraitUp]);
if (kDebugMode) { if (kDebugMode) {
//kDebugMode
print('Debug mode'); print('Debug mode');
} else { bool unsentReports =
final crashlyticsInstance = FirebaseCrashlytics.instance; await FirebaseCrashlytics.instance.checkForUnsentReports();
print('Release mode'); if (unsentReports) {
if (crashlyticsInstance.isCrashlyticsCollectionEnabled) { // Existem relatórios não enviados
FlutterError.onError = crashlyticsInstance.recordFlutterError; await crashlyticsInstance.sendUnsentReports();
print('Crashlytics enabled'); print('Existem relatórios de falhas não enviados.');
} else {
// Não existem relatórios não enviados
print('Todos os relatórios de falhas foram enviados.');
} }
} else {
print('Release mode');
await crashlyticsInstance.setCrashlyticsCollectionEnabled(true);
// if (crashlyticsInstance.isCrashlyticsCollectionEnabled) {
FlutterError.onError = await crashlyticsInstance.recordFlutterError;
print('Crashlytics enabled');
// }
} }
} }

View File

@ -180,7 +180,7 @@ class _AppState extends State<App> {
); );
_setupFirebaseMessaging(); _setupFirebaseMessaging();
// if (TestUtil.isInTest) // // if (TestUtil.isInTest) //
DeepLinkService().ensureInitialization(); DeepLinkService().ensureInitialization();
} }

View File

@ -1,3 +1,5 @@
import 'dart:developer';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart'; import 'package:hub/components/templates_components/card_item_template_component/card_item_template_component_widget.dart';
import 'package:hub/features/backend/index.dart'; import 'package:hub/features/backend/index.dart';
@ -196,6 +198,8 @@ class _VisitHistoryWidgetState extends State<VisitHistoryWidget>
} }
Widget _item(BuildContext context, dynamic visitaWrapItem) { Widget _item(BuildContext context, dynamic visitaWrapItem) {
log(DateTime.now().toString());
log(visitaWrapItem['VAW_DTFIM'].toString());
return CardItemTemplateComponentWidget( return CardItemTemplateComponentWidget(
imagePath: imagePath:
'https://freaccess.com.br/freaccess/getImage.php?devUUID=$devUUID&userUUID=$userUUID&cliID=$cliUUID&atividade=getFoto&Documento=${visitaWrapItem['VTE_DOCUMENTO'] ?? ''}&tipo=E', 'https://freaccess.com.br/freaccess/getImage.php?devUUID=$devUUID&userUUID=$userUUID&cliID=$cliUUID&atividade=getFoto&Documento=${visitaWrapItem['VTE_DOCUMENTO'] ?? ''}&tipo=E',
@ -218,10 +222,19 @@ class _VisitHistoryWidgetState extends State<VisitHistoryWidget>
statusHashMap: [ statusHashMap: [
if (Status.getStatus(visitaWrapItem['VAW_STATUS']) == StatusEnum.active) if (Status.getStatus(visitaWrapItem['VAW_STATUS']) == StatusEnum.active)
{ {
FFLocalizations.of(context).getVariableText( if (visitaWrapItem['VAW_DTFIM'] != '' &&
ptText: 'Ativo', visitaWrapItem['VAW_DTFIM'] != null)
enText: 'Active', if (DateTime.now().isAfter(
): FlutterFlowTheme.of(context).warning, DateTime.parse(visitaWrapItem['VAW_DTFIM'] as String)))
FFLocalizations.of(context).getVariableText(
ptText: 'Vencido',
enText: 'Expired',
): FlutterFlowTheme.of(context).error
else
FFLocalizations.of(context).getVariableText(
ptText: 'Ativo',
enText: 'Active',
): FlutterFlowTheme.of(context).warning,
}, },
if (Status.getStatus(visitaWrapItem['VAW_STATUS']) == if (Status.getStatus(visitaWrapItem['VAW_STATUS']) ==
StatusEnum.finished) StatusEnum.finished)

View File

@ -6,27 +6,142 @@ part of 'vehicles_on_the_property.dart';
class VehicleHistoryScreen extends StatefulWidget { class VehicleHistoryScreen extends StatefulWidget {
VehicleHistoryScreen(this.model, {super.key}); VehicleHistoryScreen(this.model, {super.key});
late VehicleModel model; late VehicleModel model;
late Future<void> _future;
List<dynamic> _wrap = [];
int _pageNumber = 1;
bool _hasData = false;
bool _loading = false;
int count = 0;
@override @override
State<VehicleHistoryScreen> createState() => _VehicleHistoryScreenState(); State<VehicleHistoryScreen> createState() => _VehicleHistoryScreenState();
} }
class _VehicleHistoryScreenState extends State<VehicleHistoryScreen> { class _VehicleHistoryScreenState extends State<VehicleHistoryScreen>
late Future<void> _future = _fetchVisits(); with _FetchingMixin, _ScrollControllerMixin, _CardItemMixin {
late ScrollController _scrollController;
List<dynamic> _wrap = [];
int _pageNumber = 1;
bool _hasData = false;
bool _loading = false;
int count = 0;
@override @override
void initState() { void initState() {
super.initState(); super.initState();
_initializeScrollController();
widget._future = _fetch();
}
// widget.model = createModel(context, () => VehicleModel()); @override
_future = _fetchVisits(); Widget build(BuildContext context) {
late final limitedHeaderTextSize =
LimitedFontSizeUtil.getHeaderFontSize(context);
late final double limitedBodyTextSize =
LimitedFontSizeUtil.getBodyFontSize(context);
return Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
if (widget._hasData == false &&
widget._pageNumber <= 1 &&
widget._loading == false)
_buildNoDataFound(context, limitedHeaderTextSize)
else if (widget._hasData == true || widget._pageNumber >= 1)
_buildVehicleList(context, limitedBodyTextSize),
if (widget._hasData == true && widget._loading == true)
_buildLoadingIndicator(context),
].addToStart(const SizedBox(height: 0)),
);
}
Widget _buildNoDataFound(BuildContext context, double limitedHeaderTextSize) {
return Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Center(
child: Text(
FFLocalizations.of(context).getVariableText(
ptText: "Nenhum veículo encontrado!",
enText: "No vehicle found",
),
style: TextStyle(
fontFamily: 'Nunito',
fontSize: limitedHeaderTextSize,
),
),
)
],
),
);
}
Widget _buildVehicleList(BuildContext context, double limitedBodyTextSize) {
return Expanded(
child: FutureBuilder<void>(
future: widget._future,
builder: (context, snapshot) {
return ListView.builder(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
controller: _scrollController,
itemCount: widget._wrap.length + 1,
itemBuilder: (context, index) {
if (index == 0) {
return _buildHeader(context, limitedBodyTextSize);
} else {
Map<String, dynamic> item = widget._wrap[index - 1];
return FutureBuilder<Widget>(
future: _item(context, item),
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
return snapshot.data ?? Container();
} else {
return Center(child: CircularProgressIndicator());
}
},
);
}
},
);
},
),
);
}
Widget _buildHeader(BuildContext context, double limitedBodyTextSize) {
log('amountRegister: ${widget.model.amountRegister}');
return Padding(
padding: const EdgeInsets.only(right: 30, top: 10),
child: Text(
(widget.model.amountRegister == '0' ||
widget.model.amountRegister == null)
? ''
: "${FFLocalizations.of(context).getVariableText(ptText: "Quantidade de Veículos: ", enText: "Amount of Vehicles: ")}${widget.model.amountRegister}/${widget.count}",
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: 'Nunito',
fontSize: limitedBodyTextSize,
),
),
);
}
Widget _buildLoadingIndicator(BuildContext context) {
return Container(
padding: const EdgeInsets.only(top: 15, bottom: 15),
child: Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(
FlutterFlowTheme.of(context).primary,
),
),
),
);
}
}
// Mixin for Scroll Controller
mixin _ScrollControllerMixin on _FetchingMixin {
late ScrollController _scrollController;
void _initializeScrollController() {
_scrollController = ScrollController() _scrollController = ScrollController()
..addListener(() { ..addListener(() {
if (_scrollController.position.atEdge && if (_scrollController.position.atEdge &&
@ -36,6 +151,56 @@ class _VehicleHistoryScreenState extends State<VehicleHistoryScreen> {
}); });
} }
void _loadMore() {
if (widget._hasData == true) {
widget._pageNumber++;
widget._future = _fetch();
}
}
}
// Mixin for Fetch Visits
mixin _FetchingMixin on State<VehicleHistoryScreen> {
Future<ApiCallResponse?> _fetch() async {
try {
setState(() => widget._loading = true);
var response = await PhpGroup.getVehiclesByProperty
.call(widget._pageNumber.toString());
final List<dynamic> vehicles = response.jsonBody['vehicles'] ?? [];
safeSetState(() => widget.count = response.jsonBody['total_rows'] ?? 0);
if (vehicles.isNotEmpty) {
setState(() {
widget._wrap.addAll(vehicles);
widget._hasData = true;
widget._loading = false;
});
return response;
}
_showNoMoreDataSnackBar(context);
setState(() {
widget._hasData = false;
widget._loading = false;
});
return null;
} catch (e, s) {
DialogUtil.errorDefault(context);
LogUtil.requestAPIFailed(
"proccessRequest.php", "", "Consulta de Veículo", e, s);
setState(() {
widget._hasData = false;
widget._loading = false;
});
}
return null;
}
void _showNoMoreDataSnackBar(BuildContext context) { void _showNoMoreDataSnackBar(BuildContext context) {
ScaffoldMessenger.of(context).showSnackBar( ScaffoldMessenger.of(context).showSnackBar(
SnackBar( SnackBar(
@ -54,36 +219,49 @@ class _VehicleHistoryScreenState extends State<VehicleHistoryScreen> {
), ),
); );
} }
}
String mockRandomMapStatusColor() { // Mixin for Card Item
var statuses = [ mixin _CardItemMixin on _FetchingMixin {
'ATI',
'INA',
'APR_CREATE',
'APR_DELETE',
'APR_UPDATE',
'AGU_CHANGE'
];
statuses.shuffle();
return statuses.first;
}
Future<Widget> _item(BuildContext context, Map<String, dynamic> uItem) async { Future<Widget> _item(BuildContext context, Map<String, dynamic> uItem) async {
// uItem['status'] = mockRandomMapStatusColor();
final bool? isOwner = uItem['isOwnerVehicle']; final bool? isOwner = uItem['isOwnerVehicle'];
late final IconData? iconData; final IconData iconData =
late final FreCardIcon? cardIcon; isOwner == true ? Symbols.no_crash : Symbols.directions_car;
final FreCardIcon? cardIcon = isOwner != null
? FreCardIcon(
height: 50,
width: 100,
icon: Icon(iconData, size: 80, opticalSize: 10))
: null;
if (isOwner is bool) {
iconData = isOwner ? Symbols.no_crash : Symbols.directions_car;
cardIcon = FreCardIcon(
height: 50,
width: 100,
icon: Icon(iconData, size: 80, opticalSize: 10));
}
final String? tag = uItem['tag']; final String? tag = uItem['tag'];
final bool containTag = tag.isNotNullAndEmpty; final bool containTag = tag.isNotNullAndEmpty;
final Map<String, String> labelsHashMap = { final Map<String, String> labelsHashMap =
_generateLabelsHashMap(context, uItem, tag, containTag);
final statusHashMapList = await _generateStatusHashMapList(uItem);
Future<void> onTapCardItemAction() async {
await _handleCardItemTap(context, cardIcon, uItem);
}
final statusLinkedHashMap = statusHashMapList
.map((map) => LinkedHashMap<String, Color>.from(map))
.toList();
final length = statusLinkedHashMap.expand((e) => [e.length]);
return CardItemTemplateComponentWidget(
icon: cardIcon,
labelsHashMap: labelsHashMap,
statusHashMap: statusHashMapList,
onTapCardItemAction: onTapCardItemAction,
itemWidthFactor: length == 1 ? 0.25 : 0.50,
);
}
Map<String, String> _generateLabelsHashMap(BuildContext context,
Map<String, dynamic> uItem, String? tag, bool containTag) {
return {
'${FFLocalizations.of(context).getVariableText(ptText: "Placa", enText: "License Plate")}:': '${FFLocalizations.of(context).getVariableText(ptText: "Placa", enText: "License Plate")}:':
uItem['licensePlate'] ?? '', uItem['licensePlate'] ?? '',
'${FFLocalizations.of(context).getVariableText(ptText: "Modelo", enText: "Model")}:': '${FFLocalizations.of(context).getVariableText(ptText: "Modelo", enText: "Model")}:':
@ -92,208 +270,47 @@ class _VehicleHistoryScreenState extends State<VehicleHistoryScreen> {
uItem['personName'] ?? '', uItem['personName'] ?? '',
if (containTag) if (containTag)
'${FFLocalizations.of(context).getVariableText(ptText: "Tag", enText: "Tag")}:': '${FFLocalizations.of(context).getVariableText(ptText: "Tag", enText: "Tag")}:':
uItem['tag'] ?? '', tag ?? '',
}; };
final Map<String, Color>? statusHashMap = }
await widget.model.generateStatusColorMap(uItem, 2);
final List<Map<String, Color>?> statusHashMapList = [ Future<List<Map<String, Color>>> _generateStatusHashMapList(
await widget.model.generateStatusColorMap(uItem, 2) Map<String, dynamic> uItem) async {
]; final statusHashMap =
Future<void> onTapCardItemAction() async { await widget.model.generateStatusColorMap(uItem, false);
final widgetFuture = widget.model.buildVehicleDetails( return statusHashMap != null ? [statusHashMap] : [];
icon: isOwner is bool ? cardIcon : null, }
Future<void> _handleCardItemTap(BuildContext context, FreCardIcon? cardIcon,
Map<String, dynamic> uItem) async {
try {
final dialogContent = await widget.model.buildVehicleDetails(
icon: cardIcon,
item: uItem, item: uItem,
context: context, context: context,
model: widget.model, model: widget.model,
); );
final dialogContent = await widgetFuture;
await showDialog( await showDialog(
useSafeArea: true, useSafeArea: true,
context: context, context: context,
builder: (context) { builder: (context) =>
return Dialog( Dialog(alignment: Alignment.center, child: dialogContent),
alignment: Alignment.center,
child: dialogContent,
);
},
).whenComplete(() { ).whenComplete(() {
safeSetState(() { safeSetState(() {
_pageNumber = 1; widget._pageNumber = 1;
_wrap = []; widget._wrap = [];
_future = _fetchVisits(); widget._future = _fetch();
});
}).catchError((e, s) {
DialogUtil.errorDefault(context);
LogUtil.requestAPIFailed(
"proccessRequest.php", "", "Consulta de Veículos", e, s);
safeSetState(() {
_hasData = false;
_loading = false;
}); });
}); });
}
final statusLinkedHashMap = statusHashMapList
.map((map) => LinkedHashMap<String, Color>.from(map ?? {}))
.toList();
final length = statusLinkedHashMap.expand((e) => [e.length]);
print('CardItemTemplateComponentWidget: ${length}');
return CardItemTemplateComponentWidget(
icon: cardIcon,
labelsHashMap: labelsHashMap,
statusHashMap: statusHashMapList,
onTapCardItemAction: onTapCardItemAction,
itemWidthFactor: length == 1 ? 0.25 : 0.50,
);
// double itemWidthFactor = statusHashMap.length == 1 ? 0.5 : 0.5;
// double itemWidthFactor;
// if (statusCount >= 3 && statusCount % 3 != 0) {
// itemWidthFactor = (index % 3 == 2) ? 0.5 : 0.25;
// } else if (statusCount == 3) {
// itemWidthFactor = (index == 2) ? 0.52 : 0.25;
// } else {
// itemWidthFactor = statusCount == 1 ? 0.5 : 0.25;
// }
}
Future<ApiCallResponse?> _fetchVisits() async {
try {
setState(() => _loading = true);
var response =
await PhpGroup.getVehiclesByProperty.call(_pageNumber.toString());
final List<dynamic> vehicles = response.jsonBody['vehicles'] ?? [];
safeSetState(() => count = response.jsonBody['total_rows'] ?? 0);
if (vehicles.isNotEmpty) {
setState(() {
_wrap.addAll(vehicles);
_hasData = true;
_loading = false;
});
return response;
}
_showNoMoreDataSnackBar(context);
setState(() {
_hasData = false;
_loading = false;
});
return null;
} catch (e, s) { } catch (e, s) {
DialogUtil.errorDefault(context); DialogUtil.errorDefault(context);
LogUtil.requestAPIFailed( LogUtil.requestAPIFailed(
"proccessRequest.php", "", "Consulta de Veículo", e, s); "proccessRequest.php", "", "Consulta de Veículos", e, s);
setState(() { safeSetState(() {
_hasData = false; widget._hasData = false;
_loading = false; widget._loading = false;
}); });
} }
return null;
}
void _loadMore() {
if (_hasData == true) {
_pageNumber++;
_future = _fetchVisits();
}
}
@override
Widget build(BuildContext context) {
late final limitedHeaderTextSize =
LimitedFontSizeUtil.getHeaderFontSize(context);
late final double limitedBodyTextSize =
LimitedFontSizeUtil.getBodyFontSize(context);
return Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.start,
children: [
if (_hasData == false && _pageNumber <= 1 && _loading == false)
Expanded(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
mainAxisSize: MainAxisSize.max,
children: [
Center(
child: Text(
FFLocalizations.of(context).getVariableText(
ptText: "Nenhum veículo encontrado!",
enText: "No vehicle found",
),
style: TextStyle(
fontFamily: 'Nunito',
fontSize: limitedHeaderTextSize,
),
),
)
],
),
)
else if (_hasData == true || _pageNumber >= 1)
Expanded(
child: FutureBuilder<void>(
future: _future,
builder: (context, snapshot) {
return ListView.builder(
shrinkWrap: true,
physics: const BouncingScrollPhysics(),
controller: _scrollController,
itemCount: _wrap.length + 1,
itemBuilder: (context, index) {
if (index == 0) {
// Add your item here
return Padding(
padding: const EdgeInsets.only(right: 30, top: 10),
child: Text(
(widget.model.amountRegister == '0' ||
widget.model.amountRegister == null)
? ''
: "${FFLocalizations.of(context).getVariableText(ptText: "Quantidade de Pets: ", enText: "Amount of Vehicles: ")}${widget.model.amountRegister}/$count",
textAlign: TextAlign.right,
style: TextStyle(
fontFamily: 'Nunito',
fontSize: limitedBodyTextSize,
),
),
);
} else {
Map<String, dynamic> item = _wrap[index - 1];
return FutureBuilder<Widget>(
future: _item(context, item),
builder: (context, snapshot) {
if (snapshot.connectionState ==
ConnectionState.done) {
return snapshot.data ?? Container();
} else {
return Center(child: CircularProgressIndicator());
}
},
);
}
});
},
)),
if (_hasData == true && _loading == true)
Container(
padding: const EdgeInsets.only(top: 15, bottom: 15),
child: Center(
child: CircularProgressIndicator(
valueColor: AlwaysStoppedAnimation<Color>(
FlutterFlowTheme.of(context).primary,
),
),
),
)
].addToStart(const SizedBox(height: 0)),
);
} }
} }

View File

@ -25,8 +25,16 @@ class VehicleModel extends FlutterFlowModel<VehiclePage>
@override @override
void initState(BuildContext context) { void initState(BuildContext context) {
log('VehicleModel -> initState');
resetInstance(); resetInstance();
initAsync(); initAsync();
initializeControllers(context);
WidgetsBinding.instance.addPostFrameCallback((_) async {
amountRegister = '0';
});
}
void initializeControllers(BuildContext context) {
tabBarController = TabController( tabBarController = TabController(
vsync: Navigator.of(context), vsync: Navigator.of(context),
length: 2, length: 2,
@ -40,14 +48,14 @@ class VehicleModel extends FlutterFlowModel<VehiclePage>
textFieldFocusModel = FocusNode(); textFieldFocusModel = FocusNode();
textFieldControllerModel = TextEditingController(); textFieldControllerModel = TextEditingController();
WidgetsBinding.instance.addPostFrameCallback((_) async {
amountRegister = '0';
});
} }
@override @override
void dispose() { void dispose() {
disposeControllers();
}
void disposeControllers() {
tabBarController.dispose(); tabBarController.dispose();
textFieldFocusLicensePlate!.dispose(); textFieldFocusLicensePlate!.dispose();
textFieldControllerLicensePlate!.dispose(); textFieldControllerLicensePlate!.dispose();
@ -65,9 +73,9 @@ class VehicleModel extends FlutterFlowModel<VehiclePage>
await StorageHelper().get(LocalsStorageKey.vehicleAmountRegister.key); await StorageHelper().get(LocalsStorageKey.vehicleAmountRegister.key);
} }
bool isFormValid(BuildContext context) { bool isFormValid(BuildContext context, GlobalKey<FormState> formKey) {
if (registerFormKey.currentState == null) return false; if (formKey.currentState == null) return false;
return registerFormKey.currentState!.validate(); return formKey.currentState!.validate();
} }
} }
@ -77,9 +85,9 @@ mixin class _BaseVehiclePage {
late final VehicleModel model; late final VehicleModel model;
late final TabController tabBarController; late final TabController tabBarController;
// dynamic item; // dynamic item;
String? vehicleId;
BuildContext context = navigatorKey.currentContext!; BuildContext context = navigatorKey.currentContext!;
bool isEditing = false; bool isEditing = false;
String? vehicleId;
ApiCallResponse? vehicleResponse; ApiCallResponse? vehicleResponse;
String? amountRegister = '0'; String? amountRegister = '0';
@ -91,19 +99,14 @@ mixin class _BaseVehiclePage {
TextEditingController? textFieldControllerLicensePlate; TextEditingController? textFieldControllerLicensePlate;
String? textControllerLicensePlateValidator( String? textControllerLicensePlateValidator(
BuildContext context, String? value) { BuildContext context, String? value) {
if (value == null || value.isEmpty) { final validationMessage = validateField(
return FFLocalizations.of(context).getVariableText( context, value, 'Placa é obrigatória', 'License Plate is required');
ptText: 'Placa é obrigatória', if (validationMessage != null) return validationMessage;
enText: 'License Plate is required',
);
}
// (ABC-1234)
final brazilianPlateRegex = RegExp(r'^[A-Z]{3}\d{4}$'); final brazilianPlateRegex = RegExp(r'^[A-Z]{3}\d{4}$');
// (ABC1D23)
final mercosurPlateRegex = RegExp(r'^[A-Z]{3}\d[A-Z0-9]\d{2}$'); final mercosurPlateRegex = RegExp(r'^[A-Z]{3}\d[A-Z0-9]\d{2}$');
if (!brazilianPlateRegex.hasMatch(value) && if (!brazilianPlateRegex.hasMatch(value!) &&
!mercosurPlateRegex.hasMatch(value)) { !mercosurPlateRegex.hasMatch(value)) {
return FFLocalizations.of(context).getVariableText( return FFLocalizations.of(context).getVariableText(
ptText: 'Placa inválida', ptText: 'Placa inválida',
@ -117,49 +120,49 @@ mixin class _BaseVehiclePage {
FocusNode? textFieldFocusColor; FocusNode? textFieldFocusColor;
TextEditingController? textFieldControllerColor; TextEditingController? textFieldControllerColor;
String? textControllerColorValidator(BuildContext contexnt, String? value) { String? textControllerColorValidator(BuildContext contexnt, String? value) {
if (value == null || value.isEmpty) { return validateField(
return FFLocalizations.of(context).getVariableText( context, value, 'Cor é obrigatória', 'Color is required');
ptText: 'Cor é obrigatória',
enText: 'Color is required',
);
}
return null;
} }
FocusNode? textFieldFocusModel; FocusNode? textFieldFocusModel;
TextEditingController? textFieldControllerModel; TextEditingController? textFieldControllerModel;
String? textControllerModelValidator(BuildContext contexnt, String? value) { String? textControllerModelValidator(BuildContext contexnt, String? value) {
return validateField(
context, value, 'Modelo é obrigatório', 'Model is required');
}
String? validateField(
BuildContext context, String? value, String ptText, String enText) {
if (value == null || value.isEmpty) { if (value == null || value.isEmpty) {
return FFLocalizations.of(context).getVariableText( return FFLocalizations.of(context).getVariableText(
ptText: 'Modelo é obrigatório', ptText: ptText,
enText: 'Model is required', enText: enText,
); );
} }
return null; return null;
} }
void switchTab(int index) { Future<void> switchTab(int index) async {
tabBarController.animateTo(index); tabBarController.animateTo(index);
if (index == 0) handleEditingChanged(false); if (index == 0) await handleEditingChanged(false);
safeSetState?.call(); safeSetState?.call();
} }
void clearFields() async { Future<void> clearFields() async {
textFieldControllerLicensePlate = TextEditingController(text: ''); textFieldControllerLicensePlate = TextEditingController(text: '');
textFieldControllerColor = TextEditingController(text: ''); textFieldControllerColor = TextEditingController(text: '');
textFieldControllerModel = TextEditingController(text: ''); textFieldControllerModel = TextEditingController(text: '');
} }
void handleEditingChanged(bool editing) { Future<void> handleEditingChanged(bool editing) async {
isEditing = editing; isEditing = editing;
clearFields(); await clearFields();
} }
void setEditForm(dynamic item) { Future<void> setEditForm(dynamic item) async {
if (item != null) { if (item != null) {
vehicleId = item['vehicleId']; vehicleId = item['vehicleId'];
log("setEditForm ");
log("setEditForm -> ${item.toString()}");
textFieldControllerLicensePlate = TextEditingController( textFieldControllerLicensePlate = TextEditingController(
text: item != null ? item['licensePlate'] ?? '' : ''); text: item != null ? item['licensePlate'] ?? '' : '');
@ -169,6 +172,23 @@ mixin class _BaseVehiclePage {
TextEditingController(text: item != null ? item['model'] ?? '' : ''); TextEditingController(text: item != null ? item['model'] ?? '' : '');
} }
} }
Future<void> handleVehicleResponse(ApiCallResponse response,
String successMessage, String errorMessage) async {
if (response.jsonBody['error'] == false) {
await DialogUtil.success(context, successMessage).then((_) async {
await switchTab(0);
});
} else {
String errorMsg;
try {
errorMsg = response.jsonBody['error_msg'];
} catch (e) {
errorMsg = errorMessage;
}
await DialogUtil.error(context, errorMsg);
}
}
} }
/// [_VehicleRegisterScreenModel] is a mixin that contains the business logic of the vehicle register page. /// [_VehicleRegisterScreenModel] is a mixin that contains the business logic of the vehicle register page.
@ -179,27 +199,17 @@ mixin _VehicleRegisterScreenModel on _BaseVehiclePage {
color: textFieldControllerColor!.text, color: textFieldControllerColor!.text,
model: textFieldControllerModel!.text, model: textFieldControllerModel!.text,
); );
if (response.jsonBody['error'] == false) { await handleVehicleResponse(
await DialogUtil.success( response,
context, FFLocalizations.of(context).getVariableText(
FFLocalizations.of(context).getVariableText( ptText: 'Veículo cadastrado com sucesso',
ptText: 'Veículo cadastrado com sucesso', enText: 'Vehicle registered successfully',
enText: 'Vehicle registered successfully', ),
)).then((_) async { FFLocalizations.of(context).getVariableText(
switchTab(0); ptText: 'Erro ao cadastrar veículo',
}); enText: 'Error registering vehicle',
} 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);
}
} }
} }
@ -210,36 +220,26 @@ mixin _VehicleUpdateScreenModel on _BaseVehiclePage {
licensePlate: textFieldControllerLicensePlate!.text, licensePlate: textFieldControllerLicensePlate!.text,
color: textFieldControllerColor!.text, color: textFieldControllerColor!.text,
model: textFieldControllerModel!.text, model: textFieldControllerModel!.text,
vehicleId: vehicleId!, vehicleId: vehicleId,
);
await handleVehicleResponse(
response,
FFLocalizations.of(context).getVariableText(
ptText: 'Veículo atualizado com sucesso',
enText: 'Vehicle updated successfully',
),
FFLocalizations.of(context).getVariableText(
ptText: 'Erro ao atualizar veículo',
enText: 'Error updating vehicle',
),
); );
if (response.jsonBody['error'] == false) {
await DialogUtil.success(
context,
FFLocalizations.of(context).getVariableText(
ptText: 'Veículo atualizado com sucesso',
enText: 'Vehicle updated successfully',
)).then((_) async {
switchTab(0);
});
} else {
String errorMessage;
try {
errorMessage = response.jsonBody['message'];
} catch (e) {
errorMessage = FFLocalizations.of(context).getVariableText(
ptText: 'Erro ao atualizar veículo',
enText: 'Error updating vehicle',
);
}
await DialogUtil.error(context, errorMessage);
}
} }
} }
/// [_VehicleHistoryScreenModel] is a mixin that contains the business logic of the vehicle history page. /// [_VehicleHistoryScreenModel] is a mixin that contains the business logic of the vehicle history page.
mixin _VehicleHistoryScreenModel on _BaseVehiclePage { mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
Future<Map<String, Color>?> generateStatusColorMap( Future<Map<String, Color>?> generateStatusColorMap(
dynamic uItem, int count) async { dynamic uItem, bool isDetail) async {
final autoApproval = final autoApproval =
await StorageHelper().get(LocalsStorageKey.vehicleAutoApproval.key); await StorageHelper().get(LocalsStorageKey.vehicleAutoApproval.key);
if (autoApproval.toBoolean == true) return null; if (autoApproval.toBoolean == true) return null;
@ -247,26 +247,9 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
final theme = FlutterFlowTheme.of(context); final theme = FlutterFlowTheme.of(context);
final localization = FFLocalizations.of(context); final localization = FFLocalizations.of(context);
byLanguage(en, pt) => localization.getVariableText(enText: en, ptText: pt); String byLanguage(String en, String pt) =>
localization.getVariableText(enText: en, ptText: pt);
final preFixStatusMap = {
"APR_CREATE": {
"text": byLanguage('Awaiting', 'Aguardando'),
"color": theme.warning,
},
"APR_DELETE": {
"text": byLanguage('Awaiting', 'Aguardando'),
"color": theme.warning,
},
"APR_UPDATE": {
"text": byLanguage('Awaiting', 'Aguardando'),
"color": theme.warning,
},
"AGU_CHANGE": {
"text": byLanguage('Awaiting', 'Aguardando'),
"color": theme.accent2,
},
};
final vehicleStatusMap = { final vehicleStatusMap = {
"ATI": { "ATI": {
"text": byLanguage('Active', 'Ativo'), "text": byLanguage('Active', 'Ativo'),
@ -277,26 +260,20 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
"color": theme.accent2, "color": theme.accent2,
}, },
"APR_CREATE": { "APR_CREATE": {
"text": byLanguage('Creation', 'Criação'), "text": byLanguage('Awaiting Creation', 'Aguardando Criação'),
"color": theme.success, "color": theme.success,
}, },
"APR_DELETE": { "APR_DELETE": {
"text": byLanguage('Awaiting Deletion', 'Exclusão'), "text": byLanguage('Awaiting Deletion', 'Aguardando Exclusão'),
"color": theme.warning, "color": theme.error,
}, },
"APR_UPDATE": { "APR_UPDATE": {
"text": byLanguage('Update', 'Atualização'), "text": byLanguage('Awaiting Update', 'Aguardando Atualização'),
"color": theme.warning,
},
"AGU_CHANGE": {
"text": byLanguage('Correction', 'Correção'),
"color": theme.accent2, "color": theme.accent2,
}, },
}; "AGU_CHANGE": {
final ownerStatusMap = { "text": byLanguage('Awaiting Change', 'Aguardando Alteração'),
true: { "color": theme.warning,
"text": byLanguage('My Vehicle', 'Meu Veículo'),
"color": theme.primaryText,
}, },
}; };
@ -304,27 +281,18 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
final isOwner = uItem['isOwnerVehicle']; final isOwner = uItem['isOwnerVehicle'];
if (vehicleStatusMap.containsKey(status)) { if (vehicleStatusMap.containsKey(status)) {
if (count > 1) final statusMap = {
return { vehicleStatusMap[status]!['text'] as String:
// if (preFixStatusMap.containsKey(status)) vehicleStatusMap[status]!['color'] as Color,
// preFixStatusMap[status]!['text'] as String: preFixStatusMap[status]!['color'] as Color,
vehicleStatusMap[status]!['text'] as String:
vehicleStatusMap[status]!['color'] as Color,
if (ownerStatusMap.containsKey(isOwner) &&
(status != 'ATI' || status != 'INA'))
ownerStatusMap[isOwner]!['text'] as String:
ownerStatusMap[isOwner]!['color'] as Color
};
if (status == 'ATI' || status == 'INA')
return {
vehicleStatusMap[status]!['text'] as String:
vehicleStatusMap[status]!['color'] as Color,
};
return {
"${preFixStatusMap[status]!['text']} ${vehicleStatusMap[status]!['text']}":
vehicleStatusMap[status]!['color'] as Color
}; };
if (!isDetail && isOwner && (status != 'ATI' && status != 'INA')) {
statusMap[byLanguage('My Vehicle', 'Meu Veículo')] = theme.primaryText;
}
return statusMap;
} }
return {}; return {};
} }
@ -352,8 +320,10 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
context.pop(); context.pop();
isEditing = true; isEditing = true;
switchTab(1);
setEditForm(item); await switchTab(1);
await setEditForm(item);
} }
final cancelText = FFLocalizations.of(context) final cancelText = FFLocalizations.of(context)
@ -584,7 +554,7 @@ mixin _VehicleHistoryScreenModel on _BaseVehiclePage {
required VehicleModel model, required VehicleModel model,
required FreCardIcon? icon, required FreCardIcon? icon,
}) async { }) async {
final status = await generateStatusColorMap(item, 1); final status = await generateStatusColorMap(item, true);
final buttons = await generateActionButtons(item); final buttons = await generateActionButtons(item);
final labels = await generateLabelsHashMap(item); final labels = await generateLabelsHashMap(item);
return DetailsComponentWidget( return DetailsComponentWidget(

View File

@ -27,76 +27,86 @@ class _VehicleRegisterScreenState extends State<VehicleRegisterScreen> {
Form _buildBody(BuildContext context) { Form _buildBody(BuildContext context) {
return Form( return Form(
key: widget.model.registerFormKey, key: widget.model.registerFormKey,
autovalidateMode: AutovalidateMode.onUserInteraction, autovalidateMode: AutovalidateMode.onUserInteraction,
child: Column( child: Column(
mainAxisSize: MainAxisSize.max, mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly, mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [ children: [
CustomInputUtil( _buildCustomInput(
controller: widget.model.textFieldControllerLicensePlate, context: context,
validator: widget.model.textControllerLicensePlateValidator controller: widget.model.textFieldControllerLicensePlate!,
.asValidator(context), validator: widget.model.textControllerLicensePlateValidator,
focusNode: widget.model.textFieldFocusLicensePlate, focusNode: widget.model.textFieldFocusLicensePlate!,
labelText: FFLocalizations.of(context) labelText: FFLocalizations.of(context)
.getVariableText(ptText: 'Placa', enText: 'License Plate'), .getVariableText(ptText: 'Placa', enText: 'License Plate'),
hintText: FFLocalizations.of(context) hintText: FFLocalizations.of(context)
.getVariableText(ptText: 'Placa', enText: 'License Plate'), .getVariableText(ptText: 'Placa', enText: 'License Plate'),
suffixIcon: Symbols.format_color_text, suffixIcon: Symbols.format_color_text,
haveMaxLength: true, ),
onChanged: (value) => setState(() {}), _buildCustomInput(
maxLength: 80, context: context,
), controller: widget.model.textFieldControllerModel!,
CustomInputUtil( validator: widget.model.textControllerModelValidator,
controller: widget.model.textFieldControllerModel, focusNode: widget.model.textFieldFocusModel!,
validator: widget.model.textControllerModelValidator labelText: FFLocalizations.of(context)
.asValidator(context), .getVariableText(ptText: 'Modelo', enText: 'Model'),
focusNode: widget.model.textFieldFocusModel, hintText: FFLocalizations.of(context).getVariableText(
labelText: FFLocalizations.of(context) ptText: 'Ex: Voyage, Ford', enText: 'e.g. Voyage, Ford'),
.getVariableText(ptText: 'Modelo', enText: 'Model'), suffixIcon: Symbols.car_repair,
hintText: FFLocalizations.of(context).getVariableText( ),
ptText: 'Ex: Voyage, Ford', _buildCustomInput(
enText: 'e.g. Voyage, Ford', context: context,
), controller: widget.model.textFieldControllerColor!,
suffixIcon: Symbols.car_repair, validator: widget.model.textControllerColorValidator,
haveMaxLength: true, focusNode: widget.model.textFieldFocusColor!,
onChanged: (value) => setState(() {}), labelText: FFLocalizations.of(context)
maxLength: 80, .getVariableText(ptText: 'Cor', enText: 'Color'),
), hintText: FFLocalizations.of(context).getVariableText(
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', ptText: 'Ex: Preto, Amarelo, Branco',
enText: 'e.g. Black, Yellow, White', enText: 'e.g. Black, Yellow, White'),
), suffixIcon: Symbols.palette,
suffixIcon: Symbols.palette, ),
haveMaxLength: true, Padding(
onChanged: (value) => setState(() {}), padding: const EdgeInsets.fromLTRB(70, 20, 70, 30),
maxLength: 80, child: SubmitButtonUtil(
labelText: FFLocalizations.of(context)
.getVariableText(ptText: 'Cadastrar', enText: 'Register'),
onPressed: widget.model.isFormValid(context, widget.model.registerFormKey)
? widget.model.registerVehicle
: null,
), ),
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 Widget _buildCustomInput({
: null), required BuildContext context,
), required TextEditingController controller,
], required String? Function(BuildContext, String?) validator,
)); required FocusNode focusNode,
required String labelText,
required String hintText,
required IconData suffixIcon,
}) {
return CustomInputUtil(
controller: controller,
validator: (value) => validator(context, value),
focusNode: focusNode,
labelText: labelText,
hintText: hintText,
suffixIcon: suffixIcon,
haveMaxLength: true,
onChanged: (value) => setState(() {}),
maxLength: 80,
);
} }
Align _buildHeader(BuildContext context) { Align _buildHeader(BuildContext context) {
// double limitedInputFontSize = LimitedFontSizeUtil.getInputFontSize(context);
double limitedHeaderFontSize = double limitedHeaderFontSize =
LimitedFontSizeUtil.getHeaderFontSize(context); LimitedFontSizeUtil.getHeaderFontSize(context);
// double limitedSubHeaderFontSize = LimitedFontSizeUtil.getSubHeaderFontSize(context);
return Align( return Align(
alignment: const AlignmentDirectional(-1.0, 0.0), alignment: const AlignmentDirectional(-1.0, 0.0),

View File

@ -18,98 +18,116 @@ class _VehicleUpdateScreenState extends State<VehicleUpdateScreen> {
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 alteração com os dados do seu veículo',
enText: 'Fill out the update 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),
),
),
),
),
Form(
key: widget.model.updateFormKey,
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,
),
Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 15),
child: 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: Icons.car_repair,
haveMaxLength: true,
onChanged: (value) => setState(() {}),
maxLength: 80,
),
),
Padding(
padding: const EdgeInsets.fromLTRB(0, 0, 0, 15),
child: 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: Icons.pets_outlined,
haveMaxLength: true,
onChanged: (value) => setState(() {}),
maxLength: 80,
),
),
Padding(
padding: const EdgeInsets.fromLTRB(70, 20, 70, 30),
child: SubmitButtonUtil(
labelText: FFLocalizations.of(context)
.getVariableText(ptText: 'Salvar', enText: 'Save'),
onPressed: widget.model.isFormValid(context)
? widget.model.updateVehicle
: null),
),
],
)),
], ],
), ),
); );
} }
Form buildBody(BuildContext context) {
return Form(
key: widget.model.updateFormKey,
autovalidateMode: AutovalidateMode.onUserInteraction,
child: Column(
mainAxisSize: MainAxisSize.max,
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: [
_buildCustomInput(
context: context,
controller: widget.model.textFieldControllerLicensePlate!,
validator: widget.model.textControllerLicensePlateValidator,
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,
),
_buildCustomInput(
context: context,
controller: widget.model.textFieldControllerModel!,
validator: widget.model.textControllerModelValidator,
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,
),
_buildCustomInput(
context: context,
controller: widget.model.textFieldControllerColor!,
validator: widget.model.textControllerColorValidator,
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,
),
_buildSubmitButton(context),
],
),
);
}
Widget _buildHeader(BuildContext 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 alteração com os dados do seu veículo',
enText: 'Fill out the update 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),
),
),
),
);
}
Widget _buildCustomInput({
required BuildContext context,
required TextEditingController controller,
required String? Function(BuildContext, String?) validator,
required FocusNode focusNode,
required String labelText,
required String hintText,
required IconData suffixIcon,
}) {
return CustomInputUtil(
controller: controller,
validator: (value) => validator(context, value),
focusNode: focusNode,
labelText: labelText,
hintText: hintText,
suffixIcon: suffixIcon,
haveMaxLength: true,
onChanged: (value) => setState(() {}),
maxLength: 80,
);
}
Widget _buildSubmitButton(BuildContext context) {
return Padding(
padding: const EdgeInsets.fromLTRB(70, 20, 70, 30),
child: SubmitButtonUtil(
labelText: FFLocalizations.of(context)
.getVariableText(ptText: 'Salvar', enText: 'Save'),
onPressed: widget.model.isFormValid(context, widget.model.updateFormKey)
? () => widget.model.updateVehicle()
: null,
),
);
}
} }

View File

@ -1,4 +1,5 @@
import 'dart:collection'; import 'dart:collection';
import 'dart:developer';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';

File diff suppressed because it is too large Load Diff

View File

@ -3,7 +3,7 @@ description: A new Flutter project.
publish_to: "none" publish_to: "none"
version: 1.3.3+22 version: 1.3.5+24
environment: environment:
sdk: ">=3.0.0 <4.0.0" sdk: ">=3.0.0 <4.0.0"