Export_header
This commit is contained in:
parent
6c1fdb1c10
commit
626b09e3c9
@ -571,15 +571,35 @@ class EnquiryListState extends ConsumerState<EnquiryList> {
|
||||
fileName: "enquiry_list",
|
||||
data: filteredData,
|
||||
txt: !ResponsiveLayout.isMobile(context) ? true : false,
|
||||
headers: [
|
||||
"id",
|
||||
|
||||
// headers: [],
|
||||
displayHeaders: [
|
||||
"S.No.",
|
||||
"Received Date & Time",
|
||||
"Vehicle.No.",
|
||||
"Insurer",
|
||||
"Updated Date",
|
||||
"Status",
|
||||
"Remarks",
|
||||
],
|
||||
keys: [
|
||||
"sno", // handled internally as i + 1
|
||||
"created_on",
|
||||
"updated_on",
|
||||
"reg_no",
|
||||
"insurer_name",
|
||||
"updated_on",
|
||||
"status",
|
||||
"remarks",
|
||||
],
|
||||
// headers: [
|
||||
// "id",
|
||||
// "created_on",
|
||||
// "updated_on",
|
||||
// "reg_no",
|
||||
// "insurer_name",
|
||||
// "status",
|
||||
// "remarks",
|
||||
// ],
|
||||
),
|
||||
|
||||
SizedBox(width: 10),
|
||||
|
||||
@ -255,7 +255,18 @@ class claimListState extends ConsumerState<claimList> {
|
||||
txt: !ResponsiveLayout.isMobile(context)
|
||||
? true
|
||||
: false,
|
||||
headers: [
|
||||
displayHeaders: [
|
||||
"S.No.",
|
||||
"Vehicle.No.",
|
||||
"Insurer",
|
||||
"Policy No.",
|
||||
"Policy Expiry Date",
|
||||
"Claim Type",
|
||||
"Claim No.",
|
||||
"Status",
|
||||
],
|
||||
keys: [
|
||||
"sno", // handled internally as i + 1
|
||||
"reg_no",
|
||||
"insurer_name",
|
||||
"policy_no",
|
||||
|
||||
@ -252,7 +252,16 @@ class endosementState extends ConsumerState<endosement> {
|
||||
txt: !ResponsiveLayout.isMobile(context)
|
||||
? true
|
||||
: false,
|
||||
headers: [
|
||||
displayHeaders: [
|
||||
"S.No.",
|
||||
"Vehicle.No.",
|
||||
"Insurer",
|
||||
"Policy No.",
|
||||
"Endorsement Type",
|
||||
"Endorsement No.",
|
||||
],
|
||||
keys: [
|
||||
"sno", // handled internally as i + 1
|
||||
"reg_no",
|
||||
"insurer_name",
|
||||
"policy_number",
|
||||
|
||||
@ -409,7 +409,12 @@ class AttendanceAllDetailsState extends ConsumerState<AttendanceAllDetails> {
|
||||
fileName: "staff_attendance_list",
|
||||
data: filteredData,
|
||||
txt: !ResponsiveLayout.isMobile(context) ? true : false,
|
||||
headers: ["staff_id", "staff_name", "month", "login_count"],
|
||||
|
||||
displayHeaders: ["S.No.", "Staff Name", "Month", "Days"],
|
||||
keys: [
|
||||
"sno", // handled internally as i + 1
|
||||
"staff_name", "month", "login_count",
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@ -253,6 +253,7 @@ class IndividualAttendanceDetailsState
|
||||
return (item['date'] ?? '-').toLowerCase().contains(
|
||||
query.toLowerCase(),
|
||||
) ||
|
||||
(item['name'] ?? '-').toLowerCase().contains(query.toLowerCase()) ||
|
||||
(item['login_time'] ?? '-').toLowerCase().contains(
|
||||
query.toLowerCase(),
|
||||
) ||
|
||||
@ -321,7 +322,7 @@ class IndividualAttendanceDetailsState
|
||||
),
|
||||
const SizedBox(width: 5), // spacing between icon and text
|
||||
Text(
|
||||
"Attendance For $staffName",
|
||||
"Attendance",
|
||||
style: GoogleFonts.inter(
|
||||
fontSize: ResponsiveLayout.isMobile(context) ? 14 : 18,
|
||||
fontWeight: FontWeight.w600,
|
||||
@ -416,8 +417,17 @@ class IndividualAttendanceDetailsState
|
||||
fileName: "staff_individual_attendance_list",
|
||||
data: filteredData,
|
||||
txt: !ResponsiveLayout.isMobile(context) ? true : false,
|
||||
headers: [
|
||||
"id",
|
||||
displayHeaders: [
|
||||
"S.No.",
|
||||
"Name",
|
||||
"Date",
|
||||
"Login",
|
||||
"Logout",
|
||||
"Number Of Hours",
|
||||
],
|
||||
keys: [
|
||||
"sno", // handled internally as i + 1
|
||||
"name",
|
||||
"date",
|
||||
"login_time",
|
||||
"logout_time",
|
||||
@ -438,6 +448,7 @@ class IndividualAttendanceDetailsState
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(flex: 1, child: Text('S.No.', style: _headerStyle)),
|
||||
Expanded(flex: 2, child: Text('Name', style: _headerStyle)),
|
||||
Expanded(flex: 2, child: Text('Date', style: _headerStyle)),
|
||||
|
||||
Expanded(flex: 2, child: Text('Login', style: _headerStyle)),
|
||||
@ -502,6 +513,7 @@ class IndividualAttendanceDetailsState
|
||||
child: Row(
|
||||
children: [
|
||||
Expanded(flex: 1, child: Text('$sno' ?? '-', style: _dataBold)),
|
||||
Expanded(flex: 2, child: Text(item['name'] ?? '-', style: _dataBold)),
|
||||
Expanded(flex: 2, child: Text(item['date'] ?? '-', style: _dataBold)),
|
||||
|
||||
Expanded(
|
||||
|
||||
@ -528,6 +528,9 @@ class AgentState extends ConsumerState<Agent> {
|
||||
SizedBox(width: 10),
|
||||
ThemedFormField(
|
||||
controller: controllers['code']!,
|
||||
inputFormatters: [
|
||||
FilteringTextInputFormatter.allow(RegExp(r'[a-zA-Z0-9]')),
|
||||
],
|
||||
validator: (value) => Validators.requiredField(value, "id"),
|
||||
txtwidth: MediaQuery.of(context).size.width * 0.26,
|
||||
),
|
||||
|
||||
@ -280,12 +280,21 @@ class AgentListState extends ConsumerState<AgentList> {
|
||||
? true
|
||||
: false,
|
||||
data: filteredData,
|
||||
headers: [
|
||||
"id",
|
||||
displayHeaders: [
|
||||
'S.No.',
|
||||
'Partner Name',
|
||||
'Email',
|
||||
'Phone Number',
|
||||
'Id',
|
||||
'Address',
|
||||
'Status',
|
||||
],
|
||||
keys: [
|
||||
"sno", // handled internally as i + 1
|
||||
"name",
|
||||
"agent_code",
|
||||
"email",
|
||||
"mobile",
|
||||
"agent_code",
|
||||
"address",
|
||||
"is_active",
|
||||
],
|
||||
|
||||
@ -255,12 +255,20 @@ class StaffListState extends ConsumerState<StaffList> {
|
||||
? true
|
||||
: false,
|
||||
data: filteredData,
|
||||
headers: [
|
||||
"id",
|
||||
displayHeaders: [
|
||||
'S.No.',
|
||||
'Staff Name',
|
||||
'Role',
|
||||
'Email',
|
||||
'Phone Number',
|
||||
'Status',
|
||||
],
|
||||
keys: [
|
||||
"sno", // handled internally as i + 1
|
||||
"name",
|
||||
"role",
|
||||
"email",
|
||||
"mobile",
|
||||
"role",
|
||||
"is_active",
|
||||
],
|
||||
),
|
||||
|
||||
@ -1234,7 +1234,7 @@ class othersPendings extends StatelessWidget {
|
||||
flex: 2,
|
||||
child: Text(
|
||||
// stringFlag + " Issued",
|
||||
'Pending Enquiries',
|
||||
'Total Assigned',
|
||||
textAlign: TextAlign.center,
|
||||
style: _headerStyle,
|
||||
),
|
||||
@ -1344,69 +1344,81 @@ class othersPendings extends StatelessWidget {
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
print(
|
||||
'Awaiting Proposal : ${row['awaiting_quotation']}',
|
||||
);
|
||||
child: Material(
|
||||
color: Colors.white,
|
||||
child: InkWell(
|
||||
hoverColor: Color(0xFFEAF6F4),
|
||||
onTap: () {
|
||||
print(
|
||||
'Awaiting Proposal : ${row['awaiting_quotation']}',
|
||||
);
|
||||
|
||||
handleDashboardNavigation(
|
||||
context,
|
||||
status: "Awaiting Proposal",
|
||||
staffId: row['staff_id'] ?? '',
|
||||
role: role,
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
row['awaiting_quotation'] ?? "",
|
||||
// row['total_approval_pending'] ?? "",
|
||||
textAlign: TextAlign.center,
|
||||
style: _tableDataStyle,
|
||||
handleDashboardNavigation(
|
||||
context,
|
||||
status: "Awaiting Proposal",
|
||||
staffId: row['staff_id'] ?? '',
|
||||
role: role,
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
row['awaiting_quotation'] ?? "",
|
||||
// row['total_approval_pending'] ?? "",
|
||||
textAlign: TextAlign.center,
|
||||
style: _tableDataStyle,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: InkWell(
|
||||
onTap: () async {
|
||||
print(
|
||||
'Awaiting Approval : ${row['pending_quotation_approval']} - ${row['staff_id']}',
|
||||
);
|
||||
handleDashboardNavigation(
|
||||
context,
|
||||
status: "Proposal Created",
|
||||
staffId: row['staff_id'] ?? '',
|
||||
role: role,
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
row['pending_quotation_approval'] ?? "",
|
||||
// row['total_approval_pending'] ?? "",
|
||||
textAlign: TextAlign.center,
|
||||
style: _tableDataStyle,
|
||||
child: Material(
|
||||
color: Colors.white,
|
||||
child: InkWell(
|
||||
hoverColor: Color(0xFFEAF6F4),
|
||||
onTap: () async {
|
||||
print(
|
||||
'Awaiting Approval : ${row['pending_quotation_approval']} - ${row['staff_id']}',
|
||||
);
|
||||
handleDashboardNavigation(
|
||||
context,
|
||||
status: "Proposal Created",
|
||||
staffId: row['staff_id'] ?? '',
|
||||
role: role,
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
row['pending_quotation_approval'] ?? "",
|
||||
// row['total_approval_pending'] ?? "",
|
||||
textAlign: TextAlign.center,
|
||||
style: _tableDataStyle,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: InkWell(
|
||||
onTap: () {
|
||||
print(
|
||||
'Awaiting Policy : ${row['awaiting_policy']}',
|
||||
);
|
||||
child: Material(
|
||||
color: Colors.white,
|
||||
child: InkWell(
|
||||
hoverColor: Color(0xFFEAF6F4),
|
||||
onTap: () {
|
||||
print(
|
||||
'Awaiting Policy : ${row['awaiting_policy']}',
|
||||
);
|
||||
|
||||
handleDashboardNavigation(
|
||||
context,
|
||||
status: "Proposal Accepted",
|
||||
staffId: row['staff_id'] ?? '',
|
||||
role: role,
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
row['awaiting_policy'] ?? "",
|
||||
// row['total_approval_pending'] ?? "",
|
||||
textAlign: TextAlign.center,
|
||||
style: _tableDataStyle,
|
||||
handleDashboardNavigation(
|
||||
context,
|
||||
status: "Proposal Accepted",
|
||||
staffId: row['staff_id'] ?? '',
|
||||
role: role,
|
||||
);
|
||||
},
|
||||
child: Text(
|
||||
row['awaiting_policy'] ?? "",
|
||||
// row['total_approval_pending'] ?? "",
|
||||
textAlign: TextAlign.center,
|
||||
style: _tableDataStyle,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@ -764,14 +764,27 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
|
||||
fileName: "Enquiry_list",
|
||||
data: filteredData,
|
||||
txt: !ResponsiveLayout.isMobile(context) ? true : false,
|
||||
headers: [
|
||||
displayHeaders: [
|
||||
"Received Date & Time",
|
||||
"Partner",
|
||||
"Assigned To",
|
||||
"Insurer",
|
||||
"Vehicle.No.",
|
||||
"Insured Name",
|
||||
"Assigned Date & Time",
|
||||
"Premium",
|
||||
"Payment Mode",
|
||||
"Policy Number",
|
||||
"Status",
|
||||
],
|
||||
keys: [
|
||||
"created_on",
|
||||
"updated_on",
|
||||
"reg_no",
|
||||
"agent_name",
|
||||
"assigned_to_name",
|
||||
"insurer_name",
|
||||
"reg_no",
|
||||
"insured_name",
|
||||
"updated_on",
|
||||
"premium_amount",
|
||||
"payment_mode",
|
||||
"policy_number",
|
||||
@ -887,26 +900,29 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
|
||||
flex: 2,
|
||||
child: Text('Received Date', style: _headerStyle),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text('Assigned Date', style: _headerStyle),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text('Vehicle.No', 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: Padding(
|
||||
padding: EdgeInsets.only(left: 8.0),
|
||||
child: Text('Insured Name', style: _headerStyle),
|
||||
),
|
||||
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(
|
||||
@ -1023,19 +1039,7 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
|
||||
maxLines: 3,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
_formatDate(item['updated_on']) ?? '-',
|
||||
style: _dataBold,
|
||||
softWrap: true,
|
||||
maxLines: 3,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(item['reg_no'] ?? '-', style: _dataBold),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(item['agent_name'] ?? '-', style: _dataBold),
|
||||
@ -1053,6 +1057,10 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
|
||||
maxLines: 3,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(item['reg_no'] ?? '-', style: _dataBold),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
|
||||
@ -1063,6 +1071,16 @@ class EnquiryHandlerState extends ConsumerState<EnquiryHandler> {
|
||||
maxLines: 3,
|
||||
),
|
||||
),
|
||||
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
_formatDate(item['updated_on']) ?? '-',
|
||||
style: _dataBold,
|
||||
softWrap: true,
|
||||
maxLines: 3,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
|
||||
@ -827,17 +827,28 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
|
||||
fileName: "Enquiry_list",
|
||||
data: filteredData,
|
||||
txt: !ResponsiveLayout.isMobile(context) ? true : false,
|
||||
headers: [
|
||||
displayHeaders: [
|
||||
"Received Date & Time",
|
||||
"Partner",
|
||||
"Assigned To",
|
||||
"Insurer",
|
||||
"Vehicle.No.",
|
||||
"Insured Name",
|
||||
"Assigned Date & Time",
|
||||
"Status",
|
||||
],
|
||||
keys: [
|
||||
"created_on",
|
||||
"updated_on",
|
||||
"reg_no",
|
||||
"agent_name",
|
||||
"assigned_to_name",
|
||||
"insurer_name",
|
||||
"reg_no",
|
||||
"insured_name",
|
||||
"premium_amount",
|
||||
"payment_mode",
|
||||
"policy_number",
|
||||
// "assigned_to_name",
|
||||
"updated_on",
|
||||
// "premium_amount",
|
||||
// "payment_mode",
|
||||
// "policy_number",
|
||||
"status",
|
||||
],
|
||||
),
|
||||
@ -859,6 +870,10 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
|
||||
child: Text('Received Date & Time', style: _headerStyle),
|
||||
),
|
||||
Expanded(flex: 2, child: Text('Partner ', style: _headerStyle)),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text('Assigned To ', style: _headerStyle),
|
||||
),
|
||||
Expanded(flex: 4, child: Text('Insurer', style: _headerStyle)),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
@ -955,6 +970,15 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
|
||||
maxLines: 2,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
item['assigned_to_name'] ?? '-',
|
||||
style: _dataBold,
|
||||
softWrap: true,
|
||||
maxLines: 2,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 4,
|
||||
child: Text(
|
||||
@ -968,61 +992,65 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Builder(
|
||||
builder: (buttonContext) => InkWell(
|
||||
hoverColor: const Color(0xffD9EBE8),
|
||||
focusColor: const Color(0xffD9EBE8),
|
||||
splashColor: const Color(0xffD9EBE8),
|
||||
highlightColor: const Color(0xffD9EBE8),
|
||||
onTap: () async {
|
||||
// ✅ Get overlay and button position RELATIVE to InkWell
|
||||
final RenderBox button =
|
||||
buttonContext.findRenderObject() as RenderBox;
|
||||
final RenderBox overlay =
|
||||
Overlay.of(buttonContext).context.findRenderObject()
|
||||
as RenderBox;
|
||||
builder: (buttonContext) => Material(
|
||||
color: Colors.white,
|
||||
child: InkWell(
|
||||
hoverColor: Color(0xFFEAF6F4),
|
||||
// hoverColor: const Color(0xffD9EBE8),
|
||||
// focusColor: const Color(0xffD9EBE8),
|
||||
// splashColor: const Color(0xffD9EBE8),
|
||||
// highlightColor: const Color(0xffD9EBE8),
|
||||
onTap: () async {
|
||||
// ✅ Get overlay and button position RELATIVE to InkWell
|
||||
final RenderBox button =
|
||||
buttonContext.findRenderObject() as RenderBox;
|
||||
final RenderBox overlay =
|
||||
Overlay.of(buttonContext).context.findRenderObject()
|
||||
as RenderBox;
|
||||
|
||||
final Offset position = button.localToGlobal(
|
||||
Offset.zero,
|
||||
ancestor: overlay,
|
||||
);
|
||||
final Offset position = button.localToGlobal(
|
||||
Offset.zero,
|
||||
ancestor: overlay,
|
||||
);
|
||||
|
||||
await showMenu(
|
||||
context: buttonContext,
|
||||
position: RelativeRect.fromLTRB(
|
||||
position.dx,
|
||||
position.dy + button.size.height,
|
||||
overlay.size.width - position.dx,
|
||||
0,
|
||||
),
|
||||
items: [
|
||||
PopupMenuItem(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: _buildPopupDownload(
|
||||
buttonContext,
|
||||
item,
|
||||
item['id'],
|
||||
item['reg_no'],
|
||||
await showMenu(
|
||||
context: buttonContext,
|
||||
position: RelativeRect.fromLTRB(
|
||||
position.dx,
|
||||
position.dy + button.size.height,
|
||||
overlay.size.width - position.dx,
|
||||
0,
|
||||
),
|
||||
items: [
|
||||
PopupMenuItem(
|
||||
child: Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: _buildPopupDownload(
|
||||
buttonContext,
|
||||
item,
|
||||
item['id'],
|
||||
item['reg_no'],
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
],
|
||||
color: Colors.white,
|
||||
);
|
||||
},
|
||||
child: Tooltip(
|
||||
message:
|
||||
'Click and Download Enquiry Files', // what appears on hover/long press
|
||||
waitDuration: const Duration(milliseconds: 500), // optional
|
||||
showDuration: const Duration(seconds: 2), // optional
|
||||
child: Text(
|
||||
item['reg_no'] ?? '-',
|
||||
style: _dataBold,
|
||||
overflow: TextOverflow
|
||||
.ellipsis, // optional, if text might overflow
|
||||
],
|
||||
color: Colors.white,
|
||||
);
|
||||
},
|
||||
child: Tooltip(
|
||||
message:
|
||||
'Click and Download Enquiry Files', // what appears on hover/long press
|
||||
waitDuration: const Duration(milliseconds: 500), // optional
|
||||
showDuration: const Duration(seconds: 2), // optional
|
||||
child: Text(
|
||||
item['reg_no'] ?? '-',
|
||||
style: _dataBold,
|
||||
overflow: TextOverflow
|
||||
.ellipsis, // optional, if text might overflow
|
||||
),
|
||||
),
|
||||
// child: Text(item['reg_no'] ?? '-', style: _dataBold),
|
||||
),
|
||||
// child: Text(item['reg_no'] ?? '-', style: _dataBold),
|
||||
),
|
||||
),
|
||||
),
|
||||
@ -1049,32 +1077,36 @@ class EnquiryStaffState extends ConsumerState<EnquiryStaff> {
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: InkWell(
|
||||
onTap: () async {
|
||||
var status = item['status'];
|
||||
var enqId = item['id'];
|
||||
child: Material(
|
||||
color: Colors.white,
|
||||
child: InkWell(
|
||||
hoverColor: Color(0xFFEAF6F4),
|
||||
onTap: () async {
|
||||
var status = item['status'];
|
||||
var enqId = item['id'];
|
||||
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
|
||||
// ✅ Remove old value (if any)
|
||||
await prefs.remove('enqStaffDataId');
|
||||
// ✅ Remove old value (if any)
|
||||
await prefs.remove('enqStaffDataId');
|
||||
|
||||
// ✅ Save the new id
|
||||
await prefs.setString('enqStaffDataId', enqId.toString());
|
||||
ref.read(quotationStaffIdProvider.notifier).state = enqId;
|
||||
buildStatusActions(context, status, enqId);
|
||||
},
|
||||
child: Tooltip(
|
||||
message: 'Click to View or Process Enquiry', //
|
||||
waitDuration: const Duration(milliseconds: 500), // optional
|
||||
showDuration: const Duration(seconds: 2), // optional
|
||||
child: Text(
|
||||
item['status'] ?? '-',
|
||||
style: _dataBold,
|
||||
overflow: TextOverflow.ellipsis, //
|
||||
// ✅ Save the new id
|
||||
await prefs.setString('enqStaffDataId', enqId.toString());
|
||||
ref.read(quotationStaffIdProvider.notifier).state = enqId;
|
||||
buildStatusActions(context, status, enqId);
|
||||
},
|
||||
child: Tooltip(
|
||||
message: 'Click to View or Process Enquiry', //
|
||||
waitDuration: const Duration(milliseconds: 500), // optional
|
||||
showDuration: const Duration(seconds: 2), // optional
|
||||
child: Text(
|
||||
item['status'] ?? '-',
|
||||
style: _dataBold,
|
||||
overflow: TextOverflow.ellipsis, //
|
||||
),
|
||||
),
|
||||
// child: Text(item['status'] ?? '-', style: _dataBold),
|
||||
),
|
||||
// child: Text(item['status'] ?? '-', style: _dataBold),
|
||||
),
|
||||
),
|
||||
],
|
||||
|
||||
@ -588,15 +588,26 @@ class policylistState extends ConsumerState<policylist> {
|
||||
fileName: "Policy_list",
|
||||
data: filteredData,
|
||||
txt: !ResponsiveLayout.isMobile(context) ? true : false,
|
||||
headers: [
|
||||
"reg_no",
|
||||
displayHeaders: [
|
||||
"Received Date & Time",
|
||||
"Partner",
|
||||
"Assigned To",
|
||||
"Insurer",
|
||||
"Vehicle.No.",
|
||||
"Insured Name",
|
||||
"Premium",
|
||||
"Payment Mode",
|
||||
"Policy Number",
|
||||
],
|
||||
keys: [
|
||||
"updated_on",
|
||||
"agent_name",
|
||||
"assigned_to_name",
|
||||
"insurer_name",
|
||||
"reg_no",
|
||||
"insured_name",
|
||||
"premium_amount",
|
||||
"payment_mode",
|
||||
"updated_on",
|
||||
"policy_number",
|
||||
],
|
||||
),
|
||||
|
||||
@ -3,6 +3,7 @@ import 'dart:io';
|
||||
import 'package:excel/excel.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_hooks/flutter_hooks.dart';
|
||||
import 'package:nhance_partner/data/utils/toastNotification.dart';
|
||||
import 'package:open_file/open_file.dart';
|
||||
import 'package:path_provider/path_provider.dart';
|
||||
|
||||
@ -21,91 +22,171 @@ class ExportBtn extends HookWidget {
|
||||
final String sheetName;
|
||||
final String fileName;
|
||||
final List<Map<String, dynamic>> data;
|
||||
final List<String> headers; // dynamic headers
|
||||
final List<String>? displayHeaders; // dynamic headers
|
||||
// final List<String> headers; // dynamic headers
|
||||
final List<String>? keys; // dynamic headers
|
||||
final bool? txt;
|
||||
|
||||
const ExportBtn({
|
||||
super.key,
|
||||
this.txt,
|
||||
required this.sheetName,
|
||||
required this.fileName,
|
||||
required this.data,
|
||||
required this.headers,
|
||||
|
||||
// required this.headers,
|
||||
required this.displayHeaders,
|
||||
this.keys,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return GestureDetector(
|
||||
onTap: () {
|
||||
ExcelExporter.exportToExcel(
|
||||
sheetName: sheetName,
|
||||
data: data,
|
||||
headers: headers,
|
||||
fileName: fileName,
|
||||
);
|
||||
},
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF425B5B),
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
?txt!
|
||||
? Text(
|
||||
'Export',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 14,
|
||||
),
|
||||
)
|
||||
: null,
|
||||
?txt! ? SizedBox(width: 20) : null,
|
||||
Image.asset(
|
||||
"assets/miscellaneous/export.png",
|
||||
height: 25,
|
||||
width: 25,
|
||||
),
|
||||
// Icon(Icons.input_sharp, color: Colors.white),
|
||||
// Image.asset("assets/miscellaneous/export", height: 15, width: 15),
|
||||
],
|
||||
return Tooltip(
|
||||
message: 'Export File',
|
||||
child: InkWell(
|
||||
onTap: () async {
|
||||
print('TAV ExcelExporter');
|
||||
final scaffold = ScaffoldMessenger.of(context);
|
||||
try {
|
||||
await ExcelExporter.exportToExcel(
|
||||
sheetName: sheetName,
|
||||
data: data,
|
||||
displayHeaders: displayHeaders!,
|
||||
keys: keys!,
|
||||
fileName: fileName,
|
||||
);
|
||||
ToastHelper.showSuccessToast(context, 'Export finished');
|
||||
} catch (e) {
|
||||
ToastHelper.showErrorToast(context, 'Export failed: $e');
|
||||
}
|
||||
},
|
||||
// onTap: () {
|
||||
// print('TAV ExcelExporter');
|
||||
//
|
||||
// ExcelExporter.exportToExcel(
|
||||
// sheetName: sheetName,
|
||||
// data: data,
|
||||
// headers: headers,
|
||||
// fileName: fileName,
|
||||
// keys: keys!,
|
||||
// );
|
||||
// },
|
||||
child: Container(
|
||||
padding: const EdgeInsets.all(8.0),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFF425B5B),
|
||||
borderRadius: BorderRadius.circular(8.0),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
?txt!
|
||||
? Text(
|
||||
'Export',
|
||||
style: TextStyle(
|
||||
color: Colors.white,
|
||||
fontWeight: FontWeight.w600,
|
||||
fontSize: 14,
|
||||
),
|
||||
)
|
||||
: null,
|
||||
?txt! ? SizedBox(width: 20) : null,
|
||||
Image.asset(
|
||||
"assets/miscellaneous/export.png",
|
||||
height: 25,
|
||||
width: 25,
|
||||
),
|
||||
// Icon(Icons.input_sharp, color: Colors.white),
|
||||
// Image.asset("assets/miscellaneous/export", height: 15, width: 15),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
class ExcelExporter {
|
||||
/// Export to an Excel file.
|
||||
/// - [displayHeaders]: labels to show in Excel (e.g. "S.No.", "Status")
|
||||
/// - [keys]: actual field names in your data map
|
||||
static Future<void> exportToExcel({
|
||||
required String sheetName,
|
||||
required List<Map<String, dynamic>> data,
|
||||
required List<String> headers,
|
||||
required List<String> displayHeaders,
|
||||
required List<String> keys,
|
||||
required String fileName,
|
||||
}) async {
|
||||
try {
|
||||
// Create Excel
|
||||
var excel = Excel.createExcel();
|
||||
if (displayHeaders.length != keys.length) {
|
||||
throw ArgumentError('displayHeaders and keys must have same length');
|
||||
}
|
||||
|
||||
// Rename default sheet
|
||||
try {
|
||||
final excel = Excel.createExcel();
|
||||
|
||||
// Rename default sheet if needed
|
||||
if (excel.sheets.containsKey('Sheet1')) {
|
||||
excel.rename('Sheet1', sheetName);
|
||||
try {
|
||||
excel.rename('Sheet1', sheetName);
|
||||
} catch (_) {}
|
||||
}
|
||||
|
||||
// Get the sheet
|
||||
Sheet sheetObject = excel[sheetName]!;
|
||||
final sheet = excel[sheetName]!;
|
||||
|
||||
// Add headers
|
||||
sheetObject.appendRow(headers.map((h) => TextCellValue(h)).toList());
|
||||
// ✅ Add headers as CellValues
|
||||
sheet.appendRow(displayHeaders.map((h) => TextCellValue(h)).toList());
|
||||
|
||||
// ✅ Add data rows
|
||||
// for (var i = 0; i < data.length; i++) {
|
||||
// final rowMap = data[i];
|
||||
// final row = <CellValue?>[];
|
||||
//
|
||||
// for (var key in keys) {
|
||||
// dynamic value;
|
||||
// if (key == 'sno' ||
|
||||
// key.toLowerCase() == 's.no' ||
|
||||
// key.toLowerCase() == 'sno.') {
|
||||
// value = i + 1; // serial number
|
||||
// } else {
|
||||
// value = rowMap[key];
|
||||
// }
|
||||
//
|
||||
// if (value == null) {
|
||||
// row.add(TextCellValue('-'));
|
||||
// } else if (value is int) {
|
||||
// row.add(IntCellValue(value));
|
||||
// } else if (value is double) {
|
||||
// row.add(DoubleCellValue(value));
|
||||
// } else {
|
||||
// row.add(TextCellValue(value.toString()));
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// sheet.appendRow(row);
|
||||
// }
|
||||
|
||||
// ✅ Reverse the data list so latest entries come first
|
||||
final reversedData = data.reversed.toList();
|
||||
|
||||
for (var i = 0; i < reversedData.length; i++) {
|
||||
final rowMap = reversedData[i];
|
||||
final row = <CellValue?>[];
|
||||
|
||||
for (var key in keys) {
|
||||
dynamic value;
|
||||
if (key == 'sno' ||
|
||||
key.toLowerCase() == 's.no' ||
|
||||
key.toLowerCase() == 'sno.') {
|
||||
value = i + 1; // serial number (descending)
|
||||
} else if (key.toLowerCase() == 'is_active') {
|
||||
// ✅ Handle Active/Inactive display
|
||||
final rawVal = rowMap[key];
|
||||
value = (rawVal == 1 || rawVal == '1') ? 'Active' : 'Inactive';
|
||||
} else {
|
||||
value = rowMap[key];
|
||||
}
|
||||
|
||||
// Add data
|
||||
for (var rowData in data) {
|
||||
var row = <CellValue?>[];
|
||||
for (var key in headers) {
|
||||
final value = rowData[key];
|
||||
if (value == null) {
|
||||
row.add(TextCellValue('-'));
|
||||
} else if (value is int) {
|
||||
@ -116,56 +197,62 @@ class ExcelExporter {
|
||||
row.add(TextCellValue(value.toString()));
|
||||
}
|
||||
}
|
||||
sheetObject.appendRow(row);
|
||||
|
||||
sheet.appendRow(row);
|
||||
}
|
||||
|
||||
var bytes = excel.encode()!;
|
||||
final excelBytes = excel.encode();
|
||||
if (excelBytes == null) throw Exception('Failed to encode Excel file');
|
||||
|
||||
if (kIsWeb) {
|
||||
// ✅ Web: base64 download instead of Blob
|
||||
final base64Str = base64Encode(bytes);
|
||||
final dataUri = "data:application/octet-stream;base64,$base64Str";
|
||||
// Web download
|
||||
final base64Str = base64Encode(excelBytes);
|
||||
final dataUri = 'data:application/octet-stream;base64,$base64Str';
|
||||
final anchor = html.AnchorElement(href: dataUri)
|
||||
..setAttribute("download", "$fileName.xlsx")
|
||||
..setAttribute('download', '$fileName.xlsx')
|
||||
..click();
|
||||
} else {
|
||||
// Mobile/Desktop: save file
|
||||
// Mobile/Desktop save + open
|
||||
final dir = await getApplicationDocumentsDirectory();
|
||||
final file = File('${dir.path}/$fileName.xlsx');
|
||||
await file.writeAsBytes(bytes);
|
||||
final filePath = '${dir.path}/$fileName.xlsx';
|
||||
final file = File(filePath);
|
||||
await file.writeAsBytes(excelBytes, flush: true);
|
||||
await OpenFile.open(file.path);
|
||||
}
|
||||
} catch (e) {
|
||||
print("Error exporting Excel: $e");
|
||||
} catch (e, st) {
|
||||
debugPrint('❌ Excel export error: $e\n$st');
|
||||
rethrow;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// class ExcelExporter {
|
||||
// static Future<void> exportToExcel({
|
||||
// required String sheetName,
|
||||
// required List<Map<String, dynamic>> data,
|
||||
// required List<String> headers,
|
||||
// required String fileName,
|
||||
// required List<String> keys,
|
||||
// }) async {
|
||||
// try {
|
||||
// // Create Excel and delete default sheet
|
||||
// // Create Excel
|
||||
// var excel = Excel.createExcel();
|
||||
//
|
||||
// // Rename default sheet
|
||||
// if (excel.sheets.containsKey('Sheet1')) {
|
||||
// excel.delete('Sheet1');
|
||||
// excel.rename('Sheet1', sheetName);
|
||||
// }
|
||||
//
|
||||
// // Create your sheet
|
||||
// Sheet sheetObject = excel[sheetName]; // now this is the only sheet
|
||||
// // Get the sheet
|
||||
// Sheet sheetObject = excel[sheetName]!;
|
||||
//
|
||||
// // Add headers
|
||||
// sheetObject.appendRow(headers.map((h) => TextCellValue(h)).toList());
|
||||
// sheetObject.appendRow(keys.map((h) => TextCellValue(h)).toList());
|
||||
//
|
||||
// // Add data
|
||||
// for (var rowData in data) {
|
||||
// var row = <CellValue?>[];
|
||||
// for (var key in headers) {
|
||||
// for (var key in keys) {
|
||||
// final value = rowData[key];
|
||||
// if (value == null) {
|
||||
// row.add(TextCellValue('-'));
|
||||
@ -183,13 +270,12 @@ class ExcelExporter {
|
||||
// var bytes = excel.encode()!;
|
||||
//
|
||||
// if (kIsWeb) {
|
||||
// // Web: download
|
||||
// final blob = html.Blob([bytes]);
|
||||
// final url = html.Url.createObjectUrlFromBlob(blob);
|
||||
// final anchor = html.AnchorElement(href: url)
|
||||
// // ✅ Web: base64 download instead of Blob
|
||||
// final base64Str = base64Encode(bytes);
|
||||
// final dataUri = "data:application/octet-stream;base64,$base64Str";
|
||||
// final anchor = html.AnchorElement(href: dataUri)
|
||||
// ..setAttribute("download", "$fileName.xlsx")
|
||||
// ..click();
|
||||
// html.Url.revokeObjectUrl(url);
|
||||
// } else {
|
||||
// // Mobile/Desktop: save file
|
||||
// final dir = await getApplicationDocumentsDirectory();
|
||||
@ -202,66 +288,3 @@ class ExcelExporter {
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// class ExcelExporter {
|
||||
// static Future<void> exportToExcel({
|
||||
// required String sheetName,
|
||||
// required List<Map<String, dynamic>> data,
|
||||
// required List<String> headers,
|
||||
// required String fileName,
|
||||
// }) async {
|
||||
// try {
|
||||
// // var excel = Excel.createExcel();
|
||||
// // Sheet sheetObject = excel[sheetName];
|
||||
//
|
||||
// // Delete default sheet
|
||||
// var excel = Excel.createExcel();
|
||||
// excel.delete('Sheet1'); // remove default
|
||||
// Sheet sheetObject = excel[sheetName];
|
||||
//
|
||||
// // Add headers
|
||||
// sheetObject.appendRow(headers.map((h) => TextCellValue(h)).toList());
|
||||
//
|
||||
// // Add data
|
||||
// for (int i = 0; i < data.length; i++) {
|
||||
// var row = <CellValue?>[];
|
||||
// for (var key in headers) {
|
||||
// final value = data[i][key];
|
||||
// if (value == null) {
|
||||
// row.add(TextCellValue('-'));
|
||||
// } else if (value is int) {
|
||||
// row.add(IntCellValue(value));
|
||||
// } else if (value is double) {
|
||||
// row.add(DoubleCellValue(value));
|
||||
// } else {
|
||||
// row.add(TextCellValue(value.toString()));
|
||||
// }
|
||||
// }
|
||||
// sheetObject.appendRow(row);
|
||||
// }
|
||||
//
|
||||
// var bytes = excel.encode()!;
|
||||
//
|
||||
// if (kIsWeb) {
|
||||
// // ✅ Web: download as file
|
||||
// final blob = html.Blob([bytes]);
|
||||
// final url = html.Url.createObjectUrlFromBlob(blob);
|
||||
// final anchor = html.AnchorElement(href: url)
|
||||
// ..setAttribute("download", "$fileName.xlsx")
|
||||
// ..click();
|
||||
// html.Url.revokeObjectUrl(url);
|
||||
// } else {
|
||||
// // ✅ Mobile/Desktop: save to file system
|
||||
// final dir = await getApplicationDocumentsDirectory();
|
||||
// final file = File('${dir.path}/$fileName.xlsx');
|
||||
// await file.writeAsBytes(bytes);
|
||||
// await OpenFile.open(file.path);
|
||||
// }
|
||||
// } catch (e) {
|
||||
// print("Error exporting Excel: $e");
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
|
||||
Loading…
Reference in New Issue
Block a user