reg workflow improvements

This commit is contained in:
James Pattinson
2025-11-10 19:55:29 +00:00
parent ba21262854
commit d173b13bb9
2 changed files with 147 additions and 81 deletions

View File

@@ -154,7 +154,7 @@ body {
padding: 40px; padding: 40px;
box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2); box-shadow: 0 4px 16px rgba(0, 0, 0, 0.2);
width: 100%; width: 100%;
max-width: 440px; max-width: 900px;
} }
.auth-card h2 { .auth-card h2 {

View File

@@ -12,6 +12,8 @@ const Register: React.FC = () => {
phone: '', phone: '',
address: '' address: ''
}); });
const [confirmPassword, setConfirmPassword] = useState('');
const [passwordsMatch, setPasswordsMatch] = useState(true);
const [error, setError] = useState(''); const [error, setError] = useState('');
const [loading, setLoading] = useState(false); const [loading, setLoading] = useState(false);
@@ -22,15 +24,41 @@ const Register: React.FC = () => {
}); });
}; };
const handlePasswordChange = (e: React.ChangeEvent<HTMLInputElement>) => {
const { name, value } = e.target;
if (name === 'password') {
setFormData(prev => ({ ...prev, password: value }));
setPasswordsMatch(value === confirmPassword);
} else if (name === 'confirmPassword') {
setConfirmPassword(value);
setPasswordsMatch(formData.password === value);
}
};
const handleSubmit = async (e: React.FormEvent) => { const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault(); e.preventDefault();
setError(''); setError('');
// Validate password confirmation
if (formData.password !== confirmPassword) {
setError('Passwords do not match. Please try again.');
return;
}
setLoading(true); setLoading(true);
try { try {
// Register the user
await authService.register(formData); await authService.register(formData);
alert('Registration successful! Please check your email. You can now log in.');
navigate('/login'); // Automatically log in the user
await authService.login({
email: formData.email,
password: formData.password
});
// Redirect to dashboard
navigate('/dashboard');
} catch (err: any) { } catch (err: any) {
setError(err.response?.data?.detail || 'Registration failed. Please try again.'); setError(err.response?.data?.detail || 'Registration failed. Please try again.');
} finally { } finally {
@@ -48,89 +76,127 @@ const Register: React.FC = () => {
{error && <div className="alert alert-error">{error}</div>} {error && <div className="alert alert-error">{error}</div>}
<form onSubmit={handleSubmit}> <form onSubmit={handleSubmit} style={{ display: 'grid', gridTemplateColumns: '1fr 1fr', gap: '40px', maxWidth: '900px', margin: '0 auto' }}>
<div className="form-group"> {/* Left Column - Personal Information */}
<label htmlFor="first_name">First Name *</label> <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
<input <div className="form-group">
type="text" <label htmlFor="first_name">First Name *</label>
id="first_name" <input
name="first_name" type="text"
value={formData.first_name} id="first_name"
onChange={handleChange} name="first_name"
required value={formData.first_name}
/> onChange={handleChange}
required
/>
</div>
<div className="form-group">
<label htmlFor="last_name">Last Name *</label>
<input
type="text"
id="last_name"
name="last_name"
value={formData.last_name}
onChange={handleChange}
required
/>
</div>
<div className="form-group">
<label htmlFor="email">Email Address *</label>
<input
type="email"
id="email"
name="email"
value={formData.email}
onChange={handleChange}
required
/>
</div>
<div className="form-group">
<label htmlFor="password">Password *</label>
<input
type="password"
id="password"
name="password"
value={formData.password}
onChange={handlePasswordChange}
minLength={8}
required
/>
<small style={{ color: '#666', fontSize: '12px' }}>
Minimum 8 characters
</small>
</div>
<div className="form-group">
<label htmlFor="confirmPassword">Confirm Password *</label>
<input
type="password"
id="confirmPassword"
name="confirmPassword"
value={confirmPassword}
onChange={handlePasswordChange}
minLength={8}
required
style={{
borderColor: confirmPassword && !passwordsMatch ? '#dc3545' : confirmPassword && passwordsMatch ? '#28a745' : undefined
}}
/>
{confirmPassword && (
<small style={{
color: passwordsMatch ? '#28a745' : '#dc3545',
fontSize: '12px'
}}>
{passwordsMatch ? '✓ Passwords match' : '✗ Passwords do not match'}
</small>
)}
{!confirmPassword && (
<small style={{ color: '#666', fontSize: '12px' }}>
Re-enter your password
</small>
)}
</div>
</div> </div>
<div className="form-group"> {/* Right Column - Contact Information */}
<label htmlFor="last_name">Last Name *</label> <div style={{ display: 'flex', flexDirection: 'column', gap: '16px' }}>
<input <div className="form-group">
type="text" <label htmlFor="phone">Phone (optional)</label>
id="last_name" <input
name="last_name" type="tel"
value={formData.last_name} id="phone"
onChange={handleChange} name="phone"
required value={formData.phone}
/> onChange={handleChange}
/>
</div>
<div className="form-group">
<label htmlFor="address">Address (optional)</label>
<textarea
id="address"
name="address"
value={formData.address}
onChange={handleChange}
rows={3}
/>
</div>
</div> </div>
<div className="form-group"> {/* Submit Button - Full Width */}
<label htmlFor="email">Email Address *</label> <div style={{ gridColumn: '1 / -1', marginTop: '8px' }}>
<input <button
type="email" type="submit"
id="email" className="btn btn-primary"
name="email" disabled={loading}
value={formData.email} style={{ width: '100%' }}
onChange={handleChange} >
required {loading ? 'Creating Account...' : 'Create Account & Sign In'}
/> </button>
</div> </div>
<div className="form-group">
<label htmlFor="password">Password *</label>
<input
type="password"
id="password"
name="password"
value={formData.password}
onChange={handleChange}
minLength={8}
required
/>
<small style={{ color: '#666', fontSize: '12px' }}>
Minimum 8 characters
</small>
</div>
<div className="form-group">
<label htmlFor="phone">Phone (optional)</label>
<input
type="tel"
id="phone"
name="phone"
value={formData.phone}
onChange={handleChange}
/>
</div>
<div className="form-group">
<label htmlFor="address">Address (optional)</label>
<textarea
id="address"
name="address"
value={formData.address}
onChange={handleChange}
rows={3}
/>
</div>
<button
type="submit"
className="btn btn-primary"
disabled={loading}
style={{ width: '100%', marginTop: '16px' }}
>
{loading ? 'Creating Account...' : 'Create Account'}
</button>
</form> </form>
<div className="form-footer"> <div className="form-footer">