enrollment-app/lib/claimshistory.dart
2026-01-09 10:02:34 +05:30

657 lines
22 KiB
Dart
Executable File
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<ClaimHistoryPopup> createState() => _ClaimHistoryPopupState();
}
class _ClaimHistoryPopupState extends State<ClaimHistoryPopup> {
late ApiService apiService;
List<Map<String, dynamic>> getClaimsHistoryList = [];
List<String> stepKeys = [];
late Map<String, dynamic> 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<void> 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<String, dynamic>.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>[
// 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<String, dynamic> 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<String, dynamic> data) {
// final modifiedBy = data['modified_by'] ?? '';
// final modifiedAt = data['modified_at'] ?? '';
// return '$status ($modifiedBy $modifiedAt)';
// }
Widget _getStepTitleFromApi(String status, Map<String, dynamic> 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<String, dynamic> data) {
List<Widget> rows = [];
print("data - $data");
// bool hasDisplayFields(Map<String, dynamic> map) {
// for (var entry in map.entries) {
// if (entry.value is Map<String, dynamic>) {
// final innerMap = entry.value as Map<String, dynamic>;
// 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<String, dynamic>) {
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;
}