import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import '../../core/auth/auth_controller.dart'; import '../../core/config.dart'; class LoginPage extends ConsumerStatefulWidget { const LoginPage({super.key}); @override ConsumerState createState() => _LoginPageState(); } class _LoginPageState extends ConsumerState { final _email = TextEditingController(); final _password = TextEditingController(); String? _error; bool _busy = false; @override void dispose() { _email.dispose(); _password.dispose(); super.dispose(); } Future _submit() async { setState(() { _busy = true; _error = null; }); final error = await ref .read(authControllerProvider.notifier) .login(_email.text.trim(), _password.text); if (!mounted) return; setState(() { _busy = false; _error = error; }); } @override Widget build(BuildContext context) { final status = ref.watch(authControllerProvider).status; return Scaffold( body: Center( child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 360), child: Padding( padding: const EdgeInsets.all(24), child: status == AuthStatus.unknown ? const CircularProgressIndicator() : AutofillGroup( child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Text('fin-tracker', style: Theme.of(context).textTheme.headlineMedium), const SizedBox(height: 4), Text(apiBaseUrl(), style: Theme.of(context).textTheme.bodySmall), const SizedBox(height: 24), TextField( controller: _email, autofillHints: const [AutofillHints.username], keyboardType: TextInputType.emailAddress, decoration: const InputDecoration(labelText: 'Email'), ), const SizedBox(height: 12), TextField( controller: _password, autofillHints: const [AutofillHints.password], obscureText: true, onSubmitted: (_) => _busy ? null : _submit(), decoration: const InputDecoration(labelText: 'Пароль'), ), if (_error != null) ...[ const SizedBox(height: 12), Text(_error!, style: TextStyle(color: Theme.of(context).colorScheme.error)), ], const SizedBox(height: 24), FilledButton( onPressed: _busy ? null : _submit, child: _busy ? const SizedBox.square( dimension: 18, child: CircularProgressIndicator(strokeWidth: 2)) : const Text('Войти'), ), ], ), ), ), ), ), ); } }