Compare commits

..

No commits in common. "d9af77a8f776878596c1b2a9cbcfc32887b53a2f" and "db6fdf3c2914fb5afd9890d0b180429726406434" have entirely different histories.

17 changed files with 165 additions and 490 deletions

View file

@ -1,220 +1,58 @@
INSERT OR IGNORE INTO users(username, password)
VALUES ("admin", "123"),
("user", "123"),
("user2", "123"),
("John", "123"),
("Emma", "123"),
("Michael", "123"),
("Liam", "123"),
("Oliver", "123"),
("Amelia", "123"),
("Benjamin", "123"),
("Mia", "123"),
("Elijah", "123"),
("Charlotte", "123"),
("Henry", "123"),
("Harper", "123"),
("Lucas", "123"),
("Emily", "123"),
("Alexander", "123"),
("Daniel", "123"),
("Ella", "123"),
("Matthew", "123"),
("Madison", "123"),
("Samuel", "123"),
("Avery", "123"),
("Sofia", "123"),
("David", "123"),
("Victoria", "123"),
("Jackson", "123"),
("Abigail", "123"),
("Gabriel", "123"),
("Luna", "123"),
("Wyatt", "123"),
("Chloe", "123"),
("Nora", "123"),
("Joshua", "123"),
("Hazel", "123"),
("Riley", "123"),
("Scarlett", "123"),
("Aria", "123"),
("Carter", "123"),
("Grace", "123"),
("Jayden", "123"),
("Hannah", "123"),
("Zoe", "123"),
("Luke", "123"),
("Sophia", "123"),
("Jack", "123"),
("Isabella", "123"),
("William", "123"),
("Mason", "123"),
("Evelyn", "123"),
("James", "123"),
("Cynthia", "123"),
("Abraham", "123"),
("Ava", "123"),
("Aiden", "123"),
("Natalie", "123"),
("Lily", "123"),
("Olivia", "123"),
("Alexander", "123"),
("Ethan", "123"),
("Mila", "123"),
("Evelyn", "123"),
("Logan", "123"),
("Riley", "123"),
("Grace", "123"),
("Arnold", "123"),
("Connor", "123"),
("Samantha", "123"),
("Emma", "123"),
("Sarah", "123"),
("Nathan", "123"),
("Layla", "123"),
("Ryan", "123"),
("Zoey", "123"),
("Megan", "123"),
("Christian", "123"),
("Eva", "123"),
("Isaac", "123"),
("Michaela", "123"),
("Caroline", "123"),
("Elijah", "123"),
("Elena", "123"),
("Julian", "123"),
("Sophie", "123"),
("Gabriella", "123"),
("Cole", "123"),
("Hannah", "123"),
("Lucy", "123"),
("Katherine", "123"),
("Benjamin", "123"),
("Ella", "123"),
("Evan", "123");
VALUES ("admin", "123");
INSERT OR IGNORE INTO projects(name, description, owner_user_id)
VALUES ("projecttest1", "Description for projecttest1", 1),
("projecttest2", "Description for projecttest2", 1),
("projecttest3", "Description for projecttest3", 1),
("projecttest4", "Description for projecttest4", 1),
("projecttest5", "Description for projecttest5", 1),
("projecttest6", "Description for projecttest6", 1),
("projecttest7", "Description for projecttest7", 1),
("projecttest8", "Description for projecttest8", 1),
("projecttest9", "Description for projecttest9", 1),
("projecttest10", "Description for projecttest10", 1),
("projecttest11", "Description for projecttest11", 1),
("projecttest12", "Description for projecttest12", 1),
("projecttest13", "Description for projecttest13", 1),
("projecttest14", "Description for projecttest14", 1),
("projecttest15", "Description for projecttest15", 1);
INSERT OR IGNORE INTO users(username, password)
VALUES ("user", "123");
INSERT OR IGNORE INTO users(username, password)
VALUES ("user2", "123");
INSERT OR IGNORE INTO site_admin VALUES (1);
INSERT OR IGNORE INTO projects(name,description,owner_user_id)
VALUES ("projecttest","test project", 1);
INSERT OR IGNORE INTO projects(name,description,owner_user_id)
VALUES ("projecttest2","test project2", 1);
INSERT OR IGNORE INTO projects(name,description,owner_user_id)
VALUES ("projecttest3","test project3", 1);
INSERT OR IGNORE INTO user_roles(user_id,project_id,p_role)
VALUES (1,1,"project_manager"),
(1,2,"project_manager"),
(1,3,"project_manager"),
(1,4,"project_manager"),
(1,5,"project_manager"),
(1,6,"project_manager"),
(1,7,"project_manager"),
(1,8,"project_manager"),
(1,9,"project_manager"),
(1,10,"project_manager"),
(1,11,"project_manager"),
(1,12,"project_manager"),
(1,13,"project_manager"),
(1,14,"project_manager"),
(1,15,"project_manager"),
(2,1,"project_manager"),
(2,2,"member"),
(2,3,"member"),
(2,4,"member"),
(2,5,"member"),
(2,6,"member"),
(2,7,"member"),
(2,8,"member"),
(2,9,"member"),
(2,10,"member"),
(2,11,"member"),
(2,12,"member"),
(2,13,"member"),
(2,14,"member"),
(2,15,"member"),
(3,1,"member"),
(3,2,"member"),
(3,3,"member"),
(3,4,"member"),
(3,5,"member"),
(3,6,"member"),
(3,7,"member"),
(3,8,"member"),
(3,9,"member"),
(3,10,"member"),
(3,11,"member"),
(3,12,"member"),
(3,13,"member"),
(3,14,"member"),
(3,15,"member"),
(4,1,"member"),
(4,2,"member"),
(4,3,"member"),
(4,4,"member"),
(4,5,"member"),
(4,6,"member"),
(4,7,"member"),
(4,8,"member"),
(4,9,"member"),
(4,10,"member"),
(4,11,"member"),
(4,12,"member"),
(4,13,"member"),
(4,14,"member"),
(4,15,"member"),
(5,1,"member"),
(5,2,"member"),
(5,3,"member"),
(5,4,"member"),
(5,5,"member"),
(5,6,"member"),
(5,7,"member"),
(5,8,"member"),
(5,9,"member"),
(5,10,"member"),
(5,11,"member"),
(5,12,"member"),
(5,13,"member"),
(5,14,"member"),
(5,15,"member");
VALUES (1,1,"project_manager");
INSERT OR IGNORE INTO user_roles(user_id,project_id,p_role)
VALUES (1,2,"project_manager");
INSERT OR IGNORE INTO user_roles(user_id,project_id,p_role)
VALUES (1,3,"project_manager");
INSERT OR IGNORE INTO user_roles(user_id,project_id,p_role)
VALUES (2,1,"member");
INSERT OR IGNORE INTO user_roles(user_id,project_id,p_role)
VALUES (3,1,"member");
INSERT OR IGNORE INTO user_roles(user_id,project_id,p_role)
VALUES (3,2,"member");
INSERT OR IGNORE INTO user_roles(user_id,project_id,p_role)
VALUES (3,3,"member");
INSERT OR IGNORE INTO user_roles(user_id,project_id,p_role)
VALUES (2,1,"project_manager");
INSERT OR IGNORE INTO weekly_reports (user_id, project_id, week, development_time, meeting_time, admin_time, own_work_time, study_time, testing_time, signed_by)
VALUES (2, 1, 12, 100, 50, 30, 150, 80, 20, NULL),
(3, 1, 12, 200, 80, 20, 200, 100, 30, NULL),
(3, 1, 14, 150, 70, 40, 180, 90, 25, NULL),
(3, 2, 12, 120, 60, 35, 160, 85, 15, NULL),
(3, 3, 12, 180, 90, 25, 190, 110, 40, NULL),
(2, 1, 13, 130, 70, 40, 170, 95, 35, NULL),
(3, 1, 15, 140, 60, 50, 200, 120, 30, NULL),
(2, 2, 11, 110, 50, 45, 140, 70, 25, NULL),
(3, 3, 14, 170, 80, 30, 180, 100, 35, NULL),
(3, 3, 15, 200, 100, 20, 220, 130, 45, NULL),
(2, 4, 12, 120, 60, 40, 160, 80, 30, NULL),
(3, 5, 14, 150, 70, 30, 180, 90, 25, NULL),
(3, 5, 15, 180, 90, 20, 190, 110, 35, NULL),
(2, 6, 11, 100, 50, 35, 130, 60, 20, NULL),
(3, 7, 14, 170, 80, 25, 180, 100, 30, NULL),
(2, 8, 12, 130, 70, 30, 170, 90, 25, NULL),
(2, 8, 13, 150, 80, 20, 180, 110, 35, NULL),
(3, 9, 12, 140, 60, 40, 180, 100, 30, NULL),
(3, 10, 11, 120, 50, 45, 150, 70, 25, NULL),
(2, 11, 13, 110, 60, 35, 140, 80, 30, NULL),
(3, 12, 12, 160, 70, 30, 180, 100, 35, NULL),
(3, 12, 13, 180, 90, 25, 190, 110, 40, NULL),
(3, 12, 14, 200, 100, 20, 220, 130, 45, NULL),
(2, 13, 11, 100, 50, 45, 130, 60, 20, NULL),
(2, 13, 12, 120, 60, 40, 160, 80, 30, NULL),
(3, 14, 13, 140, 70, 30, 160, 90, 35, NULL),
(3, 15, 12, 150, 80, 25, 180, 100, 30, NULL),
(3, 15, 13, 170, 90, 20, 190, 110, 35, NULL);
VALUES (2, 1, 12, 20, 10, 5, 30, 15, 10, NULL);
INSERT OR IGNORE INTO site_admin VALUES (1);
INSERT OR IGNORE INTO weekly_reports (user_id, project_id, week, development_time, meeting_time, admin_time, own_work_time, study_time, testing_time, signed_by)
VALUES (3, 1, 12, 20, 10, 5, 30, 15, 10, NULL);
INSERT OR IGNORE INTO weekly_reports (user_id, project_id, week, development_time, meeting_time, admin_time, own_work_time, study_time, testing_time, signed_by)
VALUES (3, 1, 14, 20, 10, 5, 30, 15, 10, NULL);
INSERT OR IGNORE INTO weekly_reports (user_id, project_id, week, development_time, meeting_time, admin_time, own_work_time, study_time, testing_time, signed_by)
VALUES (3, 2, 12, 20, 10, 5, 30, 15, 10, NULL);
INSERT OR IGNORE INTO weekly_reports (user_id, project_id, week, development_time, meeting_time, admin_time, own_work_time, study_time, testing_time, signed_by)
VALUES (3, 3, 12, 20, 10, 5, 30, 15, 10, NULL);

View file

@ -67,7 +67,6 @@ function AddProject(): JSX.Element {
e.preventDefault();
setName(e.target.value);
}}
placeholder={"Name"}
/>
<InputField
label="Description"
@ -77,7 +76,6 @@ function AddProject(): JSX.Element {
e.preventDefault();
setDescription(e.target.value);
}}
placeholder={"Description"}
/>
</div>
<div className="flex items-center justify-between">

View file

@ -1,9 +1,9 @@
import { useEffect, useState } from "react";
import Button from "./Button";
import AddMember, { AddMemberInfo } from "./AddMember";
import BackButton from "./BackButton";
import GetUsersInProject, { ProjectMember } from "./GetUsersInProject";
import GetAllUsers from "./GetAllUsers";
import InputField from "./InputField";
/**
* Provides UI for adding a member to a project.
@ -13,7 +13,6 @@ function AddUserToProject(props: { projectName: string }): JSX.Element {
const [names, setNames] = useState<string[]>([]);
const [users, setUsers] = useState<string[]>([]);
const [usersProj, setUsersProj] = useState<ProjectMember[]>([]);
const [search, setSearch] = useState("");
// Gets all users and project members for filtering
GetAllUsers({ setUsersProp: setUsers });
@ -37,10 +36,8 @@ function AddUserToProject(props: { projectName: string }): JSX.Element {
// Attempts to add all of the selected users to the project
const handleAddClick = async (): Promise<void> => {
if (names.length === 0) {
if (names.length === 0)
alert("You have to choose at least one user to add");
return;
}
for (const name of names) {
const newMember: AddMemberInfo = {
userName: name,
@ -63,47 +60,32 @@ function AddUserToProject(props: { projectName: string }): JSX.Element {
};
return (
<div className="border-4 border-black bg-white flex flex-col items-center py-10 px-20 rounded-3xl content-center overflow-auto">
<div className="border-4 border-black bg-white flex flex-col items-center pt-10 rounded-3xl content-center pl-20 pr-20 h-[63vh] w-[50] overflow-auto">
<h1 className="text-center font-bold text-[36px] pb-10">
{props.projectName}
</h1>
<p className="p-1 text-center font-bold text-[26px]">
Choose users to add:
</p>
<div>
<InputField
placeholder={"Search users"}
type={"Text"}
value={search}
onChange={(e) => {
setSearch(e.target.value);
}}
/>
<ul className="font-medium space-y-2 border-2 border-black mt-2 px-2 pb-2 rounded-2xl text-center overflow-auto h-[26vh] w-[34vh]">
<div className="border-2 border-black pl-2 pr-2 pb-2 rounded-xl text-center overflow-auto h-[26vh] w-[26vh]">
<ul className="text-center font-medium space-y-2">
<div></div>
{users
.filter((user) => {
return search.toLowerCase() === ""
? user
: user.toLowerCase().includes(search.toLowerCase());
})
.map((user) => (
<li
className={
names.includes(user)
? "items-start p-1 border-2 border-transparent rounded-full bg-orange-500 transition-all hover:bg-orange-600 text-white hover:cursor-pointer ring-2 ring-black"
: "items-start p-1 border-2 border-black rounded-full bg-orange-200 hover:bg-orange-400 transition-all hover:text-white hover:cursor-pointer"
}
key={user}
value={user}
onClick={() => {
handleUserClick(user);
}}
>
<span>{user}</span>
</li>
))}
{users.map((user) => (
<li
className={
names.includes(user)
? "items-start p-1 border-2 border-transparent rounded-full bg-orange-500 hover:bg-orange-600 text-white hover:cursor-pointer ring-2 ring-black"
: "items-start p-1 border-2 border-black rounded-full bg-orange-200 hover:bg-orange-400 hover:text-slate-100 hover:cursor-pointer"
}
key={user}
value={user}
onClick={() => {
handleUserClick(user);
}}
>
<span>{user}</span>
</li>
))}
</ul>
</div>
<p className="pt-10 pb-5 underline text-center font-bold text-[18px]">
@ -117,7 +99,9 @@ function AddUserToProject(props: { projectName: string }): JSX.Element {
}}
type="button"
/>
<BackButton />
</div>
<p className="text-center text-gray-500 text-xs"></p>
</div>
);
}

View file

@ -9,10 +9,6 @@ function ChangeUsername(props: { nameChange: StrNameChange }): void {
alert("You have to give a new name\n\nName not changed");
return;
}
if (props.nameChange.prevName === localStorage.getItem("username")) {
alert("You cannot change admin name");
return;
}
api
.changeUserName(props.nameChange, localStorage.getItem("accessToken") ?? "")
.then((response: APIResponse<void>) => {

View file

@ -4,21 +4,19 @@
* @returns {JSX.Element} The input field
* @example
* <InputField
* label="Example"
* placeholder="New placeholder"
* type="text"
* value={example}
* label="Example"
* onChange={(e) => {
* setExample(e.target.value);
* }}
* value={example}
* />
*/
function InputField(props: {
label?: string;
placeholder?: string;
type?: string;
value?: string;
onChange?: (e: React.ChangeEvent<HTMLInputElement>) => void;
label: string;
type: string;
value: string;
onChange: (e: React.ChangeEvent<HTMLInputElement>) => void;
}): JSX.Element {
return (
<div className="">
@ -32,7 +30,7 @@ function InputField(props: {
className="appearance-none border-2 border-black rounded-2xl w-full py-2 px-3 text-gray-700 leading-tight focus:outline-none focus:shadow-outline"
id={props.label}
type={props.type}
placeholder={props.placeholder}
placeholder={props.label}
value={props.value}
onChange={props.onChange}
/>

View file

@ -11,10 +11,6 @@ function LoginCheck(props: {
password: string;
setAuthority: Dispatch<SetStateAction<number>>;
}): void {
if (props.username === "" || props.password === "") {
alert("Please enter username and password to login");
return;
}
const user: NewUser = {
username: props.username,
password: props.password,
@ -47,7 +43,6 @@ function LoginCheck(props: {
}
} else {
console.error("Token could not be fetched/No such user");
alert("Could not login, wrong username or password");
}
})
.catch((error) => {

View file

@ -33,7 +33,6 @@ function Login(props: {
props.setUsername(e.target.value);
}}
value={props.username}
placeholder={"Username"}
/>
<InputField
type="password"
@ -42,7 +41,6 @@ function Login(props: {
props.setPassword(e.target.value);
}}
value={props.password}
placeholder={"Password"}
/>
</div>
<Button

View file

@ -23,7 +23,7 @@ function MemberInfoModal(props: {
className="fixed inset-10 bg-opacity-30 backdrop-blur-sm
flex justify-center items-center"
>
<div className="border-4 border-black bg-white rounded-2xl text-center flex flex-col">
<div className="border-4 border-black bg-white rounded-lg text-center flex flex-col">
<div className="mx-10">
<p className="font-bold text-[30px]">{props.username}</p>
<p

View file

@ -4,47 +4,19 @@ import GetUsersInProject, { ProjectMember } from "./GetUsersInProject";
import { Link } from "react-router-dom";
import GetProjectTimes, { projectTimes } from "./GetProjectTimes";
import DeleteProject from "./DeleteProject";
import InputField from "./InputField";
function ProjectInfoModal(props: {
projectname: string;
onClose: () => void;
onClick: (username: string) => void;
}): JSX.Element {
const [showInput, setShowInput] = useState(false);
const [users, setUsers] = useState<ProjectMember[]>([]);
const [times, setTimes] = useState<projectTimes>();
const [search, setSearch] = useState("");
const [newProjName, setNewProjName] = useState("");
const totalTime = useRef(0);
GetUsersInProject({ projectName: props.projectname, setUsersProp: setUsers });
GetProjectTimes({ setTimesProp: setTimes, projectName: props.projectname });
const handleChangeNameView = (): void => {
if (showInput) {
setShowInput(false);
} else {
setShowInput(true);
}
};
const handleClickChangeName = (): void => {
if (newProjName === "") return;
if (
confirm(
`Are you sure you want to change name of ${props.projectname} to ${newProjName}?`,
)
) {
//TODO: change and insert change name functionality
alert("Not implemented yet");
setNewProjName("");
} else {
alert("Name was not changed!");
}
};
useEffect(() => {
if (times?.totalTime !== undefined) {
totalTime.current = times.totalTime;
@ -56,90 +28,44 @@ function ProjectInfoModal(props: {
className="fixed inset-0 bg-black bg-opacity-30 backdrop-blur-sm
flex justify-center items-center"
>
<div className="border-4 border-black bg-white p-2 rounded-2xl text-center h-[64vh] w-[40] overflow-auto">
<div className="border-4 border-black bg-white p-2 rounded-2xl text-center h-[61vh] w-[40] overflow-auto">
<div className="pl-10 pr-10">
<h1 className="font-bold text-[32px]">{props.projectname}</h1>
<p
className="mb-4 hover:font-bold hover:cursor-pointer hover:underline"
onClick={handleChangeNameView}
>
(Change project name)
</p>
{showInput && (
<>
<h2 className="text-[20px] font-bold pb-2">Change name:</h2>
<div className="border-2 rounded-2xl border-black p-6 mb-7 space-y-4">
<InputField
type={"text"}
value={newProjName}
onChange={function (e): void {
setNewProjName(e.target.value);
}}
placeholder={"Project Name"}
/>
<div className="px-6 grid grid-cols-2 gap-10">
<Button
text={"Change"}
onClick={function (): void {
handleClickChangeName();
}}
type={"submit"}
/>
<Button
text={"Close"}
onClick={function (): void {
handleChangeNameView();
}}
type={"submit"}
/>
</div>
</div>
</>
)}
<h2 className="text-[20px] font-bold pb-2">Statistics:</h2>
<div className="border-2 border-black rounded-2xl px-2 py-1 text-left divide-y-2 flex flex-col overflow-auto">
<p>Number of members: {users.length}</p>
<p>
<h1 className="font-bold text-[32px] mb-[20px]">
{props.projectname}
</h1>
<div className="p-1 text-center">
<h2 className="text-[20px] font-bold">Statistics:</h2>
</div>
<div className="border-2 border-black rounded-lg h-[8vh] text-left divide-y-2 flex flex-col overflow-auto mx-10">
<p className="p-2">Number of members: {users.length}</p>
<p className="p-2">
Total time reported:{" "}
{Math.floor(totalTime.current / 60 / 24) + " d "}
{Math.floor((totalTime.current / 60) % 24) + " h "}
{(totalTime.current % 60) + " m "}
</p>
</div>
<h3 className="pt-7 text-[20px] font-bold">Project members:</h3>
<div className="">
<InputField
placeholder={"Search member"}
type={"Text"}
value={search}
onChange={(e) => {
setSearch(e.target.value);
}}
/>
<ul className="border-2 border-black mt-2 p-2 rounded-2xl text-left overflow-auto h-[24vh] font-medium space-y-2">
{users
.filter((user) => {
return search.toLowerCase() === ""
? user.Username
: user.Username.toLowerCase().includes(
search.toLowerCase(),
);
})
.map((user) => (
<li
className="items-start px-2 py-1 border-2 border-black rounded-2xl bg-orange-200 transition-all hover:bg-orange-600 hover:text-white hover:cursor-pointer"
key={user.Username}
onClick={() => {
props.onClick(user.Username);
}}
>
<span>
Name: {user.Username}
<div></div>
Role: {user.UserRole}
</span>
</li>
))}
<div className="h-[6vh] p-7 text-center">
<h2 className="text-[20px] font-bold">Project members:</h2>
</div>
<div className="border-2 border-black p-2 rounded-lg text-center overflow-auto h-[24vh] mx-10">
<ul className="text-left font-medium space-y-2">
<div></div>
{users.map((user) => (
<li
className="items-start p-1 border-2 border-black rounded-lg bg-orange-200 hover:bg-orange-600 hover:text-slate-100 hover:cursor-pointer"
key={user.Username}
onClick={() => {
props.onClick(user.Username);
}}
>
<span>
Name: {user.Username}
<div></div>
Role: {user.UserRole}
</span>
</li>
))}
</ul>
</div>
<div className="space-x-5 my-2">

View file

@ -2,7 +2,6 @@ import { useState } from "react";
import { NewProject } from "../Types/goTypes";
import ProjectInfoModal from "./ProjectInfoModal";
import MemberInfoModal from "./MemberInfoModal";
import InputField from "./InputField";
/**
* A list of projects for admin manage projects page, that sets an onClick
@ -22,7 +21,6 @@ export function ProjectListAdmin(props: {
const [projectName, setProjectName] = useState("");
const [userModalVisible, setUserModalVisible] = useState(false);
const [username, setUsername] = useState("");
const [search, setSearch] = useState("");
const handleClickUser = (username: string): void => {
setUsername(username);
@ -46,7 +44,6 @@ export function ProjectListAdmin(props: {
return (
<>
<h1 className="font-bold text-[30px] mb-[20px]">Manage Projects</h1>
{projectModalVisible && (
<ProjectInfoModal
onClose={handleCloseProject}
@ -62,32 +59,18 @@ export function ProjectListAdmin(props: {
/>
)}
<div>
<InputField
placeholder={"Search"}
type={"Text"}
value={search}
onChange={(e) => {
setSearch(e.target.value);
}}
/>
<ul className="mt-3 border-2 text-left border-black rounded-2xl px-2 divide-y divide-gray-300 font-semibold text-[30px] cursor-pointer overflow-auto h-[65vh] w-[50vw]">
{props.projects
.filter((project) => {
return search.toLowerCase() === ""
? project.name
: project.name.toLowerCase().includes(search.toLowerCase());
})
.map((project) => (
<li
className="hover:font-extrabold hover:underline p-1"
key={project.name}
onClick={() => {
handleClickProject(project.name);
}}
>
{project.name}
</li>
))}
<ul className="font-bold underline text-[30px] cursor-pointer padding">
{props.projects.map((project) => (
<li
className="pt-5"
key={project.name}
onClick={() => {
handleClickProject(project.name);
}}
>
{project.name}
</li>
))}
</ul>
</div>
</>

View file

@ -61,7 +61,6 @@ export default function Register(): JSX.Element {
onChange={(e) => {
setUsername(e.target.value);
}}
placeholder={"Username"}
/>
<InputField
label="Password"
@ -70,7 +69,6 @@ export default function Register(): JSX.Element {
onChange={(e) => {
setPassword(e.target.value);
}}
placeholder={"Password"}
/>
</div>
<div className="flex items-center justify-between">

View file

@ -13,7 +13,6 @@ function UserInfoModal(props: {
}): JSX.Element {
const [showInput, setShowInput] = useState(false);
const [newUsername, setNewUsername] = useState("");
const [newPassword, setNewPassword] = useState("");
if (!props.isVisible) {
return <></>;
}
@ -27,34 +26,11 @@ function UserInfoModal(props: {
};
const handleClickChangeName = (): void => {
if (newUsername === "") return;
if (
confirm(
`Do you really want to change username of ${props.username} to ${newUsername}?`,
)
) {
const nameChange: StrNameChange = {
prevName: props.username,
newName: newUsername.replace(/ /g, ""),
};
ChangeUsername({ nameChange: nameChange });
} else {
alert("Name was not changed!");
}
};
const handleClickChangePassword = (): void => {
if (newPassword === "") return;
if (
confirm(`Are you sure you want to change password of ${props.username}?`)
) {
//TODO: insert change password functionality
alert("Not implemented yet");
setNewPassword("");
} else {
alert("Password was not changed!");
}
const nameChange: StrNameChange = {
prevName: props.username,
newName: newUsername.replace(/ /g, ""),
};
ChangeUsername({ nameChange: nameChange });
};
return (
@ -62,14 +38,14 @@ function UserInfoModal(props: {
className="fixed inset-0 bg-black bg-opacity-30 backdrop-blur-sm
flex justify-center items-center"
>
<div className="border-4 border-black bg-white rounded-2xl text-center flex flex-col">
<div className="border-4 border-black bg-white rounded-lg text-center flex flex-col">
<div className="mx-10">
<p className="font-bold text-[30px]">{props.username}</p>
<p
className="mb-[10px] hover:font-bold hover:cursor-pointer underline"
onClick={handleChangeNameView}
>
(Change Username or Password)
(Change Username)
</p>
{showInput && (
<div>
@ -78,25 +54,14 @@ function UserInfoModal(props: {
type={"text"}
value={newUsername}
onChange={function (e): void {
e.defaultPrevented;
setNewUsername(e.target.value);
}}
placeholder={"Username"}
/>
<div className="m-4"></div>
<InputField
label={"New password"}
type={"password"}
value={newPassword}
onChange={function (e): void {
setNewPassword(e.target.value);
}}
placeholder={"Password"}
/>
<Button
text={"Change"}
onClick={function (): void {
handleClickChangeName();
handleClickChangePassword();
}}
type={"submit"}
/>

View file

@ -1,6 +1,5 @@
import { useState } from "react";
import UserInfoModal from "./UserInfoModal";
import InputField from "./InputField";
/**
* A list of users for admin manage users page, that sets an onClick
@ -16,7 +15,6 @@ import InputField from "./InputField";
export function UserListAdmin(props: { users: string[] }): JSX.Element {
const [modalVisible, setModalVisible] = useState(false);
const [username, setUsername] = useState("");
const [search, setSearch] = useState("");
const handleClick = (username: string): void => {
setUsername(username);
@ -30,39 +28,24 @@ export function UserListAdmin(props: { users: string[] }): JSX.Element {
return (
<>
<h1 className="font-bold text-[30px] mb-[20px]">Manage Users</h1>
<UserInfoModal
onClose={handleClose}
isVisible={modalVisible}
username={username}
/>
<div>
<InputField
placeholder={"Search"}
type={"Text"}
value={search}
onChange={(e) => {
setSearch(e.target.value);
}}
/>
<ul className="mt-3 border-2 text-left border-black rounded-2xl px-2 divide-y divide-gray-300 font-semibold text-[30px] transition-all cursor-pointer overflow-auto h-[65vh] w-[50vw]">
{props.users
.filter((user) => {
return search.toLowerCase() === ""
? user
: user.toLowerCase().includes(search.toLowerCase());
})
.map((user) => (
<li
className="hover:font-extrabold hover:underline p-1"
key={user}
onClick={() => {
handleClick(user);
}}
>
{user}
</li>
))}
<ul className="font-bold underline text-[30px] cursor-pointer padding">
{props.users.map((user) => (
<li
className="pt-5"
key={user}
onClick={() => {
handleClick(user);
}}
>
{user}
</li>
))}
</ul>
</div>
</>

View file

@ -13,7 +13,14 @@ function AdminManageProjects(): JSX.Element {
setProjectsProp: setProjects,
username: localStorage.getItem("username") ?? "",
});
const content = <ProjectListAdmin projects={projects} />;
const content = (
<>
<h1 className="font-bold text-[30px] mb-[20px]">Manage Projects</h1>
<div className="border-4 border-black bg-white flex flex-col items-center h-[65vh] w-[50vw] rounded-3xl content-center overflow-scroll space-y-[10vh] p-[30px]">
<ProjectListAdmin projects={projects} />
</div>
</>
);
const buttons = (
<>

View file

@ -12,7 +12,14 @@ function AdminManageUsers(): JSX.Element {
const navigate = useNavigate();
const content = <UserListAdmin users={users} />;
const content = (
<>
<h1 className="font-bold text-[30px] mb-[20px]">Manage Users</h1>
<div className="border-4 border-black bg-white flex flex-col items-center h-[65vh] w-[50vw] rounded-3xl content-center overflow-scroll space-y-[10vh] p-[30px]">
<UserListAdmin users={users} />
</div>
</>
);
const buttons = (
<>

View file

@ -5,14 +5,14 @@ function AdminMenuPage(): JSX.Element {
const content = (
<>
<h1 className="font-bold text-[30px] mb-[20px]">Administrator Menu</h1>
<div className="border-4 border-black bg-white flex flex-col items-center justify-center min-h-[65vh] h-fit w-[50vw] rounded-3xl content-center overflow-auto space-y-[10vh] p-[30px]">
<div className="border-4 border-black bg-white flex flex-col items-center justify-center min-h-[65vh] h-fit w-[50vw] rounded-3xl content-center overflow-scroll space-y-[10vh] p-[30px]">
<Link to="/adminManageUser">
<h1 className="font-bold hover:underline text-[30px] cursor-pointer hover:font-extrabold">
<h1 className="font-bold underline text-[30px] cursor-pointer">
Manage Users
</h1>
</Link>
<Link to="/adminManageProject">
<h1 className="font-bold hover:underline text-[30px] cursor-pointer hover:font-extrabold">
<h1 className="font-bold underline text-[30px] cursor-pointer">
Manage Projects
</h1>
</Link>

View file

@ -1,12 +1,11 @@
import { useLocation } from "react-router-dom";
import AddUserToProject from "../../Components/AddUserToProject";
import BasicWindow from "../../Components/BasicWindow";
import BackButton from "../../Components/BackButton";
function AdminProjectAddMember(): JSX.Element {
const projectName = useLocation().search.slice(1);
const content = <AddUserToProject projectName={projectName} />;
const buttons = <BackButton />;
const buttons = <></>;
return <BasicWindow content={content} buttons={buttons} />;
}
export default AdminProjectAddMember;