mirror of
https://github.com/Ategon/Jamjar.git
synced 2025-02-12 06:16:21 +00:00
Add sign up
This commit is contained in:
parent
aaa9305c09
commit
2178675f2a
7 changed files with 110 additions and 35 deletions
25
package-lock.json
generated
25
package-lock.json
generated
|
@ -15,7 +15,8 @@
|
|||
"lucide-react": "^0.453.0",
|
||||
"next": "15.0.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
"react-dom": "^18.2.0",
|
||||
"react-toastify": "^11.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20",
|
||||
|
@ -7605,6 +7606,28 @@
|
|||
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/react-toastify": {
|
||||
"version": "11.0.3",
|
||||
"resolved": "https://registry.npmjs.org/react-toastify/-/react-toastify-11.0.3.tgz",
|
||||
"integrity": "sha512-cbPtHJPfc0sGqVwozBwaTrTu1ogB9+BLLjd4dDXd863qYLj7DGrQ2sg5RAChjFUB4yc3w8iXOtWcJqPK/6xqRQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"clsx": "^2.1.1"
|
||||
},
|
||||
"peerDependencies": {
|
||||
"react": "^18 || ^19",
|
||||
"react-dom": "^18 || ^19"
|
||||
}
|
||||
},
|
||||
"node_modules/react-toastify/node_modules/clsx": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/clsx/-/clsx-2.1.1.tgz",
|
||||
"integrity": "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/read-cache": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/read-cache/-/read-cache-1.0.0.tgz",
|
||||
|
|
|
@ -16,7 +16,8 @@
|
|||
"lucide-react": "^0.453.0",
|
||||
"next": "15.0.1",
|
||||
"react": "^18.2.0",
|
||||
"react-dom": "^18.2.0"
|
||||
"react-dom": "^18.2.0",
|
||||
"react-toastify": "^11.0.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^20",
|
||||
|
|
|
@ -3,6 +3,7 @@ import { Inter } from "next/font/google";
|
|||
import "./globals.css";
|
||||
import Navbar from "../components/navbar";
|
||||
import Providers from "./providers";
|
||||
import { ToastContainer } from "react-toastify";
|
||||
|
||||
const inter = Inter({ subsets: ["latin"] });
|
||||
|
||||
|
@ -24,6 +25,7 @@ export default function RootLayout({
|
|||
<div className="bg-zinc-100 dark:bg-zinc-950 min-h-screen">
|
||||
<Navbar />
|
||||
<div className="max-w-8xl mx-auto">{children}</div>
|
||||
<ToastContainer />
|
||||
</div>
|
||||
</div>
|
||||
</Providers>
|
||||
|
|
|
@ -3,23 +3,43 @@
|
|||
import { Button, Form, Input } from "@nextui-org/react";
|
||||
import { redirect } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { toast } from "react-toastify";
|
||||
|
||||
export default function UserPage() {
|
||||
const [username, setUsername] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
const [error, setError] = useState("");
|
||||
const [errors, setErrors] = useState({});
|
||||
|
||||
return (
|
||||
<div className="absolute flex items-center justify-center top-0 left-0 w-screen h-screen">
|
||||
<Form
|
||||
className="w-full max-w-xs flex flex-col gap-4"
|
||||
validationBehavior="native"
|
||||
validationErrors={errors}
|
||||
onReset={() => {
|
||||
setUsername("");
|
||||
setPassword("");
|
||||
}}
|
||||
onSubmit={async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (!username && !password) {
|
||||
setErrors({
|
||||
username: "Please enter a valid username",
|
||||
password: "Please enter a valid password",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
if (!username) {
|
||||
setErrors({ username: "Please enter a valid username" });
|
||||
return;
|
||||
}
|
||||
|
||||
if (!password) {
|
||||
setErrors({ password: "Please enter a valid password" });
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
process.env.NEXT_PUBLIC_MODE === "PROD"
|
||||
? "https://d2jam.com/api/v1/login"
|
||||
|
@ -32,7 +52,7 @@ export default function UserPage() {
|
|||
);
|
||||
|
||||
if (response.status == 401) {
|
||||
setError("Invalid username or password");
|
||||
setErrors({ password: "Invalid username or password" });
|
||||
setPassword("");
|
||||
return;
|
||||
}
|
||||
|
@ -40,12 +60,13 @@ export default function UserPage() {
|
|||
const token = await response.json();
|
||||
document.cookie = `token=${token}`;
|
||||
|
||||
toast.success("Successfully logged in");
|
||||
|
||||
redirect("/");
|
||||
}}
|
||||
>
|
||||
<Input
|
||||
isRequired
|
||||
errorMessage="Please enter a valid username"
|
||||
label="Username"
|
||||
labelPlacement="outside"
|
||||
name="username"
|
||||
|
@ -57,7 +78,6 @@ export default function UserPage() {
|
|||
|
||||
<Input
|
||||
isRequired
|
||||
errorMessage="Please enter a valid password"
|
||||
label="Password"
|
||||
labelPlacement="outside"
|
||||
name="password"
|
||||
|
@ -74,9 +94,6 @@ export default function UserPage() {
|
|||
Reset
|
||||
</Button>
|
||||
</div>
|
||||
<p>Sign up is being worked on currently</p>
|
||||
{error && <p className="text-red-500">{error}</p>}
|
||||
{}
|
||||
</Form>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -2,11 +2,14 @@
|
|||
|
||||
import { redirect } from "next/navigation";
|
||||
import React, { useEffect } from "react";
|
||||
import { toast } from "react-toastify";
|
||||
|
||||
export default function UserPage() {
|
||||
useEffect(() => {
|
||||
document.cookie = "token=; expires=Thu, 01 Jan 1970 00:00:00 UTC; path=/;";
|
||||
|
||||
toast.success("Successfully logged out");
|
||||
|
||||
redirect("/");
|
||||
});
|
||||
|
||||
|
|
|
@ -3,28 +3,67 @@
|
|||
import { Button, Form, Input } from "@nextui-org/react";
|
||||
import { redirect } from "next/navigation";
|
||||
import { useState } from "react";
|
||||
import { toast } from "react-toastify";
|
||||
|
||||
export default function UserPage() {
|
||||
const [username, setUsername] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
//const [password2, setPassword2] = useState("");
|
||||
const [error, setError] = useState("");
|
||||
const [password2, setPassword2] = useState("");
|
||||
const [errors, setErrors] = useState({});
|
||||
|
||||
return (
|
||||
<div className="absolute flex items-center justify-center top-0 left-0 w-screen h-screen">
|
||||
<Form
|
||||
className="w-full max-w-xs flex flex-col gap-4"
|
||||
validationBehavior="native"
|
||||
validationErrors={errors}
|
||||
onReset={() => {
|
||||
setUsername("");
|
||||
setPassword("");
|
||||
setPassword2("");
|
||||
}}
|
||||
onSubmit={async (e) => {
|
||||
e.preventDefault();
|
||||
|
||||
if (!password || !username || !password2) {
|
||||
const localErrors: Record<string, string> = {};
|
||||
|
||||
if (password && password.length < 8) {
|
||||
setPassword2("");
|
||||
setErrors({ password: "Password must be minimum 8 characters" });
|
||||
return;
|
||||
}
|
||||
|
||||
if (!password) {
|
||||
localErrors["password"] = "Please enter a valid password";
|
||||
}
|
||||
|
||||
if (!password2) {
|
||||
localErrors["password2"] = "Please reenter your password";
|
||||
}
|
||||
|
||||
if (!username) {
|
||||
localErrors["username"] = "Please enter a valid username";
|
||||
}
|
||||
setErrors(localErrors);
|
||||
return;
|
||||
}
|
||||
|
||||
if (password.length < 8) {
|
||||
setPassword2("");
|
||||
setErrors({ password: "Password must be minimum 8 characters" });
|
||||
return;
|
||||
}
|
||||
|
||||
if (password != password2) {
|
||||
setPassword2("");
|
||||
setErrors({ password2: "Passwords do not match" });
|
||||
return;
|
||||
}
|
||||
|
||||
const response = await fetch(
|
||||
process.env.NEXT_PUBLIC_MODE === "PROD"
|
||||
? "https://d2jam.com/api/v1/login"
|
||||
: "http://localhost:3005/api/v1/login",
|
||||
? "https://d2jam.com/api/v1/signup"
|
||||
: "http://localhost:3005/api/v1/signup",
|
||||
{
|
||||
body: JSON.stringify({ username: username, password: password }),
|
||||
method: "POST",
|
||||
|
@ -32,21 +71,16 @@ export default function UserPage() {
|
|||
}
|
||||
);
|
||||
|
||||
if (response.status == 401) {
|
||||
setError("Invalid username or password");
|
||||
setPassword("");
|
||||
return;
|
||||
}
|
||||
|
||||
const token = await response.json();
|
||||
document.cookie = `token=${token}`;
|
||||
|
||||
toast.success("Successfully signed up");
|
||||
|
||||
redirect("/");
|
||||
}}
|
||||
>
|
||||
<Input
|
||||
isRequired
|
||||
errorMessage="Please enter a valid username"
|
||||
label="Username"
|
||||
labelPlacement="outside"
|
||||
name="username"
|
||||
|
@ -58,7 +92,6 @@ export default function UserPage() {
|
|||
|
||||
<Input
|
||||
isRequired
|
||||
errorMessage="Please enter a valid password"
|
||||
label="Password"
|
||||
labelPlacement="outside"
|
||||
name="password"
|
||||
|
@ -69,14 +102,13 @@ export default function UserPage() {
|
|||
/>
|
||||
<Input
|
||||
isRequired
|
||||
errorMessage="Please enter a valid password"
|
||||
label="Password"
|
||||
label="Password Confirmation"
|
||||
labelPlacement="outside"
|
||||
name="password"
|
||||
placeholder="Enter your password"
|
||||
name="password2"
|
||||
placeholder="Reenter your password"
|
||||
type="password"
|
||||
value={password}
|
||||
onValueChange={setPassword}
|
||||
value={password2}
|
||||
onValueChange={setPassword2}
|
||||
/>
|
||||
<div className="flex gap-2">
|
||||
<Button color="primary" type="submit">
|
||||
|
@ -86,9 +118,6 @@ export default function UserPage() {
|
|||
Reset
|
||||
</Button>
|
||||
</div>
|
||||
<p>Sign up is being worked on currently</p>
|
||||
{error && <p className="text-red-500">{error}</p>}
|
||||
{}
|
||||
</Form>
|
||||
</div>
|
||||
);
|
||||
|
|
|
@ -19,7 +19,7 @@ import {
|
|||
Tooltip,
|
||||
} from "@nextui-org/react";
|
||||
import { SiDiscord, SiForgejo, SiGithub } from "@icons-pack/react-simple-icons";
|
||||
import { LogInIcon } from "lucide-react";
|
||||
import { LogInIcon, NotebookPen } from "lucide-react";
|
||||
import { useEffect, useState } from "react";
|
||||
import { hasCookie, getCookies } from "@/helpers/cookie";
|
||||
import { usePathname } from "next/navigation";
|
||||
|
@ -139,7 +139,7 @@ export default function Navbar() {
|
|||
</Button>
|
||||
</Link>
|
||||
</NavbarItem>
|
||||
{/* <NavbarItem>
|
||||
<NavbarItem>
|
||||
<Link href="/signup">
|
||||
<Button
|
||||
endContent={<NotebookPen />}
|
||||
|
@ -149,7 +149,7 @@ export default function Navbar() {
|
|||
Sign up
|
||||
</Button>
|
||||
</Link>
|
||||
</NavbarItem> */}
|
||||
</NavbarItem>
|
||||
</div>
|
||||
) : (
|
||||
<Dropdown>
|
||||
|
|
Loading…
Reference in a new issue