import 'dart:convert'; import 'dart:io' as html; import 'package:dropdown_search/dropdown_search.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:http/http.dart' as http; import 'package:nhance_partner/presentation/providers/userRoleProvider.dart'; import 'package:nhance_partner/presentation/screens/Enquiry/enquiry/tabs.dart'; import '../../../../core/config/env.dart'; import '../../../../core/services/api_service.dart'; import '../../../../data/services/auth_service.dart'; import '../../../../data/utils/toastNotification.dart'; import '../../../../data/utils/validators.dart'; import '../../../layouts/responsive_layout.dart'; import '../../../providers/manager_provider.dart'; import '../../../themes/indicators/customizd_file_upload.dart'; import '../../../themes/indicators/input_field_decoration.dart'; import '../../../themes/indicators/text_field_theme.dart'; import '../../../themes/indicators/upload_doc_theme.dart' hide ThemedUploadField; class QuotationTab extends ConsumerStatefulWidget { // final Map? data; final List>? data; String? id; final Future Function()? onRefresh; QuotationTab({super.key, this.data, this.id, this.onRefresh}); @override ConsumerState createState() => QuotationTabState(); } class QuotationTabState extends ConsumerState { int currentPage = 0; int itemsPerPage = 10; List> dataVal = []; final TextEditingController _searchController = TextEditingController(); late ApiService apiService; final _formKey = GlobalKey(); final GlobalKey>> dropDownKey = GlobalKey>>(); final GlobalKey tabKey = GlobalKey(); bool blockKey = false; List tabHeader = [ 'regNum', 'insurer', 'idv', 'insuranceId', 'premAmount', 'planType', 'addit_doc', 'remarks', // 'mobile', // 'code', // 'address', // 'regNo', ]; late String isActive = "1"; // html.File? docUploadedFile; PlatformFile? docUploadedFile; String? selectedFileNames; String? docUploadedFileFromApi; String? selectedId; bool isLoading = false; bool isquotation = false; bool showAction = false; Map controllers = {}; String? _token; dynamic userId; dynamic managerId; dynamic role; List> getVehicleTypeData = []; List> filteredVechicleData = []; List> getInsurersData = []; List> filteredInsurersData = []; Map dataDetails() { final data = { "id": selectedId, "enquiry_id": widget.id, "insured_declared_value": controllers["idv"]?.text, "premium_amount": controllers["premAmount"]?.text, "insurance_plan_type_id": controllers["insuranceId"]?.text, "updated_by": userId, }; return data; } List> getQuotationData = []; List> originalData = []; List> filteredData = []; // bool isLoading = false; @override void initState() { super.initState(); apiService = ApiService(); for (String field in tabHeader) { controllers[field] = TextEditingController(); } // updateData(); _initializeToken(); Future.microtask(() { managerId = ref.watch(managerIdProvider); userId = ref.watch(userIdProvider); role = ref.watch(userRoleProvider); getQuotationList(); }); } Future _initializeToken() async { _token = await AuthService.getToken(); print("APISERTOKEN - $_token"); } void refresh() { getQuotationList(); } @override void dispose() { // Dispose all TextEditingControllers for (var controller in controllers.values) { controller.dispose(); } super.dispose(); } Future getQuotationList() async { print('getClaimList called MagId - '); setState(() { isLoading = true; }); try { final response; if (widget.data != null && widget.id != null) { final data = List>.from(widget.data as Iterable); // response = await apiService.findSingleQuotationData(widget.id); // print('quoationListData - ${widget.data}'); setState(() { getQuotationData = data; // getQuotationData = List>.from(response['data']); originalData = getQuotationData; filteredData = List.from(originalData); print('quoationListData - $getQuotationData'); blockKey = getQuotationData.any( (item) => item['status'] == 'Accepted', ); print('blockKey- $blockKey'); // blockKey = getQuotationData.any( // (item) => (item['status']?.toString().toLowerCase() ?? '') == 'approved', // ); // print('originalData - $getClaimPolicies'); }); // if (response['status'] == 'success') { // final rawData = response['data']; // print('quoationListData1 - ${response['data']}'); // setState(() { // if (rawData is List) { // // already a list // getQuotationData = List>.from(rawData); // } else if (rawData is Map) { // // single object, wrap into a list // getQuotationData = [Map.from(rawData)]; // } else { // getQuotationData = []; // } // // getQuotationData = List>.from(response['data']); // originalData = getQuotationData; // filteredData = List.from(originalData); // // print('originalData - $getClaimPolicies'); // }); // } else { // getQuotationData = []; // originalData = []; // } } } catch (e) { print('Exception occurred: $e'); } finally { setState(() { isLoading = false; }); } } void findAndUpdateById(updateId) { try { final match = getQuotationData.firstWhere( (q) => q['id'] == updateId, orElse: () => {}, ); if (match.isNotEmpty) { print("Found quotation: $match"); updateData(match); } else { print("No quotation found with id $updateId"); } } catch (e) { print("Error finding quotation: $e"); } } void updateData(Map data) { print('UPDID - $data}'); setState(() { controllers['regNum']?.text = data['reg_no']?.toString() ?? ''; controllers['insurer']?.text = data['insurer_name']?.toString() ?? ''; controllers['idv']?.text = data['insured_declared_value']?.toString() ?? ''; controllers['premAmount']?.text = data['premium_amount']?.toString() ?? ''; controllers['insuranceId']?.text = data['insurance_plan_type_id']?.toString() ?? ''; controllers['planType']?.text = data['insurance_plan_type']?.toString() ?? ''; controllers['remarks']?.text = data['reject_reason']?.toString() ?? ''; String? status = data['status']?.toString() ?? ''; if (status == 'Pending') { print('status - $status'); showAction = true; } String? apiDocPath = data["additional_uploaded_file_name"]; if (apiDocPath != null && apiDocPath.isNotEmpty) { print('apiDocPath - $apiDocPath'); selectedFileNames = apiDocPath.split('/').last; print('selectedFileNames - $selectedFileNames'); docUploadedFileFromApi = apiDocPath; print('docUploadedFileFromApi - $docUploadedFileFromApi'); docUploadedFile = null; } else { selectedFileNames = null; docUploadedFile = null; docUploadedFileFromApi = null; } }); } void handleActions(data) { print('Action - $data'); createData(data); } Future createData(val) async { final String apiUrldata; apiUrldata = '${Env.apiUrl}quotation/acceptOrRejectQuotation'; // final token = await getToken(); // Fetch token if (_token == null) { throw Exception('Token not found. Please log in.'); } final Map data = { "id": selectedId, "status": val, "action_by": userId, // "action_user": (role == 'agent') ? 'agent' : 'handler', "action_user": role, }; // data['id'] = selectedId; // Add plan_id for update // data['status'] = val; print("data------- $data"); try { final response = await http.post( Uri.parse(apiUrldata), headers: { 'Authorization': 'Bearer $_token', 'Content-Type': 'application/json', 'app-signature': Env.App_Signature, }, body: jsonEncode(data), // Convert map to JSON ); if (response.statusCode == 200) { print("Response: ${response.body}"); ToastHelper.showSuccessToast(context, 'Status Updated'); print("tre1"); selectedId = null; // just update field isquotation = false; print("tre11"); // 🔄 Refresh parent if (widget.onRefresh != null) { await widget.onRefresh!(); } // refresh(); // WidgetsBinding.instance.addPostFrameCallback((_) { // tabKey.currentState?.loadQuotationTab(widget.id ?? ""); // }); // context.go(AppRoutes.staffLst); } else if (response.statusCode == 403) { await apiService.clearLocalStorageAndRedirect(); } else { final responseBody = jsonDecode(response.body); dynamic msg = responseBody['data']; ToastHelper.showErrorToast(context, 'Status Updation Failed'); print("Failed to submit plan. Status: ${response.statusCode}"); print("Error: ${response.body}"); } } catch (e) { print(" Error submitting Staff: $e"); } } void UpdataDocuments() { final dataSet = dataDetails(); print('UpdataDocuments - $dataSet}'); createDocumentData(dataSet); } Future createDocumentData(Map userData) async { final id = widget.id; final uri = Uri.parse('${Env.apiUrl}quotation/updateQuotation'); if (_token == null) { throw Exception('Token not found. Please log in.'); } // Use MultipartRequest (POST only) final request = http.MultipartRequest('POST', uri); request.headers['Authorization'] = 'Bearer $_token'; request.headers['app-signature'] = Env.App_Signature; print("USerDAta - $userData"); // userData.forEach((key, value) { // request.fields[key] = value.toString(); // print("✅ Encoded travel_details2: ${request.fields[key]}"); // }); userData.forEach((key, value) { if (key != 'additional_uploaded_file_name') { request.fields[key] = value.toString(); print("✅ Encoded $key: ${request.fields[key]}"); } }); // Attach file if selected if (docUploadedFile != null) { try { if (docUploadedFile!.bytes != null) { final multipartFile = http.MultipartFile.fromBytes( 'additional_uploaded_file_name', docUploadedFile!.bytes!, filename: docUploadedFile!.name, ); request.files.add(multipartFile); } else if (docUploadedFile!.path != null) { final multipartFile = await http.MultipartFile.fromPath( 'additional_uploaded_file_name', docUploadedFile!.path!, filename: docUploadedFile!.name, ); request.files.add(multipartFile); } print("📎 File attached: ${docUploadedFile!.name}"); } catch (e) { print("❌ Failed to attach file: $e"); } } print(" Sending request with fields: ${request.fields}"); try { final streamedResponse = await request.send(); final response = await http.Response.fromStream(streamedResponse); print("Response status: ${response.statusCode}"); print("Response body: ${response.body}"); if (response.statusCode == 200 || response.statusCode == 201) { // dispose(); ToastHelper.showSuccessToast(context, 'Document Uploaded'); print("Response: ${response.body}"); if (widget.onRefresh != null) { await widget.onRefresh!(); } // context.go(AppRoutes.agentLst); } else if (response.statusCode == 403) { await apiService.clearLocalStorageAndRedirect(); } else { final responseBody = jsonDecode(response.body); dynamic msg = responseBody['data']; print("❌ Submission failed. Status: ${response.statusCode}"); print("Body: ${response.body}"); ToastHelper.showErrorToast(context, 'Document Upload Failed'); } } catch (e) { print("🔥 Error submitting user: $e"); } } Color _getStatusColor(String? status) { switch (status) { case 'Pending': return Colors.yellow; case 'Accepted': return Colors.green; case 'Rejected': return Colors.red; default: return Colors.grey; } } @override Widget build(BuildContext context) { bool isMobile = ResponsiveLayout.isMobile(context); return SelectionArea( child: Container( height: MediaQuery.of(context).size.height, width: MediaQuery.of(context).size.width, child: filteredData.isNotEmpty ? SingleChildScrollView( scrollDirection: Axis.vertical, child: Column( children: [ Container( // color: Colors.green, decoration: BoxDecoration( color: Color(0xffEDF6F5), borderRadius: BorderRadius.circular(10.0), ), width: MediaQuery.of(context).size.width, // height: MediaQuery.of(context).size.height * 0.8, padding: isMobile ? EdgeInsets.all(6.0) : EdgeInsets.all(16.0), child: Column( children: [ // Text('datta') _buildDataTable(context), ], ), ), const SizedBox(height: 20), if (isquotation) Container( // color: Colors.green, decoration: BoxDecoration( color: Color(0xffEDF6F5), borderRadius: BorderRadius.circular(10.0), ), width: MediaQuery.of(context).size.width, // height: MediaQuery.of(context).size.height * 0.8, padding: isMobile ? EdgeInsets.only(left: 14.0, right: 14.0) : EdgeInsets.all(26.0), child: Column( children: [ SingleChildScrollView( child: buildFormFields(context), ), const SizedBox(height: 20), if (!blockKey) Row( mainAxisAlignment: MainAxisAlignment.end, children: [ GestureDetector( onTap: () { handleActions('Rejected'); }, child: Container( padding: EdgeInsets.symmetric( horizontal: 45.0, vertical: 8, ), decoration: BoxDecoration( borderRadius: BorderRadius.circular(8.0), color: Color(0xFF425B5B), ), child: Text( 'Reject', style: TextStyle(color: Colors.white), ), ), ), const SizedBox(width: 10), GestureDetector( onTap: () { handleActions('Accepted'); }, child: Container( padding: EdgeInsets.symmetric( horizontal: 45.0, vertical: 8, ), decoration: BoxDecoration( borderRadius: BorderRadius.circular(8.0), color: Color(0xFF425B5B), ), child: Text( 'Accept', style: TextStyle(color: Colors.white), ), ), ), ], ), ], ), ), ], ), ) : Center(child: Text('No Available Data')), ) ); } Widget _buildDataTable(BuildContext context) { if (filteredData.isEmpty) { return const SizedBox( height: 50, child: Center(child: Text('No available data')), ); } final sortedData = [...filteredData] ..sort((a, b) => int.parse(b['id']) - int.parse(a['id'])); return SingleChildScrollView( child: Column( children: [ ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemCount: ResponsiveLayout.isMobile(context) ? sortedData .length // only cards for mobile : sortedData.length + 1, // +1 for header in desktop itemBuilder: (context, index) { if (!ResponsiveLayout.isMobile(context) && index == 0) { return _buildHeader(); } final startIndex = (currentPage - 1) * itemsPerPage; final item = sortedData[index - (ResponsiveLayout.isMobile(context) ? 0 : 1)]; final sno = startIndex + index; return !ResponsiveLayout.isMobile(context) ? _buildDataRow(item, sno) : _buildDataCard(item, sno); }, ), ], ), ); } Widget buildFormFields(BuildContext context) { return Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildResponsiveRow( context, buildName(context), buildInsusrer(context), ), if (!ResponsiveLayout.isMobile(context)) const SizedBox(height: 10), _buildResponsiveRow( context, buildIdv(context), buildPremiumAmnt(context), ), if (!ResponsiveLayout.isMobile(context)) const SizedBox(height: 10), _buildResponsiveRow( context, buildPlanType(context), SizedBox.shrink(), // buildDocuments(context), ), // if (!ResponsiveLayout.isMobile(context)) const SizedBox(height: 10), // _buildResponsiveRow( // context, // buildAdditonalDocuments(context), // buildRemarks(context), // ), ], ), ); } Widget _buildResponsiveRow( BuildContext context, Widget first, Widget second, ) { if (ResponsiveLayout.isMobile(context)) { // Stack vertically return Column(children: [first, const SizedBox(height: 2), second]); } else { // Place side by side return Row( children: [ Expanded(child: first), const SizedBox(width: 25), Expanded(child: second), ], ); } } Widget buildName(BuildContext context) { return buildResponsiveField( label: "Vehicle Number", field: ThemedFormField( controller: controllers['regNum']!, readOnly: true, // validator: (value) => Validators.requiredField(value, "regNum"), txtwidth: ResponsiveLayout.isMobile(context) ? null : MediaQuery.of(context).size.width * 0.26, ), ); } Widget buildInsusrer(BuildContext context) { return buildResponsiveField( label: "Insurer", field: ThemedFormField( controller: controllers['insurer']!, readOnly: true, txtwidth: ResponsiveLayout.isMobile(context) ? null : MediaQuery.of(context).size.width * 0.26, ), ); } Widget buildIdv(BuildContext context) { return buildResponsiveField( label: "IDV", field: ThemedFormField( controller: controllers['idv']!, readOnly: true, txtwidth: ResponsiveLayout.isMobile(context) ? null : MediaQuery.of(context).size.width * 0.26, ), ); } Widget buildPremiumAmnt(BuildContext context) { return buildResponsiveField( label: "Premium Amount", field: ThemedFormField( controller: controllers['premAmount']!, readOnly: true, txtwidth: ResponsiveLayout.isMobile(context) ? null : MediaQuery.of(context).size.width * 0.26, ), ); } Widget buildPlanType(BuildContext context) { return buildResponsiveField( label: "Plan Type", field: ThemedFormField( controller: controllers['planType']!, readOnly: true, txtwidth: ResponsiveLayout.isMobile(context) ? null : MediaQuery.of(context).size.width * 0.26, ), ); } Widget buildDocuments(BuildContext context) { return buildResponsiveUploadField( label: 'Proposal Documents', hintText: selectedFileNames, onFileSelected: (fileName, file) { setState(() { docUploadedFile = file; selectedFileNames = fileName; UpdataDocuments(); }); }, showDownload: docUploadedFile != null || docUploadedFileFromApi != null, onRemove: () { setState(() { docUploadedFile = null; docUploadedFileFromApi = null; selectedFileNames = null; }); }, onDownload: () => apiService.downloadFile( apiUrl: 'quotation/downloadAdditionalUploadedFile?id=$selectedId', apiId: selectedId, localFile: docUploadedFile, fileName: selectedFileNames, ), ); } // Widget buildAdditonalDocuments(BuildContext context) { // return buildResponsiveField( // label: "Additional Documents", // field: ThemedFormField( // controller: controllers['addit_doc']!, // // validator: (value) => Validators.phone(value, "phNumber"), // txtwidth: ResponsiveLayout.isMobile(context) // ? null // : MediaQuery.of(context).size.width * 0.26, // ), // ); // } // // Widget buildRemarks(BuildContext context) { // return buildResponsiveField( // label: "Remarks", // field: ThemedFormField( // controller: controllers['remarks']!, // // validator: (value) => Validators.phone(value, "phNumber"), // txtwidth: ResponsiveLayout.isMobile(context) // ? null // : MediaQuery.of(context).size.width * 0.26, // ), // ); // } Widget buildResponsiveField({required String label, required Widget field}) { final isMobile = ResponsiveLayout.isMobile(context); if (isMobile) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(label, style: _textStyle), const SizedBox(height: 8), field, const SizedBox(height: 16), ], ); } else { return Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded(child: Text(label, style: _textStyle)), const SizedBox(width: 10), field, ], ); } } // Widget buildResponsiveUploadField({ // required String label, // required String? hintText, // required void Function(String fileName, dynamic file) onFileSelected, // }) // { // final isMobile = ResponsiveLayout.isMobile(context); // // final uploadWidget = ThemedUploadField( // hintText: hintText ?? "Upload Document", // txtwidth: isMobile ? null : MediaQuery.of(context).size.width * 0.26, // onFileSelected: onFileSelected, // ); // // if (isMobile) { // return Column( // crossAxisAlignment: CrossAxisAlignment.start, // children: [ // Text(label, style: _textStyle), // const SizedBox(height: 8), // uploadWidget, // const SizedBox(height: 16), // ], // ); // } else { // return Row( // mainAxisAlignment: MainAxisAlignment.spaceBetween, // children: [ // Expanded(child: Text(label, style: _textStyle)), // const SizedBox(width: 10), // uploadWidget, // ], // ); // } // } Widget buildResponsiveUploadField({ required String label, required String? hintText, required void Function(String fileName, dynamic file) onFileSelected, bool showDownload = false, VoidCallback? onRemove, VoidCallback? onDownload, }) { final isMobile = ResponsiveLayout.isMobile(context); final uploadWidget = ThemedUploadField( hintText: hintText ?? "Upload Document", txtwidth: isMobile ? null : MediaQuery.of(context).size.width * 0.26, onFileSelected: onFileSelected, ); final downloadRow = showDownload ? Padding( padding: const EdgeInsets.only(top: 5), child: Row( children: [ // IconButton( // onPressed: onRemove, // icon: const Icon( // Icons.remove_circle_outline_rounded, // color: Colors.redAccent, // ), // tooltip: 'Remove Upload', // ), GestureDetector( onTap: onDownload, child: Container( padding: const EdgeInsets.all(5), decoration: BoxDecoration( borderRadius: BorderRadius.circular(5), color: const Color(0xFF425B5B), ), child: Row( children: const [ Text( "Download", style: TextStyle( fontSize: 12, fontWeight: FontWeight.w200, color: Colors.white, ), ), SizedBox(width: 5), Icon(Icons.download, size: 13, color: Colors.white), ], ), ), ), ], ), ) : const SizedBox.shrink(); if (isMobile) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text(label, style: _textStyle), const SizedBox(height: 8), uploadWidget, downloadRow, const SizedBox(height: 16), ], ); } else { return Column( crossAxisAlignment: CrossAxisAlignment.end, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded(child: Text(label, style: _textStyle)), const SizedBox(width: 10), uploadWidget, ], ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [SizedBox.shrink(), downloadRow], ), ], ); } } Widget buildId(BuildContext context) { return buildResponsiveField( label: "Vehicle Number *", field: ThemedFormField( controller: controllers['regNo']!, validator: (value) => Validators.requiredField(value, "regNo"), txtwidth: ResponsiveLayout.isMobile(context) ? null : MediaQuery.of(context).size.width * 0.26, ), ); } Widget _buildHeader() { return Container( decoration: BoxDecoration( color: Color(0xFFEDF6F5), borderRadius: BorderRadius.circular(6), ), padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16), child: const Row( children: [ Expanded(flex: 1, child: Text(' ', style: _headerStyle)), Expanded(flex: 1, child: Text('Vehicle Number', style: _headerStyle)), Expanded(flex: 1, child: Text('Insurer', style: _headerStyle)), Expanded(flex: 1, child: Text('IDV', style: _headerStyle)), Expanded(flex: 1, child: Text('Plan Type', style: _headerStyle)), Expanded(flex: 1, child: Text('Premium Amount', style: _headerStyle)), Expanded(flex: 1, child: Text('Status', style: _headerStyle)), ], ), ); } Widget _buildDataRow(Map item, sno) { return Container( padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 16), // margin: const EdgeInsets.only(top: 10), decoration: BoxDecoration( color: Colors.white, // color: Color(0xFFE0F7F9), border: const Border( bottom: BorderSide(color: Color(0xFFEAEAEA), width: 1), ), borderRadius: BorderRadius.circular(8), ), child: Row( children: [ // ✅ Single-select checkbox Expanded( flex: 1, child: Checkbox( activeColor: Colors.black, value: selectedId == item['id'], // only selected row is checked onChanged: (val) { setState(() { if (val == true) { selectedId = item['id']; // select this row isquotation = true; } else { selectedId = null; isquotation = false; // unselect } }); findAndUpdateById(selectedId); print("Selected row id: $selectedId"); }, ), ), Expanded( flex: 1, child: Text(item['reg_no'] ?? '-', style: _dataBold), ), Expanded( flex: 1, child: Text(item['insurer_name'] ?? '-', style: _dataBold), ), Expanded( flex: 1, child: Text( item['insured_declared_value'] ?? '-', style: _dataBold, ), ), Expanded( flex: 1, child: Text(item['insurance_plan_type'] ?? '-', style: _dataBold), ), Expanded( flex: 1, child: Text(item['premium_amount'] ?? '-', style: _dataBold), ), Expanded( flex: 1, child: Text( item['status'] ?? '-', style: TextStyle( fontSize: 14, fontWeight: FontWeight.w400, color: _getStatusColor(item['status']), // color: item['status'] == 'Accepted' ? Colors.green : Colors.red, ), ), ), ], ), ); } Widget _buildDataCard(Map item, int sno) { return Container( // margin: const EdgeInsets.symmetric(vertical: 6, horizontal: 8), padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: const Color(0xFFFFFFFF), // color: const Color(0xFFF6FEFD), borderRadius: BorderRadius.circular(8.0), border: Border.all(color: const Color(0xffD9EBE8)), ), child: Row( children: [ Column( children: [ // ✅ Single-select checkbox Checkbox( activeColor: Colors.black, value: selectedId == item['id'], // only selected row is checked onChanged: (val) { setState(() { if (val == true) { selectedId = item['id']; // select this row isquotation = true; } else { selectedId = null; isquotation = false; // unselect } }); findAndUpdateById(selectedId); print("Selected row id: $selectedId"); }, ), ], ), Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( // mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( // flex: 2, child: Text( item['insurer_name'] ?? '-', style: _cardRow1BodyStyle, ), ), Expanded( // flex: 2, child: Text( item['insurance_plan_type'] ?? '-', style: _cardRow1BodyStyle, ), ), ], ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( // "TN64V3456", item['reg_no'] ?? '-', style: _cardheaderStyle, ), Text( 'IDV: ${item['insured_declared_value']}' ?? '-', style: _cardRow2BodyStyle, ), ], ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ RichText( text: TextSpan( children: [ TextSpan( text: 'Status : ', // key style: TextStyle( color: Colors.black, fontWeight: FontWeight.w600, fontSize: 11, ), // key color ), TextSpan( text: '${item['status'] ?? '-'}', // value style: TextStyle( color: _getStatusColor(item['status']), fontWeight: FontWeight.w600, fontSize: 11, ), // value color ), ], ), ), Text( '${item['premium_amount']}' ?? '-', style: _cardheaderStyle, ), ], ), ], ), ), ], ), ); } static final _dataBold = TextStyle( fontSize: 14, fontWeight: FontWeight.w400, color: Color(0xFF000000), ); static final _dataSub = TextStyle( fontSize: 10, fontWeight: FontWeight.w300, color: Color(0xFF585757), ); static const _headerStyle = TextStyle( color: Colors.black, fontWeight: FontWeight.bold, ); static const _textStyle = TextStyle( fontSize: 14, fontWeight: FontWeight.w600, ); static const _cardheaderStyle = TextStyle( color: Colors.black, fontWeight: FontWeight.w600, fontSize: 12, ); static const _cardBodyStyle = TextStyle( // color: Color(0xFF545454), color: Colors.black, fontWeight: FontWeight.w600, fontSize: 12, ); static const _cardRow1BodyStyle = TextStyle( // color: Color(0xFF545454), color: Colors.black, fontWeight: FontWeight.w500, fontSize: 12, ); static const _cardRow2BodyStyle = TextStyle( color: Color(0xFF545454), // color: Colors.black, fontWeight: FontWeight.w500, fontSize: 12, ); }