Files
fforte/lib/screens/addCam/add_cam_main.dart
2025-05-07 23:59:30 +02:00

775 lines
31 KiB
Dart

import 'package:fforte/enums/databases.dart';
import 'package:fforte/screens/addCam/cam_widgets.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/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<String, TextEditingController>? existingData;
const AddCamMain(
{super.key,
this.isTemplate = false,
this.existingData,
this.isFinished = false,
this.isSent = false});
@override
State<AddCamMain> createState() => _AddCamMainState();
}
class _AddCamMainState extends State<AddCamMain> {
// 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();
Map<String, TextEditingController> getFieldsController() {
Map<String, TextEditingController> rmap = {
// Step 1
"Status": TextEditingController(),
"Betreuung": TextEditingController(),
"Standort": TextEditingController(),
"CID": TextEditingController(),
"FFTyp": TextEditingController(),
"Mez": TextEditingController(),
"KSchloNr": TextEditingController(),
"Rudel": TextEditingController(),
// Step 2
"OrtInfo": TextEditingController(),
"BeiOrt": TextEditingController(),
"Bland": TextEditingController(),
"Lkr": TextEditingController(),
"Platzung": TextEditingController(),
// Step 3
"DECLNG": TextEditingController(),
"DECLAT": TextEditingController(),
"Datum": TextEditingController(),
"KontDat": TextEditingController(),
"KTage1": TextEditingController(),
"KTage2": TextEditingController(),
"AbbauDat": TextEditingController(),
"Auftrag": TextEditingController(),
"KontAbsp": TextEditingController(),
"SonstBem": TextEditingController(),
// Step 4
"Adresse1": TextEditingController(),
"Adresse2": TextEditingController(),
"Adresse3": TextEditingController(),
"FKontakt1": TextEditingController(),
"FKontakt2": TextEditingController(),
"FKontakt3": TextEditingController(),
"IntKomm": TextEditingController(),
// Gone?
"ProtoAm": TextEditingController(),
"FotoFilm": TextEditingController(),
};
return rmap;
}
Map<String, String> getFieldsText() {
Map<String, String> rmap = {};
for (var itemKey in getFieldsController().keys) {
rmap[itemKey] = getFieldsController()["key"]!.text;
}
return rmap;
}
// Map<String, dynamic> getPlace() {
// Map<String, dynamic> 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;
// }
bool empty = false;
@override
void initState() {
super.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);
}
// 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'] ?? "";
// }
}
// checks if required fields are not empty. If one is the name will be returned
// TODO rewrite
// List<String> validateData() {
// List<String> emptyFields = <String>[];
//
// Map<String, TextEditingController> 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<Step> getSteps() => [
// First step
Step(
title: Text(AppLocalizations.of(context)!.firststep),
content: Column(
children: [
Align(
alignment: Alignment.bottomLeft,
child: VarTextField(
required: true,
dbName: "Standort",
textController: getFieldsController()["Standort"]!,
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(() {
getFieldsController()["Status"]!.text = status;
});
},
),
// --------------------
VarTextField(
textController: getFieldsController()["Betreuung"]!,
localization: AppLocalizations.of(context)!.betreuung,
dbName: "Betreuung",
required: false,
dbDesignation: DatabasesEnum.place,
),
const SizedBox(
height: 20,
),
// --------------------
VarTextField(
textController: getFieldsController()["CID"]!,
localization: AppLocalizations.of(context)!.camLink,
dbName: "CID",
required: true,
dbDesignation: DatabasesEnum.place,
),
// --------------------
VarTextField(
textController: getFieldsController()["FFTyp"]!,
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;
getFieldsController()["Mez"]!.text = mez;
});
},
),
const SizedBox(
height: 15,
),
// --------------------
VarTextField(
textController: getFieldsController()["KSchloNr"]!,
localization: AppLocalizations.of(context)!.kschlonr,
dbName: "KSchloNr",
required: false,
dbDesignation: DatabasesEnum.place,
),
const SizedBox(
height: 5,
),
// --------------------
VarTextField(
textController: getFieldsController()["Rudel"]!,
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<LatLng>(
MaterialPageRoute(builder: (context) {
return Karte(
ortInfoC: getFieldsController()["OrtInfo"]!,
beiOrtC: getFieldsController()["BeiOrt"]!,
currentPosition: currentPosition,
onPositionChange: (updatedPosition) {
setState(() {
currentPosition = updatedPosition;
getFieldsController()["DECLNG"]!.text =
updatedPosition.longitude.toString();
getFieldsController()["DECLAT"]!.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: getFieldsController()["Bland"]!,
localization: AppLocalizations.of(context)!.bland,
dbName: "BLand",
required: true,
dbDesignation: DatabasesEnum.place,
defaultValue: "bLand",
),
// --------------------
VarTextField(
textController: getFieldsController()["Lkr"]!,
localization: AppLocalizations.of(context)!.lkr,
dbName: "Lkr",
required: true,
dbDesignation: DatabasesEnum.place,
),
// --------------------
VarTextField(
textController: getFieldsController()["BeiOrt"]!,
localization: AppLocalizations.of(context)!.beiort,
dbName: "BeiOrt",
required: true,
dbDesignation: DatabasesEnum.place,
),
// --------------------
VarTextField(
textController: getFieldsController()["OrtInfo"]!,
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;
getFieldsController()["Platzung"]!.text = platzung;
});
},
),
],
)),
// Third step
Step(
title: Text(AppLocalizations.of(context)!.thirdstep),
content: Column(
children: [
Datum(
initDatum: datum,
onDateChanged: (value) {
datum = value;
getFieldsController()["Datum"]!.text =
value.toString().split(" ").first;
},
name: AppLocalizations.of(context)!.pickDate,
),
// --------------------
KontDat(
initKontDat: kontDat,
onDateChanged: (value) {
setState(() {
kontDat = value;
getFieldsController()["KontDat"]!.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: getFieldsController()["KTage1"]!,
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: getFieldsController()["KTage2"]!,
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;
getFieldsController()["AbbauDat"]!.text =
value.toString().split(" ").first;
},
),
],
),
const SizedBox(
height: 20,
),
// --------------------
VarTextField(
textController: getFieldsController()["Auftrag"]!,
localization: AppLocalizations.of(context)!.auftrag,
dbName: "Auftrag",
required: false,
dbDesignation: DatabasesEnum.place,
),
// --------------------
VarTextField(
textController: getFieldsController()["KontAbsp"]!,
localization: AppLocalizations.of(context)!.kontabsp,
dbName: "KontAbsp",
required: false,
dbDesignation: DatabasesEnum.place,
),
// --------------------
VarTextField(
textController: getFieldsController()["SonstBem"]!,
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: getFieldsController()["Adresse1"]!,
localization: AppLocalizations.of(context)!.adresse1,
dbName: "Adresse1",
dbDesignation: DatabasesEnum.place,
required: true,
defaultValue: "addresse1",
),
// --------------------
VarTextField(
textController: getFieldsController()["Adresse2"]!,
localization: AppLocalizations.of(context)!.adresse2,
dbName: "Adresse2",
required: false,
dbDesignation: DatabasesEnum.place,
),
// --------------------
VarTextField(
textController: getFieldsController()["Adresse3"]!,
localization: AppLocalizations.of(context)!.adresse3,
dbName: "Adresse3",
required: false,
dbDesignation: DatabasesEnum.place,
),
const SizedBox(
height: 15,
),
// --------------------
VarTextField(
textController: getFieldsController()["FKontakt1"]!,
localization: AppLocalizations.of(context)!.fkontakt1,
dbName: "FKontakt1",
required: false,
dbDesignation: DatabasesEnum.place,
),
// --------------------
VarTextField(
textController: getFieldsController()["FKontakt2"]!,
localization: AppLocalizations.of(context)!.fkontakt2,
dbName: "FKontakt2",
required: false,
dbDesignation: DatabasesEnum.place,
),
// --------------------
VarTextField(
textController: getFieldsController()["FKontakt3"]!,
localization: AppLocalizations.of(context)!.fkontakt3,
dbName: "FKontakt3",
required: false,
dbDesignation: DatabasesEnum.place,
),
// --------------------
VarTextField(
textController: getFieldsController()["IntKomm"]!,
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<double> animation,
Animation<double> secondaryAnimation) {
return SharedAxisTransition(
animation: animation,
secondaryAnimation: secondaryAnimation,
transitionType: SharedAxisTransitionType.vertical,
child: child,
);
},
child: Stepper(
key: ValueKey<int>(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 {
// TODO implement validateData again
// List<String> emptyFields = validateData();
// ! always filled out
// empty = false;
// if (widget.isSent) {
// Navigator.pushNamedAndRemoveUntil(
// context, '/home', (route) => false);
// } else if (empty == true) {
// DialogHelper.showTemplateDialog(
// context, emptyFields, getFieldsText();
// return;
// } else if (empty == false) {
// await DialogHelper.showSaveOptionsDialog(
// context, getFieldsText(), widget.isTemplate);
// }
}
},
onStepCancel: () {
if (currentStep == 0) {
Navigator.pop(context);
} else {
setState(() {
currentStep -= 1;
});
}
},
),
),
);
}
}