60 lines
2.1 KiB
TypeScript
60 lines
2.1 KiB
TypeScript
"use client";
|
|
import { useState } from "react";
|
|
import Link from "next/link";
|
|
import { useRouter } from "next/navigation";
|
|
import AuthShell, { Field } from "@/components/AuthShell";
|
|
import { GoogleButton, OrDivider } from "@/components/GoogleAuth";
|
|
import { api, setToken } from "@/lib/api";
|
|
import { useLanguage } from "@/contexts/LanguageContext";
|
|
|
|
export default function Login() {
|
|
const r = useRouter();
|
|
const [email, setEmail] = useState("");
|
|
const [password, setPassword] = useState("");
|
|
const [err, setErr] = useState("");
|
|
const [loading, setLoading] = useState(false);
|
|
const { setLang } = useLanguage();
|
|
|
|
|
|
async function submit(e: React.FormEvent) {
|
|
e.preventDefault();
|
|
setErr(""); setLoading(true);
|
|
try {
|
|
const res = await api("/auth/login", {
|
|
method: "POST", body: JSON.stringify({ email, password }),
|
|
});
|
|
r.push(`/login-otp?email=${encodeURIComponent(email)}`);
|
|
return;
|
|
} catch (e: any) {
|
|
setErr(
|
|
typeof e.detail === "string"
|
|
? e.detail
|
|
: "Invalid email or password"
|
|
);
|
|
} finally {
|
|
setLoading(false);
|
|
}
|
|
}
|
|
|
|
|
|
return (
|
|
<AuthShell title="Log in" subtitle="Welcome back to VerifyPack">
|
|
<GoogleButton label="Log in with Google" />
|
|
<OrDivider text="Or, log in with your email" />
|
|
<form onSubmit={submit}>
|
|
<Field label="Email" type="email" value={email} onChange={(e: any) => setEmail(e.target.value)} required />
|
|
<Field label="Password" type="password" value={password} onChange={(e: any) => setPassword(e.target.value)} required />
|
|
{err && <p className="text-sm text-rose-600 mb-3">{err}</p>}
|
|
<button disabled={loading}
|
|
className="w-full bg-brand-600 text-white py-3 rounded-full font-semibold disabled:opacity-60">
|
|
{loading ? "Signing in..." : "Log in"}
|
|
</button>
|
|
</form>
|
|
<div className="flex justify-between mt-5 text-sm">
|
|
<Link href="/forgot-password" className="text-brand-600">Forgot password?</Link>
|
|
<Link href="/signup" className="text-brand-600 font-semibold">Create account</Link>
|
|
</div>
|
|
</AuthShell>
|
|
);
|
|
}
|