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_button2/dropdown_button2.dart';
|
||||||
import 'package:dropdown_search/dropdown_search.dart';
|
import 'package:dropdown_search/dropdown_search.dart';
|
||||||
import 'package:flutter/cupertino.dart';
|
import 'package:flutter/cupertino.dart';
|
||||||
|
import 'package:flutter/gestures.dart';
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
import 'package:flutter/services.dart';
|
import 'package:flutter/services.dart';
|
||||||
import 'package:google_fonts/google_fonts.dart';
|
import 'package:google_fonts/google_fonts.dart';
|
||||||
@ -51,6 +52,9 @@ class _NonEBClaimsListState extends State<NonEBClaimsList> {
|
|||||||
String? _postPreToken = '';
|
String? _postPreToken = '';
|
||||||
TextEditingController searchController = TextEditingController();
|
TextEditingController searchController = TextEditingController();
|
||||||
TextEditingController searchClaimsStatusController = TextEditingController();
|
TextEditingController searchClaimsStatusController = TextEditingController();
|
||||||
|
final ScrollController _statusScrollController = ScrollController();
|
||||||
|
bool _canScrollStatusLeft = false;
|
||||||
|
bool _canScrollStatusRight = false;
|
||||||
|
|
||||||
Map<String, TextEditingController> controllers = {};
|
Map<String, TextEditingController> controllers = {};
|
||||||
List<dynamic> reversedDataPolicy = [];
|
List<dynamic> reversedDataPolicy = [];
|
||||||
@ -77,25 +81,33 @@ class _NonEBClaimsListState extends State<NonEBClaimsList> {
|
|||||||
int? appliedClaimStatus;
|
int? appliedClaimStatus;
|
||||||
|
|
||||||
Color getStatusColor(String status) {
|
Color getStatusColor(String status) {
|
||||||
switch (status.toLowerCase()) {
|
switch (status.toLowerCase().trim()) {
|
||||||
case 'claim received':
|
case 'claim intimation received':
|
||||||
return const Color(0xFF4A90E2); // blue
|
return const Color(0xFF4A90E2);
|
||||||
case 'under process':
|
case 'claim intimated':
|
||||||
return const Color(0xFFF5A623); // orange
|
return const Color(0xFF5B9BD5);
|
||||||
case 'information required':
|
case 'insurer pending':
|
||||||
return const Color(0xFFFF8C42); // amber
|
return const Color(0xFFF5A623);
|
||||||
case 'approved':
|
case 'surveyor pending':
|
||||||
return const Color(0xFF2ECC71); // green
|
return const Color(0xFFFF8C42);
|
||||||
case 'settled':
|
case 'insured pending':
|
||||||
return const Color(0xFF1ABC9C); // teal-green
|
return const Color(0xFFE67E22);
|
||||||
case 'rejected':
|
case 'insurer / surveyor pending':
|
||||||
return const Color(0xFFE74C3C); // red
|
return const Color(0xFFD35400);
|
||||||
case 'denial review awaite':
|
case 'workshop pending':
|
||||||
return const Color(0xFF9B59B6); // purple
|
return const Color(0xFF9B59B6);
|
||||||
case 'closed':
|
case 'claim approved':
|
||||||
return const Color(0xFFB0BEC5); // purple
|
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:
|
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) {
|
for (String field in tabHeader) {
|
||||||
controllers[field] = TextEditingController();
|
controllers[field] = TextEditingController();
|
||||||
}
|
}
|
||||||
|
_statusScrollController.addListener(_updateStatusScrollArrows);
|
||||||
|
WidgetsBinding.instance
|
||||||
|
.addPostFrameCallback((_) => _updateStatusScrollArrows());
|
||||||
|
|
||||||
// if (_postPreToken != null && _postPreToken!.isNotEmpty) {
|
// if (_postPreToken != null && _postPreToken!.isNotEmpty) {
|
||||||
//
|
//
|
||||||
@ -178,6 +193,7 @@ class _NonEBClaimsListState extends State<NonEBClaimsList> {
|
|||||||
|
|
||||||
@override
|
@override
|
||||||
void dispose() {
|
void dispose() {
|
||||||
|
_statusScrollController.dispose();
|
||||||
for (var controller in controllers.values) {
|
for (var controller in controllers.values) {
|
||||||
controller.dispose();
|
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) {
|
int getStatusCount(String status) {
|
||||||
return filteredData
|
return filteredData
|
||||||
.where((item) =>
|
.where((item) =>
|
||||||
(item['status'] ?? '').toString().toLowerCase() ==
|
_claimStatusLabel(item).toLowerCase() == status.toLowerCase())
|
||||||
status.toLowerCase())
|
|
||||||
.length;
|
.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 {
|
Future<void> applyFilter() async {
|
||||||
logDebug("Filtersss");
|
logDebug("Filtersss");
|
||||||
|
|
||||||
@ -734,6 +765,7 @@ class _NonEBClaimsListState extends State<NonEBClaimsList> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Widget _buildDataRow(Map<String, dynamic> item) {
|
Widget _buildDataRow(Map<String, dynamic> item) {
|
||||||
|
final statusLabel = _claimStatusLabel(item);
|
||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 16),
|
padding: const EdgeInsets.symmetric(vertical: 6, horizontal: 16),
|
||||||
margin: const EdgeInsets.only(top: 10),
|
margin: const EdgeInsets.only(top: 10),
|
||||||
@ -795,10 +827,12 @@ class _NonEBClaimsListState extends State<NonEBClaimsList> {
|
|||||||
Container(
|
Container(
|
||||||
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
padding: EdgeInsets.symmetric(horizontal: 10, vertical: 4),
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: getStatusColor(item['status_display'] ?? ''),
|
color: getStatusColor(statusLabel),
|
||||||
borderRadius: BorderRadius.circular(10),
|
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() {
|
Widget _buildStatusSummary() {
|
||||||
final List<dynamic> statusMaster = _claimStatusMaster;
|
final List<dynamic> statusMaster = _claimStatusMaster;
|
||||||
|
|
||||||
if (statusMaster.isEmpty) return const SizedBox();
|
if (statusMaster.isEmpty) return const SizedBox();
|
||||||
|
|
||||||
final List<dynamic> displayStatuses = appliedClaimStatus != null
|
final List<String> displayStatuses = appliedClaimStatus != null
|
||||||
? statusMaster
|
? statusMaster
|
||||||
.where((status) =>
|
.where((status) =>
|
||||||
int.parse(status['id'].toString()) == appliedClaimStatus)
|
int.parse(status['id'].toString()) == appliedClaimStatus)
|
||||||
.toList()
|
.map((status) => status['display_name']?.toString() ?? '')
|
||||||
: statusMaster;
|
.where((name) => name.isNotEmpty)
|
||||||
|
.toList()
|
||||||
|
: _uniqueDisplayNames(statusMaster);
|
||||||
|
|
||||||
return SizedBox(
|
return Row(
|
||||||
height: 35,
|
children: [
|
||||||
child: ListView.separated(
|
_buildStatusScrollButton(
|
||||||
scrollDirection: Axis.horizontal,
|
icon: Icons.chevron_left,
|
||||||
itemCount: displayStatuses.length,
|
enabled: _canScrollStatusLeft,
|
||||||
separatorBuilder: (_, __) => const SizedBox(width: 10),
|
onTap: () => _scrollStatusBy(-240),
|
||||||
itemBuilder: (context, index) {
|
),
|
||||||
final statusName =
|
const SizedBox(width: 8),
|
||||||
displayStatuses[index]['display_name']?.toString() ?? '';
|
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 count = getStatusCount(statusName);
|
||||||
final color = getStatusColor(statusName);
|
final color = getStatusColor(statusName);
|
||||||
|
|
||||||
return Container(
|
return Container(
|
||||||
padding: const EdgeInsets.symmetric(horizontal: 12, vertical: 8),
|
padding: const EdgeInsets.symmetric(
|
||||||
decoration: BoxDecoration(
|
horizontal: 12, vertical: 8),
|
||||||
color: color,
|
decoration: BoxDecoration(
|
||||||
borderRadius: BorderRadius.circular(6),
|
color: color,
|
||||||
),
|
borderRadius: BorderRadius.circular(6),
|
||||||
child: Text(
|
),
|
||||||
'$statusName - $count',
|
child: Text(
|
||||||
style: GoogleFonts.poppins(
|
'$statusName - $count',
|
||||||
fontSize: 12,
|
softWrap: false,
|
||||||
fontWeight: FontWeight.w500,
|
style: GoogleFonts.poppins(
|
||||||
color: Colors.white,
|
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;
|
bool shouldRebuild(_) => false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _StatusDragScrollBehavior extends MaterialScrollBehavior {
|
||||||
|
@override
|
||||||
|
Set<PointerDeviceKind> get dragDevices => {
|
||||||
|
PointerDeviceKind.touch,
|
||||||
|
PointerDeviceKind.mouse,
|
||||||
|
PointerDeviceKind.stylus,
|
||||||
|
PointerDeviceKind.trackpad,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
// ================= ICON BUTTON =================
|
// ================= ICON BUTTON =================
|
||||||
class _IconActionButton extends StatelessWidget {
|
class _IconActionButton extends StatelessWidget {
|
||||||
final IconData icon;
|
final IconData icon;
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user