nhance_partner/lib/presentation/screens/Enquiry/enquiry/tabs.dart
2026-01-08 16:01:06 +05:30

454 lines
15 KiB
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 '../../../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<TabEnquiryList> createState() => TabEnquiryListState();
}
class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
int? expandedIndex;
int selectedIndex = 0;
List<TabItem> tabs = [];
Map<String, dynamic>? 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<void> _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<void> _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<dynamic>?)
?.map((e) => Map<String, dynamic>.from(e as Map))
.toList() ??
[],
id: id ?? "",
),
// QuotationTab(
// data: (enquiryData?["quotations"] as List<dynamic>?)!
// .map((e) => Map<String, dynamic>.from(e as Map))
// .toList(),
// id: id ?? "",
// ),
),
TabItem(
"Policy",
PolicyTab(
data:
(enquiryData?["policies"] as List<dynamic>?)
?.map((e) => Map<String, dynamic>.from(e as Map))
.toList() ??
[], // fallback to empty list
id: id ?? "",
),
// PolicyTab(
// data: (enquiryData?["policies"] as List<dynamic>?)!
// .map((e) => Map<String, dynamic>.from(e as Map))
// .toList(),
// id: id ?? "",
// ),
),
// TabItem("Proposal", QuotationTab(data: enquiryData?["quotations"])),
// TabItem("Policy", PolicyTab()),
];
});
}
Future<void> _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<dynamic>?)
?.map((e) => Map<String, dynamic>.from(e as Map))
.toList() ??
[],
id: id ?? "",
onRefresh: () async {
await _loadData(id); // refresh parent data
},
),
),
TabItem(
"Policy",
PolicyTab(
data: enquiryData?["policies"] is List
? List<Map<String, dynamic>>.from(
(enquiryData?["policies"] as List).map(
(e) => Map<String, dynamic>.from(e as Map),
),
)
: enquiryData?["policies"] is Map
? [Map<String, dynamic>.from(enquiryData?["policies"] as Map)]
: [],
id: id ?? "",
),
),
// TabItem(
// "Policy",
// PolicyTab(
// data:
// (enquiryData?["policies"] as List<dynamic>?)
// ?.map((e) => Map<String, dynamic>.from(e as Map))
// .toList() ??
// [],
// id: id ?? "",
// ),
// ),
];
if (tabIndex != null) {
selectedIndex = tabIndex;
expandedIndex = tabIndex;
}
});
}
/// Public method to load data and select a tab
Future<void> 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<String?>(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);
}