feat: User management, SMTP email activation and password resets
Build and Deploy / build-and-push (push) Successful in 1m0s
Build and Deploy / build-and-push (push) Successful in 1m0s
This commit is contained in:
@@ -26,10 +26,13 @@ export function AuthModal() {
|
||||
setSuccess('');
|
||||
|
||||
try {
|
||||
if (isRegister) {
|
||||
if (authMode === 'forgot-password') {
|
||||
await api.forgotPassword(email);
|
||||
setSuccess('If an account exists, a reset link has been sent to your email.');
|
||||
} else if (isRegister) {
|
||||
const res = await api.register(email, password);
|
||||
if (res.status === 'pending') {
|
||||
setSuccess(res.message || 'Account created successfully! Please contact an admin to activate your account.');
|
||||
setSuccess(res.message || 'Account created successfully! Please check your email for the activation link.');
|
||||
setEmail('');
|
||||
setPassword('');
|
||||
} else {
|
||||
@@ -84,10 +87,10 @@ export function AuthModal() {
|
||||
</div>
|
||||
|
||||
<h2 className="text-2xl font-bold text-white text-center mb-2 relative z-10">
|
||||
{isRegister ? 'Create an Account' : 'Welcome Back'}
|
||||
{authMode === 'forgot-password' ? 'Reset Password' : isRegister ? 'Create an Account' : 'Welcome Back'}
|
||||
</h2>
|
||||
<p className="text-zinc-400 text-sm text-center mb-8 relative z-10">
|
||||
{isRegister ? 'Sign up to start building 3D scenes.' : 'Sign in to access your projects.'}
|
||||
{authMode === 'forgot-password' ? 'Enter your email to receive a reset link.' : isRegister ? 'Sign up to start building 3D scenes.' : 'Sign in to access your projects.'}
|
||||
</p>
|
||||
|
||||
{error && (
|
||||
@@ -116,18 +119,28 @@ export function AuthModal() {
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div className="relative">
|
||||
<Lock className="absolute left-3 top-1/2 -translate-y-1/2 text-zinc-400" size={18} />
|
||||
<input
|
||||
type="password"
|
||||
placeholder="Password"
|
||||
required
|
||||
autoComplete={isRegister ? "new-password" : "current-password"}
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
className="w-full bg-zinc-950/50 border border-zinc-700/50 rounded-xl py-3 pl-10 pr-4 text-white placeholder-zinc-500 focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-all"
|
||||
/>
|
||||
</div>
|
||||
{authMode !== 'forgot-password' && (
|
||||
<div className="relative">
|
||||
<Lock className="absolute left-3 top-1/2 -translate-y-1/2 text-zinc-400" size={18} />
|
||||
<input
|
||||
type="password"
|
||||
placeholder="Password"
|
||||
required
|
||||
autoComplete={isRegister ? "new-password" : "current-password"}
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
className="w-full bg-zinc-950/50 border border-zinc-700/50 rounded-xl py-3 pl-10 pr-4 text-white placeholder-zinc-500 focus:outline-none focus:border-primary focus:ring-1 focus:ring-primary transition-all"
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
|
||||
{authMode === 'login' && (
|
||||
<div className="flex justify-end">
|
||||
<button type="button" onClick={() => openAuthModal('forgot-password')} className="text-xs text-primary hover:underline">
|
||||
Forgot Password?
|
||||
</button>
|
||||
</div>
|
||||
)}
|
||||
|
||||
<button
|
||||
type="submit"
|
||||
@@ -135,12 +148,14 @@ export function AuthModal() {
|
||||
className="w-full bg-primary hover:bg-primary/90 text-white font-bold py-3 rounded-xl mt-2 transition-all flex items-center justify-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed shadow-[0_0_20px_rgba(var(--primary-rgb),0.3)] hover:shadow-[0_0_30px_rgba(var(--primary-rgb),0.5)]"
|
||||
>
|
||||
{loading && <Loader2 size={18} className="animate-spin" />}
|
||||
{isRegister ? 'Sign Up' : 'Sign In'}
|
||||
{authMode === 'forgot-password' ? 'Send Reset Link' : isRegister ? 'Sign Up' : 'Sign In'}
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<div className="mt-8 text-center text-sm text-zinc-400 relative z-10">
|
||||
{isRegister ? (
|
||||
{authMode === 'forgot-password' ? (
|
||||
<p>Remember your password? <button onClick={() => openAuthModal('login')} className="text-primary hover:underline font-medium">Sign in</button></p>
|
||||
) : isRegister ? (
|
||||
<p>Already have an account? <button onClick={() => openAuthModal('login')} className="text-primary hover:underline font-medium">Sign in</button></p>
|
||||
) : (
|
||||
<p>Don't have an account? <button onClick={() => openAuthModal('register')} className="text-primary hover:underline font-medium">Sign up</button></p>
|
||||
|
||||
Reference in New Issue
Block a user