1378 lines
44 KiB
Dart
1378 lines
44 KiB
Dart
// import 'dart:io' as html;
|
|
import 'package:http/http.dart' as http;
|
|
import 'package:dropdown_search/dropdown_search.dart';
|
|
import 'package:flutter/cupertino.dart';
|
|
import 'package:flutter/material.dart';
|
|
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
|
import 'package:go_router/go_router.dart';
|
|
import 'package:google_fonts/google_fonts.dart';
|
|
import 'package:intl/intl.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
import '../../../../core/routing/routes.dart';
|
|
|
|
import '../../../../core/services/api_service.dart';
|
|
import 'package:universal_html/html.dart' as html;
|
|
|
|
import '../../../../data/utils/Pagination.dart';
|
|
|
|
import '../../layouts/main_layout.dart';
|
|
import '../../layouts/responsive_layout.dart';
|
|
import '../../providers/manager_provider.dart';
|
|
import '../../providers/quotation_staff_proivder.dart';
|
|
import '../../providers/userRoleProvider.dart';
|
|
import '../../themes/indicators/export_btn.dart';
|
|
import '../../themes/indicators/search_field_theme.dart';
|
|
import '../../widgets/custom_Stdate_EnDate_Filter.dart';
|
|
import '../../widgets/custom_action_popup.dart';
|
|
import '../staff/assignStaff.dart';
|
|
|
|
class EnquiryListInline extends ConsumerStatefulWidget {
|
|
const EnquiryListInline({super.key});
|
|
@override
|
|
ConsumerState<EnquiryListInline> createState() => EnquiryHandlerState();
|
|
}
|
|
|
|
class EnquiryHandlerState extends ConsumerState<EnquiryListInline> {
|
|
int currentPage = 1;
|
|
int itemsPerPage = 10;
|
|
late ApiService apiService;
|
|
dynamic userId;
|
|
dynamic managerId;
|
|
dynamic dashboardKey;
|
|
dynamic SelectedStatus;
|
|
dynamic SelectedStaffId;
|
|
dynamic handlerId;
|
|
final _formKey = GlobalKey<FormState>();
|
|
|
|
// List<Map<String, dynamic>> dataVal = [];
|
|
List<Map<String, dynamic>> getStaffData = [];
|
|
List<Map<String, dynamic>> originalData = [];
|
|
List<Map<String, dynamic>> filteredData = [];
|
|
bool isLoading = false;
|
|
dynamic roleId;
|
|
|
|
Map<String, TextEditingController> controllers = {};
|
|
List<String> tabHeader = ['startDate', 'endDate'];
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
|
|
apiService = ApiService();
|
|
|
|
for (String field in tabHeader) {
|
|
controllers[field] = TextEditingController();
|
|
}
|
|
|
|
Future.microtask(() async {
|
|
final id = ref.read(managerIdProvider);
|
|
roleId = ref.read(userRoleProvider);
|
|
userId = ref.read(userIdProvider);
|
|
managerId = ref.read(managerIdProvider);
|
|
|
|
// dashboardKey = ref.read(dashboardKeyProvider);
|
|
// final dashboardStatus = ref.read(dashboardStatusProvider);
|
|
// final dashboardStaffId = ref.read(dashboardStaffIdProvider);
|
|
final prefs = await SharedPreferences.getInstance();
|
|
dashboardKey = prefs.getString('dashboardKeyProvider');
|
|
final dashboardStatus = prefs.getString('dashboardStatusProvider');
|
|
final dashboardStaffId = prefs.getString('dashboardStaffIdProvider');
|
|
// handlerId = ref.read(handlerIdProvider);
|
|
|
|
print('handlerIdENQ - $handlerId');
|
|
print("C72 => r : $roleId | mId: $id | uId: $userId !mID : $managerId ");
|
|
|
|
print('dashboardKey - $dashboardKey');
|
|
print('dashboardStatus - $dashboardStatus');
|
|
print('dashboardStaffId - $dashboardStaffId');
|
|
|
|
if (managerId != null &&
|
|
dashboardKey != null &&
|
|
dashboardStatus != null &&
|
|
dashboardStaffId != null) {
|
|
print("DASHBOARD STATus-$dashboardStatus -- $dashboardStaffId -");
|
|
SelectedStatus = dashboardStatus;
|
|
SelectedStaffId = dashboardStaffId;
|
|
getStaffList(
|
|
managerId,
|
|
roleId,
|
|
SelectedStatus: dashboardStatus,
|
|
SelectedStaffId: dashboardStaffId,
|
|
);
|
|
} else {
|
|
print('ELSE');
|
|
getStaffList(managerId, roleId);
|
|
}
|
|
});
|
|
}
|
|
|
|
void refresh() {
|
|
final id = ref.read(managerIdProvider);
|
|
final roleId = ref.read(userRoleProvider);
|
|
final userId = ref.read(userIdProvider);
|
|
|
|
print("C82 => r : $roleId | mId: $id | uId: $userId ");
|
|
if (managerId != null) {
|
|
getStaffList(managerId, roleId);
|
|
}
|
|
}
|
|
|
|
void filterDateRange() {
|
|
// print('SelectedStatus - $SelectedStatus');
|
|
// // ✅ Validate the form first
|
|
// if (!_formKey.currentState!.validate()) {
|
|
// // stop execution if validation fails
|
|
// return;
|
|
// }
|
|
//
|
|
// final fromDateText = controllers['startDate']?.text ?? '';
|
|
// final toDateText = controllers['endDate']?.text ?? '';
|
|
//
|
|
// // Optional: double-check End >= Start
|
|
// final fromDate = DateFormat('dd-MM-yyyy').parse(fromDateText);
|
|
// final toDate = DateFormat('dd-MM-yyyy').parse(toDateText);
|
|
//
|
|
// if (toDate.isBefore(fromDate)) {
|
|
// // This is already caught by the validator, but extra safety
|
|
// ScaffoldMessenger.of(context).showSnackBar(
|
|
// SnackBar(content: Text("End Date cannot be earlier than Start Date")),
|
|
// );
|
|
// return;
|
|
// }
|
|
|
|
// ✅ Call your API
|
|
getStaffList(
|
|
managerId,
|
|
roleId,
|
|
SelectedStatus: SelectedStatus ?? '',
|
|
SelectedStaffId: SelectedStaffId ?? '',
|
|
);
|
|
}
|
|
|
|
Future<void> refrshfilterDateRange() async {
|
|
// setState(() async {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
|
|
// ✅ Clear any old data
|
|
await prefs.remove('dashboardKeyProvider');
|
|
await prefs.remove('dashboardStatusProvider');
|
|
await prefs.remove('dashboardStaffIdProvider');
|
|
SelectedStatus = '';
|
|
SelectedStaffId = null;
|
|
controllers['startDate']!.clear();
|
|
controllers['endDate']!.clear();
|
|
|
|
controllers['startDate']?.text = '';
|
|
controllers['endDate']?.text = '';
|
|
// Reset the FormField validation
|
|
_formKey.currentState?.reset();
|
|
// });
|
|
getStaffList(
|
|
managerId,
|
|
roleId,
|
|
SelectedStatus: SelectedStatus ?? '',
|
|
SelectedStaffId: SelectedStaffId ?? '',
|
|
);
|
|
}
|
|
|
|
Future<void> getStaffList(
|
|
int managerId,
|
|
role, {
|
|
String fromDate = '',
|
|
String toDate = '',
|
|
String SelectedStatus = '',
|
|
String SelectedStaffId = '',
|
|
}) async {
|
|
print('A72 => Fns called => $managerId | $role');
|
|
setState(() {
|
|
isLoading = true;
|
|
});
|
|
|
|
dynamic fromDt;
|
|
dynamic toDt;
|
|
|
|
final fromDateVal = controllers['startDate']?.text ?? '';
|
|
final toDateVal = controllers['endDate']?.text ?? '';
|
|
final dateFormat = DateFormat('dd-MM-yyyy');
|
|
|
|
if (dashboardKey != 'fromDashboard' &&
|
|
fromDateVal == '' &&
|
|
toDateVal == '') {
|
|
print("ENQ LIST PAGE");
|
|
|
|
final today = DateTime.now();
|
|
fromDt = dateFormat.format(today.subtract(Duration(days: 15)));
|
|
toDt = dateFormat.format(today);
|
|
|
|
print('Enq FROM TO - $fromDt - $toDt');
|
|
} else {
|
|
fromDt = fromDateVal;
|
|
toDt = toDateVal;
|
|
}
|
|
|
|
try {
|
|
final response = await apiService.fetchEnquiryList(
|
|
managerId,
|
|
userId,
|
|
role,
|
|
fromDate: fromDt,
|
|
toDate: toDt,
|
|
selectedStatus: SelectedStatus != null ? SelectedStatus : '',
|
|
selectedStaffId: SelectedStaffId ?? '',
|
|
);
|
|
|
|
if (response['status'] == 'success') {
|
|
final data = response['data'];
|
|
final fromDate = response['from_date'] ?? '';
|
|
final toDate = response['to_date'] ?? '';
|
|
|
|
print('FromDate : $fromDate');
|
|
print('ToDate : $toDate');
|
|
|
|
setState(() {
|
|
controllers['startDate']?.text = fromDate;
|
|
controllers['endDate']?.text = toDate;
|
|
if (data is List) {
|
|
getStaffData = List<Map<String, dynamic>>.from(data);
|
|
} else if (data is Map) {
|
|
getStaffData = [Map<String, dynamic>.from(data)];
|
|
} else {
|
|
getStaffData = [];
|
|
}
|
|
originalData = getStaffData;
|
|
filteredData = List.from(originalData);
|
|
});
|
|
} else {
|
|
getStaffData = [];
|
|
originalData = [];
|
|
}
|
|
} catch (e) {
|
|
print('Exception occurred: $e');
|
|
} finally {
|
|
setState(() {
|
|
isLoading = false;
|
|
});
|
|
}
|
|
}
|
|
|
|
// Future<void> getStaffList1(
|
|
// int managerId,
|
|
// role, {
|
|
// String fromDate = '',
|
|
// String toDate = '',
|
|
// }) async {
|
|
// print('C89 => Fns called => $managerId | $role');
|
|
// setState(() {
|
|
// isLoading = true;
|
|
// });
|
|
//
|
|
// try {
|
|
// final response = await apiService.fetchPolicyList(
|
|
// managerId,
|
|
// role,
|
|
// fromDate: controllers['startDate']?.text ?? '',
|
|
// toDate: controllers['endDate']?.text ?? '',
|
|
// );
|
|
//
|
|
// print('FromDate : $fromDate');
|
|
// print('ToDate : $toDate');
|
|
//
|
|
// if (response['status'] == 'success') {
|
|
// final data = response['data'];
|
|
// print('C99 => getStaffListData => ${response['data']}');
|
|
// final fromDate = response['from_date'] ?? '';
|
|
// final toDate = response['to_date'] ?? '';
|
|
//
|
|
// print('FromDate : $fromDate');
|
|
// print('ToDate : $toDate');
|
|
// setState(() {
|
|
// controllers['startDate']?.text = fromDate;
|
|
// controllers['endDate']?.text = toDate;
|
|
//
|
|
// if (data is List) {
|
|
// // Already a list of maps
|
|
// getStaffData = List<Map<String, dynamic>>.from(data);
|
|
// } else if (data is Map) {
|
|
// // Single object, wrap in a list
|
|
// getStaffData = [Map<String, dynamic>.from(data)];
|
|
// } else {
|
|
// getStaffData = [];
|
|
// }
|
|
// // getStaffData = List<Map<String, dynamic>>.from(response['data']);
|
|
// originalData = getStaffData;
|
|
// filteredData = List.from(originalData);
|
|
// // print('originalData - $getClaimPolicies');
|
|
// });
|
|
// } else {
|
|
// getStaffData = [];
|
|
// originalData = [];
|
|
// }
|
|
// } catch (e) {
|
|
// print('Exception occurred: $e');
|
|
// } finally {
|
|
// setState(() {
|
|
// isLoading = false;
|
|
// });
|
|
// }
|
|
// }
|
|
|
|
List<dynamic> get _paginatedData {
|
|
// Sort descending by id first
|
|
final sortedData = [...filteredData]
|
|
..sort((a, b) => int.parse(b['id']) - int.parse(a['id']));
|
|
|
|
if (sortedData.isEmpty) return [];
|
|
|
|
// Ensure currentPage is valid
|
|
final maxPage = (sortedData.length / itemsPerPage).ceil();
|
|
final safePage = currentPage.clamp(1, maxPage);
|
|
|
|
final startIndex = (safePage - 1) * itemsPerPage;
|
|
final endIndex = (startIndex + itemsPerPage).clamp(0, sortedData.length);
|
|
|
|
return sortedData.sublist(startIndex, endIndex);
|
|
}
|
|
|
|
void filterData(String query) {
|
|
print("FilterDAta - $query");
|
|
setState(() {
|
|
filteredData = getStaffData.where((item) {
|
|
// final isActiveStatus = item['is_active'] == "1" ? "active" : "inactive";
|
|
|
|
return (item['agent_name'] ?? '-').toLowerCase().contains(
|
|
query.toLowerCase(),
|
|
) ||
|
|
(item['reg_no'] ?? '-').toLowerCase().contains(
|
|
query.toLowerCase(),
|
|
) ||
|
|
(item['insurer_name'] ?? '-').toLowerCase().contains(
|
|
query.toLowerCase(),
|
|
) ||
|
|
(item['assigned_to_name'] ?? '-').toLowerCase().contains(
|
|
query.toLowerCase(),
|
|
) ||
|
|
(item['insured_name'] ?? '-').toLowerCase().contains(
|
|
query.toLowerCase(),
|
|
) ||
|
|
(item['premium_amount'] ?? '-').toLowerCase().contains(
|
|
query.toLowerCase(),
|
|
) ||
|
|
(item['payment_mode'] ?? '-').toLowerCase().contains(
|
|
query.toLowerCase(),
|
|
) ||
|
|
(_formatDate(item['created_on']) ?? '-').toLowerCase().contains(
|
|
query.toLowerCase(),
|
|
) ||
|
|
(_formatDate(item['updated_on']) ?? '-').toLowerCase().contains(
|
|
query.toLowerCase(),
|
|
) ||
|
|
(item['policy_number'] ?? '-').toLowerCase().contains(
|
|
query.toLowerCase(),
|
|
) ||
|
|
(item['status'] ?? '-').toLowerCase().contains(query.toLowerCase());
|
|
}).toList();
|
|
});
|
|
}
|
|
|
|
final TextEditingController _searchStaffController = TextEditingController();
|
|
|
|
String _formatDate(String rawDate) {
|
|
try {
|
|
final dateTime = DateTime.parse(rawDate);
|
|
return DateFormat(
|
|
'dd-MM-yyyy HH:mm',
|
|
).format(dateTime); // 24-hour format
|
|
} catch (e) {
|
|
return rawDate; // fallback if parsing fails
|
|
}
|
|
}
|
|
|
|
Future<void> handleStaff(
|
|
BuildContext context,
|
|
dynamic data,
|
|
id,
|
|
regNum,
|
|
) async {
|
|
showDialog(
|
|
context: context,
|
|
builder: (ctx) => AssignStaffDialog(
|
|
enquiryPrimaryId: id,
|
|
regNum: regNum,
|
|
userId: userId,
|
|
onSubmit: (value) {
|
|
debugPrint("New assignY: $value");
|
|
refresh();
|
|
},
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<void> handleEdit(item) async {
|
|
// Navigator.pop(context);
|
|
print('EDITStaff - ${item['id']}');
|
|
|
|
final prefs = await SharedPreferences.getInstance();
|
|
|
|
await prefs.remove('enqAgentDataId');
|
|
|
|
final id = item['id'].toString();
|
|
// ✅ Save the new id
|
|
await prefs.setString('enqAgentDataId', id.toString());
|
|
ref.read(enquiryIdProvider.notifier).state = id;
|
|
|
|
context.go(AppRoutes.tabEnquiry);
|
|
}
|
|
|
|
// List<Widget> _buildPopupMenuActions(
|
|
// BuildContext context,
|
|
// dynamic data,
|
|
// id,
|
|
// regNum,
|
|
// ) {
|
|
// return [
|
|
// if (roleId == 'manager' && data['status'] == 'Awaiting Quotation') ...[
|
|
// Material(
|
|
// color: Colors.transparent,
|
|
// child: InkWell(
|
|
// onTap: () {
|
|
// Navigator.pop(context);
|
|
// showDialog(
|
|
// context: context,
|
|
// builder: (ctx) => AssignStaffDialog(
|
|
// enquiryPrimaryId: id,
|
|
// regNum: regNum,
|
|
// userId: 1,
|
|
// onSubmit: (value) {
|
|
// debugPrint("New assignY: $value");
|
|
// refresh();
|
|
// },
|
|
// ),
|
|
// );
|
|
// },
|
|
// hoverColor: Color(0xFFE3F1F0),
|
|
// splashColor: Color(0xFFE3F1F0),
|
|
// borderRadius: BorderRadius.circular(6),
|
|
// child: Padding(
|
|
// padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
|
// child: Row(
|
|
// // mainAxisSize: MainAxisSize.min,
|
|
// children: [
|
|
// Image.asset(
|
|
// "assets/miscellaneous/image_3.png",
|
|
// // height: 45,
|
|
// // width: 15,
|
|
// ),
|
|
//
|
|
// SizedBox(width: 10),
|
|
// Text('Assign Staff'),
|
|
// ],
|
|
// ),
|
|
// ),
|
|
// ),
|
|
// ),
|
|
// ],
|
|
//
|
|
// Material(
|
|
// color: Colors.transparent,
|
|
// child: InkWell(
|
|
// onTap: () async {
|
|
// Navigator.pop(context);
|
|
// final prefs = await SharedPreferences.getInstance();
|
|
//
|
|
// // ✅ Remove old value (if any)
|
|
// await prefs.remove('enqStaffDataId');
|
|
//
|
|
// // ✅ Save the new id
|
|
// await prefs.setString('enqStaffDataId', id.toString());
|
|
//
|
|
// // Read it back if needed
|
|
// // final dynamic? enqStaffDataId = prefs.getString('enqStaffDataId');
|
|
//
|
|
// // ✅ Update provider too
|
|
// // ref.read(quotationStaffIdProvider.notifier).state = enqStaffDataId;
|
|
// ref.read(quotationStaffIdProvider.notifier).state = id;
|
|
//
|
|
// context.go(AppRoutes.quotation);
|
|
// },
|
|
// hoverColor: Color(0xFFE3F1F0),
|
|
// splashColor: Color(0xFFE3F1F0),
|
|
// borderRadius: BorderRadius.circular(6),
|
|
// child: Padding(
|
|
// padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
|
// child: Row(
|
|
// // mainAxisSize: MainAxisSize.min,
|
|
// children: [
|
|
// Image.asset(
|
|
// "assets/miscellaneous/image_1.png",
|
|
// height: 15,
|
|
// width: 15,
|
|
// ),
|
|
//
|
|
// const SizedBox(width: 10),
|
|
// ((data['status'] == 'Policy Created') ||
|
|
// (data['status'] == 'Quotation Accepted'))
|
|
// ? const Text('View Quotation')
|
|
// : const Text('Create Quotation'),
|
|
// ],
|
|
// ),
|
|
// ),
|
|
// ),
|
|
// ),
|
|
//
|
|
// if (data['status'] == 'Quotation Accepted' ||
|
|
// data['status'] == 'Policy Created')
|
|
// Material(
|
|
// color: Colors.transparent,
|
|
// child: InkWell(
|
|
// onTap: () async {
|
|
// Navigator.pop(context);
|
|
//
|
|
// final prefs = await SharedPreferences.getInstance();
|
|
//
|
|
// // ✅ Remove old value (if any)
|
|
// await prefs.remove('enqStaffDataId');
|
|
//
|
|
// // ✅ Save the new id
|
|
// await prefs.setString('enqStaffDataId', id.toString());
|
|
//
|
|
// // ✅ Update provider too
|
|
//
|
|
// ref.read(quotationStaffIdProvider.notifier).state = id;
|
|
// context.go(AppRoutes.policy);
|
|
// },
|
|
// hoverColor: Color(0xFFE3F1F0),
|
|
// splashColor: Color(0xFFE3F1F0),
|
|
// borderRadius: BorderRadius.circular(6),
|
|
// child: Padding(
|
|
// padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
|
// child: Row(
|
|
// // mainAxisSize: MainAxisSize.min,
|
|
// children: [
|
|
// Image.asset(
|
|
// "assets/miscellaneous/image_2.png",
|
|
// height: 15,
|
|
// width: 15,
|
|
// ),
|
|
//
|
|
// const SizedBox(width: 10),
|
|
// data['status'] == 'Policy Created'
|
|
// ? Text('View Policy')
|
|
// : Text('Create Policy'),
|
|
// ],
|
|
// ),
|
|
// ),
|
|
// ),
|
|
// ),
|
|
// ];
|
|
// }
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return MainLayout(
|
|
title: "Enquiries",
|
|
body: SelectionArea(
|
|
child: Container(
|
|
// color: Colors.yellow.shade50,
|
|
width: MediaQuery.of(context).size.width,
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
children: [
|
|
Container(
|
|
height: 30,
|
|
width: MediaQuery.of(context).size.width,
|
|
child: GestureDetector(
|
|
onTap: () {
|
|
context.go(AppRoutes.dashboard);
|
|
},
|
|
child: Row(
|
|
crossAxisAlignment: CrossAxisAlignment.center,
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
children: [
|
|
Tooltip(
|
|
message: 'Back',
|
|
child: IconButton(
|
|
icon: const Icon(Icons.arrow_left_sharp, size: 25),
|
|
onPressed: () async {
|
|
context.go(AppRoutes.dashboard);
|
|
final prefs = await SharedPreferences.getInstance();
|
|
await prefs.remove('dashboardKeyProvider');
|
|
await prefs.remove('dashboardStatusProvider');
|
|
await prefs.remove('dashboardStaffIdProvider');
|
|
},
|
|
splashRadius: 18,
|
|
padding: const EdgeInsets.all(4),
|
|
hoverColor: Colors.black12,
|
|
constraints: const BoxConstraints(),
|
|
),
|
|
),
|
|
const SizedBox(width: 5), // spacing between icon and text
|
|
Text(
|
|
"Enquiries",
|
|
style: TextStyle(
|
|
fontSize: 18,
|
|
fontWeight: FontWeight.w600,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
SizedBox(height: 5),
|
|
ResponsiveLayout.isMobile(context)
|
|
? Container(
|
|
height: MediaQuery.of(context).size.height * 0.69,
|
|
child: SingleChildScrollView(
|
|
child: Padding(
|
|
padding: EdgeInsets.all(8),
|
|
child: _buildContent(context),
|
|
),
|
|
),
|
|
)
|
|
: Expanded(
|
|
child: Container(
|
|
width: MediaQuery.of(context).size.width,
|
|
padding: EdgeInsets.all(8.0),
|
|
child: _buildContent(context),
|
|
),
|
|
),
|
|
|
|
// Expanded(
|
|
// child: Container(
|
|
// // color: Colors.green,
|
|
// // color: Colors.green.shade50,
|
|
// width: MediaQuery.of(context).size.width,
|
|
//
|
|
// padding: EdgeInsets.all(8.0),
|
|
// child:
|
|
// ),
|
|
// ),
|
|
Container(
|
|
// height: 20,
|
|
width: MediaQuery.of(context).size.width,
|
|
// color: Colors.green.shade50,
|
|
child: PaginationControls(
|
|
currentPage: currentPage,
|
|
itemsPerPage: itemsPerPage,
|
|
// totalItems: dataVal.length,
|
|
totalItems: filteredData.length,
|
|
// activeColor: layoutColor, // your theme color
|
|
onPageChanged: (page) {
|
|
setState(() {
|
|
currentPage = page;
|
|
});
|
|
},
|
|
onItemsPerPageChanged: (items) {
|
|
setState(() {
|
|
itemsPerPage = items;
|
|
currentPage = 1;
|
|
});
|
|
},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),),
|
|
);
|
|
}
|
|
|
|
Widget _buildContent(BuildContext context) {
|
|
return Column(
|
|
children: [
|
|
if (ResponsiveLayout.isMobile(context)) ...[
|
|
Container(
|
|
padding: EdgeInsets.all(8.0),
|
|
color: Color(0xffD9EBE8),
|
|
child: DateFilterRow(
|
|
key: ValueKey(SelectedStatus ?? ''),
|
|
onFilterStaff: (val) {
|
|
print('Selected Filterd STAFF Id - $val');
|
|
SelectedStaffId = val;
|
|
},
|
|
selectedStaffId: SelectedStaffId,
|
|
role: roleId,
|
|
id: userId,
|
|
selectedStatusVal: SelectedStatus,
|
|
startController: controllers['startDate']!,
|
|
endController: controllers['endDate']!,
|
|
formKey: _formKey,
|
|
isMobile: ResponsiveLayout.isMobile(context),
|
|
onStatusChanged: (val) {
|
|
SelectedStatus = val; // update parent
|
|
},
|
|
|
|
onFilter: () {
|
|
// call your filter logic
|
|
filterDateRange();
|
|
},
|
|
onRefresh: () {
|
|
// call your refresh logic
|
|
refrshfilterDateRange();
|
|
},
|
|
),
|
|
),
|
|
],
|
|
|
|
Container(
|
|
// height: 40,
|
|
// color: Colors.pink,
|
|
child: Row(
|
|
crossAxisAlignment: CrossAxisAlignment.end,
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
children: [
|
|
if (!ResponsiveLayout.isMobile(context)) ...[
|
|
DateFilterRow(
|
|
key: ValueKey(SelectedStatus ?? ''),
|
|
role: roleId,
|
|
id: userId,
|
|
selectedStatusVal: SelectedStatus,
|
|
onFilterStaff: (val) {
|
|
print('Selected Filterd STAFF Id - $val');
|
|
SelectedStaffId = val;
|
|
},
|
|
selectedStaffId: SelectedStaffId,
|
|
startController: controllers['startDate']!,
|
|
endController: controllers['endDate']!,
|
|
onStatusChanged: (val) {
|
|
SelectedStatus = val; // update parent
|
|
},
|
|
formKey: _formKey,
|
|
isMobile: ResponsiveLayout.isMobile(context),
|
|
onFilter: () {
|
|
// call your filter logic
|
|
filterDateRange();
|
|
},
|
|
onRefresh: () {
|
|
// call your refresh logic
|
|
refrshfilterDateRange();
|
|
},
|
|
),
|
|
|
|
Spacer(),
|
|
],
|
|
|
|
ThemedSearchField(
|
|
hintText: 'Search',
|
|
backgroundColor: Color(0xFFF6F8F8),
|
|
onChanged: filterData,
|
|
controller: _searchStaffController,
|
|
txtwidth: ResponsiveLayout.isMobile(context)
|
|
? MediaQuery.of(context).size.width * 0.7
|
|
: MediaQuery.of(context).size.width * 0.13,
|
|
),
|
|
|
|
ResponsiveLayout.isMobile(context)
|
|
? Spacer()
|
|
: SizedBox(width: 10),
|
|
|
|
ExportBtn(
|
|
sheetName: "Enquiry",
|
|
fileName: "Enquiry_list",
|
|
data: filteredData,
|
|
txt: !ResponsiveLayout.isMobile(context) ? true : false,
|
|
displayHeaders: [
|
|
"Received Date & Time",
|
|
"Partner",
|
|
"Assigned To",
|
|
"Insurer",
|
|
"Vehicle.No.",
|
|
"Insured Name",
|
|
"Assigned Date & Time",
|
|
"Premium",
|
|
"Payment Mode",
|
|
"Policy Number",
|
|
"Status",
|
|
],
|
|
keys: [
|
|
"created_on",
|
|
"agent_name",
|
|
"assigned_to_name",
|
|
"insurer_name",
|
|
"reg_no",
|
|
"insured_name",
|
|
"updated_on",
|
|
"premium_amount",
|
|
"payment_mode",
|
|
"policy_number",
|
|
"status",
|
|
],
|
|
),
|
|
SizedBox(width: 10),
|
|
GestureDetector(
|
|
onTap: () async {
|
|
final prefs = await SharedPreferences.getInstance();
|
|
|
|
await prefs.remove('enqAgentDataId');
|
|
ref.read(enquiryIdProvider.notifier).state = null;
|
|
context.go(AppRoutes.tabEnquiry);
|
|
// 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),
|
|
Text(
|
|
'Raise Enquiry',
|
|
style: GoogleFonts.inter(
|
|
color: Colors.white,
|
|
fontWeight: FontWeight.w600,
|
|
fontSize: 14,
|
|
),
|
|
),
|
|
],
|
|
],
|
|
),
|
|
),
|
|
),
|
|
// 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),
|
|
if (!ResponsiveLayout.isMobile(context))
|
|
Container(
|
|
decoration: BoxDecoration(
|
|
color: Color(0xFFEDF6F5),
|
|
borderRadius: BorderRadius.circular(6),
|
|
),
|
|
padding: const EdgeInsets.symmetric(vertical: 12, horizontal: 16),
|
|
child: const Row(
|
|
children: [
|
|
Expanded(
|
|
flex: 2,
|
|
child: Text('Received Date ', style: _headerStyle),
|
|
),
|
|
|
|
Expanded(flex: 2, child: Text('Partner ', style: _headerStyle)),
|
|
Expanded(
|
|
flex: 2,
|
|
child: Text('Assigned To ', style: _headerStyle),
|
|
),
|
|
Expanded(flex: 3, child: Text('Insurer ', style: _headerStyle)),
|
|
|
|
Expanded(
|
|
flex: 2,
|
|
child: Text('Vehicle.No ', style: _headerStyle),
|
|
),
|
|
|
|
// Expanded(
|
|
// flex: 2,
|
|
// // child: Padding(
|
|
// // padding: EdgeInsets.only(left: 8.0),
|
|
// child: Text('Insured Name ', style: _headerStyle),
|
|
// // ),
|
|
// ),
|
|
Expanded(
|
|
flex: 2,
|
|
child: Text('Assigned Date ', style: _headerStyle),
|
|
),
|
|
Expanded(flex: 2, child: Text('Premium ', style: _headerStyle)),
|
|
Expanded(
|
|
flex: 2,
|
|
child: Text('Payment Mode ', style: _headerStyle),
|
|
),
|
|
Expanded(
|
|
flex: 2,
|
|
child: Text('Policy Number ', style: _headerStyle),
|
|
),
|
|
|
|
Expanded(flex: 2, child: Text('Status ', style: _headerStyle)),
|
|
Expanded(flex: 1, child: Text('Action', style: _headerStyle)),
|
|
],
|
|
),
|
|
),
|
|
ResponsiveLayout.isMobile(context)
|
|
? _buildDataTable(context)
|
|
: Expanded(child: _buildDataTable(context)),
|
|
],
|
|
);
|
|
}
|
|
|
|
Widget _buildDataTable(BuildContext context) {
|
|
if (filteredData.isEmpty) {
|
|
return const SizedBox(
|
|
height: 50,
|
|
child: Center(child: Text('No available data')),
|
|
);
|
|
}
|
|
|
|
final sortedData = [..._paginatedData];
|
|
|
|
if (ResponsiveLayout.isMobile(context)) {
|
|
// Use Column instead of ListView
|
|
return Column(
|
|
children: List.generate(sortedData.length, (index) {
|
|
final startIndex = (currentPage - 1) * itemsPerPage;
|
|
final item = sortedData[index];
|
|
final sno = startIndex + index;
|
|
return _buildDataCard(item, sno);
|
|
}),
|
|
);
|
|
}
|
|
|
|
// Desktop: keep ListView.builder
|
|
return ListView.builder(
|
|
itemCount: sortedData.length + 1,
|
|
itemBuilder: (context, index) {
|
|
if (index == 0) return _buildHeader();
|
|
final startIndex = (currentPage - 1) * itemsPerPage;
|
|
final item = sortedData[index - 1];
|
|
final sno = startIndex + index;
|
|
return _buildDataRow(item, sno);
|
|
},
|
|
);
|
|
}
|
|
|
|
// Widget _buildDataTable(BuildContext context) {
|
|
// if (filteredData.isEmpty) {
|
|
// return const SizedBox(
|
|
// height: 50,
|
|
// child: Center(child: Text('No available data')),
|
|
// );
|
|
// }
|
|
//
|
|
// final sortedData = [..._paginatedData];
|
|
// return ListView.builder(
|
|
// itemCount: ResponsiveLayout.isMobile(context)
|
|
// ? sortedData
|
|
// .length // only cards for mobile
|
|
// : sortedData.length + 1, // +1 for header in desktop
|
|
// itemBuilder: (context, index) {
|
|
// if (!ResponsiveLayout.isMobile(context) && index == 0) {
|
|
// return _buildHeader();
|
|
// }
|
|
//
|
|
// final startIndex = (currentPage - 1) * itemsPerPage;
|
|
// final item =
|
|
// sortedData[index - (ResponsiveLayout.isMobile(context) ? 0 : 1)];
|
|
// final sno = startIndex + index;
|
|
//
|
|
// return !ResponsiveLayout.isMobile(context)
|
|
// ? _buildDataRow(item, sno)
|
|
// : _buildDataCard(item, sno);
|
|
// },
|
|
// );
|
|
// }
|
|
|
|
Widget _buildHeader() {
|
|
return SizedBox.shrink();
|
|
}
|
|
|
|
Widget _buildDataRow(Map<String, dynamic> item, sno) {
|
|
return Container(
|
|
padding: const EdgeInsets.symmetric(vertical: 10, horizontal: 16),
|
|
// margin: const EdgeInsets.only(top: 10),
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
// color: Color(0xFFE0F7F9),
|
|
border: const Border(
|
|
bottom: BorderSide(color: Color(0xFFEAEAEA), width: 1),
|
|
),
|
|
borderRadius: BorderRadius.circular(8),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
Expanded(
|
|
flex: 2,
|
|
child: Text(
|
|
_formatDate(item['created_on']) ?? '-',
|
|
style: _dataBold,
|
|
softWrap: true,
|
|
maxLines: 3,
|
|
),
|
|
),
|
|
|
|
Expanded(
|
|
flex: 2,
|
|
child: Text(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: 2,
|
|
child: Column(
|
|
mainAxisAlignment: MainAxisAlignment.start,
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(item['reg_no'] ?? '-', style: _dataBold),
|
|
Text(item['insured_name'] ?? '-', style: _dataBoldsmall),
|
|
],
|
|
),
|
|
),
|
|
|
|
// Expanded(
|
|
// flex: 2,
|
|
//
|
|
// child: Text(
|
|
// item['insured_name'] ?? '-',
|
|
// style: _dataBold,
|
|
// softWrap: true,
|
|
// maxLines: 3,
|
|
// ),
|
|
// ),
|
|
Expanded(
|
|
flex: 2,
|
|
child: Text(
|
|
_formatDate(item['updated_on']) ?? '-',
|
|
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(
|
|
flex: 2,
|
|
child: Text(item['status'] ?? '-', style: _dataBold),
|
|
),
|
|
|
|
Expanded(
|
|
flex: 1,
|
|
child: Row(
|
|
children: [
|
|
if (item['status'] == 'Awaiting Proposal')
|
|
Tooltip(
|
|
message: "Assign Staff",
|
|
child: IconButton(
|
|
icon: Icon(Icons.assignment_ind_outlined, size: 15),
|
|
onPressed: () {
|
|
handleStaff(context, item, item['id'], item['reg_no']);
|
|
},
|
|
splashRadius: 5,
|
|
hoverColor: Colors.black12,
|
|
padding: const EdgeInsets.all(4),
|
|
constraints: const BoxConstraints(),
|
|
),
|
|
),
|
|
|
|
Tooltip(
|
|
message: 'Edit',
|
|
child: IconButton(
|
|
icon: Image.asset(
|
|
"assets/miscellaneous/Edit.png",
|
|
height: 12,
|
|
width: 12,
|
|
),
|
|
onPressed: () {
|
|
handleEdit(item);
|
|
},
|
|
splashRadius: 5,
|
|
hoverColor: Colors.black12,
|
|
padding: const EdgeInsets.all(4),
|
|
constraints: const BoxConstraints(),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
Widget _buildDataCard(Map<String, dynamic> item, int sno) {
|
|
return Container(
|
|
margin: const EdgeInsets.symmetric(vertical: 6, horizontal: 8),
|
|
padding: const EdgeInsets.all(12),
|
|
decoration: BoxDecoration(
|
|
color: const Color(0xFFF6FEFD),
|
|
borderRadius: BorderRadius.circular(8.0),
|
|
border: Border.all(color: const Color(0xffD9EBE8)),
|
|
),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
/// Top row: Reg.No + Action menu
|
|
Row(
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
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,
|
|
// children: _buildPopupMenuActions(
|
|
// context,
|
|
// item,
|
|
// item['id'],
|
|
// item['reg_no'],
|
|
// ),
|
|
// ),
|
|
// ),
|
|
// ),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
const Divider(color: Color(0xffD9EBE8), thickness: 0.8),
|
|
|
|
/// Company + Status
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
const Text("Company", style: _cardheaderStyle),
|
|
Text(item['insurer_name'] ?? '-', style: _cardBodyStyle),
|
|
],
|
|
),
|
|
),
|
|
const SizedBox(width: 5),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
const Text("Status", style: _cardheaderStyle),
|
|
Text(item['status'] ?? '-', style: _cardBodyStyle),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 15),
|
|
|
|
/// Agents + Assigned To
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
const Text("Partner", style: _cardheaderStyle),
|
|
Text(item['agent_name'] ?? '-', style: _cardBodyStyle),
|
|
],
|
|
),
|
|
),
|
|
const SizedBox(width: 5),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
const Text("Assigned To", style: _cardheaderStyle),
|
|
Text(
|
|
item['assigned_to_name'] ?? '-',
|
|
style: _cardBodyStyle,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 15),
|
|
|
|
/// Insured Name + Premium
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
const Text("Insured Name", style: _cardheaderStyle),
|
|
Text(item['insured_name'] ?? '-', style: _cardBodyStyle),
|
|
],
|
|
),
|
|
),
|
|
const SizedBox(width: 5),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
const Text("Premium", style: _cardheaderStyle),
|
|
Text(item['premium_amount'] ?? '-', style: _cardBodyStyle),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 15),
|
|
|
|
/// Payment Mode + Policy Number
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
const Text("Payment Mode", style: _cardheaderStyle),
|
|
Text(item['payment_mode'] ?? '-', style: _cardBodyStyle),
|
|
],
|
|
),
|
|
),
|
|
const SizedBox(width: 5),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
const Text("Policy Number", style: _cardheaderStyle),
|
|
Text(item['policy_number'] ?? '-', style: _cardBodyStyle),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
const SizedBox(height: 15),
|
|
|
|
/// Date + Remarks
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
const Text("Date", style: _cardheaderStyle),
|
|
Text(
|
|
_formatDate(item['updated_on']) ?? '-',
|
|
style: _cardBodyStyle,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
const SizedBox(width: 5),
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
const Text("Remarks", style: _cardheaderStyle),
|
|
Text(
|
|
item['remarks'] ?? '-',
|
|
style: _cardBodyStyle,
|
|
maxLines: 3,
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
],
|
|
),
|
|
);
|
|
}
|
|
|
|
static final _dataBold = TextStyle(
|
|
fontSize: 14,
|
|
|
|
fontWeight: FontWeight.w400,
|
|
color: Color(0xFF000000),
|
|
);
|
|
static final _dataBoldsmall = TextStyle(
|
|
fontSize: 12,
|
|
|
|
fontWeight: FontWeight.w400,
|
|
color: Color(0xFF000000),
|
|
);
|
|
|
|
static final _dataSub = TextStyle(
|
|
fontSize: 10,
|
|
fontWeight: FontWeight.w300,
|
|
color: Color(0xFF585757),
|
|
);
|
|
|
|
static const _headerStyle = TextStyle(
|
|
color: Colors.black,
|
|
fontWeight: FontWeight.bold,
|
|
);
|
|
static const _cardheaderStyle = TextStyle(
|
|
color: Colors.black,
|
|
fontWeight: FontWeight.w600,
|
|
fontSize: 12,
|
|
);
|
|
|
|
static const _cardBodyStyle = TextStyle(
|
|
color: Color(0xFF545454),
|
|
fontWeight: FontWeight.w400,
|
|
fontSize: 12,
|
|
);
|
|
}
|