113 lines
3.4 KiB
TypeScript
113 lines
3.4 KiB
TypeScript
import { useState } from "react";
|
|
import { api } from "../API/API";
|
|
import { NewProject } from "../Types/goTypes";
|
|
import Logo from "../assets/Logo.svg";
|
|
import Button from "./Button";
|
|
import { useNavigate } from "react-router-dom";
|
|
import ProjectNameInput from "./Inputs/ProjectNameInput";
|
|
import DescriptionInput from "./Inputs/DescriptionInput";
|
|
import { alphanumeric } from "../Data/regex";
|
|
import { projNameHighLimit, projNameLowLimit } from "../Data/constants";
|
|
|
|
/**
|
|
* Provides UI for adding a project to the system.
|
|
* @returns {JSX.Element} - Returns the component UI for adding a project
|
|
*/
|
|
function AddProject(): JSX.Element {
|
|
const [name, setName] = useState("");
|
|
const [description, setDescription] = useState("");
|
|
const navigate = useNavigate();
|
|
|
|
/**
|
|
* Tries to add a project to the system
|
|
*/
|
|
const handleCreateProject = async (): Promise<void> => {
|
|
if (
|
|
!alphanumeric.test(name) ||
|
|
name.length > projNameHighLimit ||
|
|
name.length < projNameLowLimit
|
|
) {
|
|
alert(
|
|
"Please provide valid project name: \n-Between 10-99 characters \n-No special characters (.-!?/*)",
|
|
);
|
|
return;
|
|
}
|
|
if (description.length > projNameHighLimit) {
|
|
alert("Please provide valid description: \n-Max 100 characters");
|
|
return;
|
|
}
|
|
const project: NewProject = {
|
|
name: name.replace(/ /g, ""),
|
|
description: description.trim(),
|
|
};
|
|
try {
|
|
const response = await api.createProject(
|
|
project,
|
|
localStorage.getItem("accessToken") ?? "",
|
|
);
|
|
if (response.success) {
|
|
alert(`${project.name} added!`);
|
|
setDescription("");
|
|
setName("");
|
|
navigate("/admin");
|
|
} else {
|
|
alert("Project not added, name could be taken");
|
|
console.error(response.message);
|
|
}
|
|
} catch (error) {
|
|
alert("Project not added");
|
|
console.error(error);
|
|
}
|
|
};
|
|
|
|
return (
|
|
<div className="flex flex-col h-fit w-screen items-center justify-center">
|
|
<div className="border-4 border-black bg-white flex flex-col items-center justify-center h-fit w-fit rounded-3xl content-center pl-20 pr-20">
|
|
<form
|
|
className="bg-white rounded px-8 pt-6 pb-8 mb-4 justify-center flex flex-col w-fit h-fit"
|
|
onSubmit={(e) => {
|
|
e.preventDefault();
|
|
void handleCreateProject();
|
|
}}
|
|
>
|
|
<img
|
|
src={Logo}
|
|
className="logo w-[7vw] self-center mb-10 mt-10"
|
|
alt="TTIME Logo"
|
|
/>
|
|
<h3 className="pb-4 mb-2 text-center font-bold text-[18px]">
|
|
Create a new project
|
|
</h3>
|
|
<ProjectNameInput
|
|
name={name}
|
|
onChange={(e) => {
|
|
e.preventDefault();
|
|
setName(e.target.value);
|
|
}}
|
|
/>
|
|
<div className="p-2"></div>
|
|
<DescriptionInput
|
|
desc={description}
|
|
onChange={(e) => {
|
|
e.preventDefault();
|
|
setDescription(e.target.value);
|
|
}}
|
|
placeholder={"Description (Optional)"}
|
|
/>
|
|
<div className="flex self-center mt-4 justify-between">
|
|
<Button
|
|
text="Create"
|
|
onClick={(): void => {
|
|
return;
|
|
}}
|
|
type="submit"
|
|
/>
|
|
</div>
|
|
</form>
|
|
<p className="text-center text-gray-500 text-xs"></p>
|
|
</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
export default AddProject;
|