import 'package:flutter/material.dart'; import 'package:mileograph_flutter/services/data_service.dart'; import 'package:provider/provider.dart'; class LatestLocoChangesPanel extends StatefulWidget { const LatestLocoChangesPanel({super.key}); @override State createState() => _LatestLocoChangesPanelState(); } class _LatestLocoChangesPanelState extends State { late final ScrollController _controller; @override void initState() { super.initState(); _controller = ScrollController(); } @override void dispose() { _controller.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final data = context.watch(); final changes = data.latestLocoChanges; final isLoading = data.isLatestLocoChangesLoading; final textTheme = Theme.of(context).textTheme; return Card( clipBehavior: Clip.antiAlias, child: Padding( padding: const EdgeInsets.all(16), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Row( children: [ const Icon(Icons.bolt, size: 20), const SizedBox(width: 8), Expanded( child: Text( 'Latest loco changes', style: textTheme.titleMedium?.copyWith( fontWeight: FontWeight.w800, ), ), ), if (isLoading && changes.isNotEmpty) const SizedBox( width: 18, height: 18, child: CircularProgressIndicator(strokeWidth: 2), ), ], ), const SizedBox(height: 8), if (isLoading && changes.isEmpty) const Padding( padding: EdgeInsets.all(12.0), child: Center(child: CircularProgressIndicator()), ) else if (changes.isEmpty) Padding( padding: const EdgeInsets.symmetric(vertical: 8.0), child: Text( 'No recent loco changes yet.', style: textTheme.bodyMedium, ), ) else SizedBox( height: 260, child: Scrollbar( controller: _controller, child: ListView.separated( controller: _controller, itemCount: changes.length, separatorBuilder: (context, index) => const Divider(height: 1), itemBuilder: (context, index) { final change = changes[index]; return ListTile( dense: true, contentPadding: EdgeInsets.zero, title: Text( change.locoLabel, style: textTheme.titleSmall?.copyWith( fontWeight: FontWeight.w600, ), ), subtitle: Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ Text('${change.changeLabel}: ${change.valueLabel}'), Text( change.approvedDateLabel, style: textTheme.labelSmall?.copyWith( color: textTheme.bodySmall?.color?.withValues(alpha: 0.7), ), ), ], ), trailing: change.approvedBy.isEmpty ? null : Text( change.approvedBy, style: textTheme.labelSmall, ), ); }, ), ), ), ], ), ), ); } }