This commit is contained in:
Surendiran 2026-04-04 14:21:39 +05:30
commit 725945d35b
7 changed files with 489 additions and 381 deletions

View File

@ -36,6 +36,7 @@ import '../../presentation/screens/home/home_screen.dart';
import '../../presentation/screens/login/login_screen.dart';
import '../../presentation/screens/payout/payout_screen.dart';
import '../../presentation/screens/payout/payout_details.dart';
import '../../presentation/screens/payout/payout_details_view.dart';
import '../../presentation/screens/payout/payout_list.dart';
import '../../presentation/screens/payout/payout_upload.dart';
import '../../presentation/screens/payout/payout_report.dart';
@ -99,9 +100,18 @@ final GoRouter appRouter = GoRouter(
),
GoRoute(
path: AppRoutes.payoutDetails,
builder: (context, state) => const PayOutDetails(),
),
GoRoute(
path: AppRoutes.payoutDetailsView,
builder: (context, state) {
final editItem = state.extra as Map<String, dynamic>?;
return PayOutDetails(editItem: editItem);
final extra = state.extra;
if (extra is Map) {
return PayOutDetailsView(
viewItem: Map<String, dynamic>.from(extra),
);
}
return PayOutDetailsView(viewItem: <String, dynamic>{});
},
),
GoRoute(

View File

@ -52,8 +52,8 @@ class AppRoutes {
static const String vehicleTypeLst = '/vehicleTypeLst';
static const String payoutList = '/payoutList';
static const String payoutDetails = '/payoutDetails';
static const String payoutDetailsView = '/payoutDetailsView';
static const String payoutUpload = '/payoutUpload';
/// Accounts + agent: commission payout report (list API TBD).
static const String payoutReport = '/payoutReport';
static const String payoutGrid = '/payoutGrid';
static const String gridList = '/gridList';

View File

@ -2061,8 +2061,7 @@ class ApiService {
// --------------------------------- PayOut Module----------------------------------------------
Future<Map<String, dynamic>> getCommissionRateList(data) async {
print("getCommissionRateList------- $data}");
final url = Uri.parse('${Env.apiUrl}/invoice/commission-rate-list');
// final url = Uri.parse('http://localhost/nhance_partner_be/invoice/commission-rate-list');
final url = Uri.parse('${Env.apiUrl}invoice/commission-rate-list');
print("getCommissionRateList 1");
// final token = await getToken(); // Fetch token

View File

@ -1,4 +1,3 @@
import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:flutter_riverpod/flutter_riverpod.dart';
@ -13,15 +12,10 @@ import '../../layouts/main_layout.dart';
import '../../layouts/responsive_layout.dart';
import '../../providers/manager_provider.dart';
import '../../providers/userRoleProvider.dart';
import '../../themes/indicators/input_field_decoration.dart';
import '../../themes/indicators/search_field_theme.dart';
import 'FormFieldBox.dart';
import 'custom_dateRange.dart';
class PayOutDetails extends ConsumerStatefulWidget {
final Map<String, dynamic>? editItem;
const PayOutDetails({super.key, this.editItem});
const PayOutDetails({super.key});
@override
ConsumerState<PayOutDetails> createState() => _PayOutDetailsState();
@ -47,12 +41,9 @@ class _PayOutDetailsState extends ConsumerState<PayOutDetails> {
dynamic totalPolicies = '0';
dynamic totalCommission = '0';
bool isEdit = false;
List<Map<String, dynamic>> masterPolicies = [];
final TextEditingController _searchStaffController = TextEditingController();
// --------------------------
// Filters
// --------------------------
@ -90,7 +81,6 @@ class _PayOutDetailsState extends ConsumerState<PayOutDetails> {
List<Map<String, dynamic>> filteredAgentData = [];
bool isLoading = false;
bool isLoadingEditData = false;
bool hasFetchedTableData = false;
final Set<int> _inlineSavingIds = <int>{};
late ApiService apiService;
@ -121,24 +111,6 @@ class _PayOutDetailsState extends ConsumerState<PayOutDetails> {
}
await getBroker();
// EDIT MODE (MUST be here)
if (widget.editItem != null) {
print('PD => editItemID ${widget.editItem}');
final invoiceID = widget.editItem!['id'];
controllers['invoiceNo']?.text =
widget.editItem!['invoice_no'];
controllers['invoiceDate']?.text =
widget.editItem!['invoice_date_ui_format'];
controllers['invoiceStatus']?.text =
widget.editItem!['payout_status'];
_loadEditData(invoiceID, managerId); // managerId ready
}
});
}
@ -175,9 +147,9 @@ class _PayOutDetailsState extends ConsumerState<PayOutDetails> {
(item['commission_amount'] ?? '').toString().toLowerCase().contains(
lowerQuery,
) ||
(_formatDate(item['issued_date']) ?? '').toLowerCase().contains(
lowerQuery,
);
_formatDate(item['issued_date']?.toString() ?? '')
.toLowerCase()
.contains(lowerQuery);
}).toList();
});
}
@ -200,138 +172,6 @@ class _PayOutDetailsState extends ConsumerState<PayOutDetails> {
});
}
void _loadEditData(String invoiceID, managerID) async {
setState(() => isLoadingEditData = true);
print("H010 => r : $roleId | mId: $managerID | ParmMID: $managerID | uId: $userId ");
print('PD => _loadEditData');
final jsondata = {
// "id": invoiceID,
"invoice_id": invoiceID,
"manager_id": managerId
// "issued_date": formattedTillDate,
};
print('PD => _loadEditData - $jsondata');
final response = await apiService.getCommissionRateList(jsondata);
// final response = await apiService.getInvoiceDetails(invoiceID);
if (response['status'] == 'success') {
print('PD => _loadEditData success');
print('PD => _loadEditData success - ${response['data']}');
final invoice = response['data'];
print("Invoice → $invoice");
// final items = List<Map<String, dynamic>>.from(response['data']['items']);
final items = response['data'];
final totPolicy = response['total_policies'].toString() ?? "0";
final totalCommiss = response['total_commission'];
setState(() {
// selectedPolicies = response['total_policies'];
isEdit = true;
totalPolicies = totPolicy;
totalCommission = totalCommiss;
// filteredPolicies = items.map((p) {
// final policyId = int.parse(p['policy_id']);
// return {...p, 'is_selected': selectedPolicies.contains(policyId)};
// }).toList();
final List<Map<String, dynamic>> items = (response['data'] as List)
.map((e) => Map<String, dynamic>.from(e))
.toList();
masterPolicies = List<Map<String, dynamic>>.from(response['data']);
filteredPolicies = List<Map<String, dynamic>>.from(response['data']);
print("selectedPolicies → $filteredPolicies ");
});
print(
"selectedPolicies → $selectedPolicies ->${response['total_policies']}",
);
print("Items → $items");
// -----------------------------
// 1. SET BASIC FIELDS
// -----------------------------
// setState(() {
// // selectedAgentId = int.tryParse(invoice['agent_id'].toString());
//
// // invoiceNoController.text = invoice['invoice_no'];
// // invoiceDate = DateTime.parse(invoice['invoice_date']);
//
// controllers['startDate']?.text = invoice['from_date'];
// controllers['endDate']?.text = invoice['to_date'];
// selectedBrokerID = int.tryParse(invoice['broker_id'].toString());
// if (invoice['agent_id'] is List) {
// selectedAgentId = (invoice['agent_id'] as List)
// .map((e) => e.toString())
// .toList();
// } else if (invoice['agent_id'] is String) {
// final raw = invoice['agent_id'].toString();
//
// if (raw.startsWith('[')) {
// // JSON string: "[1,2]"
// selectedAgentId = List<String>.from(
// jsonDecode(raw).map((e) => e.toString()),
// );
// } else if (raw.contains(',')) {
// // Comma separated: "1,2"
// selectedAgentId = raw.split(',').map((e) => e.trim()).toList();
// } else if (raw.isNotEmpty) {
// // Single value: "1"
// selectedAgentId = [raw];
// } else {
// selectedAgentId = [];
// }
// } else {
// selectedAgentId = [];
// }
//
// // if (invoice['till_date'] != "0000-00-00") {
// // policyTillDate = DateTime.parse(invoice['till_date']);
// // } else {
// // policyTillDate = DateTime.now();
// // }
// });
// print('PD => selectedBrokerID $selectedBrokerID');
// -----------------------------
// 3. LOAD ALL POLICIES FOR THIS BROKER + AGENT
// -----------------------------
// await loadPolicies();
// -----------------------------
// 2. SET SELECTED POLICIES
// -----------------------------
// selectedPolicies = items
// .map<int>((p) => int.parse(p['policy_id'].toString()))
// .toSet();
// -----------------------------
// 3. LOAD ALL POLICIES FOR THIS BROKER + AGENT
// -----------------------------
// await loadPolicies();
// -----------------------------
// 4. KEEP ONLY POLICIES THAT MATCH API DATA
// -----------------------------
// setState(() {
// filteredPolicies = filteredPolicies.map((p) {
// final policyId = int.parse(p['policy_id']);
// return {...p, 'is_selected': selectedPolicies.contains(policyId)};
// }).toList();
// });
}
setState(() => isLoadingEditData = false);
}
String formatDate(String date) {
final d = DateTime.parse(date);
return DateFormat('dd-MM-yyyy').format(d);
}
// Get Broker List
Future<void> getBroker() async {
print('PD =>getBroker called');
@ -452,7 +292,7 @@ class _PayOutDetailsState extends ConsumerState<PayOutDetails> {
"from_date": controllers['startDate']?.text,
"to_date": controllers['endDate']?.text,
"manager_id": managerId,
if (agentIds != null && agentIds.isNotEmpty) "agent_id": agentIds,
if (agentIds.isNotEmpty) "agent_id": agentIds,
// "agent_id": agentIds,
// "issued_date": formattedTillDate,
};
@ -672,13 +512,6 @@ class _PayOutDetailsState extends ConsumerState<PayOutDetails> {
}
}
String _displayText(dynamic value) {
if (value == null) return '-';
final text = value.toString().trim();
if (text.isEmpty || text.toLowerCase() == 'null') return '-';
return text;
}
List<Map<String, dynamic>> _buildUtrPayloadForSelectedPolicies({
required String defaultUtrDate,
}) {
@ -770,23 +603,11 @@ class _PayOutDetailsState extends ConsumerState<PayOutDetails> {
@override
Widget build(BuildContext context) {
final df = DateFormat("dd-MM-yyyy");
final int status =
int.tryParse(controllers['invoiceStatus']?.text ?? '0') ?? 0;
final bool isPending = status == 1;
return MainLayout(
title: "Pay Out",
body: !isLoadingEditData
? Container(
body: Container(
color: Colors.white,
padding: const EdgeInsets.all(8),
margin: isEdit
? EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width * 0.1,
)
: null,
child: Column(
children: [
// const SizedBox(height: 20),
@ -828,60 +649,6 @@ class _PayOutDetailsState extends ConsumerState<PayOutDetails> {
),
),
// 🟢 Status Chip
if (isEdit) ...[
Spacer(),
Text(
controllers['invoiceNo']?.text ?? '',
style: GoogleFonts.inter(
fontSize: 13,
fontWeight: FontWeight.w500,
color: const Color(0xFF374151),
),
),
SizedBox(width: 10),
Text(
// controllers['invoiceDate']?.text ?? '',
'(${controllers['invoiceDate']?.text ?? ''})',
style: GoogleFonts.inter(
fontSize: 11,
fontWeight: FontWeight.w300,
color: const Color(0xFF6B7280),
),
),
// SizedBox(width: 10),
// Spacer(),
SizedBox(width: 10),
Text(
'Status: ${isPending ? 'Pending' : 'Completed'}',
style: GoogleFonts.inter(
fontSize: 11,
fontWeight: FontWeight.w300,
color: const Color(0xFF6B7280),
// color: isPending
// ? Colors.blueAccent
// : const Color(0xFF047857),
),
),
Spacer(),
ThemedSearchField(
hintText: 'Search',
// backgroundColor: Color(0xFFF6F8F8),
onChanged: filterPolicyData,
controller: _searchStaffController,
backgroundColor: Color(0xFFFFFFFF),
txtHeight: 30,
txtwidth: ResponsiveLayout.isMobile(context)
? MediaQuery.of(context).size.width * 0.7
: MediaQuery.of(context).size.width * 0.15,
),
],
if (!isEdit) ...[
const Spacer(),
if (hasFetchedTableData) ...[
const SizedBox(width: 10),
@ -971,13 +738,11 @@ class _PayOutDetailsState extends ConsumerState<PayOutDetails> {
const SizedBox(width: 10),
],
],
],
),
),
),
// SizedBox(height: 5),
if (!isEdit) ...[
Container(
padding: EdgeInsets.all(8.0),
child: DateFilterRowPayout(
@ -1017,7 +782,6 @@ class _PayOutDetailsState extends ConsumerState<PayOutDetails> {
),
SizedBox(height: 10),
],
// Policy Selection
Card(
// color: Colors.amber,
@ -1157,80 +921,10 @@ class _PayOutDetailsState extends ConsumerState<PayOutDetails> {
),
),
],
if (isEdit) ...[
Container(
padding: const EdgeInsets.all(8),
// color: Colors.amber,
color: Color(0xFFf9fafb),
// color: Colors.white,
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
// mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
// selectedPolicies.length.toString(),
totalPolicies,
style: GoogleFonts.poppins(
fontSize: 12,
fontWeight: FontWeight.w500,
color: Colors.blueGrey,
),
),
const SizedBox(width: 4),
Text(
"policies selected",
style: GoogleFonts.poppins(
fontSize: 12,
fontWeight: FontWeight.w500,
color: Colors.blueGrey,
),
),
const SizedBox(width: 4),
Text(
"|",
style: GoogleFonts.poppins(
fontSize: 12,
fontWeight: FontWeight.w500,
color: Colors.blueGrey,
),
),
const SizedBox(width: 4),
Text(
"Total Payout Amount",
style: GoogleFonts.poppins(
fontSize: 12,
fontWeight: FontWeight.w500,
color: Colors.blueGrey,
),
),
const SizedBox(width: 4),
/// NULL-SAFE TOTAL COMMISSION CALCULATION
Text(
// "${_calculateTotalCommission()}",
"$totalCommission",
style: GoogleFonts.poppins(
fontSize: 14,
fontWeight: FontWeight.w500,
color: Colors.teal,
),
),
const SizedBox(width: 10),
],
),
),
],
// ----------------------
// const SizedBox(height: 100),
],
),
)
: Container(
color: Colors.white,
height: MediaQuery.of(context).size.height * 0.7,
child: Center(child: CircularProgressIndicator()),
),
);
}
@ -1265,7 +959,6 @@ class _PayOutDetailsState extends ConsumerState<PayOutDetails> {
),
child: Row(
children: [
if (!isEdit) ...[
SizedBox(
width: colCheck,
child: Checkbox(
@ -1284,11 +977,6 @@ class _PayOutDetailsState extends ConsumerState<PayOutDetails> {
)
.where((id) => id != 0) // Filter out invalid IDs
.toSet();
// selectedPolicies = filteredPolicies
// .map(
// (p) => int.tryParse(p["policy_id"].toString()) ?? 0,
// )
// .toSet();
} else {
selectedPolicies.clear();
}
@ -1298,7 +986,6 @@ class _PayOutDetailsState extends ConsumerState<PayOutDetails> {
},
),
),
],
_headerText("POLICY NO", colPolicy),
_headerText("POLICY DATE", colDate),
_headerText("PARTNER", colAgent),
@ -1327,10 +1014,7 @@ class _PayOutDetailsState extends ConsumerState<PayOutDetails> {
Widget _policyTableBody() {
return SizedBox(
// height: isEdit ? 400 : 340, // avoids overflow
height: isEdit
? MediaQuery.of(context).size.height * 0.65
: MediaQuery.of(context).size.height * 0.48, // avoids overflow
height: MediaQuery.of(context).size.height * 0.48,
child: ListView.builder(
itemCount: filteredPolicies.length,
itemBuilder: (context, index) {
@ -1362,7 +1046,6 @@ class _PayOutDetailsState extends ConsumerState<PayOutDetails> {
),
child: Row(
children: [
if (!isEdit) ...[
SizedBox(
width: colCheck,
child: Checkbox(
@ -1378,7 +1061,6 @@ class _PayOutDetailsState extends ConsumerState<PayOutDetails> {
},
),
),
],
_cell(p["policy_no"], colPolicy),
// _cell(p["issued_date"] ?? "-", colDate),
_cell(_formatDate(p['issued_date']), colDate),
@ -1612,16 +1294,15 @@ class _PayOutDetailsState extends ConsumerState<PayOutDetails> {
}
static final double colCheck = 44;
double get colPolicy => isEdit ? 150 : 200;
double get colDate => isEdit ? 120 : 200;
static final double colPolicy = 200;
static final double colDate = 200;
static final double colAgent = 200;
static final double colCustomer = 200;
static final double colPremium = 200;
// static final double colCommission = 200;
static final double colCommission = 200;
double get colCommission => isEdit ? 120 : 200;
double get _tableMinWidth =>
(isEdit ? 0 : colCheck) +
colCheck +
colPolicy +
colDate +
colAgent +

View File

@ -0,0 +1,419 @@
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 '../../../core/routing/routes.dart';
import '../../../core/services/api_service.dart';
import '../../layouts/main_layout.dart';
import '../../layouts/responsive_layout.dart';
import '../../providers/manager_provider.dart';
import '../../themes/indicators/search_field_theme.dart';
/// Read-only payout invoice + policy lines (opened from payout list View).
class PayOutDetailsView extends ConsumerStatefulWidget {
final Map<String, dynamic> viewItem;
const PayOutDetailsView({super.key, required this.viewItem});
@override
ConsumerState<PayOutDetailsView> createState() => _PayOutDetailsViewState();
}
class _PayOutDetailsViewState extends ConsumerState<PayOutDetailsView> {
final TextEditingController _searchStaffController = TextEditingController();
List<Map<String, dynamic>> masterPolicies = [];
List<Map<String, dynamic>> filteredPolicies = [];
bool isLoading = false;
late ApiService apiService;
dynamic managerId;
dynamic totalPolicies = '0';
dynamic totalCommission = '0';
static const double colPolicy = 150;
static const double colDate = 120;
static const double colAgent = 200;
static const double colCustomer = 200;
static const double colPremium = 200;
static const double colCommission = 120;
double get _tableMinWidth =>
colPolicy + colDate + colAgent + colCustomer + colPremium + colCommission + 32;
@override
void initState() {
super.initState();
apiService = ApiService();
Future.microtask(() {
managerId = ref.read(managerIdProvider);
_loadInvoicePolicies();
});
}
@override
void dispose() {
_searchStaffController.dispose();
super.dispose();
}
Future<void> _loadInvoicePolicies() async {
final invoiceId = widget.viewItem['id'];
if (invoiceId == null) {
setState(() {
filteredPolicies = [];
masterPolicies = [];
});
return;
}
setState(() => isLoading = true);
try {
final jsondata = {
'invoice_id': invoiceId,
'manager_id': managerId,
};
final response = await apiService.getCommissionRateList(jsondata);
if (response['status'] == 'success') {
final totPolicy = (response['total_policies'] ?? 0).toString();
final totalCommiss = response['total_commission'];
setState(() {
totalPolicies = totPolicy;
totalCommission = totalCommiss;
masterPolicies = List<Map<String, dynamic>>.from(response['data'] ?? []);
filteredPolicies = List<Map<String, dynamic>>.from(response['data'] ?? []);
});
} else {
setState(() {
masterPolicies = [];
filteredPolicies = [];
});
}
} catch (_) {
setState(() {
masterPolicies = [];
filteredPolicies = [];
});
} finally {
if (mounted) setState(() => isLoading = false);
}
}
void filterPolicyData(String query) {
final lowerQuery = query.toLowerCase();
setState(() {
if (query.trim().isEmpty) {
filteredPolicies = List.from(masterPolicies);
return;
}
filteredPolicies = masterPolicies.where((item) {
return (item['policy_no'] ?? '').toString().toLowerCase().contains(lowerQuery) ||
(item['customer_name'] ?? '').toString().toLowerCase().contains(lowerQuery) ||
(item['agent_name'] ?? '').toString().toLowerCase().contains(lowerQuery) ||
(item['insurer_name'] ?? '').toString().toLowerCase().contains(lowerQuery) ||
(item['premium_amount'] ?? '').toString().toLowerCase().contains(lowerQuery) ||
(item['commission_amount'] ?? '').toString().toLowerCase().contains(lowerQuery) ||
_formatDate(item['issued_date']?.toString() ?? '')
.toLowerCase()
.contains(lowerQuery);
}).toList();
});
}
String _displayText(dynamic value) {
if (value == null) return '-';
final text = value.toString().trim();
if (text.isEmpty || text.toLowerCase() == 'null') return '-';
return text;
}
String _invoiceDateLabel() {
final ui = widget.viewItem['invoice_date_ui_format'];
if (ui != null && ui.toString().trim().isNotEmpty) {
return ui.toString();
}
final raw = widget.viewItem['invoice_date'];
if (raw == null) return '-';
try {
return DateFormat('dd-MM-yyyy').format(DateTime.parse(raw.toString()));
} catch (_) {
return raw.toString();
}
}
String _formatDate(String? rawDate) {
if (rawDate == null || rawDate.isEmpty) return '-';
try {
return DateFormat('dd-MM-yyyy').format(DateTime.parse(rawDate));
} catch (_) {
return rawDate;
}
}
Widget _headerText(String text, double width) {
return SizedBox(
width: width,
child: Text(
text,
style: GoogleFonts.poppins(
fontSize: 11,
fontWeight: FontWeight.w500,
color: Colors.blueGrey,
letterSpacing: 0.5,
),
),
);
}
Widget _cell(String? value, double width) {
return SizedBox(
width: width,
child: Text(
value ?? '-',
overflow: TextOverflow.ellipsis,
style: const TextStyle(fontSize: 11),
),
);
}
Widget _policyTableHeader() {
return Container(
height: 30,
padding: const EdgeInsets.symmetric(horizontal: 16),
decoration: const BoxDecoration(
color: Color(0xFFf9fafb),
border: Border(bottom: BorderSide(color: Color(0xFFf9fafb))),
),
child: Row(
children: [
_headerText('POLICY NO', colPolicy),
_headerText('POLICY DATE', colDate),
_headerText('PARTNER', colAgent),
_headerText('CUSTOMER', colCustomer),
_headerText('PREMIUM', colPremium),
_headerText('PAYOUT', colCommission),
],
),
);
}
Widget _policyTableBody() {
return SizedBox(
height: MediaQuery.of(context).size.height * 0.65,
child: ListView.builder(
itemCount: filteredPolicies.length,
itemBuilder: (context, index) {
final p = filteredPolicies[index];
return Container(
height: 38,
padding: const EdgeInsets.symmetric(horizontal: 16),
decoration: const BoxDecoration(
color: Colors.white,
border: Border(bottom: BorderSide(color: Color(0xFFf9fafb))),
),
child: Row(
children: [
_cell(p['policy_no']?.toString(), colPolicy),
_cell(_formatDate(p['issued_date']?.toString()), colDate),
_cell(
(p['agent_code'] != null && p['agent_name'] != null)
? '${p['agent_code']} - ${p['agent_name']}'
: (p['agent_name'] ?? '-').toString(),
colAgent,
),
_cell(p['customer_name']?.toString(), colCustomer),
_cell('${p['premium_amount']}', colPremium),
SizedBox(
width: colCommission,
child: Text(
'${_displayText(p['commission_amount'])}',
overflow: TextOverflow.ellipsis,
style: const TextStyle(
fontSize: 11,
fontWeight: FontWeight.w600,
color: Color(0xFF009B77),
),
),
),
],
),
);
},
),
);
}
@override
Widget build(BuildContext context) {
final statusRaw = widget.viewItem['payout_status'];
final statusInt = int.tryParse(statusRaw?.toString() ?? '0') ?? 0;
final isPending = statusInt == 1;
final invoiceNo = _displayText(widget.viewItem['invoice_no']);
return MainLayout(
title: 'Pay Out',
body: isLoading
? Container(
color: Colors.white,
height: MediaQuery.of(context).size.height * 0.7,
child: const Center(child: CircularProgressIndicator()),
)
: Container(
color: Colors.white,
padding: const EdgeInsets.all(8),
margin: EdgeInsets.symmetric(
horizontal: MediaQuery.of(context).size.width * 0.1,
),
child: Column(
children: [
SizedBox(
height: 40,
width: MediaQuery.of(context).size.width,
child: Row(
crossAxisAlignment: CrossAxisAlignment.center,
children: [
Tooltip(
message: 'Back',
child: IconButton(
icon: const Icon(
Icons.arrow_left_sharp,
size: 25,
color: Color(0xFF425B5B),
),
onPressed: () => context.go(AppRoutes.payoutList),
splashRadius: 18,
hoverColor: Colors.black12,
padding: const EdgeInsets.all(4),
constraints: const BoxConstraints(),
),
),
const SizedBox(width: 5),
Text(
'View Payout Details',
style: GoogleFonts.inter(
fontSize: 14,
fontWeight: FontWeight.w500,
),
),
const Spacer(),
Text(
invoiceNo,
style: GoogleFonts.inter(
fontSize: 13,
fontWeight: FontWeight.w500,
color: const Color(0xFF374151),
),
),
const SizedBox(width: 10),
Text(
'(${_invoiceDateLabel()})',
style: GoogleFonts.inter(
fontSize: 11,
fontWeight: FontWeight.w300,
color: const Color(0xFF6B7280),
),
),
const SizedBox(width: 10),
Text(
'Status: ${isPending ? 'Pending' : 'Completed'}',
style: GoogleFonts.inter(
fontSize: 11,
fontWeight: FontWeight.w300,
color: const Color(0xFF6B7280),
),
),
const Spacer(),
ThemedSearchField(
hintText: 'Search',
onChanged: filterPolicyData,
controller: _searchStaffController,
backgroundColor: const Color(0xFFFFFFFF),
txtHeight: 30,
txtwidth: ResponsiveLayout.isMobile(context)
? MediaQuery.of(context).size.width * 0.7
: MediaQuery.of(context).size.width * 0.15,
),
],
),
),
Card(
color: Colors.white,
shape: RoundedRectangleBorder(
borderRadius: BorderRadius.circular(12),
),
elevation: 0,
child: SingleChildScrollView(
scrollDirection: Axis.horizontal,
child: SizedBox(
width: _tableMinWidth,
child: Column(
children: [
_policyTableHeader(),
_policyTableBody(),
],
),
),
),
),
Container(
padding: const EdgeInsets.all(8),
color: const Color(0xFFf9fafb),
child: Row(
mainAxisAlignment: MainAxisAlignment.end,
children: [
Text(
'$totalPolicies',
style: GoogleFonts.poppins(
fontSize: 12,
fontWeight: FontWeight.w500,
color: Colors.blueGrey,
),
),
const SizedBox(width: 4),
Text(
'policies',
style: GoogleFonts.poppins(
fontSize: 12,
fontWeight: FontWeight.w500,
color: Colors.blueGrey,
),
),
const SizedBox(width: 4),
Text(
'|',
style: GoogleFonts.poppins(
fontSize: 12,
fontWeight: FontWeight.w500,
color: Colors.blueGrey,
),
),
const SizedBox(width: 4),
Text(
'Total Payout Amount',
style: GoogleFonts.poppins(
fontSize: 12,
fontWeight: FontWeight.w500,
color: Colors.blueGrey,
),
),
const SizedBox(width: 4),
Text(
'$totalCommission',
style: GoogleFonts.poppins(
fontSize: 14,
fontWeight: FontWeight.w500,
color: Colors.teal,
),
),
],
),
),
],
),
),
);
}
}

View File

@ -1015,9 +1015,8 @@ class _PayoutListState extends ConsumerState<PayoutList> {
),
tooltip: 'View Payout',
onPressed: () {
// TODO: handle edit
context.go(AppRoutes.payoutDetails, extra: item);
print("PL 9 => Edit clicked for ${item['invoice_no']}");
context.go(AppRoutes.payoutDetailsView, extra: item);
print("PL 9 => View clicked for ${item['invoice_no']}");
},
splashRadius: 16,
hoverColor: Colors.black12,