let AI comment everything because well... yeah...
This commit is contained in:
@@ -22,9 +22,14 @@ import 'widgets/mez.dart';
|
||||
import 'widgets/platzung.dart';
|
||||
import 'widgets/status.dart';
|
||||
|
||||
/// Widget for adding or editing camera trap locations
|
||||
/// Supports template creation, editing existing entries, and new entries
|
||||
class AddCamMain extends StatefulWidget {
|
||||
/// Whether this form is being used to create a template
|
||||
final bool isTemplate;
|
||||
/// Whether the entry has been sent to the server
|
||||
final bool isSent;
|
||||
/// Existing data to populate the form with (for editing)
|
||||
final Map<String, dynamic>? existingData;
|
||||
|
||||
const AddCamMain({
|
||||
@@ -38,14 +43,17 @@ class AddCamMain extends StatefulWidget {
|
||||
State<AddCamMain> createState() => _AddCamMainState();
|
||||
}
|
||||
|
||||
/// State class for the camera trap location form
|
||||
class _AddCamMainState extends State<AddCamMain> {
|
||||
// var declaration
|
||||
/// Current step in the multi-step form
|
||||
int currentStep = 0;
|
||||
/// Whether this form is being used as a template
|
||||
late bool isTemplate;
|
||||
|
||||
/// Current GPS position, initialized with default values for Germany
|
||||
Position currentPosition = Position(
|
||||
longitude: 10.0,
|
||||
latitude: 51.0,
|
||||
longitude: 10.0, // Default longitude (roughly center of Germany)
|
||||
latitude: 51.0, // Default latitude (roughly center of Germany)
|
||||
timestamp: DateTime.now(),
|
||||
accuracy: 0.0,
|
||||
altitude: 0.0,
|
||||
@@ -56,6 +64,12 @@ class _AddCamMainState extends State<AddCamMain> {
|
||||
headingAccuracy: 0.0,
|
||||
);
|
||||
|
||||
/// Map containing all form fields with their controllers and required status
|
||||
/// Organized by steps:
|
||||
/// - Step 1: Basic information (ID, Status, etc.)
|
||||
/// - Step 2: Location information
|
||||
/// - Step 3: Dates and control periods
|
||||
/// - Step 4: Contact information
|
||||
Map<String, Map<String, dynamic>> rmap = {
|
||||
"ID": {"controller": TextEditingController(), "required": false},
|
||||
// Step 1
|
||||
@@ -102,6 +116,8 @@ class _AddCamMainState extends State<AddCamMain> {
|
||||
"Sent": {"controller": TextEditingController(), "required": false},
|
||||
};
|
||||
|
||||
/// Retrieves all field values as a map
|
||||
/// @return Map of field names to their current values
|
||||
Map<String, String> getFieldsText() {
|
||||
Map<String, String> puff = {};
|
||||
|
||||
@@ -112,8 +128,12 @@ class _AddCamMainState extends State<AddCamMain> {
|
||||
return puff;
|
||||
}
|
||||
|
||||
/// Flag indicating whether position is currently being loaded
|
||||
bool isLoadingPosition = false;
|
||||
|
||||
/// Initializes the GPS position
|
||||
/// Handles location permissions and device settings
|
||||
/// @return Future<Position> The determined position
|
||||
Future<Position> _initializePosition() async {
|
||||
try {
|
||||
final position = await GeolocatorService.deteterminePosition();
|
||||
|
||||
@@ -1,25 +0,0 @@
|
||||
|
||||
|
||||
// Karte
|
||||
// ! completely new page
|
||||
|
||||
|
||||
// Status
|
||||
|
||||
|
||||
// STTyp
|
||||
|
||||
|
||||
// platzung
|
||||
|
||||
|
||||
// FotoFilm
|
||||
|
||||
|
||||
// MEZ
|
||||
|
||||
|
||||
// KontDat
|
||||
|
||||
|
||||
// AbbauDat
|
||||
@@ -1,19 +1,34 @@
|
||||
// * Service for handling GPS location functionality
|
||||
// * Provides methods for:
|
||||
// * - Location permission handling
|
||||
// * - GPS service status checks
|
||||
// * - Position determination
|
||||
// * - Always-on location checks
|
||||
|
||||
import 'package:fforte/screens/addCam/exceptions/location_disabled_exception.dart';
|
||||
import 'package:fforte/screens/addCam/exceptions/location_forbidden_exception.dart';
|
||||
import 'package:fforte/screens/excursion/exceptions/need_always_location_exception.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
|
||||
/// Service class for handling all GPS location related functionality
|
||||
class GeolocatorService {
|
||||
// determine live position with checks for denied permission and turned off location service
|
||||
/// Determine the current device position with permission checks
|
||||
/// @param alwaysOnNeeded Whether the app needs always-on location permission
|
||||
/// @throws LocationDisabledException if location services are disabled
|
||||
/// @throws LocationForbiddenException if location permission is denied
|
||||
/// @throws NeedAlwaysLocation if always-on permission is needed but not granted
|
||||
/// @return Future<Position> The current GPS position
|
||||
static Future<Position> deteterminePosition({bool alwaysOnNeeded = false}) async {
|
||||
bool locationEnabled;
|
||||
LocationPermission permissionGiven;
|
||||
|
||||
// Check if location services are enabled
|
||||
locationEnabled = await Geolocator.isLocationServiceEnabled();
|
||||
if (!locationEnabled) {
|
||||
throw LocationDisabledException();
|
||||
}
|
||||
|
||||
// Check and request location permissions if needed
|
||||
permissionGiven = await Geolocator.checkPermission();
|
||||
if (permissionGiven == LocationPermission.denied) {
|
||||
permissionGiven = await Geolocator.requestPermission();
|
||||
@@ -22,13 +37,16 @@ class GeolocatorService {
|
||||
}
|
||||
}
|
||||
|
||||
// Check for always-on permission if required
|
||||
if (alwaysOnNeeded && permissionGiven != LocationPermission.always) {
|
||||
throw NeedAlwaysLocation();
|
||||
}
|
||||
|
||||
return await Geolocator.getCurrentPosition();
|
||||
return await Geolocator.getCurrentPosition();
|
||||
}
|
||||
|
||||
/// Check if always-on location permission is enabled
|
||||
/// @return Future<bool> True if always-on permission is granted or location is disabled
|
||||
static Future<bool> alwaysPositionEnabled() async {
|
||||
LocationPermission permissionGiven = await Geolocator.checkPermission();
|
||||
bool locationEnabled = await Geolocator.isLocationServiceEnabled();
|
||||
|
||||
@@ -1,8 +1,18 @@
|
||||
// * Widget for managing camera trap dismantling dates
|
||||
// * Features:
|
||||
// * - Date picker for selecting dismantling date
|
||||
// * - Date display and reset functionality
|
||||
// * - Localized text support
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fforte/l10n/app_localizations.dart';
|
||||
|
||||
/// Widget for selecting and displaying camera trap dismantling dates
|
||||
/// Allows users to pick a date or clear the selection
|
||||
class AbbauDat extends StatefulWidget {
|
||||
/// Initial dismantling date, can be null if not set
|
||||
final DateTime? initAbbauDat;
|
||||
/// Callback function when date is changed
|
||||
final Function(DateTime) onDateChanged;
|
||||
|
||||
const AbbauDat({super.key, required this.initAbbauDat, required this.onDateChanged});
|
||||
@@ -11,7 +21,9 @@ class AbbauDat extends StatefulWidget {
|
||||
State<AbbauDat> createState() => _AbbauDatState();
|
||||
}
|
||||
|
||||
/// State class for the dismantling date widget
|
||||
class _AbbauDatState extends State<AbbauDat> {
|
||||
/// Currently selected dismantling date
|
||||
DateTime? abbauDat;
|
||||
|
||||
@override
|
||||
@@ -25,6 +37,7 @@ class _AbbauDatState extends State<AbbauDat> {
|
||||
return Row(
|
||||
children: [
|
||||
Column(children: [
|
||||
// Date picker button
|
||||
SizedBox(
|
||||
width: 140,
|
||||
child: ElevatedButton(
|
||||
@@ -38,34 +51,34 @@ class _AbbauDatState extends State<AbbauDat> {
|
||||
),
|
||||
Row(
|
||||
children: [
|
||||
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"))
|
||||
]),
|
||||
],
|
||||
)
|
||||
const SizedBox(width: 10),
|
||||
// Display selected date or "nothing" text
|
||||
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),
|
||||
// Clear date button
|
||||
ElevatedButton(
|
||||
onPressed: () {
|
||||
setState(() {
|
||||
abbauDat = null;
|
||||
});
|
||||
},
|
||||
child: const Text("X"))
|
||||
]),
|
||||
],
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
/// Show date picker dialog and return selected date
|
||||
/// @return Future<DateTime?> Selected date or null if cancelled
|
||||
Future<DateTime?> pickDate() async {
|
||||
final date = await showDatePicker(
|
||||
context: context,
|
||||
|
||||
@@ -1,8 +1,18 @@
|
||||
// * Widget for selecting camera trap media type
|
||||
// * Provides radio button selection between:
|
||||
// * - Photo mode
|
||||
// * - Film/Video mode
|
||||
// * Includes localization support
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fforte/l10n/app_localizations.dart';
|
||||
|
||||
/// Widget for selecting between photo and film/video mode
|
||||
/// Uses radio buttons for selection with localized labels
|
||||
class FotoFilm extends StatefulWidget {
|
||||
/// Callback function when media type selection changes
|
||||
final Function(String) onFotoFilmChanged;
|
||||
/// Initial media type selection ('foto' by default)
|
||||
final String initialFotoFilm;
|
||||
|
||||
const FotoFilm(
|
||||
@@ -14,7 +24,9 @@ class FotoFilm extends StatefulWidget {
|
||||
State<FotoFilm> createState() => _FotoFilmState();
|
||||
}
|
||||
|
||||
/// State class for the photo/film selection widget
|
||||
class _FotoFilmState extends State<FotoFilm> {
|
||||
/// Currently selected media type
|
||||
String? _selectedFotoFilm;
|
||||
|
||||
@override
|
||||
@@ -27,6 +39,7 @@ class _FotoFilmState extends State<FotoFilm> {
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
// Photo mode radio button
|
||||
ListTile(
|
||||
visualDensity: const VisualDensity(vertical: -4),
|
||||
title: Text(AppLocalizations.of(context)!.foto),
|
||||
@@ -41,6 +54,7 @@ class _FotoFilmState extends State<FotoFilm> {
|
||||
},
|
||||
),
|
||||
),
|
||||
// Film/Video mode radio button
|
||||
ListTile(
|
||||
visualDensity: const VisualDensity(vertical: -4),
|
||||
title: Text(AppLocalizations.of(context)!.film),
|
||||
|
||||
@@ -1,4 +1,10 @@
|
||||
// import 'package:fforte/screens/helper/snack_bar_helper.dart';
|
||||
// * Interactive map widget for camera trap location selection
|
||||
// * Features:
|
||||
// * - OpenStreetMap integration
|
||||
// * - Location marker placement
|
||||
// * - GPS coordinates display and saving
|
||||
// * - Localized interface
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_map/flutter_map.dart';
|
||||
import 'package:geolocator/geolocator.dart';
|
||||
@@ -6,11 +12,18 @@ import 'package:latlong2/latlong.dart';
|
||||
// import 'package:geocoding/geocoding.dart';
|
||||
import 'package:fforte/l10n/app_localizations.dart';
|
||||
|
||||
/// Widget for displaying and interacting with the map
|
||||
/// Allows users to select and save camera trap locations
|
||||
class Karte extends StatefulWidget {
|
||||
/// Controller for nearby location name
|
||||
final TextEditingController beiOrtC;
|
||||
/// Controller for location details
|
||||
final TextEditingController ortInfoC;
|
||||
/// Controller for longitude coordinate
|
||||
final TextEditingController decLngC;
|
||||
/// Controller for latitude coordinate
|
||||
final TextEditingController decLatC;
|
||||
/// Current GPS position
|
||||
final Position currentPosition;
|
||||
|
||||
const Karte(
|
||||
@@ -25,15 +38,20 @@ class Karte extends StatefulWidget {
|
||||
KarteState createState() => KarteState();
|
||||
}
|
||||
|
||||
/// State class for the map widget
|
||||
class KarteState extends State<Karte> {
|
||||
/// Current marker on the map
|
||||
Marker? currentMarker;
|
||||
/// Selected position coordinates
|
||||
LatLng? selectedPosition;
|
||||
/// Whether the save button should be visible
|
||||
bool saveVisible = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
// Initialize marker at current position
|
||||
currentMarker = Marker(
|
||||
point: LatLng(
|
||||
widget.currentPosition.latitude, widget.currentPosition.longitude),
|
||||
@@ -50,6 +68,7 @@ class KarteState extends State<Karte> {
|
||||
appBar: AppBar(
|
||||
title: Text(AppLocalizations.of(context)!.map),
|
||||
actions: [
|
||||
// Save location button
|
||||
Visibility(
|
||||
visible: saveVisible,
|
||||
child: Padding(
|
||||
@@ -76,6 +95,7 @@ class KarteState extends State<Karte> {
|
||||
),
|
||||
],
|
||||
),
|
||||
// Map display with OpenStreetMap tiles
|
||||
body: FlutterMap(
|
||||
mapController: MapController(),
|
||||
options: MapOptions(
|
||||
@@ -89,15 +109,21 @@ class KarteState extends State<Karte> {
|
||||
onTap: _handleTap,
|
||||
),
|
||||
children: [
|
||||
// OpenStreetMap tile layer
|
||||
TileLayer(
|
||||
urlTemplate: 'https://tile.openstreetmap.org/{z}/{x}/{y}.png',
|
||||
userAgentPackageName: 'de.lupus.apps',
|
||||
),
|
||||
// Marker layer
|
||||
MarkerLayer(markers: [currentMarker!]),
|
||||
]),
|
||||
);
|
||||
}
|
||||
|
||||
/// Handle tap events on the map
|
||||
/// Creates a new marker at the tapped location
|
||||
/// @param position The tap position on the screen
|
||||
/// @param latlng The geographical coordinates of the tap
|
||||
_handleTap(TapPosition position, LatLng latlng) {
|
||||
setState(() {
|
||||
currentMarker = Marker(
|
||||
@@ -111,7 +137,7 @@ class KarteState extends State<Karte> {
|
||||
);
|
||||
// selectedPosition = latlng;
|
||||
saveVisible = true;
|
||||
});
|
||||
});
|
||||
// ScaffoldMessenger.of(context).showSnackBar(SnackBar(
|
||||
// content: Text(
|
||||
// "${AppLocalizations.of(context)!.markerSet}\n${selectedPosition!.latitude}\n${selectedPosition!.longitude}")));
|
||||
|
||||
@@ -1,8 +1,18 @@
|
||||
// * Widget for managing camera trap control/check dates
|
||||
// * Features:
|
||||
// * - Date picker for selecting control dates
|
||||
// * - Date display in localized format
|
||||
// * - Callback support for date changes
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fforte/l10n/app_localizations.dart';
|
||||
|
||||
/// Widget for selecting and displaying camera trap control dates
|
||||
/// Used to schedule when the camera trap should be checked
|
||||
class KontDat extends StatefulWidget {
|
||||
/// Initial control date, if any
|
||||
final DateTime? initKontDat;
|
||||
/// Callback function when date is changed
|
||||
final Function(DateTime) onDateChanged;
|
||||
|
||||
const KontDat(
|
||||
@@ -12,7 +22,9 @@ class KontDat extends StatefulWidget {
|
||||
State<KontDat> createState() => _KontDatState();
|
||||
}
|
||||
|
||||
/// State class for the control date widget
|
||||
class _KontDatState extends State<KontDat> {
|
||||
/// Currently selected control date
|
||||
DateTime? kontDat;
|
||||
|
||||
@override
|
||||
@@ -26,6 +38,7 @@ class _KontDatState extends State<KontDat> {
|
||||
return Row(
|
||||
children: [
|
||||
Row(children: [
|
||||
// Date picker button
|
||||
SizedBox(
|
||||
width: 140,
|
||||
child: ElevatedButton(
|
||||
@@ -39,9 +52,8 @@ class _KontDatState extends State<KontDat> {
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!.pickkontdat)),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
const SizedBox(width: 10),
|
||||
// Display selected date in DD.MM.YYYY format
|
||||
Text(
|
||||
'${kontDat?.day}. ${kontDat?.month}. ${kontDat?.year}',
|
||||
),
|
||||
@@ -50,6 +62,8 @@ class _KontDatState extends State<KontDat> {
|
||||
);
|
||||
}
|
||||
|
||||
/// Show date picker dialog and return selected date
|
||||
/// @return Future<DateTime?> Selected date or null if cancelled
|
||||
Future<DateTime?> pickDate() async {
|
||||
final date = await showDatePicker(
|
||||
context: context,
|
||||
|
||||
@@ -1,8 +1,18 @@
|
||||
// * Widget for selecting time zone settings (MEZ/MESZ)
|
||||
// * Features:
|
||||
// * - Radio button selection between summer and winter time
|
||||
// * - Localized labels for time zones
|
||||
// * - Default selection support
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fforte/l10n/app_localizations.dart';
|
||||
|
||||
/// Widget for selecting between summer time (MESZ) and winter time (MEZ)
|
||||
/// Used to configure camera trap time settings
|
||||
class MEZ extends StatefulWidget {
|
||||
/// Callback function when time zone selection changes
|
||||
final Function(String) onMEZChanged;
|
||||
/// Initial time zone selection ('sommerzeit' by default)
|
||||
final String initialMEZ;
|
||||
|
||||
const MEZ(
|
||||
@@ -12,7 +22,9 @@ class MEZ extends StatefulWidget {
|
||||
State<MEZ> createState() => _MEZState();
|
||||
}
|
||||
|
||||
/// State class for the time zone selection widget
|
||||
class _MEZState extends State<MEZ> {
|
||||
/// Currently selected time zone
|
||||
String? _selectedMEZ;
|
||||
|
||||
@override
|
||||
@@ -25,6 +37,7 @@ class _MEZState extends State<MEZ> {
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
// Summer time (MESZ) radio button
|
||||
ListTile(
|
||||
visualDensity: const VisualDensity(vertical: -4),
|
||||
title: Text(AppLocalizations.of(context)!.sommerzeit),
|
||||
@@ -39,6 +52,7 @@ class _MEZState extends State<MEZ> {
|
||||
},
|
||||
),
|
||||
),
|
||||
// Winter time (MEZ) radio button
|
||||
ListTile(
|
||||
visualDensity: const VisualDensity(vertical: -4),
|
||||
title: Text(AppLocalizations.of(context)!.winterzeit),
|
||||
|
||||
@@ -1,8 +1,26 @@
|
||||
// * Widget for selecting camera trap placement type
|
||||
// * Features:
|
||||
// * - Multiple placement options via radio buttons
|
||||
// * - Localized labels for each placement type
|
||||
// * - Support for initial selection
|
||||
// * Available placement types:
|
||||
// * - Bait station (Kirrung)
|
||||
// * - Water source (Wasserstelle)
|
||||
// * - Forest (Wald)
|
||||
// * - Game pass (Wildwechsel)
|
||||
// * - Path/Road (Weg/Straße)
|
||||
// * - Farm/Garden (Hof/Garten)
|
||||
// * - Meadow/Field (Wiese/Feld/Offenfläche)
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fforte/l10n/app_localizations.dart';
|
||||
|
||||
/// Widget for selecting the type of location where the camera trap is placed
|
||||
/// Provides various predefined placement options common in wildlife monitoring
|
||||
class Platzung extends StatefulWidget {
|
||||
/// Callback function when placement type selection changes
|
||||
final Function(String) onPlatzungChanged;
|
||||
/// Initial placement type selection
|
||||
final String? initialPlatzung;
|
||||
|
||||
const Platzung({
|
||||
@@ -15,7 +33,9 @@ class Platzung extends StatefulWidget {
|
||||
State<Platzung> createState() => _PlatzungState();
|
||||
}
|
||||
|
||||
/// State class for the placement type selection widget
|
||||
class _PlatzungState extends State<Platzung> {
|
||||
/// Currently selected placement type
|
||||
String? _selectedPlatzung;
|
||||
|
||||
@override
|
||||
@@ -30,6 +50,7 @@ class _PlatzungState extends State<Platzung> {
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
// Bait station placement option
|
||||
ListTile(
|
||||
visualDensity: const VisualDensity(vertical: -4),
|
||||
title: Text(AppLocalizations.of(context)!.kirrung),
|
||||
@@ -44,6 +65,7 @@ class _PlatzungState extends State<Platzung> {
|
||||
},
|
||||
),
|
||||
),
|
||||
// Water source placement option
|
||||
ListTile(
|
||||
visualDensity: const VisualDensity(vertical: -4),
|
||||
title: Text(AppLocalizations.of(context)!.wasserstelle),
|
||||
@@ -58,6 +80,7 @@ class _PlatzungState extends State<Platzung> {
|
||||
},
|
||||
),
|
||||
),
|
||||
// Forest placement option
|
||||
ListTile(
|
||||
visualDensity: const VisualDensity(vertical: -4),
|
||||
title: Text(AppLocalizations.of(context)!.wald),
|
||||
@@ -72,6 +95,7 @@ class _PlatzungState extends State<Platzung> {
|
||||
},
|
||||
),
|
||||
),
|
||||
// Game pass placement option
|
||||
ListTile(
|
||||
visualDensity: const VisualDensity(vertical: -4),
|
||||
title: Text(AppLocalizations.of(context)!.wildwechsel),
|
||||
@@ -86,6 +110,7 @@ class _PlatzungState extends State<Platzung> {
|
||||
},
|
||||
),
|
||||
),
|
||||
// Path/Road placement option
|
||||
ListTile(
|
||||
visualDensity: const VisualDensity(vertical: -4),
|
||||
title: Text(AppLocalizations.of(context)!.wegstrasse),
|
||||
@@ -100,6 +125,7 @@ class _PlatzungState extends State<Platzung> {
|
||||
},
|
||||
),
|
||||
),
|
||||
// Farm/Garden placement option
|
||||
ListTile(
|
||||
visualDensity: const VisualDensity(vertical: -4),
|
||||
title: Text(AppLocalizations.of(context)!.hofgarten),
|
||||
@@ -114,6 +140,7 @@ class _PlatzungState extends State<Platzung> {
|
||||
},
|
||||
),
|
||||
),
|
||||
// Meadow/Field placement option
|
||||
ListTile(
|
||||
visualDensity: const VisualDensity(vertical: -4),
|
||||
title: Text(AppLocalizations.of(context)!.wiesefeld),
|
||||
|
||||
@@ -1,8 +1,18 @@
|
||||
// * Widget for selecting camera trap status
|
||||
// * Features:
|
||||
// * - Radio button selection between active and inactive
|
||||
// * - Localized status labels
|
||||
// * - Default selection support
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fforte/l10n/app_localizations.dart';
|
||||
|
||||
/// Widget for selecting the operational status of a camera trap
|
||||
/// Allows toggling between active and inactive states
|
||||
class Status extends StatefulWidget {
|
||||
/// Callback function when status selection changes
|
||||
final Function(String) onStatusChanged;
|
||||
/// Initial status selection ('Aktiv' by default)
|
||||
final String initialStatus;
|
||||
|
||||
const Status(
|
||||
@@ -12,7 +22,9 @@ class Status extends StatefulWidget {
|
||||
State<Status> createState() => _StatusState();
|
||||
}
|
||||
|
||||
/// State class for the status selection widget
|
||||
class _StatusState extends State<Status> {
|
||||
/// Currently selected status
|
||||
String? _selectedStatus;
|
||||
|
||||
@override
|
||||
@@ -25,6 +37,7 @@ class _StatusState extends State<Status> {
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
// Active status option
|
||||
ListTile(
|
||||
visualDensity: const VisualDensity(vertical: -4),
|
||||
title: Text(AppLocalizations.of(context)!.aktiv),
|
||||
@@ -39,6 +52,7 @@ class _StatusState extends State<Status> {
|
||||
},
|
||||
),
|
||||
),
|
||||
// Inactive status option
|
||||
ListTile(
|
||||
visualDensity: const VisualDensity(vertical: -4),
|
||||
title: Text(AppLocalizations.of(context)!.inaktiv),
|
||||
|
||||
@@ -1,8 +1,19 @@
|
||||
// * Widget for selecting the sampling type for camera trap monitoring
|
||||
// * Features:
|
||||
// * - Two sampling modes: opportunistic and systematic
|
||||
// * - Radio button selection interface
|
||||
// * - State management for selection
|
||||
// * - Callback for selection changes
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:fforte/l10n/app_localizations.dart';
|
||||
|
||||
/// Widget for managing sampling type selection
|
||||
/// Provides choice between opportunistic and systematic sampling
|
||||
class STTyp extends StatefulWidget {
|
||||
/// Callback function when sampling type changes
|
||||
final Function(String) onSTTypChanged;
|
||||
/// Initial sampling type value
|
||||
final String initialSTTyp;
|
||||
|
||||
const STTyp(
|
||||
@@ -14,7 +25,9 @@ class STTyp extends StatefulWidget {
|
||||
State<STTyp> createState() => _STTypState();
|
||||
}
|
||||
|
||||
/// State class for the sampling type selection widget
|
||||
class _STTypState extends State<STTyp> {
|
||||
/// Currently selected sampling type
|
||||
String? _selectedSTTyp;
|
||||
|
||||
@override
|
||||
@@ -27,6 +40,7 @@ class _STTypState extends State<STTyp> {
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
// Opportunistic sampling option
|
||||
ListTile(
|
||||
visualDensity: const VisualDensity(vertical: -4),
|
||||
title: Text(AppLocalizations.of(context)!.opportunistisch),
|
||||
@@ -41,6 +55,7 @@ class _STTypState extends State<STTyp> {
|
||||
},
|
||||
),
|
||||
),
|
||||
// Systematic sampling option
|
||||
ListTile(
|
||||
visualDensity: const VisualDensity(vertical: -4),
|
||||
title: Text(AppLocalizations.of(context)!.systematisch),
|
||||
|
||||
Reference in New Issue
Block a user