first commit

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
root
2026-05-10 19:20:03 +00:00
parent 1050bb39ec
commit a3f08242fe
58 changed files with 5803 additions and 261 deletions

View File

@@ -0,0 +1,79 @@
"use client";
import { signIn } from "next-auth/react";
import Link from "next/link";
import { useRouter } from "next/navigation";
import { useState } from "react";
export function LoginForm({ callbackUrl }: { callbackUrl: string }) {
const router = useRouter();
const [email, setEmail] = useState("");
const [password, setPassword] = useState("");
const [error, setError] = useState<string | null>(null);
const [busy, setBusy] = useState(false);
const submit = async (e: React.FormEvent) => {
e.preventDefault();
setBusy(true);
setError(null);
const res = await signIn("credentials", {
email,
password,
redirect: false,
callbackUrl,
});
setBusy(false);
if (res?.error) {
setError("Invalid email or password.");
return;
}
router.push(callbackUrl);
router.refresh();
};
return (
<div className="mx-auto flex min-h-[70vh] max-w-lg flex-col justify-center px-4 py-16 sm:px-6">
<h1 className="text-3xl font-semibold text-white">Sign in</h1>
<p className="mt-2 text-sm text-slate-400">
Demo account from seed: <code className="rounded bg-white/10 px-2 py-0.5">demo@local.dev</code> /{" "}
<code className="rounded bg-white/10 px-2 py-0.5">demo1234</code>
</p>
<form onSubmit={submit} className="mt-8 space-y-4">
<label className="block text-sm text-slate-300">
Email
<input
type="email"
required
value={email}
onChange={(e) => setEmail(e.target.value)}
className="mt-2 w-full rounded-xl border border-white/10 bg-black/30 px-4 py-3 text-white outline-none ring-sky-500/40 focus:ring"
/>
</label>
<label className="block text-sm text-slate-300">
Password
<input
type="password"
required
value={password}
onChange={(e) => setPassword(e.target.value)}
className="mt-2 w-full rounded-xl border border-white/10 bg-black/30 px-4 py-3 text-white outline-none ring-sky-500/40 focus:ring"
/>
</label>
{error ? <p className="text-sm text-rose-300">{error}</p> : null}
<button
type="submit"
disabled={busy}
className="w-full rounded-2xl bg-gradient-to-r from-sky-500 to-indigo-500 py-3 font-semibold text-white shadow-lg shadow-indigo-500/25 disabled:opacity-50"
>
{busy ? "Signing in…" : "Continue"}
</button>
</form>
<p className="mt-6 text-sm text-slate-400">
No account?{" "}
<Link className="text-sky-300 hover:underline" href="/register">
Create one
</Link>
</p>
</div>
);
}