447 lines
12 KiB
Dart
447 lines
12 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';
|
|
|
|
class QuotationStaffTab extends ConsumerStatefulWidget {
|
|
String? id;
|
|
List<Map<String, dynamic>>? data;
|
|
final Future<void> Function()? onRefresh;
|
|
|
|
QuotationStaffTab({super.key, this.data, this.id, this.onRefresh});
|
|
@override
|
|
ConsumerState<QuotationStaffTab> createState() => QuotationStaffTabState();
|
|
}
|
|
|
|
class QuotationStaffTabState extends ConsumerState<QuotationStaffTab> {
|
|
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'];
|
|
print('selectedInsurdId- $selectedInsurdId');
|
|
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);
|
|
|
|
// dynamic data = getQuotationData
|
|
// .where((item) => item['status'] == 'Accepted')
|
|
// .toList();
|
|
// blockKey = getQuotationData.any(
|
|
// (item) => item['status'] == 'Accepted',
|
|
// );
|
|
|
|
final acceptedList = getQuotationData
|
|
.where((item) => item['status'] == 'Accepted')
|
|
.toList();
|
|
|
|
print('blockKey- $blockKey');
|
|
print('originalDataData - $acceptedList');
|
|
|
|
final data = acceptedList.isNotEmpty ? acceptedList.first : null;
|
|
|
|
final id = selectedQuotationFrmListData?['id'];
|
|
|
|
handleEdit(id, data);
|
|
|
|
// selectedQuotationFrmListData = data;
|
|
|
|
print('originalDatasdata- $data');
|
|
print(
|
|
'originalDataselectedQuotationFrmListData - $selectedQuotationFrmListData',
|
|
);
|
|
});
|
|
} 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,
|
|
padding: EdgeInsets.symmetric(vertical: 10),
|
|
decoration: BoxDecoration(
|
|
border: Border(
|
|
top: BorderSide(color: Colors.blueGrey.shade200, width: 0.2),
|
|
),
|
|
),
|
|
// child: SingleChildScrollView(
|
|
// scrollDirection: Axis.vertical,
|
|
child: Column(
|
|
children: [
|
|
// if (!blockKey) ...[
|
|
// if (!blockKey && roleId != 'manager') ...[
|
|
CreateProposalForm(
|
|
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),
|
|
// ],
|
|
],
|
|
),
|
|
// ),
|
|
);
|
|
}
|
|
|
|
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,
|
|
),
|
|
);
|
|
}
|
|
|
|
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,
|
|
);
|
|
}
|