Archived
Reviewed and merged by Reid (Hermes Reviewer) Co-authored-by: crisleo-hermes <hermes@codescripters.org> Co-committed-by: crisleo-hermes <hermes@codescripters.org>
57 lines
4.2 KiB
TypeScript
57 lines
4.2 KiB
TypeScript
import React, { useState } from "react";
|
|
import { useNavigate } from "react-router-dom";
|
|
import { useAuth } from "../context/AuthContext";
|
|
|
|
function AuthForm({ isLogin, onToggle }: { isLogin: boolean; onToggle: () => void }) {
|
|
const [email, setEmail] = useState("");
|
|
const [password, setPassword] = useState("");
|
|
const [confirmPassword, setConfirmPassword] = useState("");
|
|
const [error, setError] = useState<string | null>(null);
|
|
const [loading, setLoading] = useState(false);
|
|
const { login, register } = useAuth();
|
|
const navigate = useNavigate();
|
|
|
|
const handleSubmit = async (e: React.FormEvent) => {
|
|
e.preventDefault(); setError(null);
|
|
if (!isLogin && password !== confirmPassword) { setError("Passwords do not match."); return; }
|
|
setLoading(true);
|
|
try {
|
|
if (isLogin) await login(email, password);
|
|
else await register(email, password);
|
|
navigate("/");
|
|
} catch (err) { setError(err instanceof Error ? err.message : isLogin ? "Login failed" : "Registration failed"); }
|
|
finally { setLoading(false); }
|
|
};
|
|
|
|
return (
|
|
<div style={{ display: "flex", justifyContent: "center", alignItems: "center", minHeight: "100vh", background: "#f8f9fa", padding: 16 }}>
|
|
<div style={{ width: "100%", maxWidth: 400, background: "#fff", borderRadius: 12, padding: 32, boxShadow: "0 2px 16px rgba(0,0,0,0.08)" }}>
|
|
<h1 style={{ fontSize: 28, fontWeight: 700, color: "#1a1a2e", textAlign: "center", marginBottom: 4 }}>Cloud Reader</h1>
|
|
<h2 style={{ fontSize: 16, color: "#888", textAlign: "center", marginBottom: 24, fontWeight: 400 }}>{isLogin ? "Sign In" : "Create Account"}</h2>
|
|
<form onSubmit={handleSubmit} style={{ display: "flex", flexDirection: "column", gap: 16 }}>
|
|
{error && <div style={{ background: "#fde8e8", padding: 12, borderRadius: 6, color: "#e74c3c", fontSize: 14 }}>{error}</div>}
|
|
<div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
|
|
<label style={{ fontSize: 14, fontWeight: 600, color: "#555" }}>Email</label>
|
|
<input type="email" value={email} onChange={(e) => setEmail(e.target.value)} placeholder="you@example.com" required style={{ padding: "10px 12px", borderRadius: 6, border: "1px solid #ddd", fontSize: 16, outline: "none" }} />
|
|
</div>
|
|
<div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
|
|
<label style={{ fontSize: 14, fontWeight: 600, color: "#555" }}>Password</label>
|
|
<input type="password" value={password} onChange={(e) => setPassword(e.target.value)} placeholder="At least 8 characters" required minLength={8} style={{ padding: "10px 12px", borderRadius: 6, border: "1px solid #ddd", fontSize: 16, outline: "none" }} />
|
|
</div>
|
|
{!isLogin && <div style={{ display: "flex", flexDirection: "column", gap: 6 }}>
|
|
<label style={{ fontSize: 14, fontWeight: 600, color: "#555" }}>Confirm Password</label>
|
|
<input type="password" value={confirmPassword} onChange={(e) => setConfirmPassword(e.target.value)} placeholder="Repeat your password" required minLength={8} style={{ padding: "10px 12px", borderRadius: 6, border: "1px solid #ddd", fontSize: 16, outline: "none" }} />
|
|
</div>}
|
|
<button type="submit" disabled={loading} style={{ padding: "12px 24px", borderRadius: 8, border: "none", background: "#1a1a2e", color: "#fff", fontSize: 16, fontWeight: 600, cursor: "pointer", opacity: loading ? 0.6 : 1, marginTop: 8 }}>{loading ? (isLogin ? "Signing in..." : "Creating account...") : (isLogin ? "Sign In" : "Create Account")}</button>
|
|
</form>
|
|
<p style={{ textAlign: "center", marginTop: 20, color: "#888", fontSize: 14 }}>
|
|
{isLogin ? "Don't have an account? " : "Already have an account? "}
|
|
<button onClick={onToggle} style={{ background: "none", border: "none", color: "#1a1a2e", fontWeight: 600, cursor: "pointer", fontSize: 14, textDecoration: "underline" }}>{isLogin ? "Register" : "Sign In"}</button>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export function LoginPage({ onToggle }: { onToggle: () => void }) { return <AuthForm isLogin={true} onToggle={onToggle} />; }
|
|
export function RegisterPage({ onToggle }: { onToggle: () => void }) { return <AuthForm isLogin={false} onToggle={onToggle} />; } |