Implement Auth
This commit is contained in:
@@ -1,3 +1,5 @@
|
||||
const roles = [{ uid: "admin" }, { uid: "moderator" }, { uid: "user" }];
|
||||
|
||||
const categoricalPalette = [
|
||||
"#fba91e",
|
||||
"#6ea56c",
|
||||
@@ -63,6 +65,7 @@ const testRunCaseStatus = [
|
||||
];
|
||||
|
||||
export {
|
||||
roles,
|
||||
priorities,
|
||||
testTypes,
|
||||
automationStatus,
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
"docs": "Docs",
|
||||
"projects": "Projects"
|
||||
},
|
||||
"Auth": {
|
||||
"signup": "Sign up",
|
||||
"signin": "Sign in"
|
||||
},
|
||||
"Projects": {
|
||||
"projectList": "Project List",
|
||||
"project": "Project",
|
||||
|
||||
@@ -24,6 +24,10 @@
|
||||
"docs": "ドキュメント",
|
||||
"projects": "プロジェクト"
|
||||
},
|
||||
"Auth": {
|
||||
"signup": "サインアップ",
|
||||
"signin": "サインイン"
|
||||
},
|
||||
"Projects": {
|
||||
"projectList": "プロジェクト一覧",
|
||||
"project": "プロジェクト",
|
||||
|
||||
53
frontend/src/app/[locale]/auth/authControl.ts
Normal file
53
frontend/src/app/[locale]/auth/authControl.ts
Normal file
@@ -0,0 +1,53 @@
|
||||
import { UserType } from "@/types/user";
|
||||
import Config from "@/config/config";
|
||||
const apiServer = Config.apiServer;
|
||||
|
||||
async function signUp(newUser: UserType) {
|
||||
const fetchOptions = {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(newUser),
|
||||
};
|
||||
|
||||
const url = `${apiServer}/auth/signup`;
|
||||
|
||||
try {
|
||||
const response = await fetch(url, fetchOptions);
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! Status: ${response.status}`);
|
||||
}
|
||||
const data = await response.json();
|
||||
return data;
|
||||
} catch (error: any) {
|
||||
console.error("Error creating sign up:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
async function signIn(signInUser: UserType) {
|
||||
const fetchOptions = {
|
||||
method: "POST",
|
||||
headers: {
|
||||
"Content-Type": "application/json",
|
||||
},
|
||||
body: JSON.stringify(signInUser),
|
||||
};
|
||||
|
||||
const url = `${apiServer}/auth/signin`;
|
||||
|
||||
try {
|
||||
const response = await fetch(url, fetchOptions);
|
||||
if (!response.ok) {
|
||||
throw new Error(`HTTP error! Status: ${response.status}`);
|
||||
}
|
||||
const data = await response.json();
|
||||
return data;
|
||||
} catch (error: any) {
|
||||
console.error("Error sign in:", error);
|
||||
throw error;
|
||||
}
|
||||
}
|
||||
|
||||
export { signUp, signIn };
|
||||
166
frontend/src/app/[locale]/auth/authPage.tsx
Normal file
166
frontend/src/app/[locale]/auth/authPage.tsx
Normal file
@@ -0,0 +1,166 @@
|
||||
"use client";
|
||||
import React from "react";
|
||||
import { useState, useEffect } from "react";
|
||||
import { Input, Button } from "@nextui-org/react";
|
||||
import { Eye, EyeOff } from "lucide-react";
|
||||
import { UserType, AuthMessages } from "@/types/user";
|
||||
import { roles } from "@/config/selection";
|
||||
import { usePathname } from "next/navigation";
|
||||
import { signUp, signIn } from "./authControl";
|
||||
type Props = {
|
||||
messages: AuthMessages;
|
||||
locale: string;
|
||||
};
|
||||
|
||||
export default function AuthPage({ messages, locale }: Props) {
|
||||
const [isSignup, setIsSignup] = useState(false);
|
||||
const pathname = usePathname();
|
||||
console.log(pathname);
|
||||
if (pathname.includes("signup")) {
|
||||
setIsSignup(true);
|
||||
}
|
||||
|
||||
const [user, setUser] = useState<UserType>({
|
||||
id: null,
|
||||
email: "",
|
||||
password: "",
|
||||
username: "",
|
||||
role: roles.findIndex((entry) => entry.uid === "user"),
|
||||
avatarPath: "",
|
||||
});
|
||||
const [errorMessage, setErrorMessage] = useState("");
|
||||
|
||||
const [isPasswordVisible, setIsPasswordVisible] = useState(false);
|
||||
const togglePasswordVisibility = () =>
|
||||
setIsPasswordVisible(!isPasswordVisible);
|
||||
|
||||
const validate = async () => {
|
||||
if (!user.email) {
|
||||
setErrorMessage("email can't be empty");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!user.password) {
|
||||
setErrorMessage("password can't be empty");
|
||||
return;
|
||||
}
|
||||
|
||||
if (!user.username) {
|
||||
setErrorMessage("username can't be empty");
|
||||
return;
|
||||
}
|
||||
|
||||
await submit();
|
||||
};
|
||||
|
||||
const submit = async () => {
|
||||
if (isSignup) {
|
||||
const signUpRet = await signUp(user);
|
||||
console.log(signUpRet);
|
||||
// if success, move to signin page
|
||||
} else {
|
||||
const signInRet = await signUp(user);
|
||||
console.log(signInRet);
|
||||
// if success, move to account page
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<div className="flex w-full flex-wrap md:flex-nowrap gap-4">
|
||||
<Input
|
||||
isRequired
|
||||
type="email"
|
||||
label="Email"
|
||||
onChange={(e) => {
|
||||
setUser({
|
||||
...user,
|
||||
email: e.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<Input
|
||||
isRequired
|
||||
type="username"
|
||||
label="User Name"
|
||||
onChange={(e) => {
|
||||
setUser({
|
||||
...user,
|
||||
username: e.target.value,
|
||||
});
|
||||
}}
|
||||
/>
|
||||
<Input
|
||||
label="Password"
|
||||
variant="bordered"
|
||||
placeholder="Enter your password"
|
||||
endContent={
|
||||
<button
|
||||
className="focus:outline-none"
|
||||
type="button"
|
||||
onClick={togglePasswordVisibility}
|
||||
>
|
||||
{isPasswordVisible ? <Eye size={24} /> : <EyeOff size={24} />}
|
||||
</button>
|
||||
}
|
||||
type={isPasswordVisible ? "text" : "password"}
|
||||
onChange={(e) => {
|
||||
setUser({
|
||||
...user,
|
||||
password: e.target.value,
|
||||
});
|
||||
}}
|
||||
className="max-w-xs"
|
||||
/>
|
||||
<Button color="primary" onPress={validate}>
|
||||
{isSignup ? messages.signup : messages.signin}
|
||||
</Button>
|
||||
</div>
|
||||
// <Modal
|
||||
// isOpen={isOpen}
|
||||
// onOpenChange={() => {
|
||||
// onCancel();
|
||||
// }}
|
||||
// >
|
||||
// <ModalContent>
|
||||
// <ModalHeader className="flex flex-col gap-1">
|
||||
// {messages.project}
|
||||
// </ModalHeader>
|
||||
// <ModalBody>
|
||||
// <Input
|
||||
// type="text"
|
||||
// label={messages.projectName}
|
||||
// value={projectName.text}
|
||||
// isInvalid={projectName.isValid}
|
||||
// errorMessage={projectName.errorMessage}
|
||||
// onChange={(e) => {
|
||||
// setProjectName({
|
||||
// ...projectName,
|
||||
// text: e.target.value,
|
||||
// });
|
||||
// }}
|
||||
// />
|
||||
// <Textarea
|
||||
// label={messages.projectDetail}
|
||||
// value={projectDetail.text}
|
||||
// isInvalid={projectDetail.isValid}
|
||||
// errorMessage={projectDetail.errorMessage}
|
||||
// onChange={(e) => {
|
||||
// setProjectDetail({
|
||||
// ...projectDetail,
|
||||
// text: e.target.value,
|
||||
// });
|
||||
// }}
|
||||
// />
|
||||
// </ModalBody>
|
||||
// <ModalFooter>
|
||||
// <Button variant="light" onPress={onCancel}>
|
||||
// {messages.close}
|
||||
// </Button>
|
||||
// <Button color="primary" onPress={validate}>
|
||||
// {editingProject ? messages.update : messages.create}
|
||||
// </Button>
|
||||
// </ModalFooter>
|
||||
// </ModalContent>
|
||||
// </Modal>
|
||||
);
|
||||
}
|
||||
15
frontend/src/app/[locale]/auth/signin/page.tsx
Normal file
15
frontend/src/app/[locale]/auth/signin/page.tsx
Normal file
@@ -0,0 +1,15 @@
|
||||
import AuthPage from "../authPage";
|
||||
import { useTranslations } from "next-intl";
|
||||
|
||||
export default function Page(params: { locale: string }) {
|
||||
const t = useTranslations("Auth");
|
||||
const messages = {
|
||||
signup: t("projectList"),
|
||||
signin: t("project"),
|
||||
};
|
||||
return (
|
||||
<>
|
||||
<AuthPage messages={messages} locale={params.locale} />
|
||||
</>
|
||||
);
|
||||
}
|
||||
0
frontend/src/app/[locale]/auth/signup/page.tsx
Normal file
0
frontend/src/app/[locale]/auth/signup/page.tsx
Normal file
13
frontend/types/user.ts
Normal file
13
frontend/types/user.ts
Normal file
@@ -0,0 +1,13 @@
|
||||
export type UserType = {
|
||||
id: number | null;
|
||||
email: string;
|
||||
password: string;
|
||||
username: string;
|
||||
role: number;
|
||||
avatarPath: string;
|
||||
};
|
||||
|
||||
export type AuthMessages = {
|
||||
signup: string;
|
||||
signin: string;
|
||||
};
|
||||
Reference in New Issue
Block a user