| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361 | // ignore: unused_importimport 'package:collection/collection.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:hive_flutter/hive_flutter.dart';import 'package:jiffy/jiffy.dart';import 'package:super_sliver_list/super_sliver_list.dart';import 'package:tp5/core/basic_page.dart';import 'package:tp5/core/utils.dart';import 'package:tp5/csv/data.dart';import 'package:tp5/flightslist/w_flt.dart';import 'package:tp5/fltinfo/view/fltinfo_page.dart';import 'package:tp5/roster/widgets/w_day.dart';class FlightslistPage extends ConsumerStatefulWidget {  const FlightslistPage({super.key});  @override  ConsumerState<ConsumerStatefulWidget> createState() =>      _FlightslistPageState();}class _FlightslistPageState extends ConsumerState<FlightslistPage> {  final _listController = ListController();  final _scrollController = ScrollController();  void scrolltonow() {    final jumpindex = _aclegs.indexWhere((e) => e.jdep!.isSameOrAfter(_now));    if (jumpindex >= 0) {      jumpToItem(jumpindex);    }  }  void jumpToItem(int index) {    try {      if (_listController.isAttached && _scrollController.hasClients) {        _listController.jumpToItem(          //duration: (d) => const Duration(milliseconds: 700),          index: index,          scrollController: _scrollController,          alignment: 0.75,          //curve: (double estimatedDistance) => Curves.decelerate,        );      }    } catch (e) {      print("flistlistpage: jumptoitemscroll controller");    }  }  bool showAllLegs = false;  bool showInflightOnly = false;  // bool _isfirstInDay(Acleg leg) =>  //     leg == _aclegs.firstWhereOrNull((e) => (e.jdep?.yMEd == leg.jdep?.yMEd));  Widget get _acLegsWidget => Container(      child: _aclegs.isEmpty          ? const Text("No leg found !")          : SuperListView.builder(              delayPopulatingCacheArea: true,              listController: _listController,              controller: _scrollController,              itemCount: _aclegs.length,              itemBuilder: (context, index) {                final leg = _aclegs.elementAt(index);                return Column(                  children: [                    // if (_isfirstInDay(leg))                    if (index == 0 ||                        leg.jdep?.yMEd !=                            _aclegs.elementAt(index - 1).jdep?.yMEd)                      WDay(                          date: leg.jdep!,                          highlight: _now.yMEd == leg.jdep?.yMEd),                    InkWell(                        onTap: () => context.push("/fltinfo",                            extra: FltinfoParams(                              al: leg.FN_CARRIER,                              fnum: leg.FN_NUMBER,                              jdep: leg.jdep,                              jdes: leg.jarr,                              dep: leg.DEP_AP_ACTUAL,                              des: leg.ARR_AP_SCHED,                            )),                        child: WFlt(acleg: leg)),                  ],                );              },            ));  final bottomnavstyle = ElevatedButton.styleFrom(      shape: RoundedRectangleBorder(        borderRadius: BorderRadius.circular(5.0),      ),      backgroundColor:          const Color.fromARGB(255, 0, 36, 53) //elevated btton background color      );  TextEditingController ctrldep = TextEditingController();  TextEditingController ctrldes = TextEditingController();  TextEditingController ctrlairline = TextEditingController();  TextEditingController ctrlfnum = TextEditingController();  Widget _flightFilter(BuildContext context) {    return Container(        padding: const EdgeInsets.all(20),        child: Column(mainAxisSize: MainAxisSize.min, children: [          Row(            children: [              Expanded(                child: TextField(                  decoration:                      const InputDecoration(labelText: "Departure Airport"),                  maxLength: 3, // Set maximum length                  controller: ctrldep,                ),              ),              const SizedBox(width: 10),              Expanded(                child: TextField(                  decoration:                      const InputDecoration(labelText: "Arrival Airport"),                  maxLength: 3, // Set maximum length                  controller: ctrldes,                ),              ),            ],          ),          const SizedBox(height: 15),          Row(            children: [              Expanded(                child: TextField(                  controller: ctrlairline,                  decoration:                      const InputDecoration(labelText: "Airline IATA code"),                  maxLength: 2, // Set maximum length                ),              ),              const SizedBox(width: 10),              Expanded(                child: TextField(                  controller: ctrlfnum,                  decoration: const InputDecoration(labelText: "Flight number"),                  maxLength: 6, // Set maximum length                ),              ),            ],          ),          const SizedBox(height: 15),          const SizedBox(height: 35),          SizedBox(            width: 360,            child: ElevatedButton(              onPressed: () async => Navigator.pop(context, {                "dep": ctrldep.text.toUpperCase(),                "des": ctrldes.text.toUpperCase(),                "al": ctrlairline.text.toUpperCase(),                "fnum": ctrlfnum.text.toUpperCase()              }), // Close the bottom sheet              style: ElevatedButton.styleFrom(                backgroundColor: Colors.green, // Set button color to green                shape: RoundedRectangleBorder(                  borderRadius:                      BorderRadius.circular(15), // Add rounded corners                ),                padding:                    const EdgeInsets.symmetric(horizontal: 20, vertical: 15),              ),              child: const Text(                'Flight filter',                style: TextStyle(fontSize: 18, color: Colors.white),              ),            ),          ),        ]));  }  Map<String, String> flightFilter = {    "dep": "",    "des": "",    "al": "",    "fnum": ""  };  void _loadSearchFlights() {    showInflightOnly = Hive.box("settings")        .get("flightslist.filter.inflightonly", defaultValue: false);    final filter = Hive.box("settings")        .get("flightslist.filter.flights", defaultValue: <Map>{});    // print("flightslist: loadsearchflights: saved: $filter");    if (filter is Map) {      for (var e in filter.keys) {        flightFilter[e] = filter[e] ?? "";      }    }  }  void _searchFlights(xcontext) async {    ctrldep.text = flightFilter["dep"] ?? "";    ctrldes.text = flightFilter["des"] ?? "";    ctrlairline.text = flightFilter["al"] ?? "";    ctrlfnum.text = flightFilter["fnum"] ?? "";    final res = await showModalBottomSheet(        context: context, builder: (context) => _flightFilter(xcontext));    if (res is Map<String, String>) {      Hive.box("settings").put("flightslist.filter.flights", (res));      setState(() {        flightFilter = res;      });    }  }  @override  void initState() {    _loadSearchFlights();    Future.delayed(const Duration(milliseconds: 700)).then((x) {      scrolltonow();    });    super.initState();  }  List<Acleg> _allAclegs = [];  List<Acleg> get _aclegs => _allAclegs      .where((leg) =>          (!showInflightOnly ||              (showInflightOnly &&                  (leg.flt_status == "Inflight" ||                      leg.flt_status == "Taxiout"))) &&          ((flightFilter["al"] == "" || leg.FN_CARRIER == flightFilter["al"]) &&              (flightFilter["fnum"] == "" ||                  leg.FN_NUMBER == flightFilter["fnum"]) &&              (flightFilter["dep"] == "" ||                  leg.DEP_AP_ACTUAL == flightFilter["dep"] ||                  leg.DEP_SCHED_DT == flightFilter["dep"]) &&              (flightFilter["des"] == "" ||                  leg.ARR_AP_ACTUAL == flightFilter["des"] ||                  leg.ARR_AP_SCHED == flightFilter["des"])))      .toList();  Jiffy _now = Jiffy.now();  @override  Widget build(BuildContext context) {    final data = ref.watch(dataProvider);    _allAclegs = data.acleg;    _now = ref.watch(clockProvider);    return BasicPage(      appBar: AppBar(        title: const Text('Flights List'),      ),      body: Center(        child: Column(          children: [            Expanded(child: _acLegsWidget),            Row(              mainAxisAlignment: MainAxisAlignment.end,              children: [                data.aclegupdate != null                    ? Text("data retrieved ${data.aclegupdate?.from(_now)}",                        style: GoogleFonts.robotoMono(                            fontSize: 10, fontWeight: FontWeight.w300))                    : Text("no data found",                        style: GoogleFonts.robotoMono(                            fontSize: 10, fontWeight: FontWeight.w300))              ],            )          ],        ),      ),      actions: [],      bottomNavigationBar: Container(        padding: const EdgeInsets.all(8),        // color: Colors.black,        decoration: BoxDecoration(            gradient: LinearGradient(          begin: Alignment.topCenter,          end: Alignment.bottomCenter,          colors: [            Colors.grey[700]!,            Colors.black,          ],        )),        child: Row(          mainAxisAlignment: MainAxisAlignment.spaceAround,          children: [            ElevatedButton.icon(              onPressed: () async {                showInflightOnly = !showInflightOnly;                setState(() {});                Future.delayed(Duration(milliseconds: 200)).then((x) {                  scrolltonow();                });                await Hive.box("settings")                    .put("flightslist.filter.inflightonly", showInflightOnly);              },              icon: showInflightOnly                  ? Icon(Icons.flight_takeoff)                  : Icon(Icons.all_out),              label: showInflightOnly                  ? Text("Inflight\nonly")                  : Text("All flight\nstatus"),              style: bottomnavstyle,            ),            const Gap(10),            Row(              children: [                ElevatedButton.icon(                  onPressed: () {                    _searchFlights(context);                  },                  icon: const Icon(Icons.manage_search),                  label: const Text("Filter\nFlights"),                  style: bottomnavstyle,                ),                const Gap(10),                Column(                    mainAxisSize: MainAxisSize.min,                    children: flightFilter.keys                        .where((e) => flightFilter[e] != "")                        .map((e) => Text(                              "$e: ${flightFilter[e]}",                              style: const TextStyle(                                  fontSize: 12, color: Colors.yellow),                            ))                        .toList()),                const Gap(10),                if (flightFilter.values.any((e) => e != ""))                  Badge(                    label: Text(flightFilter.values                        .where((e) => e != "")                        .length                        .toString()),                    child: IconButton.outlined(                        onPressed: () {                          for (var k in flightFilter.keys) {                            flightFilter[k] = "";                          }                          Hive.box("settings")                              .delete("flightslist.filter.flights");                          setState(() {});                        },                        icon:                            const Icon(Icons.filter_alt_off_rounded, size: 18)),                  )              ],            ),          ],        ),      ),    );  }}
 |