import 'package:flutter/material.dart'; import '../../../../api/connect/rmv/rmv_models.dart'; import 'product_chip.dart'; import 'realtime_time.dart'; /// Renders a single departure or arrival row. Used in the station detail view. class DepartureArrivalTile extends StatelessWidget { final Product? product; final String name; /// Direction (for departures) or origin (for arrivals). final String towards; final DateTime scheduled; final DateTime? realtime; final int? delayMinutes; final String? track; final String? realTrack; final bool cancelled; final VoidCallback? onTap; const DepartureArrivalTile({ super.key, required this.product, required this.name, required this.towards, required this.scheduled, this.realtime, this.delayMinutes, this.track, this.realTrack, this.cancelled = false, this.onTap, }); factory DepartureArrivalTile.fromDeparture( Departure d, { VoidCallback? onTap, }) => DepartureArrivalTile( product: d.product, name: d.name, towards: 'nach ${d.direction}', scheduled: d.scheduledTime, realtime: d.realTime, delayMinutes: d.delayMinutes, track: d.track, realTrack: d.realTrack, cancelled: d.cancelled, onTap: onTap, ); factory DepartureArrivalTile.fromArrival( Arrival a, { VoidCallback? onTap, }) => DepartureArrivalTile( product: a.product, name: a.name, towards: 'von ${a.origin}', scheduled: a.scheduledTime, realtime: a.realTime, delayMinutes: a.delayMinutes, track: a.track, realTrack: a.realTrack, cancelled: a.cancelled, onTap: onTap, ); @override Widget build(BuildContext context) { final effectiveTrack = (realTrack?.isNotEmpty ?? false) ? realTrack! : (track ?? ''); final trackChanged = realTrack != null && track != null && realTrack != track; return ListTile( onTap: onTap, leading: SizedBox( width: 72, child: ProductChip(product: product, fallbackLabel: name), ), title: Text( towards, maxLines: 1, overflow: TextOverflow.ellipsis, style: TextStyle( decoration: cancelled ? TextDecoration.lineThrough : null, ), ), subtitle: effectiveTrack.isEmpty ? null : Row( children: [ Icon( Icons.directions_transit, size: 14, color: Theme.of(context).colorScheme.secondary, ), const SizedBox(width: 4), Text( 'Gleis $effectiveTrack', style: TextStyle( color: trackChanged ? Colors.red : Theme.of(context).colorScheme.secondary, fontWeight: trackChanged ? FontWeight.bold : null, ), ), ], ), trailing: RealtimeTime( scheduled: scheduled, realtime: realtime, delayMinutes: delayMinutes, cancelled: cancelled, style: Theme.of(context).textTheme.titleMedium, ), ); } }