nhance_partner/lib/presentation/screens/staff/Enquiry/tabs/quotationTab_old.dart
2025-11-21 09:27:52 +05:30

734 lines
22 KiB
Dart

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<Map<String, dynamic>>? data;
final Future<void> Function()? onRefresh;
PropoalStaffTab({super.key, this.data, this.id, this.onRefresh});
@override
ConsumerState<PropoalStaffTab> createState() => PropoalStaffTabState();
}
class PropoalStaffTabState extends ConsumerState<PropoalStaffTab> {
int currentPage = 0;
int itemsPerPage = 10;
bool blockKey = false;
List<Map<String, dynamic>> dataVal = [];
final TextEditingController _searchController = TextEditingController();
late ApiService apiService;
final _formKey = GlobalKey<FormState>();
final GlobalKey<DropdownSearchState<Map<String, dynamic>>> dropDownKey =
GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
List<String> 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<String, TextEditingController> controllers = {};
String? _token;
dynamic userId;
dynamic roleId;
dynamic selectedEnquiryId;
dynamic managerId;
dynamic enqQuotation;
dynamic selectedQuotationFrmListId;
Map<String, dynamic>? selectedQuotationFrmListData;
List<Map<String, dynamic>> getVehicleTypeData = [];
List<Map<String, dynamic>> filteredVechicleData = [];
List<Map<String, dynamic>> getInsurersData = [];
List<Map<String, dynamic>> filteredInsurersData = [];
Map<String, dynamic> 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<Map<String, dynamic>> getQuotationData = [];
late Map<String, dynamic> enquiryData;
List<Map<String, dynamic>> originalData = [];
List<Map<String, dynamic>> filteredData = [];
// bool isLoading = false;
Future<void> _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<void> _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<void> _loadData(enqQuotation) async {
getQuotationList(enqQuotation);
}
void refresh() {
print("refresh--");
setState(() {
selectedQuotationFrmListId = null;
selectedQuotationFrmListData = null;
});
if (enqQuotation != null) {
_loadData(enqQuotation);
}
}
Future<void> 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<String, dynamic>.from(response['data']['enquiry']);
print('enquiryData - ${enquiryData}');
updateEnquiryData(enquiryData);
// getQuotationData = List<Map<String, dynamic>>.from(response['data']);
getQuotationData = List<Map<String, dynamic>>.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<String, dynamic> 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<String, dynamic> 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,
);
}