add edit and delete
This commit is contained in:
parent
085a7648f3
commit
12b385d7e0
@ -4,3 +4,4 @@ APPWRITE_PUBLIC_ENDPOINT=<YOUR_API_ENDPOINT/v1>
|
||||
PTV_GEOLINK_API_KEY=<YOUR_GEOLINK_API_KEY>
|
||||
APPWRITE_DATABASE_ID=<DatabaseID>
|
||||
APPWRITE_COLLECTION_ID=<Collection_ID>
|
||||
TANKSTOPS_BASE_URL=https://api.e-control.at/sprit/1.0/search/gas-stations/by-address?latitude=<lat>&longitude=<lon>&fuelType=DIE<SUPSuperOrDIEDiesel>&includeClosed=false
|
||||
@ -112,4 +112,22 @@ class AppwriteRepository {
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
Future<models.Document> updateTankStop(String documentId, Map<String, dynamic> map) async {
|
||||
final response = await _databases.updateDocument(
|
||||
databaseId: dotenv.get('APPWRITE_DATABASE_ID'),
|
||||
collectionId: dotenv.get('APPWRITE_COLLECTION_ID'),
|
||||
documentId: documentId,
|
||||
data: map,
|
||||
);
|
||||
return response;
|
||||
}
|
||||
|
||||
Future<dynamic> deleteTankStop(String documentId) async {
|
||||
return await _databases.deleteDocument(
|
||||
databaseId: dotenv.get('APPWRITE_DATABASE_ID'),
|
||||
collectionId: dotenv.get('APPWRITE_COLLECTION_ID'),
|
||||
documentId: documentId,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -227,6 +227,6 @@ class LoginController extends GetxController {
|
||||
}
|
||||
|
||||
void goToTankPage() {
|
||||
Get.offAndToNamed(TankPage.namedRoute);
|
||||
Get.offAndToNamed(TankPage.namedRoute, arguments: {'from': 'Input'});
|
||||
}
|
||||
}
|
||||
|
||||
@ -40,6 +40,9 @@ class TankController extends GetxController {
|
||||
|
||||
final FocusNode firstFocusNode = FocusNode(); // Deklariere den FocusNode
|
||||
|
||||
final isEditMode = false.obs;
|
||||
String documentId = '';
|
||||
|
||||
// Methode für das ausgewählte Datum
|
||||
Future<void> selectDateTime(BuildContext context) async {
|
||||
// 1. Datum auswählen
|
||||
@ -150,8 +153,38 @@ class TankController extends GetxController {
|
||||
@override
|
||||
void onInit() {
|
||||
super.onInit();
|
||||
// Rufe den Standort direkt beim Initialisieren des Controllers ab, falls gewünscht.
|
||||
handleInputOrUpdate();
|
||||
}
|
||||
|
||||
void handleInputOrUpdate() {
|
||||
var mapFromArguments = Get.arguments as Map<String, dynamic>?;
|
||||
if (mapFromArguments != null && mapFromArguments['from'] != null) {
|
||||
isEditMode.value = mapFromArguments['from'] == 'Input' ? true : false;
|
||||
}
|
||||
//bei true ein insert bei false ein update
|
||||
if (isEditMode.value) {
|
||||
fetchCurrentLocation();
|
||||
} else {
|
||||
// Im Editiermodus, keine Standortabfrage durchführen
|
||||
print('Im Editiermodus, keine Standortabfrage durchführen');
|
||||
// Den Fokus auf das erste Eingabefeld setzen
|
||||
FocusScope.of(Get.context!).requestFocus(firstFocusNode);
|
||||
print('TankController is in Edit Mode');
|
||||
if (mapFromArguments != null && mapFromArguments['data'] != null) {
|
||||
var dataMap = mapFromArguments['data'] as Map<String, dynamic>;
|
||||
print('Data Map for Edit Mode: $dataMap');
|
||||
// Setze die documentId für spätere Updates
|
||||
documentId = dataMap['\$id'] ?? '';
|
||||
// Setze die Werte in die TextEditingController
|
||||
dateController.text = dataMap['date'] ?? '';
|
||||
kilometerStandEdittingController.text = dataMap['odometer'] ?? '';
|
||||
mengeController.text = dataMap['liters'] ?? '';
|
||||
pricePerLiterController.text = dataMap['pricePerLiter'] ?? '';
|
||||
ortController.text = dataMap['location'] ?? '';
|
||||
// Berechne den Gesamtpreis
|
||||
updateSumPrice();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
@ -213,7 +246,36 @@ class TankController extends GetxController {
|
||||
print('Formular ist gültig');
|
||||
formKeyTank.currentState!.save();
|
||||
try {
|
||||
//creatiung a tank stop
|
||||
//false update a tank stop
|
||||
if (isEditMode.value == false) {
|
||||
await _authRepository.updateTankStop(documentId, {
|
||||
'userId': _dataBox.read('userId'),
|
||||
'date': f.format(DateTime.parse(dateController.text)),
|
||||
'odometer': kilometerStandEdittingController.text,
|
||||
'liters': mengeController.text,
|
||||
'pricePerLiter': pricePerLiterController.text,
|
||||
'location': ortController.text,
|
||||
}).then((models.Document document) {
|
||||
print('Tankstopp erfolgreich aktualisiert: ${document.data}');
|
||||
messageToUser = 'Tankstopp erfolgreich aktualisiert!';
|
||||
isErrorBySaving = false;
|
||||
})
|
||||
// Handle specific Appwrite exceptions
|
||||
.catchError((error) {
|
||||
isErrorBySaving = true;
|
||||
if (error is AppwriteException) {
|
||||
// Handle specific Appwrite exceptions
|
||||
messageToUser = 'Appwrite Fehler: ${error.message}';
|
||||
print('Appwrite Fehler: ${error.message}');
|
||||
} else {
|
||||
// Handle other types of errors
|
||||
messageToUser = 'Allgemeiner Fehler: $error';
|
||||
print('Allgemeiner Fehler: $error');
|
||||
}
|
||||
print('Fehler bei der speicherung: $error');
|
||||
});
|
||||
} else {
|
||||
//true creating a tank stop
|
||||
await _authRepository.createTankStop({
|
||||
'userId': _dataBox.read('userId'),
|
||||
'date': f.format(DateTime.parse(dateController.text)),
|
||||
@ -240,6 +302,8 @@ class TankController extends GetxController {
|
||||
}
|
||||
print('Fehler bei der speicherung: $error');
|
||||
});
|
||||
// bei true ein insert
|
||||
}
|
||||
}
|
||||
// Handle any other exceptions that might occur
|
||||
catch (e) {
|
||||
@ -259,6 +323,7 @@ class TankController extends GetxController {
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
duration: const Duration(seconds: 4),
|
||||
);
|
||||
goToTankStopsView();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -8,6 +8,7 @@ class TankPage extends GetView<TankController> {
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
var tankCtrl = controller;
|
||||
return SafeArea(
|
||||
child: Scaffold(
|
||||
appBar: AppBar(
|
||||
@ -126,7 +127,8 @@ class TankPage extends GetView<TankController> {
|
||||
SizedBox(
|
||||
width: 350,
|
||||
height: 50,
|
||||
child: ElevatedButton(
|
||||
child: Obx(
|
||||
() => ElevatedButton(
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: Colors.blue.withValues(
|
||||
alpha: 0.9,
|
||||
@ -140,9 +142,15 @@ class TankPage extends GetView<TankController> {
|
||||
onPressed: () {
|
||||
controller.saveTankstopp();
|
||||
},
|
||||
child: Text(
|
||||
child: tankCtrl.isEditMode.value == true ? Text(
|
||||
'Tankstop erfassen',
|
||||
style: TextStyle(color: Colors.white, fontSize: 20),
|
||||
style:
|
||||
TextStyle(color: Colors.white, fontSize: 20),
|
||||
): Text(
|
||||
'Tankstop updaten',
|
||||
style: TextStyle(
|
||||
color: Colors.white, fontSize: 20),
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
|
||||
@ -36,7 +36,7 @@ class TanklistController extends GetxController {
|
||||
@override
|
||||
void onClose() {}
|
||||
|
||||
void getTankList() async {
|
||||
Future<void> getTankList() async {
|
||||
isloadingList(true);
|
||||
bool isErrorByLoading = false;
|
||||
String message = '';
|
||||
@ -45,8 +45,14 @@ class TanklistController extends GetxController {
|
||||
.listTankStops(szRxUserId.value)
|
||||
.then((tankListData) {
|
||||
if (tankListData.documents.isEmpty) {
|
||||
isErrorByLoading = true;
|
||||
isErrorByLoading = false;
|
||||
message = 'Leere Liste keine Daten vorhanden';
|
||||
isloadingList(false);
|
||||
rxTankListAlles.clear();
|
||||
rxTankListActualYear.clear();
|
||||
szRxSummeYearLiter('0.0');
|
||||
szRxSummePrice('0.0');
|
||||
update();
|
||||
return;
|
||||
}
|
||||
rxTankListAlles.clear();
|
||||
@ -64,6 +70,7 @@ class TanklistController extends GetxController {
|
||||
rxTankListActualYear.value = rxTankListAlles
|
||||
.where((tank) => tank.date.startsWith(szRxYear.value))
|
||||
.toList();
|
||||
// rxTankListActualYear.value = rxTankListAlles;
|
||||
//Summe Liter aktuelles Jahr*********
|
||||
szRxSummeYearLiter(
|
||||
rxTankListActualYear.fold<double>(0.0, (previousValue, element) {
|
||||
@ -72,10 +79,11 @@ class TanklistController extends GetxController {
|
||||
//Summe Preis aktuelles Jahr*********
|
||||
szRxSummePrice(
|
||||
rxTankListActualYear.fold<double>(0.0, (previousValue, element) {
|
||||
return previousValue + (double.tryParse(element.szSummePreis!) ?? 0.0);
|
||||
return previousValue +
|
||||
(double.tryParse(element.szSummePreis!) ?? 0.0);
|
||||
}).toStringAsFixed(2));
|
||||
|
||||
message = 'Liste wurde erfolgreich geladen';
|
||||
isErrorByLoading = false;
|
||||
}).catchError((error) {
|
||||
isErrorByLoading = true;
|
||||
if (error is AppwriteException) {
|
||||
@ -94,21 +102,20 @@ class TanklistController extends GetxController {
|
||||
}
|
||||
}
|
||||
String title = isErrorByLoading ? 'Fehler' : 'Erfolg';
|
||||
Get.snackbar(
|
||||
title,
|
||||
message,
|
||||
backgroundColor: isErrorByLoading ? Colors.red : Colors.green,
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
duration: const Duration(seconds: 4),
|
||||
);
|
||||
print('$title: $message');
|
||||
update();
|
||||
}
|
||||
|
||||
void goToUpdatePage() {
|
||||
void goToUpdatePage(AppWriteTankModel item) {
|
||||
var map = item.toMap();
|
||||
print('Go to Update Page with data: $map');
|
||||
// Go to Update Page
|
||||
Get.offAndToNamed(TankPage.namedRoute,
|
||||
arguments: {'from': 'Update', 'data': map});
|
||||
}
|
||||
|
||||
void goToInputPage() {
|
||||
Get.offAndToNamed(TankPage.namedRoute);
|
||||
Get.offAndToNamed(TankPage.namedRoute, arguments: {'from': 'Input'});
|
||||
}
|
||||
|
||||
void logoutSessionAndGoToLoginPage() async {
|
||||
@ -127,4 +134,30 @@ class TanklistController extends GetxController {
|
||||
void goToChartView() {
|
||||
Get.offAndToNamed(GraphPage.namedRoute);
|
||||
}
|
||||
|
||||
void deleteTankStop(String documentId) async {
|
||||
bool isErrorByLoading = false;
|
||||
String message = '';
|
||||
try {
|
||||
await _authRepository.deleteTankStop(documentId).then((response) async {
|
||||
await getTankList();
|
||||
message = 'Tankstopp wurde erfolgreich gelöscht';
|
||||
}).catchError((error) {
|
||||
isErrorByLoading = true;
|
||||
if (error is AppwriteException) {
|
||||
message = error.message!;
|
||||
} else {
|
||||
message = 'Uuups da ist was schief gelaufen';
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
isErrorByLoading = true;
|
||||
message = 'Fehler beim Löschen des Tankstopps';
|
||||
print('Error deleting tank stop: $e');
|
||||
}
|
||||
String title = isErrorByLoading ? 'Fehler' : 'Erfolg';
|
||||
print('$title: $message');
|
||||
}
|
||||
|
||||
void goToGasView() {}
|
||||
}
|
||||
|
||||
@ -22,6 +22,13 @@ class TanklistPage extends GetView<TanklistController> {
|
||||
actions: [
|
||||
IconButton(
|
||||
icon: Icon(Icons.add_chart, color: Colors.grey.shade300),
|
||||
onPressed: () async {
|
||||
// Handle go to Chart View
|
||||
tankListCtrl.goToGasView();
|
||||
},
|
||||
),
|
||||
IconButton(
|
||||
icon: Icon(Icons.local_gas_station_sharp, color: Colors.grey.shade300),
|
||||
onPressed: () async {
|
||||
// Handle go to Chart View
|
||||
tankListCtrl.goToChartView();
|
||||
@ -57,20 +64,30 @@ class TanklistPage extends GetView<TanklistController> {
|
||||
SizedBox(
|
||||
child: Column(
|
||||
children: [
|
||||
Text(tankListCtrl.szRxYear.value, style: TextStyle(fontSize: 25, color: Colors.orange)),
|
||||
Text(tankListCtrl.szRxYear.value,
|
||||
style: TextStyle(
|
||||
fontSize: 25, color: Colors.orange)),
|
||||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceAround,
|
||||
children: [
|
||||
Column(
|
||||
children: [
|
||||
Text('Jahresverbrauch', style: TextStyle(fontSize: 14)),
|
||||
Text( tankListCtrl.szRxSummeYearLiter.value, style: TextStyle(fontSize: 20, color: Colors.orange)),
|
||||
Text('Jahresverbrauch',
|
||||
style: TextStyle(fontSize: 14)),
|
||||
Text(tankListCtrl.szRxSummeYearLiter.value,
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
color: Colors.orange)),
|
||||
],
|
||||
),
|
||||
Column(
|
||||
children: [
|
||||
Text('Jahressumme', style: TextStyle(fontSize: 14)),
|
||||
Text(tankListCtrl.szRxSummePrice.value, style: TextStyle(fontSize: 20, color: Colors.orange)),
|
||||
Text('Jahressumme',
|
||||
style: TextStyle(fontSize: 14)),
|
||||
Text(tankListCtrl.szRxSummePrice.value,
|
||||
style: TextStyle(
|
||||
fontSize: 20,
|
||||
color: Colors.orange)),
|
||||
],
|
||||
),
|
||||
],
|
||||
@ -78,9 +95,12 @@ class TanklistPage extends GetView<TanklistController> {
|
||||
],
|
||||
),
|
||||
),
|
||||
Divider(color: Colors.grey.shade200, height: 0.0,),
|
||||
Divider(
|
||||
color: Colors.grey.shade200,
|
||||
height: 0.0,
|
||||
),
|
||||
Expanded(
|
||||
child: ListView.builder(
|
||||
child: tankListCtrl.rxTankListActualYear.isNotEmpty ? ListView.builder(
|
||||
padding: EdgeInsets.only(top: 8, bottom: 8),
|
||||
physics: const BouncingScrollPhysics(),
|
||||
itemBuilder: ((BuildContext context, int index) {
|
||||
@ -105,14 +125,27 @@ class TanklistPage extends GetView<TanklistController> {
|
||||
),
|
||||
],
|
||||
),
|
||||
child: MyListTileItem(listItem: item),
|
||||
child: MyListTileItem(
|
||||
listItem: item,
|
||||
onPressedEdit: () {
|
||||
tankListCtrl.goToUpdatePage(item);
|
||||
},
|
||||
onPressedDelete: () {
|
||||
tankListCtrl.deleteTankStop(item.documentId);
|
||||
},
|
||||
),
|
||||
),
|
||||
SizedBox(height: 15),
|
||||
],
|
||||
);
|
||||
}),
|
||||
itemCount: tankListCtrl.rxTankListActualYear.length,
|
||||
):Expanded(child: Center(
|
||||
child: Text('Keine Einträge für das aktuelle Jahr vorhanden',
|
||||
style: TextStyle(
|
||||
fontSize: 18, color: Colors.grey.shade600)),
|
||||
),
|
||||
)
|
||||
),
|
||||
],
|
||||
),
|
||||
|
||||
@ -2,11 +2,13 @@ import 'package:flutter/material.dart';
|
||||
|
||||
import '../../../data/models/tank_model.dart';
|
||||
|
||||
|
||||
class MyListTileItem extends StatelessWidget {
|
||||
const MyListTileItem({super.key, required this.listItem});
|
||||
const MyListTileItem(
|
||||
{super.key, required this.listItem, required this.onPressedEdit, required this.onPressedDelete});
|
||||
|
||||
final AppWriteTankModel listItem;
|
||||
final void Function()? onPressedEdit;
|
||||
final void Function()? onPressedDelete;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
@ -72,7 +74,8 @@ class MyListTileItem extends StatelessWidget {
|
||||
children: [
|
||||
Icon(Icons.price_change),
|
||||
SizedBox(width: 10),
|
||||
Text('${listItem.szSummePreis} €', style: TextStyle(color: textColor, fontSize: 25)),
|
||||
Text('${listItem.szSummePreis} €',
|
||||
style: TextStyle(color: textColor, fontSize: 25)),
|
||||
],
|
||||
),
|
||||
Divider(thickness: 1, color: Colors.black),
|
||||
@ -89,6 +92,38 @@ class MyListTileItem extends StatelessWidget {
|
||||
),
|
||||
],
|
||||
),
|
||||
Divider(thickness: 1, color: Colors.black),
|
||||
Wrap(
|
||||
spacing: 10,
|
||||
children: [
|
||||
ElevatedButton.icon(
|
||||
onPressed: onPressedEdit,
|
||||
label: Text(
|
||||
'Edit',
|
||||
style: TextStyle(color: Colors.grey.shade200),
|
||||
),
|
||||
icon: const Icon(Icons.edit),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color.fromARGB(255, 3, 71, 128),
|
||||
foregroundColor: Colors.grey.shade200,
|
||||
shadowColor: Colors.white,
|
||||
),
|
||||
),
|
||||
ElevatedButton.icon(
|
||||
onPressed: onPressedDelete,
|
||||
label: Text(
|
||||
'Delete',
|
||||
style: TextStyle(color: Colors.grey.shade200),
|
||||
),
|
||||
icon: const Icon(Icons.delete),
|
||||
style: ElevatedButton.styleFrom(
|
||||
backgroundColor: const Color.fromARGB(255, 128, 3, 45),
|
||||
foregroundColor: Colors.grey.shade200,
|
||||
shadowColor: Colors.white,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user