import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:provider/provider.dart'; import '../l10n/app_localizations.dart'; import '../providers/auth_provider.dart'; import '../providers/settings_provider.dart'; import '../services/api_service.dart'; import 'register_page.dart'; import 'settings_page.dart'; class LoginPage extends StatefulWidget { const LoginPage({super.key}); @override _LoginPageState createState() => _LoginPageState(); } class _LoginPageState extends State { final _usernameController = TextEditingController(); final _passwordController = TextEditingController(); final _passwordFocusNode = FocusNode(); bool _isLoading = false; @override void dispose() { _usernameController.dispose(); _passwordController.dispose(); _passwordFocusNode.dispose(); super.dispose(); } void _handleLogin() async { final l10n = AppLocalizations.of(context)!; if (_usernameController.text.isEmpty || _passwordController.text.isEmpty) { ScaffoldMessenger.of( context, ).showSnackBar(SnackBar(content: Text(l10n.fillAllFields))); return; } setState(() => _isLoading = true); final settings = context.read(); final auth = context.read(); final api = ApiService(settings, null); try { final response = await api.login( _usernameController.text, _passwordController.text, ); if (response.statusCode == 200) { final data = jsonDecode(response.body); await auth.login(data['token'], data['username']); } else { if (!mounted) { return; } final error = jsonDecode(response.body)['error'] ?? l10n.loginFailed; ScaffoldMessenger.of( context, ).showSnackBar(SnackBar(content: Text(error))); } } catch (e) { if (!mounted) { return; } ScaffoldMessenger.of(context).showSnackBar( SnackBar(content: Text(l10n.networkError)), ); } finally { if (mounted) setState(() => _isLoading = false); } } @override Widget build(BuildContext context) { final l10n = AppLocalizations.of(context)!; return Scaffold( appBar: AppBar( actions: [ IconButton( icon: const Icon(Icons.settings), onPressed: () => Navigator.push( context, MaterialPageRoute(builder: (_) => const SettingsPage()), ), ), ], ), body: Center( child: SingleChildScrollView( padding: const EdgeInsets.symmetric(horizontal: 32.0), child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 400), child: Column( mainAxisAlignment: MainAxisAlignment.center, children: [ // Logo & Name Icon( Icons.flutter_dash, size: 80, color: Theme.of(context).colorScheme.primary, ), const SizedBox(height: 16), Text( "HIGHTUBE", style: TextStyle( fontSize: 32, fontWeight: FontWeight.bold, letterSpacing: 4, color: Theme.of(context).colorScheme.primary, ), ), const Text( "Open Source Live Platform", style: TextStyle(color: Colors.grey), ), const SizedBox(height: 48), // Fields TextField( controller: _usernameController, textInputAction: TextInputAction.next, onSubmitted: (_) => _passwordFocusNode.requestFocus(), decoration: InputDecoration( labelText: l10n.username, prefixIcon: const Icon(Icons.person), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), ), ), ), const SizedBox(height: 16), TextField( controller: _passwordController, focusNode: _passwordFocusNode, obscureText: true, textInputAction: TextInputAction.done, onSubmitted: (_) { if (!_isLoading) { _handleLogin(); } }, decoration: InputDecoration( labelText: l10n.password, prefixIcon: const Icon(Icons.lock), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), ), ), ), const SizedBox(height: 32), // Login Button SizedBox( width: double.infinity, height: 50, child: ElevatedButton( onPressed: _isLoading ? null : _handleLogin, style: ElevatedButton.styleFrom( shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), child: _isLoading ? const CircularProgressIndicator() : Text( l10n.login, style: const TextStyle(fontWeight: FontWeight.bold), ), ), ), const SizedBox(height: 16), // Register Link TextButton( onPressed: () => Navigator.push( context, MaterialPageRoute(builder: (_) => RegisterPage()), ), child: Text(l10n.dontHaveAccount), ), ], ), ), ), ), ); } }