FIX_Grid View
This commit is contained in:
parent
cb9c84bf0b
commit
780159f380
File diff suppressed because one or more lines are too long
@ -922,7 +922,6 @@ class ApiService {
|
||||
String? vehicleType,
|
||||
String? segment,
|
||||
String? rto,
|
||||
String? planType,
|
||||
String? search,
|
||||
String? loggedId,
|
||||
}) async {
|
||||
@ -936,7 +935,6 @@ class ApiService {
|
||||
final vehicleTypeTrimmed = vehicleType?.trim();
|
||||
final segmentTrimmed = segment?.trim();
|
||||
final rtoTrimmed = rto?.trim();
|
||||
final planTypeTrimmed = planType?.trim();
|
||||
final searchTrimmed = search?.trim();
|
||||
final loggedIdTrimmed = loggedId?.trim();
|
||||
final endpoint = Uri.parse('${Env.apiUrl}grid');
|
||||
@ -963,9 +961,6 @@ class ApiService {
|
||||
if (rtoTrimmed != null && rtoTrimmed.isNotEmpty) {
|
||||
queryParameters['rto'] = rtoTrimmed;
|
||||
}
|
||||
if (planTypeTrimmed != null && planTypeTrimmed.isNotEmpty) {
|
||||
queryParameters['plan_type'] = planTypeTrimmed;
|
||||
}
|
||||
if (searchTrimmed != null && searchTrimmed.isNotEmpty) {
|
||||
queryParameters['search'] = searchTrimmed;
|
||||
}
|
||||
@ -988,7 +983,6 @@ class ApiService {
|
||||
String? vehicleType,
|
||||
String? segment,
|
||||
String? rto,
|
||||
String? planType,
|
||||
String? search,
|
||||
String? loggedId,
|
||||
}) async {
|
||||
@ -1007,13 +1001,17 @@ class ApiService {
|
||||
}
|
||||
}
|
||||
|
||||
final downloadRoleLc = role?.trim().toLowerCase();
|
||||
|
||||
addQuery('role', role);
|
||||
addQuery('file_id', fileId);
|
||||
// Manager / Accounts use file_id; Agent uses logged_id only (same as loadPayoutGrid).
|
||||
if (downloadRoleLc != 'agent') {
|
||||
addQuery('file_id', fileId);
|
||||
}
|
||||
addQuery('insurer', insurer);
|
||||
addQuery('vehicle_type', vehicleType);
|
||||
addQuery('segment', segment);
|
||||
addQuery('rto', rto);
|
||||
addQuery('plan_type', planType);
|
||||
addQuery('search', search);
|
||||
addQuery('logged_id', loggedId);
|
||||
|
||||
|
||||
@ -33,9 +33,14 @@ class gridViewScreen extends ConsumerStatefulWidget {
|
||||
}
|
||||
|
||||
class _gridViewScreenState extends ConsumerState<gridViewScreen> {
|
||||
static const String _defaultVehicleTypeLabel = 'TWO WHEELER NEW';
|
||||
|
||||
final ApiService _apiService = ApiService();
|
||||
String? _loggedId;
|
||||
|
||||
/// `file_id` from the last successful Manager/Accounts grid load (export matches this).
|
||||
String? _gridFileIdUsed;
|
||||
|
||||
bool _isLoading = false;
|
||||
|
||||
// API response
|
||||
@ -43,7 +48,6 @@ class _gridViewScreenState extends ConsumerState<gridViewScreen> {
|
||||
List<Map<String, dynamic>> _filteredGrid = [];
|
||||
|
||||
List<String> _insurers = [];
|
||||
List<Map<String, dynamic>> _planTypes = [];
|
||||
List<String> _rtos = [];
|
||||
List<String> _vehicleTypes = [];
|
||||
List<String> _segments = [];
|
||||
@ -53,7 +57,6 @@ class _gridViewScreenState extends ConsumerState<gridViewScreen> {
|
||||
String? _selectedRto;
|
||||
String? _selectedVehicleType;
|
||||
String? _selectedSegment;
|
||||
String? _selectedPlanTypeValue; // comp/tp/od
|
||||
|
||||
final TextEditingController _searchController = TextEditingController();
|
||||
final TextEditingController _editVehicleTypeController =
|
||||
@ -267,32 +270,63 @@ class _gridViewScreenState extends ConsumerState<gridViewScreen> {
|
||||
final queryFileId = queryParams['file_id']?.trim();
|
||||
final effectiveRole =
|
||||
(queryRole != null && queryRole.isNotEmpty) ? queryRole : apiRole;
|
||||
String? effectiveFileId =
|
||||
(queryFileId != null && queryFileId.isNotEmpty) ? queryFileId : null;
|
||||
final roleLc = (effectiveRole ?? '').toLowerCase();
|
||||
|
||||
if (effectiveFileId == null &&
|
||||
(effectiveRole?.toLowerCase() == 'manager' ||
|
||||
effectiveRole?.toLowerCase() == 'agent' ||
|
||||
effectiveRole?.toLowerCase() == 'accounts')) {
|
||||
final fileListRes = await _apiService.fetchGridFileList();
|
||||
if ((fileListRes['status'] ?? '').toString().toLowerCase() ==
|
||||
'success') {
|
||||
final files = List<Map<String, dynamic>>.from(
|
||||
fileListRes['data'] ?? const [],
|
||||
);
|
||||
if (files.isNotEmpty) {
|
||||
files.sort((a, b) {
|
||||
final left = int.tryParse(a['id']?.toString() ?? '') ?? 0;
|
||||
final right = int.tryParse(b['id']?.toString() ?? '') ?? 0;
|
||||
return right.compareTo(left);
|
||||
});
|
||||
effectiveFileId = files.first['id']?.toString();
|
||||
// Manager / Accounts: require file_id (URL or latest from file list).
|
||||
// Agent: never send file_id; require logged-in user id for retention.
|
||||
String? effectiveFileId;
|
||||
if (roleLc == 'agent') {
|
||||
effectiveFileId = null;
|
||||
} else {
|
||||
effectiveFileId =
|
||||
(queryFileId != null && queryFileId.isNotEmpty) ? queryFileId : null;
|
||||
|
||||
if (effectiveFileId == null &&
|
||||
(roleLc == 'manager' || roleLc == 'accounts')) {
|
||||
final fileListRes = await _apiService.fetchGridFileList();
|
||||
if ((fileListRes['status'] ?? '').toString().toLowerCase() ==
|
||||
'success') {
|
||||
final files = List<Map<String, dynamic>>.from(
|
||||
fileListRes['data'] ?? const [],
|
||||
);
|
||||
if (files.isNotEmpty) {
|
||||
files.sort((a, b) {
|
||||
final left = int.tryParse(a['id']?.toString() ?? '') ?? 0;
|
||||
final right = int.tryParse(b['id']?.toString() ?? '') ?? 0;
|
||||
return right.compareTo(left);
|
||||
});
|
||||
effectiveFileId = files.first['id']?.toString();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (roleLc == 'manager' || roleLc == 'accounts') {
|
||||
if (effectiveFileId == null || effectiveFileId.trim().isEmpty) {
|
||||
if (mounted) {
|
||||
ToastHelper.showErrorToast(
|
||||
context,
|
||||
'No grid file found. Open grid from a file or upload a payout grid first.',
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
final loggedIdForGrid =
|
||||
(effectiveRole ?? '').toLowerCase() == 'agent' ? _loggedId : null;
|
||||
if (roleLc == 'agent') {
|
||||
final lid = _loggedId?.trim();
|
||||
if (lid == null || lid.isEmpty) {
|
||||
if (mounted) {
|
||||
ToastHelper.showErrorToast(
|
||||
context,
|
||||
'Unable to load grid: missing logged-in user id.',
|
||||
);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
final loggedIdForGrid = roleLc == 'agent' ? _loggedId?.trim() : null;
|
||||
|
||||
final res = await _apiService.loadPayoutGrid(
|
||||
role: effectiveRole,
|
||||
@ -300,6 +334,9 @@ class _gridViewScreenState extends ConsumerState<gridViewScreen> {
|
||||
loggedId: loggedIdForGrid,
|
||||
);
|
||||
if ((res['status'] ?? '').toString().toLowerCase() != 'success') {
|
||||
if (mounted) {
|
||||
setState(() => _gridFileIdUsed = null);
|
||||
}
|
||||
ToastHelper.showErrorToast(
|
||||
context,
|
||||
res['data']?.toString() ?? 'Failed to load payout grid',
|
||||
@ -310,7 +347,6 @@ class _gridViewScreenState extends ConsumerState<gridViewScreen> {
|
||||
final payload = _extractPayload(res);
|
||||
final grid = payload['grid'];
|
||||
final insurers = payload['insurers'];
|
||||
final planTypes = payload['plan_types'];
|
||||
final rtos = payload['rtos'];
|
||||
final vehicleTypes = payload['vehicle_types'];
|
||||
final segments = payload['segments'];
|
||||
@ -325,13 +361,19 @@ class _gridViewScreenState extends ConsumerState<gridViewScreen> {
|
||||
_filteredGrid = List<Map<String, dynamic>>.from(_grid);
|
||||
|
||||
_insurers = _toStringList(insurers);
|
||||
_planTypes = _toPlanTypeList(planTypes);
|
||||
_rtos = _toStringList(rtos);
|
||||
_vehicleTypes = _toStringList(vehicleTypes);
|
||||
_segments = _toStringList(segments);
|
||||
|
||||
_gridFileIdUsed =
|
||||
(roleLc == 'manager' || roleLc == 'accounts') ? effectiveFileId : null;
|
||||
|
||||
_applyDefaultVehicleTypeSelection();
|
||||
_applyFilters();
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
setState(() => _gridFileIdUsed = null);
|
||||
}
|
||||
ToastHelper.showErrorToast(context, e.toString());
|
||||
} finally {
|
||||
if (mounted) setState(() => _isLoading = false);
|
||||
@ -381,25 +423,18 @@ class _gridViewScreenState extends ConsumerState<gridViewScreen> {
|
||||
.toList();
|
||||
}
|
||||
|
||||
List<Map<String, dynamic>> _toPlanTypeList(dynamic raw) {
|
||||
if (raw is! List) return <Map<String, dynamic>>[];
|
||||
return raw.map<Map<String, dynamic>>((item) {
|
||||
if (item is Map) {
|
||||
final map = item.cast<String, dynamic>();
|
||||
final value = map['value']?.toString() ??
|
||||
map['id']?.toString() ??
|
||||
map['key']?.toString() ??
|
||||
'';
|
||||
final label = map['label']?.toString() ??
|
||||
map['name']?.toString() ??
|
||||
map['title']?.toString() ??
|
||||
map['value']?.toString() ??
|
||||
value;
|
||||
return {'value': value, 'label': label};
|
||||
/// Sets [_selectedVehicleType] to the dropdown spelling that matches
|
||||
/// [_defaultVehicleTypeLabel], or prepends that label if the API omits it.
|
||||
void _applyDefaultVehicleTypeSelection() {
|
||||
final desiredLower = _defaultVehicleTypeLabel.toLowerCase();
|
||||
for (final v in _vehicleTypes) {
|
||||
if (v.trim().toLowerCase() == desiredLower) {
|
||||
_selectedVehicleType = v;
|
||||
return;
|
||||
}
|
||||
final v = item?.toString() ?? '';
|
||||
return {'value': v, 'label': v.toUpperCase()};
|
||||
}).where((e) => (e['value']?.toString().trim().isNotEmpty ?? false)).toList();
|
||||
}
|
||||
_vehicleTypes = [_defaultVehicleTypeLabel, ..._vehicleTypes];
|
||||
_selectedVehicleType = _defaultVehicleTypeLabel;
|
||||
}
|
||||
|
||||
void _applyFilters() {
|
||||
@ -411,20 +446,6 @@ class _gridViewScreenState extends ConsumerState<gridViewScreen> {
|
||||
return raw?.toString().toLowerCase() == selected.toLowerCase();
|
||||
}
|
||||
|
||||
bool matchesPlanType() {
|
||||
if (_selectedPlanTypeValue == null) return true;
|
||||
final raw = row[_selectedPlanTypeValue];
|
||||
if (raw == null) return false;
|
||||
final s = raw.toString().trim().toLowerCase();
|
||||
if (s.isEmpty || s == 'null' || s == '-') return false;
|
||||
|
||||
// Treat 0 payout as "not configured" so it doesn't match plan filters.
|
||||
final n = num.tryParse(s);
|
||||
if (n != null) return n != 0;
|
||||
|
||||
return s != '0';
|
||||
}
|
||||
|
||||
bool matchesSearch() {
|
||||
if (q.isEmpty) return true;
|
||||
final values = <String>[
|
||||
@ -447,7 +468,6 @@ class _gridViewScreenState extends ConsumerState<gridViewScreen> {
|
||||
equalsOrAll(_selectedVehicleType, row['vehicle_type']) &&
|
||||
equalsOrAll(_selectedSegment, row['segment']) &&
|
||||
equalsOrAll(_selectedRto, row['rto']) &&
|
||||
matchesPlanType() &&
|
||||
matchesSearch();
|
||||
}).toList();
|
||||
|
||||
@ -591,24 +611,13 @@ class _gridViewScreenState extends ConsumerState<gridViewScreen> {
|
||||
|
||||
bool get _showPartnerRetentionValues =>
|
||||
_showAddButton || _accountsAgentPreview;
|
||||
bool get _showCompColumnForAgent =>
|
||||
!_showAddButton ||
|
||||
_selectedPlanTypeValue == 'comp';
|
||||
bool get _showTpColumnForAgent =>
|
||||
!_showAddButton ||
|
||||
_selectedPlanTypeValue == 'tp';
|
||||
bool get _showOdColumnForAgent =>
|
||||
!_showAddButton ||
|
||||
_selectedPlanTypeValue == 'od';
|
||||
|
||||
bool get _hasAnyFilterSelection {
|
||||
return (_selectedInsurer != null && _selectedInsurer!.trim().isNotEmpty) ||
|
||||
(_selectedRto != null && _selectedRto!.trim().isNotEmpty) ||
|
||||
(_selectedVehicleType != null &&
|
||||
_selectedVehicleType!.trim().isNotEmpty) ||
|
||||
(_selectedSegment != null && _selectedSegment!.trim().isNotEmpty) ||
|
||||
(_selectedPlanTypeValue != null &&
|
||||
_selectedPlanTypeValue!.trim().isNotEmpty);
|
||||
(_selectedSegment != null && _selectedSegment!.trim().isNotEmpty);
|
||||
}
|
||||
|
||||
String _toEditText(dynamic value) {
|
||||
@ -766,17 +775,6 @@ class _gridViewScreenState extends ConsumerState<gridViewScreen> {
|
||||
Widget _buildFilterBar(BuildContext context) {
|
||||
final isMobile = ResponsiveLayout.isMobile(context);
|
||||
|
||||
final planTypeItems = List<Map<String, dynamic>>.from(_planTypes);
|
||||
Map<String, dynamic>? selectedPlanType;
|
||||
if (_selectedPlanTypeValue != null) {
|
||||
for (final e in planTypeItems) {
|
||||
if ((e['value'] as String?) == _selectedPlanTypeValue) {
|
||||
selectedPlanType = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Widget dropdownInsurer() {
|
||||
return SizedBox(
|
||||
width: isMobile ? double.infinity : 200,
|
||||
@ -811,46 +809,6 @@ class _gridViewScreenState extends ConsumerState<gridViewScreen> {
|
||||
);
|
||||
}
|
||||
|
||||
Widget dropdownPlanType() {
|
||||
return SizedBox(
|
||||
width: isMobile ? double.infinity : 220,
|
||||
height: 40,
|
||||
child: DropdownSearch<Map<String, dynamic>>(
|
||||
items: (filter, infiniteScrollProps) {
|
||||
final items = planTypeItems;
|
||||
if (filter.isEmpty) return items;
|
||||
return items
|
||||
.where((e) =>
|
||||
(e['label']?.toString() ?? '')
|
||||
.toLowerCase()
|
||||
.contains(filter.toLowerCase()))
|
||||
.toList();
|
||||
},
|
||||
selectedItem: selectedPlanType,
|
||||
itemAsString: (item) => item['label']?.toString() ?? '',
|
||||
compareFn: (a, b) => (a['value'] == b['value']),
|
||||
popupProps: const PopupProps.menu(
|
||||
showSearchBox: true,
|
||||
fit: FlexFit.loose,
|
||||
),
|
||||
dropdownBuilder: (context, selectedItem) => Padding(
|
||||
padding: const EdgeInsets.only(left: 10),
|
||||
child: Text(
|
||||
selectedItem?['label']?.toString() ?? '',
|
||||
style: GoogleFonts.poppins(fontSize: 12, color: Colors.black),
|
||||
overflow: TextOverflow.ellipsis,
|
||||
),
|
||||
),
|
||||
onChanged: (val) => _setFilter(() {
|
||||
_selectedPlanTypeValue = val?['value'] as String?;
|
||||
}),
|
||||
decoratorProps: DropDownDecoratorProps(
|
||||
decoration: _dropdownDecoration('Plan Type'),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget dropdownRto() {
|
||||
return SizedBox(
|
||||
width: isMobile ? double.infinity : 180,
|
||||
@ -974,11 +932,10 @@ class _gridViewScreenState extends ConsumerState<gridViewScreen> {
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_selectedInsurer = null;
|
||||
_selectedPlanTypeValue = null;
|
||||
_selectedRto = null;
|
||||
_selectedVehicleType = null;
|
||||
_selectedSegment = null;
|
||||
_searchController.clear();
|
||||
_applyDefaultVehicleTypeSelection();
|
||||
});
|
||||
_applyFilters();
|
||||
},
|
||||
@ -996,12 +953,10 @@ class _gridViewScreenState extends ConsumerState<gridViewScreen> {
|
||||
child: isMobile
|
||||
? Column(
|
||||
children: [
|
||||
dropdownInsurer(),
|
||||
const SizedBox(height: 10),
|
||||
dropdownPlanType(),
|
||||
const SizedBox(height: 10),
|
||||
dropdownVehicleType(),
|
||||
const SizedBox(height: 10),
|
||||
dropdownInsurer(),
|
||||
const SizedBox(height: 10),
|
||||
dropdownSegment(),
|
||||
const SizedBox(height: 10),
|
||||
dropdownRto(),
|
||||
@ -1018,12 +973,10 @@ class _gridViewScreenState extends ConsumerState<gridViewScreen> {
|
||||
scrollDirection: Axis.horizontal,
|
||||
child: Row(
|
||||
children: [
|
||||
dropdownInsurer(),
|
||||
const SizedBox(width: 12),
|
||||
dropdownPlanType(),
|
||||
const SizedBox(width: 12),
|
||||
dropdownVehicleType(),
|
||||
const SizedBox(width: 12),
|
||||
dropdownInsurer(),
|
||||
const SizedBox(width: 12),
|
||||
dropdownSegment(),
|
||||
const SizedBox(width: 12),
|
||||
dropdownRto(),
|
||||
@ -1107,13 +1060,8 @@ class _gridViewScreenState extends ConsumerState<gridViewScreen> {
|
||||
padding: const EdgeInsets.symmetric(horizontal: 8, vertical: 8),
|
||||
itemCount: _paginatedGrid.length,
|
||||
separatorBuilder: (context, index) => const SizedBox(height: 10),
|
||||
itemBuilder: (context, index) => _gridViewCard(
|
||||
row: _paginatedGrid[index],
|
||||
showCompColumn: _showCompColumnForAgent,
|
||||
showTpColumn: _showTpColumnForAgent,
|
||||
showOdColumn: _showOdColumnForAgent,
|
||||
showPartnerCompValue: _showPartnerRetentionValues,
|
||||
),
|
||||
itemBuilder: (context, index) =>
|
||||
_gridViewCard(row: _paginatedGrid[index]),
|
||||
);
|
||||
}
|
||||
|
||||
@ -1139,12 +1087,9 @@ class _gridViewScreenState extends ConsumerState<gridViewScreen> {
|
||||
Expanded(flex: 2, child: Text('Vehicle', style: _headerStyle)),
|
||||
Expanded(flex: 3, child: Text('Segment', style: _headerStyle)),
|
||||
Expanded(flex: 2, child: Text('RTO', style: _headerStyle)),
|
||||
if (_showCompColumnForAgent)
|
||||
Expanded(flex: 2, child: Text('Comp', style: _headerStyle)),
|
||||
if (_showTpColumnForAgent)
|
||||
Expanded(flex: 2, child: Text('TP', style: _headerStyle)),
|
||||
if (_showOdColumnForAgent)
|
||||
Expanded(flex: 2, child: Text('OD', style: _headerStyle)),
|
||||
Expanded(flex: 2, child: Text('Comp', style: _headerStyle)),
|
||||
Expanded(flex: 2, child: Text('TP', style: _headerStyle)),
|
||||
Expanded(flex: 2, child: Text('OD', style: _headerStyle)),
|
||||
Expanded(flex: 3, child: Text('Remarks', style: _headerStyle)),
|
||||
],
|
||||
),
|
||||
@ -1181,48 +1126,18 @@ class _gridViewScreenState extends ConsumerState<gridViewScreen> {
|
||||
),
|
||||
),
|
||||
Expanded(flex: 2, child: Text(_nullableString(row['rto']), style: _dataBold)),
|
||||
if (_showCompColumnForAgent)
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(
|
||||
_showPartnerRetentionValues
|
||||
? _nullableString(row['partner_comp'])
|
||||
: _nullableString(row['comp']),
|
||||
style: _dataBold,
|
||||
),
|
||||
),
|
||||
if (_showTpColumnForAgent)
|
||||
Expanded(flex: 2, child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('${_nullableString(row['tp'])}', style: _dataBold),
|
||||
if (_showPartnerRetentionValues) ...[
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
'${_nullableString(row['partner_tp'])}',
|
||||
style: _dataBold,
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
if (_showOdColumnForAgent)
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text('${_nullableString(row['od'])}', style: _dataBold),
|
||||
if (_showPartnerRetentionValues) ...[
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
'${_nullableString(row['partner_od'])}',
|
||||
style: _dataBold,
|
||||
),
|
||||
],
|
||||
],
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(_nullableString(row['comp']), style: _dataBold),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(_nullableString(row['tp']), style: _dataBold),
|
||||
),
|
||||
Expanded(
|
||||
flex: 2,
|
||||
child: Text(_nullableString(row['od']), style: _dataBold),
|
||||
),
|
||||
Expanded(
|
||||
flex: 3,
|
||||
child: Text(
|
||||
@ -1287,15 +1202,23 @@ class _gridViewScreenState extends ConsumerState<gridViewScreen> {
|
||||
}
|
||||
try {
|
||||
final queryParams = Uri.base.queryParameters;
|
||||
final fileIdFromQuery = queryParams['file_id']?.trim();
|
||||
final role = _apiRoleFromAppRole(ref.read(userRoleProvider));
|
||||
final roleLc = (role ?? '').toLowerCase();
|
||||
final fileIdFromQuery = queryParams['file_id']?.trim();
|
||||
final fileIdToSend =
|
||||
(roleLc == 'manager' || roleLc == 'accounts')
|
||||
? fileIdFromQuery
|
||||
? (_gridFileIdUsed ??
|
||||
(fileIdFromQuery != null && fileIdFromQuery.isNotEmpty
|
||||
? fileIdFromQuery
|
||||
: null))
|
||||
: null;
|
||||
final previewAgentId =
|
||||
queryParams['agent_id']?.trim();
|
||||
final loggedIdForExport = roleLc == 'agent'
|
||||
? _loggedId?.trim()
|
||||
: (previewAgentId != null && previewAgentId.isNotEmpty
|
||||
? previewAgentId
|
||||
: null);
|
||||
await _apiService.downloadGridExcel(
|
||||
role: role,
|
||||
fileId: fileIdToSend,
|
||||
@ -1303,11 +1226,8 @@ class _gridViewScreenState extends ConsumerState<gridViewScreen> {
|
||||
vehicleType: _selectedVehicleType,
|
||||
segment: _selectedSegment,
|
||||
rto: _selectedRto,
|
||||
planType: _selectedPlanTypeValue,
|
||||
search: _searchController.text.trim(),
|
||||
loggedId: previewAgentId != null && previewAgentId.isNotEmpty
|
||||
? previewAgentId
|
||||
: _loggedId,
|
||||
loggedId: loggedIdForExport,
|
||||
);
|
||||
} catch (e) {
|
||||
if (mounted) {
|
||||
@ -1340,18 +1260,8 @@ class _gridViewScreenState extends ConsumerState<gridViewScreen> {
|
||||
|
||||
class _gridViewCard extends StatelessWidget {
|
||||
final Map<String, dynamic> row;
|
||||
final bool showCompColumn;
|
||||
final bool showTpColumn;
|
||||
final bool showOdColumn;
|
||||
final bool showPartnerCompValue;
|
||||
|
||||
const _gridViewCard({
|
||||
required this.row,
|
||||
required this.showCompColumn,
|
||||
required this.showTpColumn,
|
||||
required this.showOdColumn,
|
||||
required this.showPartnerCompValue,
|
||||
});
|
||||
const _gridViewCard({required this.row});
|
||||
|
||||
String _nullableString(dynamic v) {
|
||||
if (v == null) return '-';
|
||||
@ -1405,21 +1315,11 @@ class _gridViewCard extends StatelessWidget {
|
||||
const SizedBox(height: 10),
|
||||
Row(
|
||||
children: [
|
||||
if (showCompColumn)
|
||||
Expanded(
|
||||
child: _upDownMetric(
|
||||
title: 'Comp',
|
||||
value: showPartnerCompValue ? row['partner_comp'] : row['comp'],
|
||||
),
|
||||
),
|
||||
if (showCompColumn && (showTpColumn || showOdColumn))
|
||||
const SizedBox(width: 10),
|
||||
if (showTpColumn)
|
||||
Expanded(child: _metric('TP', row['tp'])),
|
||||
if (showTpColumn && showOdColumn)
|
||||
const SizedBox(width: 10),
|
||||
if (showOdColumn)
|
||||
Expanded(child: _metric('OD', row['od'])),
|
||||
Expanded(child: _metric('Comp', row['comp'])),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(child: _metric('TP', row['tp'])),
|
||||
const SizedBox(width: 10),
|
||||
Expanded(child: _metric('OD', row['od'])),
|
||||
],
|
||||
),
|
||||
const SizedBox(height: 10),
|
||||
@ -1460,40 +1360,6 @@ class _gridViewCard extends StatelessWidget {
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _upDownMetric({
|
||||
required String title,
|
||||
required dynamic value,
|
||||
}) {
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 10, vertical: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: const Color(0xFFF8FAFC),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
border: Border.all(color: const Color(0xFFE2E8F0)),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
Text(
|
||||
title,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 10,
|
||||
color: const Color(0xFF64748B),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 2),
|
||||
Text(
|
||||
_nullableString(value),
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 11,
|
||||
fontWeight: FontWeight.w600,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
/* import 'package:dropdown_search/dropdown_search.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
Loading…
Reference in New Issue
Block a user