import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:flutter_animate/flutter_animate.dart'; import '../../../providers/auth_provider.dart'; import '../../../core/theme/app_theme.dart'; import '../../../core/utils/validators.dart'; import '../../../core/constants/app_constants.dart'; class LoginScreen extends ConsumerStatefulWidget { const LoginScreen({super.key}); @override ConsumerState createState() => _LoginScreenState(); } class _LoginScreenState extends ConsumerState { final _formKey = GlobalKey(); final _emailController = TextEditingController(); final _passwordController = TextEditingController(); bool _obscurePassword = true; @override void dispose() { _emailController.dispose(); _passwordController.dispose(); super.dispose(); } @override Widget build(BuildContext context) { final authState = ref.watch(authProvider); final authNotifier = ref.read(authProvider.notifier); ref.listen(authProvider, (_, state) { if (state.status == AuthStatus.authenticated) { context.go('/'); } if (state.needsTwoFactor) { context.push('/auth/2fa'); } }); return Scaffold( body: SafeArea( child: SingleChildScrollView( padding: const EdgeInsets.all(24), child: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const SizedBox(height: 60), Icon( Icons.lightbulb_outline, size: 64, color: VoIdeaColors.primary, ).animate().fadeIn().scale(), const SizedBox(height: 16), Text( AppConstants.appName, textAlign: TextAlign.center, style: Theme.of(context).textTheme.headlineMedium?.copyWith( fontWeight: FontWeight.bold, color: VoIdeaColors.primary, ), ).animate().fadeIn(delay: 100.ms), const SizedBox(height: 8), Text( 'Войдите в аккаунт', textAlign: TextAlign.center, style: Theme.of(context).textTheme.bodyLarge?.copyWith( color: VoIdeaColors.muted, ), ).animate().fadeIn(delay: 200.ms), const SizedBox(height: 48), TextFormField( controller: _emailController, keyboardType: TextInputType.emailAddress, decoration: const InputDecoration( labelText: 'Email', prefixIcon: Icon(Icons.email_outlined), ), validator: Validators.email, ).animate().fadeIn(delay: 300.ms).slideX(), const SizedBox(height: 16), TextFormField( controller: _passwordController, obscureText: _obscurePassword, decoration: InputDecoration( labelText: 'Пароль', prefixIcon: const Icon(Icons.lock_outlined), suffixIcon: IconButton( icon: Icon(_obscurePassword ? Icons.visibility_off : Icons.visibility), onPressed: () => setState(() => _obscurePassword = !_obscurePassword), ), ), validator: Validators.password, ).animate().fadeIn(delay: 400.ms).slideX(), const SizedBox(height: 8), Align( alignment: Alignment.centerRight, child: TextButton( onPressed: () => context.push('/auth/forgot-password'), child: const Text('Забыли пароль?'), ), ), const SizedBox(height: 24), if (authState.error != null) Padding( padding: const EdgeInsets.only(bottom: 16), child: Text( authState.error!, style: const TextStyle(color: VoIdeaColors.error), textAlign: TextAlign.center, ), ), ElevatedButton( onPressed: authState.status == AuthStatus.loading ? null : () { if (_formKey.currentState!.validate()) { authNotifier.login( _emailController.text.trim(), _passwordController.text, ); } }, child: authState.status == AuthStatus.loading ? const SizedBox( height: 20, width: 20, child: CircularProgressIndicator( strokeWidth: 2, color: Colors.white, ), ) : const Text('Войти'), ).animate().fadeIn(delay: 500.ms), const SizedBox(height: 12), OutlinedButton.icon( onPressed: () { _emailController.text = AppConstants.demoEmail; _passwordController.text = AppConstants.demoPassword; authNotifier.login(AppConstants.demoEmail, AppConstants.demoPassword); }, icon: const Icon(Icons.play_circle_outline, size: 18), label: const Text('Демо-доступ'), ).animate().fadeIn(delay: 550.ms), const SizedBox(height: 12), OutlinedButton( onPressed: () => context.push('/auth/register'), child: const Text('Создать аккаунт'), ).animate().fadeIn(delay: 600.ms), const SizedBox(height: 32), const Row( children: [ Expanded(child: Divider()), Padding( padding: EdgeInsets.symmetric(horizontal: 16), child: Text('или'), ), Expanded(child: Divider()), ], ), const SizedBox(height: 16), OutlinedButton.icon( onPressed: () => _oauthLogin('google'), icon: const Icon(Icons.g_mobiledata), label: const Text('Google'), ), const SizedBox(height: 8), OutlinedButton.icon( onPressed: () => _oauthLogin('yandex'), icon: const Icon(Icons.cloud), label: const Text('Яндекс'), ), ], ), ), ), ), ); } void _oauthLogin(String provider) { ref.read(authProvider.notifier).getOAuthUrl(provider).then((url) { if (url != null && mounted) { context.push('/auth/oauth?provider=$provider&url=$url'); } }); } }