442 lines
14 KiB
Dart
442 lines
14 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:nhance_partner/presentation/screens/staff/Enquiry/tabs/policyTab.dart';
|
|
import 'package:nhance_partner/presentation/screens/staff/Enquiry/tabs/quotationTab.dart';
|
|
import 'package:nhance_partner/presentation/screens/staff/Enquiry/tabs/quotationTab_old.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
import '../../../../../core/routing/routes.dart';
|
|
import '../../../../../core/services/api_service.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';
|
|
|
|
class TabEnquiryStaffList extends ConsumerStatefulWidget {
|
|
String? id;
|
|
String? showKey;
|
|
|
|
TabEnquiryStaffList({super.key, this.id, this.showKey});
|
|
@override
|
|
ConsumerState<TabEnquiryStaffList> createState() =>
|
|
TabEnquiryStaffListState();
|
|
}
|
|
|
|
class TabEnquiryStaffListState extends ConsumerState<TabEnquiryStaffList> {
|
|
int? expandedIndex;
|
|
int selectedIndex = 0;
|
|
List<TabItem> tabs = [];
|
|
Map<String, dynamic>? enquiryData;
|
|
bool isLoading = true;
|
|
late ApiService apiService;
|
|
ScrollController _scrollController = ScrollController();
|
|
dynamic role;
|
|
|
|
dynamic selectedInsuredName;
|
|
dynamic selectedVehicleNum;
|
|
dynamic selectedVehicleType;
|
|
dynamic selectedBrokerName;
|
|
|
|
dynamic selectedAgentName;
|
|
dynamic selectedAgentCode;
|
|
dynamic selectedInsurer;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
apiService = ApiService();
|
|
|
|
if (kIsWeb) {
|
|
Future.microtask(() => _restoreId(ref));
|
|
}
|
|
|
|
Future.microtask(() {
|
|
final id = ref.read(quotationStaffIdProvider);
|
|
role = ref.read(userRoleProvider);
|
|
print("IntialID - $id");
|
|
if (id != null) {
|
|
_loadData(id);
|
|
} else {
|
|
setState(() => isLoading = false);
|
|
tabs = [
|
|
// TabItem("Proposal", PropoalStaffTab()),
|
|
TabItem("Quote", QuotationStaffTab()),
|
|
// TabItem("Policy", PolicyStaffTab()),
|
|
];
|
|
}
|
|
});
|
|
// 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> _loadData(id, {int? tabIndex}) async {
|
|
print('loadQuotationTab 2');
|
|
setState(() => isLoading = true);
|
|
final response = await apiService.findEnqQuotePolicyView(id);
|
|
print('loadQuotationTab 3 ');
|
|
final data = response["data"];
|
|
setState(() {
|
|
print('loadQuotationTab 4');
|
|
print('loadQuotationTab enquiryData4 - $data');
|
|
isLoading = false;
|
|
|
|
enquiryData = data;
|
|
|
|
// ✅ Move these lines inside setState
|
|
selectedInsuredName = data['enquiry']?['name'];
|
|
selectedVehicleNum = data['enquiry']?['reg_no'];
|
|
selectedVehicleType = data['enquiry']?['vehicle_type'];
|
|
selectedBrokerName = data['enquiry']?['broker_name'];
|
|
selectedAgentName = data['enquiry']?['agent_name'];
|
|
selectedAgentCode = data['enquiry']?['agent_code'];
|
|
selectedInsurer = data['enquiry']?['short_name'];
|
|
print(
|
|
'loadQuotationTab 4s -$selectedBrokerName $selectedInsuredName - $selectedVehicleNum - $selectedVehicleType',
|
|
);
|
|
|
|
tabs = [
|
|
// TabItem("Proposal", PropoalStaffTab()),
|
|
TabItem("Quote", QuotationStaffTab()),
|
|
// TabItem("Policy", PolicyStaffTab()),
|
|
];
|
|
|
|
// if (widget.showKey == "Policy") {
|
|
// tabs.add(TabItem("Policy", PolicyStaffTab()));
|
|
// }
|
|
|
|
// if (tabIndex != null) {
|
|
// selectedIndex = tabIndex;
|
|
// expandedIndex = tabIndex;
|
|
// }
|
|
|
|
// Auto-select tab based on showKey
|
|
// if (widget.showKey == "Policy") {
|
|
// selectedIndex = 1; // Policy tab index
|
|
// } else
|
|
|
|
if (tabIndex != null) {
|
|
selectedIndex = tabIndex;
|
|
} else {
|
|
selectedIndex = 0; // Default Quotation tab
|
|
}
|
|
|
|
expandedIndex = selectedIndex;
|
|
});
|
|
|
|
if (selectedBrokerName == 'Nhance') {
|
|
print("Chooese name Nhance");
|
|
|
|
final prefs = await SharedPreferences.getInstance();
|
|
await prefs.remove('enqBrokerNameProvider');
|
|
|
|
// ✅ Save the new id
|
|
await prefs.setString(
|
|
'enqBrokerNameProvider',
|
|
selectedBrokerName.toString(),
|
|
);
|
|
ref.read(enqBrokerNameProvider.notifier).state = selectedBrokerName;
|
|
} else {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
await prefs.remove('enqBrokerNameProvider');
|
|
ref.read(enqBrokerNameProvider.notifier).state = null;
|
|
}
|
|
}
|
|
|
|
/// 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") ;
|
|
//
|
|
// print('ENQID: $id');
|
|
|
|
return AlertDialog(
|
|
backgroundColor: Colors.white,
|
|
content: Container(
|
|
width: MediaQuery.of(context).size.width * 0.4,
|
|
height: MediaQuery.of(context).size.height * 0.5,
|
|
|
|
// width: MediaQuery.of(context).size.width * 0.65,
|
|
// height: MediaQuery.of(context).size.height * 0.9,
|
|
child: isLoading
|
|
? const Center(child: CircularProgressIndicator())
|
|
: tabs.isEmpty
|
|
? const Center(
|
|
child: Text(
|
|
"No data available",
|
|
style: TextStyle(fontSize: 16, color: Colors.black54),
|
|
),
|
|
)
|
|
: _buildDesktopTabs(),
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildDesktopTabs() {
|
|
return Column(
|
|
children: [
|
|
Container(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
children: [
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Text('Enquiry Details', style: _headertextStyle),
|
|
GestureDetector(
|
|
onTap: () => Navigator.pop(context),
|
|
child: Container(
|
|
padding: const EdgeInsets.all(5.0),
|
|
decoration: BoxDecoration(
|
|
color: const Color(0xFFF1F1F1),
|
|
borderRadius: BorderRadius.circular(5.0),
|
|
),
|
|
child: Tooltip(
|
|
message: 'Close',
|
|
child: const Icon(Icons.close, size: 18),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
SizedBox(height: 10),
|
|
Container(
|
|
padding: const EdgeInsets.symmetric(
|
|
vertical: 6,
|
|
horizontal: 16,
|
|
),
|
|
decoration: BoxDecoration(
|
|
// color: Color(0xffEDF6F5),
|
|
color: Color(0xFFF6FBFA),
|
|
// color: Color(0xFFE0F7F9),
|
|
border: const Border(
|
|
bottom: BorderSide(color: Color(0xFFEAEAEA), width: 1),
|
|
),
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
child: Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
insured_name(context),
|
|
vehcile_num(context),
|
|
AgentName(context),
|
|
Insurer(context),
|
|
// vehcile_Type(context),
|
|
// broker(context),
|
|
SizedBox.shrink(),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
|
|
SizedBox(height: 20),
|
|
Row(
|
|
children: List.generate(tabs.length, (index) {
|
|
final isSelected = selectedIndex == index;
|
|
|
|
return Container(
|
|
// decoration: BoxDecoration(border: Border(bottom: BorderSide())),
|
|
padding: const EdgeInsets.symmetric(horizontal: 1.0),
|
|
child: InkWell(
|
|
onTap: () => setState(() => selectedIndex = index),
|
|
child: Column(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
// ---- TEXT ----
|
|
SizedBox(
|
|
width: 80,
|
|
child: Text(
|
|
tabs[index].title,
|
|
style: GoogleFonts.poppins(
|
|
fontSize: 13,
|
|
fontWeight: isSelected
|
|
? FontWeight.w600
|
|
: FontWeight.w600,
|
|
color: isSelected
|
|
? const Color(
|
|
0xFF2E7D6E,
|
|
) // Purple-ish like screenshot
|
|
: Colors.black87,
|
|
),
|
|
),
|
|
),
|
|
|
|
const SizedBox(height: 6),
|
|
|
|
// ---- UNDERLINE INDICATOR ----
|
|
AnimatedContainer(
|
|
duration: Duration(milliseconds: 250),
|
|
curve: Curves.easeInOut,
|
|
height: 3,
|
|
width: isSelected ? 80 : 0,
|
|
decoration: BoxDecoration(
|
|
color: const Color(
|
|
0xFF2E7D6E,
|
|
), // underline color from screenshot
|
|
borderRadius: BorderRadius.circular(50),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}),
|
|
),
|
|
|
|
Expanded(child: tabs[selectedIndex].widget),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget insured_name(BuildContext context) {
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text('Insured', style: _textStyle),
|
|
SizedBox(height: 10),
|
|
Text(selectedInsuredName ?? '', style: _textDataStyle),
|
|
|
|
// ThemedFormField(
|
|
// controller: controllers['insurer']!,
|
|
// readOnly: true,
|
|
// txtwidth: ResponsiveLayout.isMobile(context)
|
|
// ? null
|
|
// : MediaQuery.of(context).size.width * 0.2,
|
|
// ),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget vehcile_num(BuildContext context) {
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text('Vehicle.No.', style: _textStyle),
|
|
SizedBox(height: 10),
|
|
Text(selectedVehicleNum ?? '', style: _textDataStyle),
|
|
|
|
// ThemedFormField(
|
|
// controller: controllers['insurer']!,
|
|
// readOnly: true,
|
|
// txtwidth: ResponsiveLayout.isMobile(context)
|
|
// ? null
|
|
// : MediaQuery.of(context).size.width * 0.2,
|
|
// ),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget AgentName(BuildContext context) {
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text('Partner Name', style: _textStyle),
|
|
SizedBox(height: 10),
|
|
// Text(selectedAgentName ?? '', style: _textDataStyle),
|
|
Text(
|
|
'${selectedAgentCode?.trim().isNotEmpty == true ? selectedAgentCode : ''}'
|
|
'${selectedAgentCode?.trim().isNotEmpty == true && selectedAgentName?.trim().isNotEmpty == true ? ' - ' : ''}'
|
|
'${selectedAgentName?.trim().isNotEmpty == true ? selectedAgentName : ''}',
|
|
style: _textDataStyle,
|
|
),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget Insurer(BuildContext context) {
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text('Insurer', style: _textStyle),
|
|
SizedBox(height: 10),
|
|
Text(selectedInsurer ?? '', style: _textDataStyle),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget vehcile_Type(BuildContext context) {
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text('Vehicle Type', style: _textStyle),
|
|
SizedBox(height: 10),
|
|
Text(selectedVehicleType ?? '', style: _textDataStyle),
|
|
// ThemedFormField(
|
|
// controller: controllers['insurer']!,
|
|
// readOnly: true,
|
|
// txtwidth: ResponsiveLayout.isMobile(context)
|
|
// ? null
|
|
// : MediaQuery.of(context).size.width * 0.2,
|
|
// ),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget broker(BuildContext context) {
|
|
return Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text('Broker', style: _textStyle),
|
|
SizedBox(height: 10),
|
|
Text(selectedBrokerName ?? '', style: _textDataStyle),
|
|
// ThemedFormField(
|
|
// controller: controllers['insurer']!,
|
|
// readOnly: true,
|
|
// txtwidth: ResponsiveLayout.isMobile(context)
|
|
// ? null
|
|
// : MediaQuery.of(context).size.width * 0.2,
|
|
// ),
|
|
],
|
|
);
|
|
}
|
|
|
|
static final _textStyle = GoogleFonts.inter(
|
|
fontSize: 12,
|
|
fontWeight: FontWeight.w400,
|
|
);
|
|
static final _textDataStyle = GoogleFonts.poppins(
|
|
fontSize: 12,
|
|
fontWeight: FontWeight.w500,
|
|
);
|
|
|
|
static final _headertextStyle = GoogleFonts.inter(
|
|
fontSize: 14,
|
|
fontWeight: FontWeight.w700,
|
|
color: const Color(0xFF425B5B),
|
|
);
|
|
}
|
|
|
|
class TabItem {
|
|
final String title;
|
|
final Widget widget;
|
|
TabItem(this.title, this.widget);
|
|
}
|