let AI comment everything because well... yeah...

This commit is contained in:
Nico
2025-06-06 21:00:32 +02:00
parent 9c84d0c375
commit cc110ac104
44 changed files with 1230 additions and 646 deletions

View File

@@ -1,12 +1,22 @@
class CheckRequired {
static bool checkRequired(Map<String, Map<String, dynamic>> fieldsList) {
for (String key in fieldsList.keys) {
if (fieldsList[key]!["required"]! && fieldsList[key]!["controller"]!.text.isEmpty) {
return true;
}
}
// * Utility class for validating required form fields
// * Used to check if all required fields have been filled out
// * before saving or submitting form data
return false;
/// Helper class for form field validation
class CheckRequired {
/// Check if any required fields are empty
/// @param fieldsList Map of field definitions with their required status and controllers
/// @return true if any required field is empty, false otherwise
static bool checkRequired(Map<String, Map<String, dynamic>> fieldsList) {
// Iterate through all fields
for (String key in fieldsList.keys) {
// Check if field is required and empty
if (fieldsList[key]!["required"]! && fieldsList[key]!["controller"]!.text.isEmpty) {
return true; // Found an empty required field
}
}
return false; // All required fields are filled
}
}

View File

@@ -1,10 +1,19 @@
// * Shared methods for deleting main entries from the database
// * Provides functionality for:
// * - Deleting all entries of a specific type
// * - Deleting a single entry by ID
import 'package:fforte/enums/databases.dart';
import 'package:fforte/interfaces/i_db.dart';
import 'package:fforte/methods/excursion_db_helper.dart';
import 'package:fforte/methods/place_db_helper.dart';
/// Helper class for deleting main entries from the database
class DeleteMainEntries {
/// Delete all main entries of a specific type
/// @param dbType The type of database (place/excursion)
static Future<void> deleteAll(DatabasesEnum dbType) async {
// Select appropriate database helper
IDb? db;
if (dbType == DatabasesEnum.place) {
@@ -15,7 +24,11 @@ class DeleteMainEntries {
await db!.deleteAllMainEntries();
}
/// Delete a single main entry by ID
/// @param dbType The type of database (place/excursion)
/// @param id ID of the entry to delete
static Future<void> deleteSingle(DatabasesEnum dbType, int id) async {
// Select appropriate database helper
IDb? db;
if (dbType == DatabasesEnum.place) {

View File

@@ -1,11 +1,20 @@
// * Shared methods for deleting templates from the database
// * Provides functionality for:
// * - Deleting all templates of a specific type
// * - Deleting a single template by ID
import 'package:fforte/enums/databases.dart';
import 'package:fforte/interfaces/i_db.dart';
import 'package:fforte/methods/excursion_db_helper.dart';
import 'package:fforte/methods/place_db_helper.dart';
/// Helper class for deleting templates from the database
class DeleteTemplates {
/// Delete a single template by ID
/// @param dbType The type of database (place/excursion)
/// @param id ID of the template to delete
static Future<void> deleteSingle(DatabasesEnum dbType, String id) async {
// Select appropriate database helper
IDb? db;
if (dbType == DatabasesEnum.place) {
@@ -17,7 +26,10 @@ class DeleteTemplates {
await db!.deleteTemplateById(id);
}
/// Delete all templates of a specific type
/// @param dbType The type of database (place/excursion)
static Future<void> deleteAll(DatabasesEnum dbType) async {
// Select appropriate database helper
IDb? db;
if (dbType == DatabasesEnum.place) {

View File

@@ -1,9 +1,22 @@
// * Service for handling HTTP requests to the backend API
// * Features:
// * - Support for camera trap and excursion data endpoints
// * - Configurable timeouts
// * - Error handling
// * - JSON data formatting
import 'dart:convert';
import 'package:dio/dio.dart';
import 'package:shared_preferences/shared_preferences.dart';
/// Service class for making HTTP requests to the backend
/// Handles both camera trap and excursion data submissions
class HttpRequestService {
/// Send data to the appropriate backend endpoint
/// @param saveDataMap Optional map of data to send
/// @param saveDataString Optional string of data to send
/// @return Future<int> HTTP status code of the response
static Future<int> httpRequest({Map<String, String>? saveDataMap, String? saveDataString}) async {
// print(jsonEncode(place));
@@ -18,6 +31,7 @@ class HttpRequestService {
Response(requestOptions: RequestOptions(path: ''), statusCode: 400);
try {
// Choose endpoint based on data type (camera trap vs excursion)
if (saveDataMap != null && saveDataMap.containsKey("CID") || saveDataString != null && saveDataString.contains("CID")) {
response = await dio.post(prefs.getString('fotofallenApiAddress') ?? "",
data: saveDataMap == null ? saveDataString : jsonEncode(saveDataMap));

View File

@@ -1,3 +1,9 @@
// * Shared method for saving entries to text files
// * Allows users to:
// * - Select a save directory
// * - Save entries as JSON files
// * - Persist the chosen directory for future use
import 'dart:convert';
import 'dart:io';
@@ -7,7 +13,14 @@ import 'package:file_picker/file_picker.dart';
import 'package:flutter/foundation.dart';
import 'package:shared_preferences/shared_preferences.dart';
/// Helper class for saving entries to files
class SaveFileMethod {
/// Save an entry to a text file in JSON format
/// @param place Map containing the entry data
/// @param id ID of the entry
/// @param fileNameLocalization Localized prefix for the filename
/// @param dbType The type of database (place/excursion)
/// @throws FileDialogCancelled if user cancels directory selection
static Future<void> saveFile(
Map<String, String> place,
int id,
@@ -15,24 +28,32 @@ class SaveFileMethod {
DatabasesEnum dbType,
) async {
try {
// Let user select save directory
String? selectedDirectory = await FilePicker.platform.getDirectoryPath();
if (selectedDirectory == null) {
throw FileDialogCancelled();
}
// Save entry as JSON
SharedPreferences prefs = await SharedPreferences.getInstance();
String jsonPlace = jsonEncode(place);
// Remember selected directory for future use
await prefs.setString('saveDir', selectedDirectory);
// Create file with format: prefix-id-identifier.txt
// For places: identifier = CID
// For excursions: identifier = date
File file = File(
'$selectedDirectory/$fileNameLocalization-$id-${dbType == DatabasesEnum.place ? place["CID"] : place["Datum"]!.split(" ").first}.txt',
);
// Write JSON data to file
await file.writeAsString(jsonPlace);
} catch (e) {
debugPrint(e.toString());
rethrow; // Re-throw to allow proper error handling by caller
}
}
}

View File

@@ -1,40 +1,60 @@
// * Shared method for saving main entries to the database
// * Handles both place and excursion entries
// * Supports:
// * - Creating new entries
// * - Converting templates to entries
// * - Updating existing entries
// * - Marking entries as sent to server
import 'package:fforte/enums/databases.dart';
import 'package:fforte/interfaces/i_db.dart';
import 'package:fforte/methods/excursion_db_helper.dart';
import 'package:fforte/methods/place_db_helper.dart';
/// Helper class for saving main entries to the database
class SaveMainEntryMethod {
/// Save or update a main entry in the database
/// @param entryData Map containing the entry data
/// @param isTemplate Whether this is being converted from a template
/// @param dbType The type of database (place/excursion)
/// @param sent Whether the entry has been sent to the server
/// @return ID of the saved entry
static Future<int> saveEntry({
required Map<String, String> entryData,
required bool isTemplate,
required DatabasesEnum dbType,
bool sent = false,
}) async {
// Select appropriate database helper
IDb? placeDB;
if (dbType == DatabasesEnum.place) {
placeDB = PlaceDBHelper();
placeDB = PlaceDBHelper();
} else if (dbType == DatabasesEnum.excursion) {
placeDB = ExcursionDBHelper();
placeDB = ExcursionDBHelper();
}
// If converting from template, delete the template first
if (isTemplate) await placeDB!.deleteTemplateById(entryData["ID"]!);
// Handle new entry creation vs update
int entryId;
if (entryData["ID"] == "" || isTemplate) {
// Create new entry
entryData.remove("ID");
entryId = await placeDB!.addMainEntry(entryData);
// Commented out template deletion by CID
// await placeDB.deleteTemplateById(entryData["CID"]!);
} else {
// Update existing entry
entryId = await placeDB!.updateMainEntry(entryData);
}
// Update sent status if entry was sent to server
if (sent == true) {
placeDB.updateSent(entryId); // Update 'Sent' using the correct ID
placeDB.updateSent(entryId);
}
return entryId;
}
}

View File

@@ -1,25 +1,39 @@
// * Shared method for saving templates to the database
// * Handles both place and excursion templates
// * Supports both creating new templates and updating existing ones
import 'package:fforte/enums/databases.dart';
import 'package:fforte/interfaces/i_db.dart';
import 'package:fforte/methods/excursion_db_helper.dart';
import 'package:fforte/methods/place_db_helper.dart';
/// Save or update a template in the database
/// @param templateData Map containing the template data
/// @param dbType The type of database (place/excursion)
/// @return ID of the saved template, or -1 if operation failed
Future<int> saveTemplate(Map<String, String> templateData, DatabasesEnum dbType,) async {
// Select appropriate database helper
IDb dbHelper;
int id =templateData["ID"]! != "" ? int.parse(templateData["ID"]!) : -1;
int id = templateData["ID"]! != "" ? int.parse(templateData["ID"]!) : -1;
if (dbType == DatabasesEnum.place) {
dbHelper = PlaceDBHelper();
} else if (dbType == DatabasesEnum.excursion) {
dbHelper = ExcursionDBHelper();
} else {
return -1;
return -1; // Invalid database type
}
// Remove sent status as it's not needed for templates
templateData.remove("Sent");
// Handle new template creation vs update
if (templateData["ID"]! == "" || templateData["ID"]! == "-1") {
// Create new template
templateData.remove("ID");
id = await dbHelper.addTemplate(templateData);
} else {
// Update existing template
await dbHelper.updateTemplate(templateData);
}

View File

@@ -1,15 +1,26 @@
// * Shared method for sending files to the server
// * Allows users to:
// * - Select a file using the system file picker
// * - Send the file contents to the server
// * Legacy widget implementation is kept for reference
import 'package:fforte/screens/sharedMethods/http_request.dart';
import 'package:file_picker/file_picker.dart';
import 'dart:io';
/// Helper class for sending files to the server
class SendFile {
/// Let user pick a file and send its contents to the server
/// Uses the system file picker for file selection
/// Sends file content using the HttpRequestService
static Future<void> sendFile() async {
File? pickedFile;
// Open file picker dialog
FilePickerResult? result = await FilePicker.platform.pickFiles();
if (result != null) {
// Read and send file contents
pickedFile = File(result.files.single.path!);
String fileContent = await pickedFile.readAsString();
await HttpRequestService.httpRequest(saveDataString: fileContent);
@@ -17,64 +28,67 @@ class SendFile {
}
}
// class SendFile extends StatefulWidget {
// const SendFile({super.key});
//
// @override
// State<SendFile> createState() => _SendFileState();
// }
//
// class _SendFileState extends State<SendFile> {
// File? pickedFile;
//
// @override
// Widget build(BuildContext context) {
// return Scaffold(
// appBar: AppBar(),
// body: Column(
// children: [
// ElevatedButton(
// onPressed: () async {
// FilePickerResult? result =
// await FilePicker.platform.pickFiles();
//
// if (result != null) {
// pickedFile = File(result.files.single.path!);
// } else {
// pickedFile = File("");
// }
// },
// child: Text(AppLocalizations.of(context)!.pickfile)),
// Text(pickedFile.toString()),
// ElevatedButton(
// onPressed: () async {
// final dio = Dio();
// final SharedPreferences prefs = await SharedPreferences.getInstance();
// String? fileContent = await pickedFile?.readAsString();
//
// dio.options.responseType = ResponseType.plain;
// Response response = Response(
// requestOptions: RequestOptions(path: ''), statusCode: 400);
//
// try {
// response = await dio.post(prefs.getString('apiAddress') ?? "",
// data: jsonEncode(fileContent));
// } on DioException catch (e) {
// if (e.response?.statusCode == 500) {
// /* print('-------------------------');
// print('code 500'); */
// return;
// }
// }
// if (response.statusCode == 201) {
// // print(response.statusCode);
// } else {
// //print(response.statusCode);
// }
// },
// child: Text(AppLocalizations.of(context)!.sendtoserver))
// ],
// ),
// );
// }
// }
// * Legacy widget implementation kept for reference
// * This was a stateful widget version of the file sender
// * with additional UI elements and error handling
/*
class SendFile extends StatefulWidget {
const SendFile({super.key});
@override
State<SendFile> createState() => _SendFileState();
}
class _SendFileState extends State<SendFile> {
File? pickedFile;
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: Column(
children: [
ElevatedButton(
onPressed: () async {
FilePickerResult? result =
await FilePicker.platform.pickFiles();
if (result != null) {
pickedFile = File(result.files.single.path!);
} else {
pickedFile = File("");
}
},
child: Text(AppLocalizations.of(context)!.pickfile)),
Text(pickedFile.toString()),
ElevatedButton(
onPressed: () async {
final dio = Dio();
final SharedPreferences prefs = await SharedPreferences.getInstance();
String? fileContent = await pickedFile?.readAsString();
dio.options.responseType = ResponseType.plain;
Response response = Response(
requestOptions: RequestOptions(path: ''), statusCode: 400);
try {
response = await dio.post(prefs.getString('apiAddress') ?? "",
data: jsonEncode(fileContent));
} on DioException catch (e) {
if (e.response?.statusCode == 500) {
return;
}
}
if (response.statusCode == 201) {
// Success handling was here
} else {
// Error handling was here
}
},
child: Text(AppLocalizations.of(context)!.sendtoserver))
],
),
);
}
}
*/