Handler Role

This commit is contained in:
venbaittech 2025-10-13 14:18:33 +05:30
parent 2de35505ab
commit b778e133a8
16 changed files with 3834 additions and 530 deletions

View File

@ -5,6 +5,7 @@ import 'package:nhance_partner/core/routing/routes.dart';
import 'package:nhance_partner/presentation/screens/Enquiry/enquiryList.dart'; import 'package:nhance_partner/presentation/screens/Enquiry/enquiryList.dart';
import 'package:nhance_partner/presentation/screens/UserManagement/Profile/profile_web.dart'; import 'package:nhance_partner/presentation/screens/UserManagement/Profile/profile_web.dart';
import 'package:nhance_partner/presentation/screens/dashboard/dashboard.dart'; import 'package:nhance_partner/presentation/screens/dashboard/dashboard.dart';
import 'package:nhance_partner/presentation/screens/handler/enquiryList.dart';
import '../../data/services/auth_service.dart'; import '../../data/services/auth_service.dart';
import '../../presentation/providers/manager_provider.dart'; import '../../presentation/providers/manager_provider.dart';
import '../../presentation/screens/Enquiry/enquiry/tabs.dart'; import '../../presentation/screens/Enquiry/enquiry/tabs.dart';
@ -155,6 +156,10 @@ final GoRouter appRouter = GoRouter(
path: AppRoutes.enquiryForStaff, path: AppRoutes.enquiryForStaff,
builder: (context, state) => const EnquiryStaff(), builder: (context, state) => const EnquiryStaff(),
), ),
GoRoute(
path: AppRoutes.enquiryHandlerLst,
builder: (context, state) => const EnquiryHandler(),
),
], ],
redirect: (context, state) async { redirect: (context, state) async {
final loggedIn = await AuthService.isLoggedIn(); final loggedIn = await AuthService.isLoggedIn();

View File

@ -12,6 +12,8 @@ class AppRoutes {
static const String enquiryForStaff = '/enquiryForStaff'; static const String enquiryForStaff = '/enquiryForStaff';
static const String tabEnquiry = '/tabEnquiry'; static const String tabEnquiry = '/tabEnquiry';
static const String enquiryHandlerLst = '/enquiryHandlerLst';
static const String claimlist = '/claimList'; static const String claimlist = '/claimList';
static const String endosement = '/endosement'; static const String endosement = '/endosement';
static const String policylist = '/policylist'; static const String policylist = '/policylist';

View File

@ -348,6 +348,8 @@ class ApiService {
if (role == 'manager') { if (role == 'manager') {
url = Uri.parse('${Env.apiUrl}dashboard/managerDashboard?manager_id=$id'); url = Uri.parse('${Env.apiUrl}dashboard/managerDashboard?manager_id=$id');
} else if (role == 'handler') {
url = Uri.parse('${Env.apiUrl}dashboard/handlerDashboard?handler_id=$id');
} else if (role == 'staff') { } else if (role == 'staff') {
url = Uri.parse('${Env.apiUrl}dashboard/staffDashboard?staff_id=$id'); url = Uri.parse('${Env.apiUrl}dashboard/staffDashboard?staff_id=$id');
} else { } else {
@ -465,7 +467,7 @@ class ApiService {
// ------------------------------------ STAFF ----------------------------------------------------- // ------------------------------------ STAFF -----------------------------------------------------
Future<Map<String, dynamic>> fetchStaffUserList(int managerId) async { Future<Map<String, dynamic>> fetchStaffUserList(int managerId, role) async {
// print(_token); // print(_token);
if (_token == null) { if (_token == null) {
await _initializeToken(); await _initializeToken();
@ -475,9 +477,15 @@ class ApiService {
// 'https://venbait.in/nhance/partner/dev/api/staff/staffList?manager_id=${managerId}', // 'https://venbait.in/nhance/partner/dev/api/staff/staffList?manager_id=${managerId}',
// ); // );
final url = Uri.parse( dynamic url;
'${Env.apiUrl}staff/staffList?manager_id=${managerId}', if (role == 'manager') {
); print('manager');
url = Uri.parse('${Env.apiUrl}staff/staffList?manager_id=${managerId}');
} else {
print('handler');
url = Uri.parse('${Env.apiUrl}staff/staffList?handler_id=${managerId}');
}
final headers = { final headers = {
'Authorization': 'Bearer $_token' ?? '', 'Authorization': 'Bearer $_token' ?? '',
'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK', 'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK',
@ -871,4 +879,50 @@ class ApiService {
final response = await _makeGetRequest(url, headers); final response = await _makeGetRequest(url, headers);
return response; return response;
} }
Future<Map<String, dynamic>> fetchHandlerNameDropDown(id) async {
print('fetchHandlerNameDropDown');
if (_token == null) {
await _initializeToken();
}
dynamic url;
print('fetchHandlerNameDropDown 1');
url = Uri.parse(
'${Env.apiUrl}staff/handlerListForStaffCreationDropdown?manager_id=$id',
);
print('fetchHandlerNameDropDown 2');
final headers = {
'Authorization': 'Bearer $_token' ?? '',
'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK',
};
print('fetchHandlerNameDropDown 3');
final response = await _makeGetRequest(url, headers);
print('fetchHandlerNameDropDown 4 - $response');
return response;
}
Future<Map<String, dynamic>> fetchStaffListForEnquiryAssignDropDown(
id,
) async {
print('fetchHandlerNameDropDown');
if (_token == null) {
await _initializeToken();
}
dynamic url;
print('fetchHandlerNameDropDown 1');
url = Uri.parse(
'${Env.apiUrl}/staff/staffListForEnquiryAssignDropdown?handler_id=$id',
);
print('fetchHandlerNameDropDown 2');
final headers = {
'Authorization': 'Bearer $_token' ?? '',
'App-Signature': 'nhance-partner-2025-signature-35468846JRhH551HK',
};
print('fetchHandlerNameDropDown 3');
final response = await _makeGetRequest(url, headers);
print('fetchHandlerNameDropDown 4 - $response');
return response;
}
} }

View File

@ -1,5 +1,6 @@
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
final managerIdProvider = StateProvider<int?>((ref) => null); final managerIdProvider = StateProvider<int?>((ref) => null);
final handlerIdProvider = StateProvider<int?>((ref) => null);
final userIdProvider = StateProvider<int?>((ref) => null); final userIdProvider = StateProvider<int?>((ref) => null);
final enquiryIdProvider = StateProvider<String?>((ref) => null); final enquiryIdProvider = StateProvider<String?>((ref) => null);

View File

@ -1,6 +1,7 @@
import 'dart:convert'; import 'dart:convert';
import 'package:dropdown_search/dropdown_search.dart'; import 'package:dropdown_search/dropdown_search.dart';
import 'package:file_picker/file_picker.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
@ -12,6 +13,7 @@ import '../../../../data/services/auth_service.dart';
import '../../../../data/utils/toastNotification.dart'; import '../../../../data/utils/toastNotification.dart';
import '../../../../data/utils/validators.dart'; import '../../../../data/utils/validators.dart';
import '../../../layouts/responsive_layout.dart'; import '../../../layouts/responsive_layout.dart';
import '../../../themes/indicators/customizd_file_upload.dart';
import '../../../themes/indicators/input_field_decoration.dart'; import '../../../themes/indicators/input_field_decoration.dart';
import '../../../themes/indicators/text_field_theme.dart'; import '../../../themes/indicators/text_field_theme.dart';
@ -41,6 +43,16 @@ class _AddDialogState extends State<AddDialog> {
late TextEditingController controller; late TextEditingController controller;
Map<String, TextEditingController> controllers = {}; Map<String, TextEditingController> controllers = {};
String? selectedClaimFileNames;
String? passportFileUrlFromApi;
String? selectedClaimId;
PlatformFile? docUploadedFile;
String? selectedFileNames;
String? passportEndorsFileUrlFromApi;
String? selectedEndorsId;
PlatformFile? docUploadedEndorsFile;
final _formKeyClaims = GlobalKey<FormState>(); final _formKeyClaims = GlobalKey<FormState>();
final _formKeyEndrosment = GlobalKey<FormState>(); final _formKeyEndrosment = GlobalKey<FormState>();
final GlobalKey<DropdownSearchState<Map<String, dynamic>>> dropDownKey = final GlobalKey<DropdownSearchState<Map<String, dynamic>>> dropDownKey =
@ -204,7 +216,7 @@ class _AddDialogState extends State<AddDialog> {
} }
} }
Future<void> createUserData(data, val) async { Future<void> createUserData1(data, val) async {
// final bool isUpdating = widget.id != null && widget.id != 'create'; // final bool isUpdating = widget.id != null && widget.id != 'create';
final String apiUrldata; final String apiUrldata;
@ -253,6 +265,115 @@ class _AddDialogState extends State<AddDialog> {
} }
} }
Future<void> createUserData(data, val) async {
final Uri uri = (val == 'Claims')
? Uri.parse('${Env.apiUrl}claim/createClaim')
: Uri.parse('${Env.apiUrl}endorsement/createEndorsement');
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';
print("USerDAta - $data");
// userData.forEach((key, value) {
// request.fields[key] = value.toString();
// print("✅ Encoded travel_details2: ${request.fields[key]}");
// });
data.forEach((key, value) {
// if (key != 'certificate_file_name') {
request.fields[key] = value.toString();
print("✅ Encoded $key: ${request.fields[key]}");
// }
});
if (val == 'Claims') {
// Attach file if selected
if (docUploadedFile != null) {
try {
if (docUploadedFile!.bytes != null) {
final multipartFile = http.MultipartFile.fromBytes(
'claim_file_name',
docUploadedFile!.bytes!,
filename: docUploadedFile!.name,
);
request.files.add(multipartFile);
}
// else if (docUploadedFile!.path != null) {
// final multipartFile = await http.MultipartFile.fromPath(
// 'certificate_file_name',
// docUploadedFile!.path!,
// filename: docUploadedFile!.name,
// );
// request.files.add(multipartFile);
// }
print("📎 File attached: ${docUploadedFile!.name}");
} catch (e) {
print("❌ Failed to attach file: $e");
}
}
} else {
// Attach file if selected
if (docUploadedEndorsFile != null) {
try {
if (docUploadedEndorsFile!.bytes != null) {
final multipartFile = http.MultipartFile.fromBytes(
'endorsement_file_name',
docUploadedEndorsFile!.bytes!,
filename: docUploadedEndorsFile!.name,
);
request.files.add(multipartFile);
}
// else if (docUploadedEndorsFile!.path != null) {
// final multipartFile = await http.MultipartFile.fromPath(
// 'endorsement_file_name',
// docUploadedEndorsFile!.path!,
// filename: docUploadedEndorsFile!.name,
// );
// request.files.add(multipartFile);
// }
print("📎 File attached: ${docUploadedEndorsFile!.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) {
print("✅ Partner submitted successfully!");
print("Response: ${response.body}");
ToastHelper.showSuccessToast(context, 'Saved Successfully');
Navigator.of(context).pop();
widget.onSubmit("success");
} else {
final responseBody = jsonDecode(response.body);
dynamic msg = responseBody['data'];
print("Failed to submit plan. Status: ${response.statusCode}");
print("Error: ${response.body}");
ToastHelper.showErrorToast(context, 'Failed To Save');
}
} catch (e) {
print("🔥 Error submitting user: $e");
}
}
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return AlertDialog( return AlertDialog(
@ -296,24 +417,19 @@ class _AddDialogState extends State<AddDialog> {
], ],
), ),
actions: [ actions: [
Center( GestureDetector(
child: GestureDetector(
onTap: () { onTap: () {
handleDone(widget.title); handleDone(widget.title);
// widget.onSubmit(controller.text.trim()); // widget.onSubmit(controller.text.trim());
// Navigator.of(context).pop(); // Navigator.of(context).pop();
}, },
child: Container( child: Container(
padding: const EdgeInsets.symmetric( padding: const EdgeInsets.symmetric(horizontal: 25.0, vertical: 8),
horizontal: 25.0,
vertical: 8,
),
decoration: BoxDecoration( decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0), borderRadius: BorderRadius.circular(8.0),
color: const Color(0xFF425B5B), color: const Color(0xFF425B5B),
), ),
child: const Text('Done', style: TextStyle(color: Colors.white)), child: const Text('Save', style: TextStyle(color: Colors.white)),
),
), ),
), ),
], ],
@ -328,6 +444,7 @@ class _AddDialogState extends State<AddDialog> {
children: [ children: [
buildClaimType(context), buildClaimType(context),
buildPolicyNumber(context), buildPolicyNumber(context),
buildUploadDocumentClaims(context),
buildClaimsDesc(context), buildClaimsDesc(context),
], ],
), ),
@ -339,7 +456,11 @@ class _AddDialogState extends State<AddDialog> {
return Form( return Form(
key: _formKeyEndrosment, key: _formKeyEndrosment,
child: Column( child: Column(
children: [buildEndrosType(context), buildEndrosRemarks(context)], children: [
buildEndrosType(context),
buildUploadDocumentEndorsment(context),
buildEndrosRemarks(context),
],
), ),
); );
} }
@ -472,6 +593,87 @@ class _AddDialogState extends State<AddDialog> {
); );
} }
Widget buildUploadDocumentClaims(BuildContext context) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Upload Document", style: _textStyle),
SizedBox(width: 10),
ThemedUploadField(
backgroundColor: Color(0xFFEDF6F5),
hintText: selectedClaimFileNames ?? "Upload Document",
txtwidth: ResponsiveLayout.isMobile(context)
? null
: MediaQuery.of(context).size.width * 0.26,
onFileSelected: (fileName, file) {
print("Picked file: $fileName (${file.size} bytes)");
setState(() {
docUploadedFile = file;
});
},
),
// Column(
// mainAxisAlignment: MainAxisAlignment.end,
// crossAxisAlignment: CrossAxisAlignment.end,
// children: [
// ThemedUploadField(
// hintText: selectedClaimFileNames ?? "Upload Document",
// txtwidth: MediaQuery.of(context).size.width * 0.26,
// onFileSelected: (fileName, file) {
// print("Picked file: $fileName (${file.size} bytes)");
// setState(() {
// docUploadedFile = file;
// });
// },
// ),
// // const SizedBox(height: 5),
// //
// // if (docUploadedFile != null || passportFileUrlFromApi != null)
// // Container(
// // // color: Colors.white,
// // child: Row(
// // children: [
// // GestureDetector(
// // onTap: () => apiService.downloadFile(
// // apiUrl:
// // 'api/agent/downloadAgentCertificateFile?agent_id=$selectedClaimId',
// // apiId: selectedClaimId,
// // localFile: docUploadedFile,
// // fileName: selectedClaimFileNames,
// // ),
// // 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),
// // ],
// // ),
// // ),
// // ),
// // ],
// // ),
// // ),
// ],
// ),
],
);
}
//------------------------- Endrosment Part ----------------------------------- //------------------------- Endrosment Part -----------------------------------
Widget buildEndrosType(context) { Widget buildEndrosType(context) {
@ -586,10 +788,91 @@ class _AddDialogState extends State<AddDialog> {
); );
} }
Widget buildUploadDocumentEndorsment(context) {
return Column(
mainAxisAlignment: MainAxisAlignment.start,
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Upload Document", style: _textStyle),
SizedBox(width: 10),
ThemedUploadField(
backgroundColor: Color(0xFFEDF6F5),
hintText: selectedFileNames ?? "Upload Document",
txtwidth: ResponsiveLayout.isMobile(context)
? null
: MediaQuery.of(context).size.width * 0.26,
onFileSelected: (fileName, file) {
print("Picked file: $fileName (${file.size} bytes)");
setState(() {
docUploadedEndorsFile = file;
});
},
),
// Column(
// mainAxisAlignment: MainAxisAlignment.end,
// crossAxisAlignment: CrossAxisAlignment.end,
// children: [
// ThemedUploadField(
// hintText: selectedFileNames ?? "Upload Document",
// txtwidth: MediaQuery.of(context).size.width * 0.26,
// onFileSelected: (fileName, file) {
// print("Picked file: $fileName (${file.size} bytes)");
// setState(() {
// docUploadedEndorsFile = file;
// });
// },
// ),
// // const SizedBox(height: 5),
// //
// // if (docUploadedEndorsFile != null || passportEndorsFileUrlFromApi != null)
// // Container(
// // // color: Colors.white,
// // child: Row(
// // children: [
// //
// // GestureDetector(
// // onTap: () => apiService.downloadFile(
// // apiUrl:
// // 'api/agent/downloadAgentCertificateFile?agent_id=$selectedEndorsId',
// // apiId: selectedEndorsId,
// // localFile: docUploadedEndorsFile,
// // 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 --------------------------------- // ------------------- STyle ---------------------------------
static final TextStyle _textStyle = TextStyle( static final TextStyle _textStyle = TextStyle(
fontSize: 14, fontSize: 12,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
); );
} }

View File

@ -3,6 +3,7 @@ import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:nhance_partner/presentation/providers/userRoleProvider.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import '../../../../core/routing/routes.dart'; import '../../../../core/routing/routes.dart';
@ -28,6 +29,7 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
bool isLoading = true; bool isLoading = true;
late ApiService apiService; late ApiService apiService;
ScrollController _scrollController = ScrollController(); ScrollController _scrollController = ScrollController();
dynamic role;
@override @override
void initState() { void initState() {
@ -40,7 +42,7 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
Future.microtask(() { Future.microtask(() {
final id = ref.read(enquiryIdProvider); final id = ref.read(enquiryIdProvider);
role = ref.read(userRoleProvider);
print("IntialID - $id"); print("IntialID - $id");
if (id != null) { if (id != null) {
_loadData(id); _loadData(id);
@ -228,8 +230,14 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {
// context.go(AppRoutes.dashboard); // context.go(AppRoutes.dashboard);
if (role == 'handler') {
ref.read(enquiryIdProvider.notifier).state = null;
context.go(AppRoutes.enquiryHandlerLst);
} else {
ref.read(enquiryIdProvider.notifier).state = null; ref.read(enquiryIdProvider.notifier).state = null;
context.go(AppRoutes.enquiryLst); context.go(AppRoutes.enquiryLst);
}
}, },
child: Row( child: Row(
children: [ children: [
@ -421,8 +429,15 @@ class TabEnquiryListState extends ConsumerState<TabEnquiryList> {
Tooltip( Tooltip(
message: 'Back', message: 'Back',
child: IconButton( child: IconButton(
icon: const Icon(Icons.arrow_left_sharp,size: 35,color: Color(0xFF425B5B)), icon: const Icon(
onPressed: () { ref.read(enquiryIdProvider.notifier).state = null; context.go(AppRoutes.enquiryLst); }, Icons.arrow_left_sharp,
size: 35,
color: Color(0xFF425B5B),
),
onPressed: () {
ref.read(enquiryIdProvider.notifier).state = null;
context.go(AppRoutes.enquiryLst);
},
splashRadius: 28, splashRadius: 28,
hoverColor: Colors.black12, hoverColor: Colors.black12,
padding: const EdgeInsets.all(8), padding: const EdgeInsets.all(8),

View File

@ -1,6 +1,7 @@
import 'dart:convert'; import 'dart:convert';
// import 'dart:io' as html; // import 'dart:io' as html;
import 'dart:typed_data'; // Import for Uint8List import 'dart:typed_data'; // Import for Uint8List
import 'package:dropdown_search/dropdown_search.dart';
import 'package:flutter/cupertino.dart'; import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
@ -15,10 +16,13 @@ import '../../../../core/services/api_service.dart';
import '../../../../data/services/auth_service.dart'; import '../../../../data/services/auth_service.dart';
import '../../../../data/utils/validators.dart'; import '../../../../data/utils/validators.dart';
import '../../../layouts/main_layout.dart'; import '../../../layouts/main_layout.dart';
import '../../../layouts/responsive_layout.dart';
import '../../../providers/manager_provider.dart'; import '../../../providers/manager_provider.dart';
import 'package:universal_html/html.dart' as html; import 'package:universal_html/html.dart' as html;
import '../../../themes/indicators/input_field_decoration.dart';
class Staff extends ConsumerStatefulWidget { class Staff extends ConsumerStatefulWidget {
final String? id; final String? id;
const Staff({super.key, this.id}); const Staff({super.key, this.id});
@ -29,6 +33,13 @@ class Staff extends ConsumerStatefulWidget {
class StaffState extends ConsumerState<Staff> { class StaffState extends ConsumerState<Staff> {
final _formKey = GlobalKey<FormState>(); final _formKey = GlobalKey<FormState>();
late ApiService apiService; late ApiService apiService;
final GlobalKey<DropdownSearchState<Map<String, dynamic>>> dropDownKey =
GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
final GlobalKey<DropdownSearchState<Map<String, dynamic>>>
dropDownKeyHandler = GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
List<String> tabHeader = ['name', 'email', 'mobile', 'code']; List<String> tabHeader = ['name', 'email', 'mobile', 'code'];
late String isActive = "1"; late String isActive = "1";
html.File? passportFile; html.File? passportFile;
@ -36,6 +47,16 @@ class StaffState extends ConsumerState<Staff> {
String? passportFileUrlFromApi; String? passportFileUrlFromApi;
String? selectedId; String? selectedId;
String? _token; String? _token;
bool isLoading = false;
bool showHandler = false;
String? selectedRole;
List<Map<String, dynamic>> filteredRolesData = [];
List<Map<String, dynamic>> getRolesData = [];
String? selectedHandler;
List<Map<String, dynamic>> filteredHandlersData = [];
List<Map<String, dynamic>> getHandlersData = [];
Map<String, TextEditingController> controllers = {}; Map<String, TextEditingController> controllers = {};
@ -47,9 +68,10 @@ class StaffState extends ConsumerState<Staff> {
"name": controllers["name"]?.text, "name": controllers["name"]?.text,
"email": controllers["email"]?.text, "email": controllers["email"]?.text,
"mobile": controllers["mobile"]?.text, "mobile": controllers["mobile"]?.text,
"emp_id": controllers["code"]?.text, // "emp_id": controllers["code"]?.text,
"is_active": isActive, "is_active": isActive,
"role_id": "2", // By default role 2 Staff, No fields Required "role_id": selectedRole, // By default role 2 Staff, No fields Required
"handler_id": selectedHandler,
"manager_id": userId, "manager_id": userId,
}; };
return data; return data;
@ -63,12 +85,18 @@ class StaffState extends ConsumerState<Staff> {
controllers[field] = TextEditingController(); controllers[field] = TextEditingController();
} }
_initializeToken();
updateData();
getRole();
Future.microtask(() { Future.microtask(() {
managerId = ref.watch(managerIdProvider); managerId = ref.watch(managerIdProvider);
userId = ref.watch(userIdProvider); userId = ref.watch(userIdProvider);
if (managerId != null) {
print('hansles');
getHandlers(managerId);
}
}); });
_initializeToken();
updateData();
} }
Future<void> _initializeToken() async { Future<void> _initializeToken() async {
@ -88,7 +116,10 @@ class StaffState extends ConsumerState<Staff> {
controllers['name']?.text = data['name'] ?? ''; controllers['name']?.text = data['name'] ?? '';
controllers['email']?.text = data['email'] ?? ''; controllers['email']?.text = data['email'] ?? '';
controllers['mobile']?.text = data['mobile'] ?? ''; controllers['mobile']?.text = data['mobile'] ?? '';
controllers['code']?.text = data['emp_id'] ?? ''; selectedRole = data['role_id'] ?? '';
selectedHandler = data['handler_id'] ?? '';
// controllers['code']?.text = data['emp_id'] ?? '';
isActive = data["is_active"]; isActive = data["is_active"];
String? apiDocPath = data["certificate_file_name"]; String? apiDocPath = data["certificate_file_name"];
@ -201,6 +232,69 @@ class StaffState extends ConsumerState<Staff> {
} }
} }
Future<void> getRole() async {
print('Handlers called');
setState(() {
isLoading = true;
});
try {
final response = await apiService.fetchMasterDropDown('staffRole');
if (response['status'] == 200) {
print('getRole - ${response['data']}');
setState(() {
getRolesData = List<Map<String, dynamic>>.from(response['data']);
print('API Data - $getRolesData');
filteredRolesData = List.from(getRolesData);
print('originalData - $filteredRolesData');
});
} else {
getRolesData = [];
filteredRolesData = [];
}
} catch (e) {
print('Exception occurred: $e');
} finally {
setState(() {
isLoading = false;
});
}
}
Future<void> getHandlers(managerId) async {
print('Handlers called');
setState(() {
isLoading = true;
});
try {
final response = await apiService.fetchHandlerNameDropDown(managerId);
if (response['code'] == 200 || response['status'] == 'success') {
print('getHandlers -');
print('getHandlers - ${response['data']}');
setState(() {
getHandlersData = List<Map<String, dynamic>>.from(response['data']);
print('API HandlersData - $getHandlersData');
filteredHandlersData = List.from(getHandlersData);
print('HandlersoriginalData - $filteredHandlersData');
});
} else {
getHandlersData = [];
filteredHandlersData = [];
}
} catch (e) {
print('Exception occurred: $e');
} finally {
setState(() {
isLoading = false;
});
}
}
@override @override
void dispose() { void dispose() {
for (var controller in controllers.values) { for (var controller in controllers.values) {
@ -331,11 +425,20 @@ class StaffState extends ConsumerState<Staff> {
children: [ children: [
Expanded(child: buildPhNumber()), Expanded(child: buildPhNumber()),
SizedBox(width: 25), SizedBox(width: 25),
Expanded(child: buildId()), Expanded(child: buildRole(context)),
], ],
), ),
SizedBox(height: 20), SizedBox(height: 20),
if (showHandler) ...[
Row(
children: [
Expanded(child: buildHandler(context)),
SizedBox(width: 25),
Expanded(child: SizedBox.shrink()),
],
),
],
// Row( // Row(
// children: [ // children: [
// Expanded(child: buildAddress()), // Expanded(child: buildAddress()),
@ -408,16 +511,217 @@ class StaffState extends ConsumerState<Staff> {
); );
} }
Widget buildAddress() { // Widget buildAddress() {
// return Row(
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
// children: [
// Text("Role*", style: _textStyle),
// SizedBox(width: 10),
// ThemedFormField(
// controller: controllers['address']!,
//
// txtwidth: MediaQuery.of(context).size.width * 0.26,
// ),
// ],
// );
// }
Widget buildRole(BuildContext context) {
Map<String, dynamic>? selectedroleVal = filteredRolesData.firstWhere(
(item) => item['id'].toString() == selectedRole,
orElse: () => {},
);
if (selectedroleVal.isNotEmpty &&
selectedroleVal['role'] != null &&
selectedroleVal['role'] == 'Staff') {
showHandler = true;
} else {
showHandler = false;
}
return Row( return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween, mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [ children: [
Text("Role *", style: _textStyle), Text("Role *", style: _textStyle),
SizedBox(width: 10), SizedBox(width: 10),
ThemedFormField( Container(
controller: controllers['address']!, 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: dropDownKey,
selectedItem: selectedroleVal.isNotEmpty ? selectedroleVal : null,
items: (filter, infiniteScrollProps) {
return filteredRolesData;
},
txtwidth: MediaQuery.of(context).size.width * 0.26, itemAsString: (val) => val['role'].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 Role",
).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 Role...",
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 Role : ${val['role']}");
print("Id: ${val['id']}");
selectedRole = val['id'];
if (val['role'] == 'Staff') {
setState(() {
showHandler = true;
});
} else {
setState(() {
showHandler = false;
});
}
// controllers['agentId']?.text = val['agent_code'];
// agentId = agent['id'];
}
},
),
),
],
);
}
Widget buildHandler(BuildContext context) {
Map<String, dynamic>? selectedHandlered = filteredHandlersData.firstWhere(
(item) => item['id'].toString() == selectedHandler,
orElse: () => {},
);
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text("Handler Name *", style: _textStyle),
SizedBox(width: 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: dropDownKeyHandler,
selectedItem: selectedHandlered.isNotEmpty
? selectedHandlered
: null,
items: (filter, infiniteScrollProps) {
return filteredHandlersData;
},
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 Handler",
).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 Handler...",
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 Handler : ${val['name']}");
print("Id: ${val['id']}");
selectedHandler = val['id'];
// controllers['agentId']?.text = val['agent_code'];
// agentId = agent['id'];
}
},
),
), ),
], ],
); );

View File

@ -2,6 +2,7 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart'; import 'package:go_router/go_router.dart';
import 'package:nhance_partner/presentation/providers/userRoleProvider.dart';
import '../../../../core/routing/routes.dart'; import '../../../../core/routing/routes.dart';
import '../../../../core/services/api_service.dart'; import '../../../../core/services/api_service.dart';
@ -26,6 +27,8 @@ class StaffListState extends ConsumerState<StaffList> {
int itemsPerPage = 10; int itemsPerPage = 10;
late ApiService apiService; late ApiService apiService;
dynamic managerId; dynamic managerId;
dynamic role;
dynamic prefid;
// List<Map<String, dynamic>> dataVal = []; // List<Map<String, dynamic>> dataVal = [];
List<Map<String, dynamic>> getStaffData = []; List<Map<String, dynamic>> getStaffData = [];
List<Map<String, dynamic>> originalData = []; List<Map<String, dynamic>> originalData = [];
@ -39,10 +42,14 @@ class StaffListState extends ConsumerState<StaffList> {
apiService = ApiService(); apiService = ApiService();
Future.microtask(() { Future.microtask(() {
final id = ref.read(managerIdProvider); final data1 = ref.read(managerIdProvider);
print("E43 => mId: $id"); final data2 = ref.read(handlerIdProvider);
if (id != null) { print("Edata1 => mId: $data1 -2 : $data2");
getStaffList(id); prefid = data2 ?? data1;
role = ref.read(userRoleProvider);
print("E43 => mId: $prefid");
if (prefid != null && role != null) {
getStaffList(prefid, role);
} }
}); });
// getStaffList(); // getStaffList();
@ -83,16 +90,18 @@ class StaffListState extends ConsumerState<StaffList> {
return (item['name'] ?? '-').toLowerCase().contains( return (item['name'] ?? '-').toLowerCase().contains(
query.toLowerCase(), query.toLowerCase(),
) || ) ||
(item['email'] ?? '-').toLowerCase().contains(query.toLowerCase()) || (item['email'] ?? '-').toLowerCase().contains(
query.toLowerCase(),
) ||
(item['mobile'] ?? '-').toLowerCase().contains( (item['mobile'] ?? '-').toLowerCase().contains(
query.toLowerCase(), query.toLowerCase(),
) || ) ||
(item['address'] ?? '-').toLowerCase().contains( (item['address'] ?? '-').toLowerCase().contains(
query.toLowerCase(), query.toLowerCase(),
) || ) ||
(item['emp_id'] ?? item['agent_code'] ?? '-').toLowerCase().contains( (item['emp_id'] ?? item['agent_code'] ?? '-')
query.toLowerCase(), .toLowerCase()
) || .contains(query.toLowerCase()) ||
isActiveStatus.contains(query.toLowerCase()); isActiveStatus.contains(query.toLowerCase());
}).toList(); }).toList();
}); });
@ -100,14 +109,15 @@ class StaffListState extends ConsumerState<StaffList> {
final TextEditingController _searchStaffController = TextEditingController(); final TextEditingController _searchStaffController = TextEditingController();
Future<void> getStaffList(int managerId) async { Future<void> getStaffList(int id, role) async {
print('E104 => Fns called => $managerId'); print('E104 => Fns called => $id');
print('E104 => Fns role => $role');
setState(() { setState(() {
isLoading = true; isLoading = true;
}); });
try { try {
final response = await apiService.fetchStaffUserList(managerId); final response = await apiService.fetchStaffUserList(id, role);
if (response['status'] == 'success') { if (response['status'] == 'success') {
print('E113 => getStaffListData => ${response['data']}'); print('E113 => getStaffListData => ${response['data']}');
@ -184,8 +194,14 @@ class StaffListState extends ConsumerState<StaffList> {
Tooltip( Tooltip(
message: 'Back', message: 'Back',
child: IconButton( child: IconButton(
icon: const Icon(Icons.arrow_left_sharp,size: 25,color: Color(0xFF425B5B)), icon: const Icon(
onPressed: () { context.go(AppRoutes.dashboard); }, Icons.arrow_left_sharp,
size: 25,
color: Color(0xFF425B5B),
),
onPressed: () {
context.go(AppRoutes.dashboard);
},
splashRadius: 18, splashRadius: 18,
hoverColor: Colors.black12, hoverColor: Colors.black12,
padding: const EdgeInsets.all(4), padding: const EdgeInsets.all(4),
@ -244,7 +260,7 @@ class StaffListState extends ConsumerState<StaffList> {
"name", "name",
"email", "email",
"mobile", "mobile",
"emp_id", "role",
"is_active", "is_active",
], ],
), ),
@ -300,6 +316,10 @@ class StaffListState extends ConsumerState<StaffList> {
flex: 2, flex: 2,
child: Text('Staff Name', style: _headerStyle), child: Text('Staff Name', style: _headerStyle),
), ),
Expanded(
flex: 1,
child: Text('Role', style: _headerStyle),
),
Expanded( Expanded(
flex: 3, flex: 3,
child: Text('Email', style: _headerStyle), child: Text('Email', style: _headerStyle),
@ -308,10 +328,7 @@ class StaffListState extends ConsumerState<StaffList> {
flex: 2, flex: 2,
child: Text('Phone Number', style: _headerStyle), child: Text('Phone Number', style: _headerStyle),
), ),
Expanded(
flex: 1,
child: Text('Employee Id', style: _headerStyle),
),
Expanded( Expanded(
flex: 1, flex: 1,
child: Text('Status', style: _headerStyle), child: Text('Status', style: _headerStyle),
@ -404,6 +421,8 @@ class StaffListState extends ConsumerState<StaffList> {
children: [ children: [
Expanded(flex: 1, child: Text('$sno' ?? '-', style: _dataBold)), Expanded(flex: 1, child: Text('$sno' ?? '-', style: _dataBold)),
Expanded(flex: 2, child: Text(item['name'] ?? '-', style: _dataBold)), Expanded(flex: 2, child: Text(item['name'] ?? '-', style: _dataBold)),
Expanded(flex: 1, child: Text(item['role'] ?? '-', style: _dataBold)),
Expanded( Expanded(
flex: 3, flex: 3,
child: Text(item['email'] ?? '-', style: _dataBold), child: Text(item['email'] ?? '-', style: _dataBold),
@ -412,10 +431,6 @@ class StaffListState extends ConsumerState<StaffList> {
flex: 2, flex: 2,
child: Text(item['mobile'] ?? '-', style: _dataBold), child: Text(item['mobile'] ?? '-', style: _dataBold),
), ),
Expanded(
flex: 1,
child: Text(item['emp_id'] ?? '-', style: _dataBold),
),
Expanded( Expanded(
flex: 1, flex: 1,

View File

@ -68,6 +68,7 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
int selectedTabIndex = 0; int selectedTabIndex = 0;
List<Map<String, dynamic>> currentList = []; List<Map<String, dynamic>> currentList = [];
List<Map<String, dynamic>> staffQuotationsPendingList = []; // cross verify
List<Map<String, dynamic>> quotationsPendingList = []; // cross verify List<Map<String, dynamic>> quotationsPendingList = []; // cross verify
List<Map<String, dynamic>> policiesPendingList = []; // cross verify List<Map<String, dynamic>> policiesPendingList = []; // cross verify
List<Map<String, dynamic>> awaitingApprovalList = []; // cross verify List<Map<String, dynamic>> awaitingApprovalList = []; // cross verify
@ -262,6 +263,16 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
}); });
} }
if (data['staff_level_pending_summary'] != null) {
print('staff_level_pending_summary -');
staffQuotationsPendingList = List<Map<String, dynamic>>.from(
(data['staff_level_pending_summary'] as List).map(
(item) => Map<String, dynamic>.from(item),
),
);
print('staff_level_pending_summary - $staffQuotationsPendingList');
}
if (data['quotations_pending'] != null) { if (data['quotations_pending'] != null) {
quotationsPendingList = List<Map<String, dynamic>>.from( quotationsPendingList = List<Map<String, dynamic>>.from(
(data['quotations_pending'] as List).map( (data['quotations_pending'] as List).map(
@ -490,7 +501,8 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
scrollDirection: Axis.vertical, scrollDirection: Axis.vertical,
child: Column( child: Column(
children: [ children: [
if (role != 'staff') // if (role != 'staff')
if (role != 'staff' && role != 'handler')
Row( Row(
children: [ children: [
Expanded( Expanded(
@ -535,8 +547,22 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
: (role == 'manager') : (role == 'manager')
? MediaQuery.of(context).size.height * 0.5 ? MediaQuery.of(context).size.height * 0.5
: MediaQuery.of(context).size.height * : MediaQuery.of(context).size.height *
0.85, // 350 adjust height as needed 0.5, // 350 adjust height as needed
child: Row( child: (role == 'manager' || role == 'handler')
? Row(
children: [
Expanded(
child: othersPendings(
title:
"Staff Proposal Pending List (${staffQuotationsPendingList.length})",
data: staffQuotationsPendingList,
stringFlag: "Quotation",
role: role!,
),
),
],
)
: Row(
children: [ children: [
Expanded( Expanded(
child: (role == 'agent') child: (role == 'agent')
@ -555,12 +581,7 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
}, },
) )
: (role == 'manager') : (role == 'manager')
? othersPendings( ? SizedBox.shrink()
title:
"Awaiting Quotation (${quotationsPendingList.length})",
data: quotationsPendingList,
stringFlag: "Quotation",
)
: agentPendings( : agentPendings(
title: title:
"Awaiting Quotation (${quotationsPendingList.length})", "Awaiting Quotation (${quotationsPendingList.length})",
@ -595,12 +616,13 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
}, },
) )
: (role == 'manager') : (role == 'manager')
? awaitingApproval( ? SizedBox.shrink()
title: // othersPendings(
"Awaiting Approval (${awaitingApprovalList.length})", // title:
data: awaitingApprovalList, // "Awaiting Quotation (${quotationsPendingList.length})",
stringFlag: "Quotation", // data: quotationsPendingList,
) // stringFlag: "Quotation",
// )
: agentPendings( : agentPendings(
title: title:
"Awaiting Approval (${awaitingApprovalList.length})", "Awaiting Approval (${awaitingApprovalList.length})",
@ -634,14 +656,15 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
handleStaffEdit(row, flag); handleStaffEdit(row, flag);
}, },
) )
: (role == 'manager') : (role == 'staff')
? othersPendings( ?
title: // ? othersPendings(
"Awaiting Policy (${policiesPendingList.length})", // title:
data: policiesPendingList, // "Awaiting Quotation (${quotationsPendingList.length})",
stringFlag: "Policies", // data: quotationsPendingList,
) // stringFlag: "Quotation",
: agentPendings( // )
agentPendings(
title: title:
"Awaiting Policy (${policiesPendingList.length})", "Awaiting Policy (${policiesPendingList.length})",
data: policiesPendingList, data: policiesPendingList,
@ -655,13 +678,14 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
onStaffEdit: (row, flag) { onStaffEdit: (row, flag) {
handleStaffEdit(row, flag); handleStaffEdit(row, flag);
}, },
), )
: SizedBox.shrink(),
), ),
], ],
), ),
), ),
const SizedBox(height: 10), const SizedBox(height: 10),
if (role == 'manager') if (role == 'manager' || role == 'handler')
SizedBox( SizedBox(
// replace Expanded // replace Expanded
height: 350, // adjust height as needed height: 350, // adjust height as needed
@ -670,7 +694,8 @@ class _DashboardScreenState extends ConsumerState<DashboardScreen> {
Expanded( Expanded(
child: UnassignedEnq( child: UnassignedEnq(
key: UniqueKey(), key: UniqueKey(),
title: "Unassigned Enquires", title: "Unassigned Enquiries",
role: role!,
data: unAssignedEnqList, data: unAssignedEnqList,
onRefresh: refresh, onRefresh: refresh,
), ),
@ -1094,11 +1119,13 @@ class agentPendings extends StatelessWidget {
class othersPendings extends StatelessWidget { class othersPendings extends StatelessWidget {
final String title; final String title;
final String stringFlag; final String stringFlag;
String role;
final List<Map<String, dynamic>> data; final List<Map<String, dynamic>> data;
othersPendings({ othersPendings({
Key? key, Key? key,
required this.title, required this.title,
required this.role,
required this.data, required this.data,
required this.stringFlag, required this.stringFlag,
}) : super(key: key); }) : super(key: key);
@ -1137,6 +1164,16 @@ class othersPendings extends StatelessWidget {
// style: _headerStyle, // style: _headerStyle,
// ), // ),
// ), // ),
if (role == 'manager') ...[
Expanded(
flex: 2,
child: Text(
"Handler Name",
textAlign: TextAlign.center,
style: _headerStyle,
),
),
],
Expanded( Expanded(
flex: 2, flex: 2,
child: Text( child: Text(
@ -1145,25 +1182,49 @@ class othersPendings extends StatelessWidget {
style: _headerStyle, style: _headerStyle,
), ),
), ),
Expanded( Expanded(
flex: 2, flex: 2,
child: Text( child: Text(
// stringFlag + " Issued", // stringFlag + " Issued",
'Pending Count', 'Num Of Enquiry Assigned',
textAlign: TextAlign.center,
style: _headerStyle,
),
),
Expanded(
flex: 2,
child: Text(
'Awaiting Proposal',
textAlign: TextAlign.center,
style: _headerStyle,
),
),
Expanded(
flex: 2,
child: Text(
'Awaiting Approval',
textAlign: TextAlign.center,
style: _headerStyle,
),
),
Expanded(
flex: 2,
child: Text(
'Awaiting Policy',
textAlign: TextAlign.center,
style: _headerStyle,
),
),
Expanded(
flex: 2,
child: Text(
// stringFlag + " Issued",
'Policy Created',
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: _headerStyle, style: _headerStyle,
), ),
), ),
// (stringFlag == "Policies")
// ? Expanded(
// flex: 2,
// child: Text(
// "Total Premium Value",
// textAlign: TextAlign.center,
// style: _headerStyle,
// ),
// )
// : const SizedBox.shrink(),
], ],
), ),
), ),
@ -1204,6 +1265,17 @@ class othersPendings extends StatelessWidget {
// style: _tableDataStyle, // style: _tableDataStyle,
// ), // ),
// ), // ),
if (role == 'manager') ...[
Expanded(
flex: 2,
child: Text(
row['handler_name'] ?? "",
textAlign: TextAlign.center,
style: _tableDataStyle,
),
),
],
Expanded( Expanded(
flex: 2, flex: 2,
child: Text( child: Text(
@ -1217,25 +1289,48 @@ class othersPendings extends StatelessWidget {
Expanded( Expanded(
flex: 2, flex: 2,
child: Text( child: Text(
issuedCount, row['total_assigned'] ?? "",
// row['total_approval_pending'] ?? "",
textAlign: TextAlign.center,
style: _tableDataStyle,
),
),
Expanded(
flex: 2,
child: Text(
row['awaiting_quotation'] ?? "",
// row['total_approval_pending'] ?? "",
textAlign: TextAlign.center,
style: _tableDataStyle,
),
),
Expanded(
flex: 2,
child: Text(
row['pending_quotation_approval'] ?? "",
// row['total_approval_pending'] ?? "",
textAlign: TextAlign.center,
style: _tableDataStyle,
),
),
Expanded(
flex: 2,
child: Text(
row['awaiting_policy'] ?? "",
// row['total_approval_pending'] ?? "",
textAlign: TextAlign.center,
style: _tableDataStyle,
),
),
Expanded(
flex: 2,
child: Text(
row['policy_created'] ?? "",
// row['total_approval_pending'] ?? "", // row['total_approval_pending'] ?? "",
textAlign: TextAlign.center, textAlign: TextAlign.center,
style: _tableDataStyle, style: _tableDataStyle,
), ),
), ),
// stringFlag == "Policies"
// ? Expanded(
// flex: 2,
// child: Text(
// formatToCroresLakhsAndThousands(permiumValue),
// textAlign: TextAlign.center,
// style: GoogleFonts.inter(
// fontSize: 14,
// fontWeight: FontWeight.w500,
// ),
// ),
// )
// : const SizedBox.shrink(),
], ],
), ),
); );
@ -1553,12 +1648,14 @@ class UnassignedEnq extends StatelessWidget {
final String title; final String title;
final List<Map<String, dynamic>> data; final List<Map<String, dynamic>> data;
final VoidCallback? onRefresh; final VoidCallback? onRefresh;
String role;
UnassignedEnq({ UnassignedEnq({
Key? key, Key? key,
required this.title, required this.title,
required this.data, required this.data,
this.onRefresh, this.onRefresh,
required this.role,
}) : super(key: key); }) : super(key: key);
@override @override
@ -1647,7 +1744,8 @@ class UnassignedEnq extends StatelessWidget {
// color: Colors.green , // color: Colors.green ,
// width: 2, // width: 2,
// ), // ),
onTap: () { onTap: (role == 'handler')
? () {
// Print the id when row is clicked // Print the id when row is clicked
print("Clicked ID: ${row['id']}"); print("Clicked ID: ${row['id']}");
// You can also navigate or perform any action here // You can also navigate or perform any action here
@ -1666,7 +1764,8 @@ class UnassignedEnq extends StatelessWidget {
}, },
), ),
); );
}, }
: null,
child: Container( child: Container(
// height: 5200, // height: 5200,
margin: const EdgeInsets.symmetric(vertical: 5), margin: const EdgeInsets.symmetric(vertical: 5),

File diff suppressed because it is too large Load Diff

View File

@ -136,6 +136,8 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
if (roleId.toString() == "1") { if (roleId.toString() == "1") {
role = "manager"; role = "manager";
} else if (roleId.toString() == "2") { } else if (roleId.toString() == "2") {
role = "handler";
} else if (roleId.toString() == "3") {
role = "staff"; role = "staff";
} else { } else {
role = "agent"; // fallback if unexpected value role = "agent"; // fallback if unexpected value
@ -171,6 +173,20 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
print("⚠️ Manager ID is null or invalid"); print("⚠️ Manager ID is null or invalid");
} }
// 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");
}
// User ID // User ID
final dynamic userIdRaw = data['id']; final dynamic userIdRaw = data['id'];
final int? userId = userIdRaw is int final int? userId = userIdRaw is int
@ -966,7 +982,7 @@ class _LoginScreenState extends ConsumerState<LoginScreen> {
width: double.infinity, width: double.infinity,
height: 50, height: 50,
child: CommonButton( child: CommonButton(
text: "Login as Agent", text: "Login as Partner",
backgroundColor: Color(0xFF436462), backgroundColor: Color(0xFF436462),
onPressed: () async { onPressed: () async {
setState(() { setState(() {

View File

@ -287,48 +287,47 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
regNum, regNum,
) { ) {
return [ return [
if (roleId == 'manager' && data['status'] == 'Awaiting Quotation') ...[ // if (roleId == 'manager' && data['status'] == 'Awaiting Quotation') ...[
Material( // Material(
color: Colors.transparent, // color: Colors.transparent,
child: InkWell( // child: InkWell(
onTap: () { // onTap: () {
Navigator.pop(context); // Navigator.pop(context);
showDialog( // showDialog(
context: context, // context: context,
builder: (ctx) => AssignStaffDialog( // builder: (ctx) => AssignStaffDialog(
enquiryPrimaryId: id, // enquiryPrimaryId: id,
regNum: regNum, // regNum: regNum,
userId: 1, // userId: 1,
onSubmit: (value) { // onSubmit: (value) {
debugPrint("New assignY: $value"); // debugPrint("New assignY: $value");
refresh(); // refresh();
}, // },
), // ),
); // );
}, // },
hoverColor: Color(0xFFE3F1F0), // hoverColor: Color(0xFFE3F1F0),
splashColor: Color(0xFFE3F1F0), // splashColor: Color(0xFFE3F1F0),
borderRadius: BorderRadius.circular(6), // borderRadius: BorderRadius.circular(6),
child: Padding( // child: Padding(
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4), // padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
child: Row( // child: Row(
// mainAxisSize: MainAxisSize.min, // // mainAxisSize: MainAxisSize.min,
children: [ // children: [
Image.asset( // Image.asset(
"assets/miscellaneous/image_3.png", // "assets/miscellaneous/image_3.png",
// height: 45, // // height: 45,
// width: 15, // // width: 15,
), // ),
//
SizedBox(width: 10), // SizedBox(width: 10),
Text('Assign Staff'), // Text('Assign Staff'),
], // ],
), // ),
), // ),
), // ),
), // ),
], // ],
Material( Material(
color: Colors.transparent, color: Colors.transparent,
child: InkWell( child: InkWell(
@ -435,7 +434,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
mainAxisAlignment: MainAxisAlignment.start, mainAxisAlignment: MainAxisAlignment.start,
children: [ children: [
Container( Container(
height: 40, height: 30,
width: MediaQuery.of(context).size.width, width: MediaQuery.of(context).size.width,
child: GestureDetector( child: GestureDetector(
onTap: () { onTap: () {
@ -470,7 +469,7 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
), ),
), ),
), ),
SizedBox(height: 10), SizedBox(height: 5),
ResponsiveLayout.isMobile(context) ResponsiveLayout.isMobile(context)
? Container( ? Container(
height: MediaQuery.of(context).size.height * 0.69, height: MediaQuery.of(context).size.height * 0.69,
@ -647,49 +646,10 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
"status", "status",
], ],
), ),
// SizedBox(width: 10),
// GestureDetector(
// onTap: () {
// // print('Export');
// },
// child: Container(
// padding: EdgeInsets.all(8.0),
// decoration: BoxDecoration(
// color: Color(0xFF425B5B),
// borderRadius: BorderRadius.circular(8.0),
// ),
// child: Row(
// mainAxisSize: MainAxisSize.min,
// children: [
// Icon(Icons.add, color: Colors.white),
//
// if (!ResponsiveLayout.isMobile(context)) ...[
// SizedBox(width: 10),
//
// GestureDetector(
// onTap: () {
// // context.go(AppRoutes.agent / create);
// context.go('/staff/create');
// },
// child: Text(
// 'Create New Staff',
// style: TextStyle(
// color: Colors.white,
// fontWeight: FontWeight.w600,
// fontSize: 14,
// ),
// ),
// ),
// ],
// ],
// ),
// ),
// ),
], ],
), ),
), ),
SizedBox(height: 10), // SizedBox(height: 10),
if (!ResponsiveLayout.isMobile(context)) if (!ResponsiveLayout.isMobile(context))
Container( Container(
decoration: BoxDecoration( decoration: BoxDecoration(
@ -701,38 +661,23 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
children: [ children: [
Expanded( Expanded(
flex: 3, 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('Partner ', style: _headerStyle)), Expanded(flex: 2, child: Text('Partner ', style: _headerStyle)),
Expanded( Expanded(flex: 4, child: Text('Insurer', style: _headerStyle)),
flex: 2, Expanded(
child: Text('Assigned To', style: _headerStyle), flex: 3,
), child: Text('Vehicle No', style: _headerStyle),
Expanded(flex: 3, child: Text('Insurer', style: _headerStyle)), ),
Expanded( Expanded(
flex: 3, flex: 3,
child: Padding(
padding: EdgeInsets.only(left: 8.0),
child: Text('Insured Name', style: _headerStyle), child: Text('Insured Name', style: _headerStyle),
), ),
),
Expanded(flex: 2, child: Text('Premium', style: _headerStyle)),
Expanded( Expanded(
flex: 2, flex: 3,
child: Text('Payment Mode', style: _headerStyle), child: Text('Assigned Date & Time', style: _headerStyle),
), ),
Expanded(
flex: 2,
child: Text('Policy Number', style: _headerStyle),
),
Expanded(flex: 3, child: Text('Status', style: _headerStyle)), Expanded(flex: 3, child: Text('Status', style: _headerStyle)),
Expanded(flex: 1, child: Text('Action', style: _headerStyle)),
], ],
), ),
), ),
@ -836,6 +781,51 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
maxLines: 3, maxLines: 3,
), ),
), ),
Expanded(
flex: 2,
child: Text(
item['agent_name'] ?? '-',
style: _dataBold,
softWrap: true,
maxLines: 2,
),
),
Expanded(
flex: 4,
child: Text(
item['insurer_name'] ?? '-',
style: _dataBold,
softWrap: true,
maxLines: 3,
),
),
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),
),
),
Expanded(
flex: 3,
child: Text(
item['insured_name'] ?? '-',
style: _dataBold,
softWrap: true,
maxLines: 3,
),
),
Expanded( Expanded(
flex: 3, flex: 3,
child: Text( child: Text(
@ -845,112 +835,81 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
maxLines: 3, maxLines: 3,
), ),
), ),
Expanded(
flex: 2,
child: Text(item['reg_no'] ?? '-', style: _dataBold),
),
Expanded(
flex: 2,
child: Text(
_formatDate(item['agent_name']) ?? '-',
style: _dataBold,
),
),
Expanded(
flex: 2,
child: Text(item['assigned_to_name'] ?? '-', style: _dataBold),
),
Expanded(
flex: 3,
child: Text(
item['insurer_name'] ?? '-',
style: _dataBold,
softWrap: true,
maxLines: 3,
),
),
Expanded(
flex: 3,
child: Center(
child: Text(
item['insured_name'] ?? '-',
style: _dataBold,
softWrap: true,
maxLines: 3,
),
),
),
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( Expanded(
flex: 3, flex: 3,
child: Text(item['status'] ?? '-', style: _dataBold), child: Text(item['status'] ?? '-', style: _dataBold),
), ),
Expanded( // Expanded(
flex: 1, // flex: 2,
child: Row( // child: Text(item['assigned_to_name'] ?? '-', style: _dataBold),
children: [ // ),
PopupMenuButton<int>( //
color: Colors.white, // Expanded(
padding: EdgeInsets.zero, // flex: 2,
offset: Offset(0, 30), // child: Text(
icon: Icon( // item['premium_amount'] ?? '-',
Icons.more_vert, // style: _dataBold,
color: Color(0xFF475569), // softWrap: true,
size: 14, // maxLines: 3,
), // ),
itemBuilder: (context) => [ // ),
CustomPopupMenuEntry( // Expanded(
child: Container( // flex: 2,
padding: EdgeInsets.symmetric( // child: Text(
horizontal: 8, // item['payment_mode'] ?? '-',
vertical: 8, // style: _dataBold,
), // softWrap: true,
child: Column( // maxLines: 3,
mainAxisSize: MainAxisSize.min, // ),
mainAxisAlignment: MainAxisAlignment.start, // ),
crossAxisAlignment: CrossAxisAlignment.start, // Expanded(
children: _buildPopupMenuActions( // flex: 2,
context, // child: Text(
item, // item['policy_number'] ?? '-',
item['id'], // style: _dataBold,
item['reg_no'], // 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'],
// ),
// ),
// ),
// ),
// ],
// ),
// ],
// ),
// ),
], ],
), ),
); );

File diff suppressed because it is too large Load Diff

View File

@ -2,8 +2,10 @@ import 'dart:convert';
import 'package:dropdown_search/dropdown_search.dart'; import 'package:dropdown_search/dropdown_search.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:google_fonts/google_fonts.dart'; import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http; import 'package:http/http.dart' as http;
import 'package:toastification/toastification.dart'; import 'package:toastification/toastification.dart';
import '../../../../core/config/env.dart'; import '../../../../core/config/env.dart';
@ -12,11 +14,12 @@ import '../../../../data/services/auth_service.dart';
import '../../../../data/utils/toastNotification.dart'; import '../../../../data/utils/toastNotification.dart';
import '../../../../data/utils/validators.dart'; import '../../../../data/utils/validators.dart';
import '../../layouts/responsive_layout.dart'; import '../../layouts/responsive_layout.dart';
import '../../providers/manager_provider.dart';
import '../../themes/indicators/input_field_decoration.dart'; import '../../themes/indicators/input_field_decoration.dart';
import '../../themes/indicators/text_field_theme.dart'; import '../../themes/indicators/text_field_theme.dart';
// 🔹 Custom Dialog Widget // 🔹 Custom Dialog Widget
class AssignStaffDialog extends StatefulWidget { class AssignStaffDialog extends ConsumerStatefulWidget {
final dynamic userId; final dynamic userId;
final dynamic regNum; final dynamic regNum;
final dynamic enquiryPrimaryId; final dynamic enquiryPrimaryId;
@ -32,10 +35,11 @@ class AssignStaffDialog extends StatefulWidget {
}); });
@override @override
State<AssignStaffDialog> createState() => _AddDialogState(); // State<AssignStaffDialog> createState() => _AddDialogState();
ConsumerState<AssignStaffDialog> createState() => _AddDialogState();
} }
class _AddDialogState extends State<AssignStaffDialog> { class _AddDialogState extends ConsumerState<AssignStaffDialog> {
late ApiService apiService; late ApiService apiService;
String? _token; String? _token;
@ -44,11 +48,18 @@ class _AddDialogState extends State<AssignStaffDialog> {
late TextEditingController controller; late TextEditingController controller;
Map<String, TextEditingController> controllers = {}; Map<String, TextEditingController> controllers = {};
List<Map<String, dynamic>> getInsurersData = [];
List<Map<String, dynamic>> filteredInsurersData = [];
String? selectedInsurer;
final _formKey = GlobalKey<FormState>(); final _formKey = GlobalKey<FormState>();
final _formKeyEndrosment = GlobalKey<FormState>(); final _formKeyEndrosment = GlobalKey<FormState>();
final GlobalKey<DropdownSearchState<Map<String, dynamic>>> dropDownKey = final GlobalKey<DropdownSearchState<Map<String, dynamic>>> dropDownKey =
GlobalKey<DropdownSearchState<Map<String, dynamic>>>(); GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
final GlobalKey<DropdownSearchState<Map<String, dynamic>>>
dropDownKeyInsurer = GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
List<String> tabHeader = ['regNum']; List<String> tabHeader = ['regNum'];
List<Map<String, dynamic>> getStaffDetailsData = []; List<Map<String, dynamic>> getStaffDetailsData = [];
@ -62,6 +73,7 @@ class _AddDialogState extends State<AssignStaffDialog> {
final data = { final data = {
"id": widget.enquiryPrimaryId, "id": widget.enquiryPrimaryId,
"assigned_to": selectedStaff, "assigned_to": selectedStaff,
"insurer_id": selectedInsurer,
"updated_by": widget.userId, "updated_by": widget.userId,
}; };
return data; return data;
@ -80,7 +92,16 @@ class _AddDialogState extends State<AssignStaffDialog> {
// 🔹 Init logic here (API calls, token fetch, etc.) // 🔹 Init logic here (API calls, token fetch, etc.)
_initializeToken(); _initializeToken();
getStaffDetails(); // getStaffDetails(1);
getInsurers();
Future.microtask(() {
final managerId = ref.watch(managerIdProvider);
final handlerId = ref.watch(handlerIdProvider);
if (handlerId != null) {
print('hansles');
getStaffDetails(handlerId);
}
});
} }
Future<void> _initializeToken() async { Future<void> _initializeToken() async {
@ -88,14 +109,47 @@ class _AddDialogState extends State<AssignStaffDialog> {
print("APISERTOKEN - $_token"); print("APISERTOKEN - $_token");
} }
Future<void> getStaffDetails() async { 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> getStaffDetails(int id) async {
print('getStaffDetails called'); print('getStaffDetails called');
setState(() { setState(() {
isLoading = true; isLoading = true;
}); });
try { try {
final response = await apiService.fetchMasterDropDown('Staffs'); final response = await apiService.fetchStaffListForEnquiryAssignDropDown(
id,
);
if (response['status'] == 200) { if (response['status'] == 200) {
print('getStaffDetails - ${response['data']}'); print('getStaffDetails - ${response['data']}');
@ -301,6 +355,7 @@ class _AddDialogState extends State<AssignStaffDialog> {
children: [ children: [
buildRegistrationNumber(context), buildRegistrationNumber(context),
buildSelectStaffMem(context), buildSelectStaffMem(context),
buildInsurer(context),
], ],
), ),
); );
@ -364,7 +419,7 @@ class _AddDialogState extends State<AssignStaffDialog> {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text("Select Staff Member", style: _textStyle), Text("Select Staff Member *", style: _textStyle),
SizedBox(height: 10), SizedBox(height: 10),
Container( Container(
color: Colors.white, color: Colors.white,
@ -446,10 +501,101 @@ class _AddDialogState extends State<AssignStaffDialog> {
); );
} }
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'];
}
},
),
),
],
);
}
// ------------------- STyle --------------------------------- // ------------------- STyle ---------------------------------
static final TextStyle _textStyle = TextStyle( static final TextStyle _textStyle = TextStyle(
fontSize: 14, fontSize: 12,
fontWeight: FontWeight.w600, fontWeight: FontWeight.w600,
); );

View File

@ -66,7 +66,7 @@ class createQuotatDialogState extends State<createQuotatDialog> {
final GlobalKey<DropdownSearchState<Map<String, dynamic>>> final GlobalKey<DropdownSearchState<Map<String, dynamic>>>
dropDownKeyInsurer = GlobalKey<DropdownSearchState<Map<String, dynamic>>>(); dropDownKeyInsurer = GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
List<String> tabHeader = ['idv', 'premium_Amount']; List<String> tabHeader = ['idv', 'premium_Amount', 'insurer'];
List<Map<String, dynamic>> getInsuranceTypeData = []; List<Map<String, dynamic>> getInsuranceTypeData = [];
List<Map<String, dynamic>> filteredInsuranceData = []; List<Map<String, dynamic>> filteredInsuranceData = [];
@ -99,7 +99,7 @@ class createQuotatDialogState extends State<createQuotatDialog> {
// 🔹 Init logic here (API calls, token fetch, etc.) // 🔹 Init logic here (API calls, token fetch, etc.)
_initializeToken(); _initializeToken();
getInsuranceType(); getInsuranceType();
getInsurers(); // getInsurers();
updateData(); updateData();
} }
@ -135,8 +135,8 @@ class createQuotatDialogState extends State<createQuotatDialog> {
.selectedQuotationFrmListdata!['insurance_plan_type_id'] .selectedQuotationFrmListdata!['insurance_plan_type_id']
?.toString(); ?.toString();
selectedInsurer = // selectedInsurer =
widget.selectedQuotationFrmListdata!['insurer_id']?.toString() ?? ''; // widget.selectedQuotationFrmListdata!['insurer_id']?.toString() ?? '';
String? apiDocPath = String? apiDocPath =
widget.selectedQuotationFrmListdata!["additional_uploaded_file_name"]; widget.selectedQuotationFrmListdata!["additional_uploaded_file_name"];
@ -465,96 +465,115 @@ class createQuotatDialogState extends State<createQuotatDialog> {
} }
Widget buildInsurer(BuildContext context) { Widget buildInsurer(BuildContext context) {
Map<String, dynamic>? selectedInsurerd = filteredInsurersData.firstWhere(
(item) => item['id'].toString() == selectedInsurer,
orElse: () => {},
);
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,
children: [ children: [
Text('Insurer *', style: _textStyle), Text('Insurer *', style: _textStyle),
SizedBox(height: 10), SizedBox(height: 10),
Container( ThemedFormField(
decoration: BoxDecoration( controller: controllers['insurer']!,
color: Colors.white, validator: (value) => Validators.requiredField(value, "insurer"),
// borderRadius: BorderRadius.circular(10.0), backgroundColor: Color(0xFFEDF6F5),
), readOnly: true,
width: ResponsiveLayout.isMobile(context) txtwidth: ResponsiveLayout.isMobile(context)
? null ? null
: MediaQuery.of(context).size.width * 0.26, : 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 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 buildPremiumAmnt(BuildContext context) { Widget buildPremiumAmnt(BuildContext context) {
return Column( return Column(
crossAxisAlignment: CrossAxisAlignment.start, crossAxisAlignment: CrossAxisAlignment.start,

View File

@ -127,6 +127,8 @@ class DrawerMenuState extends ConsumerState<DrawerMenu> {
_hidePopup(); _hidePopup();
if (roleId == 'agent') { if (roleId == 'agent') {
context.go(AppRoutes.enquiryLst); context.go(AppRoutes.enquiryLst);
} else if (roleId == 'handler') {
context.go(AppRoutes.enquiryHandlerLst);
} else { } else {
context.go(AppRoutes.enquiryForStaff); context.go(AppRoutes.enquiryForStaff);
} }