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 '../../../providers/manager_provider.dart'; import 'enquiry_tab.dart'; import 'quotation_tab.dart'; import 'policy_tab.dart'; import '../../../layouts/main_layout.dart'; class TabEnquiryList extends ConsumerStatefulWidget { String? id; TabEnquiryList({super.key, this.id}); @override ConsumerState createState() => TabEnquiryListState(); } class TabEnquiryListState extends ConsumerState { int? expandedIndex; int selectedIndex = 0; List tabs = []; Map? enquiryData; bool isLoading = true; late ApiService apiService; ScrollController _scrollController = ScrollController(); dynamic role; @override void initState() { super.initState(); apiService = ApiService(); if (kIsWeb) { Future.microtask(() => _restoreId(ref)); } Future.microtask(() { final id = ref.read(enquiryIdProvider); role = ref.read(userRoleProvider); print("IntialID - $id"); if (id != null) { _loadData(id); } else { setState(() => isLoading = false); tabs = [ TabItem("Enquiry", EnquiryTab()), TabItem("Proposal", QuotationTab()), TabItem("Policy", PolicyTab()), ]; } }); // fetch immediately } Future _restoreId(WidgetRef ref) async { final prefs = await SharedPreferences.getInstance(); final String? savedId = prefs.getString( 'enqAgentDataId', ); // already a string if (savedId != null) { ref.read(enquiryIdProvider.notifier).state = savedId; print("savedenqStaffDataId ID restored: $savedId"); _loadData(savedId); } } Future _loadData1(id) async { print('Load Data'); setState(() => isLoading = true); final response = await apiService.findEnqQuotePolicyView(id); setState(() { enquiryData = response["data"]; print('Load Data - $enquiryData'); isLoading = false; tabs = [ TabItem( "Enquiry", EnquiryTab(data: enquiryData?["enquiry"], id: id ?? ""), ), TabItem( "Proposal", QuotationTab( data: (enquiryData?["quotations"] as List?) ?.map((e) => Map.from(e as Map)) .toList() ?? [], id: id ?? "", ), // QuotationTab( // data: (enquiryData?["quotations"] as List?)! // .map((e) => Map.from(e as Map)) // .toList(), // id: id ?? "", // ), ), TabItem( "Policy", PolicyTab( data: (enquiryData?["policies"] as List?) ?.map((e) => Map.from(e as Map)) .toList() ?? [], // fallback to empty list id: id ?? "", ), // PolicyTab( // data: (enquiryData?["policies"] as List?)! // .map((e) => Map.from(e as Map)) // .toList(), // id: id ?? "", // ), ), // TabItem("Proposal", QuotationTab(data: enquiryData?["quotations"])), // TabItem("Policy", PolicyTab()), ]; }); } Future _loadData(id, {int? tabIndex}) async { print('loadQuotationTab 2'); setState(() => isLoading = true); final response = await apiService.findEnqQuotePolicyView(id); setState(() { enquiryData = response["data"]; isLoading = false; tabs = [ TabItem( "Enquiry", EnquiryTab(data: enquiryData?["enquiry"], id: id ?? ""), ), TabItem( "Proposal", QuotationTab( data: (enquiryData?["quotations"] as List?) ?.map((e) => Map.from(e as Map)) .toList() ?? [], id: id ?? "", onRefresh: () async { await _loadData(id); // refresh parent data }, ), ), TabItem( "Policy", PolicyTab( data: enquiryData?["policies"] is List ? List>.from( (enquiryData?["policies"] as List).map( (e) => Map.from(e as Map), ), ) : enquiryData?["policies"] is Map ? [Map.from(enquiryData?["policies"] as Map)] : [], id: id ?? "", ), ), // TabItem( // "Policy", // PolicyTab( // data: // (enquiryData?["policies"] as List?) // ?.map((e) => Map.from(e as Map)) // .toList() ?? // [], // id: id ?? "", // ), // ), ]; if (tabIndex != null) { selectedIndex = tabIndex; expandedIndex = tabIndex; } }); } /// Public method to load data and select a tab Future loadQuotationTab(String id) async { print('loadQuotationTab 1'); await _loadData(id, tabIndex: 2); // now _loadData will set the selected tab } @override Widget build(BuildContext context) { final bool isMobile = MediaQuery.of(context).size.width < 600; final id = ref.watch(enquiryIdProvider); print("TABUPDID- $id"); // // When provider changes, re-fetch // ref.listen(enquiryIdProvider, (prev, next) { // if (prev != next) { // _loadData(id); // } // }); print('ENQID: $id'); return MainLayout( title: "Enquiry", body: SafeArea( child: SelectionArea( child: isLoading ? const Center(child: CircularProgressIndicator()) : isMobile ? SingleChildScrollView( child: Column( children: [ Padding( padding: const EdgeInsets.symmetric( horizontal: 1, vertical: 1, ), child: GestureDetector( onTap: () { // context.go(AppRoutes.dashboard); if (role == 'handler') { ref.read(enquiryIdProvider.notifier).state = null; context.go(AppRoutes.enquiryHandlerLst); } else if (role == 'manager') { ref.read(enquiryIdProvider.notifier).state = null; context.go(AppRoutes.enquiryForStaff); } else { ref.read(enquiryIdProvider.notifier).state = null; context.go(AppRoutes.enquiryLst); } }, child: Row( children: [ const Icon( Icons.arrow_left_sharp, size: 20, color: Color(0xFF425B5B), ), // const SizedBox(width: 8), Text( "Enquiry ", style: GoogleFonts.inter( fontSize: 14, fontWeight: FontWeight.w600, color: Colors.black, ), ), ], ), ), ), _buildMobileTabs( shrinkWrap: true, physics: NeverScrollableScrollPhysics(), ), ], ), ) : _buildDesktopTabs(), ), ), ); } Widget _buildMobileTabs({ required bool shrinkWrap, required ScrollPhysics physics, }) { return ListView.builder( shrinkWrap: shrinkWrap, physics: physics, itemCount: tabs.length, padding: const EdgeInsets.all(16), itemBuilder: (context, index) { final isExpanded = expandedIndex == index; return Card( margin: const EdgeInsets.only(bottom: 12), color: isExpanded ? const Color(0xFFEDF6F5) : const Color(0xFF425B5B), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), side: const BorderSide(color: Color(0xFF425B5B), width: 1), ), child: Theme( // ✅ removes top & bottom dividers inside ExpansionTile data: Theme.of(context).copyWith(dividerColor: Colors.transparent), child: ExpansionTile( key: ValueKey(index), collapsedIconColor: isExpanded ? Colors.black : Colors.white, iconColor: isExpanded ? Colors.black : Colors.white, initiallyExpanded: isExpanded, tilePadding: const EdgeInsets.symmetric(horizontal: 16.0), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), collapsedShape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), onExpansionChanged: (expanded) { setState(() { expandedIndex = expanded ? index : null; if (expanded) { WidgetsBinding.instance.addPostFrameCallback((_) { RenderBox box = context.findRenderObject() as RenderBox; double yPos = box.localToGlobal(Offset.zero).dy; _scrollController.animateTo( _scrollController.offset + yPos - 100, duration: const Duration(milliseconds: 300), curve: Curves.easeInOut, ); }); } }); }, title: Text( tabs[index].title, style: GoogleFonts.inter( fontSize: 14, color: isExpanded ? Colors.black : Colors.white, fontWeight: FontWeight.w600, ), ), children: [ Container( // padding: const EdgeInsets.all(12), child: tabs[index].widget, ), ], ), ), ); }, ); } Widget _buildDesktopTabs() { return Column( children: [ Padding( padding: const EdgeInsets.symmetric(horizontal: 2, vertical: 2), child: GestureDetector( onTap: () { // context.go(AppRoutes.dashboard); // ref.read(enquiryIdProvider.notifier).state = null; // context.go(AppRoutes.enquiryLst); if (role == 'handler') { ref.read(enquiryIdProvider.notifier).state = null; context.go(AppRoutes.enquiryHandlerLst); } else { ref.read(enquiryIdProvider.notifier).state = null; context.go(AppRoutes.enquiryLst); } }, child: Row( children: [ Tooltip( message: 'Back', child: IconButton( icon: const Icon( Icons.arrow_left_sharp, size: 25, color: Color(0xFF425B5B), ), onPressed: () { if (role == 'handler') { ref.read(enquiryIdProvider.notifier).state = null; context.go(AppRoutes.enquiryHandlerLst); } else if (role == 'manager') { ref.read(enquiryIdProvider.notifier).state = null; context.go(AppRoutes.enquiryForStaff); } else { ref.read(enquiryIdProvider.notifier).state = null; context.go(AppRoutes.enquiryLst); } // ref.read(enquiryIdProvider.notifier).state = null; // context.go(AppRoutes.enquiryLst); }, splashRadius: 28, hoverColor: Colors.black12, padding: const EdgeInsets.all(8), constraints: const BoxConstraints(), ), ), const SizedBox(width: 8), Text( "Enquiry", style: GoogleFonts.inter( fontSize: 18, fontWeight: FontWeight.w700, color: Colors.black87, ), ), ], ), ), ), Row( children: List.generate(tabs.length, (index) { final isSelected = selectedIndex == index; return Padding( padding: const EdgeInsets.only(left: 10.0), child: ElevatedButton( style: ElevatedButton.styleFrom( elevation: 2, backgroundColor: isSelected ? const Color(0xFF425B5B) : const Color(0xFFEDFFFC), foregroundColor: isSelected ? Colors.white : Colors.black87, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(6), ), padding: const EdgeInsets.symmetric( horizontal: 24, vertical: 12, ), ), onPressed: () { setState(() => selectedIndex = index); }, child: Text(tabs[index].title), ), ); }), ), SizedBox(height: 10), Expanded(child: tabs[selectedIndex].widget), ], ); } } class TabItem { final String title; final Widget widget; TabItem(this.title, this.widget); }