mod switch between pages and remove errors
This commit is contained in:
parent
059b4773f4
commit
461b07bf10
@ -4,7 +4,8 @@ import '../controllers/login_controller.dart';
|
|||||||
class LoginBinding extends Bindings {
|
class LoginBinding extends Bindings {
|
||||||
@override
|
@override
|
||||||
void dependencies() {
|
void dependencies() {
|
||||||
Get.lazyPut<LoginController>(() => LoginController());
|
// Permanent für bessere Controller-Stabilität
|
||||||
|
Get.put<LoginController>(LoginController(), permanent: true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,3 +1,4 @@
|
|||||||
|
import 'package:flutter/material.dart';
|
||||||
import 'package:get/get.dart';
|
import 'package:get/get.dart';
|
||||||
import 'package:geolocator/geolocator.dart';
|
import 'package:geolocator/geolocator.dart';
|
||||||
import '../../services/geolocation.dart';
|
import '../../services/geolocation.dart';
|
||||||
@ -42,20 +43,15 @@ class GeolocationController extends GetxController {
|
|||||||
latitude: position.latitude,
|
latitude: position.latitude,
|
||||||
longitude: position.longitude,
|
longitude: position.longitude,
|
||||||
);
|
);
|
||||||
if(resultData != null) {
|
if (resultData != null) {
|
||||||
_ptvModel.value = PTVModel.fromJson(resultData);
|
_ptvModel.value = PTVModel.fromJson(resultData);
|
||||||
} else {
|
} else {
|
||||||
_ptvModel.value = null;
|
_ptvModel.value = null;
|
||||||
}
|
}
|
||||||
// Erfolgs-Snackbar anzeigen
|
debugPrint('Position ermittelt: ${_currentPosition.value}');
|
||||||
Get.snackbar(
|
|
||||||
'Position ermittelt',
|
|
||||||
'Aktuelle Position wurde erfolgreich abgerufen',
|
|
||||||
snackPosition: SnackPosition.BOTTOM,
|
|
||||||
);
|
|
||||||
} else {
|
} else {
|
||||||
_statusText.value = 'Position konnte nicht ermittelt werden';
|
_statusText.value = 'Position konnte nicht ermittelt werden';
|
||||||
|
debugPrint('Fehler beim Abrufen der Position');
|
||||||
// Fehler-Snackbar anzeigen
|
// Fehler-Snackbar anzeigen
|
||||||
Get.snackbar(
|
Get.snackbar(
|
||||||
'Fehler',
|
'Fehler',
|
||||||
@ -172,14 +168,17 @@ class GeolocationController extends GetxController {
|
|||||||
_isLoading.value = true;
|
_isLoading.value = true;
|
||||||
_statusText.value = 'Berechtigungen werden geprüft...';
|
_statusText.value = 'Berechtigungen werden geprüft...';
|
||||||
|
|
||||||
LocationPermission permission = await GeolocationService.checkPermission();
|
LocationPermission permission =
|
||||||
|
await GeolocationService.checkPermission();
|
||||||
bool serviceEnabled = await GeolocationService.isLocationServiceEnabled();
|
bool serviceEnabled = await GeolocationService.isLocationServiceEnabled();
|
||||||
|
|
||||||
_statusText.value = 'Service aktiv: $serviceEnabled\n'
|
_statusText.value =
|
||||||
|
'Service aktiv: $serviceEnabled\n'
|
||||||
'Berechtigung: ${LocationPermissionHelper.getPermissionStatusText(permission)}';
|
'Berechtigung: ${LocationPermissionHelper.getPermissionStatusText(permission)}';
|
||||||
|
|
||||||
// Detaillierte Information in Snackbar
|
// Detaillierte Information in Snackbar
|
||||||
String permissionStatus = LocationPermissionHelper.getPermissionStatusText(permission);
|
String permissionStatus =
|
||||||
|
LocationPermissionHelper.getPermissionStatusText(permission);
|
||||||
Get.snackbar(
|
Get.snackbar(
|
||||||
'Berechtigungs-Status',
|
'Berechtigungs-Status',
|
||||||
'Location Service: ${serviceEnabled ? "Aktiv" : "Inaktiv"}\n$permissionStatus',
|
'Location Service: ${serviceEnabled ? "Aktiv" : "Inaktiv"}\n$permissionStatus',
|
||||||
|
|||||||
@ -8,33 +8,76 @@ import '../routes/app_routes.dart';
|
|||||||
|
|
||||||
class InputController extends GetxController {
|
class InputController extends GetxController {
|
||||||
final GeolocationController geoCtrl = Get.put(GeolocationController());
|
final GeolocationController geoCtrl = Get.put(GeolocationController());
|
||||||
final LoginController loginCtrl = Get.put(LoginController());
|
// Lazy-get für LoginController - wird nur erstellt wenn benötigt
|
||||||
|
LoginController get loginCtrl => Get.find<LoginController>();
|
||||||
final _ptvModel = Rxn<PTVModel>();
|
final _ptvModel = Rxn<PTVModel>();
|
||||||
final _user = (Get.arguments as user_models.User).obs;
|
final _user = (Get.arguments as user_models.User).obs;
|
||||||
final formKey = GlobalKey<FormState>();
|
final formKey = GlobalKey<FormState>();
|
||||||
|
late TextEditingController dateController;
|
||||||
|
late TextEditingController odometerController;
|
||||||
|
late TextEditingController litersController;
|
||||||
|
late TextEditingController pricePerLiterController;
|
||||||
|
late TextEditingController locationController;
|
||||||
|
late TextEditingController sumPriceController;
|
||||||
|
|
||||||
PTVModel? get ptvModel => _ptvModel.value;
|
PTVModel? get ptvModel => _ptvModel.value;
|
||||||
user_models.User? get currentUser => _user.value;
|
user_models.User? get currentUser => _user.value;
|
||||||
|
|
||||||
|
// Sichere Getter für Controller-Text
|
||||||
|
String get safeDate => _isControllerValid(dateController) ? dateController.text : '';
|
||||||
|
String get safeLocation => _isControllerValid(locationController) ? locationController.text : '';
|
||||||
|
|
||||||
|
// Hilfsmethode zur Controller-Validierung
|
||||||
|
bool _isControllerValid(TextEditingController? controller) {
|
||||||
|
try {
|
||||||
|
return controller != null && controller.text.isNotEmpty;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
|
_initController();
|
||||||
_getLocation();
|
_getLocation();
|
||||||
super.onInit();
|
super.onInit();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void _initController() {
|
||||||
|
dateController = TextEditingController();
|
||||||
|
odometerController = TextEditingController();
|
||||||
|
litersController = TextEditingController();
|
||||||
|
pricePerLiterController = TextEditingController();
|
||||||
|
locationController = TextEditingController();
|
||||||
|
sumPriceController = TextEditingController();
|
||||||
|
// init Date today to dateController
|
||||||
|
dateController.text = DateTime.now().toString().split(' ').first;
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onReady() {}
|
void onReady() {}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onClose() {
|
void onClose() {
|
||||||
|
// Dispose aller TextEditingController
|
||||||
|
dateController.dispose();
|
||||||
|
odometerController.dispose();
|
||||||
|
litersController.dispose();
|
||||||
|
pricePerLiterController.dispose();
|
||||||
|
locationController.dispose();
|
||||||
|
sumPriceController.dispose();
|
||||||
|
|
||||||
geoCtrl.onClose();
|
geoCtrl.onClose();
|
||||||
loginCtrl.onClose();
|
// LoginController nicht schließen da er permanent sein könnte
|
||||||
super.onClose();
|
super.onClose();
|
||||||
}
|
}
|
||||||
|
|
||||||
void _getLocation() async {
|
void _getLocation() async {
|
||||||
await geoCtrl.getCurrentPosition().then(
|
await geoCtrl.getCurrentPosition().then(
|
||||||
(_) => {_ptvModel.value = geoCtrl.ptvModel},
|
(_) => {
|
||||||
|
_ptvModel.value = geoCtrl.ptvModel,
|
||||||
|
locationController.text = geoCtrl.ptvModel?.locations?.first.formattedAddress ?? '',
|
||||||
|
},
|
||||||
);
|
);
|
||||||
update();
|
update();
|
||||||
}
|
}
|
||||||
@ -43,9 +86,43 @@ class InputController extends GetxController {
|
|||||||
//AppNavigation.goToListPage
|
//AppNavigation.goToListPage
|
||||||
}
|
}
|
||||||
|
|
||||||
void logout() {
|
void logout() async {
|
||||||
loginCtrl.logout();
|
// Zeige Loading um weitere Interaktionen zu verhindern
|
||||||
//AppNavigation.toLogin();
|
Get.dialog(
|
||||||
|
const Center(
|
||||||
|
child: CircularProgressIndicator(),
|
||||||
|
),
|
||||||
|
barrierDismissible: false,
|
||||||
|
);
|
||||||
|
|
||||||
|
try {
|
||||||
|
// Kurze Verzögerung um sicherzustellen dass UI Updates verarbeitet werden
|
||||||
|
await Future.delayed(const Duration(milliseconds: 100));
|
||||||
|
|
||||||
|
// Logout ausführen
|
||||||
|
await loginCtrl.logout();
|
||||||
|
|
||||||
|
// Dialog schließen
|
||||||
|
if (Get.isDialogOpen == true) {
|
||||||
|
Get.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Navigation nach kurzer Verzögerung
|
||||||
|
await Future.delayed(const Duration(milliseconds: 100));
|
||||||
AppNavigation.offAllToLogin();
|
AppNavigation.offAllToLogin();
|
||||||
|
|
||||||
|
} catch (e) {
|
||||||
|
// Dialog schließen bei Fehler
|
||||||
|
if (Get.isDialogOpen == true) {
|
||||||
|
Get.back();
|
||||||
|
}
|
||||||
|
|
||||||
|
Get.snackbar(
|
||||||
|
'Fehler',
|
||||||
|
'Logout fehlgeschlagen: $e',
|
||||||
|
snackPosition: SnackPosition.BOTTOM,
|
||||||
|
backgroundColor: Colors.red.shade500,
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -24,6 +24,23 @@ class LoginController extends GetxController {
|
|||||||
account_models.Account? get account => _account.value;
|
account_models.Account? get account => _account.value;
|
||||||
user_models.User? get logedInUser => _logedInUser.value;
|
user_models.User? get logedInUser => _logedInUser.value;
|
||||||
|
|
||||||
|
// Sichere Getter für Controller
|
||||||
|
String get safeEmail => _isControllerValid(mailController) ? mailController.text : '';
|
||||||
|
String get safePassword => _isControllerValid(passwordController) ? passwordController.text : '';
|
||||||
|
String get safeName => _isControllerValid(nameController) ? nameController.text : '';
|
||||||
|
|
||||||
|
// Hilfsmethode zur Controller-Validierung
|
||||||
|
bool _isControllerValid(TextEditingController? controller) {
|
||||||
|
try {
|
||||||
|
if (controller == null) return false;
|
||||||
|
// Teste ob der Controller noch verwendbar ist
|
||||||
|
controller.text;
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onInit() {
|
void onInit() {
|
||||||
// Initialisiere TextEditingController
|
// Initialisiere TextEditingController
|
||||||
@ -71,6 +88,17 @@ class LoginController extends GetxController {
|
|||||||
Future<void> login() async {
|
Future<void> login() async {
|
||||||
logout();
|
logout();
|
||||||
try {
|
try {
|
||||||
|
// Sichere Controller-Zugriffe
|
||||||
|
if (!_isControllerValid(mailController) || !_isControllerValid(passwordController)) {
|
||||||
|
Get.snackbar(
|
||||||
|
'Fehler',
|
||||||
|
'Formular nicht verfügbar. Bitte laden Sie die Seite neu.',
|
||||||
|
snackPosition: SnackPosition.BOTTOM,
|
||||||
|
backgroundColor: Colors.red.shade500,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
var result = await _account.value!.createEmailPasswordSession(
|
var result = await _account.value!.createEmailPasswordSession(
|
||||||
email: mailController.text,
|
email: mailController.text,
|
||||||
password: passwordController.text,
|
password: passwordController.text,
|
||||||
@ -107,13 +135,30 @@ class LoginController extends GetxController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
clearFields() {
|
clearFields() {
|
||||||
mailController.clear();
|
try {
|
||||||
passwordController.clear();
|
if (_isControllerValid(mailController)) mailController.clear();
|
||||||
nameController.clear();
|
if (_isControllerValid(passwordController)) passwordController.clear();
|
||||||
|
if (_isControllerValid(nameController)) nameController.clear();
|
||||||
|
} catch (e) {
|
||||||
|
// Ignore dispose errors beim Clearing
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Future<void> register() async {
|
Future<void> register() async {
|
||||||
try {
|
try {
|
||||||
|
// Sichere Controller-Zugriffe
|
||||||
|
if (!_isControllerValid(mailController) ||
|
||||||
|
!_isControllerValid(passwordController) ||
|
||||||
|
!_isControllerValid(nameController)) {
|
||||||
|
Get.snackbar(
|
||||||
|
'Fehler',
|
||||||
|
'Formular nicht verfügbar. Bitte laden Sie die Seite neu.',
|
||||||
|
snackPosition: SnackPosition.BOTTOM,
|
||||||
|
backgroundColor: Colors.red.shade500,
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
await _account.value!.create(
|
await _account.value!.create(
|
||||||
userId: ID.unique(),
|
userId: ID.unique(),
|
||||||
email: mailController.text,
|
email: mailController.text,
|
||||||
@ -142,15 +187,31 @@ class LoginController extends GetxController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Future<void> logout() async {
|
Future<void> logout() async {
|
||||||
|
try {
|
||||||
await _account.value!.deleteSession(sessionId: 'current');
|
await _account.value!.deleteSession(sessionId: 'current');
|
||||||
_logedInUser.value = null;
|
_logedInUser.value = null;
|
||||||
|
|
||||||
|
// Erfolgsmeldung nur wenn noch nicht navigiert wurde
|
||||||
|
if (Get.currentRoute != '/login') {
|
||||||
Get.snackbar(
|
Get.snackbar(
|
||||||
'Erfolg',
|
'Erfolg',
|
||||||
'Logout erfolgreich',
|
'Logout erfolgreich',
|
||||||
snackPosition: SnackPosition.BOTTOM,
|
snackPosition: SnackPosition.BOTTOM,
|
||||||
backgroundColor: Colors.red.shade500,
|
backgroundColor: Colors.green.shade500,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
} catch (e) {
|
||||||
|
if (Get.currentRoute != '/login') {
|
||||||
|
Get.snackbar(
|
||||||
|
'Meldung',
|
||||||
|
'Keine aktive Sitzung zum Abmelden',
|
||||||
|
snackPosition: SnackPosition.BOTTOM,
|
||||||
|
backgroundColor: Colors.orange.shade500,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
debugPrint('Logout error: $e');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
void onClose() {
|
void onClose() {
|
||||||
|
|||||||
@ -45,7 +45,8 @@ class InputPage extends GetView<InputController> {
|
|||||||
children: [
|
children: [
|
||||||
Obx(
|
Obx(
|
||||||
() => inputCtrl.ptvModel != null && inputCtrl.currentUser != null
|
() => inputCtrl.ptvModel != null && inputCtrl.currentUser != null
|
||||||
? Text('UserEmail: ${inputCtrl.currentUser!.email}\nName: ${inputCtrl.currentUser!.name}\nFormattedAddress: ${inputCtrl.ptvModel!.locations!.first.formattedAddress}',
|
? Text(
|
||||||
|
'DateNow: ${inputCtrl.safeDate}\nUserEmail: ${inputCtrl.currentUser!.email}\nName: ${inputCtrl.currentUser!.name}\nFormattedAddress: ${inputCtrl.safeLocation}',
|
||||||
)
|
)
|
||||||
: const Text('Keine Daten gefunden'),
|
: const Text('Keine Daten gefunden'),
|
||||||
),
|
),
|
||||||
|
|||||||
@ -18,8 +18,36 @@ class MyFormField extends StatelessWidget {
|
|||||||
final TextInputType keyboardType;
|
final TextInputType keyboardType;
|
||||||
final String? Function(String?)? validator;
|
final String? Function(String?)? validator;
|
||||||
|
|
||||||
|
// Prüft ob Controller noch verwendbar ist
|
||||||
|
bool _isControllerValid() {
|
||||||
|
try {
|
||||||
|
userController.text;
|
||||||
|
return true;
|
||||||
|
} catch (e) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@override
|
@override
|
||||||
Widget build(BuildContext context) {
|
Widget build(BuildContext context) {
|
||||||
|
// Wenn Controller disposed ist, zeige Ersatz-Widget
|
||||||
|
if (!_isControllerValid()) {
|
||||||
|
return Container(
|
||||||
|
height: 56,
|
||||||
|
decoration: BoxDecoration(
|
||||||
|
color: fillColor,
|
||||||
|
borderRadius: BorderRadius.circular(4),
|
||||||
|
border: Border.all(color: Colors.grey),
|
||||||
|
),
|
||||||
|
child: Center(
|
||||||
|
child: Text(
|
||||||
|
'$labelText (Controller nicht verfügbar)',
|
||||||
|
style: TextStyle(color: Colors.grey[600]),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
return TextFormField(
|
return TextFormField(
|
||||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||||
style: const TextStyle(color: Colors.black),
|
style: const TextStyle(color: Colors.black),
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user