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 {
|
||||
@override
|
||||
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:geolocator/geolocator.dart';
|
||||
import '../../services/geolocation.dart';
|
||||
@ -34,7 +35,7 @@ class GeolocationController extends GetxController {
|
||||
_statusText.value = 'Position wird ermittelt...';
|
||||
|
||||
Position? position = await GeolocationService.getCurrentPosition();
|
||||
|
||||
|
||||
if (position != null) {
|
||||
_currentPosition.value = position;
|
||||
_statusText.value = GeolocationService.positionToString(position);
|
||||
@ -42,20 +43,15 @@ class GeolocationController extends GetxController {
|
||||
latitude: position.latitude,
|
||||
longitude: position.longitude,
|
||||
);
|
||||
if(resultData != null) {
|
||||
if (resultData != null) {
|
||||
_ptvModel.value = PTVModel.fromJson(resultData);
|
||||
} else {
|
||||
_ptvModel.value = null;
|
||||
}
|
||||
// Erfolgs-Snackbar anzeigen
|
||||
Get.snackbar(
|
||||
'Position ermittelt',
|
||||
'Aktuelle Position wurde erfolgreich abgerufen',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
);
|
||||
debugPrint('Position ermittelt: ${_currentPosition.value}');
|
||||
} else {
|
||||
_statusText.value = 'Position konnte nicht ermittelt werden';
|
||||
|
||||
debugPrint('Fehler beim Abrufen der Position');
|
||||
// Fehler-Snackbar anzeigen
|
||||
Get.snackbar(
|
||||
'Fehler',
|
||||
@ -65,7 +61,7 @@ class GeolocationController extends GetxController {
|
||||
}
|
||||
} catch (e) {
|
||||
_statusText.value = 'Fehler beim Abrufen der Position: $e';
|
||||
|
||||
|
||||
Get.snackbar(
|
||||
'Fehler',
|
||||
'Unerwarteter Fehler: $e',
|
||||
@ -92,7 +88,7 @@ class GeolocationController extends GetxController {
|
||||
onError: (String error) {
|
||||
_statusText.value = 'Tracking Fehler: $error';
|
||||
_isTracking.value = false;
|
||||
|
||||
|
||||
Get.snackbar(
|
||||
'Tracking Fehler',
|
||||
error,
|
||||
@ -106,7 +102,7 @@ class GeolocationController extends GetxController {
|
||||
if (success) {
|
||||
_isTracking.value = true;
|
||||
_statusText.value = 'Tracking aktiv - Warten auf erste Position...';
|
||||
|
||||
|
||||
Get.snackbar(
|
||||
'Tracking gestartet',
|
||||
'Position wird kontinuierlich überwacht',
|
||||
@ -114,7 +110,7 @@ class GeolocationController extends GetxController {
|
||||
);
|
||||
} else {
|
||||
_statusText.value = 'Tracking konnte nicht gestartet werden';
|
||||
|
||||
|
||||
Get.snackbar(
|
||||
'Fehler',
|
||||
'Tracking konnte nicht gestartet werden',
|
||||
@ -123,7 +119,7 @@ class GeolocationController extends GetxController {
|
||||
}
|
||||
} catch (e) {
|
||||
_statusText.value = 'Fehler beim Starten des Trackings: $e';
|
||||
|
||||
|
||||
Get.snackbar(
|
||||
'Fehler',
|
||||
'Tracking-Fehler: $e',
|
||||
@ -142,7 +138,7 @@ class GeolocationController extends GetxController {
|
||||
await GeolocationService.stopPositionStream();
|
||||
_isTracking.value = false;
|
||||
_statusText.value = 'Tracking gestoppt';
|
||||
|
||||
|
||||
Get.snackbar(
|
||||
'Tracking gestoppt',
|
||||
'Position wird nicht mehr überwacht',
|
||||
@ -172,14 +168,17 @@ class GeolocationController extends GetxController {
|
||||
_isLoading.value = true;
|
||||
_statusText.value = 'Berechtigungen werden geprüft...';
|
||||
|
||||
LocationPermission permission = await GeolocationService.checkPermission();
|
||||
LocationPermission permission =
|
||||
await GeolocationService.checkPermission();
|
||||
bool serviceEnabled = await GeolocationService.isLocationServiceEnabled();
|
||||
|
||||
_statusText.value = 'Service aktiv: $serviceEnabled\n'
|
||||
'Berechtigung: ${LocationPermissionHelper.getPermissionStatusText(permission)}';
|
||||
|
||||
_statusText.value =
|
||||
'Service aktiv: $serviceEnabled\n'
|
||||
'Berechtigung: ${LocationPermissionHelper.getPermissionStatusText(permission)}';
|
||||
|
||||
// Detaillierte Information in Snackbar
|
||||
String permissionStatus = LocationPermissionHelper.getPermissionStatusText(permission);
|
||||
String permissionStatus =
|
||||
LocationPermissionHelper.getPermissionStatusText(permission);
|
||||
Get.snackbar(
|
||||
'Berechtigungs-Status',
|
||||
'Location Service: ${serviceEnabled ? "Aktiv" : "Inaktiv"}\n$permissionStatus',
|
||||
@ -188,7 +187,7 @@ class GeolocationController extends GetxController {
|
||||
);
|
||||
} catch (e) {
|
||||
_statusText.value = 'Fehler beim Prüfen der Berechtigungen: $e';
|
||||
|
||||
|
||||
Get.snackbar(
|
||||
'Fehler',
|
||||
'Berechtigungen konnten nicht geprüft werden: $e',
|
||||
@ -203,7 +202,7 @@ class GeolocationController extends GetxController {
|
||||
Future<void> openLocationSettings() async {
|
||||
try {
|
||||
bool opened = await GeolocationService.openLocationSettings();
|
||||
|
||||
|
||||
if (opened) {
|
||||
Get.snackbar(
|
||||
'Einstellungen geöffnet',
|
||||
@ -230,7 +229,7 @@ class GeolocationController extends GetxController {
|
||||
Future<void> openAppSettings() async {
|
||||
try {
|
||||
bool opened = await GeolocationService.openAppSettings();
|
||||
|
||||
|
||||
if (opened) {
|
||||
Get.snackbar(
|
||||
'Einstellungen geöffnet',
|
||||
@ -279,4 +278,4 @@ class GeolocationController extends GetxController {
|
||||
_isTracking.value = false;
|
||||
_isLoading.value = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -8,33 +8,76 @@ import '../routes/app_routes.dart';
|
||||
|
||||
class InputController extends GetxController {
|
||||
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 _user = (Get.arguments as user_models.User).obs;
|
||||
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;
|
||||
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
|
||||
void onInit() {
|
||||
_initController();
|
||||
_getLocation();
|
||||
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
|
||||
void onReady() {}
|
||||
|
||||
@override
|
||||
void onClose() {
|
||||
// Dispose aller TextEditingController
|
||||
dateController.dispose();
|
||||
odometerController.dispose();
|
||||
litersController.dispose();
|
||||
pricePerLiterController.dispose();
|
||||
locationController.dispose();
|
||||
sumPriceController.dispose();
|
||||
|
||||
geoCtrl.onClose();
|
||||
loginCtrl.onClose();
|
||||
// LoginController nicht schließen da er permanent sein könnte
|
||||
super.onClose();
|
||||
}
|
||||
|
||||
void _getLocation() async {
|
||||
await geoCtrl.getCurrentPosition().then(
|
||||
(_) => {_ptvModel.value = geoCtrl.ptvModel},
|
||||
(_) => {
|
||||
_ptvModel.value = geoCtrl.ptvModel,
|
||||
locationController.text = geoCtrl.ptvModel?.locations?.first.formattedAddress ?? '',
|
||||
},
|
||||
);
|
||||
update();
|
||||
}
|
||||
@ -43,9 +86,43 @@ class InputController extends GetxController {
|
||||
//AppNavigation.goToListPage
|
||||
}
|
||||
|
||||
void logout() {
|
||||
loginCtrl.logout();
|
||||
//AppNavigation.toLogin();
|
||||
AppNavigation.offAllToLogin();
|
||||
void logout() async {
|
||||
// Zeige Loading um weitere Interaktionen zu verhindern
|
||||
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();
|
||||
|
||||
} 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;
|
||||
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
|
||||
void onInit() {
|
||||
// Initialisiere TextEditingController
|
||||
@ -71,6 +88,17 @@ class LoginController extends GetxController {
|
||||
Future<void> login() async {
|
||||
logout();
|
||||
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(
|
||||
email: mailController.text,
|
||||
password: passwordController.text,
|
||||
@ -107,13 +135,30 @@ class LoginController extends GetxController {
|
||||
}
|
||||
|
||||
clearFields() {
|
||||
mailController.clear();
|
||||
passwordController.clear();
|
||||
nameController.clear();
|
||||
try {
|
||||
if (_isControllerValid(mailController)) mailController.clear();
|
||||
if (_isControllerValid(passwordController)) passwordController.clear();
|
||||
if (_isControllerValid(nameController)) nameController.clear();
|
||||
} catch (e) {
|
||||
// Ignore dispose errors beim Clearing
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> register() async {
|
||||
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(
|
||||
userId: ID.unique(),
|
||||
email: mailController.text,
|
||||
@ -142,14 +187,30 @@ class LoginController extends GetxController {
|
||||
}
|
||||
|
||||
Future<void> logout() async {
|
||||
await _account.value!.deleteSession(sessionId: 'current');
|
||||
_logedInUser.value = null;
|
||||
Get.snackbar(
|
||||
'Erfolg',
|
||||
'Logout erfolgreich',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
backgroundColor: Colors.red.shade500,
|
||||
);
|
||||
try {
|
||||
await _account.value!.deleteSession(sessionId: 'current');
|
||||
_logedInUser.value = null;
|
||||
|
||||
// Erfolgsmeldung nur wenn noch nicht navigiert wurde
|
||||
if (Get.currentRoute != '/login') {
|
||||
Get.snackbar(
|
||||
'Erfolg',
|
||||
'Logout erfolgreich',
|
||||
snackPosition: SnackPosition.BOTTOM,
|
||||
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
|
||||
|
||||
@ -45,7 +45,8 @@ class InputPage extends GetView<InputController> {
|
||||
children: [
|
||||
Obx(
|
||||
() => 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'),
|
||||
),
|
||||
|
||||
@ -18,8 +18,36 @@ class MyFormField extends StatelessWidget {
|
||||
final TextInputType keyboardType;
|
||||
final String? Function(String?)? validator;
|
||||
|
||||
// Prüft ob Controller noch verwendbar ist
|
||||
bool _isControllerValid() {
|
||||
try {
|
||||
userController.text;
|
||||
return true;
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
@override
|
||||
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(
|
||||
autovalidateMode: AutovalidateMode.onUserInteraction,
|
||||
style: const TextStyle(color: Colors.black),
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user