diff --git a/android/app/build.gradle b/android/app/build.gradle index 26fd88b3319b6c1c60538186ba1d7909045c7b3e..6ebc67751f621809297e35cc884c90b911c8eb43 100644 --- a/android/app/build.gradle +++ b/android/app/build.gradle @@ -44,7 +44,7 @@ android { defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). - applicationId "com.example.smf_mobile" + applicationId "com.upsmf.beta" minSdkVersion 21 targetSdkVersion 31 versionCode flutterVersionCode.toInteger() diff --git a/android/app/google-services.json b/android/app/google-services.json index ad2c9482b18241521d164ded12dd63776f4b17c7..e1d3b1684ef4d356465bd99d498979e10d41d990 100644 --- a/android/app/google-services.json +++ b/android/app/google-services.json @@ -1,41 +1,33 @@ { "project_info": { - "project_number": "927565375305", - "project_id": "up-smf-47fd3", - "storage_bucket": "up-smf-47fd3.appspot.com" + "project_number": "711487557480", + "project_id": "up-smf-373f9", + "storage_bucket": "up-smf-373f9.appspot.com" }, "client": [ { "client_info": { - "mobilesdk_app_id": "1:927565375305:android:72f8b2fed08ff47dc6dc98", + "mobilesdk_app_id": "1:711487557480:android:569911081eab25d11150dd", "android_client_info": { - "package_name": "com.example.smf_mobile" + "package_name": "com.upsmf.beta" } }, "oauth_client": [ { - "client_id": "927565375305-57h44768ioqql1j8lm5q0jrq4es9lqj8.apps.googleusercontent.com", - "client_type": 1, - "android_info": { - "package_name": "com.example.smf_mobile", - "certificate_hash": "7157475a2fccb7c2857112262c12be29359f845d" - } - }, - { - "client_id": "927565375305-den7asbeb5ucg36rpbn76ppnnd10pm4r.apps.googleusercontent.com", + "client_id": "711487557480-6dolnt6ee3jntc0ukihbbmq82hrsfmql.apps.googleusercontent.com", "client_type": 3 } ], "api_key": [ { - "current_key": "AIzaSyDmWSOiwgEnSoTt6GKiArZT9wHREe-f1rw" + "current_key": "AIzaSyAn-unnydboxQRtncYOPgYxxFGUEYqTnRw" } ], "services": { "appinvite_service": { "other_platform_oauth_client": [ { - "client_id": "927565375305-den7asbeb5ucg36rpbn76ppnnd10pm4r.apps.googleusercontent.com", + "client_id": "711487557480-6dolnt6ee3jntc0ukihbbmq82hrsfmql.apps.googleusercontent.com", "client_type": 3 } ] diff --git a/android/app/src/debug/AndroidManifest.xml b/android/app/src/debug/AndroidManifest.xml index fad2853bf4d928f4d704e37b901325eba4307876..89b3eebd5b278f1f313af4a494eb6cf79560b726 100644 --- a/android/app/src/debug/AndroidManifest.xml +++ b/android/app/src/debug/AndroidManifest.xml @@ -1,5 +1,5 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.example.smf_mobile"> + package="com.upsmf.beta"> <!-- Flutter needs it to communicate with the running application to allow setting breakpoints, to provide hot reload, etc. --> diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml index f6f287cbcbeb4961e33dc5edae8fe98bba965cf2..db43866a43039c3b7eb40641c2a5693e2ef00e24 100644 --- a/android/app/src/main/AndroidManifest.xml +++ b/android/app/src/main/AndroidManifest.xml @@ -1,7 +1,6 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.example.smf_mobile"> - <uses-permission android:name="android.permission.INTERNET"/> - <application + package="com.upsmf.beta"> + <application android:label="UP SMF" android:name="${applicationName}" android:icon="@mipmap/ic_launcher"> @@ -25,10 +24,6 @@ <action android:name="android.intent.action.MAIN"/> <category android:name="android.intent.category.LAUNCHER"/> </intent-filter> - <intent-filter> - <action android:name="FLUTTER_NOTIFICATION_CLICK" /> - <category android:name="android.intent.category.DEFAULT" /> - </intent-filter> </activity> <!-- Don't delete the meta-data below. This is used by the Flutter tool to generate GeneratedPluginRegistrant.java --> diff --git a/android/app/src/main/kotlin/com/example/smf_mobile/MainActivity.kt b/android/app/src/main/kotlin/com/upsmf/beta/MainActivity.kt similarity index 75% rename from android/app/src/main/kotlin/com/example/smf_mobile/MainActivity.kt rename to android/app/src/main/kotlin/com/upsmf/beta/MainActivity.kt index 4664aef6c142827e3c46a5f814653304965d0f07..2e02ac799f3b4bac29a49f858bef88623574d483 100644 --- a/android/app/src/main/kotlin/com/example/smf_mobile/MainActivity.kt +++ b/android/app/src/main/kotlin/com/upsmf/beta/MainActivity.kt @@ -1,4 +1,4 @@ -package com.example.smf_mobile +package com.upsmf.beta import io.flutter.embedding.android.FlutterActivity diff --git a/android/app/src/main/res/drawable/flutter_devs.png b/android/app/src/main/res/drawable/flutter_devs.png deleted file mode 100644 index 275d9ad266027529356df93df0097f05ea3e9889..0000000000000000000000000000000000000000 Binary files a/android/app/src/main/res/drawable/flutter_devs.png and /dev/null differ diff --git a/android/app/src/profile/AndroidManifest.xml b/android/app/src/profile/AndroidManifest.xml index fad2853bf4d928f4d704e37b901325eba4307876..89b3eebd5b278f1f313af4a494eb6cf79560b726 100644 --- a/android/app/src/profile/AndroidManifest.xml +++ b/android/app/src/profile/AndroidManifest.xml @@ -1,5 +1,5 @@ <manifest xmlns:android="http://schemas.android.com/apk/res/android" - package="com.example.smf_mobile"> + package="com.upsmf.beta"> <!-- Flutter needs it to communicate with the running application to allow setting breakpoints, to provide hot reload, etc. --> diff --git a/lib/constants/api_endpoints.dart b/lib/constants/api_endpoints.dart index ab3a522b895c24ea04f17842de508b236bb65738..d806807c86037bc0810f631d2dc88971483f5413 100644 --- a/lib/constants/api_endpoints.dart +++ b/lib/constants/api_endpoints.dart @@ -7,7 +7,10 @@ class ApiUrl { '$baseUrl/api/user/updateUserDeviceToken'; static const getAllApplications = '$baseUrl/api/forms/getAllApplications'; static const submitInspection = '$baseUrl/api/forms/submitInspection'; + static const submitBulkInspection = '$baseUrl/api/forms/submitBulkInspection'; static const getAllUsers = '$baseUrl/api/user/v1/getAllUser'; static const getFormDetails = '$baseUrl/api/forms/getFormById?id='; static const submitConcent = '$baseUrl/api/forms/consentApplication'; + static const submitBulkConcent = '$baseUrl/api/forms/consentBulkApplication'; + static const getAllForms = '$baseUrl/api/forms/getAllForms?isDetail=true'; } diff --git a/lib/constants/app_constants.dart b/lib/constants/app_constants.dart index 9bf19be5b7f54693a4c252aedff1229da279cf2c..e583bbd6fb57f0f50ea25ba0f9e98968f8b7bc50 100644 --- a/lib/constants/app_constants.dart +++ b/lib/constants/app_constants.dart @@ -24,6 +24,7 @@ class InspectionStatus { static const String leadInspectorCompleted = 'LEADINSCOMPLETED'; static const String inspectionPending = 'PENDING'; static const String returned = 'RETURNED'; + static const String approved = 'APPROVED'; } class FieldValue { @@ -34,6 +35,7 @@ class FieldValue { class AppDatabase { static const String name = 'smf_db'; static const String applicationsTable = 'applications'; + static const String formsTable = 'forms'; static const String inspectionTable = 'inspections'; static const String loginPinsTable = 'login_pins'; } diff --git a/lib/database/offline_model.dart b/lib/database/offline_model.dart index ef73324fc9061894c100238645572a7f49e92779..6ad7747188bc563354692fb07376fa8d740275d5 100644 --- a/lib/database/offline_model.dart +++ b/lib/database/offline_model.dart @@ -9,6 +9,7 @@ class OfflineModel { return sql.openDatabase(path.join(dbPath, AppDatabase.name), onCreate: (db, version) async { const String applicationsTable = AppDatabase.applicationsTable; + const String formsTable = AppDatabase.formsTable; const String inspectionTable = AppDatabase.inspectionTable; const String loginPinsTable = AppDatabase.loginPinsTable; @@ -17,6 +18,11 @@ class OfflineModel { username VARCHAR(64), application_data TEXT )'''); + await db.execute('''CREATE TABLE $formsTable ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + username VARCHAR(64), + form_data TEXT + )'''); await db.execute('''CREATE TABLE $inspectionTable ( id INTEGER PRIMARY KEY AUTOINCREMENT, inspector_type CHECK( inspector_type IN ('${Inspector.leadInspector}','${Inspector.assistantInspector}') ), @@ -54,6 +60,30 @@ class OfflineModel { where: 'username = ?', whereArgs: whereArgs); } + static Future<void> saveForms(Map<String, Object> data) async { + final db = await OfflineModel.database(); + db.insert( + AppDatabase.formsTable, + data, + conflictAlgorithm: ConflictAlgorithm.replace, + ); + } + + static Future<Map> getForms(String username) async { + final db = await OfflineModel.database(); + List<dynamic> whereArgs = [username]; + List<Map> rows = await db.query(AppDatabase.formsTable, + where: 'username = ?', orderBy: 'id DESC', whereArgs: whereArgs); + return rows[0]; + } + + static Future<void> deleteForms(String username) async { + Database db = await OfflineModel.database(); + List<dynamic> whereArgs = [username]; + await db.delete(AppDatabase.formsTable, + where: 'username = ?', whereArgs: whereArgs); + } + static Future<void> saveInspection(Map<String, Object> data) async { final db = await OfflineModel.database(); db.insert( diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb index 659768fb173fad20c92d9700328e551c80abe80e..ae93053ce950d00f607e0ea194b8f53ec01ebd3e 100644 --- a/lib/l10n/app_en.arb +++ b/lib/l10n/app_en.arb @@ -19,6 +19,7 @@ "signIn": "SIGN IN", "goBack": "Go back", "goBackText": "Go back, re-enter the email", + "youAreOffline": "You are offline", "pendingApplications": "Pending applications", "today": "Today", "upcoming": "Upcoming", @@ -45,5 +46,9 @@ "leadInspector": "Lead inspector", "assistingInspectors": "Assisting inspectors", "iDisagree": "I disagree", - "iConsent": "I consent" + "iConsent": "I consent", + "acceptTermsAndConditions": "Please accept terms and conditions", + "dataSynchoronized": "Data synchoronized", + "dataSynchoronizedText": "Data has been synchoronized" + } \ No newline at end of file diff --git a/lib/landing_page.dart b/lib/landing_page.dart index 2fbec398fd02e4c19a516aa8289f546fc94eea77..262c790700434fdf8e41e8249cfef25d79b6bfc7 100644 --- a/lib/landing_page.dart +++ b/lib/landing_page.dart @@ -1,16 +1,17 @@ +import 'dart:convert'; import 'dart:io'; import 'package:flutter/material.dart'; import 'package:flutter_localizations/flutter_localizations.dart'; import 'package:provider/provider.dart'; +import 'package:smf_mobile/database/offline_model.dart'; import 'package:smf_mobile/pages/home_page.dart'; import 'package:smf_mobile/pages/login_email_page.dart'; import 'package:smf_mobile/repositories/application_repository.dart'; import 'package:smf_mobile/repositories/form_repository.dart'; import 'package:smf_mobile/repositories/login_repository.dart'; import 'package:smf_mobile/repositories/user_repository.dart'; +import 'package:smf_mobile/services/application_service.dart'; import 'package:smf_mobile/util/helper.dart'; -import 'package:smf_mobile/util/notification_helper.dart'; -// import 'package:smf_mobile/util/notification_helper.dart'; import 'constants/app_constants.dart'; import 'constants/app_urls.dart'; import 'constants/color_constants.dart'; @@ -18,7 +19,6 @@ import 'routes.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:firebase_core/firebase_core.dart'; import 'package:firebase_messaging/firebase_messaging.dart'; -// import 'package:flutter_secure_storage/flutter_secure_storage.dart'; class LandingPage extends StatefulWidget { static const route = AppUrl.landingPage; @@ -32,7 +32,12 @@ class LandingPage extends StatefulWidget { } Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async { - print("Handling a background message..."); + print('firebaseMessagingBackgroundHandler...'); + bool tokenExpired = await Helper.isTokenExpired(); + if (!tokenExpired) { + saveApplications(); + submitBulkInspection(); + } // BuildContext context; // if (message.notification != null) { // String applicationId = message.data['applicationId'] ?? ''; @@ -43,6 +48,46 @@ Future<void> firebaseMessagingBackgroundHandler(RemoteMessage message) async { // } } +void saveApplications() async { + print('saveApplications...'); + Map _data; + final request = await ApplicationService.getApplications(); + _data = json.decode(request.body); + if (_data['statusInfo']['statusCode'] == 200) { + String username = await Helper.getUser(Storage.username); + Map<String, Object> data = { + 'username': username, + 'application_data': request.body + }; + await OfflineModel.deleteApplications(username); + await OfflineModel.saveApplications(data); + } +} + +void submitBulkInspection() async { + print('submitBulkInspection...'); + List<Map> inspections = []; + List<Map> consents = []; + try { + List<Map> rawInspections = await OfflineModel.getInspections(); + for (var inspection in rawInspections) { + if (inspection['inspector_type'] == Inspector.leadInspector) { + inspections.add(jsonDecode(inspection['inspection_data'])); + } else { + consents.add(jsonDecode(inspection['inspection_data'])); + } + } + if (inspections.isNotEmpty) { + await ApplicationService.submitBulkInspection(inspections); + } + if (consents.isNotEmpty) { + await ApplicationService.submitBulkConsent(consents); + } + } catch (_) { + // print(_); + } +} + class _LandingPageState extends State<LandingPage> { final client = HttpClient(); Locale _locale = const Locale('en', 'US'); diff --git a/lib/models/application_model.dart b/lib/models/application_model.dart index f1ecb95c224df384c87db03677b6aee689b14640..c1f8cca0e3e085fbab5211fa7dad53ae77be3b75 100644 --- a/lib/models/application_model.dart +++ b/lib/models/application_model.dart @@ -1,5 +1,3 @@ -import 'package:intl/intl.dart'; - class Application { final int formId; final String applicationId; diff --git a/lib/models/form_model.dart b/lib/models/form_model.dart index b30851ea9c881ec648d5d567dff53d6e60489838..e0cd6bd34ca250ce6d7d308d90fb08f34c7ceef0 100644 --- a/lib/models/form_model.dart +++ b/lib/models/form_model.dart @@ -23,7 +23,7 @@ class FormData { version: json['version'], title: json['title'], description: json['description'], - fields: json['fields'] ?? [], + fields: json['fields'], inspectionFields: json['inspectionFields'] ?? [], updatedDate: json['updatedDate']); } diff --git a/lib/pages/application_details_page.dart b/lib/pages/application_details_page.dart index f8553c1bd08a5feb10703f9ea6da691d9335bc93..124c5cc9abdcf7c5ea742d34c72ec90af1e6b99a 100644 --- a/lib/pages/application_details_page.dart +++ b/lib/pages/application_details_page.dart @@ -18,8 +18,8 @@ import 'package:smf_mobile/widgets/people_card.dart'; import 'package:smf_mobile/widgets/silverappbar_delegate.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'dart:async'; -import 'package:connectivity_plus/connectivity_plus.dart'; -import 'package:smf_mobile/util/connectivity_helper.dart'; +// import 'package:connectivity_plus/connectivity_plus.dart'; +// import 'package:smf_mobile/util/connectivity_helper.dart'; class ApplicationDetailsPage extends StatefulWidget { final Application application; @@ -34,8 +34,8 @@ class ApplicationDetailsPage extends StatefulWidget { class _ApplicationDetailsPageState extends State<ApplicationDetailsPage> with SingleTickerProviderStateMixin { - Map _source = {ConnectivityResult.none: false}; - final MyConnectivity _connectivity = MyConnectivity.instance; + // Map _source = {ConnectivityResult.none: false}; + // final MyConnectivity _connectivity = MyConnectivity.instance; final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); TabController? _tabController; late FormData _formData; @@ -61,18 +61,24 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage> @override void initState() { super.initState(); - _connectivity.initialise(); - _connectivity.myStream.listen((source) { - setState(() => _source = source); - }); + // _connectivity.initialise(); + // _connectivity.myStream.listen((source) { + // if (mounted) { + // setState(() => _source = source); + // } + // }); widget.application.dataObject.forEach((key, value) => _tabs.add(key)); _tabController = TabController(vsync: this, length: _tabs.length); _tabController!.addListener(_setActiveTabIndex); - _checkInspectorRole(); + _getData(); + } + + _getData() async { + await _checkInspectorRole(); _populateFields(); } - Future<void> _checkInspectorRole() async { + Future<dynamic> _checkInspectorRole() async { String id = await Helper.getUser(Storage.userId); _userId = int.parse(id); if (widget.application.leadInspector.isNotEmpty) { @@ -101,7 +107,7 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage> if (widget.application.inspectors[i]['id'] == _userId && !_isleadInspector) { _note = widget.application.inspectors[i]['comments'] ?? ''; - _inspectionStatus = widget.application.inspectors[i]['status'] ?? false; + _inspectionStatus = widget.application.inspectors[i]['status'] ?? ''; _iConcent = widget.application.inspectors[i]['consentApplication'] ?? false; if (widget.application.inspectors[i]['consentApplication'] != null) { @@ -112,13 +118,12 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage> } setState(() {}); } + return; } Future<dynamic> _getFormDetails() async { - _validateUser(); _formData = await Provider.of<FormRespository>(context, listen: false) .getFormDetails(widget.application.formId); - // print('object'); _errorMessage = Provider.of<FormRespository>(context, listen: false).errorMessage; if (_errorMessage != '') { @@ -145,16 +150,61 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage> void _populateFields() async { Map updatedFields = {}; - widget.application.dataObject.forEach((key, value) => { - updatedFields = {}, - value.forEach((childKey, childValue) => { - updatedFields[childKey] = { - childValue: {'value': 'Correct', 'comments': ''} - } - }), - _data[key] = updatedFields - }); - _data.forEach((key, value) => _fields.add(value)); + // print(widget.application.inspectionStatus); + if (widget.application.inspectionStatus != + InspectionStatus.leadInspectorCompleted && + widget.application.status != InspectionStatus.inspectionCompleted && + widget.application.status != InspectionStatus.approved) { + widget.application.dataObject.forEach((key, value) => { + updatedFields = {}, + value.forEach((childKey, childValue) => { + updatedFields[childKey] = { + childValue: {'value': 'Correct', 'comments': ''} + } + }), + _data[key] = updatedFields + }); + _data.forEach((key, value) => _fields.add(value)); + } else { + Map existingData = {}; + print(_leadInspectorId); + widget.application.dataObject.forEach((key, value) => { + updatedFields = {}, + existingData = widget.application.inspectorDataObject[key], + value.forEach((childKey, childValue) => { + updatedFields[childKey] = { + childValue: { + 'value': _isleadInspector + ? existingData[childKey] + [existingData[childKey].keys.elementAt(0)] + ['value'] + : '', + 'comments': _isleadInspector + ? existingData[childKey] + [existingData[childKey].keys.elementAt(0)] + ['comments'] + : '' + } + } + }), + _data[key] = updatedFields + }); + _data.forEach((key, value) => _fields.add(value)); + } + + // widget.application.inspectorDataObject.forEach((key, value) => { + // // updatedFields = {}, + // value.forEach((childKey, childValue) => { + // print(childValue), + // test = childValue[childValue.keys.elementAt(0)], + // print(test['comments']), + // // updatedFields[childKey] = { + // // childValue: {'value': 'Correct', 'comments': ''} + // // } + // }), + // // _data[key] = updatedFields + // }); + if (!_isleadInspector) { updatedFields = {}; widget.application.inspectorDataObject.forEach((key, value) => { @@ -197,7 +247,11 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage> } Future<void> _submitInspection() async { - _validateUser(); + bool isInternetConnected = await Helper.isInternetConnected(); + // await Future.delayed(const Duration(milliseconds: 10)); + if (isInternetConnected) { + _validateUser(); + } if (_isleadInspector) { Map data = { 'applicationId': widget.application.applicationId, @@ -211,6 +265,7 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage> formId: 1645422297511, inspectors: widget.application.inspectors, leadInspector: widget.application.leadInspector, + inspectionFields: _formData.inspectionFields, inspectionData: data, ))); } else { @@ -229,8 +284,8 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage> final responseCode = await Provider.of<ApplicationRespository>(context, listen: false) - .submitConcent(Helper.isInternetConnected(_source), data); - if (responseCode != 0) { + .submitConcent(isInternetConnected, data); + if (responseCode == 200) { Navigator.of(context).pushReplacement(MaterialPageRoute( builder: (context) => const InspectionCompletedPage())); } else { @@ -910,10 +965,17 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage> ) ], )) - : widget.application.status != - InspectionStatus.inspectionCompleted && - widget.application.inspectionStatus != - InspectionStatus.leadInspectorCompleted + : (widget.application.status != + InspectionStatus + .inspectionCompleted && + widget.application.inspectionStatus != + InspectionStatus + .leadInspectorCompleted && + widget.application.status != + InspectionStatus.approved) || + (widget.application.status == + InspectionStatus.sentForInspection && + !_isleadInspector) ? TextButton( onPressed: () { _submitInspection(); diff --git a/lib/pages/create_pin_page.dart b/lib/pages/create_pin_page.dart index ed1f45a86ce1f41aa47571b518abfdb8700f0cd8..f9a270eaa5ae4d319a596b08b60817cdc1683a22 100644 --- a/lib/pages/create_pin_page.dart +++ b/lib/pages/create_pin_page.dart @@ -5,14 +5,12 @@ import 'package:provider/provider.dart'; import 'package:smf_mobile/constants/app_urls.dart'; import 'package:smf_mobile/constants/color_constants.dart'; import 'package:google_fonts/google_fonts.dart'; -import 'package:smf_mobile/pages/home_page.dart'; import 'package:smf_mobile/pages/login_email_page.dart'; import 'package:smf_mobile/pages/login_otp_page.dart'; import 'package:smf_mobile/repositories/login_repository.dart'; import 'package:smf_mobile/util/helper.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:otp_text_field/otp_field.dart'; -import 'package:unique_identifier/unique_identifier.dart'; class CreatePinPage extends StatefulWidget { static const route = AppUrl.loginEmailPage; @@ -353,19 +351,20 @@ class _CreatePinPageState extends State<CreatePinPage> { child: Divider( color: AppColors.black16, )), - InkWell( - onTap: () => Navigator.of(context) - .pushReplacement(MaterialPageRoute( - builder: (context) => const LoginEmailPage(), - )), - child: Container( - width: double.infinity, - padding: const EdgeInsets.only( - top: 10, - ), + Center( + child: Container( + padding: const EdgeInsets.only( + top: 10, + ), + child: InkWell( + onTap: () => Navigator.of(context) + .pushReplacement(MaterialPageRoute( + builder: (context) => + const LoginEmailPage(), + )), child: Text( AppLocalizations.of(context)!.goBack, - textAlign: TextAlign.center, + // textAlign: TextAlign.center, style: GoogleFonts.lato( color: AppColors.primaryBlue, fontSize: 14, @@ -374,7 +373,7 @@ class _CreatePinPageState extends State<CreatePinPage> { fontWeight: FontWeight.w700, height: 1.4), )), - ) + )) ]), ) ], diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart index 370e9a827ad1777212f2866f9a8e08c89e6a981f..335369aa377d03b11a06b4ba36a90db5714e9f58 100644 --- a/lib/pages/home_page.dart +++ b/lib/pages/home_page.dart @@ -5,18 +5,24 @@ import 'package:provider/provider.dart'; import 'package:smf_mobile/constants/app_constants.dart'; import 'package:smf_mobile/constants/app_urls.dart'; import 'package:smf_mobile/constants/color_constants.dart'; +// import 'package:smf_mobile/database/offline_model.dart'; import 'package:smf_mobile/models/application_model.dart'; import 'package:smf_mobile/pages/application_details_page.dart'; import 'package:smf_mobile/pages/login_email_page.dart'; import 'package:smf_mobile/pages/past_applications.dart'; import 'package:smf_mobile/repositories/application_repository.dart'; +import 'package:smf_mobile/repositories/form_repository.dart'; import 'package:smf_mobile/repositories/login_repository.dart'; import 'package:smf_mobile/util/helper.dart'; +import 'package:smf_mobile/util/notification_helper.dart'; import 'package:smf_mobile/widgets/application_card.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'dart:async'; -import 'package:connectivity_plus/connectivity_plus.dart'; -import 'package:smf_mobile/util/connectivity_helper.dart'; +// import 'package:connectivity_plus/connectivity_plus.dart'; +// import 'package:smf_mobile/util/connectivity_helper.dart'; + +// import 'dart:async'; +// import 'dart:convert'; // import 'dart:developer' as developer; @@ -29,8 +35,8 @@ class HomePage extends StatefulWidget { } class _HomePageState extends State<HomePage> with WidgetsBindingObserver { - Map _source = {ConnectivityResult.none: false}; - final MyConnectivity _connectivity = MyConnectivity.instance; + // Map _source = {ConnectivityResult.none: false}; + // final MyConnectivity _connectivity = MyConnectivity.instance; List<Application> _allApplications = []; final List<Application> _pendingApplications = []; final List<Application> _upcomingApplications = []; @@ -40,18 +46,20 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver { @override void initState() { super.initState(); - _connectivity.initialise(); - _connectivity.myStream.listen((source) { - setState(() { - _source = source; - }); - }); + // _connectivity.initialise(); + // _connectivity.myStream.listen((source) { + // if (mounted) { + // setState(() { + // _source = source; + // }); + // } + // }); // print('applicationId:' + widget.applicationId); WidgetsBinding.instance!.addObserver(this); } void _checkNewApplication(String applicationId) { - print('applicationId $applicationId'); + // print('applicationId $applicationId'); if (applicationId != '') { for (Application application in _allApplications) { if (application.applicationId == applicationId) { @@ -79,11 +87,6 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver { _checkNewApplication(message.data['applicationId']); } }); - // setState(() {}); - // print('_isInForeground...'); - // Future.delayed(const Duration(milliseconds: 500), () { - // _checkNewApplication(); - // }); } } @@ -104,11 +107,35 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver { } } + Future<dynamic> _getForms() async { + await Provider.of<FormRespository>(context, listen: false).getAllForms(); + } + + Future<dynamic> _syncApplications() async { + var synced = + await Provider.of<ApplicationRespository>(context, listen: false) + .submitBulkInspection(); + if (synced) { + NotificationHelper.scheduleNotification( + DateTime.now(), + 0, + AppLocalizations.of(context)!.dataSynchoronized, + AppLocalizations.of(context)!.dataSynchoronizedText, + ''); + } + } + Future<dynamic> _getApplications() async { - _validateUser(); + bool isInternetConnected = await Helper.isInternetConnected(); + // await Future.delayed(const Duration(milliseconds: 10)); + if (isInternetConnected) { + _validateUser(); + _getForms(); + _syncApplications(); + } _allApplications = await Provider.of<ApplicationRespository>(context, listen: false) - .getApplications(Helper.isInternetConnected(_source)); + .getApplications(isInternetConnected); String _errorMessage = Provider.of<ApplicationRespository>(context, listen: false) .errorMessage; @@ -123,15 +150,18 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver { temp = List.from(temp.reversed); int days = Helper.getDateDiffence( DateTime.now(), DateTime.parse(temp.join("-"))); - if (days == 0) { + if ((days == 0 || days > 0) && + application.status == InspectionStatus.sentForInspection) { _pendingApplications.add(application); - } else if (days > 0) { + } else if ((days == 0 || days > 0) && + application.status != InspectionStatus.sentForInspection) { _pastApplications.add(application); } else { _upcomingApplications.add(application); } } } + // print(_pendingApplications[1].inspectorDataObject); } else if (_errorMessage.isNotEmpty) { Helper.toastMessage(_errorMessage); } diff --git a/lib/pages/inspection_summary.dart b/lib/pages/inspection_summary.dart index 2fb38fb6c7c2a437ddb31e89091163fa98586ede..d08836f6d202de01e5ad73486f645aaafa7e5850 100644 --- a/lib/pages/inspection_summary.dart +++ b/lib/pages/inspection_summary.dart @@ -4,23 +4,24 @@ import 'package:provider/provider.dart'; import 'package:smf_mobile/constants/app_constants.dart'; import 'package:smf_mobile/constants/app_urls.dart'; import 'package:smf_mobile/constants/color_constants.dart'; -import 'package:smf_mobile/models/form_model.dart'; +// import 'package:smf_mobile/models/form_model.dart'; import 'package:smf_mobile/pages/login_email_page.dart'; import 'package:smf_mobile/repositories/application_repository.dart'; -import 'package:smf_mobile/repositories/form_repository.dart'; +// import 'package:smf_mobile/repositories/form_repository.dart'; import 'package:smf_mobile/util/helper.dart'; import 'package:smf_mobile/widgets/people_card.dart'; import 'inspection_completed.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'dart:async'; -import 'package:connectivity_plus/connectivity_plus.dart'; -import 'package:smf_mobile/util/connectivity_helper.dart'; +// import 'package:connectivity_plus/connectivity_plus.dart'; +// import 'package:smf_mobile/util/connectivity_helper.dart'; class InspectionSummaryPage extends StatefulWidget { static const route = AppUrl.inspectionSummary; final int formId; final List inspectors; final List leadInspector; + final List inspectionFields; final Map inspectionData; const InspectionSummaryPage( @@ -28,6 +29,7 @@ class InspectionSummaryPage extends StatefulWidget { required this.formId, required this.inspectors, required this.leadInspector, + required this.inspectionFields, required this.inspectionData}) : super(key: key); @override @@ -35,13 +37,13 @@ class InspectionSummaryPage extends StatefulWidget { } class _InspectionSummaryPageState extends State<InspectionSummaryPage> { - Map _source = {ConnectivityResult.none: false}; - final MyConnectivity _connectivity = MyConnectivity.instance; + // Map _source = {ConnectivityResult.none: false}; + // final MyConnectivity _connectivity = MyConnectivity.instance; final TextEditingController _summaryController = TextEditingController(); final List<Map> _inspectors = []; int _leadInspectorId = 0; bool _iAgree = false; - late FormData _formData; + // late FormData _formData; String _errorMessage = ''; late Map _summaryField; late Map _termsField; @@ -49,18 +51,20 @@ class _InspectionSummaryPageState extends State<InspectionSummaryPage> { @override void initState() { super.initState(); - _connectivity.initialise(); - _connectivity.myStream.listen((source) { - setState(() => _source = source); - }); + // _connectivity.initialise(); + // _connectivity.myStream.listen((source) { + // if (mounted) { + // setState(() => _source = source); + // } + // }); _populateApplicationInspectors(); } - // @override - // void dispose() { - // // _connectivity.disposeStream(); - // super.dispose(); - // } + @override + void dispose() { + // _connectivity.disposeStream(); + super.dispose(); + } Future<void> _populateApplicationInspectors() async { if (widget.leadInspector.isNotEmpty) { @@ -87,32 +91,49 @@ class _InspectionSummaryPageState extends State<InspectionSummaryPage> { } } + // Future<dynamic> _getFormDetails(context) async { + // _validateUser(); + // _formData = await Provider.of<FormRespository>(context, listen: false) + // .getFormDetails(widget.formId); + // // print('object'); + // String _errorMessage = + // Provider.of<FormRespository>(context, listen: false).errorMessage; + // if (_errorMessage != '') { + // Helper.toastMessage(_errorMessage); + // } else { + // for (int i = 0; i < _formData.inspectionFields.length; i++) { + // if (_formData.inspectionFields[i]['fieldType'] == FieldType.heading) { + // _summaryField = _formData.inspectionFields[i]; + // } else if (_formData.inspectionFields[i]['fieldType'] == + // FieldType.checkbox) { + // _termsField = _formData.inspectionFields[i]; + // } + // } + // } + // return _formData; + // } + Future<dynamic> _getFormDetails(context) async { - _validateUser(); - _formData = await Provider.of<FormRespository>(context, listen: false) - .getFormDetails(widget.formId); - // print('object'); - String _errorMessage = - Provider.of<FormRespository>(context, listen: false).errorMessage; - if (_errorMessage != '') { - Helper.toastMessage(_errorMessage); - } else { - for (int i = 0; i < _formData.inspectionFields.length; i++) { - if (_formData.inspectionFields[i]['fieldType'] == FieldType.heading) { - _summaryField = _formData.inspectionFields[i]; - } else if (_formData.inspectionFields[i]['fieldType'] == - FieldType.checkbox) { - _termsField = _formData.inspectionFields[i]; - } + for (int i = 0; i < widget.inspectionFields.length; i++) { + if (widget.inspectionFields[i]['fieldType'] == FieldType.heading) { + _summaryField = widget.inspectionFields[i]; + } else if (widget.inspectionFields[i]['fieldType'] == + FieldType.checkbox) { + _termsField = widget.inspectionFields[i]; } } - return _formData; + return widget.inspectionFields; } Future<void> _submitInspection() async { - _validateUser(); + bool isInternetConnected = await Helper.isInternetConnected(); + // await Future.delayed(const Duration(milliseconds: 10)); + if (isInternetConnected) { + _validateUser(); + } if (!_iAgree) { - Helper.toastMessage('Please accept terms and conditions'); + Helper.toastMessage( + AppLocalizations.of(context)!.acceptTermsAndConditions); return; } try { @@ -124,8 +145,8 @@ class _InspectionSummaryPageState extends State<InspectionSummaryPage> { }; final responseCode = await Provider.of<ApplicationRespository>(context, listen: false) - .submitInspection(Helper.isInternetConnected(_source), data); - if (responseCode != 0) { + .submitInspection(isInternetConnected, data); + if (responseCode == 200) { Navigator.of(context).pushReplacement(MaterialPageRoute( builder: (context) => const InspectionCompletedPage())); } else { @@ -148,7 +169,7 @@ class _InspectionSummaryPageState extends State<InspectionSummaryPage> { titleSpacing: 20, backgroundColor: Colors.white, title: Text( - 'Inspection Summary', + AppLocalizations.of(context)!.inspectionSummary, style: GoogleFonts.lato( color: AppColors.black87, fontSize: 16.0, diff --git a/lib/pages/login_email_page.dart b/lib/pages/login_email_page.dart index f4c1ba7e0b096e438f82e7eb7b0e10a24cf06b96..e0adf514bdfb0e9638a47c3a945505aabf8e9616 100644 --- a/lib/pages/login_email_page.dart +++ b/lib/pages/login_email_page.dart @@ -2,6 +2,7 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:otp_text_field/style.dart'; import 'package:provider/provider.dart'; +import 'package:smf_mobile/constants/app_constants.dart'; import 'package:smf_mobile/constants/app_urls.dart'; import 'package:smf_mobile/constants/color_constants.dart'; import 'package:google_fonts/google_fonts.dart'; @@ -14,6 +15,9 @@ import 'package:smf_mobile/util/helper.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:otp_text_field/otp_field.dart'; import 'package:unique_identifier/unique_identifier.dart'; +import 'dart:async'; +// import 'package:connectivity_plus/connectivity_plus.dart'; +// import 'package:smf_mobile/util/connectivity_helper.dart'; class LoginEmailPage extends StatefulWidget { static const route = AppUrl.loginEmailPage; @@ -26,6 +30,8 @@ class LoginEmailPage extends StatefulWidget { class _LoginEmailPageState extends State<LoginEmailPage> { final TextEditingController _emailController = TextEditingController(); final GlobalKey<ScaffoldState> _scaffoldKey = GlobalKey<ScaffoldState>(); + // Map _source = {ConnectivityResult.none: false}; + // final MyConnectivity _connectivity = MyConnectivity.instance; String _errorMessage = ''; late Locale locale; String _pin = ''; @@ -34,6 +40,14 @@ class _LoginEmailPageState extends State<LoginEmailPage> { @override void initState() { super.initState(); + // _connectivity.initialise(); + // _connectivity.myStream.listen((source) { + // if (mounted) { + // setState(() { + // _source = source; + // }); + // } + // }); initUniqueIdentifierState(); } @@ -78,16 +92,16 @@ class _LoginEmailPageState extends State<LoginEmailPage> { } Future<void> _validatePin() async { - print('_validatePin...'); - String pin = _pin; + bool isInternetConnected = await Helper.isInternetConnected(); + // await Future.delayed(const Duration(milliseconds: 10)); try { - Map pinDetails = await OfflineModel.getPinDetails(pin); - print(pinDetails); - if (pinDetails['username'] != null) { + Map pinDetails = await OfflineModel.getPinDetails(_pin); + // print(pinDetails); + if (isInternetConnected && pinDetails['username'] != null) { final responseCode = await Provider.of<LoginRespository>(context, listen: false) .validateOtp( - context, pinDetails['username'], '', _identifier, pin, false); + context, pinDetails['username'], '', _identifier, _pin, false); if (responseCode == 200) { Navigator.of(context).pushReplacement(MaterialPageRoute( builder: (context) => const HomePage(), @@ -97,6 +111,13 @@ class _LoginEmailPageState extends State<LoginEmailPage> { .errorMessage; Helper.toastMessage(_errorMessage); } + } else if (pinDetails['username'] != null) { + Helper.setUser(Storage.username, pinDetails['username']); + Helper.setUser(Storage.authtoken, ''); + Helper.toastMessage(AppLocalizations.of(context)!.youAreOffline); + Navigator.of(context).pushReplacement(MaterialPageRoute( + builder: (context) => const HomePage(), + )); } else { Helper.toastMessage(AppLocalizations.of(context)!.inValidPin); } @@ -107,6 +128,7 @@ class _LoginEmailPageState extends State<LoginEmailPage> { @override void dispose() { + // _connectivity.disposeStream(); super.dispose(); } @@ -337,27 +359,27 @@ class _LoginEmailPageState extends State<LoginEmailPage> { child: Divider( color: AppColors.black16, )), - InkWell( - onTap: () => Navigator.of(context) - .pushReplacement(MaterialPageRoute( - builder: (context) => const CreatePinPage(), - )), + Center( child: Container( - width: double.infinity, padding: const EdgeInsets.only( top: 10, ), - child: Text( - AppLocalizations.of(context)!.createPin, - textAlign: TextAlign.center, - style: GoogleFonts.lato( - color: AppColors.primaryBlue, - fontSize: 14, - letterSpacing: - 0.5 /*percentages not used in flutter. defaulting to zero*/, - fontWeight: FontWeight.w700, - height: 1.4), - )), + child: InkWell( + onTap: () => Navigator.of(context) + .pushReplacement(MaterialPageRoute( + builder: (context) => + const CreatePinPage(), + )), + child: Text( + AppLocalizations.of(context)!.createPin, + style: GoogleFonts.lato( + color: AppColors.primaryBlue, + fontSize: 14, + letterSpacing: + 0.5 /*percentages not used in flutter. defaulting to zero*/, + fontWeight: FontWeight.w700, + height: 1.4), + ))), ) ]), ) diff --git a/lib/repositories/application_repository.dart b/lib/repositories/application_repository.dart index d1d1fc7e2d1d9210f17906bf072dabf6ee503ea0..f0063a7f2556e981bbc82164b0286af7a1231ec6 100644 --- a/lib/repositories/application_repository.dart +++ b/lib/repositories/application_repository.dart @@ -13,18 +13,24 @@ class ApplicationRespository with ChangeNotifier { List<Application> _applications = []; String _errorMessage = ''; + void _saveApplications(String username, String applicationData) async { + Map<String, Object> data = { + 'username': username, + 'application_data': applicationData + }; + await OfflineModel.deleteApplications(username); + await OfflineModel.saveApplications(data); + } + Future<dynamic> getApplications(bool internetConnected) async { String username = await Helper.getUser(Storage.username); try { if (internetConnected) { final request = await ApplicationService.getApplications(); _data = json.decode(request.body); - Map<String, Object> data = { - 'username': username, - 'application_data': request.body - }; - await OfflineModel.deleteApplications(username); - await OfflineModel.saveApplications(data); + if (_data['statusInfo']['statusCode'] == 200) { + _saveApplications(username, request.body); + } } else { var applications = await OfflineModel.getApplications(username); _data = json.decode(applications['application_data']); @@ -51,6 +57,21 @@ class ApplicationRespository with ChangeNotifier { 'inspection_data': data }; await OfflineModel.saveInspection(applicationData); + + // Updating application status in the database + String username = await Helper.getUser(Storage.username); + var rawData = await OfflineModel.getForms(username); + Map applicationFieldData = json.decode(rawData['application_data']); + List applications = applicationFieldData['responseData']; + + for (int i = 0; i < applications.length; i++) { + if (applications[i]['applicationId'] == data['applicationId']) { + applications[i]['inspection']['status'] = + InspectionStatus.leadInspectorCompleted; + } + } + applicationFieldData['responseData'] = applications; + _saveApplications(username, jsonEncode(applicationFieldData)); } else { final request = await ApplicationService.submitInspection(data); _data = json.decode(request.body); @@ -67,11 +88,46 @@ class ApplicationRespository with ChangeNotifier { } else { statusCode = 200; } - // var tData = await OfflineModel.getInspections(); - // developer.log(tData.toString()); return statusCode; } + Future<dynamic> submitBulkInspection() async { + List<Map> inspections = []; + List<Map> consents = []; + Map data1 = {}, data2 = {}; + bool response = false; + try { + List<Map> rawInspections = await OfflineModel.getInspections(); + for (var inspection in rawInspections) { + if (inspection['inspector_type'] == Inspector.leadInspector) { + inspections.add(jsonDecode(inspection['inspection_data'])); + } else { + consents.add(jsonDecode(inspection['inspection_data'])); + } + } + if (inspections.isNotEmpty) { + final request1 = + await ApplicationService.submitBulkInspection(inspections); + data1 = json.decode(request1.body); + } + if (consents.isNotEmpty) { + final request2 = await ApplicationService.submitBulkConsent(consents); + data2 = json.decode(request2.body); + } + } catch (_) { + return _; + } + // if (data1['statusInfo']['statusCode'] != 200 || + // data2['statusInfo']['statusCode'] != 200) { + // _errorMessage = _data['statusInfo']['errorMessage']; + // } + if ((inspections.isNotEmpty && data1['statusInfo']['statusCode']) || + (consents.isNotEmpty && data2['statusInfo']['statusCode'])) { + response = true; + } + return response; + } + Future<dynamic> submitConcent(bool internetConnected, Map data) async { try { if (!internetConnected) { @@ -80,6 +136,20 @@ class ApplicationRespository with ChangeNotifier { 'inspection_data': data }; await OfflineModel.saveInspection(applicationData); + + // Updating application status in the database + String username = await Helper.getUser(Storage.username); + var rawData = await OfflineModel.getApplications(username); + Map applicationFieldData = json.decode(rawData['application_data']); + List applications = applicationFieldData['responseData']; + + for (int i = 0; i < applications.length; i++) { + if (applications[i]['applicationId'] == data['applicationId']) { + applications[i]['status'] = InspectionStatus.inspectionCompleted; + } + } + applicationFieldData['responseData'] = applications; + _saveApplications(username, jsonEncode(applicationFieldData)); } else { final request = await ApplicationService.submitConcent(data); _data = json.decode(request.body); diff --git a/lib/repositories/form_repository.dart b/lib/repositories/form_repository.dart index 9e469fa339c8929c01ffe8b640854358aa82d8c0..c95464435355b1825968d744b8905698c9e0c22f 100644 --- a/lib/repositories/form_repository.dart +++ b/lib/repositories/form_repository.dart @@ -1,7 +1,10 @@ import 'dart:convert'; import 'package:flutter/widgets.dart'; +import 'package:smf_mobile/constants/app_constants.dart'; +import 'package:smf_mobile/database/offline_model.dart'; import 'package:smf_mobile/services/form_service.dart'; import 'package:smf_mobile/models/form_model.dart'; +import 'package:smf_mobile/util/helper.dart'; // import 'dart:developer' as developer; class FormRespository with ChangeNotifier { @@ -9,17 +12,67 @@ class FormRespository with ChangeNotifier { late FormData _formData; String _errorMessage = ''; - Future<dynamic> getFormDetails(int formId) async { + Future<dynamic> getAllForms() async { + List forms = []; try { - final request = await FormService.getFormDetails(formId); + String username = await Helper.getUser(Storage.username); + final request = await FormService.getAllForms(); _data = json.decode(request.body); + if (_data['statusInfo']['statusCode'] == 200) { + Map<String, Object> data = { + 'username': username, + 'form_data': request.body + }; + await OfflineModel.deleteForms(username); + await OfflineModel.saveForms(data); + // Map<dynamic, dynamic> _forms = await OfflineModel.getForms(username); + // print(request.body); + } } catch (_) { return _; } if (_data['statusInfo']['statusCode'] != 200) { _errorMessage = _data['statusInfo']['errorMessage']; } else { - _formData = FormData.fromJson(_data['responseData']); + forms = _data['responseData']; + } + return forms; + } + + // Future<dynamic> getFormDetails(int formId) async { + // try { + // final request = await FormService.getFormDetails(formId); + // _data = json.decode(request.body); + // } catch (_) { + // return _; + // } + // if (_data['statusInfo']['statusCode'] != 200) { + // _errorMessage = _data['statusInfo']['errorMessage']; + // } else { + // _formData = FormData.fromJson(_data['responseData']); + // } + // return _formData; + // } + + Future<dynamic> getFormDetails(int formId) async { + Map<String, dynamic> formDetails = {}; + try { + String username = await Helper.getUser(Storage.username); + var rawData = await OfflineModel.getForms(username); + Map formData = json.decode(rawData['form_data']); + List forms = formData['responseData']; + for (var form in forms) { + if (form['id'] == formId) { + formDetails = form; + } + } + } catch (_) { + return _; + } + // print(formId); + // print(formDetails); + if (formDetails.isNotEmpty) { + _formData = FormData.fromJson(formDetails); } return _formData; } diff --git a/lib/repositories/login_repository.dart b/lib/repositories/login_repository.dart index dd1adc36c81d263c8c18d558906e091721076abf..c7eecafd5b73b155bea02f5687058fffc491dde2 100644 --- a/lib/repositories/login_repository.dart +++ b/lib/repositories/login_repository.dart @@ -48,7 +48,6 @@ class LoginRespository with ChangeNotifier { Future<dynamic> validateOtp(context, String username, String otp, String identifier, String pin, bool isOtp) async { - print('res validateOtp'); try { Map requestData = {}; if (isOtp) { @@ -83,7 +82,7 @@ class LoginRespository with ChangeNotifier { _data = json.decode(request.body); // print(_data); if (_data['statusInfo']['statusCode'] == 200) { - print('_configureMessaging...'); + // print('_configureMessaging...'); _configureMessaging(context); } }); diff --git a/lib/services/application_service.dart b/lib/services/application_service.dart index a1663dd57ab36bc0db1dd8b5d1b9052dc0cfe661..dc1be0cda39d4f4d94fb5ab2dbbbd56b763fb06a 100644 --- a/lib/services/application_service.dart +++ b/lib/services/application_service.dart @@ -4,7 +4,7 @@ import 'package:http/http.dart' as http; import 'package:smf_mobile/constants/api_endpoints.dart'; import 'package:smf_mobile/constants/app_constants.dart'; import 'package:smf_mobile/services/base_service.dart'; -import 'dart:developer' as developer; +// import 'dart:developer' as developer; class ApplicationService extends BaseService { ApplicationService(HttpClient client) : super(client); @@ -32,15 +32,39 @@ class ApplicationService extends BaseService { return response; } + static Future<dynamic> submitBulkInspection(List data) async { + var body = json.encode(data); + Map<String, String> headers = await BaseService.getHeaders(); + + final response = await http.post(Uri.parse(ApiUrl.submitBulkInspection), + headers: headers, body: body); + // developer.log(ApiUrl.submitInspection); + // developer.log(body); + // developer.log(response.body); + return response; + } + static Future<dynamic> submitConcent(Map data) async { var body = json.encode(data); Map<String, String> headers = await BaseService.getHeaders(); final response = await http.post(Uri.parse(ApiUrl.submitConcent), headers: headers, body: body); - developer.log(ApiUrl.submitConcent); - developer.log(body); - developer.log(response.body); + // developer.log(ApiUrl.submitConcent); + // developer.log(body); + // developer.log(response.body); + return response; + } + + static Future<dynamic> submitBulkConsent(List data) async { + var body = json.encode(data); + Map<String, String> headers = await BaseService.getHeaders(); + + final response = await http.post(Uri.parse(ApiUrl.submitBulkConcent), + headers: headers, body: body); + // developer.log(ApiUrl.submitInspection); + // developer.log(body); + // developer.log(response.body); return response; } } diff --git a/lib/services/form_service.dart b/lib/services/form_service.dart index 7e1fc27211ab2451071451d91083965372846f36..a408c986462982501d8764d485d7298780c1ce47 100644 --- a/lib/services/form_service.dart +++ b/lib/services/form_service.dart @@ -7,6 +7,15 @@ import 'package:smf_mobile/services/base_service.dart'; class FormService extends BaseService { FormService(HttpClient client) : super(client); + static Future<dynamic> getAllForms() async { + Map<String, String> headers = await BaseService.getHeaders(); + + final response = + await http.get(Uri.parse(ApiUrl.getAllForms), headers: headers); + // developer.log(response.body); + return response; + } + static Future<dynamic> getFormDetails(int formId) async { Map<String, String> headers = await BaseService.getHeaders(); diff --git a/lib/util/connectivity_helper.dart b/lib/util/connectivity_helper.dart index 5704601cb1fd1070c4e9bad652f84411a5c4fb3c..55f6d6ae8df82022ecbc767c136c5e32c50add33 100644 --- a/lib/util/connectivity_helper.dart +++ b/lib/util/connectivity_helper.dart @@ -28,7 +28,11 @@ class MyConnectivity { } on SocketException catch (_) { isOnline = false; } - _controller.sink.add({result: isOnline}); + try { + _controller.sink.add({result: isOnline}); + } catch (_) { + return; + } } void disposeStream() => _controller.close(); diff --git a/lib/util/helper.dart b/lib/util/helper.dart index 65afc9619cb61796bdc1c5009667f53cf96769e8..dc161fae39377eb725d54ac9388a57b89f7368a9 100644 --- a/lib/util/helper.dart +++ b/lib/util/helper.dart @@ -1,5 +1,6 @@ import 'dart:math'; -import 'package:connectivity_plus/connectivity_plus.dart'; +import 'dart:io'; +// import 'package:connectivity_plus/connectivity_plus.dart'; import 'package:flutter/material.dart'; import 'package:fluttertoast/fluttertoast.dart'; import 'package:intl/intl.dart'; @@ -28,6 +29,10 @@ class Helper { return value; } + static Future<void> setUser(String key, String value) async { + _storage.write(key: key, value: value); + } + static int getDateDiffence(DateTime today, DateTime dateTimeCreatedAt) { // print('$today, $dateTimeCreatedAt'); // String month = today.month < 10 ? '0${today.month}' : '${today.month}'; @@ -39,7 +44,7 @@ class Helper { static Future<bool> isTokenExpired() async { bool isTokenExpired = true; var authToken = await _storage.read(key: Storage.authtoken); - if (authToken != null) { + if (authToken != null && authToken != '') { isTokenExpired = JwtDecoder.isExpired(authToken); } return isTokenExpired; @@ -95,22 +100,33 @@ class Helper { return _inspectionStatus; } - static bool isInternetConnected(source) { - bool connected; - switch (source.keys.toList()[0]) { - case ConnectivityResult.mobile: - // print('connected to mobile...'); - connected = true; - break; - case ConnectivityResult.wifi: - // print('connected to wifi...'); - connected = true; - break; - case ConnectivityResult.none: - default: - // print('offline...'); - connected = false; + // static bool isInternetConnected(source) { + // bool connected; + // switch (source.keys.toList()[0]) { + // case ConnectivityResult.mobile: + // print('connected to mobile...'); + // connected = true; + // break; + // case ConnectivityResult.wifi: + // print('connected to wifi...'); + // connected = true; + // break; + // case ConnectivityResult.none: + // default: + // print('offline mode...'); + // connected = false; + // } + // return connected; + // } + + static Future<bool> isInternetConnected() async { + bool _isConnectionSuccessful; + try { + final response = await InternetAddress.lookup('www.google.com'); + _isConnectionSuccessful = response.isNotEmpty; + } on SocketException catch (e) { + _isConnectionSuccessful = false; } - return connected; + return _isConnectionSuccessful; } } diff --git a/lib/util/notification_helper.dart b/lib/util/notification_helper.dart index fbee26f83fb51801a23896459e51503f7257cb53..95aea227620a13eed603fdb1d394446bd8115e8e 100644 --- a/lib/util/notification_helper.dart +++ b/lib/util/notification_helper.dart @@ -43,7 +43,7 @@ class NotificationHelper { enableLights: true, playSound: true, // sound: RawResourceAndroidNotificationSound('mixkit_happy_bell'), - // largeIcon: DrawableResourceAndroidBitmap('flutter_devs'), + largeIcon: DrawableResourceAndroidBitmap('flutter_devs'), styleInformation: BigTextStyleInformation(''), ); diff --git a/lib/widgets/lead_inspector_application_field.dart b/lib/widgets/lead_inspector_application_field.dart index c7549e691026114519b914ec42a946bb71b60231..d6f70404e52fcda591d167b48a357013a53e555e 100644 --- a/lib/widgets/lead_inspector_application_field.dart +++ b/lib/widgets/lead_inspector_application_field.dart @@ -284,16 +284,21 @@ class _LeadInspectorApplicationFieldState _displayCommentDialog(); } }, - icon: - _radioValue != FieldValue.correct - ? const Icon( - Icons.edit, - color: AppColors.black40, - ) - : const Icon( - Icons.message, - color: AppColors.black40, - ), + icon: _radioValue != + FieldValue.correct && + widget.applicationStatus != + InspectionStatus + .inspectionCompleted && + widget.applicationStatus != + InspectionStatus.approved + ? const Icon( + Icons.edit, + color: AppColors.black40, + ) + : const Icon( + Icons.message, + color: AppColors.black40, + ), ), ) ], diff --git a/pubspec.lock b/pubspec.lock index 4816bf3640122e8b37dbc2592cbe2e8a474edd75..0de1cc52d77e7e4750b37dc6f65533e0d30b6139 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -36,6 +36,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "2.1.0" + change_app_package_name: + dependency: "direct main" + description: + name: change_app_package_name + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.0" characters: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 206d2b94fb1b89906ca8e82c2f08e2f4faf13842..28443e29e6cf0edfeef25c5fdde67039b79ae7d1 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -50,6 +50,7 @@ dependencies: unique_identifier: ^0.2.2 sqflite: ^2.0.2 connectivity_plus: ^2.2.1 + change_app_package_name: ^1.0.0 dev_dependencies: flutter_test: