949 lines
37 KiB
Dart
Executable File
949 lines
37 KiB
Dart
Executable File
import 'dart:convert';
|
|
import 'package:flutter/foundation.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_svg/flutter_svg.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
import 'package:google_fonts/google_fonts.dart';
|
|
import 'package:jwt_decode/jwt_decode.dart';
|
|
import 'package:nhance_app_pwa/customAppBar/customAppBar.dart';
|
|
import 'package:nhance_app_pwa/pages/postEnrollment/service/api_service.dart';
|
|
import 'package:nhance_app_pwa/pages/postEnrollment/service/svg_service.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:video_player/video_player.dart';
|
|
|
|
import '../../customAppBar/customFooter.dart';
|
|
import '../../customAppBar/responsive.dart';
|
|
import '../../customAppBar/tabs.dart';
|
|
import '../../customAppBar/toastHelper.dart';
|
|
import '../helpers/custom_download_snackbar.dart';
|
|
import '../helpers/ecard_download_notification_service.dart';
|
|
import '../helpers/ecard_download_service.dart';
|
|
import '../service/SessionManager.dart';
|
|
import '../service/TokenService.dart';
|
|
import '../service/multi_video_player.dart';
|
|
import '../service/popup_helper.dart';
|
|
|
|
import '../helpers/aligned_html_content.dart';
|
|
import 'package:nhance_app_pwa/logger.dart';
|
|
|
|
class claimprocess extends StatefulWidget {
|
|
const claimprocess({Key? key}) : super(key: key);
|
|
|
|
@override
|
|
State<claimprocess> createState() => _claimprocessState();
|
|
}
|
|
|
|
class _claimprocessState extends State<claimprocess> {
|
|
late ApiService apiService;
|
|
bool isLoading = false;
|
|
bool isActive = true;
|
|
dynamic _token;
|
|
dynamic empCodeString;
|
|
dynamic empPrimaryId;
|
|
dynamic client_id;
|
|
dynamic mobileNo;
|
|
dynamic client_branch_id;
|
|
dynamic emailId;
|
|
List<Map<String, dynamic>> policyList = [];
|
|
bool _isDownloadingClaimForm = false;
|
|
final EcardDownloadService _ecardDownloadService = const EcardDownloadService();
|
|
dynamic cashLessClaimsDetails;
|
|
dynamic reimbursementClaimsDetails;
|
|
dynamic cashLessSectionName;
|
|
dynamic cashLessHeading;
|
|
late Map<String, String> cashLessContent;
|
|
late Map<String, String> cashLessNotes;
|
|
|
|
dynamic reimbursementSectionName;
|
|
dynamic reimbursementHeading;
|
|
late Map<String, String> reimbursementContent;
|
|
late Map<String, String> reimbursementNotes;
|
|
final session = SessionManager();
|
|
String? cashLessContentHtml;
|
|
String? cashLessNotesHtml;
|
|
|
|
String? reimbursementContentHtml;
|
|
String? reimbursementNotesHtml;
|
|
|
|
List<String> multiVideoUrlsList = [];
|
|
|
|
final PageController _videoPageController = PageController();
|
|
int _currentVideoIndex = 0;
|
|
|
|
final List<VideoPlayerController> _videoControllers = [];
|
|
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
apiService = ApiService(context); // Initialize ApiService here
|
|
_loadToken();
|
|
}
|
|
|
|
@override
|
|
void dispose() {
|
|
for (final controller in _videoControllers) {
|
|
controller.dispose();
|
|
}
|
|
_videoPageController.dispose();
|
|
super.dispose();
|
|
}
|
|
|
|
|
|
Future<void> _loadToken() async {
|
|
logDebug('_loadToken');
|
|
final String? token = await TokenService.getPostToken();
|
|
if (token != null && token.isNotEmpty) {
|
|
// Decode the JWT token received from the API response
|
|
Map<String, dynamic>? decodedToken = Jwt.parseJwt(token);
|
|
logDebug(decodedToken);
|
|
empCodeString = session.empCodeString;
|
|
logDebug(empCodeString); // Check if emp_code is correct
|
|
empPrimaryId = session.empPrimaryId;
|
|
client_id = session.client_id;
|
|
mobileNo = session.mobileNo;
|
|
client_branch_id = session.empClientBranchId;
|
|
emailId = session.empEmailCorporate ?? '';
|
|
logDebug(client_id);
|
|
getCashlessAndReimbursement();
|
|
getActiveAndInactivePolicyDetails();
|
|
}
|
|
}
|
|
|
|
Future<void> getActiveAndInactivePolicyDetails() async {
|
|
if (client_id == null || empCodeString == null) {
|
|
return;
|
|
}
|
|
|
|
try {
|
|
final responseActive = await apiService.getActiveAndInactivePolicyDetails(
|
|
client_id!, empCodeString!, 'Active', client_branch_id, mobileNo, emailId);
|
|
|
|
final responseInactive = await apiService.getActiveAndInactivePolicyDetails(
|
|
client_id!, empCodeString!, 'Inactive', client_branch_id, mobileNo, emailId);
|
|
|
|
final bool isActiveSuccess = responseActive['status'] == 'success' &&
|
|
responseActive['data'] != null;
|
|
final bool isInactiveSuccess = responseInactive['status'] == 'success' &&
|
|
responseInactive['data'] != null;
|
|
|
|
final List<Map<String, dynamic>> activeData = isActiveSuccess
|
|
? List<Map<String, dynamic>>.from(responseActive['data'])
|
|
: [];
|
|
|
|
final List<Map<String, dynamic>> inactiveData = isInactiveSuccess
|
|
? List<Map<String, dynamic>>.from(responseInactive['data'])
|
|
: [];
|
|
|
|
final retailPolicyDetails =
|
|
List.from(responseActive['retail_policy_data'] ?? []);
|
|
|
|
final filteredRetail = retailPolicyDetails
|
|
.where((item) => item.containsKey('policy_transaction_id'))
|
|
.toList();
|
|
|
|
final combinedPolicies = [...activeData, ...inactiveData, ...filteredRetail];
|
|
|
|
if (mounted) {
|
|
setState(() {
|
|
policyList = combinedPolicies
|
|
.where((policy) =>
|
|
policy['client_policy_id'] != null &&
|
|
policy['client_policy_id'].toString().trim().isNotEmpty)
|
|
.map((policy) => Map<String, dynamic>.from(policy))
|
|
.toList();
|
|
});
|
|
}
|
|
} catch (e) {
|
|
logDebug('Error fetching policies for claim form: $e');
|
|
}
|
|
}
|
|
|
|
String _policyDropdownLabel(Map<String, dynamic> policy) {
|
|
final name = policy['policy_name'] ?? policy['heading'] ?? '';
|
|
final no = policy['policy_no'] ?? '';
|
|
if (name.toString().isNotEmpty && no.toString().isNotEmpty) {
|
|
return '$name - $no';
|
|
}
|
|
return name.toString().isNotEmpty ? name.toString() : no.toString();
|
|
}
|
|
|
|
bool _isApiSuccess(Map<String, dynamic> response) {
|
|
final status = response['status'];
|
|
return status == true || status == 'success';
|
|
}
|
|
|
|
String? _extractDownloadUrl(dynamic data) {
|
|
if (data == null) return null;
|
|
if (data is Map && data['download_url'] != null) {
|
|
final url = data['download_url'].toString().trim();
|
|
if (url.isNotEmpty) return url;
|
|
}
|
|
if (data is String && data.trim().isNotEmpty) return data.trim();
|
|
return null;
|
|
}
|
|
|
|
void _showInsurerClaimFormPopup() {
|
|
if (policyList.isEmpty) {
|
|
ToastHelper.showErrorToast(context, 'No policies available');
|
|
return;
|
|
}
|
|
|
|
String? selectedClientPolicyId = policyList.first['client_policy_id']?.toString();
|
|
|
|
showDialog(
|
|
context: context,
|
|
barrierDismissible: true,
|
|
builder: (dialogContext) {
|
|
return StatefulBuilder(
|
|
builder: (context, setDialogState) {
|
|
return AlertDialog(
|
|
shape: RoundedRectangleBorder(
|
|
borderRadius: BorderRadius.circular(12),
|
|
),
|
|
title: Text(
|
|
'Insurer Claim Form',
|
|
style: GoogleFonts.poppins(
|
|
fontSize: Responsive.isDesktop(context) ? 20 : 18,
|
|
fontWeight: FontWeight.w600,
|
|
color: const Color(0xFF000000),
|
|
),
|
|
),
|
|
content: SizedBox(
|
|
width: Responsive.isDesktop(context) ? 420 : double.maxFinite,
|
|
child: DropdownButtonFormField<String>(
|
|
value: selectedClientPolicyId,
|
|
decoration: InputDecoration(
|
|
labelText: 'Select Policy',
|
|
border: const OutlineInputBorder(),
|
|
labelStyle: GoogleFonts.poppins(
|
|
fontSize: 14,
|
|
color: const Color(0xFF636363),
|
|
),
|
|
),
|
|
items: policyList.map((policy) {
|
|
final clientPolicyId =
|
|
policy['client_policy_id']?.toString() ?? '';
|
|
return DropdownMenuItem<String>(
|
|
value: clientPolicyId,
|
|
child: Text(
|
|
_policyDropdownLabel(policy),
|
|
style: GoogleFonts.poppins(
|
|
fontSize: 14,
|
|
color: const Color(0xFF000000),
|
|
),
|
|
),
|
|
);
|
|
}).toList(),
|
|
onChanged: (value) {
|
|
setDialogState(() {
|
|
selectedClientPolicyId = value;
|
|
});
|
|
},
|
|
),
|
|
),
|
|
actions: [
|
|
TextButton(
|
|
onPressed: () => Navigator.pop(dialogContext),
|
|
child: Text(
|
|
'Cancel',
|
|
style: GoogleFonts.poppins(
|
|
color: const Color(0xFF636363),
|
|
fontWeight: FontWeight.w500,
|
|
),
|
|
),
|
|
),
|
|
TextButton(
|
|
onPressed: _isDownloadingClaimForm ||
|
|
selectedClientPolicyId == null ||
|
|
selectedClientPolicyId!.isEmpty
|
|
? null
|
|
: () async {
|
|
await _downloadInsurerClaimForm(
|
|
selectedClientPolicyId!,
|
|
dialogContext,
|
|
);
|
|
},
|
|
child: Text(
|
|
'Download',
|
|
style: GoogleFonts.poppins(
|
|
color: const Color(0xFFE26728),
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
);
|
|
},
|
|
);
|
|
},
|
|
);
|
|
}
|
|
|
|
Future<void> _downloadInsurerClaimForm(
|
|
String clientPolicyId,
|
|
BuildContext dialogContext,
|
|
) async {
|
|
if (_isDownloadingClaimForm) return;
|
|
|
|
setState(() => _isDownloadingClaimForm = true);
|
|
|
|
try {
|
|
final response =
|
|
await apiService.getInsurerClaimFormDownloadUrl(clientPolicyId);
|
|
|
|
if (!mounted) return;
|
|
|
|
if (!_isApiSuccess(response)) {
|
|
ToastHelper.showErrorToast(
|
|
context,
|
|
response['message']?.toString() ?? 'Unable to download claim form',
|
|
);
|
|
return;
|
|
}
|
|
|
|
final downloadUrl = _extractDownloadUrl(response['data']);
|
|
if (downloadUrl == null || downloadUrl.isEmpty) {
|
|
ToastHelper.showErrorToast(
|
|
context,
|
|
response['message']?.toString() ?? 'Claim form is not available',
|
|
);
|
|
return;
|
|
}
|
|
|
|
final successMessage = response['message']?.toString() ??
|
|
'Claim form downloaded successfully';
|
|
|
|
final selectedPolicy = policyList.firstWhere(
|
|
(policy) =>
|
|
policy['client_policy_id']?.toString() == clientPolicyId,
|
|
orElse: () => {},
|
|
);
|
|
final policyNo = selectedPolicy['policy_no']?.toString();
|
|
final safePolicyNo =
|
|
policyNo?.replaceAll(RegExp(r'[^\w\-.]'), '_') ?? clientPolicyId;
|
|
final fileName = 'claim_form_$safePolicyNo.pdf';
|
|
|
|
if (!kIsWeb) {
|
|
CustomDownloadSnackbar.show(
|
|
context,
|
|
message: 'Downloading claim form...',
|
|
);
|
|
}
|
|
|
|
final token = await TokenService.getPostToken();
|
|
final result = await _ecardDownloadService.downloadEcard(
|
|
url: downloadUrl,
|
|
fileName: fileName,
|
|
headers: {
|
|
'APP-SIGNATURE':
|
|
'nhance-2025-signature-T8f6gV9k5fK2wf5V5c4vId3b0J8z6cAm2x8Y',
|
|
if (token != null && token.isNotEmpty)
|
|
'Authorization': 'Bearer $token',
|
|
},
|
|
);
|
|
|
|
if (!mounted) return;
|
|
|
|
if (result.success) {
|
|
if (dialogContext.mounted) {
|
|
Navigator.pop(dialogContext);
|
|
}
|
|
ToastHelper.showSuccessToast(context, successMessage);
|
|
if (!kIsWeb &&
|
|
result.savedPath != null &&
|
|
result.savedPath!.isNotEmpty) {
|
|
await EcardDownloadNotificationService.showDownloadCompleted(
|
|
filePath: result.savedPath!,
|
|
fileName: fileName,
|
|
);
|
|
}
|
|
} else {
|
|
ToastHelper.showErrorToast(
|
|
context,
|
|
result.message ?? 'Could not download claim form',
|
|
);
|
|
}
|
|
} catch (e) {
|
|
logDebug('Claim form download error: $e');
|
|
if (mounted) {
|
|
ToastHelper.showErrorToast(
|
|
context,
|
|
'Unable to download claim form. Please try again.',
|
|
);
|
|
}
|
|
} finally {
|
|
if (mounted) {
|
|
setState(() => _isDownloadingClaimForm = false);
|
|
}
|
|
}
|
|
}
|
|
|
|
Widget _buildInsurerClaimFormButton(BuildContext context) {
|
|
return MouseRegion(
|
|
cursor: SystemMouseCursors.click,
|
|
child: GestureDetector(
|
|
onTap: _showInsurerClaimFormPopup,
|
|
child: Card(
|
|
elevation: 0,
|
|
shape: RoundedRectangleBorder(
|
|
side: const BorderSide(
|
|
color: Color(0xFFD9D9D9),
|
|
width: 1.0,
|
|
),
|
|
borderRadius: BorderRadius.circular(8.0),
|
|
),
|
|
child: Container(
|
|
decoration: const BoxDecoration(
|
|
color: Colors.white,
|
|
),
|
|
padding: Responsive.isDesktop(context)
|
|
? const EdgeInsets.symmetric(
|
|
vertical: 15, horizontal: 15)
|
|
: const EdgeInsets.symmetric(
|
|
vertical: 20, horizontal: 10),
|
|
child: Row(
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
children: [
|
|
Expanded(
|
|
flex: 11,
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
children: [
|
|
SvgPicture.string(
|
|
SvgService.getSvg('general'),
|
|
width: 25,
|
|
height: 25,
|
|
),
|
|
const SizedBox(width: 10),
|
|
Text(
|
|
'Insurer Claim Form',
|
|
textAlign: TextAlign.start,
|
|
style: GoogleFonts.poppins(
|
|
fontSize: Responsive.isDesktop(context) ? 18 : 12,
|
|
fontWeight: FontWeight.w400,
|
|
color: const Color(0xFF404040),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
const Expanded(
|
|
flex: 1,
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.end,
|
|
children: [
|
|
Icon(
|
|
Icons.chevron_right,
|
|
color: Color(0xFFE26728),
|
|
size: 20,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<void> getCashlessAndReimbursement() async {
|
|
setState(() {
|
|
isLoading = true;
|
|
});
|
|
final response = await apiService.getCashlessAndReimbursementToApi();
|
|
logDebug('check 1 getCashlessAndReimbursement');
|
|
if (response['status'] == 'success') {
|
|
logDebug(response['data']);
|
|
setState(() {
|
|
cashLessClaimsDetails = response['data'][0];
|
|
cashLessSectionName = cashLessClaimsDetails['content_section'];
|
|
cashLessHeading = cashLessClaimsDetails['heading'];
|
|
|
|
cashLessContentHtml = cashLessClaimsDetails['content'];
|
|
cashLessNotesHtml = cashLessClaimsDetails['notes'];
|
|
|
|
reimbursementClaimsDetails = response['data'][1];
|
|
reimbursementSectionName = reimbursementClaimsDetails['content_section'];
|
|
reimbursementHeading = reimbursementClaimsDetails['heading'];
|
|
|
|
reimbursementContentHtml = reimbursementClaimsDetails['content'];
|
|
reimbursementNotesHtml = reimbursementClaimsDetails['notes'];
|
|
|
|
final List<dynamic> dataList = response['data'];
|
|
multiVideoUrlsList.clear();
|
|
for (final item in dataList) {
|
|
// ✅ FIND VIDEO SECTION
|
|
if (item['content_section'] == 'Video') {
|
|
final String? videoUrl = item['content'];
|
|
|
|
// ✅ SAFETY CHECK
|
|
if (videoUrl != null && videoUrl.trim().isNotEmpty) {
|
|
multiVideoUrlsList.add(videoUrl.trim());
|
|
}
|
|
}
|
|
}
|
|
|
|
/// ✅ DIRECT VIDEO FILE PATHS (MP4)
|
|
// multiVideoUrlsList = [
|
|
// "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/BigBuckBunny.mp4",
|
|
// "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/ElephantsDream.mp4",
|
|
// "https://commondatastorage.googleapis.com/gtv-videos-bucket/sample/Sintel.mp4",
|
|
// ];
|
|
|
|
|
|
isLoading = false;
|
|
});
|
|
await _initVideoControllers();
|
|
|
|
|
|
} else {
|
|
logDebug('API request failed with status: ${response['status']}');
|
|
}
|
|
}
|
|
|
|
Future<void> _initVideoControllers() async {
|
|
// ✅ Clear old controllers
|
|
for (final controller in _videoControllers) {
|
|
controller.dispose();
|
|
}
|
|
_videoControllers.clear();
|
|
|
|
for (final url in multiVideoUrlsList) {
|
|
final controller = VideoPlayerController.networkUrl(Uri.parse(url));
|
|
await controller.initialize();
|
|
controller.setLooping(true);
|
|
controller.setVolume(1);
|
|
_videoControllers.add(controller);
|
|
}
|
|
|
|
if (mounted) {
|
|
setState(() {});
|
|
}
|
|
}
|
|
|
|
|
|
|
|
ThemeData _buildPageTheme(BuildContext context) {
|
|
final isDesktop = Responsive.isDesktop(context);
|
|
final baseTheme = Theme.of(context);
|
|
|
|
return baseTheme.copyWith(
|
|
textTheme: GoogleFonts.poppinsTextTheme(baseTheme.textTheme).copyWith(
|
|
titleLarge: GoogleFonts.poppins(
|
|
fontSize: isDesktop ? 18 : 16,
|
|
fontWeight: FontWeight.w600,
|
|
color: const Color(0xFF000000),
|
|
),
|
|
titleMedium: GoogleFonts.poppins(
|
|
fontSize: isDesktop ? 18 : 16,
|
|
fontWeight: FontWeight.w500,
|
|
color: const Color(0xFF000000),
|
|
),
|
|
bodyLarge: GoogleFonts.poppins(
|
|
fontSize: isDesktop ? 16 : 14,
|
|
fontWeight: FontWeight.w400,
|
|
color: const Color(0xFF000000),
|
|
height: 1.5,
|
|
),
|
|
labelLarge: GoogleFonts.poppins(
|
|
fontSize: isDesktop ? 18 : 14,
|
|
fontWeight: FontWeight.w500,
|
|
color: const Color(0xFF593AFF),
|
|
),
|
|
labelMedium: GoogleFonts.poppins(
|
|
fontSize: isDesktop ? 18 : 14,
|
|
fontWeight: FontWeight.w400,
|
|
color: const Color(0xFF636363),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildHtmlContent(BuildContext context, String html) {
|
|
final bodyStyle = Theme.of(context).textTheme.bodyLarge ??
|
|
GoogleFonts.poppins(fontSize: 14, color: const Color(0xFF000000));
|
|
|
|
return AlignedHtmlContent(
|
|
html: html,
|
|
bodyStyle: bodyStyle,
|
|
markerWidth: Responsive.isDesktop(context) ? 36 : 32,
|
|
);
|
|
}
|
|
|
|
Widget _buildTabLabel({
|
|
required BuildContext context,
|
|
required String label,
|
|
required bool selected,
|
|
required VoidCallback onTap,
|
|
}) {
|
|
final isDesktop = Responsive.isDesktop(context);
|
|
final horizontalPadding = isDesktop ? 80.0 : 16.0;
|
|
final verticalPadding = isDesktop ? 12.0 : 10.0;
|
|
|
|
return GestureDetector(
|
|
onTap: onTap,
|
|
child: selected
|
|
? Material(
|
|
elevation: 5,
|
|
borderRadius: BorderRadius.circular(10),
|
|
color: Colors.white,
|
|
child: TextButton(
|
|
onPressed: onTap,
|
|
style: TextButton.styleFrom(
|
|
padding: EdgeInsets.symmetric(
|
|
horizontal: horizontalPadding,
|
|
vertical: verticalPadding,
|
|
),
|
|
),
|
|
child: Text(
|
|
label,
|
|
textAlign: TextAlign.center,
|
|
style: Theme.of(context).textTheme.labelLarge,
|
|
),
|
|
),
|
|
)
|
|
: Container(
|
|
width: double.infinity,
|
|
alignment: Alignment.center,
|
|
padding: EdgeInsets.symmetric(
|
|
horizontal: horizontalPadding,
|
|
vertical: verticalPadding,
|
|
),
|
|
child: Text(
|
|
label,
|
|
textAlign: TextAlign.center,
|
|
style: Theme.of(context).textTheme.labelMedium,
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return PopScope(
|
|
canPop: false,
|
|
onPopInvokedWithResult: (didPop, result) {
|
|
if (didPop) return;
|
|
// context.go('/claims');
|
|
context.pop();
|
|
},
|
|
child: Scaffold(
|
|
backgroundColor: Colors.white,
|
|
appBar: CustomAppBar(),
|
|
body: Theme(
|
|
data: _buildPageTheme(context),
|
|
child: Stack(
|
|
children: [
|
|
SingleChildScrollView(
|
|
child: Container(
|
|
padding: Responsive.isDesktop(context)
|
|
? EdgeInsets.symmetric(
|
|
horizontal: MediaQuery.of(context).size.width * 0.2,
|
|
vertical: MediaQuery.of(context).size.height * 0.03,
|
|
)
|
|
: const EdgeInsets.fromLTRB(16, 8, 16, 24),
|
|
color: Colors.white,
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Container(
|
|
padding: Responsive.isDesktop(context)
|
|
? EdgeInsets.symmetric(vertical: 15, horizontal: 25)
|
|
: EdgeInsets.all(0),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
children: [
|
|
Expanded(
|
|
flex: 12,
|
|
child: InkWell(
|
|
onTap: () {
|
|
// context.pop(); //
|
|
context.go('/claims');
|
|
},
|
|
child: Row(
|
|
mainAxisAlignment:
|
|
MainAxisAlignment.start,
|
|
children: [
|
|
// if (!Responsive.isDesktop(context))
|
|
Icon(
|
|
Icons.chevron_left,
|
|
color: Color(0xFF000000),
|
|
size: 30,
|
|
),
|
|
SizedBox(
|
|
width: Responsive.isDesktop(context)
|
|
? 0
|
|
: 5),
|
|
Column(
|
|
mainAxisAlignment:
|
|
MainAxisAlignment.center,
|
|
crossAxisAlignment:
|
|
CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
'Claim Process',
|
|
textAlign: TextAlign.start,
|
|
style: Theme.of(context)
|
|
.textTheme
|
|
.titleLarge,
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
),
|
|
SizedBox(height: 5),
|
|
if (multiVideoUrlsList.isNotEmpty) ...[
|
|
NhanceMultiVideoWrapper(
|
|
videoUrls: multiVideoUrlsList,
|
|
)
|
|
],
|
|
SizedBox(height: 15),
|
|
Container(
|
|
decoration: BoxDecoration(
|
|
color: Color(0xFFF6FAFF),
|
|
borderRadius: BorderRadius.circular(5),
|
|
),
|
|
padding: Responsive.isDesktop(context)
|
|
? EdgeInsets.symmetric(vertical: 15, horizontal: 25)
|
|
: const EdgeInsets.all(8),
|
|
child: Row(
|
|
children: [
|
|
Expanded(
|
|
child: _buildTabLabel(
|
|
context: context,
|
|
label: cashLessSectionName ?? '',
|
|
selected: isActive,
|
|
onTap: () => setState(() => isActive = true),
|
|
),
|
|
),
|
|
const SizedBox(width: 8),
|
|
Expanded(
|
|
child: _buildTabLabel(
|
|
context: context,
|
|
label: reimbursementSectionName ?? '',
|
|
selected: !isActive,
|
|
onTap: () => setState(() => isActive = false),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
SizedBox(height: 15),
|
|
if (isActive)
|
|
Container(
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(5),
|
|
),
|
|
padding: Responsive.isDesktop(context)
|
|
? const EdgeInsets.symmetric(
|
|
vertical: 10, horizontal: 10)
|
|
: EdgeInsets.zero,
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
if (cashLessContentHtml != null)
|
|
Padding(
|
|
padding:
|
|
const EdgeInsets.only(bottom: 16),
|
|
child: Column(
|
|
crossAxisAlignment:
|
|
CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
cashLessHeading ?? '',
|
|
textAlign: TextAlign.start,
|
|
style: Theme.of(context)
|
|
.textTheme
|
|
.titleMedium,
|
|
),
|
|
const SizedBox(height: 8),
|
|
_buildHtmlContent(
|
|
context,
|
|
cashLessContentHtml!,
|
|
),
|
|
]
|
|
)
|
|
),
|
|
if (cashLessNotesHtml != null)
|
|
Padding(
|
|
padding:
|
|
const EdgeInsets.only(bottom: 10),
|
|
child: Column(
|
|
crossAxisAlignment:
|
|
CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
'Notes',
|
|
textAlign: TextAlign.start,
|
|
style: Theme.of(context)
|
|
.textTheme
|
|
.titleMedium,
|
|
),
|
|
const SizedBox(height: 8),
|
|
_buildHtmlContent(
|
|
context,
|
|
cashLessNotesHtml!,
|
|
),
|
|
],
|
|
),
|
|
)
|
|
]),
|
|
)
|
|
else
|
|
Container(
|
|
decoration: BoxDecoration(
|
|
borderRadius: BorderRadius.circular(5),
|
|
),
|
|
padding: Responsive.isDesktop(context)
|
|
? const EdgeInsets.symmetric(
|
|
vertical: 10, horizontal: 10)
|
|
: EdgeInsets.zero,
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
if (reimbursementContentHtml != null)
|
|
Padding(
|
|
padding:
|
|
const EdgeInsets.only(bottom: 16),
|
|
child: Column(
|
|
crossAxisAlignment:
|
|
CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
reimbursementHeading ?? '',
|
|
textAlign: TextAlign.start,
|
|
style: Theme.of(context)
|
|
.textTheme
|
|
.titleMedium,
|
|
),
|
|
const SizedBox(height: 8),
|
|
_buildHtmlContent(
|
|
context,
|
|
reimbursementContentHtml!,
|
|
),
|
|
]
|
|
)
|
|
),
|
|
|
|
if (reimbursementNotesHtml != null)
|
|
Padding(
|
|
padding:
|
|
const EdgeInsets.only(bottom: 10),
|
|
child: Column(
|
|
crossAxisAlignment:
|
|
CrossAxisAlignment.start,
|
|
children: [
|
|
Text(
|
|
'Notes',
|
|
textAlign: TextAlign.start,
|
|
style: Theme.of(context)
|
|
.textTheme
|
|
.titleMedium,
|
|
),
|
|
const SizedBox(height: 8),
|
|
_buildHtmlContent(
|
|
context,
|
|
reimbursementNotesHtml!,
|
|
),
|
|
]
|
|
)
|
|
),
|
|
|
|
]),
|
|
),
|
|
_buildInsurerClaimFormButton(context),
|
|
SizedBox(height: Responsive.isDesktop(context) ? 40 : 10),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
if (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
|
|
),
|
|
),
|
|
if (Responsive.isDesktop(context))
|
|
Align(
|
|
alignment: Alignment.bottomCenter,
|
|
child: Container(
|
|
width: double.infinity,
|
|
child: CustomFooter(),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
// floatingActionButton: Responsive.isDesktop(context)
|
|
// ? null
|
|
// : FloatingActionButton(
|
|
// onPressed: () {
|
|
// Navigator.pushNamed(context, 'chatbot');
|
|
// },
|
|
// child: Icon(Icons.chat),
|
|
// ),
|
|
floatingActionButtonLocation: Responsive.isDesktop(context)
|
|
? null
|
|
: FloatingActionButtonLocation.miniEndFloat,
|
|
bottomNavigationBar: Responsive.isDesktop(context)
|
|
? null
|
|
: CustomBottomNavigationBar(
|
|
onTabChanged: (index) {
|
|
// Add your navigation logic here
|
|
// repositionBotman();
|
|
if (index == 0) {
|
|
context.push('/home');
|
|
} else if (index == 1) {
|
|
context.push('/claims');
|
|
} else if (index == 2) {
|
|
context.push('/faqs');
|
|
} else if (index == 3) {
|
|
context.push('/profile');
|
|
} else if (index == 4) {
|
|
context.push('/help');
|
|
}
|
|
// else if (index == 4) {
|
|
// // context.push('/wellness');
|
|
// // Wellness tab clicked → show popup
|
|
// if(!isRetailLoggedIn)
|
|
// PopupHelper.showRedirectPopup(
|
|
// context: context,
|
|
// apiService: apiService,
|
|
// empPrimaryId: session.empPrimaryId,
|
|
// );
|
|
// }
|
|
},
|
|
icons: [
|
|
Icons.home_outlined,
|
|
Icons.sticky_note_2_outlined,
|
|
Icons.question_answer_outlined,
|
|
Icons.person_outline_outlined,
|
|
Icons.headset_mic_outlined,
|
|
],
|
|
labels: ["Home", "Claims", "FAQs", "Profile","Help"],
|
|
initialIndex: 0, // Initial index of the bottom navigation bar
|
|
),
|
|
));
|
|
}
|
|
|
|
}
|