non EB
This commit is contained in:
parent
c6b15a050a
commit
197a699c16
@ -4,6 +4,7 @@ import 'package:csv/csv.dart';
|
||||
import 'package:dropdown_button2/dropdown_button2.dart';
|
||||
import 'package:dropdown_search/dropdown_search.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/gestures.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/services.dart';
|
||||
import 'package:google_fonts/google_fonts.dart';
|
||||
@ -51,6 +52,9 @@ class _NonEBClaimsListState extends State<NonEBClaimsList> {
|
||||
String? _postPreToken = '';
|
||||
TextEditingController searchController = TextEditingController();
|
||||
TextEditingController searchClaimsStatusController = TextEditingController();
|
||||
final ScrollController _statusScrollController = ScrollController();
|
||||
bool _canScrollStatusLeft = false;
|
||||
bool _canScrollStatusRight = false;
|
||||
|
||||
Map<String, TextEditingController> controllers = {};
|
||||
List<dynamic> reversedDataPolicy = [];
|
||||
@ -77,25 +81,33 @@ class _NonEBClaimsListState extends State<NonEBClaimsList> {
|
||||
int? appliedClaimStatus;
|
||||
|
||||
Color getStatusColor(String status) {
|
||||
switch (status.toLowerCase()) {
|
||||
case 'claim received':
|
||||
return const Color(0xFF4A90E2); // blue
|
||||
case 'under process':
|
||||
return const Color(0xFFF5A623); // orange
|
||||
case 'information required':
|
||||
return const Color(0xFFFF8C42); // amber
|
||||
case 'approved':
|
||||
return const Color(0xFF2ECC71); // green
|
||||
case 'settled':
|
||||
return const Color(0xFF1ABC9C); // teal-green
|
||||
case 'rejected':
|
||||
return const Color(0xFFE74C3C); // red
|
||||
case 'denial review awaite':
|
||||
return const Color(0xFF9B59B6); // purple
|
||||
case 'closed':
|
||||
return const Color(0xFFB0BEC5); // purple
|
||||
switch (status.toLowerCase().trim()) {
|
||||
case 'claim intimation received':
|
||||
return const Color(0xFF4A90E2);
|
||||
case 'claim intimated':
|
||||
return const Color(0xFF5B9BD5);
|
||||
case 'insurer pending':
|
||||
return const Color(0xFFF5A623);
|
||||
case 'surveyor pending':
|
||||
return const Color(0xFFFF8C42);
|
||||
case 'insured pending':
|
||||
return const Color(0xFFE67E22);
|
||||
case 'insurer / surveyor pending':
|
||||
return const Color(0xFFD35400);
|
||||
case 'workshop pending':
|
||||
return const Color(0xFF9B59B6);
|
||||
case 'claim approved':
|
||||
return const Color(0xFF2ECC71);
|
||||
case 'claim settled':
|
||||
return const Color(0xFF1ABC9C);
|
||||
case 'claim closed':
|
||||
return const Color(0xFF95A5A6);
|
||||
case 'claim rejected':
|
||||
return const Color(0xFFE74C3C);
|
||||
case 'claim withdrawn':
|
||||
return const Color(0xFF7F8C8D);
|
||||
default:
|
||||
return const Color(0xFFB0BEC5); // grey fallback
|
||||
return const Color(0xFFB0BEC5);
|
||||
}
|
||||
}
|
||||
|
||||
@ -125,6 +137,9 @@ class _NonEBClaimsListState extends State<NonEBClaimsList> {
|
||||
for (String field in tabHeader) {
|
||||
controllers[field] = TextEditingController();
|
||||
}
|
||||
_statusScrollController.addListener(_updateStatusScrollArrows);
|
||||
WidgetsBinding.instance
|
||||
.addPostFrameCallback((_) => _updateStatusScrollArrows());
|
||||
|
||||
// if (_postPreToken != null && _postPreToken!.isNotEmpty) {
|
||||
//
|
||||
@ -178,6 +193,7 @@ class _NonEBClaimsListState extends State<NonEBClaimsList> {
|
||||
|
||||
@override
|
||||
void dispose() {
|
||||
_statusScrollController.dispose();
|
||||
for (var controller in controllers.values) {
|
||||
controller.dispose();
|
||||
}
|
||||
@ -274,14 +290,29 @@ class _NonEBClaimsListState extends State<NonEBClaimsList> {
|
||||
}
|
||||
}
|
||||
|
||||
String _claimStatusLabel(Map<String, dynamic> item) {
|
||||
return (item['status_display'] ?? item['status'] ?? '').toString();
|
||||
}
|
||||
|
||||
int getStatusCount(String status) {
|
||||
return filteredData
|
||||
.where((item) =>
|
||||
(item['status'] ?? '').toString().toLowerCase() ==
|
||||
status.toLowerCase())
|
||||
_claimStatusLabel(item).toLowerCase() == status.toLowerCase())
|
||||
.length;
|
||||
}
|
||||
|
||||
List<String> _uniqueDisplayNames(List<dynamic> statusMaster) {
|
||||
final seen = <String>{};
|
||||
final result = <String>[];
|
||||
for (final status in statusMaster) {
|
||||
final name = status['display_name']?.toString() ?? '';
|
||||
if (name.isNotEmpty && seen.add(name.toLowerCase())) {
|
||||
result.add(name);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
Future<void> applyFilter() async {
|
||||
logDebug("Filtersss");
|
||||
|
||||
@ -734,6 +765,7 @@ class _NonEBClaimsListState extends State<NonEBClaimsList> {
|
||||
}
|
||||
|
||||
Widget _buildDataRow(Map<String, dynamic> item) {
|
||||
final statusLabel = _claimStatusLabel(item);
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 16),
|
||||
margin: const EdgeInsets.only(top: 10),
|
||||
@ -795,10 +827,12 @@ class _NonEBClaimsListState extends State<NonEBClaimsList> {
|
||||
Container(
|
||||
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||
decoration: BoxDecoration(
|
||||
color: getStatusColor(item['status_display'] ?? ''),
|
||||
color: getStatusColor(statusLabel),
|
||||
borderRadius: BorderRadius.circular(10),
|
||||
),
|
||||
child: Text(item['status_display'] ?? '-', style: _dataBoldStatus)),
|
||||
child: Text(
|
||||
statusLabel.isEmpty ? '-' : statusLabel,
|
||||
style: _dataBoldStatus)),
|
||||
],
|
||||
),
|
||||
),
|
||||
@ -874,48 +908,131 @@ class _NonEBClaimsListState extends State<NonEBClaimsList> {
|
||||
);
|
||||
}
|
||||
|
||||
void _updateStatusScrollArrows() {
|
||||
if (!_statusScrollController.hasClients) return;
|
||||
final position = _statusScrollController.position;
|
||||
final canLeft = position.pixels > position.minScrollExtent + 1;
|
||||
final canRight = position.pixels < position.maxScrollExtent - 1;
|
||||
if (canLeft != _canScrollStatusLeft || canRight != _canScrollStatusRight) {
|
||||
setState(() {
|
||||
_canScrollStatusLeft = canLeft;
|
||||
_canScrollStatusRight = canRight;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void _scrollStatusBy(double delta) {
|
||||
if (!_statusScrollController.hasClients) return;
|
||||
final target = (_statusScrollController.offset + delta)
|
||||
.clamp(0.0, _statusScrollController.position.maxScrollExtent);
|
||||
_statusScrollController.animateTo(
|
||||
target,
|
||||
duration: const Duration(milliseconds: 280),
|
||||
curve: Curves.easeOutCubic,
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildStatusScrollButton({
|
||||
required IconData icon,
|
||||
required bool enabled,
|
||||
required VoidCallback onTap,
|
||||
}) {
|
||||
return SizedBox(
|
||||
width: 32,
|
||||
height: 40,
|
||||
child: Material(
|
||||
color: enabled ? const Color(0xFF00999E) : const Color(0xFFE8E8E8),
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: InkWell(
|
||||
onTap: enabled ? onTap : null,
|
||||
borderRadius: BorderRadius.circular(8),
|
||||
child: Icon(
|
||||
icon,
|
||||
size: 22,
|
||||
color: enabled ? Colors.white : Colors.black38,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
Widget _buildStatusSummary() {
|
||||
final List<dynamic> statusMaster = _claimStatusMaster;
|
||||
|
||||
if (statusMaster.isEmpty) return const SizedBox();
|
||||
|
||||
final List<dynamic> displayStatuses = appliedClaimStatus != null
|
||||
final List<String> displayStatuses = appliedClaimStatus != null
|
||||
? statusMaster
|
||||
.where((status) =>
|
||||
int.parse(status['id'].toString()) == appliedClaimStatus)
|
||||
.toList()
|
||||
: statusMaster;
|
||||
.where((status) =>
|
||||
int.parse(status['id'].toString()) == appliedClaimStatus)
|
||||
.map((status) => status['display_name']?.toString() ?? '')
|
||||
.where((name) => name.isNotEmpty)
|
||||
.toList()
|
||||
: _uniqueDisplayNames(statusMaster);
|
||||
|
||||
return SizedBox(
|
||||
height: 35,
|
||||
child: ListView.separated(
|
||||
scrollDirection: Axis.horizontal,
|
||||
itemCount: displayStatuses.length,
|
||||
separatorBuilder: (_, __) => const SizedBox(width: 10),
|
||||
itemBuilder: (context, index) {
|
||||
final statusName =
|
||||
displayStatuses[index]['display_name']?.toString() ?? '';
|
||||
return Row(
|
||||
children: [
|
||||
_buildStatusScrollButton(
|
||||
icon: Icons.chevron_left,
|
||||
enabled: _canScrollStatusLeft,
|
||||
onTap: () => _scrollStatusBy(-240),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
Expanded(
|
||||
child: ScrollConfiguration(
|
||||
behavior: _StatusDragScrollBehavior(),
|
||||
child: MouseRegion(
|
||||
cursor: SystemMouseCursors.grab,
|
||||
child: SizedBox(
|
||||
height: 40,
|
||||
child: NotificationListener<ScrollMetricsNotification>(
|
||||
onNotification: (_) {
|
||||
_updateStatusScrollArrows();
|
||||
return false;
|
||||
},
|
||||
child: ListView.separated(
|
||||
controller: _statusScrollController,
|
||||
scrollDirection: Axis.horizontal,
|
||||
physics: const ClampingScrollPhysics(),
|
||||
itemCount: displayStatuses.length,
|
||||
separatorBuilder: (_, __) => const SizedBox(width: 10),
|
||||
itemBuilder: (context, index) {
|
||||
final statusName = displayStatuses[index];
|
||||
|
||||
final count = getStatusCount(statusName);
|
||||
final color = getStatusColor(statusName);
|
||||
final count = getStatusCount(statusName);
|
||||
final color = getStatusColor(statusName);
|
||||
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: color,
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
child: Text(
|
||||
'$statusName - $count',
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.white,
|
||||
return Container(
|
||||
padding: const EdgeInsets.symmetric(
|
||||
horizontal: 12, vertical: 8),
|
||||
decoration: BoxDecoration(
|
||||
color: color,
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
),
|
||||
child: Text(
|
||||
'$statusName - $count',
|
||||
softWrap: false,
|
||||
style: GoogleFonts.poppins(
|
||||
fontSize: 12,
|
||||
fontWeight: FontWeight.w500,
|
||||
color: Colors.white,
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
),
|
||||
),
|
||||
),
|
||||
const SizedBox(width: 8),
|
||||
_buildStatusScrollButton(
|
||||
icon: Icons.chevron_right,
|
||||
enabled: _canScrollStatusRight,
|
||||
onTap: () => _scrollStatusBy(240),
|
||||
),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
@ -1620,6 +1737,16 @@ class _ClaimsHeaderDelegate extends SliverPersistentHeaderDelegate {
|
||||
bool shouldRebuild(_) => false;
|
||||
}
|
||||
|
||||
class _StatusDragScrollBehavior extends MaterialScrollBehavior {
|
||||
@override
|
||||
Set<PointerDeviceKind> get dragDevices => {
|
||||
PointerDeviceKind.touch,
|
||||
PointerDeviceKind.mouse,
|
||||
PointerDeviceKind.stylus,
|
||||
PointerDeviceKind.trackpad,
|
||||
};
|
||||
}
|
||||
|
||||
// ================= ICON BUTTON =================
|
||||
class _IconActionButton extends StatelessWidget {
|
||||
final IconData icon;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user