import 'package:flutter/material.dart'; import '../api_service.dart'; import '../settings.dart'; import '../theme.dart'; import 'home_screen.dart'; import 'settings_screen.dart'; class LoginScreen extends StatefulWidget { final ApiService api; final Settings settings; const LoginScreen({super.key, required this.api, required this.settings}); @override State createState() => _LoginScreenState(); } class _LoginScreenState extends State { final _email = TextEditingController(); final _pin = TextEditingController(); bool _busy = false; String? _error; Future _login() async { if (_email.text.trim().isEmpty || _pin.text.isEmpty) { setState(() => _error = 'Enter your work email and PIN'); return; } setState(() { _busy = true; _error = null; }); try { await widget.api.login(_email.text, _pin.text); if (!mounted) return; Navigator.pushReplacement(context, MaterialPageRoute(builder: (_) => HomeScreen(api: widget.api, settings: widget.settings))); } on ApiException catch (e) { setState(() => _error = e.message); } finally { if (mounted) setState(() => _busy = false); } } @override Widget build(BuildContext context) { return Scaffold( body: SafeArea( child: Center( child: SingleChildScrollView( padding: const EdgeInsets.all(24), child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 420), child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Row(mainAxisAlignment: MainAxisAlignment.spaceBetween, children: [ Row(children: [ Container( width: 40, height: 40, decoration: BoxDecoration(color: AppColors.emerald, borderRadius: BorderRadius.circular(12)), child: const Icon(Icons.badge_outlined, color: Colors.white), ), const SizedBox(width: 10), const Text('Scalar360', style: TextStyle(fontSize: 18, fontWeight: FontWeight.bold, color: AppColors.navy)), ]), IconButton( icon: const Icon(Icons.settings_outlined, color: AppColors.muted), onPressed: () => Navigator.push(context, MaterialPageRoute(builder: (_) => SettingsScreen(settings: widget.settings))), ), ]), const SizedBox(height: 28), const Text('Employee sign in', style: TextStyle(fontSize: 26, fontWeight: FontWeight.bold, color: AppColors.navy)), const SizedBox(height: 4), const Text('Use your work email and the PIN from HR', style: TextStyle(color: AppColors.muted)), const SizedBox(height: 24), TextField( controller: _email, keyboardType: TextInputType.emailAddress, autocorrect: false, decoration: const InputDecoration(labelText: 'Work email', prefixIcon: Icon(Icons.mail_outline)), ), const SizedBox(height: 14), TextField( controller: _pin, obscureText: true, keyboardType: TextInputType.number, onSubmitted: (_) => _login(), decoration: const InputDecoration(labelText: 'PIN', prefixIcon: Icon(Icons.pin_outlined)), ), if (_error != null) ...[ const SizedBox(height: 14), Container( padding: const EdgeInsets.all(12), decoration: BoxDecoration(color: AppColors.danger.withValues(alpha: 0.08), borderRadius: BorderRadius.circular(12)), child: Row(children: [ const Icon(Icons.error_outline, color: AppColors.danger, size: 18), const SizedBox(width: 8), Expanded(child: Text(_error!, style: const TextStyle(color: AppColors.danger))), ]), ), ], const SizedBox(height: 22), FilledButton( onPressed: _busy ? null : _login, child: _busy ? const SizedBox(height: 22, width: 22, child: CircularProgressIndicator(strokeWidth: 2, color: Colors.white)) : const Text('Sign in'), ), const SizedBox(height: 16), Text('Server: ${widget.settings.baseUrl}', textAlign: TextAlign.center, style: const TextStyle(color: AppColors.muted, fontSize: 12)), ], ), ), ), ), ), ); } }