Merge branch 'frontend' into dev

This commit is contained in:
Imbus 2024-03-19 03:40:24 +01:00
commit ab313551c9
8 changed files with 162 additions and 62 deletions

View file

@ -0,0 +1,34 @@
import { User } from "../Types/goTypes";
import { api, APIResponse } from "../API/API";
/**
* Use to remove a user from the system
* @param props - The username of user to remove
* @returns {boolean} True if removed, false if not
* @example
* const exampleUsername = "user";
* DeleteUser({ usernameToDelete: exampleUsername });
*/
function DeleteUser(props: { usernameToDelete: string }): boolean {
//console.log(props.usernameToDelete); FOR DEBUG
let removed = false;
api
.removeUser(
props.usernameToDelete,
localStorage.getItem("accessToken") ?? "",
)
.then((response: APIResponse<User>) => {
if (response.success) {
removed = true;
} else {
console.error(response.message);
}
})
.catch((error) => {
console.error("An error occurred during creation:", error);
});
return removed;
}
export default DeleteUser;

View file

@ -1,17 +1,17 @@
import { useState } from "react"; import { useState } from "react";
import { NewWeeklyReport } from "../Types/goTypes"; import type { NewWeeklyReport } from "../Types/goTypes";
import { api } from "../API/API"; import { api } from "../API/API";
import { useNavigate, useParams } from "react-router-dom"; import { useNavigate, useParams } from "react-router-dom";
import Button from "./Button"; import Button from "./Button";
export default function NewWeeklyReport(): JSX.Element { export default function NewWeeklyReport(): JSX.Element {
const [week, setWeek] = useState(0); const [week, setWeek] = useState<number>();
const [developmentTime, setDevelopmentTime] = useState(0); const [developmentTime, setDevelopmentTime] = useState<number>();
const [meetingTime, setMeetingTime] = useState(0); const [meetingTime, setMeetingTime] = useState<number>();
const [adminTime, setAdminTime] = useState(0); const [adminTime, setAdminTime] = useState<number>();
const [ownWorkTime, setOwnWorkTime] = useState(0); const [ownWorkTime, setOwnWorkTime] = useState<number>();
const [studyTime, setStudyTime] = useState(0); const [studyTime, setStudyTime] = useState<number>();
const [testingTime, setTestingTime] = useState(0); const [testingTime, setTestingTime] = useState<number>();
const { projectName } = useParams(); const { projectName } = useParams();
const token = localStorage.getItem("accessToken") ?? ""; const token = localStorage.getItem("accessToken") ?? "";
@ -19,13 +19,13 @@ export default function NewWeeklyReport(): JSX.Element {
const handleNewWeeklyReport = async (): Promise<void> => { const handleNewWeeklyReport = async (): Promise<void> => {
const newWeeklyReport: NewWeeklyReport = { const newWeeklyReport: NewWeeklyReport = {
projectName: projectName ?? "", projectName: projectName ?? "",
week, week: week ?? 0,
developmentTime, developmentTime: developmentTime ?? 0,
meetingTime, meetingTime: meetingTime ?? 0,
adminTime, adminTime: adminTime ?? 0,
ownWorkTime, ownWorkTime: ownWorkTime ?? 0,
studyTime, studyTime: studyTime ?? 0,
testingTime, testingTime: testingTime ?? 0,
}; };
await api.submitWeeklyReport(newWeeklyReport, token); await api.submitWeeklyReport(newWeeklyReport, token);
@ -45,7 +45,7 @@ export default function NewWeeklyReport(): JSX.Element {
} }
e.preventDefault(); e.preventDefault();
void handleNewWeeklyReport(); void handleNewWeeklyReport();
navigate(-1); navigate("/project");
}} }}
> >
<div className="flex flex-col items-center"> <div className="flex flex-col items-center">
@ -58,7 +58,9 @@ export default function NewWeeklyReport(): JSX.Element {
setWeek(weekNumber); setWeek(weekNumber);
}} }}
onKeyDown={(event) => { onKeyDown={(event) => {
event.preventDefault(); const keyValue = event.key;
if (!/\d/.test(keyValue) && keyValue !== "Backspace")
event.preventDefault();
}} }}
onPaste={(event) => { onPaste={(event) => {
event.preventDefault(); event.preventDefault();

View file

@ -0,0 +1,54 @@
import { Link } from "react-router-dom";
import Button from "./Button";
import DeleteUser from "./DeleteUser";
import UserProjectListAdmin from "./UserProjectListAdmin";
function UserInfoModal(props: {
isVisible: boolean;
username: string;
onClose: () => void;
}): JSX.Element {
if (!props.isVisible) return <></>;
return (
<div
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-lg text-center">
<p className="font-bold text-[30px]">{props.username}</p>
<Link to="/AdminChangeUserName">
<p className="mb-[20px] hover:font-bold hover:cursor-pointer underline">
(Change Username)
</p>
</Link>
<div>
<h2 className="font-bold text-[22px] mb-[20px]">
Member of these projects:
</h2>
<div className="pr-6 pl-6">
<UserProjectListAdmin />
</div>
</div>
<div className="items-center space-x-6 pr-6 pl-6">
<Button
text={"Delete"}
onClick={function (): void {
DeleteUser({ usernameToDelete: props.username });
}}
type="button"
/>
<Button
text={"Close"}
onClick={function (): void {
props.onClose();
}}
type="button"
/>
</div>
</div>
</div>
);
}
export default UserInfoModal;

View file

@ -1,5 +1,6 @@
import { Link } from "react-router-dom"; import { useState } from "react";
import { PublicUser } from "../Types/goTypes"; import { PublicUser } from "../Types/goTypes";
import UserInfoModal from "./UserInfoModal";
/** /**
* The props for the UserProps component * The props for the UserProps component
@ -9,27 +10,52 @@ interface UserProps {
} }
/** /**
* A list of users for admin manage users page, that links admin to the right user page * A list of users for admin manage users page, that sets an onClick
* thanks to the state property * function for eact user <li> element, which displays a modul with
* @param props - The users to display * user info.
* @param props - An array of users users to display
* @returns {JSX.Element} The user list * @returns {JSX.Element} The user list
* @example * @example
* const users = [{ id: 1, userName: "Random name" }]; * const users = [{ id: 1, userName: "ExampleName" }];
* return <UserList users={users} />; * return <UserList users={users} />;
*/ */
export function UserListAdmin(props: UserProps): JSX.Element { export function UserListAdmin(props: UserProps): JSX.Element {
const [modalVisible, setModalVisible] = useState(false);
const [username, setUsername] = useState("");
const handleClick = (username: string): void => {
setUsername(username);
setModalVisible(true);
};
const handleClose = (): void => {
setUsername("");
setModalVisible(false);
};
return ( return (
<div> <>
<ul className="font-bold underline text-[30px] cursor-pointer padding"> <UserInfoModal
{props.users.map((user) => ( onClose={handleClose}
<Link to="/adminUserInfo" key={user.userId} state={user.username}> isVisible={modalVisible}
<li className="pt-5" key={user.userId}> username={username}
/>
<div>
<ul className="font-bold underline text-[30px] cursor-pointer padding">
{props.users.map((user) => (
<li
className="pt-5"
key={user.userId}
onClick={() => {
handleClick(user.username);
}}
>
{user.username} {user.username}
</li> </li>
</Link> ))}
))} </ul>
</ul> </div>
</div> </>
); );
} }

View file

@ -1,17 +1,17 @@
import React, { useEffect, useState } from "react"; import { useEffect, useState } from "react";
import { api } from "../API/API"; import { api } from "../API/API";
import { Project } from "../Types/goTypes"; import { Project } from "../Types/goTypes";
const UserProjectListAdmin: React.FC = () => { function UserProjectListAdmin(): JSX.Element {
const [projects, setProjects] = useState<Project[]>([]); const [projects, setProjects] = useState<Project[]>([]);
useEffect(() => { useEffect(() => {
const fetchProjects = async (): Promise<void> => { const fetchProjects = async (): Promise<void> => {
try { try {
const token = localStorage.getItem("accessToken") ?? ""; const token = localStorage.getItem("accessToken") ?? "";
const username = "NoUser"; // getUsernameFromContext(); // Assuming you have a function to get the username from your context // const username = props.username;
const response = await api.getUserProjects(username, token); const response = await api.getUserProjects(token);
if (response.success) { if (response.success) {
setProjects(response.data ?? []); setProjects(response.data ?? []);
} else { } else {
@ -26,18 +26,16 @@ const UserProjectListAdmin: React.FC = () => {
}, []); }, []);
return ( return (
<div> <div className="border-2 border-black bg-white p-2 rounded-lg text-center">
<h2>User Projects</h2>
<ul> <ul>
{projects.map((project) => ( {projects.map((project) => (
<li key={project.id}> <li key={project.id}>
<span>{project.name}</span> <span>{project.name}</span>
{/* Add any additional project details you want to display */}
</li> </li>
))} ))}
</ul> </ul>
</div> </div>
); );
}; }
export default UserProjectListAdmin; export default UserProjectListAdmin;

View file

@ -1,3 +1,4 @@
import BackButton from "../../Components/BackButton";
import BasicWindow from "../../Components/BasicWindow"; import BasicWindow from "../../Components/BasicWindow";
import Button from "../../Components/Button"; import Button from "../../Components/Button";
@ -13,13 +14,7 @@ function AdminChangeUsername(): JSX.Element {
}} }}
type="button" type="button"
/> />
<Button <BackButton />
text="Back"
onClick={(): void => {
return;
}}
type="button"
/>
</> </>
); );

View file

@ -7,13 +7,12 @@ import BasicWindow from "../Components/BasicWindow";
export const ProjectNameContext = createContext(""); export const ProjectNameContext = createContext("");
function UserProjectPage(): JSX.Element { function UserProjectPage(): JSX.Element {
/* const [projects, setProjects] = useState<Project[]>([]); const [projects, setProjects] = useState<Project[]>([]);
*/ const [selectedProject, setSelectedProject] = useState(""); const [selectedProject, setSelectedProject] = useState("");
/* const getProjects = async (): Promise<void> => { const getProjects = async (): Promise<void> => {
const username = localStorage.getItem("username") ?? ""; // replace with actual username const token = localStorage.getItem("accessToken") ?? "";
const token = localStorage.getItem("accessToken") ?? ""; // replace with actual token const response = await api.getUserProjects(token);
const response = await api.getUserProjects(username, token);
console.log(response); console.log(response);
if (response.success) { if (response.success) {
setProjects(response.data ?? []); setProjects(response.data ?? []);
@ -23,16 +22,8 @@ function UserProjectPage(): JSX.Element {
}; };
// Call getProjects when the component mounts // Call getProjects when the component mounts
useEffect(() => { useEffect(() => {
getProjects(); void getProjects();
}, []); */ }, []);
// Mock data
const projects: Project[] = [
{ id: "1", name: "Project Test App" },
{ id: "2", name: "Project 2" },
{ id: "3", name: "Project 3" },
// Add more mock projects as needed
];
const handleProjectClick = (projectName: string): void => { const handleProjectClick = (projectName: string): void => {
setSelectedProject(projectName); setSelectedProject(projectName);