Files
group-2-threaded-project-pe…/web/app/login/page.js
augmentedpotato 4bd98ef06f Improve auth flows
2026-04-03 14:52:32 -06:00

93 lines
2.5 KiB
JavaScript

"use client";
import dynamic from "next/dynamic";
import Link from "next/link";
import { useState } from "react";
import { useRouter, useSearchParams } from "next/navigation";
import { useAuth } from "@/context/AuthContext";
function resolveNextPath(candidate) {
if (!candidate || !candidate.startsWith("/")) {
return "/";
}
if (candidate.startsWith("//") || candidate.startsWith("/login") || candidate.startsWith("/register")) {
return "/";
}
return candidate;
}
function LoginPage() {
const {login} = useAuth();
const router = useRouter();
const searchParams = useSearchParams();
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState("");
const [loading, setLoading] = useState(false);
async function handleSubmit(e) {
e.preventDefault();
setError("");
setLoading(true);
try {
await login(username, password);
router.push(resolveNextPath(searchParams.get("next")));
}
catch (err) {
setError(err.message);
}
finally {
setLoading(false);
}
}
return (
<main className="auth-page">
<div className="auth-card">
<h1 className="auth-title">Log In</h1>
{error && <p className="auth-error">{error}</p>}
<form className="auth-form" onSubmit={handleSubmit}>
<label className="auth-label">
Username
<input className="auth-input"
type="text"
value={username}
onChange={(e) => setUsername(e.target.value)}
required
autoComplete="username"/>
</label>
<label className="auth-label">
Password
<input className="auth-input"
type="password"
value={password}
onChange={(e) => setPassword(e.target.value)}
required
autoComplete="current-password"/>
</label>
<button className="auth-submit-btn" type="submit" disabled={loading}>
{loading ? "Logging in…" : "Log In"}
</button>
</form>
<p className="auth-switch">
Don&apos;t have an account?{" "}
<Link href={searchParams.get("next") ? `/register?next=${encodeURIComponent(searchParams.get("next"))}` : "/register"} className="auth-switch-link">Register here</Link>
</p>
</div>
</main>
);
}
export default dynamic(() => Promise.resolve(LoginPage), {
ssr: false,
});