-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Ivo
committed
Apr 23, 2023
1 parent
9b03c48
commit 5e0fe33
Showing
11 changed files
with
255 additions
and
25 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,19 @@ | ||
{ | ||
"title": "Sign In" | ||
"title": "Sign In", | ||
"identifier": { | ||
"title": "Email or Username", | ||
"placeholder": "user@uni.edu", | ||
"errors": { | ||
"empty": "Can't be empty" | ||
} | ||
}, | ||
"password": { | ||
"title": "Password", | ||
"placeholder": "********", | ||
"errors": { | ||
"empty": "Can't be empty" | ||
} | ||
}, | ||
"lost-password": "I forgot my password", | ||
"new-user": "Register" | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
{ | ||
"title": "Sign Up", | ||
"errors": { | ||
"user": { | ||
"existing": "There's a user with this email or username already." | ||
} | ||
}, | ||
"email": { | ||
"title": "Email", | ||
"placeholder": "user@uni.edu", | ||
"errors": { | ||
"disallowed": "You must use your institutional email", | ||
"empty": "Can't be empty", | ||
"invalid": "This is not a valid email address" | ||
} | ||
}, | ||
"password": { | ||
"title": "Password", | ||
"placeholder": "********", | ||
"errors": { | ||
"empty": "Can't be empty" | ||
} | ||
}, | ||
"username": { | ||
"title": "Username", | ||
"placeholder": "johndoe", | ||
"errors": { | ||
"empty": "Can't be empty" | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,110 @@ | ||
import { useEffect, useState } from "react"; | ||
import { SubmitHandler, useForm } from "react-hook-form"; | ||
import { zodResolver } from "@hookform/resolvers/zod"; | ||
import axios from "axios"; | ||
import { AlertTriangle, UserPlus } from "lucide-react"; | ||
import { useRouter } from "next/router"; | ||
import { useTranslation } from "next-i18next"; | ||
|
||
import { Button } from "@app/components/Button"; | ||
import { Input } from "@app/components/Input"; | ||
import { Spinner } from "@app/components/Spinner"; | ||
import { | ||
SignUpFormSchema, | ||
SignUpFormSchemaType | ||
} from "@app/schemas/components/auth/signup.zod"; | ||
|
||
export function SignUpForm() { | ||
const { t } = useTranslation(["signup"]); | ||
const [isSigningUp, setIsSigningUp] = useState(false); | ||
const [signUpStatus, setSignUpStatus] = useState< | ||
| { | ||
status: "success"; | ||
} | ||
| { | ||
status: "error"; | ||
errorMessage: string; | ||
} | ||
>(); | ||
const { | ||
register, | ||
reset, | ||
formState: { errors }, | ||
handleSubmit | ||
} = useForm<SignUpFormSchemaType>({ | ||
resolver: zodResolver(SignUpFormSchema) | ||
}); | ||
const router = useRouter(); | ||
|
||
useEffect(() => { | ||
if (signUpStatus?.status === "success") { | ||
router.push("/signin"); | ||
} | ||
// eslint-disable-next-line react-hooks/exhaustive-deps | ||
}, [signUpStatus]); | ||
|
||
const handleAuth: SubmitHandler<SignUpFormSchemaType> = async ({ | ||
email, | ||
username, | ||
password | ||
}) => { | ||
setIsSigningUp(true); | ||
axios | ||
.post("/api/users/signup", { | ||
email, | ||
username, | ||
password | ||
}) | ||
.then(() => { | ||
setSignUpStatus({ status: "success" }); | ||
reset(); | ||
}) | ||
.catch(({ response }) => | ||
setSignUpStatus({ status: "error", errorMessage: response.data.status }) | ||
) | ||
.finally(() => setIsSigningUp(false)); | ||
}; | ||
|
||
return ( | ||
<form | ||
className="flex flex-col gap-y-2.5 lg:mx-auto lg:w-1/2" | ||
onSubmit={handleSubmit(handleAuth)} | ||
> | ||
{signUpStatus?.status === "error" ? ( | ||
<div className="flex gap-x-2 rounded-lg border border-red-500 bg-red-400/20 p-2"> | ||
<AlertTriangle className="stroke-red-600 dark:stroke-red-200" /> | ||
<p className="text-red-600 dark:text-red-200"> | ||
{t(`signup:errors.${signUpStatus.errorMessage}`)} | ||
</p> | ||
</div> | ||
) : null} | ||
<Input | ||
error={errors.username} | ||
label={t("signup:username.title")} | ||
placeholder={t("signup:username.placeholder")} | ||
{...register("username")} | ||
/> | ||
<Input | ||
error={errors.email} | ||
label={t("signup:email.title")} | ||
placeholder={t("signup:email.placeholder")} | ||
{...register("email")} | ||
/> | ||
<Input | ||
error={errors.password} | ||
label={t("signup:password.title")} | ||
placeholder={t("signup:password.placeholder")} | ||
type="password" | ||
{...register("password")} | ||
/> | ||
<Button | ||
disabled={isSigningUp} | ||
LeftIcon={!isSigningUp ? UserPlus : undefined} | ||
type="submit" | ||
> | ||
{isSigningUp ? <Spinner /> : null} | ||
{t("signup:title")} | ||
</Button> | ||
</form> | ||
); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
import dynamic from "next/dynamic"; | ||
import { useTranslation } from "next-i18next"; | ||
|
||
import { SEO } from "@app/components/SEO"; | ||
import { Spinner } from "@app/components/Spinner"; | ||
import { withSSRGuest } from "@app/hocs/withSSRGuest"; | ||
import { withSSRTranslations } from "@app/hocs/withSSRTranslations"; | ||
|
||
const SignUpForm = dynamic( | ||
() => import("@app/components/Forms/SignUp").then((mod) => mod.SignUpForm), | ||
{ | ||
loading: () => ( | ||
<div className="flex flex-1 items-center justify-center"> | ||
<Spinner /> | ||
</div> | ||
), | ||
ssr: false | ||
} | ||
); | ||
|
||
export const getServerSideProps = withSSRTranslations(withSSRGuest(), { | ||
namespaces: ["signup"] | ||
}); | ||
|
||
export default function SignUp() { | ||
const { t } = useTranslation(["signup"]); | ||
|
||
return ( | ||
<> | ||
<SEO | ||
title={t("signup:title")} | ||
description={t("signup:description")} | ||
/> | ||
<h2 className="text-center text-2xl font-bold uppercase text-primary-700 dark:text-primary-400"> | ||
{t("signup:title")} | ||
</h2> | ||
<SignUpForm /> | ||
</> | ||
); | ||
} |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
import { z } from "zod"; | ||
|
||
export const SignInFormSchema = z.object({ | ||
identifier: z.string().min(1, "signin:identifier.errors.empty"), | ||
password: z.string().min(1, "signin:password.errors.empty") | ||
}); | ||
|
||
export type SignInFormSchemaType = z.infer<typeof SignInFormSchema>; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import { z } from "zod"; | ||
|
||
export const SignUpFormSchema = z.object({ | ||
username: z.string().min(1, "signup:username.errors.empty"), | ||
email: z | ||
.string() | ||
.min(1, "signup:email.errors.empty") | ||
.email("signup:email.errors.invalid") | ||
.regex( | ||
new RegExp( | ||
"[a-z0-9]+@(?!gmail|yahoo|qq|yandex|hotmail|outlook|123|126|163).[a-z0-9]+" | ||
), | ||
"signup:email.errors.disallowed" | ||
), | ||
password: z.string().min(1, "signup:password.errors.empty") | ||
}); | ||
|
||
export type SignUpFormSchemaType = z.infer<typeof SignUpFormSchema>; |