import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; import 'package:easy_localization/easy_localization.dart'; import 'package:flutter/material.dart'; import 'package:mohem_flutter_app/classes/colors.dart'; import 'package:mohem_flutter_app/extensions/int_extensions.dart'; import 'package:mohem_flutter_app/extensions/string_extensions.dart'; import 'package:mohem_flutter_app/extensions/widget_extensions.dart'; import 'package:mohem_flutter_app/generated/locale_keys.g.dart'; import 'package:mohem_flutter_app/models/etqan_ovr/etqan_get_employee_incident_report.dart'; import 'package:mohem_flutter_app/provider/etqan_ovr_provider.dart'; import 'package:mohem_flutter_app/classes/utils.dart'; import 'package:mohem_flutter_app/widgets/app_bar_widget.dart'; import 'package:provider/provider.dart'; import 'package:open_filex/open_filex.dart'; import 'package:path_provider/path_provider.dart'; class EtqanOvrRequestDetailed extends StatefulWidget { const EtqanOvrRequestDetailed({Key? key}) : super(key: key); @override _EtqanOvrRequestDetailedState createState() => _EtqanOvrRequestDetailedState(); } class _EtqanOvrRequestDetailedState extends State { List get fieldOrder => ['Project', 'Created', 'Occurrence Time', 'OVR Reference No', 'Involved Employee Number', 'Description']; List get hiddenFields => ['OVR Id', 'Is Anonymous']; Future _viewAttachment(BuildContext context, String base64Data) async { try { Uint8List bytes = base64.decode(base64Data); String dir = (await getApplicationDocumentsDirectory()).path; String ext = 'pdf'; if (base64Data.startsWith('/9j/')) { ext = 'jpg'; } else if (base64Data.startsWith('iVBORw0KGgo')) { ext = 'png'; } File file = File("$dir/${DateTime.now().millisecondsSinceEpoch}.$ext"); await file.writeAsBytes(bytes); OpenFilex.open(file.path); } catch (e) { Utils.showToast("Cannot open attachment."); } } List _getOrderedList(List list) { List orderedList = []; List filteredList = list.where((EtqanGetIncidentRequestResponse item) => !hiddenFields.any((f) => f.toLowerCase() == item.key?.toLowerCase())).toList(); for (String fieldName in fieldOrder) { var item = filteredList.firstWhere((e) => e.key?.toLowerCase() == fieldName.toLowerCase(), orElse: () => EtqanGetIncidentRequestResponse()); if (item.key != null) { orderedList.add(item); } } for (var item in filteredList) { if (!fieldOrder.any((f) => f.toLowerCase() == item.key?.toLowerCase())) { orderedList.add(item); } } return orderedList; } @override void initState() { super.initState(); WidgetsBinding.instance.addPostFrameCallback((_) { EtqanOvrProviderModel provider = context.read(); provider.fetchEtqanEmployeeIncidentRequests(context, provider.getTicketId); }); } @override Widget build(BuildContext context) { return Scaffold( backgroundColor: Colors.white, appBar: AppBarWidget(context, title: LocaleKeys.incidentDetails.tr()), body: Consumer( builder: (BuildContext context, EtqanOvrProviderModel provider, Widget? child) { if (provider.getEtqanEmployeeIncidnetRequest == null || provider.getEtqanEmployeeIncidnetRequest!.isEmpty) { return Utils.getNoDataWidget(context); } List orderedList = _getOrderedList(provider.getEtqanEmployeeIncidnetRequest!); return SingleChildScrollView( physics: const BouncingScrollPhysics(), padding: const EdgeInsets.all(16), child: Container( decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(15), border: Border.all(color: const Color(0xffefefef), width: 1), boxShadow: [BoxShadow(color: Colors.black.withValues(alpha: 0.05), blurRadius: 10, offset: const Offset(0, 2))], ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: orderedList.asMap().entries.map((MapEntry entry) { int index = entry.key; EtqanGetIncidentRequestResponse data = entry.value; bool isLast = index == orderedList.length - 1; bool isAttachment = data.key?.toLowerCase() == 'attachment'; String displayKey = context.locale.languageCode == "ar" ? (data.keyAr ?? data.key ?? "") : (data.key ?? ""); String displayValue = context.locale.languageCode == "ar" ? (data.valueAr ?? data.value ?? "") : (data.value ?? ""); bool hasSubValues = data.subValues != null && data.subValues!.isNotEmpty; return Column( children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded(flex: 2, child: displayKey.toText12(isBold: true, color: MyColors.grey57Color)), 8.width, Expanded( flex: 3, child: isAttachment && hasSubValues ? Column( crossAxisAlignment: CrossAxisAlignment.start, children: data.subValues!.asMap().entries.map((entry) { int subIndex = entry.key; String base64Data = entry.value; return Padding( padding: EdgeInsets.only(bottom: subIndex < data.subValues!.length - 1 ? 8.0 : 0), child: GestureDetector( onTap: () => _viewAttachment(context, base64Data), child: Row( crossAxisAlignment: CrossAxisAlignment.start, mainAxisAlignment: context.locale.languageCode == "ar" ? MainAxisAlignment.end : MainAxisAlignment.start, children: [ Text( data.subValues!.length > 1 ? '${LocaleKeys.viewAttachment.tr()} ${subIndex + 1}' : LocaleKeys.viewAttachment.tr(), // textAlign: context.locale.languageCode == "ar" ? TextAlign.start : TextAlign.start, style: const TextStyle( fontSize: 14, color: MyColors.green9CColor, decoration: TextDecoration.underline, decorationColor: MyColors.green9CColor, ), ), ], ), ), ); }).toList(), ) : hasSubValues ? Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ if (displayValue.isNotEmpty) displayValue.toText14(color: MyColors.darkTextColor), if (displayValue.isNotEmpty) 8.height, ...data.subValues! .map( (subValue) => Padding( padding: const EdgeInsets.only(bottom: 4), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [const Text("• ", style: TextStyle(fontSize: 14)), Expanded(child: subValue.toText14(color: MyColors.darkTextColor))], ), ), ) .toList(), ], ) : (displayValue.isNotEmpty ? displayValue : "-").toText14(color: MyColors.darkTextColor), ), ], ), ), if (!isLast) const Padding(padding: EdgeInsets.only(left: 14, right: 14), child: Divider(height: 1, thickness: 1, color: Color(0xffefefef))), ], ); }).toList(), ), ), ); }, ).paddingOnly(bottom: 20), ); } }