From 39fb3a5c02cf3f1b0178cbf9ff3f6e6cd2da817e Mon Sep 17 00:00:00 2001 From: "sanjeev.p" Date: Fri, 26 Dec 2025 15:32:39 +0530 Subject: [PATCH] FIX_new master Endrs type master --- lib/core/routing/app_router.dart | 6 +- lib/core/routing/routes.dart | 1 + lib/core/services/api_service.dart | 10 +- lib/presentation/layouts/appheader.dart | 9 + .../EndorsementType/endorsementList.dart | 478 ++++++++++++++++++ .../EndorsementType/endorsementType.dart | 320 ++++++++++++ .../screens/dashboard/tabs/live.dart | 47 +- 7 files changed, 866 insertions(+), 5 deletions(-) create mode 100644 lib/presentation/screens/Masters/EndorsementType/endorsementList.dart create mode 100644 lib/presentation/screens/Masters/EndorsementType/endorsementType.dart diff --git a/lib/core/routing/app_router.dart b/lib/core/routing/app_router.dart index 7ac7f4c..7cacccf 100644 --- a/lib/core/routing/app_router.dart +++ b/lib/core/routing/app_router.dart @@ -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(), diff --git a/lib/core/routing/routes.dart b/lib/core/routing/routes.dart index ecb84b8..ec745e8 100644 --- a/lib/core/routing/routes.dart +++ b/lib/core/routing/routes.dart @@ -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'; } diff --git a/lib/core/services/api_service.dart b/lib/core/services/api_service.dart index f01254f..fcedade 100644 --- a/lib/core/services/api_service.dart +++ b/lib/core/services/api_service.dart @@ -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, diff --git a/lib/presentation/layouts/appheader.dart b/lib/presentation/layouts/appheader.dart index 9cc0acd..ed8c5bf 100644 --- a/lib/presentation/layouts/appheader.dart +++ b/lib/presentation/layouts/appheader.dart @@ -220,6 +220,15 @@ class _AppHeaderState extends ConsumerState { ), ], SizedBox(height: 2), + _buildPopupItem( + label: "Endorsement Type", + onTap: () { + setState(() => _activeMenu = 'Masters'); + _hidePopup(); + context.go(AppRoutes.endorsementTypeLst); + }, + ), + SizedBox(height: 2), _buildPopupItem( label: "Payment Mode", onTap: () { diff --git a/lib/presentation/screens/Masters/EndorsementType/endorsementList.dart b/lib/presentation/screens/Masters/EndorsementType/endorsementList.dart new file mode 100644 index 0000000..7120e7b --- /dev/null +++ b/lib/presentation/screens/Masters/EndorsementType/endorsementList.dart @@ -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 createState() => EndorsementTypeListState(); +} + +class EndorsementTypeListState extends ConsumerState { + int currentPage = 1; + int itemsPerPage = 10; + late ApiService apiService; + dynamic managerId; + dynamic role; + dynamic prefid; + dynamic userId; + // List> dataVal = []; + List> getEndorsementTypeData = []; + List> originalData = []; + List> filteredData = []; + bool isLoading = false; + + Map? 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 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 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 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>.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 _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 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.7–0.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), + ); +} diff --git a/lib/presentation/screens/Masters/EndorsementType/endorsementType.dart b/lib/presentation/screens/Masters/EndorsementType/endorsementType.dart new file mode 100644 index 0000000..ca95e95 --- /dev/null +++ b/lib/presentation/screens/Masters/EndorsementType/endorsementType.dart @@ -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? data; + final VoidCallback onSubmit; + const EndorsementType({super.key, this.id, this.data, required this.onSubmit}); + @override + ConsumerState createState() => EndorsementTypeState(); +} + +class EndorsementTypeState extends ConsumerState { + final _formKey = GlobalKey(); + late ApiService apiService; + + final GlobalKey>> dropDownKey = + GlobalKey>>(); + + final GlobalKey>> + dropDownKeyHandler = GlobalKey>>(); + + List 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> filteredRolesData = []; + List> getRolesData = []; + + List? selectedHandlerIds = []; + String? selectedHandler; + List> filteredHandlersData = []; + List> getHandlersData = []; + + Map controllers = {}; + + dynamic userId; + dynamic managerId; + + Map 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 _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 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 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, + ); +} diff --git a/lib/presentation/screens/dashboard/tabs/live.dart b/lib/presentation/screens/dashboard/tabs/live.dart index 08926b7..e76cb40 100644 --- a/lib/presentation/screens/dashboard/tabs/live.dart +++ b/lib/presentation/screens/dashboard/tabs/live.dart @@ -110,6 +110,27 @@ class _DashboardState extends ConsumerState { } } + Future 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 handleEdit(String id) async { // Navigator.pop(context); print('EDITStaff'); @@ -561,6 +582,7 @@ class _DashboardState extends ConsumerState { stringFlag: "Proposal", role: role!, onRefresh: refresh, + onExportExcel: getExportExcel, ), ), // if (role == 'handler') ...[ @@ -1163,6 +1185,7 @@ class othersPendings extends StatelessWidget { String role; final List> 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),