From e76c4a66434578a0d62658c3953bc40e3a89c175 Mon Sep 17 00:00:00 2001
From: shoaib-mohmad <shoaib.mohmad@tarento.com>
Date: Tue, 29 Mar 2022 17:45:30 +0530
Subject: [PATCH] Completed attachment support in offline mode.

---
 lib/constants/app_constants.dart              |   1 +
 lib/database/offline_model.dart               |  30 ++++
 lib/l10n/app_en.arb                           |   5 +-
 lib/models/application_model.dart             |  12 +-
 lib/pages/application_details_page.dart       | 145 +++++++++++------
 lib/pages/attachment_viewer.dart              |  52 ++++++
 lib/pages/home_page.dart                      |   1 +
 lib/pages/inspection_summary.dart             |   1 -
 lib/pages/login_email_page.dart               |  16 +-
 lib/repositories/application_repository.dart  |  35 ++--
 lib/repositories/form_repository.dart         |   1 +
 lib/services/application_service.dart         |   4 +-
 lib/widgets/application_card.dart             |  32 ++--
 ...assistant_inspector_application_field.dart | 152 +++++++++++++++---
 .../lead_inspector_application_field.dart     | 128 ++++++++++-----
 15 files changed, 467 insertions(+), 148 deletions(-)
 create mode 100644 lib/pages/attachment_viewer.dart

diff --git a/lib/constants/app_constants.dart b/lib/constants/app_constants.dart
index 743a3a8..34c32dc 100644
--- a/lib/constants/app_constants.dart
+++ b/lib/constants/app_constants.dart
@@ -41,6 +41,7 @@ class AppDatabase {
   static const String formsTable = 'forms';
   static const String inspectionTable = 'inspections';
   static const String loginPinsTable = 'login_pins';
+  static const String attachmentsTable = 'attachments';
 }
 
 class Storage {
diff --git a/lib/database/offline_model.dart b/lib/database/offline_model.dart
index 666f3da..9c73202 100644
--- a/lib/database/offline_model.dart
+++ b/lib/database/offline_model.dart
@@ -12,6 +12,7 @@ class OfflineModel {
       const String formsTable = AppDatabase.formsTable;
       const String inspectionTable = AppDatabase.inspectionTable;
       const String loginPinsTable = AppDatabase.loginPinsTable;
+      const String attachmentsTable = AppDatabase.attachmentsTable;
 
       await db.execute('''CREATE TABLE $applicationsTable (
             id INTEGER PRIMARY KEY AUTOINCREMENT,
@@ -33,6 +34,11 @@ class OfflineModel {
             username VARCHAR(64),
             pin VARCHAR(4)
             )''');
+      await db.execute('''CREATE TABLE $attachmentsTable (
+            id INTEGER PRIMARY KEY AUTOINCREMENT,
+            application_id VARCHAR(64),
+            attachment VARCHAR(512)
+            )''');
     }, version: 1);
   }
 
@@ -132,4 +138,28 @@ class OfflineModel {
         whereArgs: whereArgs);
     return rows.isNotEmpty ? rows[0] : {};
   }
+
+  static Future<void> saveAttachment(Map<String, Object> data) async {
+    final db = await OfflineModel.database();
+    db.insert(
+      AppDatabase.attachmentsTable,
+      data,
+      conflictAlgorithm: ConflictAlgorithm.replace,
+    );
+  }
+
+  static Future<List<Map>> getAttachments(String applicationId) async {
+    final db = await OfflineModel.database();
+    List<dynamic> whereArgs = [applicationId];
+    List<Map> rows = await db.query(AppDatabase.attachmentsTable,
+        where: 'application_id = ?', orderBy: 'id DESC', whereArgs: whereArgs);
+    return rows;
+  }
+
+  static Future<void> deleteAttachments(String applicationId) async {
+    Database db = await OfflineModel.database();
+    List<dynamic> whereArgs = [applicationId];
+    await db.delete(AppDatabase.attachmentsTable,
+        where: 'application_id = ?', whereArgs: whereArgs);
+  }
 }
diff --git a/lib/l10n/app_en.arb b/lib/l10n/app_en.arb
index 4904b68..7e68b32 100644
--- a/lib/l10n/app_en.arb
+++ b/lib/l10n/app_en.arb
@@ -32,7 +32,7 @@
     "pastApplications": "Past applications",
     "viewPastApplications": "View past applications",
     "next": "Next",
-    "previous": "previous",
+    "previous": "Previous",
     "inspectionCompleted": "Inspection completed",
     "leadInspectorCompleted": "Lead inspector completed",
     "completed": "Completed",
@@ -66,5 +66,6 @@
     "fileViewer": "File viewer",
     "preview": "Preview",
     "remove": "Remove",
-    "attachment": "Attachment"
+    "attachment": "Attachment",
+    "version": "Version"
 }
\ No newline at end of file
diff --git a/lib/models/application_model.dart b/lib/models/application_model.dart
index c1f8cca..305ca68 100644
--- a/lib/models/application_model.dart
+++ b/lib/models/application_model.dart
@@ -39,14 +39,18 @@ class Application {
       email: json['email'] ?? '',
       status: json['status'],
       dataObject: json['dataObject'],
-      inspectors: json['inspection']['assignedTo'] ?? [],
-      leadInspector: json['inspection']['leadInspector'] ?? [],
+      inspectors:
+          json['inspection'] != null ? json['inspection']['assignedTo'] : [],
+      leadInspector:
+          json['inspection'] != null ? json['inspection']['leadInspector'] : [],
       inspectorDataObject: json['inspectorDataObject'] != null
           ? json['inspectorDataObject']['dataObject']
           : {},
       inspectorSummaryDataObject: json['inspectorSummaryDataObject'] ?? {},
-      inspectionStatus: json['inspection']['status'] ?? '',
-      scheduledDate: json['inspection']['scheduledDate'] ?? '',
+      inspectionStatus:
+          json['inspection'] != null ? json['inspection']['status'] : '',
+      scheduledDate:
+          json['inspection'] != null ? json['inspection']['scheduledDate'] : '',
       createdDate: json['createdDate'],
       createdBy: json['createdBy'],
     );
diff --git a/lib/pages/application_details_page.dart b/lib/pages/application_details_page.dart
index e240dc6..431340a 100644
--- a/lib/pages/application_details_page.dart
+++ b/lib/pages/application_details_page.dart
@@ -583,52 +583,71 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage>
                                                         CrossAxisAlignment
                                                             .start,
                                                     children: [
-                                                      Padding(
-                                                        padding:
-                                                            const EdgeInsets
-                                                                .only(top: 5),
-                                                        child: Text(
-                                                          AppLocalizations.of(
-                                                                  context)!
-                                                              .inspectionSummary,
-                                                          style:
-                                                              GoogleFonts.lato(
-                                                            color: AppColors
-                                                                .black87,
-                                                            fontSize: 14.0,
-                                                            letterSpacing: 0.25,
-                                                            fontWeight:
-                                                                FontWeight.w700,
-                                                          ),
-                                                        ),
-                                                      ),
-                                                      Container(
-                                                        margin: const EdgeInsets
-                                                            .only(top: 10),
-                                                        padding:
-                                                            const EdgeInsets
-                                                                    .fromLTRB(
-                                                                15, 10, 15, 10),
-                                                        width: double.infinity,
-                                                        decoration:
-                                                            BoxDecoration(
-                                                          border: Border.all(
-                                                              color: AppColors
-                                                                  .black16),
-                                                        ),
-                                                        child: Text(
-                                                          _inspectionSummary,
-                                                          style:
-                                                              GoogleFonts.lato(
-                                                            color: AppColors
-                                                                .black87,
-                                                            fontSize: 14.0,
-                                                            letterSpacing: 0.25,
-                                                            fontWeight:
-                                                                FontWeight.w400,
-                                                          ),
-                                                        ),
-                                                      ),
+                                                      _inspectionSummary != ''
+                                                          ? Padding(
+                                                              padding:
+                                                                  const EdgeInsets
+                                                                          .only(
+                                                                      top: 5),
+                                                              child: Text(
+                                                                AppLocalizations.of(
+                                                                        context)!
+                                                                    .inspectionSummary,
+                                                                style:
+                                                                    GoogleFonts
+                                                                        .lato(
+                                                                  color: AppColors
+                                                                      .black87,
+                                                                  fontSize:
+                                                                      14.0,
+                                                                  letterSpacing:
+                                                                      0.25,
+                                                                  fontWeight:
+                                                                      FontWeight
+                                                                          .w700,
+                                                                ),
+                                                              ),
+                                                            )
+                                                          : const Center(),
+                                                      _inspectionSummary != ''
+                                                          ? Container(
+                                                              margin:
+                                                                  const EdgeInsets
+                                                                          .only(
+                                                                      top: 10),
+                                                              padding:
+                                                                  const EdgeInsets
+                                                                          .fromLTRB(
+                                                                      15,
+                                                                      10,
+                                                                      15,
+                                                                      10),
+                                                              width: double
+                                                                  .infinity,
+                                                              decoration:
+                                                                  BoxDecoration(
+                                                                border: Border.all(
+                                                                    color: AppColors
+                                                                        .black16),
+                                                              ),
+                                                              child: Text(
+                                                                _inspectionSummary,
+                                                                style:
+                                                                    GoogleFonts
+                                                                        .lato(
+                                                                  color: AppColors
+                                                                      .black87,
+                                                                  fontSize:
+                                                                      14.0,
+                                                                  letterSpacing:
+                                                                      0.25,
+                                                                  fontWeight:
+                                                                      FontWeight
+                                                                          .w400,
+                                                                ),
+                                                              ),
+                                                            )
+                                                          : const Center(),
                                                       _leadInspectorId != 0
                                                           ? Container(
                                                               margin: const EdgeInsets
@@ -717,6 +736,9 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage>
                                           itemBuilder: (context, i) {
                                             return _isleadInspector
                                                 ? LeadInspectorApplicationField(
+                                                    applicationId: widget
+                                                        .application
+                                                        .applicationId,
                                                     fieldName:
                                                         field.keys.elementAt(i),
                                                     fieldData: field[field.keys
@@ -739,14 +761,25 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage>
                                                     parentAction: updateField,
                                                   )
                                                 : widget.application.status ==
-                                                        InspectionStatus
-                                                            .inspectionCompleted
+                                                            InspectionStatus
+                                                                .inspectionCompleted ||
+                                                        widget.application
+                                                                .status ==
+                                                            InspectionStatus
+                                                                .approved ||
+                                                        widget.application
+                                                                .inspectionStatus ==
+                                                            InspectionStatus
+                                                                .leadInspectorCompleted
                                                     ? AssistantInspectorApplicationField(
                                                         fieldName: field.keys
                                                             .elementAt(i),
                                                         fieldData: field[field
                                                             .keys
                                                             .elementAt(i)],
+                                                        fieldType: _fieldTypes[
+                                                            field.keys
+                                                                .elementAt(i)],
                                                         leadInspectorData:
                                                             _leadInspectorFields[
                                                                 _leadInspectorFields
@@ -785,7 +818,9 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage>
                 ),
               ),
               child: Column(children: [
-                !_isleadInspector
+                !_isleadInspector &&
+                        widget.application.inspectionStatus ==
+                            InspectionStatus.leadInspectorCompleted
                     ? Row(
                         mainAxisAlignment: MainAxisAlignment.center,
                         children: [
@@ -978,7 +1013,8 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage>
                                   )
                                 ],
                               ))
-                          : (widget.application.status !=
+                          : (_isleadInspector &&
+                                      widget.application.status !=
                                           InspectionStatus
                                               .inspectionCompleted &&
                                       widget.application.inspectionStatus !=
@@ -986,9 +1022,12 @@ class _ApplicationDetailsPageState extends State<ApplicationDetailsPage>
                                               .leadInspectorCompleted &&
                                       widget.application.status !=
                                           InspectionStatus.approved) ||
-                                  (widget.application.status ==
-                                          InspectionStatus.sentForInspection &&
-                                      !_isleadInspector)
+                                  (widget.application.inspectionStatus ==
+                                          InspectionStatus
+                                              .leadInspectorCompleted &&
+                                      !_isleadInspector &&
+                                      widget.application.status !=
+                                          InspectionStatus.inspectionCompleted)
                               ? TextButton(
                                   onPressed: () {
                                     _submitInspection();
diff --git a/lib/pages/attachment_viewer.dart b/lib/pages/attachment_viewer.dart
new file mode 100644
index 0000000..2e995dd
--- /dev/null
+++ b/lib/pages/attachment_viewer.dart
@@ -0,0 +1,52 @@
+import 'dart:io';
+
+import 'package:flutter/material.dart';
+import 'package:google_fonts/google_fonts.dart';
+import 'package:smf_mobile/constants/color_constants.dart';
+import 'package:flutter_gen/gen_l10n/app_localizations.dart';
+import 'package:webview_flutter/webview_flutter.dart';
+import 'dart:async';
+
+class AttachmentViewer extends StatefulWidget {
+  final String fileUrl;
+  const AttachmentViewer({Key? key, required this.fileUrl}) : super(key: key);
+  @override
+  _AttachmentViewerState createState() => _AttachmentViewerState();
+}
+
+class _AttachmentViewerState extends State<AttachmentViewer> {
+  final Completer<WebViewController> _controller =
+      Completer<WebViewController>();
+  late String _fileUrl;
+  bool _isLoading = true;
+  @override
+  void initState() {
+    super.initState();
+  }
+
+  @override
+  Widget build(BuildContext context) {
+    return Scaffold(
+        appBar: AppBar(
+          titleSpacing: 10,
+          elevation: 0,
+          backgroundColor: Colors.white,
+          leading: const BackButton(color: AppColors.black60),
+          title: Text(
+            AppLocalizations.of(context)!.fileViewer,
+            style: GoogleFonts.lato(
+              color: AppColors.black87,
+              fontSize: 16.0,
+              letterSpacing: 0.12,
+              fontWeight: FontWeight.w600,
+            ),
+          ),
+          // centerTitle: true,
+        ),
+        // Tab controller
+        body: Container(
+            color: AppColors.scaffoldBackground,
+            height: MediaQuery.of(context).size.height,
+            child: Image.file(File(widget.fileUrl))));
+  }
+}
diff --git a/lib/pages/home_page.dart b/lib/pages/home_page.dart
index 971ee17..05c79cc 100644
--- a/lib/pages/home_page.dart
+++ b/lib/pages/home_page.dart
@@ -112,6 +112,7 @@ class _HomePageState extends State<HomePage> with WidgetsBindingObserver {
   }
 
   Future<dynamic> _syncApplications() async {
+    // print('_syncApplications...');
     var synced =
         await Provider.of<ApplicationRespository>(context, listen: false)
             .submitBulkInspection();
diff --git a/lib/pages/inspection_summary.dart b/lib/pages/inspection_summary.dart
index 2343f02..3ef74b9 100644
--- a/lib/pages/inspection_summary.dart
+++ b/lib/pages/inspection_summary.dart
@@ -146,7 +146,6 @@ class _InspectionSummaryPageState extends State<InspectionSummaryPage> {
       final responseCode =
           await Provider.of<ApplicationRespository>(context, listen: false)
               .submitInspection(isInternetConnected, data);
-      // print(responseCode.toString());
       if (responseCode == 200) {
         Navigator.of(context).pushReplacement(MaterialPageRoute(
             builder: (context) => const InspectionCompletedPage()));
diff --git a/lib/pages/login_email_page.dart b/lib/pages/login_email_page.dart
index 4970319..c1271b2 100644
--- a/lib/pages/login_email_page.dart
+++ b/lib/pages/login_email_page.dart
@@ -1,6 +1,7 @@
 import 'package:flutter/material.dart';
 import 'package:flutter/services.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';
@@ -10,7 +11,7 @@ import 'package:smf_mobile/pages/login_pin_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:unique_identifier/unique_identifier.dart';
+// import 'package:unique_identifier/unique_identifier.dart';
 import 'dart:async';
 import 'package:email_validator/email_validator.dart';
 
@@ -256,6 +257,19 @@ class _LoginEmailPageState extends State<LoginEmailPage> {
                           ),
                         ]),
                   ),
+                  Padding(
+                    padding: const EdgeInsets.only(top: 10, bottom: 20),
+                    child: Text(
+                      AppLocalizations.of(context)!.version + ' ' + appVersion,
+                      style: GoogleFonts.lato(
+                          color: AppColors.black87,
+                          fontSize: 12,
+                          letterSpacing:
+                              0.25 /*percentages not used in flutter. defaulting to zero*/,
+                          fontWeight: FontWeight.w700,
+                          height: 1.4),
+                    ),
+                  ),
                   const Spacer(),
                   Column(
                     children: [
diff --git a/lib/repositories/application_repository.dart b/lib/repositories/application_repository.dart
index 16914e3..e157ee3 100644
--- a/lib/repositories/application_repository.dart
+++ b/lib/repositories/application_repository.dart
@@ -54,16 +54,15 @@ class ApplicationRespository with ChangeNotifier {
       if (!internetConnected) {
         Map<String, Object> applicationData = {
           'inspector_type': Inspector.leadInspector,
-          'inspection_data': data
+          'inspection_data': json.encode(data)
         };
         await OfflineModel.saveInspection(applicationData);
 
         // Updating application status in the database
         String username = await Helper.getUser(Storage.username);
-        var rawData = await OfflineModel.getForms(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]['inspection']['status'] =
@@ -71,6 +70,7 @@ class ApplicationRespository with ChangeNotifier {
             applications[i]['inspectorDataObject'] = data;
           }
         }
+
         applicationFieldData['responseData'] = applications;
         _saveApplications(username, jsonEncode(applicationFieldData));
       } else {
@@ -97,13 +97,24 @@ class ApplicationRespository with ChangeNotifier {
     List<Map> consents = [];
     Map data1 = {}, data2 = {};
     bool response = false;
+    List<Map> attachments = [];
     try {
       List<Map> rawInspections = await OfflineModel.getInspections();
       for (var inspection in rawInspections) {
+        Map inspectionData = jsonDecode(inspection['inspection_data']);
+        attachments =
+            await OfflineModel.getAttachments(inspectionData['applicationId']);
+        for (var attachment in attachments) {
+          String temp = json.encode(inspectionData);
+          String fileUrl =
+              await ApplicationService.uploadImage(attachment['attachment']);
+          temp = temp.replaceAll(attachment['attachment'], fileUrl);
+          inspectionData = json.decode(temp);
+        }
         if (inspection['inspector_type'] == Inspector.leadInspector) {
-          inspections.add(jsonDecode(inspection['inspection_data']));
+          inspections.add(inspectionData);
         } else {
-          consents.add(jsonDecode(inspection['inspection_data']));
+          consents.add(inspectionData);
         }
       }
       if (inspections.isNotEmpty) {
@@ -116,14 +127,18 @@ class ApplicationRespository with ChangeNotifier {
         data2 = json.decode(request2.body);
       }
     } catch (_) {
-      return _;
+      return false;
+    }
+    if (data1['statusInfo']['statusCode'] != 200 ||
+        data2['statusInfo']['statusCode'] != 200) {
+      _errorMessage = _data['statusInfo']['errorMessage'];
     }
-    // if (data1['statusInfo']['statusCode'] != 200 ||
-    //     data2['statusInfo']['statusCode'] != 200) {
-    //   _errorMessage = _data['statusInfo']['errorMessage'];
-    // }
     if ((inspections.isNotEmpty && data1['statusInfo']['statusCode']) ||
         (consents.isNotEmpty && data2['statusInfo']['statusCode'])) {
+      for (var attachment in attachments) {
+        await OfflineModel.deleteAttachments(attachment['attachment']);
+      }
+      await OfflineModel.deleteInspections();
       response = true;
     }
     return response;
diff --git a/lib/repositories/form_repository.dart b/lib/repositories/form_repository.dart
index bcd60d2..2102a41 100644
--- a/lib/repositories/form_repository.dart
+++ b/lib/repositories/form_repository.dart
@@ -69,6 +69,7 @@ class FormRespository with ChangeNotifier {
       if (formDetails['id'] == null) {
         return;
       }
+      // print(formDetails);
     } catch (_) {
       return _;
     }
diff --git a/lib/services/application_service.dart b/lib/services/application_service.dart
index ae76d92..8690c02 100644
--- a/lib/services/application_service.dart
+++ b/lib/services/application_service.dart
@@ -1,12 +1,12 @@
 import 'dart:convert';
 import 'dart:io';
 import 'package:dio/dio.dart';
-import 'package:dio/adapter.dart';
+// import 'package:dio/adapter.dart';
 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);
diff --git a/lib/widgets/application_card.dart b/lib/widgets/application_card.dart
index 31b865f..739c38c 100644
--- a/lib/widgets/application_card.dart
+++ b/lib/widgets/application_card.dart
@@ -24,29 +24,31 @@ class _ApplicationCardState extends State<ApplicationCard> {
     super.initState();
   }
 
-  String _getApplicationStatus(String inspetionStatus, String actualStatus) {
-    String status = '';
-    if (actualStatus == InspectionStatus.inspectionCompleted) {
-      status = InspectionStatus.inspectionCompleted;
-    }
-    if (inspetionStatus == InspectionStatus.leadInspectorCompleted) {
-      status = InspectionStatus.leadInspectorCompleted;
-    } else {
-      status = actualStatus;
-    }
-    return status;
-  }
+  // String _getApplicationStatus(String inspetionStatus, String actualStatus) {
+  //   String status = '';
+  //   if (actualStatus == InspectionStatus.inspectionCompleted) {
+  //     status = InspectionStatus.inspectionCompleted;
+  //   }
+  //   if (inspetionStatus == InspectionStatus.leadInspectorCompleted) {
+  //     status = InspectionStatus.leadInspectorCompleted;
+  //   } else {
+  //     status = actualStatus;
+  //   }
+  //   return status;
+  // }
 
   @override
   Widget build(BuildContext context) {
     return InkWell(
-        onTap: () => Navigator.push(
+        onTap: () {
+          // print(widget.application.inspectionStatus);
+          Navigator.push(
               context,
               MaterialPageRoute(
                   builder: (context) => ApplicationDetailsPage(
                         application: widget.application,
-                      )),
-            ),
+                      )));
+        },
         child: Container(
           width: double.infinity,
           margin: const EdgeInsets.only(bottom: 10),
diff --git a/lib/widgets/assistant_inspector_application_field.dart b/lib/widgets/assistant_inspector_application_field.dart
index 473781f..6380ec1 100644
--- a/lib/widgets/assistant_inspector_application_field.dart
+++ b/lib/widgets/assistant_inspector_application_field.dart
@@ -3,17 +3,20 @@ import 'package:google_fonts/google_fonts.dart';
 import 'package:smf_mobile/constants/app_constants.dart';
 import 'package:smf_mobile/constants/color_constants.dart';
 import 'package:flutter_gen/gen_l10n/app_localizations.dart';
+import 'package:smf_mobile/pages/file_viewer.dart';
 import 'package:smf_mobile/util/helper.dart';
 
 class AssistantInspectorApplicationField extends StatefulWidget {
   final String fieldName;
   final Map fieldData;
+  final String fieldType;
   final Map leadInspectorData;
   final ValueChanged<Map> parentAction;
   const AssistantInspectorApplicationField({
     Key? key,
     required this.fieldName,
     required this.fieldData,
+    required this.fieldType,
     required this.leadInspectorData,
     required this.parentAction,
   }) : super(key: key);
@@ -29,13 +32,27 @@ class _AssistantInspectorApplicationFieldState
   String _inspectionComment = '';
   String _attachment = '';
   String _noteText = '';
+  final List<String> _imageExtensions = [
+    'apng',
+    'png',
+    'jpg',
+    'jpeg',
+    'avif',
+    'gif',
+    'svg'
+  ];
 
   @override
   void initState() {
     super.initState();
+    // print(widget.leadInspectorData['value']);
+
+    _radioValue = widget.leadInspectorData['value'] == null ||
+            widget.leadInspectorData['value'] == ''
+        ? FieldValue.correct
+        : widget.leadInspectorData['value'];
     try {
       _inspectionComment = widget.leadInspectorData['comments'];
-      _radioValue = widget.leadInspectorData['value'];
       _inspectionValue = widget.leadInspectorData['inspectionValue'];
       _attachment = widget.leadInspectorData['attachment'];
     } catch (_) {
@@ -62,6 +79,31 @@ class _AssistantInspectorApplicationFieldState
     widget.parentAction(data);
   }
 
+  void _viewFile(String fileUrl) {
+    String extension = fileUrl.split('.').last.toLowerCase();
+    if (_imageExtensions.contains(extension) || extension == FieldType.pdf) {
+      Navigator.push(
+        context,
+        MaterialPageRoute(
+            builder: (context) => FileViewer(
+                  fileType: extension == FieldType.pdf
+                      ? FieldType.pdf
+                      : FieldType.image,
+                  fileUrl: fileUrl,
+                )),
+      );
+    } else {
+      Navigator.push(
+        context,
+        MaterialPageRoute(
+            builder: (context) => FileViewer(
+                  fileType: '',
+                  fileUrl: fileUrl,
+                )),
+      );
+    }
+  }
+
   @override
   Widget build(BuildContext context) {
     return SingleChildScrollView(
@@ -105,22 +147,44 @@ class _AssistantInspectorApplicationFieldState
                           ),
                         ),
                         Container(
-                          margin: const EdgeInsets.only(top: 10),
-                          padding: const EdgeInsets.fromLTRB(15, 10, 15, 10),
-                          width: double.infinity,
-                          decoration: BoxDecoration(
-                            border: Border.all(color: AppColors.black16),
-                          ),
-                          child: Text(
-                            widget.fieldData.keys.elementAt(0),
-                            style: GoogleFonts.lato(
-                              color: AppColors.black87,
-                              fontSize: 14.0,
-                              letterSpacing: 0.25,
-                              fontWeight: FontWeight.w400,
+                            margin: const EdgeInsets.only(top: 10),
+                            padding: const EdgeInsets.fromLTRB(15, 10, 15, 10),
+                            width: double.infinity,
+                            decoration: BoxDecoration(
+                              border: Border.all(color: AppColors.black16),
                             ),
-                          ),
-                        )
+                            child: Column(
+                              crossAxisAlignment: CrossAxisAlignment.start,
+                              children: [
+                                Text(
+                                  widget.fieldData.keys.elementAt(0),
+                                  style: GoogleFonts.lato(
+                                    color: AppColors.black87,
+                                    fontSize: 14.0,
+                                    letterSpacing: 0.25,
+                                    fontWeight: FontWeight.w400,
+                                  ),
+                                ),
+                                widget.fieldType == FieldType.file
+                                    ? InkWell(
+                                        onTap: () => _viewFile(
+                                            widget.fieldData.keys.elementAt(0)),
+                                        child: Padding(
+                                            padding:
+                                                const EdgeInsets.only(top: 10),
+                                            child: Text(
+                                              AppLocalizations.of(context)!
+                                                  .preview,
+                                              style: GoogleFonts.lato(
+                                                color: AppColors.primaryBlue,
+                                                fontSize: 14.0,
+                                                letterSpacing: 0.25,
+                                                fontWeight: FontWeight.w700,
+                                              ),
+                                            )))
+                                    : const Center(),
+                              ],
+                            ))
                       ],
                     ),
                   ),
@@ -298,8 +362,60 @@ class _AssistantInspectorApplicationFieldState
                                                     color: AppColors.black08,
                                                   ),
                                                 ),
-                                                child:
-                                                    Image.network(_attachment),
+                                                child: Column(
+                                                    crossAxisAlignment:
+                                                        CrossAxisAlignment
+                                                            .start,
+                                                    children: [
+                                                      Text(
+                                                        _attachment,
+                                                        style: GoogleFonts.lato(
+                                                          color:
+                                                              AppColors.black87,
+                                                          fontSize: 14.0,
+                                                          letterSpacing: 0.25,
+                                                          fontWeight:
+                                                              FontWeight.w400,
+                                                        ),
+                                                      ),
+                                                      Row(
+                                                        children: [
+                                                          InkWell(
+                                                              onTap: () => Navigator
+                                                                  .push(
+                                                                      context,
+                                                                      MaterialPageRoute(
+                                                                          builder: (context) =>
+                                                                              FileViewer(
+                                                                                fileType: FieldType.image,
+                                                                                fileUrl: _attachment,
+                                                                              ))),
+                                                              child: Padding(
+                                                                  padding: const EdgeInsets
+                                                                          .only(
+                                                                      top: 10),
+                                                                  child: Text(
+                                                                    AppLocalizations.of(
+                                                                            context)!
+                                                                        .preview,
+                                                                    style:
+                                                                        GoogleFonts
+                                                                            .lato(
+                                                                      color: AppColors
+                                                                          .primaryBlue,
+                                                                      fontSize:
+                                                                          14.0,
+                                                                      letterSpacing:
+                                                                          0.25,
+                                                                      fontWeight:
+                                                                          FontWeight
+                                                                              .w700,
+                                                                    ),
+                                                                  ))),
+                                                          const Spacer(),
+                                                        ],
+                                                      ),
+                                                    ]),
                                               ),
                                             )
                                           : const Center(),
diff --git a/lib/widgets/lead_inspector_application_field.dart b/lib/widgets/lead_inspector_application_field.dart
index ba6b791..e75074d 100644
--- a/lib/widgets/lead_inspector_application_field.dart
+++ b/lib/widgets/lead_inspector_application_field.dart
@@ -3,6 +3,8 @@ import 'package:flutter/material.dart';
 import 'package:google_fonts/google_fonts.dart';
 import 'package:smf_mobile/constants/app_constants.dart';
 import 'package:smf_mobile/constants/color_constants.dart';
+import 'package:smf_mobile/database/offline_model.dart';
+import 'package:smf_mobile/pages/attachment_viewer.dart';
 import 'package:smf_mobile/pages/file_viewer.dart';
 import 'package:smf_mobile/services/application_service.dart';
 import 'package:smf_mobile/util/helper.dart';
@@ -12,6 +14,7 @@ import 'package:image_picker/image_picker.dart';
 import 'package:image_cropper/image_cropper.dart';
 
 class LeadInspectorApplicationField extends StatefulWidget {
+  final String applicationId;
   final String fieldName;
   final Map fieldData;
   final String fieldType;
@@ -20,6 +23,7 @@ class LeadInspectorApplicationField extends StatefulWidget {
   final ValueChanged<Map> parentAction;
   const LeadInspectorApplicationField({
     Key? key,
+    required this.applicationId,
     required this.fieldName,
     required this.fieldData,
     required this.fieldType,
@@ -249,7 +253,22 @@ class _LeadInspectorApplicationFieldState
               statusBarColor: Colors.grey.shade900,
               backgroundColor: Colors.white,
             ));
-        String fileUrl = await ApplicationService.uploadImage(cropped!.path);
+
+        String fileUrl = '';
+        bool isInternetConnected = await Helper.isInternetConnected();
+        if (isInternetConnected) {
+          fileUrl = await ApplicationService.uploadImage(cropped!.path);
+        } else {
+          fileUrl = cropped!.path;
+          Map<String, Object> data = {
+            'application_id': widget.applicationId,
+            'attachment': fileUrl
+          };
+          await OfflineModel.saveAttachment(data);
+          // List<Map> attachments =
+          //     await OfflineModel.getAttachments(widget.applicationId);
+          // print(attachments);
+        }
         _triggerAttachmentUpdate(fileUrl);
       } catch (e) {
         // print(e);
@@ -259,14 +278,16 @@ class _LeadInspectorApplicationFieldState
   }
 
   Future<void> _deleteAttachment(String attachment) async {
-    List data = [attachment];
-    final bool fileDeleted = await ApplicationService.deleteImage(data);
-    if (fileDeleted) {
-      Helper.toastMessage('Attachment removed');
-      setState(() {
-        _attachment = '';
-      });
+    bool isInternetConnected = await Helper.isInternetConnected();
+    if (isInternetConnected) {
+      List data = [attachment];
+      await ApplicationService.deleteImage(data);
     }
+
+    Helper.toastMessage('Attachment removed');
+    setState(() {
+      _attachment = '';
+    });
   }
 
   void _viewFile(String fileUrl) {
@@ -691,18 +712,34 @@ class _LeadInspectorApplicationFieldState
                                             Row(
                                               children: [
                                                 InkWell(
-                                                    onTap: () => Navigator.push(
-                                                        context,
-                                                        MaterialPageRoute(
-                                                            builder:
-                                                                (context) =>
-                                                                    FileViewer(
-                                                                      fileType:
-                                                                          FieldType
-                                                                              .image,
-                                                                      fileUrl:
-                                                                          _attachment,
-                                                                    ))),
+                                                    onTap: () async {
+                                                      bool isInternetConnected =
+                                                          await Helper
+                                                              .isInternetConnected();
+                                                      if (isInternetConnected) {
+                                                        Navigator.push(
+                                                            context,
+                                                            MaterialPageRoute(
+                                                                builder:
+                                                                    (context) =>
+                                                                        FileViewer(
+                                                                          fileType:
+                                                                              FieldType.image,
+                                                                          fileUrl:
+                                                                              _attachment,
+                                                                        )));
+                                                      } else {
+                                                        Navigator.push(
+                                                            context,
+                                                            MaterialPageRoute(
+                                                                builder:
+                                                                    (context) =>
+                                                                        AttachmentViewer(
+                                                                          fileUrl:
+                                                                              _attachment,
+                                                                        )));
+                                                      }
+                                                    },
                                                     child: Padding(
                                                         padding:
                                                             const EdgeInsets
@@ -722,28 +759,35 @@ class _LeadInspectorApplicationFieldState
                                                           ),
                                                         ))),
                                                 const Spacer(),
-                                                InkWell(
-                                                    onTap: () =>
-                                                        _deleteAttachment(
-                                                            _attachment),
-                                                    child: Padding(
-                                                        padding:
-                                                            const EdgeInsets
-                                                                .only(top: 10),
-                                                        child: Text(
-                                                          AppLocalizations.of(
-                                                                  context)!
-                                                              .remove,
-                                                          style:
-                                                              GoogleFonts.lato(
-                                                            color: AppColors
-                                                                .sentForIns,
-                                                            fontSize: 14.0,
-                                                            letterSpacing: 0.25,
-                                                            fontWeight:
-                                                                FontWeight.w700,
-                                                          ),
-                                                        ))),
+                                                widget.applicationStatus !=
+                                                        InspectionStatus
+                                                            .inspectionCompleted
+                                                    ? InkWell(
+                                                        onTap: () =>
+                                                            _deleteAttachment(
+                                                                _attachment),
+                                                        child: Padding(
+                                                            padding:
+                                                                const EdgeInsets
+                                                                        .only(
+                                                                    top: 10),
+                                                            child: Text(
+                                                              AppLocalizations.of(
+                                                                      context)!
+                                                                  .remove,
+                                                              style: GoogleFonts
+                                                                  .lato(
+                                                                color: AppColors
+                                                                    .sentForIns,
+                                                                fontSize: 14.0,
+                                                                letterSpacing:
+                                                                    0.25,
+                                                                fontWeight:
+                                                                    FontWeight
+                                                                        .w700,
+                                                              ),
+                                                            )))
+                                                    : const Center(),
                                               ],
                                             ),
                                           ]))
-- 
GitLab