import 'package:dart_mq/dart_mq.dart'; import 'package:flutter/material.dart'; import 'package:stadtbote/content_views/tour_details_page.dart'; import 'package:stadtbote/content_views/utils/content_view_widget.dart'; import 'package:stadtbote/messages/pop_content_view_message.dart'; import 'package:stadtbote/model/job_tour.dart'; import 'package:stadtbote/popups/map_popup.dart'; import '../model/job.dart'; import '../popups/files_popup.dart'; import '../tools/app_localizations.dart'; import '../tools/constants.dart'; import '../tools/util.dart'; class TourListPage extends ContentViewWidget { const TourListPage({super.key, required this.job, this.readOnly = false}); final Job job; final bool readOnly; @override State createState() => _TourListPageState(); @override Future getHeaderWidget(BuildContext context) async { await Future.delayed(const Duration(microseconds: 0)); return _HeaderWidget(); } } class _TourListPageState extends State with ProducerMixin { late List _tours; late bool _initCompleted = false; @override void initState() { Future.delayed(const Duration(seconds: 0), () async { _tours = widget.job.tours; _initCompleted = true; setState(() {}); }); super.initState(); } @override Widget build(BuildContext context) { if (!_initCompleted) { return Util.getWaitWidget(context); } late List jobWidgets = _createTourWidgets(); return Padding( padding: const EdgeInsets.all(18.0), child: Column( children: [ Container( color: Colors.transparent, child: Row( children: [ Text( widget.job.id.toString(), textAlign: TextAlign.left, ), ], ), ), Row( children: [ Text( widget.job.crFilter != null ? widget.job.crFilter.toString() : "", textAlign: TextAlign.left, ), ], ), Row( children: [ Image.asset("assets/${mapVehicleTypeToImageName(widget.job.vhtId)}", width: 60, height: 60), const SizedBox(width: 10), Expanded( child: Text(mapVehicleTypeToText(widget.job.vhtId)), ), const SizedBox(width: 10), SizedBox( width: 100, child: Visibility( visible: widget.job.tours[0].pos != null, child: ElevatedButton( style: ButtonStyle( shape: WidgetStateProperty.all( RoundedRectangleBorder( borderRadius: BorderRadius.circular(8.0), side: const BorderSide(color: Colors.grey), ), ), backgroundColor: WidgetStateProperty.all(Colors.lightGreen), foregroundColor: WidgetStateProperty.all(Colors.black), ), onPressed: () => {showMapPopup(context, widget.job.tours[0], widget.job.tours)}, child: Text('map'.tr)), )) ], ), Expanded( child: Scrollbar(thumbVisibility: true, child: ListView(padding: const EdgeInsets.all(0), children: jobWidgets)), ) ], ), ); } List _createTourWidgets() { List tourWidgets = []; JobTour? lastTour; for (var tour in _tours) { bool tourReadOnly = isTourReadOnly(lastTour, tour); Color color = Colors.transparent; switch (tour.state) { case 0: color = !tourReadOnly ? Colors.white : Colors.grey; break; case 1: color = Colors.lightGreen; break; default: color = Colors.yellow; break; } lastTour = tour; tourWidgets.add( ListTile( contentPadding: const EdgeInsets.all(0), onTap: () { _clicked(tour, tourReadOnly); }, title: Container( decoration: BoxDecoration( border: Border.all(color: Colors.grey, width: 0.5), color: color, borderRadius: const BorderRadius.all(Radius.circular(13))), padding: const EdgeInsets.all(5.0), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, mainAxisAlignment: MainAxisAlignment.center, children: [ Row( children: [ Expanded( child: Text( "${'station'.tr} ${tour.sort} ${mapTourMode(tour.mode)}", textAlign: TextAlign.left, ), ), FilesBadge(files: tour.files), ], ), Text( tour.comp, textAlign: TextAlign.left, ), Text( tour.street, textAlign: TextAlign.left, ), Text( tour.city, textAlign: TextAlign.left, ), ], ), )), ); } return tourWidgets; } bool isTourReadOnly(JobTour? lastTour, JobTour tour) { bool readOnly; if (!widget.readOnly) { readOnly = false; if (lastTour == null) { readOnly = tour.state != 0; } else { if (lastTour.state == 0) { readOnly = true; } } } else { readOnly = true; } return readOnly; } Future _clicked(JobTour tour, bool readOnly) async { sendMessage( routingKey: Constants.messageTopicPushContentView, payload: TourDetailsPage(job: widget.job, tour: tour, readOnly: readOnly), ); } } class _HeaderWidget extends StatefulWidget { @override State<_HeaderWidget> createState() => _HeaderWidgetState(); } class _HeaderWidgetState extends State<_HeaderWidget> with ProducerMixin { @override void initState() { super.initState(); } @override Widget build(BuildContext context) { var cellWidth = (MediaQuery.of(context).size.width - 60 - 60 - 25) / 2; return Padding( padding: const EdgeInsets.all(8), child: Stack( alignment: Alignment.center, children: [ Row( mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Visibility( visible: true, child: Container( width: 60, height: 60, decoration: const BoxDecoration( shape: BoxShape.circle, color: Colors.white, ), child: FittedBox( child: GestureDetector( onTap: () async { sendMessage( routingKey: Constants.messageTopicPopContentView, payload: PopContentViewMessage(count: 1), ); }, child: const CircleAvatar( radius: 10, backgroundColor: Constants.colorPrimary, child: Padding(padding: EdgeInsets.all(1.0), child: Icon(Icons.arrow_back, size: 20.0, color: Colors.white)), ), ), ), ), ), Visibility( visible: false, child: Container( width: 60, height: 60, decoration: const BoxDecoration( shape: BoxShape.circle, color: Colors.red, ), child: FittedBox( child: GestureDetector( onTap: () async { sendMessage( routingKey: Constants.messageTopicPopContentView, payload: PopContentViewMessage(count: 1), ); }, child: const CircleAvatar( backgroundColor: Constants.colorPrimary, radius: 10, child: Padding(padding: EdgeInsets.all(1.0), child: Icon(Icons.info_outline, size: 20.0, color: Colors.white))), ), ), ), ), ], ), SizedBox( height: 100, width: cellWidth * 2, child: const Center( child: Text( textAlign: TextAlign.center, "Liste der Stationen", style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18, color: Colors.white), ), ), ), ], ), ); } }