2025-10-28 14:01:34 +01:00

228 lines
6.8 KiB
Dart

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<account_models.Account>();
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<user_models.User>();
final formKey = GlobalKey<FormState>();
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<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,
);
// 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<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,
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<void> 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);
}
}