FIX_new master Endrs type master

This commit is contained in:
sanjeev.p 2025-12-26 15:32:39 +05:30
parent 9f3b22200f
commit 39fb3a5c02
7 changed files with 866 additions and 5 deletions

View File

@ -14,6 +14,7 @@ import '../../presentation/screens/Enquiry/enquiry/tabs.dart';
import '../../presentation/screens/Enquiry/policy_claims_endros/claims.dart';
import '../../presentation/screens/Enquiry/policy_claims_endros/endrosment.dart';
import '../../presentation/screens/Masters/Brokers/brokerList.dart';
import '../../presentation/screens/Masters/EndorsementType/endorsementList.dart';
import '../../presentation/screens/StaffAttendance/attendanceAllDetails.dart';
import '../../presentation/screens/StaffAttendance/individual_Attendance.dart';
import '../../presentation/screens/UserManagement/Agent/agent.dart';
@ -271,7 +272,10 @@ final GoRouter appRouter = GoRouter(
path: AppRoutes.brokerLst,
builder: (context, state) => const BrokerList(),
),
GoRoute(
path: AppRoutes.endorsementTypeLst,
builder: (context, state) => const EndorsementTypeList(),
),
GoRoute(
path: AppRoutes.paymentModeLst,
builder: (context, state) => const PaymentLsit(),

View File

@ -31,4 +31,5 @@ class AppRoutes {
static const String invoiceList = '/invoiceList';
static const String brokerLst = '/brokerLst';
static const String paymentModeLst = '/paymentMode';
static const String endorsementTypeLst = '/endorsementTypeLst';
}

View File

@ -456,13 +456,18 @@ class ApiService {
pathVal = 'dashboard/downloadT50AgentPoliciesExcel?manager_id=$managerId';
} else if (path == 'NonPerformingBelow50K') {
pathVal = 'dashboard/downloadLowPremiumAgentExcel?manager_id=$managerId';
} else if (path == 'staff_pending_summary') {
pathVal = 'dashboard/downloadStaffPendingSummaryExcel?manager_id=$managerId';
} else if (path == 'staff_pending_summary_by_id') {
pathVal = 'dashboard/downloadStaffPendingSummaryExcelByID?manager_id=$managerId&staff_id=$id';
} else {
//NoBusiness
//NoBusiness
pathVal =
'dashboard/downloadAgentsWithoutPoliciesExcel?manager_id=$managerId';
}
final url = Uri.parse('${Env.apiUrl}$pathVal');
// final url = 'http://localhost/nhance_partner_be/dashboard/downloadAgentsWithoutPoliciesExcel?manager_id=1';
// final url = Uri.parse('https://venbait.in/nhance/partner/dev/$path');
print('getPdfDownload 2 - $url');
await _initializeToken();
@ -1584,8 +1589,9 @@ class ApiService {
url = Uri.parse('${Env.apiUrl}master/getAllBrokers');
} else if (val == 'PaymentMode') {
url = Uri.parse('${Env.apiUrl}master/getAllPaymentModelist');
} else if (val == 'EndorsementType') {
url = Uri.parse('${Env.apiUrl}master/getAllEndorsement');
}
final headers = {
'Authorization': 'Bearer $_token' ?? '',
'app-signature': Env.App_Signature,

View File

@ -220,6 +220,15 @@ class _AppHeaderState extends ConsumerState<AppHeader> {
),
],
SizedBox(height: 2),
_buildPopupItem(
label: "Endorsement Type",
onTap: () {
setState(() => _activeMenu = 'Masters');
_hidePopup();
context.go(AppRoutes.endorsementTypeLst);
},
),
SizedBox(height: 2),
_buildPopupItem(
label: "Payment Mode",
onTap: () {

View File

@ -0,0 +1,478 @@
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:nhance_partner/presentation/providers/userRoleProvider.dart';
import 'package:nhance_partner/presentation/screens/Masters/EndorsementType/endorsementType.dart';
import '../../../../core/routing/routes.dart';
import '../../../../core/services/api_service.dart';
import '../../../../data/utils/Pagination.dart';
import '../../../layouts/main_layout.dart';
import '../../../layouts/responsive_layout.dart';
import '../../../providers/manager_provider.dart';
import '../../../themes/indicators/export_btn.dart';
import '../../../themes/indicators/filter_btn.dart';
import '../../../themes/indicators/search_field_theme.dart';
import '../../../themes/indicators/text_field_theme.dart';
import '../../../widgets/custom_action_popup.dart';
class EndorsementTypeList extends ConsumerStatefulWidget {
const EndorsementTypeList({super.key});
@override
ConsumerState<EndorsementTypeList> createState() => EndorsementTypeListState();
}
class EndorsementTypeListState extends ConsumerState<EndorsementTypeList> {
int currentPage = 1;
int itemsPerPage = 10;
late ApiService apiService;
dynamic managerId;
dynamic role;
dynamic prefid;
dynamic userId;
// List<Map<String, dynamic>> dataVal = [];
List<Map<String, dynamic>> getEndorsementTypeData = [];
List<Map<String, dynamic>> originalData = [];
List<Map<String, dynamic>> filteredData = [];
bool isLoading = false;
Map<String, dynamic>? selectedEndorsementType;
dynamic selectedId;
@override
void initState() {
super.initState();
apiService = ApiService();
Future.microtask(() {
final data1 = ref.read(managerIdProvider);
userId = ref.watch(userIdProvider);
// final data2 = ref.read(handlerIdProvider);
print("Edata1 => mId: $data1 -2 :");
prefid = data1;
role = ref.read(userRoleProvider);
print("E43 => mId: $prefid");
if (prefid != null && role != null) {
getEndorsementType();
}
});
// getEndorsementTypeList();
}
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 handleEdit(Map<String, dynamic> item) {
setState(() {
selectedId = item['id'];
selectedEndorsementType = item;
});
}
void filterData(String query) {
setState(() {
final q = query.toLowerCase();
if (q.isEmpty) {
filteredData = getEndorsementTypeData;
return;
}
filteredData = getEndorsementTypeData.where((item) {
final isActiveStatus = item['is_active'] == "1" ? "active" : "inactive";
return (item['endorsement_type'] ?? '').toString().toLowerCase().contains(q) ||
isActiveStatus.contains(q);
}).toList();
});
}
final TextEditingController _searchStaffController = TextEditingController();
Future<void> getEndorsementType() async {
print('getEndorsementType called');
setState(() {
isLoading = true;
});
try {
final response = await apiService.fetchMasterDropDown('EndorsementType');
if (response['status'] == 200) {
print('getEndorsementType - ${response['data']}');
setState(() {
getEndorsementTypeData = List<Map<String, dynamic>>.from(response['data']);
print('API Data - $getEndorsementTypeData');
filteredData = List.from(getEndorsementTypeData);
print('originalData - $filteredData');
});
} else {
getEndorsementTypeData = [];
filteredData = [];
}
} catch (e) {
print('Exception occurred: $e');
} finally {
setState(() {
isLoading = false;
});
}
}
List<Widget> _buildPopupMenuActions(BuildContext context, dynamic data) {
return [
GestureDetector(
onTap: () {
Navigator.pop(context);
print('EDITStaff - ${data['id']}');
dynamic id = data['id'];
context.go('/staff/$id');
},
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.edit_sharp, color: Color(0xFF319718), size: 18),
SizedBox(width: 10),
Text('Edit'),
],
),
),
];
}
@override
Widget build(BuildContext context) {
managerId = ref.watch(managerIdProvider);
return MainLayout(
title: "Endorsement Type",
body: Container(
// padding: EdgeInsets.all(8.0),
// margin: EdgeInsets.all(10.0),
// color: Colors.yellow.shade50,
width: MediaQuery.of(context).size.width,
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Container(
// height: 30,
// color: Colors.red.shade50,
width: MediaQuery.of(context).size.width,
child: GestureDetector(
onTap: () {
context.go(AppRoutes.dashboard);
},
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(
'Endorsement Type',
style: GoogleFonts.poppins(
fontSize: 14,
fontWeight: FontWeight.w500,
),
),
],
),
),
),
SizedBox(height: 5),
Expanded(
child: Container(
// color: Colors.green,
// color: Colors.green.shade50,
width: MediaQuery.of(context).size.width,
// margin: EdgeInsets.all(10.0),
decoration: BoxDecoration(
// color: Colors.white,
borderRadius: BorderRadius.circular(15.0),
),
padding: EdgeInsets.all(8.0),
child: Column(
children: [
Container(
// height: 40,
// color: Colors.pink,
child: Row(
crossAxisAlignment: CrossAxisAlignment.end,
mainAxisAlignment: MainAxisAlignment.start,
children: [
EndorsementType(
key: ValueKey(selectedId),
data: selectedEndorsementType,
id: selectedId,
onSubmit: () {
getEndorsementType();
setState(() {
selectedEndorsementType = null;
selectedId = null;
}); // reset after save
},
),
Spacer(),
ThemedSearchField(
hintText: 'Search',
// backgroundColor: Color(0xFFF6F8F8),
backgroundColor: Color(0xFFFFFFFF),
txtHeight: 30,
onChanged: filterData,
controller: _searchStaffController,
txtwidth: MediaQuery.of(context).size.width * 0.15,
),
SizedBox(width: 10),
ExportBtn(
sheetName: "EndorsementType",
fileName: "endorsement_type_list",
txt: !ResponsiveLayout.isMobile(context)
? true
: false,
data: filteredData,
displayHeaders: ['S.No.', 'Endorsement Type', 'Status'],
keys: ["sno", "endorsement_type", "is_active"],
),
],
),
),
SizedBox(height: 10),
Container(
decoration: BoxDecoration(
color: Color(0xFFF1F5F9),
// color: Color(0xFFEDF6F5),
borderRadius: BorderRadius.circular(6),
),
padding: const EdgeInsets.symmetric(
vertical: 8,
horizontal: 16,
),
child: Row(
children: [
Expanded(
flex: 1,
child: Text('S.No.', style: _headerStyle),
),
Expanded(
flex: 1,
child: Text('Endorsement Type', style: _headerStyle),
),
Expanded(
flex: 1,
child: Text('Status', style: _headerStyle),
),
Expanded(
flex: 1,
child: Text('Action', style: _headerStyle),
),
],
),
),
Expanded(
child: Container(
color: Colors.white,
child: _buildDataTable(context),
),
),
],
),
),
),
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 _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: filteredData.length + 1, // +1 for header, +1 for pagination
itemCount: sortedData.length + 1, // +1 for header, +1 for pagination
itemBuilder: (context, index) {
if (index == 0) return _buildHeader();
// if (index == dataVal.length + 1)
// return _buildPagination(context);
final startIndex = ((currentPage - 1) * itemsPerPage);
// final item = filteredData[index - 1];
final item = sortedData[index - 1];
final sno = startIndex + index;
return _buildDataRow(item, sno);
},
);
}
Widget _buildHeader() {
return SizedBox.shrink();
}
Widget _buildDataRow(Map<String, dynamic> item, sno) {
return Container(
padding: const EdgeInsets.symmetric(vertical: 1, horizontal: 16),
// margin: const EdgeInsets.only(top: 10),
decoration: BoxDecoration(
color: Colors.white,
// color: Color(0xFFE0F7F9),
border: const Border(
bottom: BorderSide(color: Colors.blueGrey, width: 0.15),
),
// borderRadius: BorderRadius.circular(8),
),
child: Row(
children: [
Expanded(flex: 1, child: Text('$sno' ?? '-', style: _dataBold)),
Expanded(flex: 1, child: Text(item['endorsement_type'] ?? '-', style: _dataBold)),
Expanded(
flex: 1,
child: Row(
children: [
Container(
// color: Colors.yellow.shade50,
child: Transform.scale(
scale: 0.4, // reduce size (0.70.9 works well)
child: Switch(
value: item['is_active'] == "1",
onChanged: (val) {
setState(() {
item['is_active'] = val ? "1" : "0";
});
final response = apiService.updateStatusMasters(
item['id'],
val ? "0" : "1",
'EndorsementType',
userId,
);
print("Response - $response");
},
activeColor: Color(0xFF2E7D6E), // thumb when active
// activeColor: Color(0xFF425B5B), // thumb when active
activeTrackColor: Color(0xFFDCFCE7), // track when active
// activeTrackColor: Color(0xFFB2D8D3), // track when active
inactiveThumbColor:
Colors.grey.shade400, // thumb when inactive
inactiveTrackColor:
Colors.grey.shade300, // track when inactive
),
),
),
],
),
),
Expanded(
flex: 1,
child: item['is_active'] == "1"
? Row(
children: [
Tooltip(
message: 'Edit',
child: IconButton(
icon: Image.asset(
"assets/miscellaneous/Edit.png",
height: 12,
width: 15,
),
onPressed: () {
print('EDITEndorsementType - ${item['id']}');
print('EDITEndorsementType - ${item}');
dynamic id = item['id'];
handleEdit(item);
print(item);
},
splashRadius: 28,
hoverColor: Colors.black12,
padding: const EdgeInsets.all(8),
constraints: const BoxConstraints(),
),
),
],
)
: Row(
children: [
Image.asset(
"assets/miscellaneous/Edit_muted.png",
height: 15,
width: 15,
),
],
),
),
],
),
);
}
static final _dataSub = GoogleFonts.inter(
fontSize: 10,
fontWeight: FontWeight.w300,
color: Color(0xFF585757),
);
static final _dataBold = GoogleFonts.inter(
fontSize: 11.5,
fontWeight: FontWeight.w400,
color: Color(0xFF000000),
);
static final _headerStyle = GoogleFonts.poppins(
fontSize: 11.2,
fontWeight: FontWeight.w500,
color: Color(0xFF1E293B),
);
}

View File

@ -0,0 +1,320 @@
import 'dart:convert';
// import 'dart:io' as html;
import 'dart:typed_data'; // Import for Uint8List
import 'package:dropdown_search/dropdown_search.dart';
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
import 'package:go_router/go_router.dart';
import 'package:google_fonts/google_fonts.dart';
import 'package:http/http.dart' as http;
import 'package:nhance_partner/core/routing/routes.dart';
import 'package:nhance_partner/data/utils/toastNotification.dart';
import 'package:nhance_partner/presentation/themes/indicators/text_field_theme.dart';
import 'package:nhance_partner/presentation/themes/indicators/text_field_theme_inline_editor.dart';
import '../../../../core/config/env.dart';
import '../../../../core/services/api_service.dart';
import '../../../../data/services/auth_service.dart';
import '../../../../data/utils/validators.dart';
import '../../../layouts/main_layout.dart';
import '../../../layouts/responsive_layout.dart';
import '../../../providers/manager_provider.dart';
import 'package:universal_html/html.dart' as html;
import '../../../themes/indicators/input_field_decoration.dart';
class EndorsementType extends ConsumerStatefulWidget {
final String? id;
final Map<String, dynamic>? data;
final VoidCallback onSubmit;
const EndorsementType({super.key, this.id, this.data, required this.onSubmit});
@override
ConsumerState<EndorsementType> createState() => EndorsementTypeState();
}
class EndorsementTypeState extends ConsumerState<EndorsementType> {
final _formKey = GlobalKey<FormState>();
late ApiService apiService;
final GlobalKey<DropdownSearchState<Map<String, dynamic>>> dropDownKey =
GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
final GlobalKey<DropdownSearchState<Map<String, dynamic>>>
dropDownKeyHandler = GlobalKey<DropdownSearchState<Map<String, dynamic>>>();
List<String> tabHeader = ['name', 'email', 'mobile', 'code'];
late String isActive = "1";
html.File? passportFile;
String? selectedFileNames;
String? passportFileUrlFromApi;
dynamic selectedId;
String? _token;
bool isLoading = false;
bool showHandler = false;
String? selectedRole;
List<Map<String, dynamic>> filteredRolesData = [];
List<Map<String, dynamic>> getRolesData = [];
List<dynamic>? selectedHandlerIds = [];
String? selectedHandler;
List<Map<String, dynamic>> filteredHandlersData = [];
List<Map<String, dynamic>> getHandlersData = [];
Map<String, TextEditingController> controllers = {};
dynamic userId;
dynamic managerId;
Map<String, dynamic> dataDetails() {
final data = {
"name": controllers["name"]?.text,
"short_name": controllers["code"]?.text,
"is_active": isActive,
};
return data;
}
@override
void initState() {
super.initState();
apiService = ApiService();
for (String field in tabHeader) {
controllers[field] = TextEditingController();
}
_initializeToken();
updateData();
Future.microtask(() {
managerId = ref.watch(managerIdProvider);
userId = ref.watch(userIdProvider);
if (managerId != null) {
print('hansles');
// getHandlers(managerId);
}
});
}
Future<void> _initializeToken() async {
_token = await AuthService.getToken();
print("APISERTOKEN - $_token");
}
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;
// }
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();
setState(() {
// clear all text controllers
for (var controller in controllers.values) {
controller.clear();
} // 👈 clear selected agent
controllers['name']?.clear();
});
}
Future<void> createUserData(data) async {
final bool isUpdating = selectedId != null;
final dynamic id = isUpdating ? int.tryParse(selectedId.toString()) : 0;
final String apiUrldata;
print("TYPE of id → $id - ${id.runtimeType}");
print("TYPE of id → $userId - ${userId.runtimeType}");
apiUrldata = isUpdating
? '${Env.apiUrl}/master/updateEndorsement/$selectedId'
: '${Env.apiUrl}/master/createEndorsement';
// final token = await getToken(); // Fetch token
if (_token == null) {
throw Exception('Token not found. Please log in.');
}
if (isUpdating) {
data['updated_by'] = userId.toString();
} else {
data['created_by'] = userId.toString();
}
print("data------- $data}");
try {
final response = await http.post(
Uri.parse(apiUrldata),
headers: {
'Authorization': 'Bearer $_token',
'Content-Type': 'application/json',
'app-signature': Env.App_Signature,
},
body: jsonEncode(data), // Convert map to JSON
);
if (response.statusCode == 200) {
final responseBody = jsonDecode(response.body);
final message = responseBody['message'];
print("EndorsementType submitted successfully!");
print("Response: ${response.body}");
if (responseBody['status'] == 200) {
refresh();
isUpdating
? ToastHelper.showSuccessToast(context, message)
: ToastHelper.showSuccessToast(context, message);
} else {
print("Failed to submit plan. Status: ${response.statusCode}");
print("Error: ${response.body}");
showDialog(
context: context,
builder: (BuildContext context) {
return AlertDialog(
title: Text("Endorsement Type Creation Failed"),
content: Text(message),
actions: [
TextButton(
child: Text("OK"),
onPressed: () {
Navigator.of(context).pop();
},
),
],
);
},
);
}
} else if (response.statusCode == 403) {
await apiService.clearLocalStorageAndRedirect();
}
} catch (e) {
print(" Error submitting Staff: $e");
}
}
@override
void dispose() {
for (var controller in controllers.values) {
controller.dispose();
}
super.dispose();
}
@override
Widget build(BuildContext context) {
return Container(
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
buildFormFields(),
SizedBox(width: 5),
InkWell(
onTap: () {
handleSave();
},
child: Container(
padding: EdgeInsets.symmetric(horizontal: 15.0, vertical: 6),
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(8.0),
color: Color(0xFF2E7D6E),
),
child: Text(
'Save',
style: GoogleFonts.inter(color: Colors.white, fontSize: 10),
),
),
),
SizedBox(width: 5),
InkWell(
onTap: () {
refresh();
},
child: Container(
padding: EdgeInsets.all(6.0),
decoration: BoxDecoration(
color: const Color(0xFF2E7D6E),
borderRadius: BorderRadius.circular(5.0),
),
child: Icon(Icons.refresh, size: 13, color: Colors.white),
),
),
],
),
);
}
Widget buildFormFields() {
return Form(
key: _formKey,
child: Row(
children: [buildEndorsementTypeName()],
),
);
}
Widget buildEndorsementTypeName() {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text("Endorsement Type *", style: _textStyle),
SizedBox(width: 10),
SizedBox(
child: ThemedFormInlineField(
controller: controllers['name']!,
validator: (value) => Validators.requiredField(value, "name"),
txtwidth: MediaQuery.of(context).size.width * 0.15,
borderColor: Color(0xFFE2E8F0),
highlightColor: Color(0xFF50A398),
// txtheight: 30,
isdense: true,
errFieldHgt: 0,
),
),
],
);
}
static final _textStyle = GoogleFonts.inter(
fontSize: 11,
fontWeight: FontWeight.w600,
);
}

View File

@ -110,6 +110,27 @@ class _DashboardState extends ConsumerState<LiveDashboard> {
}
}
Future<void> getExportExcel() async {
final prefmanagerid = ref.read(managerIdProvider);
final path = "staff_level_pending_summary";
final id = '';
final month = 'current';
try {
final response = await apiService.generateChartExcel(path,id,month,prefmanagerid);
return response;
} catch (e) {
print('Exception occurred: $e');
} finally {
setState(() {
isLoading = false;
});
}
}
Future<void> handleEdit(String id) async {
// Navigator.pop(context);
print('EDITStaff');
@ -561,6 +582,7 @@ class _DashboardState extends ConsumerState<LiveDashboard> {
stringFlag: "Proposal",
role: role!,
onRefresh: refresh,
onExportExcel: getExportExcel,
),
),
// if (role == 'handler') ...[
@ -1163,6 +1185,7 @@ class othersPendings extends StatelessWidget {
String role;
final List<Map<String, dynamic>> data;
final VoidCallback? onRefresh;
VoidCallback? onExportExcel;
othersPendings({
Key? key,
@ -1171,6 +1194,7 @@ class othersPendings extends StatelessWidget {
required this.data,
required this.stringFlag,
required this.onRefresh,
this.onExportExcel,
}) : super(key: key);
@override
@ -1223,16 +1247,35 @@ class othersPendings extends StatelessWidget {
children: [
// Title
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
mainAxisAlignment: MainAxisAlignment.start,
children: [
Text(title, style: _chartHeader),
Spacer(),
InkWell(
onTap: () {
onRefresh!();
},
child: Icon(Icons.refresh, size: 18),
),
const SizedBox(width: 12),
InkWell(
onTap: () => onExportExcel?.call(),
child: Tooltip(
message: 'Export Excel',
child: Container(
padding: const EdgeInsets.all(5.0),
decoration: BoxDecoration(
color: const Color(0xFF2E7D6E),
borderRadius: BorderRadius.circular(2.0),
),
child: Image.asset(
"assets/miscellaneous/export.png",
height: 11,
width: 11,
),
),
),
),
],
),
const SizedBox(height: 10),