STAFF_ENQ_REDESIGN
This commit is contained in:
parent
25d9e1d0dd
commit
c6a212bc65
@ -338,7 +338,7 @@ class ApiService {
|
||||
}
|
||||
|
||||
// ----------------------------------- Dashboard -------------------------------------------------
|
||||
Future<Map<String, dynamic>> fetchDashboard(int id, role) async {
|
||||
Future<Map<String, dynamic>> fetchDashboard(int id, role, userId) async {
|
||||
// print(_token);
|
||||
if (_token == null) {
|
||||
await _initializeToken();
|
||||
@ -349,11 +349,13 @@ class ApiService {
|
||||
if (role == 'manager') {
|
||||
url = Uri.parse('${Env.apiUrl}dashboard/managerDashboard?manager_id=$id');
|
||||
} else if (role == 'handler') {
|
||||
url = Uri.parse('${Env.apiUrl}dashboard/handlerDashboard?handler_id=$id');
|
||||
url = Uri.parse(
|
||||
'${Env.apiUrl}dashboard/handlerDashboard?manager_id=$id&handler_id=$userId',
|
||||
);
|
||||
} else if (role == 'staff') {
|
||||
url = Uri.parse('${Env.apiUrl}dashboard/staffDashboard?staff_id=$id');
|
||||
url = Uri.parse('${Env.apiUrl}dashboard/staffDashboard?staff_id=$userId');
|
||||
} else {
|
||||
url = Uri.parse('${Env.apiUrl}dashboard/agentDashboard?agent_id=$id');
|
||||
url = Uri.parse('${Env.apiUrl}dashboard/agentDashboard?agent_id=$userId');
|
||||
}
|
||||
// final url = Uri.parse(
|
||||
// 'https://venbait.in/nhance/partner/dev/api/agent/agentList?manager_id=${managerId}',
|
||||
@ -559,9 +561,13 @@ class ApiService {
|
||||
|
||||
final String query;
|
||||
|
||||
if (role == 'manager') {
|
||||
if (role == 'manager' || role == 'handler') {
|
||||
query = 'manager_id=$id';
|
||||
} else if (role == 'staff') {
|
||||
}
|
||||
// else if (role == 'handler') {
|
||||
// query = 'handler_id=$id';
|
||||
// }
|
||||
else if (role == 'staff') {
|
||||
query = 'staff_id=$id';
|
||||
} else {
|
||||
query = 'agent_id=$id';
|
||||
@ -595,9 +601,11 @@ class ApiService {
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> findEnqQuotePolicyView(id) async {
|
||||
print('findEnqQuotePolicyView - $id');
|
||||
print('findEnqQuotePolicyVie2w - $id');
|
||||
if (_token == null) {
|
||||
print('findEnqQuotePolicyVie2w 1');
|
||||
await _initializeToken();
|
||||
print('findEnqQuotePolicyVie2w 2');
|
||||
}
|
||||
final url = Uri.parse(
|
||||
'${Env.apiUrl}enquiry/enquiryQuotePolicyView?enquiry_id=$id',
|
||||
@ -606,7 +614,17 @@ class ApiService {
|
||||
'Authorization': 'Bearer $_token' ?? '',
|
||||
'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK',
|
||||
};
|
||||
print('findEnqQuotePolicyVie2w 3');
|
||||
final response = await _makeGetRequest(url, headers);
|
||||
|
||||
if (response.containsKey('error')) {
|
||||
print(
|
||||
'❌ API returned invalid JSON or HTML. Raw response: ${response['raw']}',
|
||||
);
|
||||
return {}; // return empty map on error
|
||||
}
|
||||
print('findEnqQuotePolicyView 1');
|
||||
print('findEnqQuotePolicyView 1 - $response');
|
||||
return response;
|
||||
}
|
||||
|
||||
@ -844,7 +862,7 @@ class ApiService {
|
||||
return response;
|
||||
}
|
||||
|
||||
// --------------------------------- MASTER DATA ----------------------------------------------
|
||||
// --------------------------------- MASTER DATA DROPDOWN----------------------------------------------
|
||||
|
||||
Future<Map<String, dynamic>> fetchMasterDropDown(String val) async {
|
||||
// print(_token);
|
||||
@ -925,4 +943,26 @@ class ApiService {
|
||||
print('fetchHandlerNameDropDown 4 - $response');
|
||||
return response;
|
||||
}
|
||||
|
||||
Future<Map<String, dynamic>> fetchAgentNameDropDown(id) async {
|
||||
print('fetchAGENTNameDropDown');
|
||||
if (_token == null) {
|
||||
await _initializeToken();
|
||||
}
|
||||
|
||||
dynamic url;
|
||||
print('fetchAGENTNameDropDown 1');
|
||||
url = Uri.parse(
|
||||
'${Env.apiUrl}agent/agentListForEnquiryCreationDropdown?manager_id=$id',
|
||||
);
|
||||
print('fetchAGENTNameDropDown 2');
|
||||
final headers = {
|
||||
'Authorization': 'Bearer $_token' ?? '',
|
||||
'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK',
|
||||
};
|
||||
print('fetchAGENTNameDropDown 3');
|
||||
final response = await _makeGetRequest(url, headers);
|
||||
print('fetchAGENTNameDropDown 4 - $response');
|
||||
return response;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
final managerIdProvider = StateProvider<int?>((ref) => null);
|
||||
final handlerIdProvider = StateProvider<int?>((ref) => null);
|
||||
// final handlerIdProvider = StateProvider<int?>((ref) => null);
|
||||
final userIdProvider = StateProvider<int?>((ref) => null);
|
||||
final enquiryIdProvider = StateProvider<String?>((ref) => null);
|
||||
final navFromEnqStaffProvider = StateProvider<String?>((ref) => null);
|
||||
|
||||
@ -6,6 +6,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:nhance_partner/presentation/layouts/responsive_layout.dart';
|
||||
import 'package:nhance_partner/presentation/providers/userRoleProvider.dart';
|
||||
import 'package:toastification/toastification.dart';
|
||||
import 'package:universal_html/html.dart' as html;
|
||||
|
||||
@ -45,6 +46,8 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
|
||||
GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
|
||||
final GlobalKey<DropdownSearchState<Map<String, dynamic>>>
|
||||
dropDownKeyInsurer = GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
|
||||
final GlobalKey<DropdownSearchState<Map<String, dynamic>>> dropDownKeyAgent =
|
||||
GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
|
||||
|
||||
List<String> tabHeader = [
|
||||
'name',
|
||||
@ -79,26 +82,32 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
|
||||
String? selectedVehicleType;
|
||||
// int? selectedVehicleTypeId;
|
||||
String? selectedInsurer;
|
||||
String? selectedAgent;
|
||||
|
||||
Map<String, TextEditingController> controllers = {};
|
||||
String? _token;
|
||||
dynamic userId;
|
||||
dynamic managerId;
|
||||
dynamic role;
|
||||
|
||||
List<Map<String, dynamic>> getVehicleTypeData = [];
|
||||
List<Map<String, dynamic>> filteredVechicleData = [];
|
||||
|
||||
List<Map<String, dynamic>> getAgentListData = [];
|
||||
List<Map<String, dynamic>> filteredAgentData = [];
|
||||
|
||||
List<Map<String, dynamic>> getInsurersData = [];
|
||||
List<Map<String, dynamic>> filteredInsurersData = [];
|
||||
|
||||
Map<String, dynamic> dataDetails() {
|
||||
final data = {
|
||||
"agent_id": userId,
|
||||
"agent_id": role == 'handler' ? selectedAgent : userId,
|
||||
"name": controllers["name"]?.text,
|
||||
"mobile": controllers["mobile"]?.text,
|
||||
"email": controllers["email"]?.text,
|
||||
"reg_no": controllers["regNo"]?.text,
|
||||
"vehicle_type_id": selectedVehicleType,
|
||||
"is_data_created_by_handler": role == 'handler' ? '1' : '0',
|
||||
// "insurer_id": selectedInsurer,
|
||||
// "rc_file_name": "rc_doc.pdf",
|
||||
// "id_proof_file_name": "id_proof.pdf",
|
||||
@ -129,6 +138,12 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
|
||||
Future.microtask(() {
|
||||
managerId = ref.watch(managerIdProvider);
|
||||
userId = ref.watch(userIdProvider);
|
||||
role = ref.watch(userRoleProvider);
|
||||
|
||||
if (managerId != null) {
|
||||
print('managerId - $managerId');
|
||||
getAgentList(managerId);
|
||||
}
|
||||
});
|
||||
|
||||
getVehicleType();
|
||||
@ -215,6 +230,38 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getAgentList(id) async {
|
||||
print('getAgentListData called');
|
||||
setState(() {
|
||||
isLoading = true;
|
||||
});
|
||||
|
||||
try {
|
||||
final response = await apiService.fetchAgentNameDropDown(id);
|
||||
print('getAgentListData called response');
|
||||
print('get Agent- ${response['data']}');
|
||||
if (response['status'] == 'success') {
|
||||
print('get Agent- ${response['data']}');
|
||||
setState(() {
|
||||
getAgentListData = List<Map<String, dynamic>>.from(response['data']);
|
||||
print('API Data - $getAgentListData');
|
||||
|
||||
filteredAgentData = List.from(getAgentListData);
|
||||
print('originalAgentData - $filteredAgentData');
|
||||
});
|
||||
} else {
|
||||
getAgentListData = [];
|
||||
filteredAgentData = [];
|
||||
}
|
||||
} catch (e) {
|
||||
print('Exception occurred: $e');
|
||||
} finally {
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void updateData() async {
|
||||
if (widget.data != null && widget.data != 'tab' && widget.id != null) {
|
||||
// dynamic response = await apiService.findEnqQuotePolicyView(widget.id!);
|
||||
@ -234,6 +281,7 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
|
||||
isActive = data["is_active"];
|
||||
selectedVehicleType = data['vehicle_type_id'] ?? '';
|
||||
selectedInsurer = data['insurer_id'] ?? '';
|
||||
selectedAgent = data['agent_id'] ?? '';
|
||||
|
||||
String? apiDocPath = data["certificate_file_name"];
|
||||
|
||||
@ -325,26 +373,6 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
|
||||
|
||||
final dataSet = dataDetails();
|
||||
|
||||
// check RC file
|
||||
// if ((docUploadedRCFile == null ||
|
||||
// (docUploadedRCFile?.bytes == null &&
|
||||
// docUploadedRCFile?.path == null)) &&
|
||||
// (rcFileUrlFromApi == null || rcFileUrlFromApi!.isEmpty)) {
|
||||
// setState(() => isSaving = false); // reset button
|
||||
// ToastHelper.showErrorToast(context, "Please upload RC Document");
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // check ID proof
|
||||
// if ((docUploadedIDProof == null ||
|
||||
// (docUploadedIDProof?.bytes == null &&
|
||||
// docUploadedIDProof?.path == null)) &&
|
||||
// (idProofFileUrlFromApi == null || idProofFileUrlFromApi!.isEmpty)) {
|
||||
// setState(() => isSaving = false); // reset button
|
||||
// ToastHelper.showErrorToast(context, "Please upload ID Proof");
|
||||
// return;
|
||||
// }
|
||||
|
||||
try {
|
||||
await createUserData(dataSet); // API call
|
||||
// ToastHelper.showInfoToast(context, "Enquiry saved successfully");
|
||||
@ -484,13 +512,24 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
|
||||
ToastHelper.showSuccessToast(context, 'Saved Enquiry');
|
||||
print("Response: ${response.body}");
|
||||
|
||||
if (isUpdating) {
|
||||
context.go(AppRoutes.tabEnquiry);
|
||||
if (role == 'handler') {
|
||||
print('Im handler');
|
||||
print('ROle - $role');
|
||||
if (isUpdating) {
|
||||
context.go(AppRoutes.enquiryHandlerLst);
|
||||
} else {
|
||||
ref.read(enquiryIdProvider.notifier).state = null;
|
||||
context.go(AppRoutes.enquiryHandlerLst);
|
||||
}
|
||||
} else {
|
||||
ref.read(enquiryIdProvider.notifier).state = null;
|
||||
context.go(AppRoutes.enquiryLst);
|
||||
print('Im agent');
|
||||
if (isUpdating) {
|
||||
context.go(AppRoutes.tabEnquiry);
|
||||
} else {
|
||||
ref.read(enquiryIdProvider.notifier).state = null;
|
||||
context.go(AppRoutes.enquiryLst);
|
||||
}
|
||||
}
|
||||
|
||||
setState(() => isSaving = false);
|
||||
} else {
|
||||
print("❌ Submission failed. Status: ${response.statusCode}");
|
||||
@ -582,16 +621,28 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
?(role == 'handler')
|
||||
? _buildResponsiveRow(
|
||||
context,
|
||||
buildAgentName(context),
|
||||
SizedBox.shrink(),
|
||||
)
|
||||
: null,
|
||||
?(role == 'handler')
|
||||
? isMobile
|
||||
? SizedBox(height: 5)
|
||||
: SizedBox(height: 15)
|
||||
: null,
|
||||
_buildResponsiveRow(context, buildName(context), buildEmail(context)),
|
||||
|
||||
isMobile ? SizedBox(height: 5) : SizedBox(height: 20),
|
||||
isMobile ? SizedBox(height: 5) : SizedBox(height: 15),
|
||||
|
||||
_buildResponsiveRow(
|
||||
context,
|
||||
buildPhNumber(context),
|
||||
buildId(context),
|
||||
),
|
||||
isMobile ? SizedBox(height: 5) : SizedBox(height: 20),
|
||||
isMobile ? SizedBox(height: 5) : SizedBox(height: 15),
|
||||
|
||||
_buildResponsiveRow(
|
||||
context,
|
||||
@ -599,7 +650,7 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
|
||||
// buildInsurer(context),
|
||||
buildUploadRCDocument(context),
|
||||
),
|
||||
isMobile ? SizedBox(height: 5) : SizedBox(height: 20),
|
||||
isMobile ? SizedBox(height: 5) : SizedBox(height: 15),
|
||||
|
||||
_buildResponsiveRow(
|
||||
context,
|
||||
@ -608,7 +659,7 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
|
||||
buildUploadPolicyDocument(context),
|
||||
),
|
||||
|
||||
isMobile ? SizedBox(height: 5) : SizedBox(height: 20),
|
||||
isMobile ? SizedBox(height: 5) : SizedBox(height: 15),
|
||||
_buildResponsiveRow(
|
||||
context,
|
||||
// buildUploadPolicyDocument(context),
|
||||
@ -927,6 +978,91 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildAgentName(BuildContext context) {
|
||||
Map<String, dynamic>? selectedAgntName = filteredAgentData.firstWhere(
|
||||
(item) => item['id'].toString() == selectedAgent,
|
||||
orElse: () => {},
|
||||
);
|
||||
return buildResponsiveField(
|
||||
label: "Select Partner *",
|
||||
field: Container(
|
||||
decoration: BoxDecoration(
|
||||
// color: Colors.white,
|
||||
borderRadius: BorderRadius.circular(10.0),
|
||||
),
|
||||
width: ResponsiveLayout.isMobile(context)
|
||||
? null
|
||||
: MediaQuery.of(context).size.width * 0.26,
|
||||
// height: 40,
|
||||
child: DropdownSearch<Map<String, dynamic>>(
|
||||
key: dropDownKeyAgent,
|
||||
selectedItem: selectedAgntName.isNotEmpty ? selectedAgntName : null,
|
||||
items: (filter, infiniteScrollProps) {
|
||||
return filteredAgentData;
|
||||
},
|
||||
|
||||
itemAsString: (val) => val['name'].toString(), // what to show
|
||||
compareFn: (item, selectedItem) =>
|
||||
item['id'] == selectedItem['id'], // ✅ compare by id
|
||||
validator: (val) {
|
||||
if (val == null) {
|
||||
return "Required"; // ✅ error message
|
||||
}
|
||||
return null;
|
||||
},
|
||||
decoratorProps: DropDownDecoratorProps(
|
||||
decoration:
|
||||
AppInputDecorations.dropdownDecoration(
|
||||
label: "Select Partner",
|
||||
).copyWith(
|
||||
filled: true,
|
||||
fillColor: Colors.white, // 👈 makes the dropdown input white
|
||||
),
|
||||
),
|
||||
|
||||
popupProps: PopupProps.menu(
|
||||
fit: FlexFit.loose,
|
||||
constraints: BoxConstraints(maxHeight: 250),
|
||||
menuProps: MenuProps(
|
||||
backgroundColor:
|
||||
Colors.white, // 👈 sets dropdown background to white
|
||||
),
|
||||
showSearchBox: true,
|
||||
searchFieldProps: TextFieldProps(
|
||||
decoration: InputDecoration(
|
||||
filled: true,
|
||||
fillColor: Colors.white,
|
||||
hintText: "Search Partner...",
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Colors.white,
|
||||
), // 👈 Normal border
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Colors.white,
|
||||
width: 1.5,
|
||||
), // 👈 Focused border
|
||||
),
|
||||
),
|
||||
),
|
||||
// constraints: BoxConstraints(),
|
||||
),
|
||||
|
||||
onChanged: (val) {
|
||||
if (val != null) {
|
||||
print("Selected Partner : ${val['name']}");
|
||||
print("Id: ${val['id']}");
|
||||
selectedAgent = val['id'];
|
||||
// controllers['agentId']?.text = val['agent_code'];
|
||||
// agentId = agent['id'];
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// Widget buildUploadRCDocument(BuildContext context) {
|
||||
// return buildResponsiveUploadField(
|
||||
// label: "Upload RC Document",
|
||||
|
||||
@ -6,6 +6,7 @@ import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:nhance_partner/presentation/providers/userRoleProvider.dart';
|
||||
import 'package:nhance_partner/presentation/screens/Enquiry/enquiry/tabs.dart';
|
||||
import '../../../../core/config/env.dart';
|
||||
import '../../../../core/services/api_service.dart';
|
||||
@ -78,6 +79,7 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
|
||||
String? _token;
|
||||
dynamic userId;
|
||||
dynamic managerId;
|
||||
dynamic role;
|
||||
|
||||
List<Map<String, dynamic>> getVehicleTypeData = [];
|
||||
List<Map<String, dynamic>> filteredVechicleData = [];
|
||||
@ -116,6 +118,7 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
|
||||
Future.microtask(() {
|
||||
managerId = ref.watch(managerIdProvider);
|
||||
userId = ref.watch(userIdProvider);
|
||||
role = ref.watch(userRoleProvider);
|
||||
|
||||
getQuotationList();
|
||||
});
|
||||
@ -159,10 +162,11 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
|
||||
filteredData = List.from(originalData);
|
||||
print('quoationListData - $getQuotationData');
|
||||
|
||||
blockKey = getQuotationData.any((item) => item['status'] == 'Accepted');
|
||||
blockKey = getQuotationData.any(
|
||||
(item) => item['status'] == 'Accepted',
|
||||
);
|
||||
print('blockKey- $blockKey');
|
||||
|
||||
|
||||
// blockKey = getQuotationData.any(
|
||||
// (item) => (item['status']?.toString().toLowerCase() ?? '') == 'approved',
|
||||
// );
|
||||
@ -275,7 +279,12 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
|
||||
throw Exception('Token not found. Please log in.');
|
||||
}
|
||||
|
||||
final Map<String, dynamic> data = {"id": selectedId, "status": val};
|
||||
final Map<String, dynamic> data = {
|
||||
"id": selectedId,
|
||||
"status": val,
|
||||
"action_by": userId,
|
||||
"action_user": (role == 'agent') ? 'agent' : 'handler',
|
||||
};
|
||||
|
||||
// data['id'] = selectedId; // Add plan_id for update
|
||||
// data['status'] = val;
|
||||
@ -307,7 +316,6 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
|
||||
await widget.onRefresh!();
|
||||
}
|
||||
|
||||
|
||||
// refresh();
|
||||
// WidgetsBinding.instance.addPostFrameCallback((_) {
|
||||
// tabKey.currentState?.loadQuotationTab(widget.id ?? "");
|
||||
@ -598,7 +606,8 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
|
||||
_buildResponsiveRow(
|
||||
context,
|
||||
buildPlanType(context),
|
||||
buildDocuments(context),
|
||||
SizedBox.shrink(),
|
||||
// buildDocuments(context),
|
||||
),
|
||||
|
||||
// if (!ResponsiveLayout.isMobile(context)) const SizedBox(height: 10),
|
||||
@ -698,7 +707,6 @@ class QuotationTabState extends ConsumerState<QuotationTab> {
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
Widget buildDocuments(BuildContext context) {
|
||||
return buildResponsiveUploadField(
|
||||
label: 'Quotation Documents',
|
||||
|
||||
@ -224,8 +224,8 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 6,
|
||||
vertical: 2,
|
||||
horizontal: 1,
|
||||
vertical: 1,
|
||||
),
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
@ -243,7 +243,7 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
|
||||
children: [
|
||||
const Icon(
|
||||
Icons.arrow_left_sharp,
|
||||
size: 25,
|
||||
size: 20,
|
||||
color: Color(0xFF425B5B),
|
||||
),
|
||||
// const SizedBox(width: 8),
|
||||
@ -417,12 +417,20 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
|
||||
return Column(
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
|
||||
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);
|
||||
// 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: [
|
||||
@ -431,12 +439,20 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
|
||||
child: IconButton(
|
||||
icon: const Icon(
|
||||
Icons.arrow_left_sharp,
|
||||
size: 35,
|
||||
size: 25,
|
||||
color: Color(0xFF425B5B),
|
||||
),
|
||||
onPressed: () {
|
||||
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);
|
||||
}
|
||||
|
||||
// ref.read(enquiryIdProvider.notifier).state = null;
|
||||
// context.go(AppRoutes.enquiryLst);
|
||||
},
|
||||
splashRadius: 28,
|
||||
hoverColor: Colors.black12,
|
||||
|
||||
@ -350,7 +350,7 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
height: 40,
|
||||
height: 30,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
@ -395,7 +395,7 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(height: ResponsiveLayout.isMobile(context) ? 5 : 10),
|
||||
SizedBox(height: ResponsiveLayout.isMobile(context) ? 5 : 5),
|
||||
ResponsiveLayout.isMobile(context)
|
||||
? Container(
|
||||
height: MediaQuery.of(context).size.height * 0.7,
|
||||
@ -593,14 +593,18 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
|
||||
Expanded(flex: 1, child: Text('S.No.', style: _headerStyle)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text('Created Date', style: _headerStyle),
|
||||
child: Text('Received Date & Time', style: _headerStyle),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text('Vehicle.No.', style: _headerStyle),
|
||||
),
|
||||
Expanded(flex: 3, child: Text('Insurer', style: _headerStyle)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text('Updated Date', style: _headerStyle),
|
||||
),
|
||||
Expanded(flex: 1, child: Text('Reg.No.', style: _headerStyle)),
|
||||
Expanded(flex: 3, child: Text('Company', style: _headerStyle)),
|
||||
Expanded(flex: 2, child: Text('Status', style: _headerStyle)),
|
||||
Expanded(flex: 2, child: Text('Remarks', style: _headerStyle)),
|
||||
Expanded(flex: 1, child: Text('Action', style: _headerStyle)),
|
||||
@ -707,15 +711,9 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
|
||||
style: _dataBold,
|
||||
),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
_formatDate(item['updated_on']) ?? '-',
|
||||
style: _dataBold,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Text(item['reg_no'] ?? '-', style: _dataBold),
|
||||
),
|
||||
Expanded(
|
||||
@ -727,7 +725,13 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
|
||||
maxLines: 3,
|
||||
),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
_formatDate(item['updated_on']) ?? '-',
|
||||
style: _dataBold,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(item['status'] ?? '-', style: _dataBold),
|
||||
@ -919,7 +923,7 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
|
||||
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Text("Company", style: _cardheaderStyle),
|
||||
Text("Insurer", style: _cardheaderStyle),
|
||||
Text(
|
||||
item['insurer_name'] ?? '-',
|
||||
style: _cardBodyStyle,
|
||||
|
||||
@ -178,7 +178,7 @@ class claimListState extends ConsumerState<claimList> {
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
height: 40,
|
||||
height: 30,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
@ -191,8 +191,14 @@ class claimListState extends ConsumerState<claimList> {
|
||||
Tooltip(
|
||||
message: 'Back',
|
||||
child: IconButton(
|
||||
icon: const Icon(Icons.arrow_left_sharp,size: 25,color: Color(0xFF425B5B)),
|
||||
onPressed: () { context.go(AppRoutes.dashboard); },
|
||||
icon: const Icon(
|
||||
Icons.arrow_left_sharp,
|
||||
size: 25,
|
||||
color: Color(0xFF425B5B),
|
||||
),
|
||||
onPressed: () {
|
||||
context.go(AppRoutes.dashboard);
|
||||
},
|
||||
splashRadius: 18,
|
||||
hoverColor: Colors.black12,
|
||||
padding: const EdgeInsets.all(4),
|
||||
@ -212,7 +218,7 @@ class claimListState extends ConsumerState<claimList> {
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(height: 10),
|
||||
SizedBox(height: 5),
|
||||
|
||||
Expanded(
|
||||
child: Container(
|
||||
@ -301,7 +307,7 @@ class claimListState extends ConsumerState<claimList> {
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
SizedBox(height: 5),
|
||||
if (!ResponsiveLayout.isMobile(context))
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
@ -320,11 +326,11 @@ class claimListState extends ConsumerState<claimList> {
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text('Reg.No.', style: _headerStyle),
|
||||
child: Text('Vehicle.No.', style: _headerStyle),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text('Company', style: _headerStyle),
|
||||
child: Text('Insurer', style: _headerStyle),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
@ -579,7 +585,7 @@ class claimListState extends ConsumerState<claimList> {
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
//company
|
||||
Text("Company", style: _cardheaderStyle),
|
||||
Text("Insurer", style: _cardheaderStyle),
|
||||
Text(
|
||||
item['policy_end_date'] != null
|
||||
? _formatDate(item['policy_end_date'])
|
||||
|
||||
@ -43,8 +43,9 @@ class endosementState extends ConsumerState<endosement> {
|
||||
final roleId = ref.read(userRoleProvider);
|
||||
final userId = ref.read(userIdProvider);
|
||||
print("F46 => r : $roleId | mId: $id | uId: $userId ");
|
||||
if (userId != null) { getStaffList(userId, roleId); }
|
||||
|
||||
if (userId != null) {
|
||||
getStaffList(userId, roleId);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@ -174,7 +175,7 @@ class endosementState extends ConsumerState<endosement> {
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
height: 40,
|
||||
height: 30,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
@ -187,8 +188,14 @@ class endosementState extends ConsumerState<endosement> {
|
||||
Tooltip(
|
||||
message: 'Back',
|
||||
child: IconButton(
|
||||
icon: const Icon(Icons.arrow_left_sharp,size: 25,color: Color(0xFF425B5B)),
|
||||
onPressed: () { context.go(AppRoutes.dashboard); },
|
||||
icon: const Icon(
|
||||
Icons.arrow_left_sharp,
|
||||
size: 25,
|
||||
color: Color(0xFF425B5B),
|
||||
),
|
||||
onPressed: () {
|
||||
context.go(AppRoutes.dashboard);
|
||||
},
|
||||
splashRadius: 18,
|
||||
hoverColor: Colors.black12,
|
||||
padding: const EdgeInsets.all(4),
|
||||
@ -208,7 +215,7 @@ class endosementState extends ConsumerState<endosement> {
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(height: 10),
|
||||
SizedBox(height: 5),
|
||||
|
||||
Expanded(
|
||||
child: Container(
|
||||
@ -295,7 +302,7 @@ class endosementState extends ConsumerState<endosement> {
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
SizedBox(height: 5),
|
||||
if (!ResponsiveLayout.isMobile(context))
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
@ -314,11 +321,11 @@ class endosementState extends ConsumerState<endosement> {
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text('Reg.No.', style: _headerStyle),
|
||||
child: Text('Vehicle.No.', style: _headerStyle),
|
||||
),
|
||||
Expanded(
|
||||
flex: 4,
|
||||
child: Text('Company', style: _headerStyle),
|
||||
child: Text('Insurer', style: _headerStyle),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
@ -548,7 +555,7 @@ class endosementState extends ConsumerState<endosement> {
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
//company
|
||||
Text("Company", style: _cardheaderStyle),
|
||||
Text("Insurer", style: _cardheaderStyle),
|
||||
Text(
|
||||
item['insurer_name'] ?? '-',
|
||||
style: _cardBodyStyle,
|
||||
|
||||
@ -43,9 +43,9 @@ class StaffListState extends ConsumerState<StaffList> {
|
||||
|
||||
Future.microtask(() {
|
||||
final data1 = ref.read(managerIdProvider);
|
||||
final data2 = ref.read(handlerIdProvider);
|
||||
print("Edata1 => mId: $data1 -2 : $data2");
|
||||
prefid = data2 ?? data1;
|
||||
// final data2 = ref.read(handlerIdProvider);
|
||||
print("Edata1 => mId: $data1 -2 :");
|
||||
prefid = data1;
|
||||
role = ref.read(userRoleProvider);
|
||||
print("E43 => mId: $prefid");
|
||||
if (prefid != null && role != null) {
|
||||
|
||||
@ -11,13 +11,14 @@ import '../../layouts/main_layout.dart';
|
||||
import '../../providers/manager_provider.dart';
|
||||
import '../../providers/quotation_staff_proivder.dart';
|
||||
import '../../providers/userRoleProvider.dart';
|
||||
import '../staff/Enquiry/tabs/tab.dart';
|
||||
import '../staff/assignStaff.dart';
|
||||
|
||||
final enquiriesProvider = Provider<List<Map<String, String>>>((ref) {
|
||||
return List.generate(5, (i) {
|
||||
return {
|
||||
"reg": "rrTN64V4387",
|
||||
"company": "rrNew India",
|
||||
"Insurer": "rrNew India",
|
||||
"date": "rr09/09/2025",
|
||||
"time": "rr11:30 AM",
|
||||
};
|
||||
@ -86,24 +87,25 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
||||
apiService = ApiService();
|
||||
|
||||
Future.microtask(() {
|
||||
// final id = ref.read(managerIdProvider);
|
||||
final prefid = ref.read(userIdProvider);
|
||||
final prefmanagerid = ref.read(managerIdProvider);
|
||||
final prefuserid = ref.read(userIdProvider);
|
||||
final prefroleId = ref.read(userRoleProvider);
|
||||
|
||||
print("B81 => roleId: $prefroleId | userId: $prefid ");
|
||||
if (prefid != null) {
|
||||
getStaffList(prefid, prefroleId);
|
||||
print("B81 => roleId: $prefroleId | userId: $prefuserid ");
|
||||
if (prefuserid != null) {
|
||||
getStaffList(prefmanagerid!, prefroleId, prefuserid);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void refresh() {
|
||||
final prefid = ref.read(userIdProvider);
|
||||
final prefmanagerid = ref.read(managerIdProvider);
|
||||
final prefuserid = ref.read(userIdProvider);
|
||||
final prefroleId = ref.read(userRoleProvider);
|
||||
|
||||
if (prefid != null) {
|
||||
print("REFRESH- calling getStaffList with $prefid, $prefroleId");
|
||||
getStaffList(prefid, prefroleId);
|
||||
if (prefuserid != null) {
|
||||
print("REFRESH- calling getStaffList with $prefmanagerid, $prefuserid");
|
||||
getStaffList(prefmanagerid!, prefroleId, prefuserid);
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,31 +130,56 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
||||
}
|
||||
|
||||
Future<void> handleStaffEdit(String id, String? flag) async {
|
||||
// Navigator.pop(context);
|
||||
print('EDITStaff');
|
||||
// Navigator.pop(context); ddd
|
||||
dynamic val;
|
||||
print('EDITStaff - $id');
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
await prefs.remove('enqStaffDataId');
|
||||
// ✅ Save the new id
|
||||
await prefs.setString('enqStaffDataId', id.toString());
|
||||
ref.read(quotationStaffIdProvider.notifier).state = id;
|
||||
|
||||
if (flag == "Policies") {
|
||||
context.go(AppRoutes.policy);
|
||||
val = 'Policy';
|
||||
} else {
|
||||
context.go(AppRoutes.quotation);
|
||||
val = '';
|
||||
}
|
||||
|
||||
var enqId = id;
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
// ✅ Remove old value (if any)
|
||||
await prefs.remove('enqStaffDataId');
|
||||
|
||||
// ✅ Save the new id
|
||||
await prefs.setString('enqStaffDataId', enqId.toString());
|
||||
await prefs.setString('navFromDashboard', 'Dashboard');
|
||||
|
||||
ref.read(quotationStaffIdProvider.notifier).state = enqId;
|
||||
ref.read(navFromEnqStaffProvider.notifier).state = 'Dashboard';
|
||||
|
||||
// showDialog(
|
||||
// context: context,
|
||||
// builder: (context) => TabEnquiryStaffList(showKey: val),
|
||||
// );
|
||||
|
||||
final result = await showDialog(
|
||||
context: context,
|
||||
barrierDismissible:
|
||||
false, // optional - prevents closing by tapping outside
|
||||
builder: (context) => TabEnquiryStaffList(showKey: val),
|
||||
);
|
||||
|
||||
// ✅ Code here runs *after* the dialog is closed
|
||||
print("Dialog closed");
|
||||
print("Dialog result: $result");
|
||||
refresh();
|
||||
}
|
||||
|
||||
Future<void> getStaffList(int managerId, role) async {
|
||||
Future<void> getStaffList(int managerId, role, userId) async {
|
||||
print('B89 => Fns called => $managerId | $role');
|
||||
setState(() {
|
||||
isLoading = true;
|
||||
});
|
||||
|
||||
try {
|
||||
final response = await apiService.fetchDashboard(managerId, role);
|
||||
final response = await apiService.fetchDashboard(managerId, role, userId);
|
||||
|
||||
if (response['status'] == 'success') {
|
||||
final data = response['data'];
|
||||
@ -396,7 +423,7 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
child: buildTab("Awaiting Quotation", 0),
|
||||
child: buildTab("Awaiting Proposal", 0),
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
Padding(
|
||||
@ -457,6 +484,12 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
||||
),
|
||||
color: Colors.white,
|
||||
child: ListTile(
|
||||
onTap: () {
|
||||
dynamic id = item['id'].toString();
|
||||
|
||||
print("Tapped ID: ${item['id']}");
|
||||
handleEdit(id);
|
||||
},
|
||||
title: Text(
|
||||
item["reg_no"] ?? "-", // from API
|
||||
style: GoogleFonts.inter(
|
||||
@ -546,6 +579,8 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
||||
0.69 //400
|
||||
: (role == 'manager')
|
||||
? MediaQuery.of(context).size.height * 0.5
|
||||
: (role == 'staff')
|
||||
? MediaQuery.of(context).size.height * 0.85
|
||||
: MediaQuery.of(context).size.height *
|
||||
0.5, // 350 adjust height as needed
|
||||
child: (role == 'manager' || role == 'handler')
|
||||
@ -556,7 +591,7 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
||||
title:
|
||||
"Staff Proposal Pending List (${staffQuotationsPendingList.length})",
|
||||
data: staffQuotationsPendingList,
|
||||
stringFlag: "Quotation",
|
||||
stringFlag: "Proposal",
|
||||
role: role!,
|
||||
),
|
||||
),
|
||||
@ -568,7 +603,7 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
||||
child: (role == 'agent')
|
||||
? agentPendings(
|
||||
title:
|
||||
"Awaiting Quotation (${quotationsPendingList.length})",
|
||||
"Awaiting Proposal (${quotationsPendingList.length})",
|
||||
data: quotationsPendingList,
|
||||
role: role!,
|
||||
onEdit: (row) {
|
||||
@ -584,7 +619,7 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
||||
? SizedBox.shrink()
|
||||
: agentPendings(
|
||||
title:
|
||||
"Awaiting Quotation (${quotationsPendingList.length})",
|
||||
"Awaiting Proposal (${quotationsPendingList.length})",
|
||||
data: quotationsPendingList,
|
||||
role: role!,
|
||||
onEdit: (row) {
|
||||
@ -619,9 +654,9 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
||||
? SizedBox.shrink()
|
||||
// othersPendings(
|
||||
// title:
|
||||
// "Awaiting Quotation (${quotationsPendingList.length})",
|
||||
// "Awaiting Proposal (${quotationsPendingList.length})",
|
||||
// data: quotationsPendingList,
|
||||
// stringFlag: "Quotation",
|
||||
// stringFlag: "Proposal",
|
||||
// )
|
||||
: agentPendings(
|
||||
title:
|
||||
@ -660,9 +695,9 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
|
||||
?
|
||||
// ? othersPendings(
|
||||
// title:
|
||||
// "Awaiting Quotation (${quotationsPendingList.length})",
|
||||
// "Awaiting Proposal (${quotationsPendingList.length})",
|
||||
// data: quotationsPendingList,
|
||||
// stringFlag: "Quotation",
|
||||
// stringFlag: "Proposal",
|
||||
// )
|
||||
agentPendings(
|
||||
title:
|
||||
@ -972,7 +1007,7 @@ class agentPendings extends StatelessWidget {
|
||||
// ),
|
||||
// ),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"Date & Time",
|
||||
textAlign: TextAlign.center,
|
||||
@ -982,7 +1017,7 @@ class agentPendings extends StatelessWidget {
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"Registration number",
|
||||
"Vehicle Number",
|
||||
textAlign: TextAlign.center,
|
||||
style: _headerStyle,
|
||||
),
|
||||
@ -991,7 +1026,7 @@ class agentPendings extends StatelessWidget {
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
"Insurer Company",
|
||||
"Insurer",
|
||||
textAlign: TextAlign.center,
|
||||
style: _headerStyle,
|
||||
),
|
||||
@ -1072,7 +1107,7 @@ class agentPendings extends StatelessWidget {
|
||||
// ),
|
||||
// Date & Time
|
||||
Expanded(
|
||||
flex: 1,
|
||||
flex: 2,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@ -1691,7 +1726,7 @@ class UnassignedEnq extends StatelessWidget {
|
||||
// ),
|
||||
Expanded(
|
||||
child: Text(
|
||||
"Registration number",
|
||||
"Vehicle Number",
|
||||
textAlign: TextAlign.center,
|
||||
style: _headerStyle,
|
||||
),
|
||||
|
||||
@ -38,6 +38,8 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
|
||||
int itemsPerPage = 10;
|
||||
late ApiService apiService;
|
||||
dynamic userId;
|
||||
dynamic managerId;
|
||||
dynamic handlerId;
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
|
||||
// List<Map<String, dynamic>> dataVal = [];
|
||||
@ -64,10 +66,13 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
|
||||
final id = ref.read(managerIdProvider);
|
||||
roleId = ref.read(userRoleProvider);
|
||||
userId = ref.read(userIdProvider);
|
||||
managerId = ref.read(managerIdProvider);
|
||||
// handlerId = ref.read(handlerIdProvider);
|
||||
|
||||
print("C72 => r : $roleId | mId: $id | uId: $userId ");
|
||||
if (userId != null) {
|
||||
getStaffList(userId, roleId);
|
||||
print('handlerIdENQ - $handlerId');
|
||||
print("C72 => r : $roleId | mId: $id | uId: $userId !mID : $managerId ");
|
||||
if (managerId != null) {
|
||||
getStaffList(managerId, roleId);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -78,8 +83,8 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
|
||||
final userId = ref.read(userIdProvider);
|
||||
|
||||
print("C82 => r : $roleId | mId: $id | uId: $userId ");
|
||||
if (userId != null) {
|
||||
getStaffList(userId, roleId);
|
||||
if (managerId != null) {
|
||||
getStaffList(managerId, roleId);
|
||||
}
|
||||
}
|
||||
|
||||
@ -128,47 +133,39 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
|
||||
String fromDate = '',
|
||||
String toDate = '',
|
||||
}) async {
|
||||
print('C89 => Fns called => $managerId | $role');
|
||||
print('A72 => Fns called => $managerId | $role');
|
||||
setState(() {
|
||||
isLoading = true;
|
||||
});
|
||||
|
||||
try {
|
||||
final response = await apiService.fetchPolicyList(
|
||||
final response = await apiService.fetchEnquiryList(
|
||||
managerId,
|
||||
role,
|
||||
fromDate: controllers['startDate']?.text ?? '',
|
||||
toDate: controllers['endDate']?.text ?? '',
|
||||
);
|
||||
|
||||
print('FromDate : $fromDate');
|
||||
print('ToDate : $toDate');
|
||||
|
||||
if (response['status'] == 'success') {
|
||||
final data = response['data'];
|
||||
print('C99 => getStaffListData => ${response['data']}');
|
||||
final fromDate = response['from_date'] ?? '';
|
||||
final toDate = response['to_date'] ?? '';
|
||||
|
||||
print('FromDate : $fromDate');
|
||||
print('ToDate : $toDate');
|
||||
|
||||
setState(() {
|
||||
controllers['startDate']?.text = fromDate;
|
||||
controllers['endDate']?.text = toDate;
|
||||
|
||||
if (data is List) {
|
||||
// Already a list of maps
|
||||
getStaffData = List<Map<String, dynamic>>.from(data);
|
||||
} else if (data is Map) {
|
||||
// Single object, wrap in a list
|
||||
getStaffData = [Map<String, dynamic>.from(data)];
|
||||
} else {
|
||||
getStaffData = [];
|
||||
}
|
||||
// getStaffData = List<Map<String, dynamic>>.from(response['data']);
|
||||
originalData = getStaffData;
|
||||
filteredData = List.from(originalData);
|
||||
// print('originalData - $getClaimPolicies');
|
||||
});
|
||||
} else {
|
||||
getStaffData = [];
|
||||
@ -183,17 +180,66 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
|
||||
}
|
||||
}
|
||||
|
||||
List<dynamic> get _paginatedData2 {
|
||||
// Sort descending by id first
|
||||
final sortedData = [...filteredData]
|
||||
..sort((a, b) => int.parse(b['id']) - int.parse(a['id']));
|
||||
|
||||
// final sortedData = [...filteredData];
|
||||
final startIndex = (currentPage - 1) * itemsPerPage;
|
||||
final endIndex = (currentPage * itemsPerPage).clamp(0, sortedData.length);
|
||||
|
||||
return sortedData.sublist(startIndex, endIndex);
|
||||
}
|
||||
// Future<void> getStaffList1(
|
||||
// int managerId,
|
||||
// role, {
|
||||
// String fromDate = '',
|
||||
// String toDate = '',
|
||||
// }) async {
|
||||
// print('C89 => Fns called => $managerId | $role');
|
||||
// setState(() {
|
||||
// isLoading = true;
|
||||
// });
|
||||
//
|
||||
// try {
|
||||
// final response = await apiService.fetchPolicyList(
|
||||
// managerId,
|
||||
// role,
|
||||
// fromDate: controllers['startDate']?.text ?? '',
|
||||
// toDate: controllers['endDate']?.text ?? '',
|
||||
// );
|
||||
//
|
||||
// print('FromDate : $fromDate');
|
||||
// print('ToDate : $toDate');
|
||||
//
|
||||
// if (response['status'] == 'success') {
|
||||
// final data = response['data'];
|
||||
// print('C99 => getStaffListData => ${response['data']}');
|
||||
// final fromDate = response['from_date'] ?? '';
|
||||
// final toDate = response['to_date'] ?? '';
|
||||
//
|
||||
// print('FromDate : $fromDate');
|
||||
// print('ToDate : $toDate');
|
||||
// setState(() {
|
||||
// controllers['startDate']?.text = fromDate;
|
||||
// controllers['endDate']?.text = toDate;
|
||||
//
|
||||
// if (data is List) {
|
||||
// // Already a list of maps
|
||||
// getStaffData = List<Map<String, dynamic>>.from(data);
|
||||
// } else if (data is Map) {
|
||||
// // Single object, wrap in a list
|
||||
// getStaffData = [Map<String, dynamic>.from(data)];
|
||||
// } else {
|
||||
// getStaffData = [];
|
||||
// }
|
||||
// // getStaffData = List<Map<String, dynamic>>.from(response['data']);
|
||||
// originalData = getStaffData;
|
||||
// filteredData = List.from(originalData);
|
||||
// // print('originalData - $getClaimPolicies');
|
||||
// });
|
||||
// } else {
|
||||
// getStaffData = [];
|
||||
// originalData = [];
|
||||
// }
|
||||
// } catch (e) {
|
||||
// print('Exception occurred: $e');
|
||||
// } finally {
|
||||
// setState(() {
|
||||
// isLoading = false;
|
||||
// });
|
||||
// }
|
||||
// }
|
||||
|
||||
List<dynamic> get _paginatedData {
|
||||
// Sort descending by id first
|
||||
@ -266,149 +312,185 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
|
||||
}
|
||||
}
|
||||
|
||||
List<Widget> _buildPopupMenuActions(
|
||||
Future<void> handleStaff(
|
||||
BuildContext context,
|
||||
dynamic data,
|
||||
id,
|
||||
regNum,
|
||||
) {
|
||||
return [
|
||||
if (roleId == 'manager' && data['status'] == 'Awaiting Quotation') ...[
|
||||
Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (ctx) => AssignStaffDialog(
|
||||
enquiryPrimaryId: id,
|
||||
regNum: regNum,
|
||||
userId: 1,
|
||||
onSubmit: (value) {
|
||||
debugPrint("New assignY: $value");
|
||||
refresh();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
hoverColor: Color(0xFFE3F1F0),
|
||||
splashColor: Color(0xFFE3F1F0),
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
child: Row(
|
||||
// mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Image.asset(
|
||||
"assets/miscellaneous/image_3.png",
|
||||
// height: 45,
|
||||
// width: 15,
|
||||
),
|
||||
|
||||
SizedBox(width: 10),
|
||||
Text('Assign Staff'),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () async {
|
||||
Navigator.pop(context);
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
// ✅ Remove old value (if any)
|
||||
await prefs.remove('enqStaffDataId');
|
||||
|
||||
// ✅ Save the new id
|
||||
await prefs.setString('enqStaffDataId', id.toString());
|
||||
|
||||
// Read it back if needed
|
||||
// final dynamic? enqStaffDataId = prefs.getString('enqStaffDataId');
|
||||
|
||||
// ✅ Update provider too
|
||||
// ref.read(quotationStaffIdProvider.notifier).state = enqStaffDataId;
|
||||
ref.read(quotationStaffIdProvider.notifier).state = id;
|
||||
|
||||
context.go(AppRoutes.quotation);
|
||||
},
|
||||
hoverColor: Color(0xFFE3F1F0),
|
||||
splashColor: Color(0xFFE3F1F0),
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
child: Row(
|
||||
// mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Image.asset(
|
||||
"assets/miscellaneous/image_1.png",
|
||||
height: 15,
|
||||
width: 15,
|
||||
),
|
||||
|
||||
const SizedBox(width: 10),
|
||||
((data['status'] == 'Policy Created') ||
|
||||
(data['status'] == 'Quotation Accepted'))
|
||||
? const Text('View Quotation')
|
||||
: const Text('Create Quotation'),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
) async {
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (ctx) => AssignStaffDialog(
|
||||
enquiryPrimaryId: id,
|
||||
regNum: regNum,
|
||||
userId: userId,
|
||||
onSubmit: (value) {
|
||||
debugPrint("New assignY: $value");
|
||||
refresh();
|
||||
},
|
||||
),
|
||||
|
||||
if (data['status'] == 'Quotation Accepted' ||
|
||||
data['status'] == 'Policy Created')
|
||||
Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () async {
|
||||
Navigator.pop(context);
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
// ✅ Remove old value (if any)
|
||||
await prefs.remove('enqStaffDataId');
|
||||
|
||||
// ✅ Save the new id
|
||||
await prefs.setString('enqStaffDataId', id.toString());
|
||||
|
||||
// ✅ Update provider too
|
||||
|
||||
ref.read(quotationStaffIdProvider.notifier).state = id;
|
||||
context.go(AppRoutes.policy);
|
||||
},
|
||||
hoverColor: Color(0xFFE3F1F0),
|
||||
splashColor: Color(0xFFE3F1F0),
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
child: Row(
|
||||
// mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Image.asset(
|
||||
"assets/miscellaneous/image_2.png",
|
||||
height: 15,
|
||||
width: 15,
|
||||
),
|
||||
|
||||
const SizedBox(width: 10),
|
||||
data['status'] == 'Policy Created'
|
||||
? Text('View Policy')
|
||||
: Text('Create Policy'),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
];
|
||||
);
|
||||
}
|
||||
|
||||
Future<void> handleEdit(item) async {
|
||||
// Navigator.pop(context);
|
||||
print('EDITStaff - ${item['id']}');
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
await prefs.remove('enqAgentDataId');
|
||||
|
||||
final id = item['id'].toString();
|
||||
// ✅ Save the new id
|
||||
await prefs.setString('enqAgentDataId', id.toString());
|
||||
ref.read(enquiryIdProvider.notifier).state = id;
|
||||
|
||||
context.go(AppRoutes.tabEnquiry);
|
||||
}
|
||||
|
||||
// List<Widget> _buildPopupMenuActions(
|
||||
// BuildContext context,
|
||||
// dynamic data,
|
||||
// id,
|
||||
// regNum,
|
||||
// ) {
|
||||
// return [
|
||||
// if (roleId == 'manager' && data['status'] == 'Awaiting Quotation') ...[
|
||||
// Material(
|
||||
// color: Colors.transparent,
|
||||
// child: InkWell(
|
||||
// onTap: () {
|
||||
// Navigator.pop(context);
|
||||
// showDialog(
|
||||
// context: context,
|
||||
// builder: (ctx) => AssignStaffDialog(
|
||||
// enquiryPrimaryId: id,
|
||||
// regNum: regNum,
|
||||
// userId: 1,
|
||||
// onSubmit: (value) {
|
||||
// debugPrint("New assignY: $value");
|
||||
// refresh();
|
||||
// },
|
||||
// ),
|
||||
// );
|
||||
// },
|
||||
// hoverColor: Color(0xFFE3F1F0),
|
||||
// splashColor: Color(0xFFE3F1F0),
|
||||
// borderRadius: BorderRadius.circular(6),
|
||||
// child: Padding(
|
||||
// padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
// child: Row(
|
||||
// // mainAxisSize: MainAxisSize.min,
|
||||
// children: [
|
||||
// Image.asset(
|
||||
// "assets/miscellaneous/image_3.png",
|
||||
// // height: 45,
|
||||
// // width: 15,
|
||||
// ),
|
||||
//
|
||||
// SizedBox(width: 10),
|
||||
// Text('Assign Staff'),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
//
|
||||
// Material(
|
||||
// color: Colors.transparent,
|
||||
// child: InkWell(
|
||||
// onTap: () async {
|
||||
// Navigator.pop(context);
|
||||
// final prefs = await SharedPreferences.getInstance();
|
||||
//
|
||||
// // ✅ Remove old value (if any)
|
||||
// await prefs.remove('enqStaffDataId');
|
||||
//
|
||||
// // ✅ Save the new id
|
||||
// await prefs.setString('enqStaffDataId', id.toString());
|
||||
//
|
||||
// // Read it back if needed
|
||||
// // final dynamic? enqStaffDataId = prefs.getString('enqStaffDataId');
|
||||
//
|
||||
// // ✅ Update provider too
|
||||
// // ref.read(quotationStaffIdProvider.notifier).state = enqStaffDataId;
|
||||
// ref.read(quotationStaffIdProvider.notifier).state = id;
|
||||
//
|
||||
// context.go(AppRoutes.quotation);
|
||||
// },
|
||||
// hoverColor: Color(0xFFE3F1F0),
|
||||
// splashColor: Color(0xFFE3F1F0),
|
||||
// borderRadius: BorderRadius.circular(6),
|
||||
// child: Padding(
|
||||
// padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
// child: Row(
|
||||
// // mainAxisSize: MainAxisSize.min,
|
||||
// children: [
|
||||
// Image.asset(
|
||||
// "assets/miscellaneous/image_1.png",
|
||||
// height: 15,
|
||||
// width: 15,
|
||||
// ),
|
||||
//
|
||||
// const SizedBox(width: 10),
|
||||
// ((data['status'] == 'Policy Created') ||
|
||||
// (data['status'] == 'Quotation Accepted'))
|
||||
// ? const Text('View Quotation')
|
||||
// : const Text('Create Quotation'),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
//
|
||||
// if (data['status'] == 'Quotation Accepted' ||
|
||||
// data['status'] == 'Policy Created')
|
||||
// Material(
|
||||
// color: Colors.transparent,
|
||||
// child: InkWell(
|
||||
// onTap: () async {
|
||||
// Navigator.pop(context);
|
||||
//
|
||||
// final prefs = await SharedPreferences.getInstance();
|
||||
//
|
||||
// // ✅ Remove old value (if any)
|
||||
// await prefs.remove('enqStaffDataId');
|
||||
//
|
||||
// // ✅ Save the new id
|
||||
// await prefs.setString('enqStaffDataId', id.toString());
|
||||
//
|
||||
// // ✅ Update provider too
|
||||
//
|
||||
// ref.read(quotationStaffIdProvider.notifier).state = id;
|
||||
// context.go(AppRoutes.policy);
|
||||
// },
|
||||
// hoverColor: Color(0xFFE3F1F0),
|
||||
// splashColor: Color(0xFFE3F1F0),
|
||||
// borderRadius: BorderRadius.circular(6),
|
||||
// child: Padding(
|
||||
// padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
// child: Row(
|
||||
// // mainAxisSize: MainAxisSize.min,
|
||||
// children: [
|
||||
// Image.asset(
|
||||
// "assets/miscellaneous/image_2.png",
|
||||
// height: 15,
|
||||
// width: 15,
|
||||
// ),
|
||||
//
|
||||
// const SizedBox(width: 10),
|
||||
// data['status'] == 'Policy Created'
|
||||
// ? Text('View Policy')
|
||||
// : Text('Create Policy'),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ];
|
||||
// }
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MainLayout(
|
||||
@ -421,7 +503,7 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
height: 40,
|
||||
height: 30,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
@ -739,14 +821,17 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
|
||||
child: const Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 3,
|
||||
flex: 2,
|
||||
child: Text('Created Date', style: _headerStyle),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
flex: 2,
|
||||
child: Text('Updated Date', style: _headerStyle),
|
||||
),
|
||||
Expanded(flex: 2, child: Text('Reg.No', style: _headerStyle)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text('Vehicle.No', style: _headerStyle),
|
||||
),
|
||||
Expanded(flex: 2, child: Text('Partner', style: _headerStyle)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
@ -754,7 +839,7 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
|
||||
),
|
||||
Expanded(flex: 3, child: Text('Insurer', style: _headerStyle)),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
flex: 2,
|
||||
child: Padding(
|
||||
padding: EdgeInsets.only(left: 8.0),
|
||||
child: Text('Insured Name', style: _headerStyle),
|
||||
@ -770,7 +855,7 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
|
||||
child: Text('Policy Number', style: _headerStyle),
|
||||
),
|
||||
|
||||
Expanded(flex: 3, child: Text('Status', style: _headerStyle)),
|
||||
Expanded(flex: 2, child: Text('Status', style: _headerStyle)),
|
||||
Expanded(flex: 1, child: Text('Action', style: _headerStyle)),
|
||||
],
|
||||
),
|
||||
@ -867,7 +952,7 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 3,
|
||||
flex: 2,
|
||||
child: Text(
|
||||
_formatDate(item['created_on']) ?? '-',
|
||||
style: _dataBold,
|
||||
@ -876,7 +961,7 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
flex: 2,
|
||||
child: Text(
|
||||
_formatDate(item['updated_on']) ?? '-',
|
||||
style: _dataBold,
|
||||
@ -890,10 +975,7 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
_formatDate(item['agent_name']) ?? '-',
|
||||
style: _dataBold,
|
||||
),
|
||||
child: Text(item['agent_name'] ?? '-', style: _dataBold),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
@ -909,14 +991,13 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Center(
|
||||
child: Text(
|
||||
item['insured_name'] ?? '-',
|
||||
style: _dataBold,
|
||||
softWrap: true,
|
||||
maxLines: 3,
|
||||
),
|
||||
flex: 2,
|
||||
|
||||
child: Text(
|
||||
item['insured_name'] ?? '-',
|
||||
style: _dataBold,
|
||||
softWrap: true,
|
||||
maxLines: 3,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
@ -948,7 +1029,7 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
|
||||
),
|
||||
|
||||
Expanded(
|
||||
flex: 3,
|
||||
flex: 2,
|
||||
child: Text(item['status'] ?? '-', style: _dataBold),
|
||||
),
|
||||
|
||||
@ -956,36 +1037,37 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
|
||||
flex: 1,
|
||||
child: Row(
|
||||
children: [
|
||||
PopupMenuButton<int>(
|
||||
color: Colors.white,
|
||||
padding: EdgeInsets.zero,
|
||||
offset: Offset(0, 30),
|
||||
icon: Icon(
|
||||
Icons.more_vert,
|
||||
color: Color(0xFF475569),
|
||||
size: 14,
|
||||
),
|
||||
itemBuilder: (context) => [
|
||||
CustomPopupMenuEntry(
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(
|
||||
horizontal: 8,
|
||||
vertical: 8,
|
||||
),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: _buildPopupMenuActions(
|
||||
context,
|
||||
item,
|
||||
item['id'],
|
||||
item['reg_no'],
|
||||
),
|
||||
),
|
||||
),
|
||||
if (item['status'] == 'Awaiting Proposal')
|
||||
Tooltip(
|
||||
message: "Assign Staff",
|
||||
child: IconButton(
|
||||
icon: Icon(Icons.assignment_ind_outlined, size: 15),
|
||||
onPressed: () {
|
||||
handleStaff(context, item, item['id'], item['reg_no']);
|
||||
},
|
||||
splashRadius: 5,
|
||||
hoverColor: Colors.black12,
|
||||
padding: const EdgeInsets.all(4),
|
||||
constraints: const BoxConstraints(),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
Tooltip(
|
||||
message: 'Edit',
|
||||
child: IconButton(
|
||||
icon: Image.asset(
|
||||
"assets/miscellaneous/Edit.png",
|
||||
height: 12,
|
||||
width: 12,
|
||||
),
|
||||
onPressed: () {
|
||||
handleEdit(item);
|
||||
},
|
||||
splashRadius: 5,
|
||||
hoverColor: Colors.black12,
|
||||
padding: const EdgeInsets.all(4),
|
||||
constraints: const BoxConstraints(),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
@ -1018,20 +1100,20 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
|
||||
offset: Offset(0, 30),
|
||||
icon: Icon(Icons.more_vert, color: Color(0xFF475569), size: 14),
|
||||
itemBuilder: (context) => [
|
||||
CustomPopupMenuEntry(
|
||||
child: Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: _buildPopupMenuActions(
|
||||
context,
|
||||
item,
|
||||
item['id'],
|
||||
item['reg_no'],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
// CustomPopupMenuEntry(
|
||||
// child: Container(
|
||||
// padding: EdgeInsets.symmetric(horizontal: 8, vertical: 8),
|
||||
// child: Column(
|
||||
// mainAxisSize: MainAxisSize.min,
|
||||
// children: _buildPopupMenuActions(
|
||||
// context,
|
||||
// item,
|
||||
// item['id'],
|
||||
// item['reg_no'],
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
],
|
||||
|
||||
@ -174,18 +174,18 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
|
||||
}
|
||||
|
||||
// Handler ID
|
||||
final dynamic handlerIdRaw = data['manager_id'];
|
||||
final int? handlerId = handlerIdRaw is int
|
||||
? handlerIdRaw
|
||||
: int.tryParse(handlerIdRaw.toString());
|
||||
|
||||
if (handlerId != null) {
|
||||
ref.read(handlerIdProvider.notifier).state = handlerId;
|
||||
print("✅ handlerId ID saved globally: $handlerId");
|
||||
await prefs.setInt('handlerId', handlerId);
|
||||
} else {
|
||||
print("⚠️ handlerId ID is null or invalid");
|
||||
}
|
||||
// final dynamic handlerIdRaw = data['handler_id'];
|
||||
// final int? handlerId = handlerIdRaw is int
|
||||
// ? handlerIdRaw
|
||||
// : int.tryParse(handlerIdRaw.toString());
|
||||
//
|
||||
// if (handlerId != null) {
|
||||
// ref.read(handlerIdProvider.notifier).state = handlerId;
|
||||
// print("✅ handlerId ID saved globally: $handlerId");
|
||||
// await prefs.setInt('handlerId', handlerId);
|
||||
// } else {
|
||||
// print("⚠️ handlerId ID is null or invalid");
|
||||
// }
|
||||
|
||||
// User ID
|
||||
final dynamic userIdRaw = data['id'];
|
||||
|
||||
@ -7,6 +7,7 @@ import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:go_router/go_router.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
import 'package:nhance_partner/presentation/screens/staff/Enquiry/tabs/tab.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import '../../../../core/config/env.dart';
|
||||
@ -197,6 +198,21 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> buildStatusActions(BuildContext context, status, id) async {
|
||||
print("Actionsstatus - $status -$id");
|
||||
dynamic val;
|
||||
if (status == 'Awaiting Proposal' || status == 'Proposal Created') {
|
||||
val = '';
|
||||
} else {
|
||||
val = 'Policy';
|
||||
}
|
||||
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (context) => TabEnquiryStaffList(showKey: val),
|
||||
);
|
||||
}
|
||||
|
||||
List<dynamic> get _paginatedData2 {
|
||||
// Sort descending by id first
|
||||
final sortedData = [...filteredData]
|
||||
@ -422,6 +438,27 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
|
||||
];
|
||||
}
|
||||
|
||||
List<Widget> _buildPopupDownload(
|
||||
BuildContext context,
|
||||
dynamic data,
|
||||
id,
|
||||
regNum,
|
||||
) {
|
||||
bool isMobile = ResponsiveLayout.isMobile(context);
|
||||
return [
|
||||
Row(
|
||||
children: [
|
||||
buildDocRC(context, isMobile, id),
|
||||
Spacer(),
|
||||
// SizedBox(width: 3),
|
||||
buildDocIdProof(context, isMobile, id),
|
||||
Spacer(),
|
||||
buildDocPrevPolicy(context, isMobile, id),
|
||||
],
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MainLayout(
|
||||
@ -723,37 +760,6 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
|
||||
);
|
||||
}
|
||||
|
||||
// Widget _buildDataTable(BuildContext context) {
|
||||
// if (filteredData.isEmpty) {
|
||||
// return const SizedBox(
|
||||
// height: 50,
|
||||
// child: Center(child: Text('No available data')),
|
||||
// );
|
||||
// }
|
||||
//
|
||||
// final sortedData = [..._paginatedData];
|
||||
// return ListView.builder(
|
||||
// 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)
|
||||
// ? _buildDataRow(item, sno)
|
||||
// : _buildDataCard(item, sno);
|
||||
// },
|
||||
// );
|
||||
// }
|
||||
|
||||
Widget _buildHeader() {
|
||||
return SizedBox.shrink();
|
||||
}
|
||||
@ -803,18 +809,54 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
|
||||
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: InkWell(
|
||||
hoverColor: Color(0xffD9EBE8),
|
||||
focusColor: Color(0xffD9EBE8),
|
||||
splashColor: Color(0xffD9EBE8),
|
||||
highlightColor: Color(0xffD9EBE8),
|
||||
onTap: () {
|
||||
dynamic id = item['id'];
|
||||
print("ENQID : $id ");
|
||||
},
|
||||
child: Text(item['reg_no'] ?? '-', style: _dataBold),
|
||||
child: Builder(
|
||||
builder: (buttonContext) => InkWell(
|
||||
hoverColor: const Color(0xffD9EBE8),
|
||||
focusColor: const Color(0xffD9EBE8),
|
||||
splashColor: const Color(0xffD9EBE8),
|
||||
highlightColor: const Color(0xffD9EBE8),
|
||||
onTap: () async {
|
||||
// ✅ Get overlay and button position RELATIVE to InkWell
|
||||
final RenderBox button =
|
||||
buttonContext.findRenderObject() as RenderBox;
|
||||
final RenderBox overlay =
|
||||
Overlay.of(buttonContext).context.findRenderObject()
|
||||
as RenderBox;
|
||||
|
||||
final Offset position = button.localToGlobal(
|
||||
Offset.zero,
|
||||
ancestor: overlay,
|
||||
);
|
||||
|
||||
await showMenu(
|
||||
context: buttonContext,
|
||||
position: RelativeRect.fromLTRB(
|
||||
position.dx,
|
||||
position.dy + button.size.height,
|
||||
overlay.size.width - position.dx,
|
||||
0,
|
||||
),
|
||||
items: [
|
||||
PopupMenuItem(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: _buildPopupDownload(
|
||||
buttonContext,
|
||||
item,
|
||||
item['id'],
|
||||
item['reg_no'],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
color: Colors.white,
|
||||
);
|
||||
},
|
||||
child: Text(item['reg_no'] ?? '-', style: _dataBold),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
flex: 3,
|
||||
|
||||
@ -837,79 +879,24 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Text(item['status'] ?? '-', style: _dataBold),
|
||||
),
|
||||
child: InkWell(
|
||||
onTap: () async {
|
||||
var status = item['status'];
|
||||
var enqId = item['id'];
|
||||
|
||||
// Expanded(
|
||||
// flex: 2,
|
||||
// child: Text(item['assigned_to_name'] ?? '-', style: _dataBold),
|
||||
// ),
|
||||
//
|
||||
// Expanded(
|
||||
// flex: 2,
|
||||
// child: Text(
|
||||
// item['premium_amount'] ?? '-',
|
||||
// style: _dataBold,
|
||||
// softWrap: true,
|
||||
// maxLines: 3,
|
||||
// ),
|
||||
// ),
|
||||
// Expanded(
|
||||
// flex: 2,
|
||||
// child: Text(
|
||||
// item['payment_mode'] ?? '-',
|
||||
// style: _dataBold,
|
||||
// softWrap: true,
|
||||
// maxLines: 3,
|
||||
// ),
|
||||
// ),
|
||||
// Expanded(
|
||||
// flex: 2,
|
||||
// child: Text(
|
||||
// item['policy_number'] ?? '-',
|
||||
// style: _dataBold,
|
||||
// softWrap: true,
|
||||
// maxLines: 3,
|
||||
// ),
|
||||
// ),
|
||||
// Expanded(
|
||||
// flex: 1,
|
||||
// child: Row(
|
||||
// children: [
|
||||
// PopupMenuButton<int>(
|
||||
// color: Colors.white,
|
||||
// padding: EdgeInsets.zero,
|
||||
// offset: Offset(0, 30),
|
||||
// icon: Icon(
|
||||
// Icons.more_vert,
|
||||
// color: Color(0xFF475569),
|
||||
// size: 14,
|
||||
// ),
|
||||
// itemBuilder: (context) => [
|
||||
// CustomPopupMenuEntry(
|
||||
// child: Container(
|
||||
// padding: EdgeInsets.symmetric(
|
||||
// horizontal: 8,
|
||||
// vertical: 8,
|
||||
// ),
|
||||
// child: Column(
|
||||
// mainAxisSize: MainAxisSize.min,
|
||||
// mainAxisAlignment: MainAxisAlignment.start,
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: _buildPopupMenuActions(
|
||||
// context,
|
||||
// item,
|
||||
// item['id'],
|
||||
// item['reg_no'],
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
// ✅ Remove old value (if any)
|
||||
await prefs.remove('enqStaffDataId');
|
||||
|
||||
// ✅ Save the new id
|
||||
await prefs.setString('enqStaffDataId', enqId.toString());
|
||||
ref.read(quotationStaffIdProvider.notifier).state = enqId;
|
||||
buildStatusActions(context, status, enqId);
|
||||
},
|
||||
child: Text(item['status'] ?? '-', style: _dataBold),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
@ -1101,6 +1088,129 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildDocRC(BuildContext context, bool isMobile, selectedEnquiryId) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
// print("Upload $idget.id}{w");
|
||||
final selectedId = selectedEnquiryId;
|
||||
// final path =
|
||||
// 'api/agent/downloadAgentIncentiveFile?id=$selectedId';
|
||||
final path =
|
||||
'api/enquiry/downloadEnquiryFile?enquiry_id=$selectedId&file_type=rc';
|
||||
apiService.getPdfDownload(path, selectedId);
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 6),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
color: const Color(0xFF425B5B),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
"RC",
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
?isMobile ? null : SizedBox(width: 2),
|
||||
// isMobile ? const Spacer() : const SizedBox(width: 15),
|
||||
const Icon(
|
||||
Icons.file_download_outlined,
|
||||
size: 16,
|
||||
color: Colors.white,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildDocIdProof(
|
||||
BuildContext context,
|
||||
bool isMobile,
|
||||
selectedEnquiryId,
|
||||
) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
print("Upload $selectedEnquiryId");
|
||||
final selectedId = selectedEnquiryId;
|
||||
// final path =
|
||||
// 'api/agent/downloadAgentIncentiveFile?id=$selectedId';
|
||||
final path =
|
||||
'api/enquiry/downloadEnquiryFile?enquiry_id=$selectedId&file_type=id_proof';
|
||||
apiService.getPdfDownload(path, selectedId);
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 6),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
color: const Color(0xFF425B5B),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
"ID Proof",
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
?isMobile ? null : SizedBox(width: 2),
|
||||
// const SizedBox(width: 15),
|
||||
Icon(Icons.file_download_outlined, size: 16, color: Colors.white),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildDocPrevPolicy(
|
||||
BuildContext context,
|
||||
bool isMobile,
|
||||
selectedEnquiryId,
|
||||
) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
print("QD597 Upload $selectedEnquiryId");
|
||||
final selectedId = selectedEnquiryId;
|
||||
// final path =
|
||||
// 'api/agent/downloadAgentIncentiveFile?id=$selectedId';
|
||||
final path =
|
||||
'api/enquiry/downloadEnquiryFile?enquiry_id=$selectedId&file_type=previous_policy';
|
||||
apiService.getPdfDownload(path, selectedId);
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4, horizontal: 6),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
color: const Color(0xFF425B5B),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
"Previous Policy",
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
?isMobile ? null : SizedBox(width: 2),
|
||||
// isMobile ? const Spacer() : const SizedBox(width: 15),
|
||||
Icon(Icons.file_download_outlined, size: 16, color: Colors.white),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
static final _dataBold = TextStyle(
|
||||
fontSize: 14,
|
||||
|
||||
|
||||
@ -700,13 +700,16 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
|
||||
children: [
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Text('Created Date', style: _headerStyle),
|
||||
child: Text('Received Date & Time', style: _headerStyle),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Text('Updated Date', style: _headerStyle),
|
||||
),
|
||||
Expanded(flex: 2, child: Text('Reg.No', style: _headerStyle)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text('Vehicle.No', style: _headerStyle),
|
||||
),
|
||||
Expanded(flex: 2, child: Text('Partner', style: _headerStyle)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
@ -1005,7 +1008,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
const Text("Company", style: _cardheaderStyle),
|
||||
const Text("Insurer", style: _cardheaderStyle),
|
||||
Text(item['insurer_name'] ?? '-', style: _cardBodyStyle),
|
||||
],
|
||||
),
|
||||
|
||||
769
lib/presentation/screens/staff/Enquiry/tabs/createQuotation.dart
Normal file
769
lib/presentation/screens/staff/Enquiry/tabs/createQuotation.dart
Normal file
@ -0,0 +1,769 @@
|
||||
import 'dart:convert';
|
||||
|
||||
import 'package:dropdown_search/dropdown_search.dart';
|
||||
import 'package:file_picker/file_picker.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:http/http.dart' as http;
|
||||
import 'package:nhance_partner/data/utils/toastNotification.dart';
|
||||
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import '../../../../../core/config/env.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/responsive_layout.dart';
|
||||
import '../../../../providers/manager_provider.dart';
|
||||
import '../../../../providers/quotation_staff_proivder.dart';
|
||||
import '../../../../themes/indicators/customizd_file_upload.dart';
|
||||
import '../../../../themes/indicators/input_field_decoration.dart';
|
||||
import '../../../../themes/indicators/text_field_theme.dart';
|
||||
|
||||
class CreateQuotationForm extends ConsumerStatefulWidget {
|
||||
final dynamic userId;
|
||||
final dynamic managerId;
|
||||
final dynamic selectedEnquiryId;
|
||||
final dynamic selectedInsurdId;
|
||||
final dynamic selectedQuotationFrmListdata;
|
||||
final dynamic selectedQuotationFrmListId;
|
||||
final void Function(String value) onSubmit;
|
||||
|
||||
const CreateQuotationForm({
|
||||
super.key,
|
||||
required this.userId,
|
||||
required this.managerId,
|
||||
required this.selectedEnquiryId,
|
||||
required this.selectedInsurdId,
|
||||
this.selectedQuotationFrmListdata,
|
||||
this.selectedQuotationFrmListId,
|
||||
required this.onSubmit,
|
||||
});
|
||||
|
||||
@override
|
||||
ConsumerState<CreateQuotationForm> createState() =>
|
||||
CreateQuotationFormState();
|
||||
// State<CreateQuotationForm> createState() => _CreateQuotationFormState();
|
||||
}
|
||||
|
||||
class CreateQuotationFormState extends ConsumerState<CreateQuotationForm> {
|
||||
late ApiService apiService;
|
||||
String? _token;
|
||||
|
||||
String? selectedFileNames;
|
||||
|
||||
List<Map<String, dynamic>> getInsurersData = [];
|
||||
List<Map<String, dynamic>> filteredInsurersData = [];
|
||||
String? selectedInsurer;
|
||||
|
||||
bool isLoading = false;
|
||||
bool _autoValidate = false;
|
||||
late TextEditingController controller;
|
||||
Map<String, TextEditingController> controllers = {};
|
||||
|
||||
final _formKey = GlobalKey<FormState>();
|
||||
|
||||
String? docUploadedFileUrlFromApi;
|
||||
String? selectedId;
|
||||
PlatformFile? docUploadedFile;
|
||||
|
||||
final GlobalKey<DropdownSearchState<Map<String, dynamic>>> dropDownKey =
|
||||
GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
|
||||
|
||||
final GlobalKey<DropdownSearchState<Map<String, dynamic>>>
|
||||
dropDownKeyInsurer = GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
|
||||
|
||||
List<String> tabHeader = ['idv', 'premium_Amount', 'insurer'];
|
||||
|
||||
List<Map<String, dynamic>> getInsuranceTypeData = [];
|
||||
List<Map<String, dynamic>> filteredInsuranceData = [];
|
||||
|
||||
String? selectedInsPlanType;
|
||||
String? selectedEndorsement;
|
||||
|
||||
Map<String, dynamic> dataDetails() {
|
||||
final data = {
|
||||
"enquiry_id": widget.selectedEnquiryId,
|
||||
"insured_declared_value": controllers["idv"]?.text,
|
||||
"insurer_id": widget.selectedInsurdId,
|
||||
// "insurer_id": selectedInsurer,
|
||||
"premium_amount": controllers["premium_Amount"]?.text,
|
||||
"insurance_plan_type_id": selectedInsPlanType,
|
||||
// "additional_uploaded_file_name": "extra_doc.pdf",
|
||||
// "created_by": widget.userId,
|
||||
"manager_id": widget.managerId,
|
||||
};
|
||||
return data;
|
||||
}
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
apiService = ApiService();
|
||||
for (String field in tabHeader) {
|
||||
controllers[field] = TextEditingController();
|
||||
}
|
||||
|
||||
// 🔹 Init logic here (API calls, token fetch, etc.)
|
||||
_initializeToken();
|
||||
getInsuranceType();
|
||||
// getInsurers();
|
||||
updateData();
|
||||
}
|
||||
|
||||
Future<void> _initializeToken() async {
|
||||
_token = await AuthService.getToken();
|
||||
print("APISERTOKEN - $_token");
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
// Dispose all TextEditingControllers
|
||||
for (var controller in controllers.values) {
|
||||
controller.dispose();
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
void reset() {
|
||||
_formKey.currentState?.reset();
|
||||
// Clear all TextEditingControllers
|
||||
for (var controller in controllers.values) {
|
||||
controller.clear();
|
||||
}
|
||||
dropDownKey.currentState?.changeSelectedItem(null);
|
||||
dropDownKeyInsurer.currentState?.changeSelectedItem(null);
|
||||
|
||||
// Reset dropdowns / selections
|
||||
selectedInsurer = null;
|
||||
selectedInsPlanType = null;
|
||||
selectedEndorsement = null;
|
||||
|
||||
// Reset file selection
|
||||
selectedFileNames = null;
|
||||
docUploadedFile = null;
|
||||
docUploadedFileUrlFromApi = null;
|
||||
|
||||
// Reset selected ID
|
||||
selectedId = null;
|
||||
|
||||
// Trigger UI update
|
||||
setState(() {});
|
||||
}
|
||||
|
||||
void updateData() {
|
||||
if (widget.selectedQuotationFrmListId != null &&
|
||||
widget.selectedQuotationFrmListdata!.isNotEmpty) {
|
||||
print('checkData -- ${widget.selectedQuotationFrmListdata}');
|
||||
selectedId = widget.selectedQuotationFrmListId!;
|
||||
// Pre-fill controllers
|
||||
controllers["idv"]?.text =
|
||||
widget.selectedQuotationFrmListdata!['insured_declared_value']
|
||||
?.toString() ??
|
||||
'';
|
||||
controllers["premium_Amount"]?.text =
|
||||
widget.selectedQuotationFrmListdata!['premium_amount']?.toString() ??
|
||||
'';
|
||||
|
||||
selectedInsPlanType = widget
|
||||
.selectedQuotationFrmListdata!['insurance_plan_type_id']
|
||||
?.toString();
|
||||
|
||||
selectedInsurer = '1';
|
||||
|
||||
// controllers["insurer"]?.text = 'LIC';
|
||||
|
||||
// selectedInsurer =
|
||||
// widget.selectedQuotationFrmListdata!['insurer_id']?.toString() ?? '';
|
||||
|
||||
String? apiDocPath =
|
||||
widget.selectedQuotationFrmListdata!["additional_uploaded_file_name"];
|
||||
if (apiDocPath != null && apiDocPath.isNotEmpty) {
|
||||
print('apiDocPath - $apiDocPath');
|
||||
selectedFileNames = apiDocPath.split('/').last;
|
||||
print('selectedFileNames - $selectedFileNames');
|
||||
docUploadedFileUrlFromApi = apiDocPath;
|
||||
print('passportFileUrlFromApi - $docUploadedFileUrlFromApi');
|
||||
docUploadedFile = null;
|
||||
} else {
|
||||
selectedFileNames = null;
|
||||
docUploadedFile = null;
|
||||
docUploadedFileUrlFromApi = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getInsurers() async {
|
||||
print('Insurers called');
|
||||
setState(() {
|
||||
isLoading = true;
|
||||
});
|
||||
|
||||
try {
|
||||
final response = await apiService.fetchMasterDropDown('Insurers');
|
||||
|
||||
if (response['status'] == 200) {
|
||||
print('getInsurers - ${response['data']}');
|
||||
setState(() {
|
||||
getInsurersData = List<Map<String, dynamic>>.from(response['data']);
|
||||
print('API Data - $getInsurersData');
|
||||
|
||||
filteredInsurersData = List.from(getInsurersData);
|
||||
print('originalData - $filteredInsurersData');
|
||||
});
|
||||
} else {
|
||||
getInsurersData = [];
|
||||
filteredInsurersData = [];
|
||||
}
|
||||
} catch (e) {
|
||||
print('Exception occurred: $e');
|
||||
} finally {
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getInsuranceType() async {
|
||||
print('getClaimList called');
|
||||
setState(() {
|
||||
isLoading = true;
|
||||
});
|
||||
|
||||
try {
|
||||
final response = await apiService.fetchMasterDropDown('InsuranceType');
|
||||
|
||||
if (response['status'] == 200) {
|
||||
print('getInsuranceTypeData - ${response['data']}');
|
||||
setState(() {
|
||||
getInsuranceTypeData = List<Map<String, dynamic>>.from(
|
||||
response['data'],
|
||||
);
|
||||
print('API Data - $getInsuranceTypeData');
|
||||
|
||||
filteredInsuranceData = List.from(getInsuranceTypeData);
|
||||
print('originalData - $filteredInsuranceData');
|
||||
});
|
||||
} else {
|
||||
getInsuranceTypeData = [];
|
||||
filteredInsuranceData = [];
|
||||
}
|
||||
} catch (e) {
|
||||
print('Exception occurred: $e');
|
||||
} finally {
|
||||
setState(() {
|
||||
isLoading = false;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void handleDone() {
|
||||
if (!_formKey.currentState!.validate()) return;
|
||||
|
||||
// setState(() {
|
||||
// _autoValidate = true; // enable autovalidation after first save attempt
|
||||
// });
|
||||
setState(() {
|
||||
if (_formKey.currentState!.validate()) {
|
||||
dataDetails();
|
||||
final dataSet = dataDetails();
|
||||
print("dataSetAgent - $dataSet");
|
||||
// print("managerId - $managerId ,userId - $userId ");
|
||||
createUserData(dataSet);
|
||||
} else {
|
||||
// isDi sable = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
Future<void> createUserData(Map<String, dynamic> userData) async {
|
||||
// final bool isUpdating = widget.selectedQuotationFrmListId != null;
|
||||
// final id = widget.selectedQuotationFrmListId!;
|
||||
|
||||
final bool isUpdating = widget.selectedQuotationFrmListId != null;
|
||||
final id = widget.selectedQuotationFrmListId; // keep nullable
|
||||
|
||||
print('id - $id');
|
||||
final uri = Uri.parse(
|
||||
// isUpdating
|
||||
// ? 'https://venbait.in/nhance/partner/dev/api/agent/updateAgent'
|
||||
// : 'https://venbait.in/nhance/partner/dev/api/agent/createAgent',
|
||||
isUpdating
|
||||
? '${Env.apiUrl}quotation/updateQuotation'
|
||||
: '${Env.apiUrl}quotation/createQuotation',
|
||||
);
|
||||
if (_token == null) {
|
||||
throw Exception('Token not found. Please log in.');
|
||||
}
|
||||
|
||||
// Use MultipartRequest (POST only)
|
||||
final request = http.MultipartRequest('POST', uri);
|
||||
request.headers['Authorization'] = 'Bearer $_token';
|
||||
request.headers['app-signature'] =
|
||||
'nhance-partner-2025-signature-35468846JRhH551HK';
|
||||
|
||||
// If updating, spoof the method Laravel-style
|
||||
if (isUpdating) {
|
||||
print('Updatrinf');
|
||||
// request.fields['_method'] = 'PUT';
|
||||
request.fields['id'] = id!;
|
||||
request.fields['updated_by'] = widget.userId!.toString();
|
||||
} else {
|
||||
print('Not Updatrinf');
|
||||
request.fields['created_by'] = widget.userId!.toString();
|
||||
}
|
||||
|
||||
print("USerDAta - $userData");
|
||||
|
||||
// userData.forEach((key, value) {
|
||||
// request.fields[key] = value.toString();
|
||||
// print("✅ Encoded travel_details2: ${request.fields[key]}");
|
||||
// });
|
||||
|
||||
userData.forEach((key, value) {
|
||||
// if (key != 'certificate_file_name') {
|
||||
request.fields[key] = value.toString();
|
||||
print("✅ Encoded $key: ${request.fields[key]}");
|
||||
// }
|
||||
});
|
||||
|
||||
if (docUploadedFile != null) {
|
||||
try {
|
||||
if (docUploadedFile!.bytes != null) {
|
||||
final multipartFile = http.MultipartFile.fromBytes(
|
||||
'additional_uploaded_file_name',
|
||||
docUploadedFile!.bytes!,
|
||||
filename: docUploadedFile!.name,
|
||||
);
|
||||
request.files.add(multipartFile);
|
||||
} else if (docUploadedFile!.path != null) {
|
||||
final multipartFile = await http.MultipartFile.fromPath(
|
||||
'additional_uploaded_file_name',
|
||||
docUploadedFile!.path!,
|
||||
filename: docUploadedFile!.name,
|
||||
);
|
||||
request.files.add(multipartFile);
|
||||
}
|
||||
print("📎 File attached: ${docUploadedFile!.name}");
|
||||
} catch (e) {
|
||||
print("❌ Failed to attach file: $e");
|
||||
}
|
||||
}
|
||||
|
||||
print(" Sending request with fields: ${request.fields}");
|
||||
|
||||
try {
|
||||
final streamedResponse = await request.send();
|
||||
final response = await http.Response.fromStream(streamedResponse);
|
||||
print("Response status: ${response.statusCode}");
|
||||
print("Response body: ${response.body}");
|
||||
|
||||
if (response.statusCode == 200 || response.statusCode == 201) {
|
||||
// dispose();
|
||||
print("✅ Agent submitted successfully!");
|
||||
|
||||
print("Response: ${response.body}");
|
||||
widget.onSubmit('Success');
|
||||
reset();
|
||||
// Navigator.of(context).pop();
|
||||
} else {
|
||||
final responseBody = jsonDecode(response.body);
|
||||
dynamic msg = responseBody['data'];
|
||||
print("❌ Submission failed. Status: ${response.statusCode}");
|
||||
print("Body: ${response.body}");
|
||||
|
||||
ToastHelper.showErrorToast(context, 'Proposal Creation Failed');
|
||||
}
|
||||
} catch (e) {
|
||||
print("🔥 Error submitting user: $e");
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// Header row
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Text(
|
||||
widget.selectedQuotationFrmListId != null
|
||||
? 'Update Proposal'
|
||||
: 'Create Proposal',
|
||||
style: GoogleFonts.inter(
|
||||
color: const Color(0xFF374141),
|
||||
fontSize: 14,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
const SizedBox(height: 8),
|
||||
|
||||
// 🔹 Switch content dynamically
|
||||
buildFormFields(context),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildFormFields(BuildContext context) {
|
||||
return Form(
|
||||
key: _formKey,
|
||||
// autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
// autovalidateMode: _autoValidate
|
||||
// ? AutovalidateMode.onUserInteraction
|
||||
// : AutovalidateMode.disabled,
|
||||
child: Row(
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
|
||||
children: [
|
||||
buildIdv(context),
|
||||
Spacer(),
|
||||
// buildInsurer(context),
|
||||
buildInsurancePlanType(context),
|
||||
Spacer(),
|
||||
buildPremiumAmnt(context),
|
||||
Spacer(),
|
||||
// buildDocuments(context),
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
handleDone();
|
||||
// widget.onSubmit(controller.text.trim());
|
||||
// Navigator.of(context).pop();
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 25.0,
|
||||
vertical: 15,
|
||||
),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
color: const Color(0xFF425B5B),
|
||||
),
|
||||
child: const Text(
|
||||
'Save',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
// if (!ResponsiveLayout.isMobile(context)) const SizedBox(height: 10),
|
||||
// _buildResponsiveRow(
|
||||
// context,
|
||||
// buildAdditonalDocuments(context),
|
||||
// buildRemarks(context),
|
||||
// ),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
// ------------------------- Claims Part -----------------------------------
|
||||
|
||||
Widget buildIdv(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('IDV *', style: _textStyle),
|
||||
SizedBox(height: 10),
|
||||
ThemedFormField(
|
||||
controller: controllers['idv']!,
|
||||
validator: (value) => Validators.doubleNumber(value, "IDV"),
|
||||
// validator: (value) => Validators.number(value, "IDV"),
|
||||
backgroundColor: Color(0xFFEDF6F5),
|
||||
// readOnly: true,
|
||||
txtwidth: ResponsiveLayout.isMobile(context)
|
||||
? null
|
||||
: MediaQuery.of(context).size.width * 0.15,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildInsurer2(BuildContext context) {
|
||||
Map<String, dynamic>? selectedInsurerd = filteredInsurersData.firstWhere(
|
||||
(item) => item['id'].toString() == selectedInsurer,
|
||||
orElse: () => {},
|
||||
);
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Insurer *', style: _textStyle),
|
||||
SizedBox(height: 10),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
// borderRadius: BorderRadius.circular(10.0),
|
||||
),
|
||||
width: ResponsiveLayout.isMobile(context)
|
||||
? null
|
||||
: MediaQuery.of(context).size.width * 0.26,
|
||||
// height: 40,
|
||||
child: DropdownSearch<Map<String, dynamic>>(
|
||||
key: dropDownKeyInsurer,
|
||||
selectedItem: selectedInsurerd.isNotEmpty ? selectedInsurerd : null,
|
||||
items: (filter, infiniteScrollProps) {
|
||||
return filteredInsurersData;
|
||||
},
|
||||
|
||||
itemAsString: (val) => val['name'].toString(), // what to show
|
||||
compareFn: (item, selectedItem) =>
|
||||
item['id'] == selectedItem['id'], // ✅ compare by id
|
||||
validator: (val) {
|
||||
if (val == null) {
|
||||
return "Required"; // ✅ error message
|
||||
}
|
||||
return null;
|
||||
},
|
||||
decoratorProps: DropDownDecoratorProps(
|
||||
decoration:
|
||||
AppInputDecorations.dropdownDecoration(
|
||||
label: "Select Insurer",
|
||||
).copyWith(
|
||||
filled: true,
|
||||
fillColor: Color(
|
||||
0xFFEDF6F5,
|
||||
), // 👈 makes the dropdown input white
|
||||
),
|
||||
),
|
||||
|
||||
popupProps: PopupProps.menu(
|
||||
fit: FlexFit.loose,
|
||||
constraints: BoxConstraints(maxHeight: 250),
|
||||
menuProps: MenuProps(
|
||||
backgroundColor:
|
||||
Colors.white, // 👈 sets dropdown background to white
|
||||
),
|
||||
showSearchBox: true,
|
||||
searchFieldProps: TextFieldProps(
|
||||
decoration: InputDecoration(
|
||||
filled: true,
|
||||
fillColor: Colors.white,
|
||||
hintText: "Search Insurer...",
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Colors.white,
|
||||
), // 👈 Normal border
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Colors.white,
|
||||
width: 1.5,
|
||||
), // 👈 Focused border
|
||||
),
|
||||
),
|
||||
),
|
||||
// constraints: BoxConstraints(),
|
||||
),
|
||||
|
||||
onChanged: (val) {
|
||||
if (val != null) {
|
||||
print("Selected Insurer : ${val['name']}");
|
||||
print("Id: ${val['id']}");
|
||||
selectedInsurer = val['id'];
|
||||
// controllers['agentId']?.text = val['agent_code'];
|
||||
// agentId = agent['id'];
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildPremiumAmnt(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Premium Amount *', style: _textStyle),
|
||||
SizedBox(height: 10),
|
||||
ThemedFormField(
|
||||
controller: controllers['premium_Amount']!,
|
||||
backgroundColor: Color(0xFFEDF6F5),
|
||||
validator: (value) => Validators.doubleNumber(value, "PremiumAmount"),
|
||||
// validator: (value) => Validators.number(value, "PremiumAmount "),
|
||||
txtwidth: ResponsiveLayout.isMobile(context)
|
||||
? null
|
||||
: MediaQuery.of(context).size.width * 0.15,
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildInsurancePlanType(context) {
|
||||
Map<String, dynamic>? selectedVehicle = filteredInsuranceData.firstWhere(
|
||||
(item) => item['id'].toString() == selectedInsPlanType,
|
||||
orElse: () => {},
|
||||
);
|
||||
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Plan Type *", style: _textStyle),
|
||||
SizedBox(height: 10),
|
||||
Container(
|
||||
color: Colors.white,
|
||||
width: ResponsiveLayout.isMobile(context)
|
||||
? null
|
||||
: MediaQuery.of(context).size.width * 0.15,
|
||||
// height: 40,
|
||||
child: DropdownSearch<Map<String, dynamic>>(
|
||||
key: dropDownKey,
|
||||
selectedItem: selectedVehicle.isNotEmpty ? selectedVehicle : null,
|
||||
items: (filter, infiniteScrollProps) {
|
||||
return filteredInsuranceData;
|
||||
},
|
||||
|
||||
itemAsString: (val) => val['insurance_plan_type'].toString(),
|
||||
compareFn: (item, selectedItem) =>
|
||||
item['id'] == selectedItem['id'], // ✅ compare by id
|
||||
validator: (val) {
|
||||
if (val == null) {
|
||||
return "Required"; // ✅ error message
|
||||
}
|
||||
return null;
|
||||
},
|
||||
decoratorProps: DropDownDecoratorProps(
|
||||
decoration:
|
||||
AppInputDecorations.dropdownDecoration(
|
||||
label: "Select Plan Type",
|
||||
).copyWith(
|
||||
filled: true,
|
||||
fillColor: Color(
|
||||
0xFFEDF6F5,
|
||||
), // 👈 makes the dropdown input white
|
||||
),
|
||||
),
|
||||
|
||||
popupProps: PopupProps.menu(
|
||||
fit: FlexFit.loose,
|
||||
constraints: BoxConstraints(maxHeight: 250),
|
||||
menuProps: MenuProps(
|
||||
backgroundColor:
|
||||
Colors.white, // 👈 sets dropdown background to white
|
||||
),
|
||||
showSearchBox: true,
|
||||
searchFieldProps: TextFieldProps(
|
||||
decoration: InputDecoration(
|
||||
filled: true,
|
||||
fillColor: Colors.white,
|
||||
hintText: "Search Plan Type...",
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Colors.white,
|
||||
), // 👈 Normal border
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Colors.white,
|
||||
width: 1.5,
|
||||
), // 👈 Focused border
|
||||
),
|
||||
),
|
||||
),
|
||||
// constraints: BoxConstraints(),
|
||||
),
|
||||
|
||||
onChanged: (val) {
|
||||
if (val != null) {
|
||||
print("Selected ClaimsType : ${val['insurance_plan_type']}");
|
||||
print("Id: ${val['id']}");
|
||||
selectedInsPlanType = val['id'];
|
||||
// controllers['agentId']?.text = val['agent_code'];
|
||||
// agentId = agent['id'];
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildDocuments(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Proposal Documents ', style: _textStyle),
|
||||
const SizedBox(height: 10),
|
||||
Column(
|
||||
mainAxisAlignment: MainAxisAlignment.end,
|
||||
crossAxisAlignment: CrossAxisAlignment.end,
|
||||
children: [
|
||||
ThemedUploadField(
|
||||
hintText: selectedFileNames ?? "Upload Document",
|
||||
txtwidth: ResponsiveLayout.isMobile(context)
|
||||
? null
|
||||
: MediaQuery.of(context).size.width * 0.26,
|
||||
backgroundColor: Color(0xFFEDF6F5),
|
||||
onFileSelected: (fileName, file) {
|
||||
print("Picked file: $fileName (${file.size} bytes)");
|
||||
setState(() {
|
||||
docUploadedFile = file;
|
||||
});
|
||||
},
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
|
||||
if (docUploadedFileUrlFromApi != null)
|
||||
Container(
|
||||
// color: Colors.white,
|
||||
child: Row(
|
||||
children: [
|
||||
GestureDetector(
|
||||
onTap: () => apiService.downloadFile(
|
||||
apiUrl:
|
||||
'api/quotation/downloadAdditionalUploadedFile?id=$selectedId',
|
||||
apiId: selectedId,
|
||||
localFile: docUploadedFile,
|
||||
fileName: selectedFileNames,
|
||||
),
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(5),
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
color: Color(0xFF425B5B),
|
||||
// color: Colors.green.shade300,
|
||||
),
|
||||
child: Row(
|
||||
children: const [
|
||||
Text(
|
||||
"Download",
|
||||
style: TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w200,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
SizedBox(width: 5),
|
||||
Icon(Icons.download, size: 13, color: Colors.white),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
// ------------------- STyle ---------------------------------
|
||||
|
||||
static final TextStyle _textStyle = TextStyle(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w600,
|
||||
);
|
||||
}
|
||||
1419
lib/presentation/screens/staff/Enquiry/tabs/policyTab.dart
Normal file
1419
lib/presentation/screens/staff/Enquiry/tabs/policyTab.dart
Normal file
File diff suppressed because it is too large
Load Diff
723
lib/presentation/screens/staff/Enquiry/tabs/quotationTab.dart
Normal file
723
lib/presentation/screens/staff/Enquiry/tabs/quotationTab.dart
Normal file
@ -0,0 +1,723 @@
|
||||
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: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 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
|
||||
|
||||
print('QmanagerId - $managerId');
|
||||
print('QuserId - $userId');
|
||||
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');
|
||||
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--");
|
||||
if (enqQuotation != null) {
|
||||
_loadData(enqQuotation);
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> getQuotationList(enqQuotation) async {
|
||||
print('getClaimList called enqQuotation- $enqQuotation');
|
||||
setState(() {
|
||||
isLoading = true;
|
||||
});
|
||||
|
||||
try {
|
||||
final response = await apiService.findEnqQuotePolicyView(enqQuotation);
|
||||
|
||||
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 {
|
||||
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) ...[
|
||||
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),
|
||||
],
|
||||
|
||||
//(TABLE)
|
||||
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.44
|
||||
: MediaQuery.of(context).size.height * 0.6,
|
||||
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('Registration 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: "Registration 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('Registration 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,
|
||||
);
|
||||
}
|
||||
214
lib/presentation/screens/staff/Enquiry/tabs/tab.dart
Normal file
214
lib/presentation/screens/staff/Enquiry/tabs/tab.dart
Normal file
@ -0,0 +1,214 @@
|
||||
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:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import '../../../../../core/routing/routes.dart';
|
||||
import '../../../../../core/services/api_service.dart';
|
||||
import '../../../../layouts/main_layout.dart';
|
||||
import '../../../../providers/manager_provider.dart';
|
||||
import '../../../../providers/quotation_staff_proivder.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;
|
||||
|
||||
@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", 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 ');
|
||||
|
||||
setState(() {
|
||||
print('loadQuotationTab 4');
|
||||
// enquiryData = response["data"];
|
||||
isLoading = false;
|
||||
tabs = [
|
||||
TabItem("Proposal", 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;
|
||||
});
|
||||
}
|
||||
|
||||
/// 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.55,
|
||||
height: MediaQuery.of(context).size.height * 0.7,
|
||||
|
||||
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: [
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
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),
|
||||
),
|
||||
);
|
||||
}),
|
||||
),
|
||||
|
||||
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),
|
||||
Expanded(child: tabs[selectedIndex].widget),
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class TabItem {
|
||||
final String title;
|
||||
final Widget widget;
|
||||
TabItem(this.title, this.widget);
|
||||
}
|
||||
@ -5,6 +5,7 @@ import 'package:flutter/material.dart';
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
import 'package:http/http.dart' as http;
|
||||
import 'package:nhance_partner/presentation/providers/userRoleProvider.dart';
|
||||
|
||||
import 'package:toastification/toastification.dart';
|
||||
|
||||
@ -27,7 +28,6 @@ class AssignStaffDialog extends ConsumerStatefulWidget {
|
||||
|
||||
const AssignStaffDialog({
|
||||
super.key,
|
||||
|
||||
required this.onSubmit,
|
||||
required this.regNum,
|
||||
required this.userId,
|
||||
@ -42,7 +42,7 @@ class AssignStaffDialog extends ConsumerStatefulWidget {
|
||||
class _AddDialogState extends ConsumerState<AssignStaffDialog> {
|
||||
late ApiService apiService;
|
||||
String? _token;
|
||||
|
||||
dynamic role;
|
||||
bool isLoading = false;
|
||||
bool showSuccess = false;
|
||||
late TextEditingController controller;
|
||||
@ -96,10 +96,13 @@ class _AddDialogState extends ConsumerState<AssignStaffDialog> {
|
||||
getInsurers();
|
||||
Future.microtask(() {
|
||||
final managerId = ref.watch(managerIdProvider);
|
||||
final handlerId = ref.watch(handlerIdProvider);
|
||||
if (handlerId != null) {
|
||||
final userID = ref.watch(userIdProvider);
|
||||
// final handlerId = ref.watch(handlerIdProvider);
|
||||
role = ref.watch(userRoleProvider);
|
||||
print("managerId - $managerId");
|
||||
if (userID != null) {
|
||||
print('hansles');
|
||||
getStaffDetails(handlerId);
|
||||
getStaffDetails(userID);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ -141,17 +144,15 @@ class _AddDialogState extends ConsumerState<AssignStaffDialog> {
|
||||
}
|
||||
|
||||
Future<void> getStaffDetails(int id) async {
|
||||
print('getStaffDetails called');
|
||||
print('getStaffDetails called By handler');
|
||||
setState(() {
|
||||
isLoading = true;
|
||||
});
|
||||
|
||||
try {
|
||||
final response = await apiService.fetchStaffListForEnquiryAssignDropDown(
|
||||
id,
|
||||
);
|
||||
final response = await apiService.fetchStaffUserList(id, role);
|
||||
|
||||
if (response['status'] == 200) {
|
||||
if (response['status'] == 'success') {
|
||||
print('getStaffDetails - ${response['data']}');
|
||||
setState(() {
|
||||
getStaffDetailsData = List<Map<String, dynamic>>.from(
|
||||
|
||||
@ -1222,7 +1222,7 @@ class PolicyScreenState extends ConsumerState<PolicyScreen> {
|
||||
date.year + 1,
|
||||
date.month,
|
||||
date.day,
|
||||
).subtract(const Duration(days: 1)); // optional: subtract 1 day
|
||||
); // optional: subtract 1 day
|
||||
|
||||
controllers['endDate']?.text = DateFormat(
|
||||
'dd-MM-yyyy',
|
||||
@ -1250,64 +1250,97 @@ class PolicyScreenState extends ConsumerState<PolicyScreen> {
|
||||
txtheight: 50,
|
||||
// backgroundColor: const Color(0xFFECECEC),
|
||||
// validator: (value) => Validators.requiredField(value, "date"),
|
||||
// validator: (value) {
|
||||
// if (value == null || value.isEmpty) {
|
||||
// return "Required";
|
||||
// }
|
||||
//
|
||||
// final startDateControllerText = controllers['startDate']?.text;
|
||||
// if (startDateControllerText == null ||
|
||||
// startDateControllerText.isEmpty) {
|
||||
// return "Select start date first";
|
||||
// }
|
||||
//
|
||||
// final startDate = DateFormat(
|
||||
// 'dd-MM-yyyy',
|
||||
// ).parse(startDateControllerText);
|
||||
// final endDate = DateFormat('dd-MM-yyyy').parse(value);
|
||||
//
|
||||
// if (endDate.isBefore(startDate)) {
|
||||
// return "End date cannot be before start date";
|
||||
// }
|
||||
//
|
||||
// // Minimum end date = start date + 1 year - 1 day (or just +1 year)
|
||||
// final minEndDate = DateTime(
|
||||
// startDate.year + 1,
|
||||
// startDate.month,
|
||||
// startDate.day,
|
||||
// ).subtract(const Duration(days: 1));
|
||||
//
|
||||
// if (endDate.isBefore(minEndDate)) {
|
||||
// return "End date must be at least 1 year from start date";
|
||||
// }
|
||||
//
|
||||
// return null;
|
||||
//
|
||||
// // final startDateControllerText = controllers['startDate']?.text;
|
||||
// // if (startDateControllerText == null ||
|
||||
// // startDateControllerText.isEmpty) {
|
||||
// // return "Select start date first";
|
||||
// // }
|
||||
// //
|
||||
// // final startDate = DateFormat(
|
||||
// // 'dd-MM-yyyy',
|
||||
// // ).parse(startDateControllerText);
|
||||
// // final endDate = DateFormat('dd-MM-yyyy').parse(value);
|
||||
// //
|
||||
// // if (endDate.isBefore(startDate)) {
|
||||
// // return "End date cannot be before start date";
|
||||
// // }
|
||||
// //
|
||||
// // final expectedEndDate = DateTime(
|
||||
// // startDate.year + 1,
|
||||
// // startDate.month,
|
||||
// // startDate.day,
|
||||
// // ).subtract(const Duration(days: 1));
|
||||
// //
|
||||
// // if (endDate != expectedEndDate) {
|
||||
// // return "End date must be exactly 1 year from start date";
|
||||
// // }
|
||||
// //
|
||||
// // return null; // valid
|
||||
// },
|
||||
validator: (value) {
|
||||
if (value == null || value.isEmpty) {
|
||||
return "Required";
|
||||
}
|
||||
|
||||
final startDateControllerText = controllers['startDate']?.text;
|
||||
if (startDateControllerText == null ||
|
||||
startDateControllerText.isEmpty) {
|
||||
final startText = controllers['startDate']?.text;
|
||||
if (startText == null || startText.isEmpty) {
|
||||
return "Select start date first";
|
||||
}
|
||||
|
||||
final startDate = DateFormat('dd-MM-yyyy').parse(startDateControllerText);
|
||||
final endDate = DateFormat('dd-MM-yyyy').parse(value);
|
||||
final startDate = DateFormat('dd-MM-yyyy').parseStrict(startText);
|
||||
final endDate = DateFormat('dd-MM-yyyy').parseStrict(value);
|
||||
|
||||
if (endDate.isBefore(startDate)) {
|
||||
return "End date cannot be before start date";
|
||||
}
|
||||
|
||||
// Minimum end date = start date + 1 year - 1 day (or just +1 year)
|
||||
final minEndDate = DateTime(
|
||||
startDate.year + 1,
|
||||
startDate.month,
|
||||
startDate.day,
|
||||
).subtract(const Duration(days: 1));
|
||||
// Add 365 days - 1 day to start date
|
||||
final expectedEndDate = startDate
|
||||
.add(const Duration(days: 365))
|
||||
.subtract(const Duration(days: 1));
|
||||
|
||||
if (endDate.isBefore(minEndDate)) {
|
||||
return "End date must be at least 1 year from start date";
|
||||
if (endDate.day != expectedEndDate.day ||
|
||||
endDate.month != expectedEndDate.month ||
|
||||
endDate.year != expectedEndDate.year) {
|
||||
return "End date must be exactly 1 year minus 1 day from start date";
|
||||
}
|
||||
|
||||
return null;
|
||||
|
||||
// final startDateControllerText = controllers['startDate']?.text;
|
||||
// if (startDateControllerText == null ||
|
||||
// startDateControllerText.isEmpty) {
|
||||
// return "Select start date first";
|
||||
// }
|
||||
//
|
||||
// final startDate = DateFormat(
|
||||
// 'dd-MM-yyyy',
|
||||
// ).parse(startDateControllerText);
|
||||
// final endDate = DateFormat('dd-MM-yyyy').parse(value);
|
||||
//
|
||||
// if (endDate.isBefore(startDate)) {
|
||||
// return "End date cannot be before start date";
|
||||
// }
|
||||
//
|
||||
// final expectedEndDate = DateTime(
|
||||
// startDate.year + 1,
|
||||
// startDate.month,
|
||||
// startDate.day,
|
||||
// ).subtract(const Duration(days: 1));
|
||||
//
|
||||
// if (endDate != expectedEndDate) {
|
||||
// return "End date must be exactly 1 year from start date";
|
||||
// }
|
||||
//
|
||||
// return null; // valid
|
||||
},
|
||||
|
||||
controller: controllers['endDate']!,
|
||||
onDateSelected: (date) {
|
||||
print("Picked Date: $date");
|
||||
|
||||
@ -244,48 +244,47 @@ class policylistState extends ConsumerState<policylist> {
|
||||
regNum,
|
||||
) {
|
||||
return [
|
||||
if (roleId == 'manager') ...[
|
||||
Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
Navigator.pop(context);
|
||||
showDialog(
|
||||
context: context,
|
||||
builder: (ctx) => AssignStaffDialog(
|
||||
enquiryPrimaryId: id,
|
||||
regNum: regNum,
|
||||
userId: userId,
|
||||
onSubmit: (value) {
|
||||
debugPrint("New assignY: $value");
|
||||
refresh();
|
||||
},
|
||||
),
|
||||
);
|
||||
},
|
||||
hoverColor: Color(0xFFE3F1F0),
|
||||
splashColor: Color(0xFFE3F1F0),
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
child: Row(
|
||||
// mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
Image.asset(
|
||||
"assets/miscellaneous/image_3.png",
|
||||
// height: 45,
|
||||
// width: 15,
|
||||
),
|
||||
|
||||
SizedBox(width: 10),
|
||||
Text('Assign Staff'),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
// if (roleId == 'manager') ...[
|
||||
// Material(
|
||||
// color: Colors.transparent,
|
||||
// child: InkWell(
|
||||
// onTap: () {
|
||||
// Navigator.pop(context);
|
||||
// showDialog(
|
||||
// context: context,
|
||||
// builder: (ctx) => AssignStaffDialog(
|
||||
// enquiryPrimaryId: id,
|
||||
// regNum: regNum,
|
||||
// userId: userId,
|
||||
// onSubmit: (value) {
|
||||
// debugPrint("New assignY: $value");
|
||||
// refresh();
|
||||
// },
|
||||
// ),
|
||||
// );
|
||||
// },
|
||||
// hoverColor: Color(0xFFE3F1F0),
|
||||
// splashColor: Color(0xFFE3F1F0),
|
||||
// borderRadius: BorderRadius.circular(6),
|
||||
// child: Padding(
|
||||
// padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
// child: Row(
|
||||
// // mainAxisSize: MainAxisSize.min,
|
||||
// children: [
|
||||
// Image.asset(
|
||||
// "assets/miscellaneous/image_3.png",
|
||||
// // height: 45,
|
||||
// // width: 15,
|
||||
// ),
|
||||
//
|
||||
// SizedBox(width: 10),
|
||||
// Text('Assign Staff'),
|
||||
// ],
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
@ -369,7 +368,7 @@ class policylistState extends ConsumerState<policylist> {
|
||||
mainAxisAlignment: MainAxisAlignment.start,
|
||||
children: [
|
||||
Container(
|
||||
height: 40,
|
||||
height: 30,
|
||||
width: MediaQuery.of(context).size.width,
|
||||
child: GestureDetector(
|
||||
onTap: () {
|
||||
@ -409,7 +408,7 @@ class policylistState extends ConsumerState<policylist> {
|
||||
),
|
||||
),
|
||||
|
||||
SizedBox(height: 10),
|
||||
SizedBox(height: 5),
|
||||
|
||||
ResponsiveLayout.isMobile(context)
|
||||
? Container(
|
||||
@ -617,7 +616,7 @@ class policylistState extends ConsumerState<policylist> {
|
||||
],
|
||||
),
|
||||
),
|
||||
SizedBox(height: 10),
|
||||
SizedBox(height: 5),
|
||||
if (!ResponsiveLayout.isMobile(context))
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
@ -627,14 +626,22 @@ class policylistState extends ConsumerState<policylist> {
|
||||
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(flex: 4, child: Text('Date', style: _headerStyle)),
|
||||
Expanded(flex: 3, child: Text('Reg.No', style: _headerStyle)),
|
||||
Expanded(
|
||||
flex: 4,
|
||||
child: Text('Recieved Date/Time', style: _headerStyle),
|
||||
),
|
||||
|
||||
Expanded(flex: 3, child: Text('Partner', style: _headerStyle)),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Text('Assigned To', style: _headerStyle),
|
||||
),
|
||||
Expanded(flex: 3, child: Text('Insurer', style: _headerStyle)),
|
||||
Expanded(flex: 4, child: Text('Insurer', style: _headerStyle)),
|
||||
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Text('Vehicle.No.', style: _headerStyle),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Text('Insured Name', style: _headerStyle),
|
||||
@ -758,10 +765,7 @@ class policylistState extends ConsumerState<policylist> {
|
||||
maxLines: 3,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Text(item['reg_no'] ?? '-', style: _dataBold),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Text(
|
||||
@ -774,7 +778,7 @@ class policylistState extends ConsumerState<policylist> {
|
||||
child: Text(item['assigned_to_name'] ?? '-', style: _dataBold),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
flex: 4,
|
||||
child: Text(
|
||||
item['insurer_name'] ?? '-',
|
||||
style: _dataBold,
|
||||
@ -782,6 +786,10 @@ class policylistState extends ConsumerState<policylist> {
|
||||
maxLines: 3,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Text(item['reg_no'] ?? '-', style: _dataBold),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Text(
|
||||
@ -873,7 +881,7 @@ class policylistState extends ConsumerState<policylist> {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Company", style: _cardheaderStyle),
|
||||
Text("Insurer", style: _cardheaderStyle),
|
||||
Text(item['insurer_name'] ?? '-', style: _cardBodyStyle),
|
||||
],
|
||||
),
|
||||
@ -980,7 +988,7 @@ class policylistState extends ConsumerState<policylist> {
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text("Date", style: _cardheaderStyle),
|
||||
Text("Recieved Date/Time", style: _cardheaderStyle),
|
||||
Text(
|
||||
_formatDate(item['updated_on']) ?? '-',
|
||||
style: _cardBodyStyle,
|
||||
|
||||
@ -78,7 +78,8 @@ class createQuotatDialogState extends State<createQuotatDialog> {
|
||||
final data = {
|
||||
"enquiry_id": widget.selectedEnquiryId,
|
||||
"insured_declared_value": controllers["idv"]?.text,
|
||||
"insurer_id": selectedInsurer,
|
||||
"insurer_id": '1',
|
||||
// "insurer_id": selectedInsurer,
|
||||
"premium_amount": controllers["premium_Amount"]?.text,
|
||||
"insurance_plan_type_id": selectedInsPlanType,
|
||||
// "additional_uploaded_file_name": "extra_doc.pdf",
|
||||
@ -135,6 +136,10 @@ class createQuotatDialogState extends State<createQuotatDialog> {
|
||||
.selectedQuotationFrmListdata!['insurance_plan_type_id']
|
||||
?.toString();
|
||||
|
||||
selectedInsurer = '1';
|
||||
|
||||
// controllers["insurer"]?.text = 'LIC';
|
||||
|
||||
// selectedInsurer =
|
||||
// widget.selectedQuotationFrmListdata!['insurer_id']?.toString() ?? '';
|
||||
|
||||
@ -426,7 +431,7 @@ class createQuotatDialogState extends State<createQuotatDialog> {
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
buildIdv(context),
|
||||
buildInsurer(context),
|
||||
// buildInsurer(context),
|
||||
buildInsurancePlanType(context),
|
||||
buildPremiumAmnt(context),
|
||||
buildDocuments(context),
|
||||
@ -464,7 +469,7 @@ class createQuotatDialogState extends State<createQuotatDialog> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildInsurer(BuildContext context) {
|
||||
Widget buildInsurer1(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
@ -474,7 +479,7 @@ class createQuotatDialogState extends State<createQuotatDialog> {
|
||||
controller: controllers['insurer']!,
|
||||
validator: (value) => Validators.requiredField(value, "insurer"),
|
||||
backgroundColor: Color(0xFFEDF6F5),
|
||||
readOnly: true,
|
||||
// readOnly: true,
|
||||
txtwidth: ResponsiveLayout.isMobile(context)
|
||||
? null
|
||||
: MediaQuery.of(context).size.width * 0.26,
|
||||
@ -483,96 +488,96 @@ class createQuotatDialogState extends State<createQuotatDialog> {
|
||||
);
|
||||
}
|
||||
|
||||
// Widget buildInsurer(BuildContext context) {
|
||||
// Map<String, dynamic>? selectedInsurerd = filteredInsurersData.firstWhere(
|
||||
// (item) => item['id'].toString() == selectedInsurer,
|
||||
// orElse: () => {},
|
||||
// );
|
||||
// return Column(
|
||||
// crossAxisAlignment: CrossAxisAlignment.start,
|
||||
// children: [
|
||||
// Text('Insurer *', style: _textStyle),
|
||||
// SizedBox(height: 10),
|
||||
// Container(
|
||||
// decoration: BoxDecoration(
|
||||
// color: Colors.white,
|
||||
// // borderRadius: BorderRadius.circular(10.0),
|
||||
// ),
|
||||
// width: ResponsiveLayout.isMobile(context)
|
||||
// ? null
|
||||
// : MediaQuery.of(context).size.width * 0.26,
|
||||
// // height: 40,
|
||||
// child: DropdownSearch<Map<String, dynamic>>(
|
||||
// key: dropDownKeyInsurer,
|
||||
// selectedItem: selectedInsurerd.isNotEmpty ? selectedInsurerd : null,
|
||||
// items: (filter, infiniteScrollProps) {
|
||||
// return filteredInsurersData;
|
||||
// },
|
||||
//
|
||||
// itemAsString: (val) => val['name'].toString(), // what to show
|
||||
// compareFn: (item, selectedItem) =>
|
||||
// item['id'] == selectedItem['id'], // ✅ compare by id
|
||||
// validator: (val) {
|
||||
// if (val == null) {
|
||||
// return "Required"; // ✅ error message
|
||||
// }
|
||||
// return null;
|
||||
// },
|
||||
// decoratorProps: DropDownDecoratorProps(
|
||||
// decoration:
|
||||
// AppInputDecorations.dropdownDecoration(
|
||||
// label: "Select Insurer",
|
||||
// ).copyWith(
|
||||
// filled: true,
|
||||
// fillColor: Color(
|
||||
// 0xFFEDF6F5,
|
||||
// ), // 👈 makes the dropdown input white
|
||||
// ),
|
||||
// ),
|
||||
//
|
||||
// popupProps: PopupProps.menu(
|
||||
// fit: FlexFit.loose,
|
||||
// constraints: BoxConstraints(maxHeight: 250),
|
||||
// menuProps: MenuProps(
|
||||
// backgroundColor:
|
||||
// Colors.white, // 👈 sets dropdown background to white
|
||||
// ),
|
||||
// showSearchBox: true,
|
||||
// searchFieldProps: TextFieldProps(
|
||||
// decoration: InputDecoration(
|
||||
// filled: true,
|
||||
// fillColor: Colors.white,
|
||||
// hintText: "Search Insurer...",
|
||||
// enabledBorder: OutlineInputBorder(
|
||||
// borderSide: BorderSide(
|
||||
// color: Colors.white,
|
||||
// ), // 👈 Normal border
|
||||
// ),
|
||||
// focusedBorder: OutlineInputBorder(
|
||||
// borderSide: BorderSide(
|
||||
// color: Colors.white,
|
||||
// width: 1.5,
|
||||
// ), // 👈 Focused border
|
||||
// ),
|
||||
// ),
|
||||
// ),
|
||||
// // constraints: BoxConstraints(),
|
||||
// ),
|
||||
//
|
||||
// onChanged: (val) {
|
||||
// if (val != null) {
|
||||
// print("Selected Insurer : ${val['name']}");
|
||||
// print("Id: ${val['id']}");
|
||||
// selectedInsurer = val['id'];
|
||||
// // controllers['agentId']?.text = val['agent_code'];
|
||||
// // agentId = agent['id'];
|
||||
// }
|
||||
// },
|
||||
// ),
|
||||
// ),
|
||||
// ],
|
||||
// );
|
||||
// }
|
||||
Widget buildInsurer2(BuildContext context) {
|
||||
Map<String, dynamic>? selectedInsurerd = filteredInsurersData.firstWhere(
|
||||
(item) => item['id'].toString() == selectedInsurer,
|
||||
orElse: () => {},
|
||||
);
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('Insurer *', style: _textStyle),
|
||||
SizedBox(height: 10),
|
||||
Container(
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
// borderRadius: BorderRadius.circular(10.0),
|
||||
),
|
||||
width: ResponsiveLayout.isMobile(context)
|
||||
? null
|
||||
: MediaQuery.of(context).size.width * 0.26,
|
||||
// height: 40,
|
||||
child: DropdownSearch<Map<String, dynamic>>(
|
||||
key: dropDownKeyInsurer,
|
||||
selectedItem: selectedInsurerd.isNotEmpty ? selectedInsurerd : null,
|
||||
items: (filter, infiniteScrollProps) {
|
||||
return filteredInsurersData;
|
||||
},
|
||||
|
||||
itemAsString: (val) => val['name'].toString(), // what to show
|
||||
compareFn: (item, selectedItem) =>
|
||||
item['id'] == selectedItem['id'], // ✅ compare by id
|
||||
validator: (val) {
|
||||
if (val == null) {
|
||||
return "Required"; // ✅ error message
|
||||
}
|
||||
return null;
|
||||
},
|
||||
decoratorProps: DropDownDecoratorProps(
|
||||
decoration:
|
||||
AppInputDecorations.dropdownDecoration(
|
||||
label: "Select Insurer",
|
||||
).copyWith(
|
||||
filled: true,
|
||||
fillColor: Color(
|
||||
0xFFEDF6F5,
|
||||
), // 👈 makes the dropdown input white
|
||||
),
|
||||
),
|
||||
|
||||
popupProps: PopupProps.menu(
|
||||
fit: FlexFit.loose,
|
||||
constraints: BoxConstraints(maxHeight: 250),
|
||||
menuProps: MenuProps(
|
||||
backgroundColor:
|
||||
Colors.white, // 👈 sets dropdown background to white
|
||||
),
|
||||
showSearchBox: true,
|
||||
searchFieldProps: TextFieldProps(
|
||||
decoration: InputDecoration(
|
||||
filled: true,
|
||||
fillColor: Colors.white,
|
||||
hintText: "Search Insurer...",
|
||||
enabledBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Colors.white,
|
||||
), // 👈 Normal border
|
||||
),
|
||||
focusedBorder: OutlineInputBorder(
|
||||
borderSide: BorderSide(
|
||||
color: Colors.white,
|
||||
width: 1.5,
|
||||
), // 👈 Focused border
|
||||
),
|
||||
),
|
||||
),
|
||||
// constraints: BoxConstraints(),
|
||||
),
|
||||
|
||||
onChanged: (val) {
|
||||
if (val != null) {
|
||||
print("Selected Insurer : ${val['name']}");
|
||||
print("Id: ${val['id']}");
|
||||
selectedInsurer = val['id'];
|
||||
// controllers['agentId']?.text = val['agent_code'];
|
||||
// agentId = agent['id'];
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Widget buildPremiumAmnt(BuildContext context) {
|
||||
return Column(
|
||||
|
||||
@ -67,6 +67,7 @@ class ThemedFormField extends HookWidget {
|
||||
),
|
||||
);
|
||||
final inputDecoration = InputDecoration(
|
||||
// isDense: true,
|
||||
errorStyle: TextStyle(color: const Color(0xFFD83731)),
|
||||
errorBorder: OutlineInputBorder(
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
|
||||
Loading…
Reference in New Issue
Block a user