enquiry issue fix
This commit is contained in:
parent
6c65a71d1f
commit
1ceccdcd43
File diff suppressed because one or more lines are too long
@ -1,4 +1,5 @@
|
||||
import 'dart:ui';
|
||||
import 'dart:async';
|
||||
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
@ -70,6 +71,8 @@ class EnquiryHandlerState extends ConsumerState<EnquiryListHandler> {
|
||||
bool isLoading = false;
|
||||
dynamic roleId;
|
||||
bool _showFilterRow = false;
|
||||
Timer? _staleAssignedBlinkTimer;
|
||||
bool _isBlinkPhaseOn = false;
|
||||
|
||||
Map<String, TextEditingController> controllers = {};
|
||||
List<String> tabHeader = [
|
||||
@ -240,6 +243,30 @@ class EnquiryHandlerState extends ConsumerState<EnquiryListHandler> {
|
||||
getVehicleType();
|
||||
getInsurers();
|
||||
getBroker();
|
||||
|
||||
_staleAssignedBlinkTimer = Timer.periodic(
|
||||
const Duration(milliseconds: 700),
|
||||
(_) {
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
_isBlinkPhaseOn = !_isBlinkPhaseOn;
|
||||
});
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_staleAssignedBlinkTimer?.cancel();
|
||||
for (final controller in controllers.values) {
|
||||
controller.dispose();
|
||||
}
|
||||
for (final rowControlMap in rowControllers.values) {
|
||||
for (final controller in rowControlMap.values) {
|
||||
controller.dispose();
|
||||
}
|
||||
}
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
Future<void> _initializeToken() async {
|
||||
@ -2588,9 +2615,17 @@ class EnquiryHandlerState extends ConsumerState<EnquiryListHandler> {
|
||||
print('idPrimary - $idPrimary');
|
||||
final editing = isEditingRow[id] ?? false;
|
||||
final controllers = rowControllers[id];
|
||||
final shouldHighlight = _shouldHighlightAssignedRow(item);
|
||||
|
||||
return DataRow(
|
||||
cells: [
|
||||
color: shouldHighlight
|
||||
? WidgetStatePropertyAll(
|
||||
_isBlinkPhaseOn
|
||||
? const Color(0xFFFFF3E0)
|
||||
: const Color(0xFFFFFFFF),
|
||||
)
|
||||
: null,
|
||||
cells: _decorateCellsForStaleAssigned([
|
||||
// S.No.
|
||||
// DataCell(Text('$sno', style: _dataBold)),
|
||||
|
||||
@ -2859,10 +2894,96 @@ class EnquiryHandlerState extends ConsumerState<EnquiryListHandler> {
|
||||
|
||||
// Status
|
||||
DataCell(Text(item['status'] ?? '-', style: _dataBold)),
|
||||
],
|
||||
], shouldHighlight),
|
||||
);
|
||||
}
|
||||
|
||||
List<DataCell> _decorateCellsForStaleAssigned(
|
||||
List<DataCell> cells,
|
||||
bool shouldHighlight,
|
||||
) {
|
||||
if (!shouldHighlight) return cells;
|
||||
|
||||
final borderColor = _isBlinkPhaseOn
|
||||
? const Color(0xFFE65100)
|
||||
: const Color(0x00000000);
|
||||
|
||||
return cells
|
||||
.map(
|
||||
(cell) => DataCell(
|
||||
Container(
|
||||
width: double.infinity,
|
||||
padding: const EdgeInsets.symmetric(horizontal: 4, vertical: 3),
|
||||
decoration: BoxDecoration(
|
||||
border: Border.all(color: borderColor, width: 1.3),
|
||||
borderRadius: BorderRadius.circular(2),
|
||||
),
|
||||
child: cell.child,
|
||||
),
|
||||
placeholder: cell.placeholder,
|
||||
showEditIcon: cell.showEditIcon,
|
||||
onTap: cell.onTap,
|
||||
onDoubleTap: cell.onDoubleTap,
|
||||
onLongPress: cell.onLongPress,
|
||||
onTapDown: cell.onTapDown,
|
||||
onTapCancel: cell.onTapCancel,
|
||||
),
|
||||
)
|
||||
.toList();
|
||||
}
|
||||
|
||||
bool _shouldHighlightAssignedRow(Map<String, dynamic> item) {
|
||||
final rawStatus = (item['enquiry_status'] ?? '').toString().trim();
|
||||
if (rawStatus.isEmpty) return false;
|
||||
|
||||
final normalizedStatus = rawStatus.toLowerCase();
|
||||
final isAssignedStatus =
|
||||
normalizedStatus == 'assigned' ||
|
||||
(normalizedStatus.contains('assigned') &&
|
||||
!normalizedStatus.contains('to be assigned'));
|
||||
if (!isAssignedStatus) return false;
|
||||
|
||||
final assignedAt = _parseAssignedDateTime(item);
|
||||
if (assignedAt == null) return false;
|
||||
|
||||
return DateTime.now().difference(assignedAt) >= const Duration(minutes: 30);
|
||||
}
|
||||
|
||||
DateTime? _parseAssignedDateTime(Map<String, dynamic> item) {
|
||||
final rawDate = [
|
||||
item['assigned_to_datetime'],
|
||||
item['assigned_datetime'],
|
||||
item['assigned_on'],
|
||||
item['updated_on'],
|
||||
].firstWhere(
|
||||
(value) => value != null && value.toString().trim().isNotEmpty,
|
||||
orElse: () => null,
|
||||
);
|
||||
|
||||
if (rawDate == null) return null;
|
||||
|
||||
final value = rawDate.toString().trim();
|
||||
try {
|
||||
return DateTime.parse(value);
|
||||
} catch (_) {}
|
||||
|
||||
final parsers = [
|
||||
DateFormat('dd-MM-yyyy hh:mm a'),
|
||||
DateFormat('dd-MM-yyyy HH:mm'),
|
||||
DateFormat('yyyy-MM-dd HH:mm:ss'),
|
||||
DateFormat('yyyy-MM-dd HH:mm'),
|
||||
];
|
||||
|
||||
for (final parser in parsers) {
|
||||
try {
|
||||
return parser.parse(value);
|
||||
} catch (_) {
|
||||
// try next parser
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
static final _dataBold = TextStyle(
|
||||
fontSize: 12,
|
||||
|
||||
|
||||
@ -66,6 +66,8 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
|
||||
int totalCompletedPages = 1;
|
||||
List<int> itemsPerPageOptions = [25, 50, 100, 200];
|
||||
Timer? _debounce;
|
||||
Timer? _staleAssignedBlinkTimer;
|
||||
bool _isBlinkPhaseOn = false;
|
||||
late ApiService apiService;
|
||||
dynamic userId;
|
||||
dynamic idPrimary;
|
||||
@ -275,6 +277,15 @@ class EnquiryStaffState extends ConsumerState<EnquiryListStaffInline> {
|
||||
// timer = Timer.periodic(Duration(seconds: 10), (Timer t) => callRefresh()); //static
|
||||
|
||||
startTimer();
|
||||
_staleAssignedBlinkTimer = Timer.periodic(
|
||||
const Duration(milliseconds: 700),
|
||||
(_) {
|
||||
if (!mounted) return;
|
||||
setState(() {
|
||||
_isBlinkPhaseOn = !_isBlinkPhaseOn;
|
||||
});
|
||||
},
|
||||
);
|
||||
for (String field in tabHeader) {
|
||||
controllers[field] = TextEditingController();
|
||||
}
|
||||
@ -501,6 +512,7 @@ if (managerId != null &&
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_staleAssignedBlinkTimer?.cancel();
|
||||
refreshSub.close();
|
||||
_horizontalScrollController.dispose();
|
||||
// ... dispose other controllers ...
|
||||
@ -2484,30 +2496,45 @@ if (managerId != null &&
|
||||
final id = int.tryParse(data['id'].toString()) ?? 0;
|
||||
final selectId = data['id'].toString() ?? '0';
|
||||
|
||||
return Container(
|
||||
width: MediaQuery
|
||||
.of(context)
|
||||
.size
|
||||
.width,
|
||||
margin: EdgeInsets.fromLTRB(12, 8, 12, 8),
|
||||
decoration: BoxDecoration(
|
||||
color: Colors.white,
|
||||
border: Border.all(color: Color(0xFFFFECF1F7)),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
DataTable(
|
||||
border: TableBorder.all(color: Colors.transparent, width: 0),
|
||||
headingRowHeight: 0,
|
||||
dividerThickness: 0.1,
|
||||
columnSpacing: 20.0,
|
||||
dataRowMinHeight: 40,
|
||||
columns: _buildDataColumns(),
|
||||
rows: [_buildDataRow(data, sno)],
|
||||
final isStaleAssigned = _shouldHighlightAssignedRow(data);
|
||||
final rowBorderColor = isStaleAssigned
|
||||
? (_isBlinkPhaseOn
|
||||
? const Color(0xFFE65100)
|
||||
: const Color(0xFFFFCDD2))
|
||||
: const Color(0xFFFFECF1F7);
|
||||
final rowBgColor = isStaleAssigned
|
||||
? (_isBlinkPhaseOn
|
||||
? const Color(0xFFFFF3E0)
|
||||
: Colors.white)
|
||||
: Colors.white;
|
||||
|
||||
return Padding(
|
||||
padding: const EdgeInsets.fromLTRB(12, 8, 12, 8),
|
||||
child: Container(
|
||||
width: double.infinity,
|
||||
clipBehavior: Clip.antiAlias,
|
||||
decoration: BoxDecoration(
|
||||
color: rowBgColor,
|
||||
border: Border.all(
|
||||
color: rowBorderColor,
|
||||
width: isStaleAssigned ? 2.0 : 1.0,
|
||||
),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
),
|
||||
child: Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
DataTable(
|
||||
border: TableBorder.all(color: Colors.transparent, width: 0),
|
||||
headingRowHeight: 0,
|
||||
dividerThickness: 0.1,
|
||||
horizontalMargin: 16,
|
||||
columnSpacing: 20.0,
|
||||
dataRowMinHeight: 40,
|
||||
columns: _buildDataColumns(),
|
||||
rows: [_buildDataRow(data, sno, isStaleAssigned: isStaleAssigned)],
|
||||
),
|
||||
|
||||
// Expanded content
|
||||
if (rowExpanded[id] ?? false)
|
||||
@ -2568,6 +2595,7 @@ if (managerId != null &&
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
},
|
||||
@ -3314,7 +3342,41 @@ if (managerId != null &&
|
||||
}
|
||||
|
||||
// 2. Now the OPTIMIZED _buildDataRow method:
|
||||
DataRow _buildDataRow(Map<String, dynamic> item, int sno) {
|
||||
bool _shouldHighlightAssignedRow(Map<String, dynamic> item) {
|
||||
final rawStatus = (item['enquiry_status'] ?? '').toString().trim();
|
||||
if (rawStatus.isEmpty) return false;
|
||||
|
||||
final normalized = rawStatus.toLowerCase();
|
||||
if (normalized != 'assigned') return false;
|
||||
|
||||
final value = (item['assigned_to_datetime'] ?? '').toString().trim();
|
||||
if (value.isEmpty) return false;
|
||||
|
||||
DateTime? assignedAt;
|
||||
try {
|
||||
assignedAt = DateTime.parse(value);
|
||||
} catch (_) {
|
||||
for (final fmt in [
|
||||
DateFormat('dd-MM-yyyy hh:mm a'),
|
||||
DateFormat('dd-MM-yyyy HH:mm'),
|
||||
DateFormat('yyyy-MM-dd HH:mm:ss'),
|
||||
DateFormat('yyyy-MM-dd HH:mm'),
|
||||
]) {
|
||||
try {
|
||||
assignedAt = fmt.parse(value);
|
||||
break;
|
||||
} catch (_) {}
|
||||
}
|
||||
}
|
||||
if (assignedAt == null) return false;
|
||||
return DateTime.now().difference(assignedAt) >= const Duration(minutes: 30);
|
||||
}
|
||||
|
||||
DataRow _buildDataRow(
|
||||
Map<String, dynamic> item,
|
||||
int sno, {
|
||||
bool isStaleAssigned = false,
|
||||
}) {
|
||||
final id = int.tryParse(item['id'].toString()) ?? 0;
|
||||
final selectId = item['id'].toString() ?? '0';
|
||||
final status = item['enquiry_status'] ?? '-';
|
||||
@ -3322,6 +3384,9 @@ if (managerId != null &&
|
||||
final borderColor = statusBorderColors[status] ?? Color(0xFFE2E8F0);
|
||||
|
||||
return DataRow(
|
||||
color: isStaleAssigned
|
||||
? const WidgetStatePropertyAll(Colors.transparent)
|
||||
: null,
|
||||
cells: [
|
||||
// Enquiry Created Date
|
||||
DataCell(
|
||||
|
||||
22
pubspec.lock
22
pubspec.lock
@ -117,10 +117,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: characters
|
||||
sha256: f71061c654a3380576a52b451dd5532377954cf9dbd272a78fc8479606670803
|
||||
sha256: faf38497bda5ead2a8c7615f4f7939df04333478bf32e4173fcb06d428b5716b
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.4.0"
|
||||
version: "1.4.1"
|
||||
charcode:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -780,26 +780,26 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: matcher
|
||||
sha256: dc58c723c3c24bf8d3e2d3ad3f2f9d7bd9cf43ec6feaa64181775e60190153f2
|
||||
sha256: dc0b7dc7651697ea4ff3e69ef44b0407ea32c487a39fff6a4004fa585e901861
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.12.17"
|
||||
version: "0.12.19"
|
||||
material_color_utilities:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: material_color_utilities
|
||||
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
|
||||
sha256: "9c337007e82b1889149c82ed242ed1cb24a66044e30979c44912381e9be4c48b"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.11.1"
|
||||
version: "0.13.0"
|
||||
meta:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: meta
|
||||
sha256: e3641ec5d63ebf0d9b41bd43201a66e3fc79a65db5f61fc181f04cd27aab950c
|
||||
sha256: "1741988757a65eb6b36abe716829688cf01910bbf91c34354ff7ec1c3de2b349"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "1.16.0"
|
||||
version: "1.18.0"
|
||||
mime:
|
||||
dependency: transitive
|
||||
description:
|
||||
@ -1297,10 +1297,10 @@ packages:
|
||||
dependency: transitive
|
||||
description:
|
||||
name: test_api
|
||||
sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00"
|
||||
sha256: "949a932224383300f01be9221c39180316445ecb8e7547f70a41a35bf421fb9e"
|
||||
url: "https://pub.dev"
|
||||
source: hosted
|
||||
version: "0.7.6"
|
||||
version: "0.7.11"
|
||||
toastification:
|
||||
dependency: "direct main"
|
||||
description:
|
||||
@ -1502,5 +1502,5 @@ packages:
|
||||
source: hosted
|
||||
version: "3.1.3"
|
||||
sdks:
|
||||
dart: ">=3.8.1 <4.0.0"
|
||||
dart: ">=3.10.0-0 <4.0.0"
|
||||
flutter: ">=3.32.0"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user