import 'package:dropdown_search/dropdown_search.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:nhance_partner/presentation/screens/Enquiry/enquiry/policy_popup.dart'; import '../../../../core/services/api_service.dart'; import '../../../../data/services/auth_service.dart'; import '../../../../data/utils/Pagination.dart'; import '../../../../data/utils/validators.dart'; import '../../../layouts/main_layout.dart'; import '../../../layouts/responsive_layout.dart'; import '../../../providers/manager_provider.dart'; import '../../../themes/indicators/export_btn.dart'; import '../../../themes/indicators/search_field_theme.dart'; import '../../../themes/indicators/text_field_theme.dart'; import '../../../widgets/custom_action_popup.dart'; import '../policy_claims_endros/sub_claims.dart'; import '../policy_claims_endros/sub_endrosment.dart'; class PolicyTab extends ConsumerStatefulWidget { final List>? data; dynamic id; // const PolicyTab({super.key}); PolicyTab({super.key, this.data, this.id}); @override ConsumerState createState() => PolicyTabState(); } class PolicyTabState extends ConsumerState { final GlobalKey claimsKey = GlobalKey(); final GlobalKey enrollKey = GlobalKey(); List> dataVal = []; final TextEditingController _searchController = TextEditingController(); List> getQuotationData = []; List> originalData = []; List> filteredData = []; late ApiService apiService; final _formKey = GlobalKey(); bool isLoading = false; List tabHeader = [ 'regNum', 'insurer', 'idv', 'insurerName', 'policyNo', 'paymentMode', 'premAmount', 'planType', ]; Map controllers = {}; String? _token; dynamic userId; dynamic managerId; dynamic selectedPolicyNumber; @override void initState() { super.initState(); apiService = ApiService(); print("PolicyTab - Called"); for (String field in tabHeader) { controllers[field] = TextEditingController(); } // updateData(); _initializeToken(); Future.microtask(() { managerId = ref.watch(managerIdProvider); userId = ref.watch(userIdProvider); getPolicyList(managerId); }); } @override void dispose() { // Dispose all TextEditingControllers for (var controller in controllers.values) { controller.dispose(); } super.dispose(); } Future _initializeToken() async { _token = await AuthService.getToken(); print("APISERTOKEN - $_token"); } Future getPolicyList(int managerId) async { print('getPolicyList called MagId - $managerId'); setState(() { isLoading = true; }); try { // final response = await apiService.fetchQuotationList(managerId); if (widget.data != null) { // final data = List>.from(widget.data as Iterable); List> data; if (widget.data is List) { data = List>.from(widget.data as List); } else if (widget.data is Map) { data = [Map.from(widget.data as Map)]; } else { data = []; } print('policyListData - ${widget.data}'); setState(() { getQuotationData = data; // getQuotationData = List>.from(response['data']); originalData = getQuotationData; filteredData = List.from(originalData); // print('originalData - $getClaimPolicies'); updateData(filteredData); }); } else { getQuotationData = []; originalData = []; filteredData = []; } } catch (e) { print('Exception occurred: $e'); } finally { setState(() { isLoading = false; }); } } void updateData(data) { if (data != null && data is List && data.isNotEmpty) { final record = data[0]; // get the first map print('UPDID - $record'); setState(() { selectedPolicyNumber = record['policy_number']?.toString() ?? ''; controllers['regNum']?.text = record['reg_no']?.toString() ?? ''; controllers['insurer']?.text = record['insurer_name']?.toString() ?? ''; controllers['idv']?.text = record['insured_declared_value']?.toString() ?? ''; controllers['insurerName']?.text = record['insured_name']?.toString() ?? ''; controllers['policyNo']?.text = record['policy_number']?.toString() ?? ''; controllers['paymentMode']?.text = record['payment_mode_value']?.toString() ?? ''; controllers['premAmount']?.text = record['premium_amount']?.toString() ?? ''; controllers['planType']?.text = record['insurance_plan_type']?.toString() ?? ''; }); } } @override Widget build(BuildContext context) { final isMobile = ResponsiveLayout.isMobile(context); return isLoading ? CircularProgressIndicator() : 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(10.0) : EdgeInsets.all(16.0), child: Column( children: [ if (!ResponsiveLayout.isMobile(context)) ...[ Container( child: Row( children: [ Text( 'Policy Details', style: GoogleFonts.inter( fontWeight: FontWeight.bold, fontSize: 16, ), ), if (!ResponsiveLayout.isMobile( context, )) ...[ Spacer(), buildDocPolicy(context, isMobile), SizedBox(width: 15), buildDocReciept(context, isMobile), ], // GestureDetector( // onTap: () { // print("Upload ${widget.id}"); // final selectedId = widget.id; // // final path = // // 'agent/downloadAgentIncentiveFile?id=$selectedId'; // final path = // 'policy/downloadPolicyFile?policy_id=$selectedId&file_type=policy_payment_receipt'; // apiService.getPdfDownload(path, selectedId); // }, // child: Container( // padding: const EdgeInsets.all(8), // decoration: BoxDecoration( // borderRadius: BorderRadius.circular(5), // color: const Color(0xFF425B5B), // ), // child: Row( // children: const [ // Text( // "Download Receipt", // style: TextStyle( // fontSize: 12, // fontWeight: FontWeight.w200, // color: Colors.white, // ), // ), // SizedBox(width: 15), // Icon( // Icons.file_download_outlined, // size: 16, // color: Colors.white, // ), // ], // ), // ), // ), ], ), ), const SizedBox(height: 20), ], SingleChildScrollView( child: buildFormFields(context), ), isMobile ? SizedBox(height: 5) : SizedBox(height: 20), ], ), ), isMobile ? SizedBox(height: 5) : SizedBox(height: 20), 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: EdgeInsets.all(16.0), child: Column( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ Text( 'More Information (optional)', style: GoogleFonts.inter( fontWeight: FontWeight.bold, fontSize: 16, ), ), if (!ResponsiveLayout.isMobile(context)) ...[ SizedBox(height: 10), Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( width: 100, child: Text('Claim', style: _headerStyle), ), SizedBox(width: 20), Expanded( child: buildMoreInfoSetClaims(context), ), ], ), ], if (ResponsiveLayout.isMobile(context)) Container( padding: EdgeInsets.all(6.0), decoration: BoxDecoration( color: Color(0xFFF6FEFD), // color: Color(0xFFCBE6E2), borderRadius: BorderRadius.circular(10.0), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ SizedBox( width: 100, child: Text( 'Claim', style: _headerStyle, ), ), _actionClaims(context), ], ), SizedBox(width: 20), buildMoreInfoSetClaims(context), ], ), ), SizedBox(height: 10), if (!ResponsiveLayout.isMobile(context)) Row( mainAxisAlignment: MainAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start, children: [ SizedBox( width: 100, child: Text( 'Endorsement', style: _headerStyle, ), ), SizedBox(width: 20), Expanded( child: buildMoreInfoSetEndrosment( context, ), ), ], ), if (ResponsiveLayout.isMobile(context)) Container( padding: EdgeInsets.all(6.0), decoration: BoxDecoration( color: Color(0xFFF6FEFD), // color: Color(0xFFCBE6E2), borderRadius: BorderRadius.circular(10.0), ), child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ SizedBox( width: 100, child: Text( 'Endorsement', style: _headerStyle, ), ), _actionEnroll(context), ], ), SizedBox(width: 20), buildMoreInfoSetEndrosment(context), ], ), ), // SizedBox(height: 10), // Row( // mainAxisAlignment: MainAxisAlignment.end, // children: [ // GestureDetector( // onTap: () { // // handleSave(); // }, // child: Container( // padding: EdgeInsets.symmetric( // horizontal: 45.0, // vertical: 8, // ), // // decoration: BoxDecoration( // borderRadius: BorderRadius.circular( // 8.0, // ), // color: Color(0xFF425B5B), // ), // child: Text( // 'Save', // style: TextStyle(color: Colors.white), // ), // ), // ), // ], // ), // SizedBox(height: 30), // _buildDataTable(context), ], ), ), ], ), ) : Center(child: Text('No Available Data')), ) ); } Widget buildDocPolicy(BuildContext context, bool isMobile) { return GestureDetector( onTap: () { print("Upload ${widget.id}"); final selectedId = widget.id; // final path = // 'agent/downloadAgentIncentiveFile?id=$selectedId'; final path = 'policy/downloadPolicyFile?policy_id=$selectedId&file_type=policy_pdf'; apiService.getPdfDownload(path, selectedId); }, child: Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( borderRadius: BorderRadius.circular(5), color: const Color(0xFF425B5B), ), child: Row( children: [ const Text( "Download Policy", style: TextStyle( fontSize: 12, fontWeight: FontWeight.w200, color: Colors.white, ), ), isMobile ? const Spacer() : const SizedBox(width: 15), const Icon( Icons.file_download_outlined, size: 16, color: Colors.white, ), ], ), ), ); } Widget buildDocReciept(BuildContext context, bool isMobile) { return GestureDetector( onTap: () { print("Upload ${widget.id}"); final selectedId = widget.id; // final path = // 'agent/downloadAgentIncentiveFile?id=$selectedId'; final path = 'policy/downloadPolicyFile?policy_id=$selectedId&file_type=policy_payment_receipt'; apiService.getPdfDownload(path, selectedId); }, child: Container( padding: const EdgeInsets.all(8), decoration: BoxDecoration( borderRadius: BorderRadius.circular(5), color: const Color(0xFF425B5B), ), child: Row( children: [ Text( "Download Receipt", style: TextStyle( fontSize: 12, fontWeight: FontWeight.w200, color: Colors.white, ), ), isMobile ? const Spacer() : const SizedBox(width: 15), Icon(Icons.file_download_outlined, size: 16, color: Colors.white), ], ), ), ); } Widget buildMoreInfoSetClaims(BuildContext context) { if (selectedPolicyNumber == null || selectedPolicyNumber!.isEmpty) { // return const Center(child: CircularProgressIndicator()); // or placeholder return const Center( child: Text( 'No records available', textAlign: TextAlign.center,), ); } return Container( padding: ResponsiveLayout.isMobile(context) ? null : EdgeInsets.all(6.0), decoration: ResponsiveLayout.isMobile(context) ? null : BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(10.0), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: ClaimsSubList( key: claimsKey, policyNumber: selectedPolicyNumber, ), ), if (!ResponsiveLayout.isMobile(context)) _actionClaims(context), ], ), ); } Widget buildMoreInfoSetEndrosment(BuildContext context) { if (selectedPolicyNumber == null || selectedPolicyNumber!.isEmpty) { // return const Center(child: CircularProgressIndicator()); // or placeholder return const Center( child: Text( 'No records available', textAlign: TextAlign.center,), ); } return Container( // padding: EdgeInsets.all(8.0), // decoration: BoxDecoration( // color: Colors.white, // borderRadius: BorderRadius.circular(6.0), // ), padding: ResponsiveLayout.isMobile(context) ? null : EdgeInsets.all(6.0), decoration: ResponsiveLayout.isMobile(context) ? null : BoxDecoration( color: Colors.white, borderRadius: BorderRadius.circular(10.0), ), child: Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, crossAxisAlignment: CrossAxisAlignment.start, children: [ Expanded( child: EndrosmentSubList( key: enrollKey, policyNumber: selectedPolicyNumber, ), ), if (!ResponsiveLayout.isMobile(context)) _actionEnroll(context), ], ), ); } Widget _actionEnroll(BuildContext context) { return Tooltip( message: 'Add Endorsement', child: IconButton( onPressed: () { showDialog( context: context, builder: (ctx) => AddDialog( userId: userId, role: null, managerId: null, title: "Endorsement", // policyNumber: selectedPolicyNumber, onSubmit: (value) { debugPrint("New Endorsement: $value"); enrollKey.currentState?.getEndrosmentList(selectedPolicyNumber); // Update claim list or call API }, ), ); }, icon: Icon(Icons.add), ), ); } Widget _actionClaims(BuildContext context) { return Tooltip( message: 'Add Claim', child: IconButton( onPressed: () { showDialog( context: context, builder: (ctx) => AddDialog( userId: userId, title: "Claims", role: null, managerId: null, // policyNumber: selectedPolicyNumber, onSubmit: (value) { debugPrint("New Claim: $value"); claimsKey.currentState?.getClaimsList(selectedPolicyNumber); // Update claim list or call API }, ), ); }, icon: Icon(Icons.add), ), ); } Widget buildFormFields(BuildContext context) { final isMobile = ResponsiveLayout.isMobile(context); return Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ _buildResponsiveRow( context, buildName(context), buildInsusrer(context), ), isMobile ? SizedBox(height: 5) : SizedBox(height: 10), _buildResponsiveRow( context, buildIdv(context), buildInsurdName(context), ), isMobile ? SizedBox(height: 5) : SizedBox(height: 10), _buildResponsiveRow( context, buildPolicyNum(context), buildPaymentMode(context), ), isMobile ? SizedBox(height: 5) : SizedBox(height: 10), _buildResponsiveRow( context, buildPlanType(context), buildPremiumAmount(context), ), isMobile ? SizedBox(height: 5) : SizedBox(height: 10), if (ResponsiveLayout.isMobile(context)) _buildResponsiveRow( context, buildDocPolicy(context, isMobile), buildDocReciept(context, isMobile), ), ], ), ); } Widget _buildResponsiveRow( BuildContext context, Widget first, Widget second, ) { if (ResponsiveLayout.isMobile(context)) { // Stack vertically return Column(children: [first, const SizedBox(height: 4), second]); } else { // Place side by side return Row( children: [ Expanded(child: first), const SizedBox(width: 25), Expanded(child: second), ], ); } } 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 buildName(BuildContext context) { return buildResponsiveField( label: "Vehicle Number", field: ThemedFormField( controller: controllers['regNum']!, readOnly: true, // validator: (value) => Validators.requiredField(value, "name"), 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, // validator: (value) => Validators.phone(value, "phNumber"), txtwidth: ResponsiveLayout.isMobile(context) ? null : MediaQuery.of(context).size.width * 0.26, ), ); } Widget buildInsurdName(BuildContext context) { return buildResponsiveField( label: "Insured Name", field: ThemedFormField( controller: controllers['insurerName']!, readOnly: true, // validator: (value) => Validators.phone(value, "phNumber"), txtwidth: ResponsiveLayout.isMobile(context) ? null : MediaQuery.of(context).size.width * 0.26, ), ); } Widget buildPolicyNum(BuildContext context) { return buildResponsiveField( label: "Policy Number", field: ThemedFormField( controller: controllers['policyNo']!, readOnly: true, // validator: (value) => Validators.phone(value, "phNumber"), txtwidth: ResponsiveLayout.isMobile(context) ? null : MediaQuery.of(context).size.width * 0.26, ), ); } Widget buildPaymentMode(BuildContext context) { return buildResponsiveField( label: "Payment Mode", field: ThemedFormField( readOnly: true, controller: controllers['paymentMode']!, 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, // validator: (value) => Validators.phone(value, "phNumber"), txtwidth: ResponsiveLayout.isMobile(context) ? null : MediaQuery.of(context).size.width * 0.26, ), ); } Widget buildPremiumAmount(BuildContext context) { return buildResponsiveField( label: "Premium Amount", field: ThemedFormField( controller: controllers['premAmount']!, readOnly: true, // validator: (value) => Validators.phone(value, "phNumber"), txtwidth: ResponsiveLayout.isMobile(context) ? null : MediaQuery.of(context).size.width * 0.26, ), ); } static const _headerStyle = TextStyle( color: Colors.black, fontWeight: FontWeight.bold, ); static const _textStyle = TextStyle( fontSize: 14, fontWeight: FontWeight.w600, ); 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 _cardheaderStyle = TextStyle( color: Colors.black, fontWeight: FontWeight.w600, fontSize: 12, ); static const _cardBodyStyle = TextStyle( color: Color(0xFF545454), fontWeight: FontWeight.w400, fontSize: 12, ); }