FIX_Frontend helpdesk issues

This commit is contained in:
sanjeev.p 2026-01-02 09:51:32 +05:30
parent 5d3bf2c917
commit 7908c2278f
13 changed files with 491 additions and 177 deletions

File diff suppressed because one or more lines are too long

View File

@ -483,9 +483,9 @@ class ApiService {
} else if (path == 'NonPerformingBelow50K') {
pathVal = 'dashboard/downloadExcelLowPremium?manager_id=$managerId';
} else if (path == 'staff_pending_summary') {
pathVal = 'dashboard/downloadExcelStaffPendingSummaryExcel?manager_id=$managerId';
pathVal = 'dashboard/downloadExcelStaffPendingSummary?manager_id=$managerId';
} else if (path == 'staff_pending_summary_by_id') {
pathVal = 'dashboard/downloadExcelStaffPendingSummaryExcelByID?manager_id=$managerId&staff_id=$id&status=$month';
pathVal = 'dashboard/downloadExcelStaffPendingSummaryByID?manager_id=$managerId&staff_id=$id&status=$month';
} else {
//NoBusiness
pathVal =
@ -574,7 +574,7 @@ class ApiService {
dynamic pathVal;
pathVal =
'dashboard/downloadStaffAndProductPoliciesExcel?manager_id=$managerId&month=$month&sales_executive_id=$salesId&vehicle_type=$id';
'dashboard/downloadExcelStaffAndProduct?manager_id=$managerId&month=$month&sales_executive_id=$salesId&vehicle_type=$id';
final url = Uri.parse('${Env.apiUrl}$pathVal');
// final url = Uri.parse('https://venbait.in/nhance/partner/dev/$path');
@ -2082,11 +2082,13 @@ class ApiService {
}
}
Future<void> generatePolicyExcel(managerId, fromDate, toDate) async {
Future<void> generatePolicyExcel(managerId, fromDate, toDate, searchValue) async {
final url = Uri.parse(
'${Env.apiUrl}reports/policy-excel?manager_id=$managerId&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}',
);
// final url = Uri.parse( 'http://localhost/nhance_partner_be/reports/policy-excel?manager_id=$managerId&from_date=${fromDate ?? ''}&to_date=${toDate ?? ''}&search=${searchValue ?? ''}', );
print('getPdfDownload policy-excel - $url');
await _initializeToken();

View File

@ -67,7 +67,8 @@ class _AppHeaderState extends ConsumerState<AppHeader> {
} else if (currentRoute.contains('broker') ||
currentRoute.contains('payment')) {
_activeMenu = 'Masters';
} else if (currentRoute.contains('payout')) {
} else if (currentRoute.contains('invoice') || // ADD THIS
currentRoute.contains('payout')) {
_activeMenu = 'Invoice';
}
});

View File

@ -829,14 +829,24 @@ class EnquiryTabState extends ConsumerState<EnquiryTab> {
itemAsString: (val) => val['vehicle_type'].toString(),
compareFn: (item, selectedItem) =>
item['id'] == selectedItem['id'], // compare by id
// decoratorProps: DropDownDecoratorProps(
// decoration:
// AppInputDecorations.dropdownDecoration(
// label: "Select Vehicle Type",
// ).copyWith(
// filled: true,
// fillColor: Colors.white, // 👈 makes the dropdown input white
// ),
// ),
decoratorProps: DropDownDecoratorProps(
decoration:
AppInputDecorations.dropdownDecoration(
label: "Select Vehicle Type",
).copyWith(
filled: true,
fillColor: Colors.white, // 👈 makes the dropdown input white
),
AppInputDecorations.dropdownDecoration(
label: "Select Vehicle Type",
).copyWith(
filled: true,
fillColor: Colors.white,
contentPadding: const EdgeInsets.fromLTRB(8, 0, 0, 0),
),
),
popupProps: PopupProps.menu(

View File

@ -930,9 +930,9 @@ class _AddDialogState extends State<AddDialog> {
label: "Select Claims Type",
).copyWith(
filled: true,
fillColor: Color(
0xFFEDF6F5,
), // 👈 makes the dropdown input white
fillColor: Color( 0xFFEDF6F5,), // 👈 makes the dropdown input white
isDense: true, // 👈 Makes the field compact
contentPadding: const EdgeInsets.symmetric(horizontal: 15, vertical: 0), // 👈 Vertical 0 helps center the text
),
),
@ -1106,9 +1106,9 @@ class _AddDialogState extends State<AddDialog> {
label: "Select Endorsement Type",
).copyWith(
filled: true,
fillColor: Color(
0xFFEDF6F5,
), // 👈 makes the dropdown input white
fillColor: Color( 0xFFEDF6F5,), // 👈 makes the dropdown input white
isDense: true, // 👈 Makes the field compact
contentPadding: const EdgeInsets.symmetric(horizontal: 15, vertical: 0), // 👈 Vertical 0 helps center the text
),
),
@ -1199,7 +1199,9 @@ class _AddDialogState extends State<AddDialog> {
label: "Select Policy From",
).copyWith(
filled: true,
fillColor: const Color(0xFFEDF6F5),
fillColor: const Color(0xFFEDF6F5), // 👈 makes the dropdown input white
isDense: true, // 👈 Makes the field compact
contentPadding: const EdgeInsets.symmetric(horizontal: 15, vertical: 0), // 👈 Vertical 0 helps center the text
),
),

View File

@ -48,6 +48,7 @@ class _UpdateEndorsementDialogState extends State<UpdateEndorsementDialog> {
String? selectedEndorsement;
String? selectedPolicyFrom;
String? selectedStatus; // "Pending" or "Completed"
String? selectedFinancialStatus;
String? selectedFileNames;
bool isLoading = false;
PlatformFile? docUploadedFile;
@ -63,6 +64,11 @@ class _UpdateEndorsementDialogState extends State<UpdateEndorsementDialog> {
{"policy_from": "External"},
];
final List<Map<String, dynamic>> financialOptions = [
{ "financial_value": "Yes"},
{ "financial_value": "No"},
];
final GlobalKey<DropdownSearchState<Map<String, dynamic>>> dropDownKey =
GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
final GlobalKey<DropdownSearchState<Map<String, dynamic>>>
@ -80,9 +86,13 @@ class _UpdateEndorsementDialogState extends State<UpdateEndorsementDialog> {
// 1. Initialize Controllers
controllers['endorsement_no'] = TextEditingController(text: widget.item['endorsement_no']);
controllers['remarks'] = TextEditingController(text: widget.item['endorsement_description']);
controllers['contact_person'] = TextEditingController(text: widget.item['contact_person']);
controllers['endorsement_premium'] = TextEditingController(text: widget.item['endorsement_premium']);
controllers['pending_days'] = TextEditingController(text: widget.item['pending_days']);
selectedEndorsement = widget.item['endorsement_type']?.toString();
selectedStatus = widget.item['status']?.toString();
selectedFinancialStatus = widget.item['financia_or_non_financial']?.toString();
selectedFileNames = widget.item['endorsement_completion_file'];
getEnroementType();
@ -183,10 +193,14 @@ class _UpdateEndorsementDialogState extends State<UpdateEndorsementDialog> {
request.fields['endorsement_type'] = selectedEndorsement ?? "";
request.fields['endorsement_description'] = controllers['remarks']?.text ?? "";
request.fields['endorsement_no'] = controllers['endorsement_no']?.text ?? "";
request.fields['contact_person'] = controllers['contact_person']?.text ?? "";
request.fields['endorsement_premium'] = controllers['endorsement_premium']?.text ?? "";
request.fields['pending_days'] = controllers['pending_days']?.text ?? "";
// Set updated_by from the widget parameter
request.fields['updated_by'] = widget.userId.toString();
request.fields['status'] = selectedStatus ?? "";
request.fields['financia_or_non_financial'] = selectedFinancialStatus ?? "";
// --- FILE UPLOAD LOGIC ---
if (docUploadedFile != null) {
@ -320,6 +334,24 @@ class _UpdateEndorsementDialogState extends State<UpdateEndorsementDialog> {
],
),
const SizedBox(height: 10),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(child: buildContactPerson(context)),
const SizedBox(width: 15),
Expanded(child: buildFinancialOrNonFinancial(context)),
],
),
const SizedBox(height: 10),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Expanded(child: buildEndPremium(context)),
const SizedBox(width: 15),
Expanded(child: buildPendingDays(context)),
],
),
const SizedBox(height: 10),
Row(
children: [
Expanded(child: buildEndrosRemarks(context)),
@ -408,9 +440,9 @@ class _UpdateEndorsementDialogState extends State<UpdateEndorsementDialog> {
label: "Select Endorsement Type",
).copyWith(
filled: true,
fillColor: Color(
0xFFEDF6F5,
), // 👈 makes the dropdown input white
fillColor: Color( 0xFFEDF6F5,), // 👈 makes the dropdown input white
isDense: true, // 👈 Makes the field compact
contentPadding: const EdgeInsets.symmetric(horizontal: 15, vertical: 0), // 👈 Vertical 0 helps center the text
),
),
@ -524,7 +556,9 @@ class _UpdateEndorsementDialogState extends State<UpdateEndorsementDialog> {
label: "Select Status",
).copyWith(
filled: true,
fillColor: const Color(0xFFEDF6F5),
fillColor: Color( 0xFFEDF6F5,), // 👈 makes the dropdown input white
isDense: true, // 👈 Makes the field compact
contentPadding: const EdgeInsets.symmetric(horizontal: 15, vertical: 0), // 👈 Vertical 0 helps center the text
),
),
@ -595,7 +629,7 @@ class _UpdateEndorsementDialogState extends State<UpdateEndorsementDialog> {
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Upload Document", style: _textStyle),
SizedBox(width: 10),
SizedBox(height: 10),
ThemedUploadField(
backgroundColor: Color(0xFFEDF6F5),
hintText: selectedFileNames ?? "Upload Document",
@ -670,6 +704,164 @@ class _UpdateEndorsementDialogState extends State<UpdateEndorsementDialog> {
);
}
Widget buildContactPerson(context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Contact Person *", style: _textStyle),
SizedBox(height: 10),
ThemedFormField(
backgroundColor: Color(0xFFEDF6F5),
controller: controllers['contact_person']!,
validator: (value) => Validators.requiredField(value, "contact_person"),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z]')),
],
txtwidth: ResponsiveLayout.isMobile(context)
? null
: MediaQuery.of(context).size.width * 0.26,
// keyboardType: TextInputType.multiline,
// txtheight: 45,
),
],
);
}
Widget buildEndPremium(context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("End. Premium *", style: _textStyle),
SizedBox(height: 10),
ThemedFormField(
backgroundColor: Color(0xFFEDF6F5),
controller: controllers['endorsement_premium']!,
validator: (value) => Validators.requiredField(value, "endorsement_premium"),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[0-9]')),
],
txtwidth: ResponsiveLayout.isMobile(context)
? null
: MediaQuery.of(context).size.width * 0.26,
),
],
);
}
Widget buildPendingDays(context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Pending Days *", style: _textStyle),
SizedBox(height: 10),
ThemedFormField(
backgroundColor: Color(0xFFEDF6F5),
controller: controllers['pending_days']!,
validator: (value) => Validators.requiredField(value, "pending_days"),
inputFormatters: [
FilteringTextInputFormatter.allow(RegExp(r'[0-9]')),
],
txtwidth: ResponsiveLayout.isMobile(context)
? null
: MediaQuery.of(context).size.width * 0.26,
// keyboardType: TextInputType.multiline,
// txtheight: 45,
),
],
);
}
Widget buildFinancialOrNonFinancial(context) {
Map<String, dynamic> selectedEndorsementFNF = financialOptions.firstWhere(
(item) => item['financial_value'].toString() == selectedFinancialStatus,
orElse: () => {},
);
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Financial Status *", style: _textStyle),
const SizedBox(height: 10),
Container(
color: Colors.white,
width: ResponsiveLayout.isMobile(context)
? null
: MediaQuery.of(context).size.width * 0.26,
child: DropdownSearch<Map<String, dynamic>>(
// Use a unique key for this dropdown
key: const ValueKey("FinancialstatusDropdown"),
selectedItem: selectedEndorsementFNF.isNotEmpty
? selectedEndorsementFNF
: null,
items: (filter, infiniteScrollProps) {
return financialOptions; // Use the static list
},
itemAsString: (val) => val['financial_value'].toString(),
compareFn: (item, selectedItem) =>
item['financial_value'] == selectedItem['financial_value'],
// --- REQUIRED VALIDATOR ---
validator: (val) {
if (val == null || val.isEmpty) {
return "Required";
}
return null;
},
decoratorProps: DropDownDecoratorProps(
decoration: AppInputDecorations.dropdownDecoration(
label: "Select Financial Status",
).copyWith(
filled: true,
fillColor: Color( 0xFFEDF6F5,), // 👈 makes the dropdown input white
isDense: true, // 👈 Makes the field compact
contentPadding: const EdgeInsets.symmetric(horizontal: 15, vertical: 0), // 👈 Vertical 0 helps center the text
),
),
popupProps: PopupProps.menu(
fit: FlexFit.loose,
constraints: const BoxConstraints(maxHeight: 150), // Shorter for 2 items
menuProps: const MenuProps(
backgroundColor: Colors.white,
),
showSearchBox: true, // Disabled search as there are only 2 items
searchFieldProps: TextFieldProps(
decoration: InputDecoration(
filled: true,
fillColor: Colors.white,
hintText: "Search Financial Status...",
enabledBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white,
), // 👈 Normal border
),
focusedBorder: OutlineInputBorder(
borderSide: BorderSide(
color: Colors.white,
width: 1.5,
), // 👈 Focused border
),
),
),
),
onChanged: (val) {
if (val != null) {
setState(() {
print("Selected Financial Status: ${val['financial_value']}");
selectedFinancialStatus = val['financial_value'];
});
}
},
),
),
],
);
}
static final TextStyle _textStyle = TextStyle(
fontSize: 12,
fontWeight: FontWeight.w600,

View File

@ -162,22 +162,65 @@ class endosementState extends ConsumerState<endosement> {
}
}
List<Widget> _buildPopupMenuActions(BuildContext context, dynamic data) {
List<Widget> _buildPopupMenuActions(BuildContext context, Map<String, dynamic> item) {
final String Id = item['id']?.toString() ?? '';
final String? pdfPath = item["endorsement_completion_file"];
final String? fileName = (pdfPath != null && pdfPath.isNotEmpty)
? pdfPath.split('/').last
: null;
return [
GestureDetector(
// --- EDIT BUTTON ---
InkWell(
onTap: () {
Navigator.pop(context);
print('EDITStaff - ${data['id']}');
dynamic id = data['id'];
// context.go('/staff/$id');
Navigator.pop(context); // Close the menu first
showDialog(
context: context,
barrierDismissible: true,
builder: (BuildContext dialogContext) {
return UpdateEndorsementDialog(
item: item,
userId: userId, // Ensure these variables are accessible
managerId: managerId,
onSubmit: (val) => refresh(),
);
},
);
},
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.edit_sharp, color: Color(0xFF319718), size: 18),
SizedBox(width: 10),
Text('Edit'),
],
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 4.0),
child: Row(
children: const [
Icon(Icons.edit_sharp, color: Color(0xFF319718), size: 18),
SizedBox(width: 12),
Text('Edit', style: TextStyle(fontSize: 14)),
],
),
),
),
const Divider(height: 1, thickness: 0.5), // Subtle separator
// --- DOWNLOAD BUTTON ---
InkWell(
onTap: () {
Navigator.pop(context); // Close the menu first
apiService.downloadFile(
apiUrl: 'api/endorsement/downloadEndorsementCompletionFile?id=$Id',
apiId: Id,
localFile: null,
fileName: fileName,
);
},
child: Padding(
padding: const EdgeInsets.symmetric(vertical: 8.0, horizontal: 4.0),
child: Row(
children: const [
Icon(Icons.download_rounded, color: Colors.blue, size: 18),
SizedBox(width: 12),
Text('Download', style: TextStyle(fontSize: 14)),
],
),
),
),
];
@ -382,7 +425,7 @@ class endosementState extends ConsumerState<endosement> {
mainAxisSize: MainAxisSize.min,
children: [
Tooltip(
message: 'Create Claims',
message: 'Create Endorsement',
child: Icon(
Icons.add,
color: Colors.white,
@ -487,7 +530,7 @@ class endosementState extends ConsumerState<endosement> {
),
),
Expanded(
flex: 1,
flex: 2,
child: Text('Action', style: _headerStyle),
),
],
@ -569,6 +612,11 @@ class endosementState extends ConsumerState<endosement> {
}
Widget _buildDataRow(Map<String, dynamic> item, sno) {
final String Id = item['id']?.toString() ?? '';
final String? pdfPath = item["endorsement_completion_file"];
final String? fileName = pdfPath != null && pdfPath.isNotEmpty
? pdfPath.split('/').last
: null;
return Container(
padding: const EdgeInsets.symmetric(vertical: 16, horizontal: 16),
// margin: const EdgeInsets.only(top: 10),
@ -583,112 +631,55 @@ class endosementState extends ConsumerState<endosement> {
child: Row(
children: [
Expanded(flex: 2, child: Text('$sno' ?? '-', style: _dataBold)),
Expanded(flex: 2, child: Text(item['policy_from'] ?? '-',style: _dataBold)),
Expanded(flex: 2, child: Text(item['status'] ?? '-',style: _dataBold)),
Expanded(flex: 2, child: Text(item['reg_no'] ?? '-',style: _dataBold)),
Expanded(flex: 2, child: Text(item['insurer_short_name'] ?? '-',style: _dataBold)),
Expanded(flex: 2, child: Text(item['policy_number'] ?? '-', style: _dataBold)),
Expanded(flex: 2, child: Text(item['endorsement_type_value'] ?? '-', style: _dataBold)),
Expanded(flex: 2, child: Text(item['endorsement_no'] ?? '-', style: _dataBold)),
Expanded(
flex: 2,
child: Text(
item['policy_from'] ?? '-',
style: _dataBold,
),
),
Expanded(
flex: 2,
child: Text(
item['status'] ?? '-',
style: _dataBold,
),
),
Expanded(
flex: 2,
child: Text(
item['reg_no'] ?? '-', // fallback
style: _dataBold,
),
),
Expanded(
flex: 2,
child: Text(
item['endorsement_type_value'] ?? '-',
style: _dataBold,
),
),
Expanded(
flex: 2,
child: Text(
item['insurer_short_name'] ?? '-', // fallback
style: _dataBold,
),
),
Expanded(
flex: 2,
child: Text(item['policy_number'] ?? '-', style: _dataBold),
),
Expanded(
flex: 2,
child: Text(
item['endorsement_type_value'] ?? '-',
style: _dataBold,
),
),
Expanded(
flex: 2,
child: Text(item['endorsement_no'] ?? '-', style: _dataBold),
),
Expanded(
flex: 1,
flex: 2, // Action column
child: item['is_active'] == "1"
? Row(
mainAxisSize: MainAxisSize.min,
children: [
Tooltip(
message: 'Edit',
child: IconButton(
icon: Image.asset(
"assets/miscellaneous/Edit.png",
height: 12,
width: 15,
IconButton(
constraints: const BoxConstraints(),
padding: EdgeInsets.zero,
icon: Image.asset("assets/miscellaneous/Edit.png", height: 15, width: 15),
onPressed: () {
showDialog(
context: context,
builder: (context) => UpdateEndorsementDialog(
item: item,
userId: userId,
managerId: managerId,
onSubmit: (val) => refresh(),
),
);
},
),
const SizedBox(width: 12),
InkWell(
onTap: () => apiService.downloadFile(
apiUrl: 'api/endorsement/downloadEndorsementCompletionFile?id=$Id',
apiId: Id,
localFile: null,
fileName: fileName,
),
child: Container(
padding: const EdgeInsets.all(4),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(4),
color: Colors.green,
),
// onPressed: () {
// showDialog(
// context: context,
// builder: (context) => UpdateEndorsementDialog(
// item: item, // Passing the whole row map
// userId: userId,
// onSubmit: (val) => refresh(),
// ),
// );
// },
onPressed: () {
// Ensure we are using the correct context
showDialog(
context: context,
barrierDismissible: true, // Allows clicking outside to close
builder: (BuildContext dialogContext) {
return UpdateEndorsementDialog(
item: item,
userId: userId,
managerId: managerId,
onSubmit: (val) => refresh(),
);
},
);
},
splashRadius: 28,
hoverColor: Colors.black12,
padding: const EdgeInsets.all(8),
constraints: const BoxConstraints(),
child: const Icon(Icons.download, size: 14, color: Colors.white),
),
),
],
)
: Row(
children: [
Image.asset(
"assets/miscellaneous/Edit_muted.png",
height: 12,
width: 15,
),
],
),
: const Text('-'),
),
// Expanded(
// flex: 1,
@ -744,24 +735,24 @@ class endosementState extends ConsumerState<endosement> {
children: [
//reg no
Text(item['reg_no'] ?? '-', style: _headerStyle),
// 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.center,
// children: _buildPopupMenuActions(context, item),
// ),
// ),
// ),
// ],
// ),
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.center,
children: _buildPopupMenuActions(context, item),
),
),
),
],
),
],
),
const Divider(color: Color(0xffD9EBE8), thickness: 0.8),

View File

@ -40,7 +40,7 @@ class BrokerState extends ConsumerState<Broker> {
late ApiService apiService;
final GlobalKey<DropdownSearchState<Map<String, dynamic>>> dropDownKey =
GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
final GlobalKey<DropdownSearchState<Map<String, dynamic>>>
dropDownKeyHandler = GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
@ -105,24 +105,70 @@ class BrokerState extends ConsumerState<Broker> {
}
void updateData() async {
if (widget.data != null) {
dynamic id = widget.data?['id'];
final data = widget.data;
if (widget.data == null) return;
final data = widget.data!;
dynamic id = data['id'];
setState(() {
selectedId = id;
controllers['name']?.text = data['name'] ?? '';
controllers['code']?.text = data['short_name'] ?? '';
controllers["is_active"]?.text = data['is_active']?.toString() ?? '';
});
if (data == null) return;
setState(() {
selectedId = id;
controllers['name']?.text = data['name'] ?? '';
controllers['code']?.text = data['short_name'] ?? '';
controllers["is_active"]?.text = data['is_active'].toString();
});
}
}
// void updateData() async {
// if (widget.data != null) {
// dynamic id = widget.data?['id'];
// final data = widget.data;
//
// if (data == null) return;
// setState(() {
// selectedId = id;
// controllers['name']?.text = data['name'] ?? '';
// controllers['code']?.text = data['short_name'] ?? '';
// controllers["is_active"]?.text = data['is_active'].toString();
// });
// }
// }
Future<void> handleSave() async {
// if (controllers['name'] != null && controllers['name'] != '') {
// return;
// }
final nameEmpty = controllers['name'] == null ||
controllers['name']!.text.trim().isEmpty;
final codeEmpty = controllers['code'] == null ||
controllers['code']!.text.trim().isEmpty;
// 🔥 Both empty
if (nameEmpty && codeEmpty) {
ToastHelper.showWarningToast(
context,
"Broker and Broker Code is required",
);
return;
}
// Broker Name only
if (nameEmpty) {
ToastHelper.showWarningToast(
context,
"Broker is required",
);
return;
}
// Broker Code only
if (codeEmpty) {
ToastHelper.showWarningToast(
context,
"Broker Code is required",
);
return;
}
if (!_formKey.currentState!.validate()) return;
setState(() {
if (_formKey.currentState!.validate()) {
@ -131,7 +177,7 @@ class BrokerState extends ConsumerState<Broker> {
print("dataSetAgent - $dataSet");
print("TYPE of is_active → ${dataSet['is_active'].runtimeType}");
print("TYPE of name → ${dataSet['name'].runtimeType}");
print("TYPE of value → ${dataSet['value'].runtimeType}");
createUserData(dataSet);
} else {
// isDisable = false;
@ -139,6 +185,28 @@ class BrokerState extends ConsumerState<Broker> {
});
}
// Future<void> handleSave() async {
// // if (controllers['name'] != null && controllers['name'] != '') {
// // return;
// // }
// if (!_formKey.currentState!.validate()) return;
// setState(() {
// if (_formKey.currentState!.validate()) {
// dataDetails();
// final dataSet = dataDetails();
// print("dataSetAgent - $dataSet");
//
// print("TYPE of is_active → ${dataSet['is_active'].runtimeType}");
// print("TYPE of name → ${dataSet['name'].runtimeType}");
// createUserData(dataSet);
// } else {
// // isDisable = false;
// }
// });
// }
void refresh() {
print('REfresj');
widget.onSubmit();

View File

@ -40,7 +40,7 @@ class EndorsementTypeState extends ConsumerState<EndorsementType> {
late ApiService apiService;
final GlobalKey<DropdownSearchState<Map<String, dynamic>>> dropDownKey =
GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
final GlobalKey<DropdownSearchState<Map<String, dynamic>>>
dropDownKeyHandler = GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
@ -118,9 +118,12 @@ class EndorsementTypeState extends ConsumerState<EndorsementType> {
}
Future<void> handleSave() async {
// if (controllers['name'] != null && controllers['name'] != '') {
// return;
// }
if (controllers['endorsement_type'] == null ||
controllers['endorsement_type']!.text.trim().isEmpty) {
ToastHelper.showWarningToast(context, "Endorsement Type is required");
return;
}
if (!_formKey.currentState!.validate()) return;
setState(() {
if (_formKey.currentState!.validate()) {
@ -129,7 +132,7 @@ class EndorsementTypeState extends ConsumerState<EndorsementType> {
print("dataSetAgent - $dataSet");
print("TYPE of is_active → ${dataSet['is_active'].runtimeType}");
print("TYPE of endorsement_type → ${dataSet['endorsement_type'].runtimeType}");
print("TYPE of value → ${dataSet['value'].runtimeType}");
createUserData(dataSet);
} else {
// isDisable = false;
@ -137,6 +140,26 @@ class EndorsementTypeState extends ConsumerState<EndorsementType> {
});
}
// Future<void> handleSave() async {
// // if (controllers['name'] != null && controllers['name'] != '') {
// // return;
// // }
// if (!_formKey.currentState!.validate()) return;
// setState(() {
// if (_formKey.currentState!.validate()) {
// dataDetails();
// final dataSet = dataDetails();
// print("dataSetAgent - $dataSet");
//
// print("TYPE of is_active → ${dataSet['is_active'].runtimeType}");
// print("TYPE of endorsement_type → ${dataSet['endorsement_type'].runtimeType}");
// createUserData(dataSet);
// } else {
// // isDisable = false;
// }
// });
// }
void refresh() {
print('REfresj');
widget.onSubmit();

View File

@ -108,6 +108,9 @@ class AgentListState extends ConsumerState<AgentList> {
(item['agent_code'] ?? '-').toLowerCase().contains(
query.toLowerCase(),
) ||
(item['retention_rate'] ?? '-').toLowerCase().contains(
query.toLowerCase(),
) ||
(isActiveStatus.contains(query.toLowerCase()));
}).toList();
});

View File

@ -798,6 +798,9 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
safeString(item['status']).toLowerCase().contains(q) ||
safeString(item['payment_mode']).toLowerCase().contains(q) ||
safeString(item['premium_amount']).toLowerCase().contains(q) ||
(q.contains('proceed') &&
item['enquiry_status']?.toLowerCase() == 'assigned' &&
item['quotation_id'] != null) ||
safeString(
_formatDate(item['created_on']),
).toLowerCase().contains(q) ||
@ -2436,6 +2439,23 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
);
}
String formatEnquiryStatus(String? status) {
if (status == null) return '-';
switch (status.toLowerCase()) {
case 'to be assigned':
return 'To Be Assigned';
case 'in progress':
return 'In Progress';
case 'assigned':
return 'Assigned';
case 'completed':
return 'Completed';
default:
return status; // fallback
}
}
// Helper: Status display container
Widget _buildStatusContainer(
Map<String, dynamic> item,

View File

@ -297,10 +297,12 @@ class policylistState extends ConsumerState<policylist> {
Future<void> fetchPolicyExcelReport() async {
final String fromDate = controllers['startDate']!.text; // "11-01-2025"
final String toDate = controllers['endDate']!.text; // "20-01-2025"
final String searchValue = _searchStaffController.text;
final response = await apiService.generatePolicyExcel(
managerId,
fromDate,
toDate,
searchValue,
);
// Map your controllers and IDs to the API parameters
// final String fromDate = controllers['startDate']!.text; // "11-01-2025"

View File

@ -341,9 +341,9 @@ class _DateFilterRowState extends ConsumerState<DateFilterRow> {
// {'id': 3, 'status': 'Proposal Accepted'},
// {'id': 4, 'status': 'Proposal Rejected'},
// {'id': 5, 'status': 'Policy Created'},
{'id': 1, 'status': 'To be assigned'},
{'id': 1, 'status': 'To be Assigned'},
{'id': 2, 'status': 'Assigned'},
{'id': 3, 'status': 'In progress'},
{'id': 3, 'status': 'In Progress'},
{'id': 4, 'status': 'Completed'},
];
Map<String, dynamic>? selectedStatusMap = statusOptions