import 'package:flutter/material.dart'; import 'package:go_router/go_router.dart'; import '../../pocketbase/service/pocketbase.service.dart'; class ForgotPasswordPage extends StatefulWidget { const ForgotPasswordPage({super.key}); @override State createState() => _ForgotPasswordPageState(); } class _ForgotPasswordPageState extends State { final _formKey = GlobalKey(); final _emailController = TextEditingController(); final _emailFocusNode = FocusNode(); bool _isLoading = false; final pocketbase = AppPocketBaseService.instance.pb; Widget _buildEmailField() { return TextFormField( controller: _emailController, focusNode: _emailFocusNode, keyboardType: TextInputType.emailAddress, textInputAction: TextInputAction.done, autofillHints: const [AutofillHints.email], style: Theme.of(context).textTheme.bodyLarge, decoration: InputDecoration( labelText: 'Email', prefixIcon: const Icon(Icons.email_outlined), border: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide( color: Theme.of(context).colorScheme.outline, ), ), enabledBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide( color: Theme.of(context).colorScheme.outline.withValues(alpha: 0.5), ), ), focusedBorder: OutlineInputBorder( borderRadius: BorderRadius.circular(12), borderSide: BorderSide( color: Theme.of(context).colorScheme.primary, width: 2, ), ), filled: true, fillColor: Theme.of(context).colorScheme.surface, ), validator: (value) { if (value?.isEmpty ?? true) { return 'Please enter your email'; } if (!RegExp(r'^[\w-.]+@([\w-]+\.)+[\w-]{2,4}$').hasMatch(value!)) { return 'Please enter a valid email'; } return null; }, onFieldSubmitted: (_) => _requestPasswordReset(), ); } Future _requestPasswordReset() async { if (!_formKey.currentState!.validate()) return; setState(() => _isLoading = true); try { await pocketbase .collection('users') .requestPasswordReset(_emailController.text.trim()); if (mounted) { ScaffoldMessenger.of(context).showSnackBar( const SnackBar( content: Text( 'Password reset instructions have been sent to your email'), backgroundColor: Colors.green, ), ); // Navigate back to sign in page context.go('/signin'); } } catch (e) { if (mounted) { ScaffoldMessenger.of(context).showSnackBar( SnackBar( content: Text('Failed to send reset instructions: ${e.toString()}'), backgroundColor: Colors.red, ), ); } } finally { if (mounted) { setState(() => _isLoading = false); } } } @override Widget build(BuildContext context) { final theme = Theme.of(context); final colorScheme = theme.colorScheme; return Scaffold( backgroundColor: colorScheme.surface, appBar: AppBar( backgroundColor: Colors.transparent, elevation: 0, leading: IconButton( icon: Icon(Icons.arrow_back, color: colorScheme.onSurface), onPressed: () => context.go('/signin'), ), ), body: Center( child: SingleChildScrollView( padding: const EdgeInsets.all(24), child: ConstrainedBox( constraints: const BoxConstraints(maxWidth: 400), child: Form( key: _formKey, child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.stretch, children: [ Hero( tag: 'app_logo', child: Image.asset( 'assets/icon/icon_mini.png', height: 80, width: 80, ), ), const SizedBox(height: 24), Text( 'Forgot Password', style: theme.textTheme.headlineMedium?.copyWith( fontWeight: FontWeight.bold, color: colorScheme.onSurface, ), textAlign: TextAlign.center, ), const SizedBox(height: 8), Text( 'Enter your email address to receive password reset instructions', style: theme.textTheme.bodyLarge?.copyWith( color: colorScheme.onSurface.withValues(alpha: 0.7), ), textAlign: TextAlign.center, ), const SizedBox(height: 32), _buildEmailField(), const SizedBox(height: 24), AnimatedContainer( duration: const Duration(milliseconds: 300), height: 50, child: ElevatedButton( onPressed: _isLoading ? null : _requestPasswordReset, style: ElevatedButton.styleFrom( backgroundColor: colorScheme.primary, foregroundColor: colorScheme.onPrimary, elevation: 0, shape: RoundedRectangleBorder( borderRadius: BorderRadius.circular(12), ), ), child: _isLoading ? const SizedBox( height: 20, width: 20, child: CircularProgressIndicator( strokeWidth: 2, valueColor: AlwaysStoppedAnimation( Colors.white, ), ), ) : const Text( 'Reset Password', style: TextStyle( fontSize: 16, fontWeight: FontWeight.w600, ), ), ), ), ], ), ), ), ), ), ); } @override void dispose() { _emailController.dispose(); _emailFocusNode.dispose(); super.dispose(); } }