bissl weiter
This commit is contained in:
16
README.md
Normal file
16
README.md
Normal file
@@ -0,0 +1,16 @@
|
||||
# fforte
|
||||
|
||||
A new Flutter project.
|
||||
|
||||
## Getting Started
|
||||
|
||||
This project is a starting point for a Flutter application.
|
||||
|
||||
A few resources to get you started if this is your first Flutter project:
|
||||
|
||||
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
|
||||
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
|
||||
|
||||
For help getting started with Flutter development, view the
|
||||
[online documentation](https://docs.flutter.dev/), which offers tutorials,
|
||||
samples, guidance on mobile development, and a full API reference.
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:fforte/screens/addCam/add_cam_main.dart~';
|
||||
import 'package:fforte/screens/Excursion/excursion_main.dart';
|
||||
import 'package:fforte/screens/addCam/add_cam_main.dart';
|
||||
import 'package:fforte/screens/intro_screen.dart';
|
||||
import 'package:fforte/screens/settings.dart';
|
||||
import 'package:fforte/screens/viewCam/view_cams.dart';
|
||||
@@ -15,14 +16,14 @@ import 'l10n/l10n.dart';
|
||||
runApp(const MyApp());
|
||||
} */
|
||||
|
||||
|
||||
void main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
SharedPreferences prefs = await SharedPreferences.getInstance();
|
||||
bool isFirstLaunch = prefs.getBool('isFirstLaunch') ?? true;
|
||||
await prefs.setString('kTage1', "28");
|
||||
await prefs.setString('kTage2', "48");
|
||||
await prefs.setString('apiAddress', 'http://192.168.1.106/www.dbb-wolf.de/data/app24.php');
|
||||
await prefs.setString(
|
||||
'apiAddress', 'http://192.168.1.106/www.dbb-wolf.de/data/app24.php');
|
||||
runApp(MyApp(isFirstLaunch: isFirstLaunch));
|
||||
}
|
||||
|
||||
@@ -30,14 +31,11 @@ class MyApp extends StatelessWidget {
|
||||
final bool isFirstLaunch;
|
||||
const MyApp({super.key, required this.isFirstLaunch});
|
||||
|
||||
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return MaterialApp(
|
||||
title: 'FFOrte',
|
||||
theme:
|
||||
FlexThemeData.light(scheme: FlexScheme.gold, useMaterial3: true),
|
||||
theme: FlexThemeData.light(scheme: FlexScheme.gold, useMaterial3: true),
|
||||
darkTheme:
|
||||
FlexThemeData.dark(scheme: FlexScheme.greenM3, useMaterial3: true),
|
||||
themeMode: ThemeMode.system,
|
||||
@@ -55,7 +53,7 @@ class MyApp extends StatelessWidget {
|
||||
'/viewCams': (context) => const ViewCams(),
|
||||
'/introScreen': (context) => const IntroScreen(),
|
||||
'/settings': (context) => const Settings(),
|
||||
'/excursion': (context) => const Settings(),
|
||||
'/excursion': (context) => const ExcursionMain(),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
@@ -101,5 +101,6 @@
|
||||
"back": "Zurück",
|
||||
"loading": "Lädt",
|
||||
"test": "Test",
|
||||
"notest": "Kein Test"
|
||||
"notest": "Kein Test",
|
||||
"dateandtime": "Datum und Zeit"
|
||||
}
|
||||
@@ -494,10 +494,13 @@
|
||||
"description": "no test"
|
||||
},
|
||||
|
||||
|
||||
"excursion": "Excursion",
|
||||
"@excursion": {
|
||||
"description": "no test"
|
||||
},
|
||||
"dateandtime": "Date and Time",
|
||||
"@dateandtime": {
|
||||
"description": "date and time step header"
|
||||
}
|
||||
|
||||
}
|
||||
@@ -33,6 +33,9 @@ class DBHelper {
|
||||
'CREATE TABLE place (ID INTEGER PRIMARY KEY AUTOINCREMENT, CID TEXT, Standort TEXT, Rudel TEXT, Datum DATE, Adresse1 TEXT, Adresse2 TEXT, Adresse3 TEXT, BLand TEXT, Lkr TEXT, BeiOrt TEXT, OrtInfo TEXT, Status TEXT, FFTyp TEXT, FotoFilm TEXT, MEZ TEXT, Platzung TEXT, KSchloNr TEXT, KontDat DATE, Betreuung TEXT, AbbauDat DATE, Auftrag TEXT, KontAbsp TEXT, SonstBem TEXT, FKontakt1 TEXT, FKontakt2 TEXT, FKontakt3 TEXT, KTage1 INTEGER, KTage2 INTEGER, ProtoAm DATE, IntKomm TEXT, DECLNG DECIMALS(4,8), DECLAT DECIMALS(4,8), Sent INTEGER DEFAULT 0)');
|
||||
await placeDB.execute(
|
||||
'CREATE TABLE templates (ID INTEGER PRIMARY KEY AUTOINCREMENT, CID TEXT, Standort TEXT, Rudel TEXT, Datum DATE, Adresse1 TEXT, Adresse2 TEXT, Adresse3 TEXT, BLand TEXT, Lkr TEXT, BeiOrt TEXT, OrtInfo TEXT, Status TEXT, FFTyp TEXT, FotoFilm TEXT, MEZ TEXT, Platzung TEXT, KSchloNr TEXT, KontDat DATE, Betreuung TEXT, AbbauDat DATE, Auftrag TEXT, KontAbsp TEXT, SonstBem TEXT, FKontakt1 TEXT, FKontakt2 TEXT, FKontakt3 TEXT, KTage1 INTEGER, KTage2 INTEGER, ProtoAm DATE, IntKomm TEXT, DECLNG DECIMALS(4,8), DECLAT DECIMALS(4,8))');
|
||||
await placeDB.execute(
|
||||
'CREATE TABLE excursion (ID INTEGER PRIMARY KEY AUTOINCREMENT)'
|
||||
);
|
||||
}
|
||||
|
||||
// Function to add a finished entry and return its ID
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import 'package:animations/animations.dart';
|
||||
import 'package:fforte/screens/sharedWidgets/datum.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
@@ -14,15 +15,22 @@ class _ExcursionMainState extends State<ExcursionMain> {
|
||||
Widget build(BuildContext context) {
|
||||
List<Step> getSteps() => [
|
||||
Step(
|
||||
title: const Text("step1"),
|
||||
content: const Column(
|
||||
title: Text(AppLocalizations.of(context)!.dateandtime),
|
||||
content: Column(
|
||||
children: [
|
||||
Text("data"),
|
||||
Datum(initDatum: DateTime.now(),
|
||||
onDateChanged: (date) {
|
||||
|
||||
}),
|
||||
const SizedBox(height: 10,)
|
||||
],
|
||||
)),
|
||||
const Step(title: Text("step2"), content: Text("data"))
|
||||
];
|
||||
|
||||
|
||||
|
||||
|
||||
int currentStep = 0;
|
||||
|
||||
return Scaffold(
|
||||
|
||||
@@ -4,6 +4,8 @@ import 'dart:io';
|
||||
import 'package:fforte/screens/addCam/cam_widgets.dart';
|
||||
import 'package:fforte/methods/db_helper.dart';
|
||||
import 'package:fforte/methods/http_request.dart';
|
||||
import 'package:fforte/screens/sharedWidgets/datum.dart';
|
||||
import 'package:fforte/screens/sharedWidgets/var_text_field.dart';
|
||||
import 'package:file_picker/file_picker.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
@@ -8,150 +8,6 @@ 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? defaultValue;
|
||||
final String? otherDefault;
|
||||
final bool required;
|
||||
|
||||
const VarTextField(
|
||||
{super.key,
|
||||
required this.textController,
|
||||
required this.localization,
|
||||
required this.dbName,
|
||||
required this.required,
|
||||
this.defaultValue,
|
||||
this.otherDefault});
|
||||
|
||||
@override
|
||||
State<VarTextField> createState() => _VarTextFieldState();
|
||||
}
|
||||
|
||||
class _VarTextFieldState extends State<VarTextField> {
|
||||
late Future<List<Map<String, dynamic>>> dbVar;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
if (widget.textController.text == "" && widget.defaultValue != null) {
|
||||
_loadPref();
|
||||
}
|
||||
|
||||
if (widget.otherDefault != null) {
|
||||
widget.textController.text = widget.otherDefault!;
|
||||
}
|
||||
|
||||
dbVar = _loadData();
|
||||
}
|
||||
|
||||
Future<List<Map<String, dynamic>>> _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.defaultValue!) ?? "";
|
||||
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 Expanded(
|
||||
child: SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Align(
|
||||
alignment: Alignment.bottomLeft,
|
||||
child: FutureBuilder<List<Map<String, dynamic>>>(
|
||||
future: dbVar,
|
||||
builder: (BuildContext context,
|
||||
AsyncSnapshot<List<Map<String, dynamic>>> 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();
|
||||
|
||||
var uniqueData = { ...filteredData.map((e) => e[widget.dbName].toString())};
|
||||
|
||||
return PopupMenuButton<String>(
|
||||
onSelected: (String value) {
|
||||
setState(() {
|
||||
widget.textController.text = value;
|
||||
});
|
||||
},
|
||||
itemBuilder: (BuildContext context) {
|
||||
return uniqueData
|
||||
.map((value) => PopupMenuItem<String>(
|
||||
value: value,
|
||||
child: Text(value),
|
||||
))
|
||||
.toList();
|
||||
},
|
||||
child: const Icon(Icons.arrow_drop_down),
|
||||
);
|
||||
} else if (snapshot.hasError) {
|
||||
return Text('Fehler: ${snapshot.error}');
|
||||
} else {
|
||||
return const CircularProgressIndicator();
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Karte
|
||||
@@ -286,82 +142,6 @@ class KarteState extends State<Karte> {
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
//
|
||||
|
||||
// Datum == Datum der Aufstellung
|
||||
// datum is the variable where the chosen date is stored
|
||||
|
||||
class Datum extends StatefulWidget {
|
||||
final DateTime? initDatum;
|
||||
final Function(DateTime) onDateChanged;
|
||||
|
||||
const Datum({super.key, required this.initDatum, required this.onDateChanged});
|
||||
|
||||
@override
|
||||
State<Datum> createState() => _DatumState();
|
||||
}
|
||||
|
||||
class _DatumState extends State<Datum> {
|
||||
DateTime? datum;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
datum = widget.initDatum;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
Row(children: [
|
||||
SizedBox(
|
||||
width: 140,
|
||||
child: ElevatedButton(
|
||||
onPressed: () async {
|
||||
final date = await pickDate();
|
||||
if (date == null) return;
|
||||
setState(() => datum = date);
|
||||
widget.onDateChanged(date);
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!.pickDate)),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Text(
|
||||
'${datum?.day}. ${datum?.month}. ${datum?.year}',
|
||||
),
|
||||
]),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Future<DateTime?> pickDate() async {
|
||||
final date = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: datum!,
|
||||
firstDate: DateTime(2000),
|
||||
lastDate: DateTime(5000));
|
||||
|
||||
return date;
|
||||
}
|
||||
}
|
||||
|
||||
// Status
|
||||
|
||||
class Status extends StatefulWidget {
|
||||
|
||||
60
lib/screens/sharedWidgets/datum.dart
Normal file
60
lib/screens/sharedWidgets/datum.dart
Normal file
@@ -0,0 +1,60 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_gen/gen_l10n/app_localizations.dart';
|
||||
|
||||
|
||||
class Datum extends StatefulWidget {
|
||||
final DateTime? initDatum;
|
||||
final Function(DateTime) onDateChanged;
|
||||
|
||||
const Datum({super.key, required this.initDatum, required this.onDateChanged});
|
||||
|
||||
@override
|
||||
State<Datum> createState() => _DatumState();
|
||||
}
|
||||
|
||||
class _DatumState extends State<Datum> {
|
||||
DateTime? datum;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
datum = widget.initDatum;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Row(
|
||||
children: [
|
||||
Row(children: [
|
||||
SizedBox(
|
||||
width: 140,
|
||||
child: ElevatedButton(
|
||||
onPressed: () async {
|
||||
final date = await pickDate();
|
||||
if (date == null) return;
|
||||
setState(() => datum = date);
|
||||
widget.onDateChanged(date);
|
||||
},
|
||||
child: Text(AppLocalizations.of(context)!.pickDate)),
|
||||
),
|
||||
const SizedBox(
|
||||
width: 10,
|
||||
),
|
||||
Text(
|
||||
'${datum?.day}. ${datum?.month}. ${datum?.year}',
|
||||
),
|
||||
]),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
Future<DateTime?> pickDate() async {
|
||||
final date = await showDatePicker(
|
||||
context: context,
|
||||
initialDate: datum!,
|
||||
firstDate: DateTime(2000),
|
||||
lastDate: DateTime(5000));
|
||||
|
||||
return date;
|
||||
}
|
||||
}
|
||||
146
lib/screens/sharedWidgets/var_text_field.dart
Normal file
146
lib/screens/sharedWidgets/var_text_field.dart
Normal file
@@ -0,0 +1,146 @@
|
||||
import 'package:fforte/methods/db_helper.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
|
||||
class VarTextField extends StatefulWidget {
|
||||
final TextEditingController textController;
|
||||
final String localization;
|
||||
final String dbName;
|
||||
final String? defaultValue;
|
||||
final String? otherDefault;
|
||||
final bool required;
|
||||
|
||||
const VarTextField(
|
||||
{super.key,
|
||||
required this.textController,
|
||||
required this.localization,
|
||||
required this.dbName,
|
||||
required this.required,
|
||||
this.defaultValue,
|
||||
this.otherDefault});
|
||||
|
||||
@override
|
||||
State<VarTextField> createState() => _VarTextFieldState();
|
||||
}
|
||||
|
||||
class _VarTextFieldState extends State<VarTextField> {
|
||||
late Future<List<Map<String, dynamic>>> dbVar;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
if (widget.textController.text == "" && widget.defaultValue != null) {
|
||||
_loadPref();
|
||||
}
|
||||
|
||||
if (widget.otherDefault != null) {
|
||||
widget.textController.text = widget.otherDefault!;
|
||||
}
|
||||
|
||||
dbVar = _loadData();
|
||||
}
|
||||
|
||||
Future<List<Map<String, dynamic>>> _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.defaultValue!) ?? "";
|
||||
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 Expanded(
|
||||
child: SizedBox(
|
||||
width: 15,
|
||||
),
|
||||
),
|
||||
Expanded(
|
||||
flex: 1,
|
||||
child: Align(
|
||||
alignment: Alignment.bottomLeft,
|
||||
child: FutureBuilder<List<Map<String, dynamic>>>(
|
||||
future: dbVar,
|
||||
builder: (BuildContext context,
|
||||
AsyncSnapshot<List<Map<String, dynamic>>> 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();
|
||||
|
||||
var uniqueData = { ...filteredData.map((e) => e[widget.dbName].toString())};
|
||||
|
||||
return PopupMenuButton<String>(
|
||||
onSelected: (String value) {
|
||||
setState(() {
|
||||
widget.textController.text = value;
|
||||
});
|
||||
},
|
||||
itemBuilder: (BuildContext context) {
|
||||
return uniqueData
|
||||
.map((value) => PopupMenuItem<String>(
|
||||
value: value,
|
||||
child: Text(value),
|
||||
))
|
||||
.toList();
|
||||
},
|
||||
child: const Icon(Icons.arrow_drop_down),
|
||||
);
|
||||
} else if (snapshot.hasError) {
|
||||
return Text('Fehler: ${snapshot.error}');
|
||||
} else {
|
||||
return const CircularProgressIndicator();
|
||||
}
|
||||
},
|
||||
),
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user