131 lines
4.3 KiB
TypeScript
131 lines
4.3 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import { signIn } from "next-auth/react";
|
|
|
|
export default function AuthPage() {
|
|
const [loginEmail, setLoginEmail] = useState("");
|
|
const [loginPassword, setLoginPassword] = useState("");
|
|
const [loginMessage, setLoginMessage] = useState("");
|
|
const [loginLoading, setLoginLoading] = useState(false);
|
|
|
|
const [name, setName] = useState("");
|
|
const [signupEmail, setSignupEmail] = useState("");
|
|
const [signupPassword, setSignupPassword] = useState("");
|
|
const [slug, setSlug] = useState("storeshifted");
|
|
const [signupMessage, setSignupMessage] = useState("");
|
|
const [signupLoading, setSignupLoading] = useState(false);
|
|
|
|
async function handleLogin(e: React.FormEvent) {
|
|
e.preventDefault();
|
|
setLoginLoading(true);
|
|
setLoginMessage("");
|
|
const res = await signIn("credentials", {
|
|
email: loginEmail,
|
|
password: loginPassword,
|
|
redirect: true,
|
|
callbackUrl: "/connect",
|
|
});
|
|
if (res?.error) setLoginMessage("Invalid credentials.");
|
|
setLoginLoading(false);
|
|
}
|
|
|
|
async function handleSignup(e: React.FormEvent) {
|
|
e.preventDefault();
|
|
setSignupLoading(true);
|
|
setSignupMessage("");
|
|
try {
|
|
const res = await fetch("/api/auth/signup", {
|
|
method: "POST",
|
|
headers: { "Content-Type": "application/json" },
|
|
body: JSON.stringify({
|
|
name,
|
|
email: signupEmail,
|
|
password: signupPassword,
|
|
slug,
|
|
}),
|
|
});
|
|
const data = await res.json();
|
|
if (!res.ok) throw new Error(data.error || "Sign up failed");
|
|
|
|
await signIn("credentials", {
|
|
email: signupEmail,
|
|
password: signupPassword,
|
|
redirect: true,
|
|
callbackUrl: "/connect",
|
|
});
|
|
} catch (err: any) {
|
|
setSignupMessage(err.message || "Sign up failed.");
|
|
} finally {
|
|
setSignupLoading(false);
|
|
}
|
|
}
|
|
|
|
return (
|
|
<main className="auth-page">
|
|
<section className="section">
|
|
<div className="container auth-page__inner auth-page__inner--wide">
|
|
<h1 className="page-title">Sign In / Sign Up</h1>
|
|
<div className="auth-page__grid">
|
|
<form className="auth-card" onSubmit={handleLogin}>
|
|
<h2>Sign In</h2>
|
|
<input
|
|
type="email"
|
|
placeholder="Email"
|
|
value={loginEmail}
|
|
onChange={(e) => setLoginEmail(e.target.value)}
|
|
/>
|
|
<input
|
|
type="password"
|
|
placeholder="Password"
|
|
value={loginPassword}
|
|
onChange={(e) => setLoginPassword(e.target.value)}
|
|
/>
|
|
<button className="btn" type="submit" disabled={loginLoading}>
|
|
{loginLoading ? "Signing in..." : "Sign in"}
|
|
</button>
|
|
{loginMessage ? <div className="connect-message">{loginMessage}</div> : null}
|
|
</form>
|
|
|
|
<form className="auth-card" onSubmit={handleSignup}>
|
|
<h2>Create Account</h2>
|
|
<input
|
|
type="text"
|
|
placeholder="Name"
|
|
value={name}
|
|
onChange={(e) => setName(e.target.value)}
|
|
/>
|
|
<input
|
|
type="email"
|
|
placeholder="Email"
|
|
value={signupEmail}
|
|
onChange={(e) => setSignupEmail(e.target.value)}
|
|
/>
|
|
<input
|
|
type="password"
|
|
placeholder="Password"
|
|
value={signupPassword}
|
|
onChange={(e) => setSignupPassword(e.target.value)}
|
|
/>
|
|
<input
|
|
type="text"
|
|
placeholder="Store slug (e.g. storeshifted)"
|
|
value={slug}
|
|
onChange={(e) => setSlug(e.target.value)}
|
|
/>
|
|
<button className="btn" type="submit" disabled={signupLoading}>
|
|
{signupLoading ? "Creating..." : "Create account"}
|
|
</button>
|
|
{signupMessage ? <div className="connect-message">{signupMessage}</div> : null}
|
|
</form>
|
|
</div>
|
|
|
|
<div className="connect-muted" style={{ marginTop: 12 }}>
|
|
Just shopping? <a href="/signup/customer">Create a customer account</a>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</main>
|
|
);
|
|
}
|