// login_screen.dart // This file contains the LoginScreen widget, which handles user authentication (login and registration) and role selection. import 'package:flutter/material.dart'; import 'package:firebase_auth/firebase_auth.dart'; import 'package:cloud_firestore/cloud_firestore.dart'; /// The LoginScreen allows users to log in or register, and select their role (trainer or player). class LoginScreen extends StatefulWidget { final void Function() onLoginSuccess; const LoginScreen({super.key, required this.onLoginSuccess}); @override State createState() => _LoginScreenState(); } /// State for the LoginScreen, manages form state, authentication, and error handling. class _LoginScreenState extends State { final _formKey = GlobalKey(); final _emailController = TextEditingController(); final _passwordController = TextEditingController(); final _nameController = TextEditingController(); String? _error; bool _loading = false; bool _isLogin = true; bool _isTrainer = false; /// Handles login or registration when the form is submitted. Future _submit() async { setState(() { _loading = true; _error = null; }); try { if (_isLogin) { // Login try { UserCredential cred = await FirebaseAuth.instance.signInWithEmailAndPassword( email: _emailController.text.trim(), password: _passwordController.text.trim(), ); // Check if user profile exists in Firestore final uid = cred.user!.uid; final userDoc = await FirebaseFirestore.instance.collection('User').doc(uid).get(); if (userDoc.exists) { widget.onLoginSuccess(); } else { setState(() { _error = 'Kein Benutzerprofil in der Datenbank gefunden!'; }); await FirebaseAuth.instance.signOut(); } } catch (e) { rethrow; } } else { // Registration - Direct attempt to create user try { UserCredential cred = await FirebaseAuth.instance.createUserWithEmailAndPassword( email: _emailController.text.trim(), password: _passwordController.text.trim(), ); // Create user document in Firestore final uid = cred.user!.uid; await FirebaseFirestore.instance.collection('User').doc(uid).set({ 'email': _emailController.text.trim(), 'name': _nameController.text.trim(), 'role': _isTrainer ? 'trainer' : 'player', 'createdAt': FieldValue.serverTimestamp(), 'favorites': [], 'trainings': {}, 'cancelledTrainings': [], 'trainingTimes': {}, 'trainingDurations': {}, }); widget.onLoginSuccess(); } catch (e) { rethrow; } } } on FirebaseAuthException catch (e) { // Handle Firebase authentication errors String errorMessage; switch (e.code) { case 'user-not-found': errorMessage = 'Kein Benutzer mit dieser E-Mail-Adresse gefunden.'; break; case 'wrong-password': errorMessage = 'Falsches Passwort.'; break; case 'invalid-email': errorMessage = 'Ungültige E-Mail-Adresse.'; break; case 'user-disabled': errorMessage = 'Dieses Konto wurde deaktiviert.'; break; case 'email-already-in-use': errorMessage = 'Diese E-Mail-Adresse wird bereits verwendet. Bitte melde dich an oder verwende eine andere E-Mail-Adresse.'; break; case 'weak-password': errorMessage = 'Das Passwort ist zu schwach.'; break; case 'operation-not-allowed': errorMessage = 'Diese Aktion ist nicht erlaubt.'; break; default: errorMessage = 'Ein Fehler ist aufgetreten: ${e.message}'; } setState(() { _error = errorMessage; }); } catch (e) { setState(() { _error = 'Ein unerwarteter Fehler ist aufgetreten. Bitte versuche es später erneut.'; }); } finally { setState(() { _loading = false; }); } } @override Widget build(BuildContext context) { return Scaffold( body: Center( child: SingleChildScrollView( padding: const EdgeInsets.all(24), child: Form( key: _formKey, child: Column( mainAxisSize: MainAxisSize.min, children: [ // Title Text(_isLogin ? 'Anmeldung' : 'Registrieren', style: Theme.of(context).textTheme.headlineMedium), const SizedBox(height: 32), if (!_isLogin) ...[ // Name field for registration TextFormField( controller: _nameController, decoration: const InputDecoration(labelText: 'Name'), validator: (v) => v != null && v.trim().isNotEmpty ? null : 'Bitte gib deinen Namen ein', ), const SizedBox(height: 16), // Role selection Row( children: [ Checkbox( value: _isTrainer, onChanged: (v) { setState(() { _isTrainer = v ?? false; }); }, ), const Text('Ich bin Trainer'), const SizedBox(width: 16), Checkbox( value: !_isTrainer, onChanged: (v) { setState(() { _isTrainer = !(v ?? false); }); }, ), const Text('Ich bin Spieler'), ], ), const SizedBox(height: 16), ], // Email field TextFormField( controller: _emailController, decoration: const InputDecoration(labelText: 'E-Mail'), keyboardType: TextInputType.emailAddress, validator: (v) => v != null && v.contains('@') ? null : 'Bitte gib eine gültige E-Mail ein', ), const SizedBox(height: 16), // Password field TextFormField( controller: _passwordController, decoration: const InputDecoration(labelText: 'Passwort'), obscureText: true, validator: (v) => v != null && v.length >= 6 ? null : 'Mindestens 6 Zeichen', ), const SizedBox(height: 24), if (_error != null) ...[ // Error message Text(_error!, style: const TextStyle(color: Colors.red)), const SizedBox(height: 12), ], // Submit button SizedBox( width: double.infinity, child: ElevatedButton( onPressed: _loading ? null : () { if (_formKey.currentState!.validate()) { _submit(); } }, child: _loading ? const CircularProgressIndicator() : Text(_isLogin ? 'Anmelden' : 'Registrieren'), ), ), const SizedBox(height: 16), // Switch between login and registration TextButton( onPressed: _loading ? null : () { setState(() { _isLogin = !_isLogin; _error = null; }); }, child: Text(_isLogin ? 'Noch kein Konto? Jetzt registrieren!' : 'Schon registriert? Jetzt anmelden!'), ), ], ), ), ), ), ); } }