bissl weiter

This commit is contained in:
Nico
2024-11-22 21:10:42 +01:00
parent 2a83daab4c
commit 3a8081ca4f
10 changed files with 250 additions and 233 deletions

16
README.md Normal file
View 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.

View File

@@ -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/intro_screen.dart';
import 'package:fforte/screens/settings.dart'; import 'package:fforte/screens/settings.dart';
import 'package:fforte/screens/viewCam/view_cams.dart'; import 'package:fforte/screens/viewCam/view_cams.dart';
@@ -15,14 +16,14 @@ import 'l10n/l10n.dart';
runApp(const MyApp()); runApp(const MyApp());
} */ } */
void main() async { void main() async {
WidgetsFlutterBinding.ensureInitialized(); WidgetsFlutterBinding.ensureInitialized();
SharedPreferences prefs = await SharedPreferences.getInstance(); SharedPreferences prefs = await SharedPreferences.getInstance();
bool isFirstLaunch = prefs.getBool('isFirstLaunch') ?? true; bool isFirstLaunch = prefs.getBool('isFirstLaunch') ?? true;
await prefs.setString('kTage1', "28"); await prefs.setString('kTage1', "28");
await prefs.setString('kTage2', "48"); 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)); runApp(MyApp(isFirstLaunch: isFirstLaunch));
} }
@@ -30,14 +31,11 @@ class MyApp extends StatelessWidget {
final bool isFirstLaunch; final bool isFirstLaunch;
const MyApp({super.key, required this.isFirstLaunch}); const MyApp({super.key, required this.isFirstLaunch});
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return MaterialApp( return MaterialApp(
title: 'FFOrte', title: 'FFOrte',
theme: theme: FlexThemeData.light(scheme: FlexScheme.gold, useMaterial3: true),
FlexThemeData.light(scheme: FlexScheme.gold, useMaterial3: true),
darkTheme: darkTheme:
FlexThemeData.dark(scheme: FlexScheme.greenM3, useMaterial3: true), FlexThemeData.dark(scheme: FlexScheme.greenM3, useMaterial3: true),
themeMode: ThemeMode.system, themeMode: ThemeMode.system,
@@ -55,7 +53,7 @@ class MyApp extends StatelessWidget {
'/viewCams': (context) => const ViewCams(), '/viewCams': (context) => const ViewCams(),
'/introScreen': (context) => const IntroScreen(), '/introScreen': (context) => const IntroScreen(),
'/settings': (context) => const Settings(), '/settings': (context) => const Settings(),
'/excursion': (context) => const Settings(), '/excursion': (context) => const ExcursionMain(),
}, },
); );
} }

View File

@@ -101,5 +101,6 @@
"back": "Zurück", "back": "Zurück",
"loading": "Lädt", "loading": "Lädt",
"test": "Test", "test": "Test",
"notest": "Kein Test" "notest": "Kein Test",
"dateandtime": "Datum und Zeit"
} }

View File

@@ -494,10 +494,13 @@
"description": "no test" "description": "no test"
}, },
"excursion": "Excursion", "excursion": "Excursion",
"@excursion": { "@excursion": {
"description": "no test" "description": "no test"
},
"dateandtime": "Date and Time",
"@dateandtime": {
"description": "date and time step header"
} }
} }

View File

@@ -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)'); '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( 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))'); '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 // Function to add a finished entry and return its ID

View File

@@ -1,4 +1,5 @@
import 'package:animations/animations.dart'; import 'package:animations/animations.dart';
import 'package:fforte/screens/sharedWidgets/datum.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';
@@ -14,15 +15,22 @@ class _ExcursionMainState extends State<ExcursionMain> {
Widget build(BuildContext context) { Widget build(BuildContext context) {
List<Step> getSteps() => [ List<Step> getSteps() => [
Step( Step(
title: const Text("step1"), title: Text(AppLocalizations.of(context)!.dateandtime),
content: const Column( content: Column(
children: [ children: [
Text("data"), Datum(initDatum: DateTime.now(),
onDateChanged: (date) {
}),
const SizedBox(height: 10,)
], ],
)), )),
const Step(title: Text("step2"), content: Text("data")) const Step(title: Text("step2"), content: Text("data"))
]; ];
int currentStep = 0; int currentStep = 0;
return Scaffold( return Scaffold(

View File

@@ -4,6 +4,8 @@ import 'dart:io';
import 'package:fforte/screens/addCam/cam_widgets.dart'; import 'package:fforte/screens/addCam/cam_widgets.dart';
import 'package:fforte/methods/db_helper.dart'; import 'package:fforte/methods/db_helper.dart';
import 'package:fforte/methods/http_request.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:file_picker/file_picker.dart';
import 'package:flutter/material.dart'; import 'package:flutter/material.dart';
import 'package:flutter_gen/gen_l10n/app_localizations.dart'; import 'package:flutter_gen/gen_l10n/app_localizations.dart';

View File

@@ -8,150 +8,6 @@ import 'package:latlong2/latlong.dart';
import 'package:shared_preferences/shared_preferences.dart'; import 'package:shared_preferences/shared_preferences.dart';
import 'package:geocoding/geocoding.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 // 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 // Status
class Status extends StatefulWidget { class Status extends StatefulWidget {

View 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;
}
}

View 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();
}
},
),
),
)
],
);
}
}