let AI comment everything because well... yeah...
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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))
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user