import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import 'package:provider/provider.dart'; import 'package:qpay/screens/onboarding/login/login_controller.dart'; import 'package:qpay/screens/onboarding/onboarding_controller.dart'; import 'package:qpay/screens/onboarding/widgets/onboarding_layout.dart'; import 'package:qpay/widgets/app_snack_bar.dart'; import 'package:skeletonizer/skeletonizer.dart'; class LoginScreen extends StatefulWidget { const LoginScreen({super.key}); @override State createState() => _LoginScreenState(); } class _LoginScreenState extends State { late OnboardingController onboardingController; final _formKey = GlobalKey(); final TextEditingController _emailController = TextEditingController(); final TextEditingController _passwordController = TextEditingController(); bool _obscurePassword = true; bool _loading = false; late LoginController _loginController; @override void initState() { super.initState(); _loginController = LoginController(context); onboardingController = Provider.of( context, listen: false, ); // Pre-fill email if it was captured during registration. final capturedEmail = onboardingController.model.email; if (capturedEmail != null && capturedEmail.isNotEmpty) { _emailController.text = capturedEmail; } } @override void dispose() { _emailController.dispose(); _passwordController.dispose(); _loginController.dispose(); super.dispose(); } Future _onLogin() async { if (!(_formKey.currentState?.validate() ?? false)) return; final email = _emailController.text.trim(); final password = _passwordController.text; // Cache credentials in the onboarding model for use by the rest // of the registration/login flow. onboardingController.updateEmail(email); onboardingController.updatePassword(password); setState(() => _loading = true); final response = await _loginController.login(email, password); if (!mounted) return; setState(() => _loading = false); if (response.isSuccess) { AppSnackBar.showSuccess(context, 'Login successful!'); } else { AppSnackBar.showError(context, response.error ?? 'Login failed'); } if (!mounted) return; if (response.isSuccess) { context.go('/'); } } @override Widget build(BuildContext context) { return OnboardingLayout( showBackButton: true, trailingLabel: 'Sign up', trailingRoute: '/onboarding/phone', trailingIcon: Icons.person_add_alt_1_rounded, bottomLinkLabel: 'Continue as guest?', bottomLinkRoute: '/', child: OnboardingCard( child: Form( key: _formKey, child: Column( crossAxisAlignment: CrossAxisAlignment.stretch, children: [ const OnboardingHero( icon: Icons.lock_open_rounded, title: 'Welcome back', subtitle: 'Sign in to continue with Velocity', ), const SizedBox(height: 28), OnboardingTextField( controller: _emailController, hintText: 'Email address', prefixIcon: Icons.email_outlined, keyboardType: TextInputType.emailAddress, validator: (value) { if (value == null || value.trim().isEmpty) { return 'Please enter your email address'; } final emailRegex = RegExp(r'^[\w\.\-+]+@[\w\.\-]+\.\w+$'); if (!emailRegex.hasMatch(value.trim())) { return 'Please enter a valid email address'; } return null; }, ), const SizedBox(height: 14), OnboardingTextField( controller: _passwordController, hintText: 'Password', prefixIcon: Icons.lock_outline, obscureText: _obscurePassword, enableSuggestions: false, autocorrect: false, suffixIcon: IconButton( icon: Icon( _obscurePassword ? Icons.visibility_rounded : Icons.visibility_off_rounded, ), tooltip: _obscurePassword ? 'Show password' : 'Hide password', onPressed: () { setState(() { _obscurePassword = !_obscurePassword; }); }, ), validator: (value) { if (value == null || value.isEmpty) { return 'Please enter your password'; } return null; }, ), const SizedBox(height: 28), Skeletonizer( enabled: _loading, child: OnboardingPrimaryButton( label: 'Sign in', icon: Icons.arrow_forward_rounded, onPressed: _onLogin, ), ), ], ), ), ), ); } }