makearmy-app/app/auth/sign-up/page.tsx

91 lines
3.7 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// app/app/auth/sign-up/page.tsx
"use client";
import { useState } from "react";
import { useRouter } from "next/navigation";
export default function SignUpPage() {
const r = useRouter();
const [form, setForm] = useState({ username: "", email: "", password: "", agree: false });
const [busy, setBusy] = useState(false);
const [err, setErr] = useState<string | null>(null);
const canSubmit = form.username.length >= 3 && form.password.length >= 8 && form.agree && !busy;
async function submit() {
setBusy(true); setErr(null);
try {
const res = await fetch("/api/auth/register", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
username: form.username.trim(),
email: form.email.trim() || undefined,
password: form.password,
}),
});
const j = await res.json();
if (!res.ok) throw new Error(j?.error || "Sign up failed");
// Auto-login right after register
const login = await fetch("/api/auth/login", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify({ identifier: form.email.trim() || form.username.trim(), password: form.password }),
});
const lj = await login.json();
if (!login.ok) throw new Error(lj?.error || "Auto login failed");
r.replace("/my/rigs"); // or wherever you want to land
} catch (e: any) {
setErr(e?.message || "Error");
} finally {
setBusy(false);
}
}
return (
<div className="max-w-md mx-auto p-6 space-y-4">
<h1 className="text-2xl font-semibold">Create Account</h1>
<label className="block">
<div className="text-sm mb-1">Username *</div>
<input className="w-full border rounded px-3 py-2" value={form.username}
onChange={e=>setForm({...form, username:e.target.value})} />
<p className="text-xs text-muted-foreground mt-1">Used for login if you dont provide an email.</p>
</label>
<label className="block">
<div className="text-sm mb-1">Email (optional)</div>
<input type="email" className="w-full border rounded px-3 py-2" value={form.email}
onChange={e=>setForm({...form, email:e.target.value})} />
<p className="text-xs text-muted-foreground mt-1">
If you skip this, we cant reset your password later.
</p>
</label>
<label className="block">
<div className="text-sm mb-1">Password *</div>
<input type="password" className="w-full border rounded px-3 py-2" value={form.password}
onChange={e=>setForm({...form, password:e.target.value})} />
</label>
<label className="flex items-start gap-2 text-sm">
<input type="checkbox" className="mt-1" checked={form.agree}
onChange={e=>setForm({...form, agree:e.target.checked})} />
<span>I understand that without an email on file, my account cant be recovered if I lose the password.</span>
</label>
{err && <div className="text-sm text-red-600">{err}</div>}
<button disabled={!canSubmit} onClick={submit}
className="px-3 py-2 rounded bg-black text-white disabled:opacity-50">
{busy ? "Creating..." : "Create account"}
</button>
<div className="text-sm">
Already have an account?{" "}
<a href="/auth/sign-in" className="underline">Sign in</a>
</div>
</div>
);
}