import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import 'package:google_fonts/google_fonts.dart'; import '../providers/auth_provider.dart'; class LoginScreen extends ConsumerStatefulWidget { const LoginScreen({super.key}); @override ConsumerState createState() => _LoginScreenState(); } class _LoginScreenState extends ConsumerState { final _formKey = GlobalKey(); final _usernameController = TextEditingController(); final _passwordController = TextEditingController(); bool _obscurePassword = true; @override void dispose() { _usernameController.dispose(); _passwordController.dispose(); super.dispose(); } Future _handleLogin() async { if (!_formKey.currentState!.validate()) return; final auth = ref.read(authProvider.notifier); final success = await auth.login( _usernameController.text.trim(), _passwordController.text, ); if (success && mounted) { context.go('/playlists'); } } @override Widget build(BuildContext context) { final authState = ref.watch(authProvider); return Scaffold( body: Container( decoration: BoxDecoration( gradient: LinearGradient( begin: Alignment.topLeft, end: Alignment.bottomRight, colors: [ Colors.blue.shade900, Colors.black, ], ), ), child: Center( child: SingleChildScrollView( padding: const EdgeInsets.all(24.0), child: Card( elevation: 8, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(16), ), child: Container( constraints: const BoxConstraints(maxWidth: 400), padding: const EdgeInsets.all(32.0), child: Form( key: _formKey, child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Icon( Icons.live_tv_rounded, size: 64, color: Colors.blue.shade700, ), const SizedBox(height: 16), Text( 'XtremFlow IPTV', style: GoogleFonts.roboto( fontSize: 28, fontWeight: FontWeight.bold, ), textAlign: TextAlign.center, ), const SizedBox(height: 8), Text( 'Admin Access', style: GoogleFonts.roboto( fontSize: 14, color: Colors.grey.shade600, ), textAlign: TextAlign.center, ), const SizedBox(height: 32), TextFormField( controller: _usernameController, decoration: InputDecoration( labelText: 'Username', prefixIcon: const Icon(Icons.person), border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), ), ), validator: (value) { if (value == null || value.trim().isEmpty) { return 'Username required'; } return null; }, autofocus: true, textInputAction: TextInputAction.next, ), const SizedBox(height: 16), TextFormField( controller: _passwordController, obscureText: _obscurePassword, decoration: InputDecoration( labelText: 'Password', prefixIcon: const Icon(Icons.lock), suffixIcon: IconButton( icon: Icon( _obscurePassword ? Icons.visibility : Icons.visibility_off, ), onPressed: () { setState(() { _obscurePassword = !_obscurePassword; }); }, ), border: OutlineInputBorder( borderRadius: BorderRadius.circular(8), ), ), validator: (value) { if (value == null || value.isEmpty) { return 'Password required'; } return null; }, textInputAction: TextInputAction.done, onFieldSubmitted: (_) => _handleLogin(), ), if (authState.errorMessage != null) ...[ const SizedBox(height: 16), Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration( color: Colors.red.shade50, borderRadius: BorderRadius.circular(8), border: Border.all(color: Colors.red.shade200), ), child: Row( children: [ Icon(Icons.error_outline, color: Colors.red.shade700), const SizedBox(width: 8), Expanded( child: Text( authState.errorMessage!, style: TextStyle(color: Colors.red.shade700), ), ), ], ), ), ], const SizedBox(height: 24), ElevatedButton( onPressed: authState.isLoading ? null : _handleLogin, style: ElevatedButton.styleFrom( padding: const EdgeInsets.symmetric(vertical: 16), shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(8), ), ), child: authState.isLoading ? const SizedBox( height: 20, width: 20, child: CircularProgressIndicator(strokeWidth: 2), ) : const Text( 'Login', style: TextStyle(fontSize: 16), ), ), const SizedBox(height: 16), Text( 'Default credentials: admin / admin', style: GoogleFonts.roboto( fontSize: 12, color: Colors.grey.shade500, fontStyle: FontStyle.italic, ), textAlign: TextAlign.center, ), ], ), ), ), ), ), ), ), ); } }