import 'package:flutter/material.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:nhancepolicy/service/api_service.dart'; class ClaimHistoryPopup extends StatefulWidget { final String ticket_id; final String empName; final String empCode; final String policyType; final String clientPolicyNo; final String claimAmount; final String claimNo; final String postToken; const ClaimHistoryPopup({ Key? key, required this.ticket_id, required this.empName, required this.empCode, required this.policyType, required this.clientPolicyNo, required this.claimAmount, required this.claimNo, required this.postToken, }) : super(key: key); @override State createState() => _ClaimHistoryPopupState(); } class _ClaimHistoryPopupState extends State { late ApiService apiService; List> getClaimsHistoryList = []; List stepKeys = []; late Map stepMap; int _index = 4; bool isLoading = false; @override void initState() { super.initState(); apiService = ApiService(context); print(widget.postToken); print(widget.claimAmount); print(widget.claimNo); print(widget.clientPolicyNo); print(widget.empCode); print(widget.policyType); print(widget.ticket_id); getClaimsHistoryDetails(); } @override void dispose() { super.dispose(); } Future getClaimsHistoryDetails() async { setState(() { isLoading = true; }); try { print('10'); // final ticketID = widget.ticket_id; // if (ticketID != '' || ticketID != null) { // return; // } final response = await apiService.getClaimsHistoryToApi( widget.ticket_id, widget.postToken); if (response['status'] == 'success') { setState(() { isLoading = false; }); setState(() { getClaimsHistoryList = [ Map.from(response['data']['ticket_data']) ]; stepMap = getClaimsHistoryList[0]; stepKeys = stepMap.keys.toList(); print('Claims History List $getClaimsHistoryList'); // originalData = getCDPolicies; // filteredData = List.from(originalData); // print('filteredData'); // print(filteredData); }); } else { setState(() { isLoading = false; }); // ToastHelper.showWarningToast( // context, 'Request failed with status: ${response.statusCode}'); print('Request failed with status: ${response['code']}'); } } catch (e) { setState(() { isLoading = false; }); print('Exception occurred: $e'); } finally { setState(() { isLoading = false; }); } } @override Widget build(BuildContext context) { // if (getClaimsHistoryList.isEmpty) { // return SizedBox( // height: 50, // child: Center(child: Text('No available Claims')), // ); // } return Container( constraints: BoxConstraints(maxWidth: 800, maxHeight: 800), padding: EdgeInsets.all(20), decoration: BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(12), ), child: SingleChildScrollView( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( child: Align( alignment: Alignment.centerLeft, child: Text( 'Claim History', style: GoogleFonts.poppins( fontSize: 20, fontWeight: FontWeight.w500, color: Color(0xFF101010), ), ), ), ), MouseRegion( cursor: SystemMouseCursors.click, // Show pointer cursor child: GestureDetector( onTap: () => Navigator.of(context).pop(), child: Container( height: 30, width: 30, decoration: BoxDecoration( color: Colors.white, border: Border.all(color: Color(0xFFBCBCBC)), borderRadius: BorderRadius.circular(6), ), child: const Icon( Icons.close, size: 25, color: Color(0xFFBCBCBC), ), ), ), ) ], ), SizedBox(height: 10), Container( margin: const EdgeInsets.symmetric(horizontal: 16, vertical: 20), decoration: BoxDecoration( color: Color(0xFFFFFFFF), // White background borderRadius: BorderRadius.circular(12), boxShadow: const [ BoxShadow( color: Color(0xFFEBEBEB), // Shadow color blurRadius: 14, // How soft the shadow is spreadRadius: 2, // How much it spreads offset: Offset(0, 1), // X and Y offset ), ], ), padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( children: [ Expanded( child: _buildKeyValue('Name', '${widget.empName ?? ''} (${widget.empCode ?? ''})'), ), SizedBox(width: 16), Expanded( child: _buildKeyValue('Policy Name', '${widget.policyType ?? ''} - ${widget.clientPolicyNo ?? ''}')), ], ), SizedBox(height: 16), Row( children: [ Expanded( child: _buildKeyValue( 'Claim Amount', '₹${widget.claimAmount ?? ''}'), ), SizedBox(width: 16), Expanded( child: _buildKeyValue( 'Claim Number', widget.claimNo ?? ''), ), ], ), ], ), ), SizedBox(height: 10), // Container( // padding: const EdgeInsets.all(16), // child: Stepper( // currentStep: _index, // onStepCancel: () { // if (_index > 0) { // setState(() { // _index -= 1; // }); // } // }, // onStepContinue: () { // if (_index < 4) { // setState(() { // _index += 1; // }); // } // }, // onStepTapped: (int index) { // setState(() { // _index = index; // }); // }, // steps: [ // Step( // title: Text('Step 1: PAYMENT INITIATED'), // content: Text('Pay Initiate Date: 05-05-2025'), // isActive: true, // state: StepState.complete, // ), // Step( // title: Text('Step 2: INFORMATION REQUIRED'), // content: Text('Raised Date: 05-05-2025'), // isActive: true, // state: StepState.complete, // ), // Step( // title: Text('Step 3: CLAIM NO. UPDATION'), // content: Column( // crossAxisAlignment: CrossAxisAlignment.start, // children: [ // Text('Claim Number: 4315440'), // Text('Registration Date: 05-05-2025'), // ], // ), // isActive: true, // state: StepState.complete, // ), // Step( // title: Text('Step 4: QUERY DOCUMENT REQUIRED'), // content: Text('Query Received Date: 05-05-2025'), // isActive: true, // state: StepState.complete, // ), // Step( // title: Text('Step 5: APPROVED'), // content: Column( // crossAxisAlignment: CrossAxisAlignment.start, // children: [ // Text('Approved Amount: 4315440'), // Text('Approved Date: 05-05-2025'), // Text('Approved Letter: Lorem ipsum...'), // Text('Description: Lorem ipsum...'), // ], // ), // isActive: true, // state: StepState.complete, // ), // ], // ), // ) // Column( // crossAxisAlignment: CrossAxisAlignment.start, // children: List.generate(5, (index) { // return _buildStep( // stepNumber: index + 1, // title: _getStepTitle(index), // content: _getStepContent(index), // isLast: index == 4, // ); // }), // ) isLoading ? Container( // color: Color(0x98FFFCE5), // Semi-transparent background child: Center( child: // Your GIF loader widget Image.asset( height: 60, width: 60, 'assets/nhance-loader.gif'), // Adjust path to your GIF loader ), ) : Container( child: getClaimsHistoryList.isNotEmpty ? Column( crossAxisAlignment: CrossAxisAlignment.start, children: List.generate(stepKeys.length, (index) { String stepTitleKey = stepKeys[index]; Map stepData = stepMap[stepTitleKey]; print('stepTitleKey'); print(stepTitleKey); print('stepData'); print(stepData); Widget content = _getStepContentFromApi(stepData); print('check'); print(context); // // 🟡 Skip step if there's no valid content (e.g., ID NOT GENERATED case) // if ((content as Column).children.isEmpty) { // print( // "Skipping step $stepTitleKey due to no valid content"); // content = Text("No content available", // style: TextStyle(color: Colors.grey)); // // or `return Container()` // } // if (content == null) { // print( // "Skipping step: $stepTitleKey due to no valid content"); // return const SizedBox(); // Completely skip step // } return _buildStep( stepNumber: index + 1, title: _getStepTitleFromApi( stepTitleKey, stepData), content: content, // content: _getStepContentFromApi(stepData), isLast: index == stepKeys.length - 1, ); }), ) : Container( height: MediaQuery.of(context).size.height * 0.4, // color: Colors.red, child: Center( child: Column( children: [ Image.asset( 'assets/claimsData.png', // Replace 'default_image.png' with your default image asset path width: 350, height: 350, fit: BoxFit.cover, ), const Text( 'No Available Claims', style: TextStyle( fontWeight: FontWeight.w500, fontSize: 15), ), ], )), ), ) ], ), ), ); } Widget _buildStep({ required int stepNumber, // required String title, required Widget title, required Widget content, bool isLast = false, }) { print(title); print("contentss - $content"); final noContent; if ((content as Column).children.isEmpty) { noContent = 0; } else { noContent = 1; } return Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ // Left Column with circle + line Column( children: [ // Add top spacing before circle SizedBox(height: stepNumber == 1 ? 0 : 4), // Step number circle Container( height: 28, width: 28, decoration: BoxDecoration( color: Color(0xFF00A5A8), shape: BoxShape.circle, ), alignment: Alignment.center, child: Text( '$stepNumber', style: TextStyle( color: Colors.white, fontSize: 13, fontWeight: FontWeight.w600, ), ), ), // Dotted line below circle (except for last step) if (!isLast) Container( height: noContent == 1 ? 70 : 25, // increase to extend line width: 2, margin: EdgeInsets.only(top: 4, bottom: 4), child: CustomPaint( painter: DottedLinePainter(), ), ), ], ), SizedBox(width: 12), // Right Side: Step title and content Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ title, if (noContent == 1) SizedBox(height: noContent == 0 ? 0 : 8), if (noContent == 1) Container( width: double.infinity, padding: EdgeInsets.all(12), decoration: BoxDecoration( color: Color(0xFFF7F7F7), borderRadius: BorderRadius.circular(8), border: Border.all(color: Color(0xFFE0E0E0)), ), child: content, ), if (noContent == 1) SizedBox(height: isLast ? 0 : 16), ], ), ), ], ); } // String _getStepTitleFromApi(String status, Map data) { // final modifiedBy = data['modified_by'] ?? ''; // final modifiedAt = data['modified_at'] ?? ''; // return '$status ($modifiedBy – $modifiedAt)'; // } Widget _getStepTitleFromApi(String status, Map data) { final modifiedBy = data['modified_by'] ?? ''; final modifiedAt = data['modified_at'] ?? ''; final symbol = (data['modified_by'] != null && data['modified_by'] != '') ? ' - ' : ''; return RichText( text: TextSpan( children: [ TextSpan( text: status, style: GoogleFonts.poppins( fontSize: 15, fontWeight: FontWeight.w500, color: Color(0xFF212120), // Status color ), ), TextSpan( text: ' ($modifiedBy$symbol$modifiedAt)', style: GoogleFonts.poppins( fontSize: 14, fontWeight: FontWeight.w400, color: Color(0xFF565656), // Subtitle color ), ), ], ), ); } Widget _getStepContentFromApi(Map data) { List rows = []; print("data - $data"); // bool hasDisplayFields(Map map) { // for (var entry in map.entries) { // if (entry.value is Map) { // final innerMap = entry.value as Map; // if (innerMap.containsKey('display_name') || // innerMap.containsKey('display_value')) { // print("display fields found"); // return true; // } // } // } // return false; // } // // if (!hasDisplayFields(data)) { // print("❌ Skipping because no display fields found"); // return SizedBox.shrink(); // or return an empty Container/Spacer if needed // } data.forEach((key, value) { // Skip metadata if (key == 'modified_by' || key == 'modified_at') return; if (value is Map) { final displayName = value['display_name']; final displayValue = value['display_value']; if (displayName != null && displayValue != null) { print("✅ displayName - $displayName, displayValue - $displayValue"); rows.add(_buildHistoryListData(displayName, displayValue)); rows.add(SizedBox(height: 6)); } } }); // data.forEach((key, value) { // // Skip metadata fields // if (key == 'modified_by' || key == 'modified_at') return; // print("ContentKey - $key"); // print("Content - $value"); // String displayName = value['display_name'] ?? key; // String displayValue = value['display_value'] ?? 'N/A'; // // print("displayName - $displayName"); // print("displayValue - $displayValue"); // if (displayName == 'N/A' || displayValue == 'N/A') return; // // rows.add(_buildHistoryListData(displayName, displayValue)); // rows.add(SizedBox(height: 6)); // }); return Column( crossAxisAlignment: CrossAxisAlignment.start, children: rows, ); } Widget _buildKeyValue(String title, String value) { final displayValue = (value == null || value.trim().isEmpty) ? 'N/A' : value; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( title, style: GoogleFonts.poppins( color: Color(0xFF747474), fontWeight: FontWeight.w400, fontSize: 16, ), ), SizedBox(height: 4), Text( displayValue, style: GoogleFonts.poppins( color: Color(0xFF000000), fontWeight: FontWeight.w500, fontSize: 16, ), ), ], ); } Widget _buildHistoryListData(String title, String value) { print("_buildHistoryListData"); final displayValue = (value == null || value.trim().isEmpty) ? 'N/A' : value; return Padding( padding: const EdgeInsets.symmetric(vertical: 6), // optional spacing child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.center, children: [ // Title - Align to center left Expanded( child: Align( alignment: Alignment.centerLeft, child: Text( title, style: GoogleFonts.poppins( color: const Color(0xFF747474), fontWeight: FontWeight.w400, fontSize: 14, ), ), ), ), // Value - Align to center right Expanded( child: Align( alignment: Alignment.centerRight, child: Text( displayValue, style: GoogleFonts.poppins( color: const Color(0xFF000000), fontWeight: FontWeight.w400, fontSize: 14, ), ), ), ), ], ), ); } } class DottedLinePainter extends CustomPainter { @override void paint(Canvas canvas, Size size) { const dashHeight = 2.0; const dashSpace = 3.0; double startY = 0; final paint = Paint() ..color = Colors.grey.shade400 ..strokeWidth = 1; while (startY < size.height) { canvas.drawLine( Offset(0, startY), Offset(0, startY + dashHeight), paint, ); startY += dashHeight + dashSpace; } } @override bool shouldRepaint(CustomPainter oldDelegate) => false; }