import 'package:fforte/enums/databases.dart'; import 'package:fforte/screens/addCam/cam_widgets.dart'; import 'package:fforte/screens/helper/dialog_helper.dart'; import 'package:fforte/screens/helper/snack_bar_helper.dart'; import 'package:fforte/screens/addCam/exceptions/location_disabled_exception.dart'; import 'package:fforte/screens/addCam/exceptions/location_forbidden_exception.dart'; import 'package:fforte/screens/addCam/services/geolocator_service.dart'; import 'package:fforte/screens/sharedMethods/check_required.dart'; import 'package:fforte/screens/sharedMethods/save_template.dart'; import 'package:fforte/screens/sharedWidgets/datum.dart'; import 'package:fforte/screens/sharedWidgets/var_text_field.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:geolocator/geolocator.dart'; import 'package:latlong2/latlong.dart'; import 'package:animations/animations.dart'; class AddCamMain extends StatefulWidget { final bool isTemplate; final bool isFinished; final bool isSent; final Map? existingData; const AddCamMain( {super.key, this.isTemplate = false, this.existingData, this.isFinished = false, this.isSent = false}); @override State createState() => _AddCamMainState(); } class _AddCamMainState extends State { // var declaration int currentStep = 0; // bool isTemplate = false; // TextEditingController cid = TextEditingController(); // TextEditingController rudelC = TextEditingController(); // TextEditingController adresse1C = TextEditingController(); // TextEditingController adresse2C = TextEditingController(); // TextEditingController adresse3C = TextEditingController(); // TextEditingController bLandC = TextEditingController(); // TextEditingController lkrC = TextEditingController(); // TextEditingController beiOrtC = TextEditingController(); // TextEditingController ortInfoC = TextEditingController(); // TextEditingController ffTypC = TextEditingController(); // TextEditingController kSchloNrC = TextEditingController(); // TextEditingController auftragC = TextEditingController(); // TextEditingController kontAbspC = TextEditingController(); // TextEditingController sonstBemC = TextEditingController(); // TextEditingController fKontakt1C = TextEditingController(); // TextEditingController fKontakt2C = TextEditingController(); // TextEditingController fKontakt3C = TextEditingController(); // TextEditingController standortC = TextEditingController(); // TextEditingController kTage1C = TextEditingController(); // TextEditingController kTage2C = TextEditingController(); // TextEditingController intKommC = TextEditingController(); // TextEditingController betreuungC = TextEditingController(); String selectedStatus = 'aktiv'; String selectedFotoFilm = 'Foto'; String selectedMEZ = 'Sommerzeit'; String selectedPlatzung = ''; Position currentPosition = Position( longitude: 10.0, latitude: 51.0, timestamp: DateTime.now(), accuracy: 0.0, altitude: 0.0, heading: 0.0, speed: 0.0, speedAccuracy: 0.0, altitudeAccuracy: 0.0, headingAccuracy: 0.0); DateTime? abbauDat; DateTime datum = DateTime.now(); DateTime? kontDat = DateTime.now(); DateTime? protoAm = DateTime.now(); static Map> rmap = { // Step 1 "Standort": { "controller": TextEditingController(), "required": true, }, "Status": { "controller": TextEditingController(), "required": true, }, "Betreuung": { "controller": TextEditingController(), "required": false, }, "CID": { "controller": TextEditingController(), "required": true, }, "FFTyp": { "controller": TextEditingController(), "required": true, }, "Mez": { "controller": TextEditingController(), "required": true, }, "KSchloNr": { "controller": TextEditingController(), "required": false, }, "Rudel": { "controller": TextEditingController(), "required": true, }, // Step 2 "DECLNG": { "controller": TextEditingController(), "required": false, }, "DECLAT": { "controller": TextEditingController(), "required": false, }, "Bland": { "controller": TextEditingController(), "required": true, }, "Lkr": { "controller": TextEditingController(), "required": true, }, "BeiOrt": { "controller": TextEditingController(), "required": true, }, "OrtInfo": { "controller": TextEditingController(), "required": false, }, "Platzung": { "controller": TextEditingController(), "required": true, }, // Step 3 "Datum": { "controller": TextEditingController(), "required": false, }, "KontDat": { "controller": TextEditingController(), "required": false, }, "KTage1": { "controller": TextEditingController(), "required": true, }, "KTage2": { "controller": TextEditingController(), "required": true, }, "AbbauDat": { "controller": TextEditingController(), "required": false, }, "Auftrag": { "controller": TextEditingController(), "required": false, }, "KontAbsp": { "controller": TextEditingController(), "required": false, }, "SonstBem": { "controller": TextEditingController(), "required": false, }, // Step 4 "Adresse1": { "controller": TextEditingController(), "required": true, }, "Adresse2": { "controller": TextEditingController(), "required": false, }, "Adresse3": { "controller": TextEditingController(), "required": false, }, "FKontakt1": { "controller": TextEditingController(), "required": false, }, "FKontakt2": { "controller": TextEditingController(), "required": false, }, "FKontakt3": { "controller": TextEditingController(), "required": false, }, "IntKomm": { "controller": TextEditingController(), "required": false, }, // Gone? "ProtoAm": { "controller": TextEditingController(), "required": false, }, "FotoFilm": { "controller": TextEditingController(), "required": false, }, }; // Map> rmap { // Map> rmap = { // // Step 1 // "Standort": { "controller": betreuungC, "required": true, }, // "Status": { "controller": TextEditingController(), "required": true, }, // "Betreuung": { "controller": TextEditingController(), "required": false, }, // "CID": { "controller": TextEditingController(), "required": true, }, // "FFTyp": { "controller": TextEditingController(), "required": true, }, // "Mez": { "controller": TextEditingController(), "required": true, }, // "KSchloNr": { "controller": TextEditingController(), "required": false, }, // "Rudel": { "controller": TextEditingController(), "required": true, }, // // // Step 2 // "DECLNG": { "controller": TextEditingController(), "required": false, }, // "DECLAT": { "controller": TextEditingController(), "required": false, }, // "Bland": { "controller": TextEditingController(), "required": true, }, // "Lkr": { "controller": TextEditingController(), "required": true, }, // "BeiOrt": { "controller": TextEditingController(), "required": true, }, // "OrtInfo": { "controller": TextEditingController(), "required": false, }, // "Platzung": { "controller": TextEditingController(), "required": true, }, // // // Step 3 // "Datum": { "controller": TextEditingController(), "required": false, }, // "KontDat": { "controller": TextEditingController(), "required": false, }, // "KTage1": { "controller": TextEditingController(), "required": true, }, // "KTage2": { "controller": TextEditingController(), "required": true, }, // "AbbauDat": { "controller": TextEditingController(), "required": false, }, // "Auftrag": { "controller": TextEditingController(), "required": false, }, // "KontAbsp": { "controller": TextEditingController(), "required": false, }, // "SonstBem": { "controller": TextEditingController(), "required": false, }, // // // Step 4 // "Adresse1": { "controller": TextEditingController(), "required": true, }, // "Adresse2": { "controller": TextEditingController(), "required": false, }, // "Adresse3": { "controller": TextEditingController(), "required": false, }, // "FKontakt1": { "controller": TextEditingController(), "required": false, }, // "FKontakt2": { "controller": TextEditingController(), "required": false, }, // "FKontakt3": { "controller": TextEditingController(), "required": false, }, // "IntKomm": { "controller": TextEditingController(), "required": false, }, // // // Gone? // "ProtoAm": { "controller": TextEditingController(), "required": false, }, // "FotoFilm": { "controller": TextEditingController(), "required": false, }, // }; // return rmap; // } Map getFieldsText() { Map puff = {}; for (var itemKey in rmap.keys) { puff[itemKey] = rmap[itemKey]!["controller"]!.text; } return puff; } // Map getPlace() { // Map place = { // 'ID': widget.existingData?['ID'], // 'CID': cid.text, // 'Rudel': rudelC.text, // 'Datum': datum.toString().split(" ").first, // 'Adresse1': adresse1C.text, // 'Adresse2': adresse2C.text, // 'Adresse3': adresse3C.text, // 'BLand': bLandC.text, // 'Lkr': lkrC.text, // 'BeiOrt': beiOrtC.text, // 'OrtInfo': ortInfoC.text, // 'Status': selectedStatus, // 'FFTyp': ffTypC.text, // 'FotoFilm': selectedFotoFilm, // 'MEZ': selectedMEZ, // 'Platzung': selectedPlatzung, // 'KSchloNr': kSchloNrC.text, // 'KontDat': kontDat.toString().split(" ").first, // 'AbbauDat': abbauDat.toString().split(" ").first.replaceAll("null", ""), // 'Auftrag': auftragC.text, // 'KontAbsp': kontAbspC.text, // 'SonstBem': sonstBemC.text, // 'FKontakt1': fKontakt1C.text, // 'FKontakt2': fKontakt2C.text, // 'FKontakt3': fKontakt3C.text, // 'Standort': standortC.text, // 'KTage1': kTage1C.text, // 'KTage2': kTage2C.text, // 'ProtoAm': protoAm.toString().split(" ").first, // 'IntKomm': intKommC.text, // 'Betreuung': betreuungC.text, // 'DECLNG': currentPosition.longitude, // 'DECLAT': currentPosition.latitude, // }; // // return place; // } @override void initState() { // updates the currentPosition var after the _determine position has finished. Means user view updates with his live location try { GeolocatorService.deteterminePosition() .then((result) => currentPosition = result); } on LocationDisabledException { SnackBarHelper.showSnackBarMessage( context, AppLocalizations.of(context)!.locationDisabled); } on LocationForbiddenException { SnackBarHelper.showSnackBarMessage( context, AppLocalizations.of(context)!.locationForbidden); } // select initial werte rmap["Mez"]!["controller"]!.text = selectedMEZ; rmap["Status"]!["controller"]!.text = selectedStatus; // TODO ADD THIS AGAIN BUT RIGHT // If a template is edited this fills in the existing values // if (widget.isTemplate || widget.isFinished && widget.existingData != null) { // cid.text = widget.existingData!['CID'] ?? ""; // rudelC.text = widget.existingData!['Rudel'] ?? ""; // adresse1C.text = widget.existingData!['Adresse1'] ?? ""; // adresse2C.text = widget.existingData!['Adresse2'] ?? ""; // adresse3C.text = widget.existingData!['Adresse3'] ?? ""; // bLandC.text = widget.existingData!['BLand'] ?? ""; // lkrC.text = widget.existingData!['Lkr'] ?? ""; // beiOrtC.text = widget.existingData!['BeiOrt'] ?? ""; // ortInfoC.text = widget.existingData!['OrtInfo'] ?? ""; // selectedStatus = widget.existingData!['Status'] ?? ""; // ffTypC.text = widget.existingData!['FFTyp'] ?? ""; // selectedFotoFilm = widget.existingData!['FotoFilm'] ?? ""; // selectedMEZ = widget.existingData!['MEZ'] ?? ""; // selectedPlatzung = widget.existingData!['Platzung'] ?? ""; // kSchloNrC.text = widget.existingData!['KSchloNr'] ?? ""; // datum = DateTime.parse(widget.existingData!['Datum']); // kontDat = widget.existingData!['KontDat'] == "" // ? null // : DateTime.parse(widget.existingData!['KontDat']); // abbauDat = widget.existingData!['AbbauDat'] == "" // ? null // : DateTime.parse(widget.existingData!['AbbauDat']); // auftragC.text = widget.existingData!['Auftrag'] ?? ""; // kontAbspC.text = widget.existingData!['KontAbsp'] ?? ""; // sonstBemC.text = widget.existingData!['SonstBem'] ?? ""; // fKontakt1C.text = widget.existingData!['FKontakt1'] ?? ""; // fKontakt2C.text = widget.existingData!['FKontakt2'] ?? ""; // fKontakt3C.text = widget.existingData!['FKontakt3'] ?? ""; // standortC.text = widget.existingData!['Standort'] ?? ""; // kTage1C.text = widget.existingData!['KTage1'].toString(); // kTage2C.text = widget.existingData!['KTage2'].toString(); // protoAm = widget.existingData!['ProtoAm'] == null // ? null // : DateTime.parse(widget.existingData!['ProtoAm']); // intKommC.text = widget.existingData!['IntKomm'] ?? ""; // betreuungC.text = widget.existingData!['Betreuung'] ?? ""; // } super.initState(); } // checks if required fields are not empty. If one is the name will be returned // TODO rewrite // List validateData() { // List emptyFields = []; // // Map fields = { // AppLocalizations.of(context)!.camLink: cid, // AppLocalizations.of(context)!.rudel: rudelC, // AppLocalizations.of(context)!.adresse1: adresse1C, // AppLocalizations.of(context)!.bland: bLandC, // AppLocalizations.of(context)!.lkr: lkrC, // AppLocalizations.of(context)!.beiort: beiOrtC, // AppLocalizations.of(context)!.status: // TextEditingController(text: selectedStatus), // AppLocalizations.of(context)!.fftyp: ffTypC, // "${AppLocalizations.of(context)!.foto} / ${AppLocalizations.of(context)!.filelocation}": // TextEditingController(text: selectedFotoFilm), // AppLocalizations.of(context)!.zeiteinstellung: // TextEditingController(text: selectedMEZ), // AppLocalizations.of(context)!.platzung: // TextEditingController(text: selectedPlatzung), // AppLocalizations.of(context)!.ktage1: kTage1C, // AppLocalizations.of(context)!.ktage1: kTage2C, // AppLocalizations.of(context)!.location: standortC, // }; // // for (var entry in fields.entries) { // if (entry.value.text.isEmpty) { // emptyFields.add(entry.key); // } // } // // empty = false; // if (emptyFields.isNotEmpty) empty = true; // // return emptyFields; // } // The widget tree which gets the shown widget from the ./cam_widgets.dart file // The names of the widgets should be self-explaining @override Widget build(BuildContext context) { // List with the steps. The steps itself will be "shown" later List getSteps() => [ // First step Step( title: Text(AppLocalizations.of(context)!.firststep), content: Column( children: [ Align( alignment: Alignment.bottomLeft, child: VarTextField( required: true, dbName: "Standort", textController: rmap["Standort"]!["controller"]!, // textController: betreuungC, localization: AppLocalizations.of(context)!.altstort, dbDesignation: DatabasesEnum.place, ), ), const SizedBox( height: 5, ), // -------------------- Align( alignment: Alignment.bottomLeft, child: Row( children: [ Text(AppLocalizations.of(context)!.status), const Text( '*', style: TextStyle(color: Colors.red), ), ], )), Status( initialStatus: selectedStatus, onStatusChanged: (status) { setState(() { rmap["Status"]!["controller"]!.text = status; }); }, ), // -------------------- VarTextField( textController: rmap["Betreuung"]!["controller"]!, localization: AppLocalizations.of(context)!.betreuung, dbName: "Betreuung", required: false, dbDesignation: DatabasesEnum.place, ), const SizedBox( height: 20, ), // -------------------- VarTextField( textController: rmap["CID"]!["controller"], localization: AppLocalizations.of(context)!.camLink, dbName: "CID", required: true, dbDesignation: DatabasesEnum.place, ), // -------------------- VarTextField( textController: rmap["FFTyp"]!["controller"], localization: AppLocalizations.of(context)!.fftyp, dbName: "FFTyp", required: true, dbDesignation: DatabasesEnum.place, ), const SizedBox( height: 15, ), // -------------------- Align( alignment: Alignment.bottomLeft, child: Row( children: [ Text(AppLocalizations.of(context)!.zeiteinstellung), const Text( '*', style: TextStyle(color: Colors.red), ) ], )), MEZ( initialMEZ: selectedMEZ, onMEZChanged: (mez) { setState(() { selectedMEZ = mez; rmap["Mez"]!["controller"]!.text = mez; }); }, ), const SizedBox( height: 15, ), // -------------------- VarTextField( textController: rmap["KSchloNr"]!["controller"], localization: AppLocalizations.of(context)!.kschlonr, dbName: "KSchloNr", required: false, dbDesignation: DatabasesEnum.place, ), const SizedBox( height: 5, ), // -------------------- VarTextField( textController: rmap["Rudel"]!["controller"], localization: AppLocalizations.of(context)!.rudel, dbName: "Rudel", required: true, dbDesignation: DatabasesEnum.place, ), const SizedBox( height: 15, ), ], )), // Second step Step( title: Text(AppLocalizations.of(context)!.secondstep), content: Column( children: [ Row( // TODO MAYBE FIX children: [ Column( children: [ Text(currentPosition.latitude.toString()), Text(currentPosition.longitude.toString()), ], ), const SizedBox( width: 15, ), ElevatedButton( onPressed: () async { final result = await Navigator.of(context) .push( MaterialPageRoute(builder: (context) { return Karte( ortInfoC: rmap["OrtInfo"]!["controller"], beiOrtC: rmap["BeiOrt"]!["controller"], currentPosition: currentPosition, onPositionChange: (updatedPosition) { setState(() { currentPosition = updatedPosition; rmap["DECLNG"]!["controller"]!.text = updatedPosition.longitude.toString(); rmap["DECLAT"]!["controller"]!.text = updatedPosition.latitude.toString(); }); }, ); })); if (result != null) { setState(() { currentPosition = Position( latitude: result.latitude, longitude: result.longitude, timestamp: DateTime.now(), accuracy: 0.0, altitude: 0.0, altitudeAccuracy: 0.0, heading: 0.0, headingAccuracy: 0.0, speed: 0.0, speedAccuracy: 0.0, ); }); } }, child: Text(AppLocalizations.of(context)!.openMap)), ], ), // -------------------- VarTextField( textController: rmap["Bland"]!["controller"]!, localization: AppLocalizations.of(context)!.bland, dbName: "BLand", required: true, dbDesignation: DatabasesEnum.place, defaultValue: "bLand", ), // -------------------- VarTextField( textController: rmap["Lkr"]!["controller"]!, localization: AppLocalizations.of(context)!.lkr, dbName: "Lkr", required: true, dbDesignation: DatabasesEnum.place, ), // -------------------- VarTextField( textController: rmap["BeiOrt"]!["controller"]!, localization: AppLocalizations.of(context)!.beiort, dbName: "BeiOrt", required: true, dbDesignation: DatabasesEnum.place, ), // -------------------- VarTextField( textController: rmap["OrtInfo"]!["controller"]!, localization: AppLocalizations.of(context)!.ortinfo, dbName: "OrtInfo", required: false, dbDesignation: DatabasesEnum.place, ), const SizedBox( height: 15, ), // -------------------- Align( alignment: Alignment.bottomLeft, child: Row( children: [ Text(AppLocalizations.of(context)!.platzung), const Text( '*', style: TextStyle(color: Colors.red), ) ], )), Platzung( initialPlatzung: selectedPlatzung, onPlatzungChanged: (platzung) { setState(() { selectedPlatzung = platzung; rmap["Platzung"]!["controller"]!.text = platzung; }); }, ), ], )), // Third step Step( title: Text(AppLocalizations.of(context)!.thirdstep), content: Column( children: [ Datum( initDatum: datum, onDateChanged: (value) { datum = value; rmap["Datum"]!["controller"]!.text = value.toString().split(" ").first; }, name: AppLocalizations.of(context)!.pickDate, ), // -------------------- KontDat( initKontDat: kontDat, onDateChanged: (value) { setState(() { kontDat = value; rmap["KontDat"]!["controller"]!.text = value.toString().split(" ").first; }); }, ), const SizedBox( height: 20, ), // -------------------- Align( alignment: Alignment.bottomLeft, child: Row( children: [ Text(AppLocalizations.of(context)!.ktage), const Text( '*', style: TextStyle(color: Colors.red), ), ], ), ), Row( children: [ Expanded( child: Text(AppLocalizations.of(context)!.ktage1)), const SizedBox( width: 15, ), Expanded( flex: 4, child: VarTextField( otherDefault: "24", textController: rmap["KTage1"]!["controller"]!, localization: AppLocalizations.of(context)!.ktage1, dbName: "KTage1", required: true, dbDesignation: DatabasesEnum.place, )) ], ), Row( children: [ Expanded( child: Text(AppLocalizations.of(context)!.ktage2)), const SizedBox( width: 15, ), Expanded( flex: 4, child: VarTextField( otherDefault: "48", textController: rmap["KTage2"]!["controller"]!, localization: AppLocalizations.of(context)!.ktage2, dbName: "KTage2", required: true, dbDesignation: DatabasesEnum.place, )) ], ), const SizedBox( height: 20, ), // -------------------- Row( children: [ AbbauDat( initAbbauDat: abbauDat, onDateChanged: (value) { abbauDat = value; rmap["AbbauDat"]!["controller"]!.text = value.toString().split(" ").first; }, ), ], ), const SizedBox( height: 20, ), // -------------------- VarTextField( textController: rmap["Auftrag"]!["controller"]!, localization: AppLocalizations.of(context)!.auftrag, dbName: "Auftrag", required: false, dbDesignation: DatabasesEnum.place, ), // -------------------- VarTextField( textController: rmap["KontAbsp"]!["controller"]!, localization: AppLocalizations.of(context)!.kontabsp, dbName: "KontAbsp", required: false, dbDesignation: DatabasesEnum.place, ), // -------------------- VarTextField( textController: rmap["SonstBem"]!["controller"]!, localization: AppLocalizations.of(context)!.sonstbemerkungen, dbName: "SonstBem", dbDesignation: DatabasesEnum.place, required: false), ], )), // Fourth step Step( title: Text(AppLocalizations.of(context)!.fourthstep), content: Column( children: [ VarTextField( textController: rmap["Adresse1"]!["controller"]!, localization: AppLocalizations.of(context)!.adresse1, dbName: "Adresse1", dbDesignation: DatabasesEnum.place, required: true, defaultValue: "addresse1", ), // -------------------- VarTextField( textController: rmap["Adresse2"]!["controller"]!, localization: AppLocalizations.of(context)!.adresse2, dbName: "Adresse2", required: false, dbDesignation: DatabasesEnum.place, ), // -------------------- VarTextField( textController: rmap["Adresse3"]!["controller"]!, localization: AppLocalizations.of(context)!.adresse3, dbName: "Adresse3", required: false, dbDesignation: DatabasesEnum.place, ), const SizedBox( height: 15, ), // -------------------- VarTextField( textController: rmap["FKontakt1"]!["controller"]!, localization: AppLocalizations.of(context)!.fkontakt1, dbName: "FKontakt1", required: false, dbDesignation: DatabasesEnum.place, ), // -------------------- VarTextField( textController: rmap["FKontakt2"]!["controller"]!, localization: AppLocalizations.of(context)!.fkontakt2, dbName: "FKontakt2", required: false, dbDesignation: DatabasesEnum.place, ), // -------------------- VarTextField( textController: rmap["FKontakt3"]!["controller"]!, localization: AppLocalizations.of(context)!.fkontakt3, dbName: "FKontakt3", required: false, dbDesignation: DatabasesEnum.place, ), // -------------------- VarTextField( textController: rmap["IntKomm"]!["controller"]!, localization: AppLocalizations.of(context)!.intkomm, dbName: "IntKomm", required: false, dbDesignation: DatabasesEnum.place, ), ], )) ]; // Here the site is built with the steps from above return Scaffold( appBar: AppBar(title: Text(AppLocalizations.of(context)!.addplace)), body: PageTransitionSwitcher( duration: const Duration(milliseconds: 800), transitionBuilder: (Widget child, Animation animation, Animation secondaryAnimation) { return SharedAxisTransition( animation: animation, secondaryAnimation: secondaryAnimation, transitionType: SharedAxisTransitionType.vertical, child: child, ); }, child: Stepper( key: ValueKey(currentStep), type: StepperType.vertical, steps: getSteps(), // Functions that handle the navigation through the steps currentStep: currentStep, onStepTapped: (value) { setState(() { currentStep = value; }); }, onStepContinue: () async { final isLastStep = currentStep == getSteps().length - 1; if (!isLastStep) { saveTemplate(getFieldsText(), DatabasesEnum.place, widget.isTemplate); setState(() { currentStep += 1; }); } else { // ! always filled out if (widget.isSent) { Navigator.pushNamedAndRemoveUntil( context, '/home', (route) => false); return; } bool empty = CheckRequired.checkRequired(rmap); if (empty == true) { DialogHelper.showTemplateDialog( context, getFieldsText()); return; } else if (empty == false) { await DialogHelper.showSaveOptionsDialog( context, getFieldsText(), widget.isTemplate); } } }, onStepCancel: () { if (currentStep == 0) { Navigator.pop(context); } else { setState(() { currentStep -= 1; }); } }, ), ), ); } }