import 'dart:io' as html; import 'package:dropdown_search/dropdown_search.dart'; import 'package:file_picker/file_picker.dart'; import 'package:flutter/cupertino.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:google_fonts/google_fonts.dart'; import 'package:nhance_partner/presentation/providers/userRoleProvider.dart'; import 'package:shared_preferences/shared_preferences.dart'; import '../../../../../core/routing/routes.dart'; import '../../../../../core/services/api_service.dart'; import '../../../../../data/services/auth_service.dart'; import '../../../../../data/utils/validators.dart'; import '../../../../layouts/main_layout.dart'; import '../../../../layouts/responsive_layout.dart'; import '../../../../providers/manager_provider.dart'; import '../../../../providers/quotation_staff_proivder.dart'; import '../../../../themes/indicators/text_field_theme.dart'; import '../../quotations/createQuotationPopUp.dart'; import 'createQuotation.dart'; import 'createQuotationOld.dart'; class PropoalStaffTab extends ConsumerStatefulWidget { String? id; List>? data; final Future Function()? onRefresh; PropoalStaffTab({super.key, this.data, this.id, this.onRefresh}); @override ConsumerState createState() => PropoalStaffTabState(); } class PropoalStaffTabState extends ConsumerState { int currentPage = 0; int itemsPerPage = 10; bool blockKey = false; List> dataVal = []; final TextEditingController _searchController = TextEditingController(); late ApiService apiService; final _formKey = GlobalKey(); final GlobalKey>> dropDownKey = GlobalKey>>(); List tabHeader = [ 'regNum', 'insurer', 'mobile', 'code', 'address', 'regNo', ]; late String isActive = "1"; PlatformFile? docUploadedFile; // PlatformFile? passportFile; String? selectedFileNames; String? selectedInsurdId; String? passportFileUrlFromApi; String? selectedId; bool isLoading = false; bool isquotation = false; Map controllers = {}; String? _token; dynamic userId; dynamic roleId; dynamic selectedEnquiryId; dynamic managerId; dynamic enqQuotation; dynamic selectedQuotationFrmListId; Map? selectedQuotationFrmListData; List> getVehicleTypeData = []; List> filteredVechicleData = []; List> getInsurersData = []; List> filteredInsurersData = []; Map dataDetails() { final data = { "regNum": controllers["regNum"]?.text, // "insurer": controllers["insurer"]?.text, "insurer": controllers["insurer"]?.text, "mobile": controllers["mobile"]?.text, "address": controllers["address"]?.text, "agent_code": controllers["code"]?.text, "is_active": isActive, "manager_id": managerId, }; return data; } List> getQuotationData = []; late Map enquiryData; List> originalData = []; List> filteredData = []; // bool isLoading = false; Future _restoreManagerId(WidgetRef ref) async { final prefs = await SharedPreferences.getInstance(); final String? savedId = prefs.getString( 'enqStaffDataId', ); // already a string if (savedId != null) { ref.read(quotationStaffIdProvider.notifier).state = savedId; print("savedenqStaffDataId ID restored: $savedId"); _loadData(savedId); } } @override void initState() { super.initState(); apiService = ApiService(); if (kIsWeb) { Future.microtask(() => _restoreManagerId(ref)); } for (String field in tabHeader) { controllers[field] = TextEditingController(); } _initializeToken(); Future.microtask(() { managerId = ref.read(managerIdProvider); // ✅ use read userId = ref.read(userIdProvider); // ✅ use read roleId = ref.read(userRoleProvider); // ✅ use read print('QmanagerId - $managerId'); print('QuserId - $userId'); print('QroleId - $roleId'); enqQuotation = ref.read(quotationStaffIdProvider); // ✅ use read print('QenqQuotation - $enqQuotation'); if (enqQuotation != null) { _loadData(enqQuotation); } }); } @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"); } void updateEnquiryData(enquiryData) { print('updateEnquiryData - $enquiryData'); if (!mounted) return; setState(() { selectedInsurdId = enquiryData['insurer_id']; selectedEnquiryId = enquiryData['id']; print('selectedEnquiryId- $selectedEnquiryId'); controllers["regNum"]?.text = enquiryData['reg_no']; // controllers["insurer"]?.text = enquiryData['insurer_name']; }); } Future _loadData(enqQuotation) async { getQuotationList(enqQuotation); } void refresh() { print("refresh--"); setState(() { selectedQuotationFrmListId = null; selectedQuotationFrmListData = null; }); if (enqQuotation != null) { _loadData(enqQuotation); } } Future getQuotationList(enqQuotation) async { print('getClaimList called enqQuotation- $enqQuotation'); if (!mounted) return; setState(() { isLoading = true; }); try { final response = await apiService.findEnqQuotePolicyView(enqQuotation); if (!mounted) return; if (response['status'] == 'success') { print('quoationListData - ${response['data']}'); setState(() { enquiryData = Map.from(response['data']['enquiry']); print('enquiryData - ${enquiryData}'); updateEnquiryData(enquiryData); // getQuotationData = List>.from(response['data']); getQuotationData = List>.from( response['data']['quotations'], ); originalData = getQuotationData; filteredData = List.from(originalData); blockKey = getQuotationData.any( (item) => item['status'] == 'Accepted', ); print('blockKey- $blockKey'); // print('originalData - $getClaimPolicies'); }); } else { getQuotationData = []; originalData = []; } } catch (e) { print('Exception occurred: $e'); } finally { if (!mounted) return; setState(() { isLoading = false; }); } } Color _getStatusColor(String? status) { switch (status) { case 'Pending': return Colors.yellow; case 'Accepted': return Colors.green; case 'Rejected': return Colors.red; default: return Colors.grey; } } void handleEdit(id, data) { print("sfd - $id"); print("sfdewe - $data"); setState(() { selectedQuotationFrmListId = id; selectedQuotationFrmListData = data; // data = data; }); } @override Widget build(BuildContext context) { final isMobile = ResponsiveLayout.isMobile(context); return Container( height: MediaQuery.of(context).size.height, width: MediaQuery.of(context).size.width, // child: SingleChildScrollView( // scrollDirection: Axis.vertical, child: Column( children: [ if (!blockKey) ...[ // if (!blockKey && roleId != 'manager') ...[ CreateQuotationForm( key: ValueKey(selectedQuotationFrmListId ?? "new"), userId: userId, selectedQuotationFrmListdata: selectedQuotationFrmListData, selectedQuotationFrmListId: selectedQuotationFrmListId, managerId: managerId, selectedInsurdId: selectedInsurdId, selectedEnquiryId: selectedEnquiryId, onSubmit: (value) { debugPrint("New Endorsement: $value"); if (value == 'Success') { refresh(); } }, ), SizedBox(height: 20), ], Container( // color: Colors.green, decoration: BoxDecoration( color: Color(0xFFEDF6F5), borderRadius: BorderRadius.circular(10.0), ), width: MediaQuery.of(context).size.width, height: !blockKey ? MediaQuery.of(context).size.height * 0.4 : MediaQuery.of(context).size.height * 0.55, padding: EdgeInsets.all(12.0), child: SingleChildScrollView( scrollDirection: Axis.vertical, child: Column( children: [ // Text('datta') _buildDataTable(context), ], ), ), ), ], ), // ), ); } Widget registerNumber(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Vehicle Number', style: _textStyle), SizedBox(height: 10), ThemedFormField( controller: controllers['regNum']!, readOnly: true, txtwidth: ResponsiveLayout.isMobile(context) ? null : MediaQuery.of(context).size.width * 0.2, ), ], ); } Widget insurer(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('Insurer', style: _textStyle), SizedBox(height: 10), ThemedFormField( controller: controllers['insurer']!, readOnly: true, txtwidth: ResponsiveLayout.isMobile(context) ? null : MediaQuery.of(context).size.width * 0.2, ), ], ); } 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 buildId(BuildContext context) { return buildResponsiveField( label: "Vehicle Number *", field: ThemedFormField( controller: controllers['regNo']!, validator: (value) => Validators.requiredField(value, "regNo"), txtwidth: ResponsiveLayout.isMobile(context) ? null : MediaQuery.of(context).size.width * 0.26, ), ); } Widget _buildDataTable(BuildContext context) { if (filteredData.isEmpty) { return const SizedBox( height: 50, child: Center(child: Text('No available data')), ); } final sortedData = [...filteredData] ..sort((a, b) => int.parse(b['id']) - int.parse(a['id'])); return SingleChildScrollView( child: Column( children: [ ListView.builder( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), itemCount: ResponsiveLayout.isMobile(context) ? sortedData .length // only cards for mobile : sortedData.length + 1, // +1 for header in desktop itemBuilder: (context, index) { if (!ResponsiveLayout.isMobile(context) && index == 0) { return _buildHeader(); } final startIndex = (currentPage - 1) * itemsPerPage; final item = sortedData[index - (ResponsiveLayout.isMobile(context) ? 0 : 1)]; final sno = startIndex + index; // return ResponsiveLayout.isMobile(context) // ? _buildDataCard(item, sno) return _buildDataRow(item, sno); }, ), ], ), ); } Widget _buildHeader() { return Container( decoration: BoxDecoration( color: Color(0xFFEDF6F5), borderRadius: BorderRadius.circular(6), ), padding: const EdgeInsets.symmetric(vertical: 3, horizontal: 3), child: Row( children: [ // Expanded(flex: 3, child: Text(' ', style: _headerStyle)), Expanded(flex: 2, child: Text('Vehicle Number', style: _headerStyle)), Expanded(flex: 3, child: Text('Insurer', style: _headerStyle)), Expanded(flex: 2, child: Text('IDV', style: _headerStyle)), Expanded(flex: 2, child: Text('Plan Type', style: _headerStyle)), Expanded(flex: 2, child: Text('Premium Amount', style: _headerStyle)), Expanded(flex: 2, child: Text('Status', style: _headerStyle)), Expanded(flex: 1, child: Text('', style: _headerStyle)), ], ), ); } Widget _buildDataRow(Map item, sno) { return Container( padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 16), margin: const EdgeInsets.only(top: 10), decoration: BoxDecoration( color: Colors.white, // color: Color(0xFFE0F7F9), border: const Border( bottom: BorderSide(color: Color(0xFFEAEAEA), width: 1), ), borderRadius: BorderRadius.circular(8), ), child: Row( children: [ Expanded( flex: 2, child: Text(item['reg_no'] ?? '-', style: _dataBold), ), Expanded( flex: 3, child: Text(item['insurer_name'] ?? '-', style: _dataBold), ), Expanded( flex: 2, child: Text( item['insured_declared_value'] ?? '-', style: _dataBold, ), ), Expanded( flex: 2, child: Text(item['insurance_plan_type'] ?? '-', style: _dataBold), ), Expanded( flex: 2, child: Text(item['premium_amount'] ?? '-', style: _dataBold), ), Expanded( flex: 2, child: Text( item['status'] ?? '-', style: GoogleFonts.inter( fontSize: 14, fontWeight: FontWeight.w400, color: _getStatusColor(item['status']), ), ), ), Expanded( flex: 1, child: item['status'] == 'Pending' ? Tooltip( message: 'Edit', child: IconButton( icon: Image.asset( "assets/miscellaneous/Edit.png", height: 15, width: 15, ), onPressed: () { final id = item['id']; print('RAV - $id'); handleEdit(id, item); }, splashRadius: 20, hoverColor: Colors.black12, padding: const EdgeInsets.all(8), constraints: const BoxConstraints(), ), ) : Image.asset( "assets/miscellaneous/Edit_muted.png", height: 15, width: 15, ), // child: GestureDetector( // onTap: () { // final id = item['id']; // print('RAV - $id'); // handleEdit(id, item); // }, // child: item['status'] == 'Pending' // ? Image.asset( // "assets/miscellaneous/Edit.png", // height: 15, // width: 15, // ) // : Image.asset( // "assets/miscellaneous/Edit_muted.png", // height: 15, // width: 15, // ), // ), ), ], ), ); } Widget _buildDataCard(Map item, int sno) { return Container( // margin: const EdgeInsets.symmetric(vertical: 6, horizontal: 8), padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: const Color(0xFFFFFFFF), // color: const Color(0xFFF6FEFD), borderRadius: BorderRadius.circular(8.0), border: Border.all(color: const Color(0xffD9EBE8)), ), child: Row( children: [ Expanded( child: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( // "TN64V3456", item['reg_no'] ?? '-', style: _cardheaderStyle, ), item['status'] == 'Pending' // ? GestureDetector( // onTap: () { // final id = item['id']; // print('RAV - $id'); // handleEdit(id, item); // }, // child: Image.asset( // "assets/miscellaneous/Edit.png", // height: 15, // width: 15, // ), // ) ? Tooltip( message: 'Edit', child: IconButton( icon: Image.asset( "assets/miscellaneous/Edit.png", height: 15, width: 15, ), onPressed: () { final id = item['id']; print('RAV - $id'); // handleEdit(id, item); }, splashRadius: 28, hoverColor: Colors.black12, padding: const EdgeInsets.all(8), constraints: const BoxConstraints(), ), ) : Image.asset( "assets/miscellaneous/Edit_muted.png", height: 15, width: 15, ), ], ), Row( // mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Expanded( // flex: 2, child: Text( item['insurer_name'] ?? '-', style: _cardRow1BodyStyle, ), ), ], ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Text( item['insurance_plan_type'] ?? '-', style: _cardRow1BodyStyle, ), Text( 'IDV: ${item['insured_declared_value']}' ?? '-', style: _cardRow2BodyStyle, ), ], ), Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ RichText( text: TextSpan( children: [ TextSpan( text: 'Status : ', // key style: GoogleFonts.inter( color: Colors.black, fontWeight: FontWeight.w600, fontSize: 11, ), // key color ), TextSpan( text: '${item['status'] ?? '-'}', // value style: GoogleFonts.inter( color: _getStatusColor(item['status']), fontWeight: FontWeight.w600, fontSize: 11, ), // value color ), ], ), ), Text( '${item['premium_amount']}' ?? '-', style: _cardheaderStyle, ), ], ), ], ), ), ], ), ); } static final _dataBold = GoogleFonts.inter( fontSize: 12, fontWeight: FontWeight.w400, color: Color(0xFF000000), ); static final _dataSub = GoogleFonts.inter( fontSize: 10, fontWeight: FontWeight.w300, color: Color(0xFF585757), ); static final _headerStyle = GoogleFonts.inter( color: Colors.black, fontWeight: FontWeight.w600, fontSize: 13, ); static final _textStyle = GoogleFonts.inter( fontSize: 14, fontWeight: FontWeight.w600, ); static final _cardheaderStyle = GoogleFonts.inter( color: Colors.black, fontWeight: FontWeight.w600, fontSize: 12, ); static final _cardBodyStyle = GoogleFonts.inter( color: Color(0xFF545454), fontWeight: FontWeight.w400, fontSize: 12, ); static final _cardRow1BodyStyle = GoogleFonts.inter( // color: Color(0xFF545454), color: Colors.black, fontWeight: FontWeight.w500, fontSize: 12, ); static final _cardRow2BodyStyle = GoogleFonts.inter( color: const Color(0xFF545454), // color: Colors.black, fontWeight: FontWeight.w500, fontSize: 12, ); }