import 'package:firebase_auth/firebase_auth.dart'; import 'package:flutter/material.dart'; /// Screen 1: Login & Registrierung (E-Mail / Passwort) über Firebase Auth. class AuthScreen extends StatefulWidget { const AuthScreen({super.key}); @override State createState() => _AuthScreenState(); } class _AuthScreenState extends State with SingleTickerProviderStateMixin { late final TabController _tabController; final _loginEmail = TextEditingController(); final _loginPassword = TextEditingController(); final _regName = TextEditingController(); final _regEmail = TextEditingController(); final _regPassword = TextEditingController(); bool _loading = false; @override void initState() { super.initState(); _tabController = TabController(length: 2, vsync: this); } @override void dispose() { _tabController.dispose(); _loginEmail.dispose(); _loginPassword.dispose(); _regName.dispose(); _regEmail.dispose(); _regPassword.dispose(); super.dispose(); } void _snack(String text) { if (!mounted) return; ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(text))); } String _authMessage(FirebaseAuthException e) { switch (e.code) { case 'user-not-found': case 'wrong-password': case 'invalid-credential': return 'E-Mail oder Passwort ist falsch.'; case 'email-already-in-use': return 'Diese E-Mail ist bereits registriert.'; case 'weak-password': return 'Passwort ist zu schwach (mindestens 6 Zeichen).'; case 'invalid-email': return 'Ungültige E-Mail-Adresse.'; case 'network-request-failed': return 'Netzwerkfehler. Internet prüfen.'; default: return e.message ?? 'Fehler: ${e.code}'; } } Future _login() async { final email = _loginEmail.text.trim(); final password = _loginPassword.text; if (email.isEmpty || password.isEmpty) { _snack('E-Mail und Passwort eingeben.'); return; } setState(() => _loading = true); try { await FirebaseAuth.instance.signInWithEmailAndPassword( email: email, password: password, ); } on FirebaseAuthException catch (e) { _snack(_authMessage(e)); } catch (e) { _snack('Unerwarteter Fehler: $e'); } finally { if (mounted) setState(() => _loading = false); } } Future _register() async { final email = _regEmail.text.trim(); final password = _regPassword.text; final name = _regName.text.trim(); if (email.isEmpty || password.isEmpty) { _snack('E-Mail und Passwort eingeben.'); return; } if (password.length < 6) { _snack('Passwort mindestens 6 Zeichen (Firebase).'); return; } setState(() => _loading = true); try { final cred = await FirebaseAuth.instance.createUserWithEmailAndPassword( email: email, password: password, ); if (name.isNotEmpty && cred.user != null) { await cred.user!.updateDisplayName(name); } } on FirebaseAuthException catch (e) { _snack(_authMessage(e)); } catch (e) { _snack('Unerwarteter Fehler: $e'); } finally { if (mounted) setState(() => _loading = false); } } @override Widget build(BuildContext context) { final scheme = Theme.of(context).colorScheme; return Scaffold( body: SafeArea( child: ListView( padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 16), children: [ const SizedBox(height: 24), Icon(Icons.construction, size: 48, color: scheme.primary), const SizedBox(height: 16), Text( 'Handwerksapp', textAlign: TextAlign.center, style: Theme.of(context).textTheme.headlineMedium?.copyWith( fontWeight: FontWeight.bold, ), ), const SizedBox(height: 8), Text( 'Nach dem Login: Aufträge anlegen, Fotos, Kunden-Unterschrift, PDF teilen.\n' 'Zuerst: Konto anlegen oder anmelden.', textAlign: TextAlign.center, style: Theme.of(context).textTheme.bodyMedium?.copyWith( color: scheme.onSurfaceVariant, ), ), const SizedBox(height: 32), TabBar( controller: _tabController, tabs: const [ Tab(text: 'Anmelden'), Tab(text: 'Registrieren'), ], ), const SizedBox(height: 16), SizedBox( height: 320, child: TabBarView( controller: _tabController, children: [ _LoginForm( email: _loginEmail, password: _loginPassword, loading: _loading, onSubmit: _login, ), _RegisterForm( name: _regName, email: _regEmail, password: _regPassword, loading: _loading, onSubmit: _register, ), ], ), ), ], ), ), ); } } class _LoginForm extends StatelessWidget { const _LoginForm({ required this.email, required this.password, required this.loading, required this.onSubmit, }); final TextEditingController email; final TextEditingController password; final bool loading; final VoidCallback onSubmit; @override Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ TextField( controller: email, keyboardType: TextInputType.emailAddress, autocorrect: false, autofillHints: const [AutofillHints.email], decoration: const InputDecoration(labelText: 'E-Mail'), ), const SizedBox(height: 12), TextField( controller: password, obscureText: true, autofillHints: const [AutofillHints.password], decoration: const InputDecoration(labelText: 'Passwort'), onSubmitted: (_) => onSubmit(), ), const Spacer(), FilledButton( onPressed: loading ? null : onSubmit, child: loading ? const SizedBox( height: 22, width: 22, child: CircularProgressIndicator(strokeWidth: 2), ) : const Text('Anmelden'), ), ], ); } } class _RegisterForm extends StatelessWidget { const _RegisterForm({ required this.name, required this.email, required this.password, required this.loading, required this.onSubmit, }); final TextEditingController name; final TextEditingController email; final TextEditingController password; final bool loading; final VoidCallback onSubmit; @override Widget build(BuildContext context) { return Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ TextField( controller: name, textCapitalization: TextCapitalization.words, decoration: const InputDecoration( labelText: 'Firmen- oder Anzeigename', ), ), const SizedBox(height: 12), TextField( controller: email, keyboardType: TextInputType.emailAddress, autocorrect: false, autofillHints: const [AutofillHints.email], decoration: const InputDecoration(labelText: 'E-Mail'), ), const SizedBox(height: 12), TextField( controller: password, obscureText: true, autofillHints: const [AutofillHints.newPassword], decoration: const InputDecoration(labelText: 'Passwort (min. 6 Zeichen)'), ), const Spacer(), FilledButton( onPressed: loading ? null : onSubmit, child: loading ? const SizedBox( height: 22, width: 22, child: CircularProgressIndicator(strokeWidth: 2), ) : const Text('Konto erstellen'), ), ], ); } }