| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558 |
- // ignore_for_file: unused_import
- import 'dart:developer';
- import 'package:collection/collection.dart';
- import 'package:flutter/foundation.dart';
- import 'package:flutter/material.dart';
- import 'package:flutter_riverpod/flutter_riverpod.dart';
- import 'package:gap/gap.dart';
- import 'package:go_router/go_router.dart';
- import 'package:google_fonts/google_fonts.dart';
- import 'package:jiffy/jiffy.dart';
- import 'package:linear_progress_bar/linear_progress_bar.dart';
- import 'package:multi_select_flutter/multi_select_flutter.dart';
- import 'package:tp5/core/core.dart';
- import 'package:tp5/csv/csv_data.dart';
- import 'package:tp5/csv/data.dart';
- import 'package:tp5/flightslist/w_flt.dart';
- import 'package:tp5/fltinfo/delaycodes.dart';
- import 'package:tp5/fltinfo/widget/w_cadre.dart';
- import 'package:tp5/ftl/widget/w_shadowbox.dart';
- import 'package:tp5/lido/lido_api.dart';
- import 'package:tp5/lido/model/Lidoapi_list.dart';
- import 'package:tp5/lido/model/Lidoapi_ofp.dart';
- import 'package:tp5/lido/w_lidoflt.dart';
- import 'package:tp5/pdf/pdf_page.dart';
- import 'package:tp5/roster/api/crewlink_api.dart';
- import 'package:tp5/roster/models/duty.dart';
- import 'package:tp5/roster/widgets/w_airport.dart';
- import 'package:tp5/roster/widgets/w_citypair.dart';
- import 'package:tp5/roster/widgets/w_crew.dart';
- import 'package:tp5/roster/widgets/w_day.dart';
- import 'package:tp5/roster/widgets/w_fnum.dart';
- import 'package:tp5/roster/widgets/w_hour.dart';
- import 'package:tp5/widgets/my_row.dart';
- class DutyinfoPage extends ConsumerStatefulWidget {
- const DutyinfoPage({required this.params, super.key});
- final DutyinfoParams params;
- @override
- ConsumerState<ConsumerStatefulWidget> createState() => _DutyinfoPageState();
- }
- class _DutyinfoPageState extends ConsumerState<DutyinfoPage> {
- @override
- void initState() {
- Future.delayed(Duration.zero, () {
- if (widget.params.tlc != null) {
- final qualif = ref.read(dataProvider).qualif;
- collegeSelected = qualif
- .where((e) => e.tlc == widget.params.tlc)
- .map((e) => e.college ?? "")
- .toSet()
- .toList();
- acSelected = qualif
- .where((e) => e.tlc == widget.params.tlc)
- .map((e) => e.ac ?? "")
- .toSet()
- .toList();
- baseSelected = qualif
- .where((e) => e.tlc == widget.params.tlc)
- .map((e) => e.base ?? "")
- .toSet()
- .toList();
- }
- crewPnlegLoad();
- });
- super.initState();
- }
- // List crew = [];
- Jiffy _now = Jiffy.now().toUtc();
- @override
- Widget build(BuildContext context) {
- //final data = ref.watch(dataProvider);
- //final pnleg = data.pnleg;
- // final _dateNotifiedcrew = data.pnlegupdate;
- _now = ref.watch(clockProvider);
- //final qualif = ref.watch(dataProvider).qualif;
- return Scaffold(
- appBar: AppBar(
- title: MyRow(
- // mainAxisAlignment: MainAxisAlignment.spaceBetween,
- children: [
- Text(
- '${widget.params.dutytype ?? ""} ${widget.params.label ?? ""} ${widget.params.dep}${widget.params.des != null ? "-${widget.params.des}" : ""}'),
- const Gap(10),
- Text(widget.params.jdep!.format(pattern: "EEE ddMMM'yy"),
- style: const TextStyle(fontSize: 12)),
- ],
- ),
- leading: IconButton(
- icon: const Icon(Icons.arrow_back),
- onPressed: () {
- context.pop(context);
- },
- ),
- actions: [
- Text(
- '${widget.params.dutytype ?? "Duty"} info',
- style: TextStyle(
- fontSize: 12,
- fontWeight: FontWeight.w700,
- color: Colors.yellow),
- ),
- Gap(10)
- ],
- ),
- body: ListView(
- padding: const EdgeInsets.all(5),
- children: [
- WCadre(
- child: Column(
- children: [
- WDay(date: widget.params.jdep!),
- if (widget.params.label != null)
- Text(
- widget.params.label!,
- style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
- )
- else if (widget.params.dutytype != null)
- Text(
- widget.params.dutytype!,
- style: TextStyle(fontWeight: FontWeight.bold, fontSize: 18),
- ),
- Row(
- mainAxisAlignment: MainAxisAlignment.center,
- mainAxisSize: MainAxisSize.max,
- children: [
- if (widget.params.des != null)
- WCitypair(
- iata1: "${widget.params.dep}",
- iata2: widget.params.des ?? "---")
- else
- WAirport(iata: widget.params.dep ?? "---"),
- ],
- ),
- Row(
- mainAxisAlignment: MainAxisAlignment.center,
- mainAxisSize: MainAxisSize.max,
- children: [
- WHour(jiffy: widget.params.jdep!),
- if (widget.params.jdes != null) ...[
- const Gap(20),
- WHour(jiffy: widget.params.jdes!)
- ],
- ]),
- const Gap(10)
- ],
- ),
- ),
- const Gap(20),
- if (widget.params.dutytype == "standby")
- _stdbyCrew()
- else
- _notifiedCrew(),
- ],
- ),
- );
- }
- Jiffy? _dateNotifiedcrew;
- static List<Pnleg> filterPnleg(Map data) {
- final List<Pnleg> pnleg = data["pnleg"];
- final DutyinfoParams filter = data["filter"];
- return pnleg
- .where((leg) => ((filter.jdep == null ||
- (filter.sameday
- ? (leg.jdep?.startOf(Unit.day) ==
- filter.jdep?.startOf(Unit.day))
- : ((leg.jdep == filter.jdep) &&
- (filter.jdes == null || leg.jarr == filter.jdes)))) &&
- (filter.dep == null || leg.dep == filter.dep) &&
- (filter.des == null || leg.arr == filter.des) &&
- (filter.label == null || leg.label == filter.label) &&
- (filter.dutytype == null || leg.dutytype == filter.dutytype)))
- .toList();
- }
- List<Pnleg> crewPnleg = [];
- bool crewPnlegLoading = false;
- crewPnlegLoad() async {
- crewPnlegLoading = true;
- setState(() {});
- final data = ref.watch(dataProvider);
- final pnleg = data.pnleg;
- _dateNotifiedcrew = data.pnlegupdate;
- crewPnleg =
- await compute(filterPnleg, {"pnleg": pnleg, "filter": widget.params});
- crewPnlegLoading = false;
- setState(() {});
- }
- _notifiedCrew() {
- // final qualif = ref.watch(qualifProvider(CrewFilter()));
- final qualif = ref.watch(dataProvider).qualif;
- return WCadre(
- titleright: crewPnlegLoading
- ? Padding(
- padding: const EdgeInsets.all(5.0),
- child: CircularProgressIndicator(),
- )
- : ElevatedButton.icon(
- label: const Text("Update", style: TextStyle(fontSize: 9)),
- onPressed: () async {
- await crewPnlegLoad();
- },
- icon: const Icon(Icons.update)),
- title: "Notified Crew (alt)",
- bottomright: _dateNotifiedcrew != null
- ? Text("data retrieved ${_dateNotifiedcrew?.from(_now)}",
- style: GoogleFonts.robotoMono(
- fontSize: 10, fontWeight: FontWeight.w300))
- : null,
- child: crewPnleg.isEmpty
- ? const Text("No data found !")
- : Column(
- children: [
- Padding(
- padding: const EdgeInsets.all(8.0),
- child: Column(
- children: crewPnleg
- .mapIndexed((int i, leg) => {
- "index": i,
- "college": (["F", ""].contains(leg.type))
- ? "DH"
- : (qualif
- .firstWhereOrNull((e) =>
- (e.tlc == leg.tlc) &&
- (e.ac == leg.actype))
- ?.college ??
- qualif
- .firstWhereOrNull(
- (e) => e.tlc == leg.tlc)
- ?.college ??
- "--")
- })
- .sortedByCompare(
- (e) => e["college"].toString(), collegeSort)
- .map<Widget>((e) {
- final x = crewPnleg.elementAt(e["index"] as int);
- // final pn = qualif.firstWhereOrNull((e) => e.tlc == x.tlc);
- final pn = (qualif.firstWhereOrNull(
- (e) => (e.tlc == x.tlc) && (e.ac == x.actype)) ??
- qualif.firstWhereOrNull((e) => e.tlc == x.tlc));
- return WCrew(
- college: pn?.college,
- mle: x.tlc,
- base: pn?.base,
- name: "${pn?.lname}, ${pn?.fname}",
- );
- }).toList()),
- )
- ],
- ),
- );
- }
- List<String> collegeSelected = [];
- List<String> acSelected = [];
- List<String> baseSelected = [];
- _stdbyCrew() {
- // final qualif = ref.watch(qualifProvider(CrewFilter()));
- final qualif = ref.watch(dataProvider).qualif;
- final tlcs = crewPnleg.map((e) => e.tlc).toSet();
- final pairs = qualif
- .where((e) => tlcs.contains(e.tlc))
- .map((e) => "${e.college},${e.ac},${e.base}")
- .toSet()
- .map((e) => e.split(","))
- .toList();
- final List<String> pnfilterd = qualif
- .where((q) =>
- ((collegeSelected.isEmpty || collegeSelected.contains(q.college)) &&
- (acSelected.isEmpty || acSelected.contains(q.ac)) &&
- (baseSelected.isEmpty || baseSelected.contains(q.base))))
- .map((e) => e.tlc ?? "")
- .toSet()
- .toList();
- final List<Pnleg> crewPnlegFiltered =
- crewPnleg.where((e) => pnfilterd.contains(e.tlc)).toList();
- return WCadre(
- titleright: crewPnlegLoading
- ? Padding(
- padding: const EdgeInsets.all(5.0),
- child: CircularProgressIndicator(),
- )
- : ElevatedButton.icon(
- label: const Text("Update", style: TextStyle(fontSize: 9)),
- onPressed: () async {
- await crewPnlegLoad();
- },
- icon: const Icon(Icons.update)),
- title: "STDBY Crew",
- bottomright: _dateNotifiedcrew != null
- ? Text("data retrieved ${_dateNotifiedcrew?.from(_now)}",
- style: GoogleFonts.robotoMono(
- fontSize: 10, fontWeight: FontWeight.w300))
- : null,
- child: crewPnleg.isEmpty
- ? const Text("No data found !")
- : Column(
- children: [
- MyRow(
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- children: [
- Gap(5),
- Column(
- children: [
- const Text('College:', style: TextStyle(fontSize: 11)),
- Text("(${(collegeSelected.length)})",
- style: TextStyle(fontSize: 11))
- ],
- ),
- Gap(5),
- MultiSelectChipDisplay(
- colorator: (value) => (collegeSelected.contains(value))
- ? Colors.green[800]
- : Colors.grey[900],
- //chipColor: Colors.blue[900],
- icon: null,
- textStyle: TextStyle(fontSize: 9, color: Colors.white),
- scrollBar: HorizontalScrollBar(),
- scroll: true,
- items: pairs
- .map((e) => e[0])
- .sortedByCompare((e) => e, collegeSort)
- .toSet()
- .map((e) => MultiSelectItem(e, "$e"))
- .toList(),
- onTap: (value) {
- setState(() {
- if (collegeSelected.contains(value)) {
- collegeSelected.remove(value);
- } else {
- collegeSelected.add(value);
- }
- });
- },
- ),
- ],
- ),
- MyRow(
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- children: [
- Gap(5),
- Column(
- children: [
- const Text('ACs:', style: TextStyle(fontSize: 11)),
- Text("(${(acSelected.length)})",
- style: TextStyle(fontSize: 11))
- ],
- ),
- Gap(5),
- MultiSelectChipDisplay(
- colorator: (value) => (acSelected.contains(value))
- ? Colors.green[800]
- : Colors.grey[900],
- //chipColor: Colors.blue[900],
- icon: null,
- textStyle: TextStyle(fontSize: 9, color: Colors.white),
- scrollBar: HorizontalScrollBar(),
- scroll: true,
- items: pairs
- .map((e) => e[1])
- .sortedByCompare((e) => e, acSort)
- .toSet()
- .map((e) => MultiSelectItem(e, "$e"))
- .toList(),
- onTap: (value) {
- setState(() {
- if (acSelected.contains(value)) {
- acSelected.remove(value);
- } else {
- acSelected.add(value);
- }
- });
- },
- ),
- ],
- ),
- MyRow(
- mainAxisAlignment: MainAxisAlignment.spaceEvenly,
- children: [
- const Gap(5),
- Column(
- children: [
- const Text('Base:', style: TextStyle(fontSize: 11)),
- Text("(${(baseSelected.length)})",
- style: TextStyle(fontSize: 11))
- ],
- ),
- const Gap(5),
- MultiSelectChipDisplay(
- colorator: (value) => (baseSelected.contains(value))
- ? Colors.green[800]
- : Colors.grey[900],
- //chipColor: Colors.blue[900],
- icon: null,
- textStyle: TextStyle(fontSize: 9, color: Colors.white),
- scrollBar: HorizontalScrollBar(),
- scroll: true,
- items: pairs
- .map((e) => e[2])
- .sortedByCompare((e) => e, baseSort)
- .toSet()
- .map((e) => MultiSelectItem(e, "$e"))
- .toList(),
- onTap: (value) {
- setState(() {
- if (baseSelected.contains(value)) {
- baseSelected.remove(value);
- } else {
- baseSelected.add(value);
- }
- });
- },
- ),
- ],
- ),
- Padding(
- padding: const EdgeInsets.all(8.0),
- child: Column(
- children: crewPnlegFiltered
- .mapIndexed((int i, leg) {
- // print(leg);
- return {
- "index": i,
- "college": (qualif
- .where((e) => e.tlc == leg.tlc)
- .map((e) => e.college)
- .sortedByCompare(
- (e) => e ?? "", collegeSort))
- .firstOrNull ??
- "--",
- // "jdep": (leg.jdep?.millisecondsSinceEpoch ?? 0)
- "jdep": (leg.label ?? "0")
- };
- })
- .sortedByCompare(
- (e) => [
- e["jdep"].toString(),
- e["college"].toString()
- ],
- jdepcollegeSort)
- .map<Widget>((e) {
- final x =
- crewPnlegFiltered.elementAt(e["index"] as int);
- // final pn =
- // qualif.firstWhereOrNull((e) => e.tlc == x.tlc);
- final pn = (qualif.firstWhereOrNull((e) =>
- (e.tlc == x.tlc) && (e.ac == x.actype)) ??
- qualif.firstWhereOrNull((e) => e.tlc == x.tlc));
- return Row(
- children: [
- Text("${e["jdep"]}"),
- WCrew(
- college: pn?.college,
- mle: x.tlc,
- base: pn?.base,
- name: "${pn?.lname}, ${pn?.fname}",
- ),
- ],
- );
- })
- .toList()),
- )
- ],
- ),
- );
- }
- }
- class DutyinfoParams {
- const DutyinfoParams({
- this.tlc,
- this.sameday = false,
- this.date,
- this.start,
- this.end,
- this.label,
- this.dutytype,
- this.jdep,
- this.jdes,
- this.dep,
- this.des,
- });
- final String? tlc;
- final bool sameday;
- final Jiffy? start;
- final Jiffy? end;
- final String? date;
- final String? label;
- final String? dutytype;
- final Jiffy? jdep;
- final Jiffy? jdes;
- final String? dep;
- final String? des;
- }
- int collegeSort(String a, String b) {
- // Define the order based on your requirements
- final order = ['CP', 'FO', 'PU', 'SE', 'ST', 'JU'];
- // Get the index of each element in the order list
- final indexA = !order.contains(a) ? 99 : order.indexOf(a);
- final indexB = !order.contains(b) ? 99 : order.indexOf(b);
- // Compare based on the index
- return indexA.compareTo(indexB);
- }
- int acSort(String a, String b) {
- // Define the order based on your requirements
- final order = ['320', '330', '32N', '319', '32T'];
- // Get the index of each element in the order list
- final indexA = !order.contains(a) ? 99 : order.indexOf(a);
- final indexB = !order.contains(b) ? 99 : order.indexOf(b);
- // Compare based on the index
- return indexA.compareTo(indexB);
- }
- int baseSort(String a, String b) {
- // Define the order based on your requirements
- final order = ['TUN', 'MIR', 'DJE'];
- // Get the index of each element in the order list
- final indexA = !order.contains(a) ? 99 : order.indexOf(a);
- final indexB = !order.contains(b) ? 99 : order.indexOf(b);
- // Compare based on the index
- return indexA.compareTo(indexB);
- }
- int jdepcollegeSort(List<String> a, List<String> b) {
- final String x = a[0];
- final String y = b[0];
- final res = x.compareTo(y);
- if (res == 0) {
- return collegeSort(a[1], b[1]);
- } else {
- return res;
- }
- }
|