import 'dart:convert'; import 'package:flutter/material.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:shared_preferences/shared_preferences.dart'; import 'package:http/http.dart' as http; import '../../customAppBar/customFooter.dart'; import '../../customAppBar/responsive.dart'; import '../../customAppBar/tabs.dart'; import '../../customAppBar/toastHelper.dart'; import '../service/SessionManager.dart'; import '../service/TokenService.dart'; import '../service/popup_helper.dart'; import 'package:nhance_app_pwa/logger.dart'; class generalExclusionsDeductibles extends StatefulWidget { const generalExclusionsDeductibles({Key? key}) : super(key: key); @override State createState() => _generalExclusionsDeductiblesState(); } class _generalExclusionsDeductiblesState extends State { late ApiService apiService; int _currentIndex = 0; bool isActive = true; bool isLoading = false; dynamic _token; dynamic empCodeString; dynamic empPrimaryId; dynamic client_id; dynamic generalExclusionsDetails; dynamic reimbursementClaimsDetails; dynamic generalSectionName; dynamic generalHeading; late Map generalContent; late Map generalNotes; // Headings String? type3SectionName, type3Heading; String? type4SectionName, type4Heading; String? type5Heading; String? type6Heading; String? type7Heading; // Content lists List type3Content = []; List type4Content = []; List type5Content = []; List type6Content = []; List type7Content = []; final session = SessionManager(); @override void initState() { super.initState(); apiService = ApiService(context); // Initialize ApiService here _loadToken(); } @override void dispose() { super.dispose(); } Future _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? 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; logDebug(client_id); getCashlessAndReimbursement(); } } /// 🔥 Extract
  • text from HTML List extractListItems(String html) { final regex = RegExp(r'
  • (.*?)<\/li>', dotAll: true); return regex .allMatches(html) .map((m) => m.group(1)!.replaceAll(RegExp(r'<[^>]*>'), '').trim()) .toList(); } Future getCashlessAndReimbursement() async { setState(() => isLoading = true); try { final response = await apiService.getCashlessAndReimbursementToApi(); if (response['status'] != 'success') { setState(() => isLoading = false); return; } final List data = response['data']; final filtered = data.where((e) => e['content_section'] != 'Video').toList(); Map? findType(String type) { try { return filtered.firstWhere((e) => e['type'] == type); } catch (_) { return null; } } final t3 = findType('3'); final t4 = findType('4'); final t5 = findType('5'); final t6 = findType('6'); final t7 = findType('7'); setState(() { if (t3 != null) { type3SectionName = t3['content_section']; type3Heading = t3['heading']; type3Content = extractListItems(t3['content']); } if (t4 != null) { type4Heading = t4['heading']; type4Content = extractListItems(t4['content']); } if (t5 != null) { type5Heading = t5['heading']; type5Content = extractListItems(t5['content']); } if (t6 != null) { type6Heading = t6['heading']; type6Content = extractListItems(t6['content']); } if (t7 != null) { type7Heading = t7['heading']; type7Content = extractListItems(t7['content']); } isLoading = false; }); } catch (e) { logDebug('API ERROR: $e'); setState(() => isLoading = false); } } 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, ), ), ); } @override Widget build(BuildContext context) { return PopScope( canPop: false, onPopInvokedWithResult: (didPop, result) { if (didPop) return; context.pop(); }, child: Scaffold( appBar: CustomAppBar(), backgroundColor: Colors.white, body: Theme( data: _buildPageTheme(context), child: 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 ), ) : SingleChildScrollView( padding: Responsive.isDesktop(context) ? EdgeInsets.symmetric( horizontal: MediaQuery.of(context).size.width * 0.2, vertical: MediaQuery.of(context).size.height * 0.03, ) : EdgeInsets.all(10), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.start, children: [ Expanded( flex: 12, child: InkWell( onTap: () { context.go('/home'); }, child: Row( mainAxisAlignment: MainAxisAlignment.start, children: [ 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( 'General Exclusions & Deductibles', textAlign: TextAlign.start, style: Theme.of(context) .textTheme .titleLarge, ), ], ), ], ), ), ), ], ), const SizedBox(height: 20), if (type3Content.isNotEmpty) ...[ Text( type3SectionName ?? '', style: Theme.of(context).textTheme.titleMedium, ), const SizedBox(height: 10), buildBulletList(context, type3Content), ], if (type4Content.isNotEmpty) ...[ const SizedBox(height: 20), Text( type4Heading ?? '', style: Theme.of(context).textTheme.titleMedium, ), buildBulletList(context, type4Content), ], if (type5Content.isNotEmpty) ...[ const SizedBox(height: 20), Text( type5Heading ?? '', style: Theme.of(context).textTheme.titleMedium, ), buildBulletList(context, type5Content), ], if (type6Content.isNotEmpty) ...[ const SizedBox(height: 20), Text( type6Heading ?? '', style: Theme.of(context).textTheme.titleMedium, ), buildBulletList(context, type6Content), ], if (type7Content.isNotEmpty) ...[ const SizedBox(height: 20), Text( type7Heading ?? '', style: Theme.of(context).textTheme.titleMedium, ), buildBulletList(context, type7Content), ], ], ), ), ), bottomNavigationBar: Responsive.isDesktop(context) ? SizedBox( height: 40, // 👈 FIXED HEIGHT (adjust if needed) width: double.infinity, child: CustomFooter(), ) : CustomBottomNavigationBar( initialIndex: 0, labels: const ["Home", "Claims", "FAQs", "Profile", "Help"], icons: const [ Icons.home_outlined, Icons.sticky_note_2_outlined, Icons.question_answer_outlined, Icons.person_outline_outlined, Icons.headset_mic_outlined, ], onTabChanged: (index) { if (index == 0) context.push('/home'); if (index == 1) context.push('/claims'); if (index == 2) context.push('/faqs'); if (index == 3) context.push('/profile'); if (index == 4) context.push('/help'); }, ), )); } Widget buildBulletList(BuildContext context, List items) { if (items.isEmpty) return const SizedBox.shrink(); final bodyStyle = Theme.of(context).textTheme.bodyLarge; final bulletSize = bodyStyle?.fontSize ?? 14; return Column( crossAxisAlignment: CrossAxisAlignment.start, children: items.map((text) { return Padding( padding: const EdgeInsets.symmetric(vertical: 6), child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Padding( padding: const EdgeInsets.only(top: 2), child: Text( '•', style: bodyStyle?.copyWith( fontSize: bulletSize + 2, fontWeight: FontWeight.w600, color: const Color(0xFFE26728), ), ), ), const SizedBox(width: 8), Expanded( child: Text( text, style: bodyStyle, ), ), ], ), ); }).toList(), ); } }