import 'package:appwrite/appwrite.dart' as account_models; import 'package:appwrite/models.dart' as user_models; import 'package:flutter/material.dart'; import 'package:get/get.dart'; import 'package:appwrite/appwrite.dart'; import 'package:flutter_dotenv/flutter_dotenv.dart'; import 'package:flutter/foundation.dart'; import '../routes/app_routes.dart'; class LoginController extends GetxController { final _account = Rxn(); late TextEditingController mailController; late TextEditingController passwordController; late TextEditingController nameController; final _endpoint = dotenv.env['APPWRITE_ENDPOINT_URL'] ?? ''; final _projectId = dotenv.env['APPWRITE_PROJECT_ID'] ?? ''; final bool _selfSigned = (dotenv.env['APPWRITE_SELF_SIGNED'] ?? 'false').toLowerCase() == 'true'; final _logedInUser = Rxn(); final formKey = GlobalKey(); final isLogIn = false.obs; 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 mailController = TextEditingController(); passwordController = TextEditingController(); nameController = TextEditingController(); // Initialisiere Client Client client = Client().setEndpoint(_endpoint).setProject(_projectId); // Optional: Unsichere/self-signed Zertifikate im Dev zulassen (nicht im Web wirksam) if (!kIsWeb && _selfSigned) { client.setSelfSigned(status: true); } _account.value = Account(client); super.onInit(); } emailValidator(String? value) { if (value == null || value.isEmpty) { return 'Please enter your email'; } final emailRegex = RegExp(r'^[^@]+@[^@]+\.[^@]+'); if (!emailRegex.hasMatch(value)) { return 'Please enter a valid email address'; } return null; } passwordValidator(String? value) { if (value == null || value.isEmpty) { return 'Please enter your password'; } if (value.length < 6) { return 'Password must be at least 6 characters long'; } return null; } nameValidator(String? value) { if (value == null || value.isEmpty) { return 'Please enter your name'; } return null; } Future 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, ); // ignore: avoid_print print('Login result: $result'); final user = await _account.value!.get(); _logedInUser.value = user; clearFields(); goToInput(user); Get.snackbar( 'Erfolg', 'Anmeldung erfolgreich ${user.name}, ID: ${user.$id}', snackPosition: SnackPosition.BOTTOM, ); } on AppwriteException catch (e) { final msg = (e.message == null || e.message!.isEmpty) ? 'Verbindungsfehler. Prüfe Zertifikat/Endpoint.' : e.message!; Get.snackbar( 'Login fehlgeschlagen', msg, snackPosition: SnackPosition.BOTTOM, duration: const Duration(seconds: 5), ); } catch (e) { Get.snackbar( 'Login fehlgeschlagen', e.toString(), snackPosition: SnackPosition.BOTTOM, duration: const Duration(seconds: 5), ); } } clearFields() { try { if (_isControllerValid(mailController)) mailController.clear(); if (_isControllerValid(passwordController)) passwordController.clear(); if (_isControllerValid(nameController)) nameController.clear(); } catch (e) { // Ignore dispose errors beim Clearing } } Future 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, password: passwordController.text, name: nameController.text, ); await login(); } on AppwriteException catch (e) { final msg = (e.message == null || e.message!.isEmpty) ? 'Registrierung fehlgeschlagen. Prüfe Verbindung.' : e.message!; Get.snackbar( 'Registrierung fehlgeschlagen', msg, snackPosition: SnackPosition.BOTTOM, duration: const Duration(seconds: 5), ); } catch (e) { Get.snackbar( 'Registrierung fehlgeschlagen', e.toString(), snackPosition: SnackPosition.BOTTOM, duration: const Duration(seconds: 5), ); } } Future logout() async { 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 void onClose() { mailController.dispose(); passwordController.dispose(); nameController.dispose(); super.onClose(); } void goToInput(Object args) { AppNavigation.toInputPageWithArgs(args); } }