import 'package:flutter/material.dart'; import 'package:flutter_riverpod/flutter_riverpod.dart'; import 'package:go_router/go_router.dart'; import '../providers/auth_provider.dart'; import '../widgets/widgets.dart'; import '../utils/validators.dart'; /// Registration page for new users class RegisterPage extends ConsumerStatefulWidget { const RegisterPage({super.key}); @override ConsumerState createState() => _RegisterPageState(); } class _RegisterPageState extends ConsumerState { final _formKey = GlobalKey(); final _nameController = TextEditingController(); final _emailController = TextEditingController(); final _passwordController = TextEditingController(); final _confirmPasswordController = TextEditingController(); bool _acceptTerms = false; @override void dispose() { _nameController.dispose(); _emailController.dispose(); _passwordController.dispose(); _confirmPasswordController.dispose(); super.dispose(); } Future _handleRegister() async { // Dismiss keyboard FocusScope.of(context).unfocus(); // Validate form if (!_formKey.currentState!.validate()) { return; } // Check terms acceptance if (!_acceptTerms) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: const Text('Please accept the terms and conditions'), backgroundColor: Theme.of(context).colorScheme.error, behavior: SnackBarBehavior.floating, ), ); return; } // Attempt registration final success = await ref.read(authProvider.notifier).register( name: _nameController.text.trim(), email: _emailController.text.trim(), password: _passwordController.text, ); if (!mounted) return; if (success) { // Show success message ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: const Text('Registration successful!'), backgroundColor: Theme.of(context).colorScheme.primary, behavior: SnackBarBehavior.floating, ), ); // Navigation is handled by AuthWrapper } else { // Show error message final authState = ref.read(authProvider); if (authState.errorMessage != null) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text(authState.errorMessage!), backgroundColor: Theme.of(context).colorScheme.error, behavior: SnackBarBehavior.floating, action: SnackBarAction( label: 'Dismiss', textColor: Colors.white, onPressed: () {}, ), ), ); } } } void _navigateBackToLogin() { context.pop(); } @override Widget build(BuildContext context) { final theme = Theme.of(context); final authState = ref.watch(authProvider); final isLoading = authState.isLoading; return GestureDetector( onTap: () => FocusScope.of(context).unfocus(), child: Scaffold( appBar: AppBar( backgroundColor: Colors.transparent, elevation: 0, leading: IconButton( icon: const Icon(Icons.arrow_back), onPressed: isLoading ? null : _navigateBackToLogin, ), ), body: SafeArea( child: Center( child: SingleChildScrollView( padding: const EdgeInsets.all(24.0), child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 400), child: Form( key: _formKey, child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ // Header const AuthHeader( title: 'Create Account', subtitle: 'Join us and start managing your retail business.', ), const SizedBox(height: 40), // Name field AuthTextField( controller: _nameController, label: 'Full Name', hint: 'Enter your full name', keyboardType: TextInputType.name, textInputAction: TextInputAction.next, prefixIcon: Icons.person_outline, validator: AuthValidators.validateName, enabled: !isLoading, autofocus: true, ), const SizedBox(height: 16), // Email field AuthTextField( controller: _emailController, label: 'Email', hint: 'Enter your email', keyboardType: TextInputType.emailAddress, textInputAction: TextInputAction.next, prefixIcon: Icons.email_outlined, validator: AuthValidators.validateEmail, enabled: !isLoading, ), const SizedBox(height: 16), // Password field PasswordField( controller: _passwordController, label: 'Password', hint: 'Create a strong password', textInputAction: TextInputAction.next, validator: AuthValidators.validatePassword, enabled: !isLoading, ), const SizedBox(height: 16), // Confirm password field PasswordField( controller: _confirmPasswordController, label: 'Confirm Password', hint: 'Re-enter your password', textInputAction: TextInputAction.done, validator: (value) => AuthValidators.validateConfirmPassword( value, _passwordController.text, ), onFieldSubmitted: (_) => _handleRegister(), enabled: !isLoading, ), const SizedBox(height: 16), // Terms and conditions checkbox Row( crossAxisAlignment: CrossAxisAlignment.start, children: [ Checkbox( value: _acceptTerms, onChanged: isLoading ? null : (value) { setState(() { _acceptTerms = value ?? false; }); }, ), Expanded( child: Padding( padding: const EdgeInsets.only(top: 12), child: GestureDetector( onTap: isLoading ? null : () { setState(() { _acceptTerms = !_acceptTerms; }); }, child: Text.rich( TextSpan( text: 'I agree to the ', style: theme.textTheme.bodyMedium, children: [ TextSpan( text: 'Terms and Conditions', style: TextStyle( color: theme.colorScheme.primary, fontWeight: FontWeight.w600, ), ), const TextSpan(text: ' and '), TextSpan( text: 'Privacy Policy', style: TextStyle( color: theme.colorScheme.primary, fontWeight: FontWeight.w600, ), ), ], ), ), ), ), ), ], ), const SizedBox(height: 24), // Register button AuthButton( onPressed: _handleRegister, text: 'Create Account', isLoading: isLoading, ), const SizedBox(height: 24), // Divider Row( children: [ Expanded( child: Divider( color: theme.colorScheme.onSurface.withOpacity(0.2), ), ), Padding( padding: const EdgeInsets.symmetric(horizontal: 16), child: Text( 'OR', style: theme.textTheme.bodySmall?.copyWith( color: theme.colorScheme.onSurface.withOpacity(0.5), ), ), ), Expanded( child: Divider( color: theme.colorScheme.onSurface.withOpacity(0.2), ), ), ], ), const SizedBox(height: 24), // Login link Row( mainAxisAlignment: MainAxisAlignment.center, children: [ Text( 'Already have an account? ', style: theme.textTheme.bodyMedium, ), TextButton( onPressed: isLoading ? null : _navigateBackToLogin, child: Text( 'Login', style: theme.textTheme.bodyMedium?.copyWith( color: theme.colorScheme.primary, fontWeight: FontWeight.bold, ), ), ), ], ), ], ), ), ), ), ), ), ), ); } }