1210 lines
43 KiB
Dart
1210 lines
43 KiB
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:nhance_partner/data/utils/toastNotification.dart';
|
|
import 'package:shared_preferences/shared_preferences.dart';
|
|
|
|
import '../../../../core/responsive/responsive_builder.dart';
|
|
import '../../../../core/routing/routes.dart';
|
|
import '../../../../core/services/api_service.dart';
|
|
import '../../../providers/manager_provider.dart';
|
|
import '../../../providers/quotation_staff_proivder.dart';
|
|
import '../../../providers/userRoleProvider.dart';
|
|
import '../../staff/Enquiry/tabs/tab.dart';
|
|
import '../../staff/assignStaff.dart';
|
|
|
|
|
|
class PartnerDashboard extends ConsumerStatefulWidget {
|
|
const PartnerDashboard({super.key});
|
|
|
|
@override
|
|
ConsumerState<PartnerDashboard> createState() => _PartnerDashboardState();
|
|
}
|
|
|
|
class _PartnerDashboardState extends ConsumerState<PartnerDashboard> {
|
|
/// ✅ DATE STATE (ONLY FOR PARTNER TAB)
|
|
DateTime? fromDate;
|
|
DateTime? toDate;
|
|
int selectedIndex = 1;
|
|
int switcherStatus = 1;
|
|
late ApiService apiService;
|
|
String? policiesIssuedToday;
|
|
String? policiesIssuedYear;
|
|
String? policiesIssuedMonth;
|
|
String? premiumValueToday;
|
|
String? premiumValueYear;
|
|
String? premiumValueMonth;
|
|
String? earningsToday;
|
|
String? earningsMonth;
|
|
String? earningsYear;
|
|
String? quotationsPendingCounts; // cross verify
|
|
String? currentKey; // cross verify
|
|
String? SelctdPartnerbroker; // cross verify
|
|
|
|
// List<Map<String, dynamic>> dataVal = [];
|
|
List<Map<String, dynamic>> getStaffData = [];
|
|
// List<Map<String, dynamic>> originalData = [];
|
|
// List<Map<String, dynamic>> filteredData = [];
|
|
int selectedTabIndex = 0;
|
|
List<Map<String, dynamic>> currentList = [];
|
|
|
|
List<Map<String, dynamic>> staffQuotationsPendingList = []; // cross verify
|
|
List<Map<String, dynamic>> quotationsPendingList = []; // cross verify
|
|
List<Map<String, dynamic>> policiesPendingList = []; // cross verify
|
|
List<Map<String, dynamic>> awaitingApprovalList = []; // cross verify
|
|
List<Map<String, dynamic>> unAssignedEnqList = []; // cross verify
|
|
List<Map<String, dynamic>> agentsPerformanceList = []; // cross verify
|
|
List<Map<String, dynamic>> nonAgentsPerformanceList = [];
|
|
List<Map<String, dynamic>> agentsPerformanceListPremium = []; // cross verify
|
|
List<Map<String, dynamic>> nonAgentsPerformanceListPremium =
|
|
[]; // cross verify
|
|
dynamic prefid;
|
|
dynamic prefroleId;
|
|
bool isLoading = false;
|
|
|
|
List<Map<String, dynamic>> getBusinessDshBdData = [];
|
|
List<Map<String, dynamic>> originalData = [];
|
|
List<Map<String, dynamic>> filteredData = [];
|
|
|
|
List<Map<String, dynamic>> brokerWise = [];
|
|
List<Map<String, dynamic>> productWise = [];
|
|
List<Map<String, dynamic>> insurerWise = [];
|
|
|
|
List<Map<String, dynamic>> originalBrokerWise = [];
|
|
List<Map<String, dynamic>> filteredBrokerWise = [];
|
|
|
|
List<Map<String, dynamic>> originalProductWise = [];
|
|
List<Map<String, dynamic>> filteredProductWise = [];
|
|
|
|
List<Map<String, dynamic>> originalInsurerWise = [];
|
|
List<Map<String, dynamic>> filteredInsurerWise = [];
|
|
|
|
bool isPerfomingAgntPolicy = true;
|
|
bool isNonPerfomingAgntPolicy = true;
|
|
bool isBrokerWisePolicy = true;
|
|
bool isProductWisePolicy = true;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
|
|
apiService = ApiService();
|
|
|
|
Future.microtask(() {
|
|
final prefmanagerid = ref.read(managerIdProvider);
|
|
final prefuserid = ref.read(userIdProvider);
|
|
final prefroleId = ref.read(userRoleProvider);
|
|
|
|
print("B81 => roleId: $prefroleId | userId: $prefuserid ");
|
|
if (prefmanagerid != null) {
|
|
getParnterDashBrdList(prefmanagerid);
|
|
// getStaffList(prefmanagerid!, prefroleId, prefuserid);
|
|
}
|
|
});
|
|
}
|
|
|
|
void refresh() {
|
|
print('___DASHBOARD___');
|
|
final prefmanagerid = ref.read(managerIdProvider);
|
|
final prefuserid = ref.read(userIdProvider);
|
|
final prefroleId = ref.read(userRoleProvider);
|
|
|
|
// if (prefuserid != null) {
|
|
// print("REFRESH- calling getStaffList with $prefmanagerid, $prefuserid");
|
|
// getStaffList(prefmanagerid!, prefroleId, prefuserid);
|
|
// }
|
|
}
|
|
|
|
/// 🔹 DATE PICKER
|
|
Future<void> pickDate(bool isFrom) async {
|
|
final picked = await showDatePicker(
|
|
context: context,
|
|
initialDate: DateTime.now(),
|
|
firstDate: DateTime(2022),
|
|
lastDate: DateTime.now(),
|
|
);
|
|
|
|
if (picked != null) {
|
|
setState(() {
|
|
if (isFrom) {
|
|
fromDate = picked;
|
|
} else {
|
|
toDate = picked;
|
|
}
|
|
});
|
|
|
|
// OPTIONAL: reload API with date range
|
|
// final managerId = ref.read(managerIdProvider);
|
|
// if (managerId != null) {
|
|
// getParnterDashBrdList(managerId);
|
|
// }
|
|
}
|
|
}
|
|
|
|
/// 🔹 DATE PICKER UI
|
|
Widget headerDatePicker({
|
|
required String label,
|
|
DateTime? date,
|
|
required VoidCallback onTap,
|
|
}) {
|
|
return InkWell(
|
|
onTap: onTap,
|
|
child: Container(
|
|
height: 32,
|
|
padding: const EdgeInsets.symmetric(horizontal: 10),
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
borderRadius: BorderRadius.circular(6),
|
|
border: Border.all(color: Colors.grey.shade300),
|
|
),
|
|
child: Row(
|
|
mainAxisSize: MainAxisSize.min,
|
|
children: [
|
|
const Icon(Icons.calendar_today, size: 14, color: Colors.grey),
|
|
const SizedBox(width: 6),
|
|
Text(
|
|
date == null
|
|
? label
|
|
: DateFormat('dd-MM-yyyy').format(date),
|
|
style: GoogleFonts.inter(fontSize: 11),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
Future<void> getParnterDashBrdList(id) async {
|
|
// print('getClaimList called MagId - $managerId - $role');
|
|
setState(() {
|
|
isLoading = true;
|
|
});
|
|
// dynamic id = widget.policyNumber;
|
|
print('getBusinessDshID - $id - $fromDate - $toDate');
|
|
try {
|
|
final response = await apiService.findPartnerDashboardData(id,fromDate,toDate);
|
|
|
|
if (response['status'] == 'success') {
|
|
final data = response['data'];
|
|
print('getBusinessDshBdData - ${response['data']}');
|
|
setState(() {
|
|
if (data is List) {
|
|
// Already a list of maps
|
|
getBusinessDshBdData = List<Map<String, dynamic>>.from(data);
|
|
} else if (data is Map) {
|
|
// Single object, wrap in a list
|
|
getBusinessDshBdData = [Map<String, dynamic>.from(data)];
|
|
} else {
|
|
getBusinessDshBdData = [];
|
|
}
|
|
// getBusinessDshBdData = List<Map<String, dynamic>>.from(response['data']);
|
|
originalData = getBusinessDshBdData;
|
|
filteredData = List.from(originalData);
|
|
// print('originalData - $getClaimPolicies');
|
|
});
|
|
|
|
if (data is Map<String, dynamic>) {
|
|
setState(() {
|
|
// agents_performance Policy
|
|
if (data['agentsPerformanceList'] != null) {
|
|
agentsPerformanceList = List<Map<String, dynamic>>.from(
|
|
(data['agentsPerformanceList'] as List).map(
|
|
(item) => Map<String, dynamic>.from(item),
|
|
),
|
|
);
|
|
} // agents_performance Premium
|
|
|
|
if (data['monthlyPremiumAmount'] != null) {
|
|
agentsPerformanceListPremium = List<Map<String, dynamic>>.from(
|
|
(data['monthlyPremiumAmount'] as List).map(
|
|
(item) => Map<String, dynamic>.from(item),
|
|
),
|
|
);
|
|
}
|
|
|
|
if (data['nonAgentsPerformanceList'] != null) {
|
|
nonAgentsPerformanceList = List<Map<String, dynamic>>.from(
|
|
(data['nonAgentsPerformanceList'] as List).map(
|
|
(item) => Map<String, dynamic>.from(item),
|
|
),
|
|
);
|
|
} // agents_performance Premium
|
|
|
|
if (data['nonAgentsPerformanceListPremium'] != null) {
|
|
nonAgentsPerformanceListPremium = List<Map<String, dynamic>>.from(
|
|
(data['nonAgentsPerformanceListPremium'] as List).map(
|
|
(item) => Map<String, dynamic>.from(item),
|
|
),
|
|
);
|
|
}
|
|
|
|
print(
|
|
'agentsPerformanceListPremium - ${agentsPerformanceListPremium}',
|
|
);
|
|
originalBrokerWise = List.from(brokerWise);
|
|
filteredBrokerWise = List.from(brokerWise);
|
|
|
|
// Store ProductWise
|
|
productWise = List<Map<String, dynamic>>.from(
|
|
data['productWise'] ?? [],
|
|
);
|
|
|
|
print('productWise - ${productWise}');
|
|
originalProductWise = List.from(productWise);
|
|
filteredProductWise = List.from(productWise);
|
|
|
|
// Store InsurerWise
|
|
insurerWise = List<Map<String, dynamic>>.from(
|
|
data['insurerWise'] ?? [],
|
|
);
|
|
print('insurerWise - ${insurerWise}');
|
|
originalInsurerWise = List.from(insurerWise);
|
|
filteredInsurerWise = List.from(insurerWise);
|
|
});
|
|
} else {
|
|
// fallback
|
|
brokerWise = [];
|
|
productWise = [];
|
|
insurerWise = [];
|
|
}
|
|
} else {
|
|
getBusinessDshBdData = [];
|
|
originalData = [];
|
|
}
|
|
} catch (e) {
|
|
print('Exception occurred: $e');
|
|
} finally {
|
|
setState(() {
|
|
isLoading = false;
|
|
});
|
|
}
|
|
}
|
|
|
|
Future<void> handleEdit(String id) async {
|
|
// Navigator.pop(context);
|
|
print('EDITStaff');
|
|
print('EDITStaff - $id');
|
|
// dynamic id = data['id'];
|
|
// context.go('/tabEnquiry/$id');
|
|
|
|
final prefs = await SharedPreferences.getInstance();
|
|
// ✅ Remove old value (if any)
|
|
await prefs.remove('enqAgentDataId');
|
|
|
|
// setState(() {
|
|
// final id = item['id'].toString();
|
|
// ✅ Save the new id
|
|
// await prefs.setString('enqAgentDataId', id.toString());
|
|
await prefs.setString('enqAgentDataId', id);
|
|
ref.read(enquiryIdProvider.notifier).state = id;
|
|
context.go(AppRoutes.tabEnquiry);
|
|
}
|
|
|
|
Future<void> handleStaffEdit(String id, String? flag) async {
|
|
// Navigator.pop(context); ddd
|
|
dynamic val;
|
|
print('EDITStaff - $id');
|
|
|
|
if (flag == "Policies") {
|
|
val = 'Policy';
|
|
} else {
|
|
val = '';
|
|
}
|
|
|
|
var enqId = id;
|
|
|
|
final prefs = await SharedPreferences.getInstance();
|
|
|
|
// ✅ Remove old value (if any)
|
|
await prefs.remove('enqStaffDataId');
|
|
|
|
// ✅ Save the new id
|
|
await prefs.setString('enqStaffDataId', enqId.toString());
|
|
await prefs.setString('navFromDashboard', 'Dashboard');
|
|
|
|
ref.read(quotationStaffIdProvider.notifier).state = enqId;
|
|
ref.read(navFromEnqStaffProvider.notifier).state = 'Dashboard';
|
|
|
|
// showDialog(
|
|
// context: context,
|
|
// builder: (context) => TabEnquiryStaffList(showKey: val),
|
|
// );
|
|
|
|
final result = await showDialog(
|
|
context: context,
|
|
barrierDismissible:
|
|
false, // optional - prevents closing by tapping outside
|
|
builder: (context) => TabEnquiryStaffList(showKey: val),
|
|
);
|
|
|
|
// ✅ Code here runs *after* the dialog is closed
|
|
print("Dialog closed");
|
|
print("Dialog result: $result");
|
|
refresh();
|
|
}
|
|
|
|
void onSearch() {
|
|
final managerId = ref.read(managerIdProvider);
|
|
|
|
if (managerId == null) return;
|
|
|
|
// Print to verify state before calling API
|
|
print("Search Triggered: $fromDate to $toDate");
|
|
|
|
// OPTIONAL: validation
|
|
if (fromDate != null && toDate != null && fromDate!.isAfter(toDate!)) {
|
|
ToastHelper.showWarningToast(context, 'From date cannot be after To date');
|
|
// ScaffoldMessenger.of(context).showSnackBar(
|
|
// const SnackBar(content: Text('From date cannot be after To date')),
|
|
// );
|
|
return;
|
|
}
|
|
|
|
// 🔍 Call API with date filter
|
|
getParnterDashBrdList(managerId);
|
|
}
|
|
|
|
void onReset() {
|
|
setState(() {
|
|
fromDate = null;
|
|
toDate = null;
|
|
});
|
|
|
|
final managerId = ref.read(managerIdProvider);
|
|
if (managerId != null) {
|
|
// ♻️ Reload without date filter
|
|
getParnterDashBrdList(managerId);
|
|
}
|
|
}
|
|
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
// final enquiries = ref.watch(enquiriesProvider);
|
|
final managerId = ref.watch(managerIdProvider);
|
|
final userId = ref.watch(userIdProvider);
|
|
final role = ref.watch(userRoleProvider);
|
|
|
|
return SelectionArea(
|
|
child: Column(
|
|
children: [
|
|
Container(
|
|
margin: EdgeInsets.all(0),
|
|
// color: Colors.red.shade100,
|
|
// height: MediaQuery.of(context).size.height * 0.75,
|
|
child: SingleChildScrollView(
|
|
scrollDirection: Axis.vertical,
|
|
child: Column(
|
|
children: [
|
|
Padding(
|
|
padding:
|
|
const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
|
child: Row(
|
|
children: [
|
|
const Spacer(),
|
|
headerDatePicker(
|
|
label: 'From',
|
|
date: fromDate,
|
|
onTap: () => pickDate(true),
|
|
),
|
|
const SizedBox(width: 8),
|
|
headerDatePicker(
|
|
label: 'To',
|
|
date: toDate,
|
|
onTap: () => pickDate(false),
|
|
),
|
|
const SizedBox(width: 8),
|
|
|
|
/// ♻️ RESET
|
|
actionIcon(
|
|
icon: Icons.refresh,
|
|
tooltip: 'Reset',
|
|
onTap: onReset,
|
|
),
|
|
|
|
const SizedBox(width: 6),
|
|
|
|
/// 🔍 SEARCH
|
|
actionIcon(
|
|
icon: Icons.search,
|
|
tooltip: 'Search',
|
|
onTap: onSearch,
|
|
),
|
|
|
|
|
|
],
|
|
),
|
|
),
|
|
|
|
if (role == 'manager' || role == 'handler' || role == 'agent')
|
|
SizedBox(
|
|
height: MediaQuery.of(context).size.height * 0.78,
|
|
// ✅ replace Expanded
|
|
// height: 350, // adjust height as needed
|
|
child: Row(
|
|
children: [
|
|
Expanded(
|
|
child: Container(
|
|
padding: const EdgeInsets.all(12.0),
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
borderRadius: BorderRadius.circular(12),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: Colors.black12,
|
|
blurRadius: 4,
|
|
offset: Offset(0, 2),
|
|
),
|
|
],
|
|
),
|
|
child: Column(
|
|
children: [
|
|
Padding(
|
|
padding: const EdgeInsets.only(
|
|
top: 8.0,
|
|
bottom: 16.0,
|
|
),
|
|
child: Row(
|
|
children: [
|
|
Expanded(
|
|
child: Row(
|
|
mainAxisAlignment:
|
|
MainAxisAlignment.spaceBetween,
|
|
children: [
|
|
Text(
|
|
'Performing Partner ( Top 50 )',
|
|
style: _chartHeader,
|
|
),
|
|
|
|
SizedBox(width: 10),
|
|
InkWell(
|
|
onTap: () async {
|
|
final path =
|
|
"PerformingTop50";
|
|
final id = '';
|
|
final month = 'current';
|
|
|
|
await apiService
|
|
.generateChartExcel(
|
|
path,
|
|
id,
|
|
month,
|
|
managerId,
|
|
fromDate: fromDate,
|
|
toDate: toDate,
|
|
);
|
|
},
|
|
child: Tooltip(
|
|
message: 'Export Excel',
|
|
child: Container(
|
|
padding: const EdgeInsets.all(
|
|
5.0,
|
|
),
|
|
decoration: BoxDecoration(
|
|
color: const Color(
|
|
0xFF2E7D6E,
|
|
),
|
|
// color: const Color(0xFF425B5B),
|
|
borderRadius:
|
|
BorderRadius.circular(
|
|
2.0,
|
|
),
|
|
),
|
|
child: Image.asset(
|
|
"assets/miscellaneous/export.png",
|
|
height: 11,
|
|
width: 11,
|
|
// color: Colors.green,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
|
|
// Text(
|
|
// isPerfomingAgntPolicy
|
|
// ? "Policies"
|
|
// : "Premium",
|
|
// style: _styleSmall1,
|
|
// ),
|
|
//
|
|
// Transform.scale(
|
|
// scale: 0.5,
|
|
// child: Switch(
|
|
// value: isPerfomingAgntPolicy,
|
|
// activeColor: Colors.teal,
|
|
// activeTrackColor: Colors.grey.shade200,
|
|
// inactiveThumbColor: Colors.orange,
|
|
// inactiveTrackColor: Colors.white,
|
|
// onChanged: (val) {
|
|
// setState(
|
|
// () => isPerfomingAgntPolicy = val,
|
|
// );
|
|
// },
|
|
// ),
|
|
// ),
|
|
],
|
|
),
|
|
),
|
|
|
|
Expanded(
|
|
child: Performance(
|
|
title: "Performing Partner",
|
|
data: isPerfomingAgntPolicy
|
|
? agentsPerformanceList
|
|
: agentsPerformanceListPremium,
|
|
isPerfomingAgntPolicy:
|
|
isPerfomingAgntPolicy,
|
|
apiService: apiService,
|
|
managerId: managerId,
|
|
fromDate: fromDate,
|
|
toDate: toDate,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
SizedBox(width: 16),
|
|
Expanded(
|
|
child: Container(
|
|
padding: const EdgeInsets.all(12.0),
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
borderRadius: BorderRadius.circular(12),
|
|
boxShadow: [
|
|
BoxShadow(
|
|
color: Colors.black12,
|
|
blurRadius: 4,
|
|
offset: Offset(0, 2),
|
|
),
|
|
],
|
|
),
|
|
child: Column(
|
|
children: [
|
|
Row(
|
|
children: [
|
|
Expanded(
|
|
child: Text(
|
|
'Non Performing Partner',
|
|
style: _chartHeader,
|
|
),
|
|
),
|
|
|
|
SizedBox(width: 10),
|
|
|
|
Text(
|
|
isNonPerfomingAgntPolicy
|
|
? "No Business"
|
|
: "Business Less than 50,000",
|
|
style: _styleSmall1,
|
|
),
|
|
|
|
Transform.scale(
|
|
scale: 0.5,
|
|
child: Switch(
|
|
value: isNonPerfomingAgntPolicy,
|
|
activeColor: Colors.teal,
|
|
activeTrackColor: Colors.grey.shade200,
|
|
inactiveThumbColor: Colors.orange,
|
|
inactiveTrackColor: Colors.white,
|
|
onChanged: (val) {
|
|
setState(
|
|
() =>
|
|
isNonPerfomingAgntPolicy = val,
|
|
);
|
|
},
|
|
),
|
|
),
|
|
SizedBox(width: 5),
|
|
InkWell(
|
|
onTap: () async {
|
|
final path = isNonPerfomingAgntPolicy
|
|
? "NoBusiness"
|
|
: "NonPerformingBelow50K";
|
|
final id = '';
|
|
final month = 'current';
|
|
|
|
await apiService.generateChartExcel(
|
|
path,
|
|
id,
|
|
month,
|
|
managerId,
|
|
fromDate: fromDate,
|
|
toDate: toDate,
|
|
);
|
|
},
|
|
child: Tooltip(
|
|
message: 'Export Excel',
|
|
child: Container(
|
|
padding: const EdgeInsets.all(5.0),
|
|
decoration: BoxDecoration(
|
|
color: const Color(0xFF2E7D6E),
|
|
// color: const Color(0xFF425B5B),
|
|
borderRadius: BorderRadius.circular(
|
|
2.0,
|
|
),
|
|
),
|
|
child: Image.asset(
|
|
"assets/miscellaneous/export.png",
|
|
height: 11,
|
|
width: 11,
|
|
// color: Colors.green,
|
|
),
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
Expanded(
|
|
child: Performance(
|
|
title: "Non-Performing Partner",
|
|
data: isNonPerfomingAgntPolicy
|
|
? nonAgentsPerformanceList
|
|
: nonAgentsPerformanceListPremium,
|
|
isPerfomingAgntPolicy:
|
|
isNonPerfomingAgntPolicy,
|
|
apiService: apiService,
|
|
managerId: managerId,
|
|
fromDate: fromDate,
|
|
toDate: toDate,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
),
|
|
],
|
|
) );
|
|
}
|
|
|
|
Widget actionIcon({
|
|
required IconData icon,
|
|
required String tooltip,
|
|
required VoidCallback onTap,
|
|
}) {
|
|
return Tooltip(
|
|
message: tooltip,
|
|
child: InkWell(
|
|
onTap: onTap,
|
|
borderRadius: BorderRadius.circular(6),
|
|
child: Container(
|
|
height: 32,
|
|
width: 32,
|
|
decoration: BoxDecoration(
|
|
color: const Color(0xFF2E7D6E),
|
|
borderRadius: BorderRadius.circular(6),
|
|
),
|
|
child: Icon(icon, size: 16, color: Colors.white),
|
|
),
|
|
),
|
|
);
|
|
}
|
|
|
|
}
|
|
|
|
class Performance extends StatefulWidget {
|
|
final String title;
|
|
final List<Map<String, dynamic>> data;
|
|
final bool isPerfomingAgntPolicy;
|
|
late ApiService apiService;
|
|
dynamic managerId;
|
|
|
|
final DateTime? fromDate;
|
|
final DateTime? toDate;
|
|
|
|
Performance({
|
|
Key? key,
|
|
required this.title,
|
|
required this.data,
|
|
required this.isPerfomingAgntPolicy,
|
|
required this.apiService,
|
|
required this.managerId,
|
|
this.fromDate,
|
|
this.toDate,
|
|
}) : super(key: key);
|
|
|
|
@override
|
|
State<Performance> createState() => _PerformanceState();
|
|
}
|
|
|
|
class _PerformanceState extends State<Performance> {
|
|
late bool isPerfomingAgntPolicy;
|
|
|
|
@override
|
|
void initState() {
|
|
super.initState();
|
|
isPerfomingAgntPolicy = widget.isPerfomingAgntPolicy;
|
|
}
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Container(
|
|
color: Colors.white,
|
|
|
|
// elevation: 1,
|
|
// shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(0.0),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
// HEADER
|
|
Container(
|
|
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12),
|
|
decoration: BoxDecoration(
|
|
color: Color(0xFFE3F9F8),
|
|
borderRadius: BorderRadius.circular(10),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
Expanded(
|
|
flex: 1,
|
|
child: Text(
|
|
"S.No.",
|
|
textAlign: TextAlign.left,
|
|
style: _headerStyle,
|
|
),
|
|
),
|
|
Expanded(
|
|
flex: 1,
|
|
child: Text(
|
|
"Partner Code",
|
|
textAlign: TextAlign.left,
|
|
style: _headerStyle,
|
|
),
|
|
),
|
|
Expanded(
|
|
flex: 2,
|
|
child: Text(
|
|
"Partner Name",
|
|
textAlign: TextAlign.left,
|
|
style: _headerStyle,
|
|
),
|
|
),
|
|
if (widget.title == 'Performing Partner') ...[
|
|
Expanded(
|
|
flex: 1,
|
|
child: Text(
|
|
"Policy Count",
|
|
textAlign: TextAlign.center,
|
|
style: _headerStyle,
|
|
),
|
|
),
|
|
Expanded(
|
|
flex: 1,
|
|
child: Text(
|
|
"Premium Amount",
|
|
textAlign: TextAlign.center,
|
|
style: _headerStyle,
|
|
),
|
|
),
|
|
],
|
|
],
|
|
),
|
|
),
|
|
|
|
const SizedBox(height: 8),
|
|
|
|
// LIST
|
|
Flexible(
|
|
child: ListView.builder(
|
|
itemCount: widget.data.length,
|
|
itemBuilder: (context, index) {
|
|
final row = widget.data[index];
|
|
return Container(
|
|
margin: const EdgeInsets.symmetric(vertical: 5),
|
|
padding: const EdgeInsets.symmetric(
|
|
vertical: 5,
|
|
horizontal: 12,
|
|
),
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
border: Border(
|
|
bottom: BorderSide(
|
|
color: Colors.blueGrey.shade100,
|
|
width: 0.3,
|
|
),
|
|
),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
Expanded(
|
|
flex: 1,
|
|
child: Text(
|
|
(index + 1).toString(),
|
|
textAlign: TextAlign.left,
|
|
style: _tableDataStyle,
|
|
),
|
|
),
|
|
Expanded(
|
|
flex: 1,
|
|
child: Text(
|
|
row['agent_code'] ?? "",
|
|
textAlign: TextAlign.left,
|
|
style: _tableDataStyle,
|
|
),
|
|
),
|
|
Expanded(
|
|
flex: 2,
|
|
child: Text(
|
|
row['agent_name'] ?? "",
|
|
textAlign: TextAlign.left,
|
|
style: _tableDataStyle,
|
|
),
|
|
),
|
|
|
|
if (widget.title == 'Performing Partner') ...[
|
|
Expanded(
|
|
flex: 1,
|
|
child: Text(
|
|
row['policy_count'] ?? "",
|
|
textAlign: TextAlign.center,
|
|
style: _tableDataStyle,
|
|
),
|
|
),
|
|
Expanded(
|
|
flex: 1,
|
|
child: Text(
|
|
row['total_premium_amount'] ?? "",
|
|
textAlign: TextAlign.right,
|
|
style: _tableDataStyle,
|
|
),
|
|
),
|
|
],
|
|
SizedBox(width: 10),
|
|
|
|
if (widget.title == 'Performing Partner') ...[
|
|
InkWell(
|
|
onTap: () async {
|
|
final path1 = 'PerformingAgentsByID';
|
|
final path2 = widget.isPerfomingAgntPolicy
|
|
? "NoBusiness"
|
|
: "NonPerformingBelow50K";
|
|
final path =
|
|
(widget.title == 'Performing Partner')
|
|
? path1
|
|
: path2;
|
|
|
|
final id =
|
|
((widget.title == 'Performing Partner') &&
|
|
(row['agent_id'] != null))
|
|
? row['agent_id']
|
|
: '';
|
|
final month = 'current';
|
|
|
|
await widget.apiService.generateChartExcel(
|
|
path,
|
|
id,
|
|
month,
|
|
widget.managerId,
|
|
fromDate: widget.fromDate,
|
|
toDate: widget.toDate,
|
|
// widget.fromDate,widget.toDate
|
|
);
|
|
},
|
|
child: Tooltip(
|
|
message: 'Click To Download Excel',
|
|
child: Icon(
|
|
Icons.download,
|
|
size: 14,
|
|
color: Colors.green.shade300,
|
|
),
|
|
),
|
|
),
|
|
],
|
|
],
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
class UnassignedEnq extends StatelessWidget {
|
|
final String title;
|
|
final List<Map<String, dynamic>> data;
|
|
final VoidCallback? onRefresh;
|
|
String role;
|
|
|
|
UnassignedEnq({
|
|
Key? key,
|
|
required this.title,
|
|
required this.data,
|
|
this.onRefresh,
|
|
required this.role,
|
|
}) : super(key: key);
|
|
|
|
@override
|
|
Widget build(BuildContext context) {
|
|
return Card(
|
|
color: Colors.white,
|
|
// color: const Color(0xFFEAF6F4),
|
|
elevation: 1,
|
|
shape: RoundedRectangleBorder(borderRadius: BorderRadius.circular(12)),
|
|
child: Padding(
|
|
padding: const EdgeInsets.all(12.0),
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
// Title
|
|
Text(title, style: _title),
|
|
const SizedBox(height: 10),
|
|
|
|
// Header row
|
|
Container(
|
|
padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 12),
|
|
decoration: BoxDecoration(
|
|
// color: const Color(0xFF3E5B56),
|
|
color: Color(0xFFE3F9F8),
|
|
borderRadius: BorderRadius.circular(10),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
// Expanded(
|
|
// child: Text(
|
|
// "S.No",
|
|
// textAlign: TextAlign.center,
|
|
// style: _headerStyle,
|
|
// ),
|
|
// ),
|
|
Expanded(
|
|
child: Text(
|
|
"Date",
|
|
// textAlign: TextAlign.center,
|
|
style: _headerStyle,
|
|
),
|
|
),
|
|
Expanded(
|
|
child: Text(
|
|
"Partner",
|
|
// textAlign: TextAlign.center,
|
|
style: _headerStyle,
|
|
),
|
|
),
|
|
Expanded(
|
|
child: Text(
|
|
"Reg.No.",
|
|
// textAlign: TextAlign.center,
|
|
style: _headerStyle,
|
|
),
|
|
),
|
|
Expanded(
|
|
child: Text(
|
|
"Insured Name",
|
|
// textAlign: TextAlign.center,
|
|
style: _headerStyle,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
const SizedBox(height: 8),
|
|
|
|
// List of rows
|
|
Flexible(
|
|
child: ListView.builder(
|
|
itemCount: data.length,
|
|
itemBuilder: (context, index) {
|
|
final row = data[index];
|
|
|
|
String date = "";
|
|
String time = "";
|
|
if ((row['created_on'] ?? "").isNotEmpty) {
|
|
final parts = row['created_on'].split(' ');
|
|
date = parts[0];
|
|
if (parts.isNotEmpty) {
|
|
DateTime parsedDate = DateTime.parse(parts[0]);
|
|
date = DateFormat(
|
|
'dd-MM-yyyy',
|
|
).format(parsedDate); // 19/09/2025
|
|
}
|
|
// time = parts.length > 1 ? parts[1] : "";
|
|
// Format the time part (HH:mm)
|
|
if (parts.length >= 2) {
|
|
final timeParts = parts[1].split(":");
|
|
time = "${timeParts[0]}:${timeParts[1]}"; // 05:45
|
|
} else {
|
|
time = "";
|
|
}
|
|
}
|
|
|
|
return InkWell(
|
|
focusColor: Color(0xFF3E5B56),
|
|
highlightColor: Color(0xFF3E5B56),
|
|
borderRadius: BorderRadius.circular(2), // for ripple effect
|
|
// onTap: () {
|
|
// handleDashboardNavigation(
|
|
// context,
|
|
// status: "To be assigned",
|
|
// staffId: row['staff_id'] ?? '',
|
|
// role: role,
|
|
// );
|
|
// },
|
|
onTap: () {
|
|
// Print the id when row is clicked
|
|
print("Clicked ID fd: ${row['id']}");
|
|
// You can also navigate or perform any action here
|
|
|
|
showDialog(
|
|
context: context,
|
|
builder: (ctx) => AssignStaffDialog(
|
|
enquiryPrimaryId: row['id'],
|
|
regNum: row['reg_no'],
|
|
userId: 1,
|
|
onSubmit: (value) {
|
|
debugPrint("New assignY: $value");
|
|
if (onRefresh != null) {
|
|
onRefresh!(); // ✅ call the parent's refresh
|
|
}
|
|
},
|
|
),
|
|
);
|
|
},
|
|
child: Container(
|
|
// height: 5200,
|
|
margin: const EdgeInsets.symmetric(vertical: 5),
|
|
padding: const EdgeInsets.symmetric(
|
|
vertical: 5,
|
|
horizontal: 12,
|
|
),
|
|
decoration: BoxDecoration(
|
|
color: Colors.white,
|
|
border: Border(
|
|
bottom: BorderSide(
|
|
color: Colors.blueGrey.shade100,
|
|
width: 0.3,
|
|
),
|
|
),
|
|
// borderRadius: BorderRadius.circular(10),
|
|
),
|
|
child: Row(
|
|
children: [
|
|
Expanded(
|
|
child: Column(
|
|
crossAxisAlignment: CrossAxisAlignment.start,
|
|
children: [
|
|
Text(date, style: _tableDataStyle),
|
|
Text(time, style: _tableDataTimeStyle),
|
|
],
|
|
),
|
|
),
|
|
Expanded(
|
|
child: Text(
|
|
row['agent_name'] ?? '', // convert int to string
|
|
// textAlign: TextAlign.center,
|
|
style: _tableDataStyle,
|
|
),
|
|
),
|
|
Expanded(
|
|
child: Text(
|
|
row['reg_no'] ?? "",
|
|
|
|
style: _tableDataStyle,
|
|
),
|
|
),
|
|
Expanded(
|
|
child: Text(
|
|
row['insured_name'] ?? "",
|
|
|
|
style: _tableDataStyle,
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
},
|
|
),
|
|
),
|
|
],
|
|
),
|
|
),
|
|
);
|
|
}
|
|
}
|
|
|
|
Future<void> handleDashboardNavigation(
|
|
BuildContext context, {
|
|
required String status,
|
|
String? staffId,
|
|
required String role,
|
|
}) async {
|
|
print('Dashboard Tap => Status: $status | Staff: $staffId');
|
|
|
|
final prefs = await SharedPreferences.getInstance();
|
|
|
|
// ✅ Clear any old data
|
|
await prefs.remove('dashboardKeyProvider');
|
|
await prefs.remove('dashboardStatusProvider');
|
|
await prefs.remove('dashboardStaffIdProvider');
|
|
|
|
// ✅ Save new values
|
|
await prefs.setString('dashboardKeyProvider', 'fromDashboard');
|
|
await prefs.setString('dashboardStatusProvider', status);
|
|
await prefs.setString('dashboardStaffIdProvider', staffId!);
|
|
|
|
context.go(AppRoutes.enquiryForStaff);
|
|
// // ✅ Navigate
|
|
// if (role == 'manager') {
|
|
// context.go(AppRoutes.enquiryForStaff);
|
|
// } else {
|
|
// context.go(AppRoutes.enquiryHandlerLst);
|
|
// }
|
|
}
|
|
|
|
final _headerStyle = GoogleFonts.inter(
|
|
fontWeight: FontWeight.w600,
|
|
fontSize: 11.5,
|
|
color: Colors.black,
|
|
);
|
|
|
|
final _title = GoogleFonts.inter(
|
|
fontWeight: FontWeight.bold,
|
|
fontSize: 11.5,
|
|
// color: Colors.red,
|
|
color: const Color(0xff425B5B),
|
|
);
|
|
|
|
final _tableDataStyle = GoogleFonts.inter(
|
|
fontSize: 11,
|
|
fontWeight: FontWeight.w500,
|
|
);
|
|
final _tableDataTimeStyle = GoogleFonts.inter(
|
|
fontSize: 10,
|
|
fontWeight: FontWeight.w400,
|
|
);
|
|
|
|
final topHeaderStyle = GoogleFonts.inter(
|
|
fontSize: 11,
|
|
color: Colors.black,
|
|
fontWeight: FontWeight.w500,
|
|
);
|
|
final _styleSmall1 = GoogleFonts.poppins(
|
|
fontSize: 10,
|
|
fontWeight: FontWeight.w400,
|
|
);
|
|
final _chartHeader = GoogleFonts.poppins(
|
|
fontSize: 11.5,
|
|
color: Colors.black,
|
|
fontWeight: FontWeight.w500,
|
|
);
|
|
|
|
|