All checks were successful
Deploy Brew Application / deploy (push) Successful in 11s
114 lines
4.2 KiB
JavaScript
114 lines
4.2 KiB
JavaScript
import { useState, useContext } from 'react';
|
|
import { AuthContext } from '../AuthContext';
|
|
import { inputCls, labelCls } from '../constants';
|
|
|
|
export default function Register({ onRegisterSuccess }) {
|
|
const [formData, setFormData] = useState({ username: '', email: '', password: '', confirmPassword: '' });
|
|
const [error, setError] = useState('');
|
|
const [success, setSuccess] = useState('');
|
|
const [loading, setLoading] = useState(false);
|
|
const { register } = useContext(AuthContext);
|
|
|
|
const handleSubmit = async (e) => {
|
|
e.preventDefault();
|
|
setError('');
|
|
setSuccess('');
|
|
|
|
if (formData.password !== formData.confirmPassword) {
|
|
setError('Passwords do not match');
|
|
return;
|
|
}
|
|
if (formData.password.length < 6) {
|
|
setError('Password must be at least 6 characters');
|
|
return;
|
|
}
|
|
|
|
setLoading(true);
|
|
const result = await register(formData.username, formData.email, formData.password);
|
|
if (result.success) {
|
|
setSuccess(result.message);
|
|
setFormData({ username: '', email: '', password: '', confirmPassword: '' });
|
|
onRegisterSuccess?.();
|
|
} else {
|
|
setError(result.error);
|
|
}
|
|
setLoading(false);
|
|
};
|
|
|
|
return (
|
|
<div className="px-5 pt-12 pb-8 max-w-[480px] mx-auto transition-colors duration-200">
|
|
<div className="mb-8 text-center">
|
|
<img src="/icon-192.png" alt="Brew Journal" className="w-16 h-16 mx-auto mb-3 rounded-[22%]" />
|
|
<h1 className="font-serif text-3xl font-semibold text-[#2C1810] dark:text-[#FAF6F1] mb-1">Create Account</h1>
|
|
<p className="text-sm text-[#9C8B7A] dark:text-[#C8B9A6]">Start tracking your coffee journey</p>
|
|
</div>
|
|
|
|
{error && (
|
|
<div className="bg-[rgba(180,64,64,0.08)] dark:bg-[rgba(229,91,91,0.08)] border border-[rgba(180,64,64,0.2)] dark:border-[rgba(229,91,91,0.2)] text-[#B44040] dark:text-[#E55B5B] text-sm px-4 py-3 rounded-lg mb-4">
|
|
{error}
|
|
</div>
|
|
)}
|
|
{success && (
|
|
<div className="bg-[rgba(74,124,89,0.08)] dark:bg-[rgba(108,178,129,0.08)] border border-[rgba(74,124,89,0.2)] dark:border-[rgba(108,178,129,0.2)] text-[#4A7C59] dark:text-[#6CB281] text-sm px-4 py-3 rounded-lg mb-4">
|
|
{success}
|
|
</div>
|
|
)}
|
|
|
|
<form onSubmit={handleSubmit} className="flex flex-col gap-4">
|
|
<div>
|
|
<label className={labelCls}>Username</label>
|
|
<input
|
|
className={inputCls}
|
|
type="text"
|
|
placeholder="coffeelover"
|
|
value={formData.username}
|
|
onChange={(e) => setFormData({ ...formData, username: e.target.value })}
|
|
required
|
|
/>
|
|
</div>
|
|
<div>
|
|
<label className={labelCls}>Email</label>
|
|
<input
|
|
className={inputCls}
|
|
type="email"
|
|
placeholder="you@example.com"
|
|
value={formData.email}
|
|
onChange={(e) => setFormData({ ...formData, email: e.target.value })}
|
|
required
|
|
/>
|
|
</div>
|
|
<div>
|
|
<label className={labelCls}>Password</label>
|
|
<input
|
|
className={inputCls}
|
|
type="password"
|
|
placeholder="••••••••"
|
|
value={formData.password}
|
|
onChange={(e) => setFormData({ ...formData, password: e.target.value })}
|
|
required
|
|
/>
|
|
</div>
|
|
<div>
|
|
<label className={labelCls}>Confirm Password</label>
|
|
<input
|
|
className={inputCls}
|
|
type="password"
|
|
placeholder="••••••••"
|
|
value={formData.confirmPassword}
|
|
onChange={(e) => setFormData({ ...formData, confirmPassword: e.target.value })}
|
|
required
|
|
/>
|
|
</div>
|
|
<button
|
|
type="submit"
|
|
disabled={loading}
|
|
className="w-full py-3.5 border-none rounded-lg bg-[#2C1810] dark:bg-[#FAF6F1] text-[#FAF6F1] dark:text-[#2C1810] text-sm font-semibold tracking-wide mt-1 cursor-pointer transition-colors"
|
|
style={{ opacity: loading ? 0.6 : 1, cursor: loading ? 'not-allowed' : 'pointer' }}
|
|
>
|
|
{loading ? 'Creating account…' : 'Create Account'}
|
|
</button>
|
|
</form>
|
|
</div>
|
|
);
|
|
}
|