// ignore_for_file: non_constant_identifier_names import 'package:fforte/other/db_helper.dart'; import 'package:flutter/material.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_map/flutter_map.dart'; import 'package:geolocator/geolocator.dart'; import 'package:intl/intl.dart'; import 'package:latlong2/latlong.dart'; import 'package:shared_preferences/shared_preferences.dart'; import 'package:geocoding/geocoding.dart'; // * Collection of All widgets displayed in the add_cam section class VarTextField extends StatefulWidget { final TextEditingController textController; final String localization; final String dbName; final String? default_value; final bool required; const VarTextField( {super.key, required this.textController, required this.localization, required this.dbName, required this.required, this.default_value}); @override State createState() => _VarTextFieldState(); } class _VarTextFieldState extends State { late Future>> dbVar; @override void initState() { super.initState(); if (widget.textController.text == "" && widget.default_value != null) { _loadPref(); } dbVar = _loadData(); } Future>> _loadData() async { var places = await DBHelper().getPlace(); var templates = await DBHelper().getTemplates(); return [...places, ...templates]; } void _loadPref() { Future.delayed(Duration.zero, () async { SharedPreferences prefs = await SharedPreferences.getInstance(); String bLand = prefs.getString(widget.default_value!) ?? ""; setState(() { widget.textController.text = bLand; }); }); } @override Widget build(BuildContext context) { return Row( children: [ Expanded( flex: 5, child: TextField( controller: widget.textController, keyboardType: TextInputType.multiline, maxLines: null, onChanged: (value) { setState(() { widget.textController.text = value; }); }, decoration: InputDecoration( hintText: widget.localization, enabledBorder: widget.required ? (widget.textController.text.isEmpty ? const UnderlineInputBorder( borderSide: BorderSide(color: Colors.red)) : const UnderlineInputBorder( borderSide: BorderSide(color: Colors.green))) : const UnderlineInputBorder( borderSide: BorderSide(color: Colors.grey)), focusedBorder: widget.required ? (widget.textController.text.isEmpty ? const UnderlineInputBorder( borderSide: BorderSide(color: Colors.red)) : const UnderlineInputBorder( borderSide: BorderSide(color: Colors.green))) : const UnderlineInputBorder( borderSide: BorderSide(color: Colors.grey))), )), const SizedBox( width: 15, ), Expanded( flex: 1, child: Align( alignment: Alignment.bottomLeft, child: FutureBuilder>>( future: dbVar, builder: (BuildContext context, AsyncSnapshot>> snapshot) { if (snapshot.hasData) { // Filtern der Daten, um sicherzustellen, dass keine 'null' Werte für den Schlüssel dbName vorhanden sind var filteredData = snapshot.data! .where((item) => item[widget.dbName] != null && item[widget.dbName] != "") .toList(); return PopupMenuButton( onSelected: (String value) { setState(() { widget.textController.text = value; }); }, itemBuilder: (BuildContext context) { return filteredData .map((item) => PopupMenuItem( value: item[widget.dbName].toString(), child: Text(item[widget.dbName].toString()), )) .toList(); }, child: const Icon(Icons.arrow_drop_down), ); } else if (snapshot.hasError) { return Text('Fehler: ${snapshot.error}'); } else { return const CircularProgressIndicator(); } }, ), ), ) ], ); } } // Karte // ! completely new page class Karte extends StatefulWidget { final TextEditingController beiOrtC; final Position currentPosition; final Function(Position) onPositionChange; const Karte( {super.key, required this.currentPosition, required this.onPositionChange, required this.beiOrtC}); @override KarteState createState() => KarteState(); } class KarteState extends State { List markers = [ ]; LatLng? selectedPosition; Position? updatedPosition; bool saveVisible = false; @override void initState() { super.initState(); markers = [ Marker( point: LatLng(widget.currentPosition.latitude, widget.currentPosition.longitude), child: const Icon( Icons.location_on, color: Colors.red, )) ]; } @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( title: Text(AppLocalizations.of(context)!.map), actions: [ Visibility( visible: saveVisible, child: Row( children: [ Text(AppLocalizations.of(context)!.saveMap), TextButton( onPressed: () async { List placemarks = await placemarkFromCoordinates( selectedPosition!.latitude, selectedPosition!.longitude); if (selectedPosition != null) { setState(() { widget.beiOrtC.text = placemarks.first.locality!; updatedPosition = Position( longitude: selectedPosition!.longitude, latitude: selectedPosition!.latitude, timestamp: DateTime.now(), accuracy: 0.0, altitude: 0.0, altitudeAccuracy: 0.0, heading: 0.0, headingAccuracy: 0.0, speed: 0.0, speedAccuracy: 0.0); widget.onPositionChange(updatedPosition!); }); } // ignore: use_build_context_synchronously Navigator.pop(context); }, child: const Icon(Icons.save), ), ], ), ), ], ), body: FlutterMap( mapController: MapController(), options: MapOptions( interactionOptions: const InteractionOptions( flags: InteractiveFlag.pinchZoom | InteractiveFlag.drag | InteractiveFlag.pinchMove), initialCenter: LatLng(widget.currentPosition.latitude, widget.currentPosition.longitude), initialZoom: 16.0, onTap: _handleTap, ), children: [ TileLayer( urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png', userAgentPackageName: 'com.example.app', ), MarkerLayer(markers: markers), ]), ); } _handleTap(TapPosition position, LatLng latlng) { setState(() { markers.clear(); markers.add( Marker( width: 80.0, height: 80.0, point: latlng, child: const Icon( Icons.location_on, color: Colors.red, ), ), ); selectedPosition = latlng; saveVisible = true; }); ScaffoldMessenger.of(context).showSnackBar(SnackBar( content: Text( "${AppLocalizations.of(context)!.markerSet}\n${selectedPosition!.latitude}\n${selectedPosition!.longitude}"))); } } // // // // // // // // // // // // // // // // Datum == Datum der Aufstellung // datum is the variable where the chosen date is stored class Datum extends StatefulWidget { final DateTime? datum; const Datum({super.key, required this.datum}); @override State createState() => _DatumState(); } class _DatumState extends State { DateTime? datum = DateTime.now(); @override Widget build(BuildContext context) { return Row( children: [ Row(children: [ SizedBox( width: 125, child: ElevatedButton( onPressed: () async { final date = await pickDate(); if (date == null) return; setState(() => datum = date); }, child: Text(AppLocalizations.of(context)!.pickDate)), ), const SizedBox( width: 10, ), Text( '${datum?.day}. ${datum?.month}. ${datum?.year}', ), ]), ], ); } Future pickDate() async { final date = await showDatePicker( context: context, initialDate: datum!, firstDate: DateTime(2000), lastDate: DateTime(5000)); if (date == null) return null; setState(() => datum = date); var place = {'Datum': DateFormat('yyyy-MM-dd').format(datum!)}; await DBHelper().addPlace(place); return datum; } } // Status class Status extends StatefulWidget { final Function(String) onStatusChanged; final String initialStatus; const Status( {super.key, required this.onStatusChanged, this.initialStatus = 'Aktiv'}); @override State createState() => _StatusState(); } class _StatusState extends State { String? _selectedStatus; @override void initState() { super.initState(); _selectedStatus = widget.initialStatus; } @override Widget build(BuildContext context) { return Column( children: [ ListTile( visualDensity: const VisualDensity(vertical: -4), title: Text(AppLocalizations.of(context)!.aktiv), leading: Radio( value: 'aktiv', groupValue: _selectedStatus, onChanged: (value) { setState(() { _selectedStatus = value; widget.onStatusChanged(value!); }); }, ), ), ListTile( visualDensity: const VisualDensity(vertical: -4), title: Text(AppLocalizations.of(context)!.inaktiv), leading: Radio( value: 'inaktiv', groupValue: _selectedStatus, onChanged: (value) { setState(() { _selectedStatus = value; widget.onStatusChanged(value!); }); }, ), ), ], ); } } // STTyp class STTyp extends StatefulWidget { final Function(String) onSTTypChanged; final String initialSTTyp; const STTyp( {super.key, required this.onSTTypChanged, this.initialSTTyp = 'opportunistisch'}); @override State createState() => _STTypState(); } class _STTypState extends State { String? _selectedSTTyp; @override void initState() { super.initState(); _selectedSTTyp = widget.initialSTTyp; } @override Widget build(BuildContext context) { return Column( children: [ ListTile( visualDensity: const VisualDensity(vertical: -4), title: Text(AppLocalizations.of(context)!.opportunistisch), leading: Radio( value: 'opportunistisch', groupValue: _selectedSTTyp, onChanged: (value) { setState(() { _selectedSTTyp = value; widget.onSTTypChanged(value!); }); }, ), ), ListTile( visualDensity: const VisualDensity(vertical: -4), title: Text(AppLocalizations.of(context)!.systematisch), leading: Radio( value: 'systematisch', groupValue: _selectedSTTyp, onChanged: (value) { setState(() { _selectedSTTyp = value; widget.onSTTypChanged(value!); }); }, ), ), ], ); } } // platzung class Platzung extends StatefulWidget { final Function(String) onPlatzungChanged; final String initialPlatzung; const Platzung( {super.key, required this.onPlatzungChanged, this.initialPlatzung = 'kirrung'}); @override State createState() => _PlatzungState(); } class _PlatzungState extends State { String? _selectedPlatzung; @override void initState() { super.initState(); _selectedPlatzung = widget.initialPlatzung; } @override Widget build(BuildContext context) { return Column( children: [ ListTile( visualDensity: const VisualDensity(vertical: -4), title: Text(AppLocalizations.of(context)!.kirrung), leading: Radio( value: 'Kirrung', groupValue: _selectedPlatzung, onChanged: (value) { setState(() { _selectedPlatzung = value; widget.onPlatzungChanged(value!); }); }, ), ), ListTile( visualDensity: const VisualDensity(vertical: -4), title: Text(AppLocalizations.of(context)!.wasserstelle), leading: Radio( value: 'Wasserstelle', groupValue: _selectedPlatzung, onChanged: (value) { setState(() { _selectedPlatzung = value; widget.onPlatzungChanged(value!); }); }, ), ), ListTile( visualDensity: const VisualDensity(vertical: -4), title: Text(AppLocalizations.of(context)!.wald), leading: Radio( value: 'Wald', groupValue: _selectedPlatzung, onChanged: (value) { setState(() { _selectedPlatzung = value; widget.onPlatzungChanged(value!); }); }, ), ), ListTile( visualDensity: const VisualDensity(vertical: -4), title: Text(AppLocalizations.of(context)!.wildwechsel), leading: Radio( value: 'Wildwechsel', groupValue: _selectedPlatzung, onChanged: (value) { setState(() { _selectedPlatzung = value; widget.onPlatzungChanged(value!); }); }, ), ), ListTile( visualDensity: const VisualDensity(vertical: -4), title: Text(AppLocalizations.of(context)!.wegstrasse), leading: Radio( value: 'Weg/Straße', groupValue: _selectedPlatzung, onChanged: (value) { setState(() { _selectedPlatzung = value; widget.onPlatzungChanged(value!); }); }, ), ), ListTile( visualDensity: const VisualDensity(vertical: -4), title: Text(AppLocalizations.of(context)!.hofgarten), leading: Radio( value: 'Hof/Garten', groupValue: _selectedPlatzung, onChanged: (value) { setState(() { _selectedPlatzung = value; widget.onPlatzungChanged(value!); }); }, ), ), ListTile( visualDensity: const VisualDensity(vertical: -4), title: Text(AppLocalizations.of(context)!.wiesefeld), leading: Radio( value: 'Wiese/Feld/Offenfläche', groupValue: _selectedPlatzung, onChanged: (value) { setState(() { _selectedPlatzung = value; widget.onPlatzungChanged(value!); }); }, ), ), ], ); } } // FotoFilm class FotoFilm extends StatefulWidget { final Function(String) onFotoFilmChanged; final String initialFotoFilm; const FotoFilm( {super.key, required this.onFotoFilmChanged, this.initialFotoFilm = 'foto'}); @override State createState() => _FotoFilmState(); } class _FotoFilmState extends State { String? _selectedFotoFilm; @override void initState() { super.initState(); _selectedFotoFilm = widget.initialFotoFilm; } @override Widget build(BuildContext context) { return Column( children: [ ListTile( visualDensity: const VisualDensity(vertical: -4), title: Text(AppLocalizations.of(context)!.foto), leading: Radio( value: 'Foto', groupValue: _selectedFotoFilm, onChanged: (value) { setState(() { _selectedFotoFilm = value; widget.onFotoFilmChanged(value!); }); }, ), ), ListTile( visualDensity: const VisualDensity(vertical: -4), title: Text(AppLocalizations.of(context)!.film), leading: Radio( value: 'Film', groupValue: _selectedFotoFilm, onChanged: (value) { setState(() { _selectedFotoFilm = value; widget.onFotoFilmChanged(value!); }); }, ), ), ], ); } } // MEZ class MEZ extends StatefulWidget { final Function(String) onMEZChanged; final String initialMEZ; const MEZ( {super.key, required this.onMEZChanged, this.initialMEZ = 'sommerzeit'}); @override State createState() => _MEZState(); } class _MEZState extends State { String? _selectedMEZ; @override void initState() { super.initState(); _selectedMEZ = widget.initialMEZ; } @override Widget build(BuildContext context) { return Column( children: [ ListTile( visualDensity: const VisualDensity(vertical: -4), title: Text(AppLocalizations.of(context)!.sommerzeit), leading: Radio( value: 'Sommerzeit', groupValue: _selectedMEZ, onChanged: (value) { setState(() { _selectedMEZ = value; widget.onMEZChanged(value!); }); }, ), ), ListTile( visualDensity: const VisualDensity(vertical: -4), title: Text(AppLocalizations.of(context)!.winterzeit), leading: Radio( value: 'Winterzeit', groupValue: _selectedMEZ, onChanged: (value) { setState(() { _selectedMEZ = value; widget.onMEZChanged(value!); }); }, ), ), ], ); } } // Bearsafe class Bearsafe extends StatefulWidget { final Function(String) onBearsafeChanged; final String initialBearsafe; const Bearsafe( {super.key, required this.onBearsafeChanged, this.initialBearsafe = 'Nein'}); @override State createState() => _BearsafeState(); } class _BearsafeState extends State { String? _selectedBearsafe; @override void initState() { super.initState(); _selectedBearsafe = widget.initialBearsafe; } @override Widget build(BuildContext context) { return Column( children: [ ListTile( visualDensity: const VisualDensity(vertical: -4), title: Text(AppLocalizations.of(context)!.nein), leading: Radio( value: 'Nein', groupValue: _selectedBearsafe, onChanged: (value) { setState(() { _selectedBearsafe = value; widget.onBearsafeChanged(value!); }); }, ), ), ListTile( visualDensity: const VisualDensity(vertical: -4), title: Text(AppLocalizations.of(context)!.ja), leading: Radio( value: 'Ja', groupValue: _selectedBearsafe, onChanged: (value) { setState(() { _selectedBearsafe = value; widget.onBearsafeChanged(value!); }); }, ), ), ], ); } } // KontDat class KontDat extends StatefulWidget { final DateTime? kontDat; const KontDat({super.key, required this.kontDat}); @override State createState() => _KontDatState(); } class _KontDatState extends State { DateTime? kontDat = DateTime.now(); @override Widget build(BuildContext context) { return Row( children: [ Row(children: [ SizedBox( width: 125, child: ElevatedButton( onPressed: () async { final date = await pickDate(); if (date == null) return; setState(() => kontDat = date); }, child: Text(AppLocalizations.of(context)!.pickkontdat)), ), const SizedBox( width: 10, ), Text( '${kontDat?.day}. ${kontDat?.month}. ${kontDat?.year}', ), ]), ], ); } Future pickDate() async { final date = await showDatePicker( context: context, initialDate: kontDat!, firstDate: DateTime(2000), lastDate: DateTime(5000)); if (date == null) return null; setState(() => kontDat = date); var place = {'KontDat': DateFormat('yyyy-MM-dd').format(kontDat!)}; await DBHelper().addPlace(place); return kontDat; } } // AbbauDat class AbbauDat extends StatefulWidget { final DateTime? abbauDat; const AbbauDat({super.key, required this.abbauDat}); @override State createState() => _AbbauDatState(); } class _AbbauDatState extends State { DateTime? abbauDat; @override Widget build(BuildContext context) { return Row( children: [ Row(children: [ SizedBox( width: 125, child: ElevatedButton( onPressed: () async { final date = await pickDate(); if (date == null) return; setState(() => abbauDat = date); }, child: Text(AppLocalizations.of(context)!.pickabbaudat)), ), const SizedBox( width: 10, ), Builder(builder: (context) { if (abbauDat != null) { return Text( '${abbauDat?.day}. ${abbauDat?.month}. ${abbauDat?.year}'); } else { return Text(AppLocalizations.of(context)!.nichts); } }), const SizedBox( width: 10, ), ElevatedButton( onPressed: () { setState(() { abbauDat = null; }); }, child: const Text("X")) ]), ], ); } Future pickDate() async { final date = await showDatePicker( context: context, initialDate: DateTime.now(), firstDate: DateTime(2000), lastDate: DateTime(5000)); if (date == null) return null; setState(() => abbauDat = date); return abbauDat; } }