Merge branch 'frontend' into gruppPP

This commit is contained in:
Peter KW 2024-04-17 23:06:26 +02:00
commit 2f8e7547da
17 changed files with 397 additions and 49 deletions

View file

@ -1004,8 +1004,8 @@ export const api: API = {
} }
}, },
async getStatistics( async getStatistics(
token: string,
projectName: string, projectName: string,
token: string,
userName?: string, userName?: string,
): Promise<APIResponse<Statistics>> { ): Promise<APIResponse<Statistics>> {
try { try {

View file

@ -37,9 +37,9 @@ function AllTimeReportsInProject(): JSX.Element {
<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] text-[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] text-[30px]">
{weeklyReports.map((newWeeklyReport, index) => ( {weeklyReports.map((newWeeklyReport, index) => (
<Link <Link
to={`/editTimeReport/${projectName}/${newWeeklyReport.week}`} to={`/editTimeReport/${projectName}/${newWeeklyReport.week}/${newWeeklyReport.signedBy ? "signed" : "unsigned"}`}
key={index} key={index}
className="border-b-2 border-black w-full" className="border-b-2 border-black w-full cursor-pointer hover:font-extrabold"
> >
<div className="flex justify-between"> <div className="flex justify-between">
<h1> <h1>

View file

@ -39,9 +39,9 @@ function AllTimeReportsInProject(): JSX.Element {
<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] text-[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] text-[30px]">
{weeklyReports.map((newWeeklyReport, index) => ( {weeklyReports.map((newWeeklyReport, index) => (
<Link <Link
to={`/editOthersTR/${projectName}/${username}/${newWeeklyReport.week}`} to={`/editOthersTR/${projectName}/${username}/${newWeeklyReport.week}/${newWeeklyReport.signedBy ? "signed" : "unsigned"}`}
key={index} key={index}
className="border-b-2 border-black w-full" className="border-b-2 border-black w-full hover:font-extrabold"
> >
<div className="flex justify-between"> <div className="flex justify-between">
<h1> <h1>

View file

@ -65,7 +65,7 @@ function DisplayUserProject(): JSX.Element {
<Link <Link
to={`/PMViewUnsignedReport/${projectName}/${usernames[index]}/${unsignedReport.week}`} to={`/PMViewUnsignedReport/${projectName}/${usernames[index]}/${unsignedReport.week}`}
> >
<h1 className="underline cursor-pointer font-bold"> <h1 className="cursor-pointer font-bold hover:font-extrabold hover:underline">
View Report View Report
</h1> </h1>
</Link> </Link>

View file

@ -45,7 +45,7 @@ function DisplayUserProject(): JSX.Element {
onClick={() => void handleProjectClick(project.name)} onClick={() => void handleProjectClick(project.name)}
key={project.id} key={project.id}
> >
<h1 className="font-bold underline text-[30px] cursor-pointer"> <h1 className="font-bold hover:underline text-[30px] cursor-pointer hover:font-extrabold">
{project.name} {project.name}
</h1> </h1>
</div> </div>

View file

@ -18,12 +18,13 @@ export default function GetWeeklyReport(): JSX.Element {
const [testingTime, setTestingTime] = useState(0); const [testingTime, setTestingTime] = useState(0);
const token = localStorage.getItem("accessToken") ?? ""; const token = localStorage.getItem("accessToken") ?? "";
const { projectName, fetchedWeek } = useParams<{ const { projectName, fetchedWeek, signedOrUnsigned } = useParams<{
projectName: string; projectName: string;
fetchedWeek: string; fetchedWeek: string;
signedOrUnsigned: string;
}>(); }>();
const username = localStorage.getItem("userName") ?? ""; const username = localStorage.getItem("userName") ?? "";
console.log(projectName, fetchedWeek); console.log(projectName, fetchedWeek, signedOrUnsigned);
useEffect(() => { useEffect(() => {
const fetchWeeklyReport = async (): Promise<void> => { const fetchWeeklyReport = async (): Promise<void> => {
@ -59,7 +60,7 @@ export default function GetWeeklyReport(): JSX.Element {
}; };
void fetchWeeklyReport(); void fetchWeeklyReport();
}, [projectName, fetchedWeek, token]); }, [projectName, fetchedWeek, signedOrUnsigned, token]);
const handleUpdateWeeklyReport = async (): Promise<void> => { const handleUpdateWeeklyReport = async (): Promise<void> => {
const updateWeeklyReport: UpdateWeeklyReport = { const updateWeeklyReport: UpdateWeeklyReport = {
@ -139,6 +140,12 @@ export default function GetWeeklyReport(): JSX.Element {
) )
event.preventDefault(); event.preventDefault();
}} }}
onClick={() => {
if (signedOrUnsigned === "signed") {
alert("You cannot edit a signed report.");
}
}}
readOnly={signedOrUnsigned === "signed"}
/> />
</td> </td>
</tr> </tr>
@ -168,6 +175,12 @@ export default function GetWeeklyReport(): JSX.Element {
) )
event.preventDefault(); event.preventDefault();
}} }}
onClick={() => {
if (signedOrUnsigned === "signed") {
alert("You cannot edit a signed report.");
}
}}
readOnly={signedOrUnsigned === "signed"}
/> />
</td> </td>
</tr> </tr>
@ -197,6 +210,12 @@ export default function GetWeeklyReport(): JSX.Element {
) )
event.preventDefault(); event.preventDefault();
}} }}
onClick={() => {
if (signedOrUnsigned === "signed") {
alert("You cannot edit a signed report.");
}
}}
readOnly={signedOrUnsigned === "signed"}
/> />
</td> </td>
</tr> </tr>
@ -226,6 +245,12 @@ export default function GetWeeklyReport(): JSX.Element {
) )
event.preventDefault(); event.preventDefault();
}} }}
onClick={() => {
if (signedOrUnsigned === "signed") {
alert("You cannot edit a signed report.");
}
}}
readOnly={signedOrUnsigned === "signed"}
/> />
</td> </td>
</tr> </tr>
@ -255,6 +280,12 @@ export default function GetWeeklyReport(): JSX.Element {
) )
event.preventDefault(); event.preventDefault();
}} }}
onClick={() => {
if (signedOrUnsigned === "signed") {
alert("You cannot edit a signed report.");
}
}}
readOnly={signedOrUnsigned === "signed"}
/> />
</td> </td>
</tr> </tr>
@ -284,11 +315,18 @@ export default function GetWeeklyReport(): JSX.Element {
) )
event.preventDefault(); event.preventDefault();
}} }}
onClick={() => {
if (signedOrUnsigned === "signed") {
alert("You cannot edit a signed report.");
}
}}
readOnly={signedOrUnsigned === "signed"}
/> />
</td> </td>
</tr> </tr>
</tbody> </tbody>
</table> </table>
{signedOrUnsigned !== "signed" && (
<Button <Button
text="Submit changes" text="Submit changes"
onClick={(): void => { onClick={(): void => {
@ -296,6 +334,7 @@ export default function GetWeeklyReport(): JSX.Element {
}} }}
type="submit" type="submit"
/> />
)}
</div> </div>
</form> </form>
</div> </div>

View file

@ -1,7 +1,8 @@
import { useState, useEffect } from "react"; import { useState, useEffect } from "react";
import { WeeklyReport } from "../Types/goTypes"; import { WeeklyReport } from "../Types/goTypes";
import { api } from "../API/API"; import { api } from "../API/API";
import { useParams } from "react-router-dom"; import { useParams, useNavigate } from "react-router-dom";
import Button from "./Button";
/** /**
* Renders the component for editing a weekly report. * Renders the component for editing a weekly report.
@ -17,11 +18,14 @@ export default function OtherUsersTR(): JSX.Element {
const [ownWorkTime, setOwnWorkTime] = useState(0); const [ownWorkTime, setOwnWorkTime] = useState(0);
const [studyTime, setStudyTime] = useState(0); const [studyTime, setStudyTime] = useState(0);
const [testingTime, setTestingTime] = useState(0); const [testingTime, setTestingTime] = useState(0);
const [reportId, setReportId] = useState(0);
const token = localStorage.getItem("accessToken") ?? ""; const token = localStorage.getItem("accessToken") ?? "";
const { projectName } = useParams(); const { projectName } = useParams();
const { username } = useParams(); const { username } = useParams();
const { fetchedWeek } = useParams(); const { fetchedWeek } = useParams();
const { signedOrUnsigned } = useParams();
console.log(projectName, username, fetchedWeek, signedOrUnsigned);
useEffect(() => { useEffect(() => {
const fetchUsersWeeklyReport = async (): Promise<void> => { const fetchUsersWeeklyReport = async (): Promise<void> => {
@ -45,6 +49,7 @@ export default function OtherUsersTR(): JSX.Element {
studyTime: 0, studyTime: 0,
testingTime: 0, testingTime: 0,
}; };
setReportId(report.reportId);
setWeek(report.week); setWeek(report.week);
setDevelopmentTime(report.developmentTime); setDevelopmentTime(report.developmentTime);
setMeetingTime(report.meetingTime); setMeetingTime(report.meetingTime);
@ -60,6 +65,27 @@ export default function OtherUsersTR(): JSX.Element {
void fetchUsersWeeklyReport(); void fetchUsersWeeklyReport();
}); });
const handleUnsignWeeklyReport = async (): Promise<boolean> => {
const response = await api.unsignReport(reportId, token);
console.log(response);
console.log(reportId);
if (response.success) {
return true;
} else {
return false;
}
};
const handleDeleteWeeklyReport = async (): Promise<boolean> => {
const response = await api.deleteWeeklyReport(reportId, token);
console.log(response);
if (response.success) {
return true;
}
return false;
};
const navigate = useNavigate();
return ( return (
<> <>
<h1 className="text-[30px] font-bold">{username}&apos;s Report</h1> <h1 className="text-[30px] font-bold">{username}&apos;s Report</h1>
@ -153,6 +179,48 @@ export default function OtherUsersTR(): JSX.Element {
</tr> </tr>
</tbody> </tbody>
</table> </table>
<div className="flex space-x-4">
{signedOrUnsigned === "signed" && (
<Button
text="Unsign Report"
onClick={(): void => {
void (async (): Promise<void> => {
const success = await handleUnsignWeeklyReport();
if (success) {
alert("Report successfully unsigned!");
navigate(-1);
} else {
alert("Failed to unsign report");
return;
}
})();
}}
type={"button"}
/>
)}
<Button
text="Delete Time Report"
onClick={(): void => {
void (async (): Promise<void> => {
const confirmDelete = window.confirm(
"Are you sure you want to delete this report? This action cannot be undone.",
);
if (!confirmDelete) {
return;
}
const success = await handleDeleteWeeklyReport();
if (success) {
alert("Report successfully deleted!");
navigate(-1);
} else {
alert("Failed to delete report");
return;
}
})();
}}
type={"button"}
/>
</div>
</div> </div>
</div> </div>
</> </>

View file

@ -8,22 +8,22 @@ function PMProjectMenu(): JSX.Element {
<h1 className="font-bold text-[30px] mb-[20px]">{projectName}</h1> <h1 className="font-bold text-[30px] mb-[20px]">{projectName}</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-scroll space-y-[5vh] 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-[5vh] p-[30px]">
<Link to={`/timeReports/${projectName}/`}> <Link to={`/timeReports/${projectName}/`}>
<h1 className="font-bold underline text-[30px] cursor-pointer"> <h1 className="font-bold hover:underline text-[30px] cursor-pointer hover:font-extrabold">
Your Time Reports Your Time Reports
</h1> </h1>
</Link> </Link>
<Link to={`/newTimeReport/${projectName}`}> <Link to={`/newTimeReport/${projectName}`}>
<h1 className="font-bold underline text-[30px] cursor-pointer"> <h1 className="font-bold hover:underline text-[30px] cursor-pointer hover:font-extrabold">
New Time Report New Time Report
</h1> </h1>
</Link> </Link>
<Link to={`/projectMembers/${projectName}`}> <Link to={`/projectMembers/${projectName}`}>
<h1 className="font-bold underline text-[30px] cursor-pointer"> <h1 className="font-bold hover:underline text-[30px] cursor-pointer hover:font-extrabold">
Statistics Statistics
</h1> </h1>
</Link> </Link>
<Link to={`/unsignedReports/${projectName}`}> <Link to={`/unsignedReports/${projectName}`}>
<h1 className="font-bold underline text-[30px] cursor-pointer"> <h1 className="font-bold hover:underline text-[30px] cursor-pointer hover:font-extrabold">
Unsigned Time Reports Unsigned Time Reports
</h1> </h1>
</Link> </Link>

View file

@ -1,6 +1,7 @@
import { useState } from "react"; import { useState } from "react";
import { Link, useParams } from "react-router-dom"; import { Link, useParams } from "react-router-dom";
import GetUsersInProject, { ProjectMember } from "./GetUsersInProject"; import GetUsersInProject, { ProjectMember } from "./GetUsersInProject";
import { api } from "../API/API";
function ProjectMembers(): JSX.Element { function ProjectMembers(): JSX.Element {
const { projectName } = useParams(); const { projectName } = useParams();
@ -11,13 +12,32 @@ function ProjectMembers(): JSX.Element {
setUsersProp: setProjectMembers, setUsersProp: setProjectMembers,
}); });
const handleUserDeleteClick = async (username: string): Promise<void> => {
const token = localStorage.getItem("accessToken") ?? "";
const response = await api.removeUserFromProject(
username,
projectName ?? "",
token,
);
console.log(response.data);
// Remove the deleted user from the state
setProjectMembers((prevMembers) =>
prevMembers.filter((member) => member.Username !== username),
);
};
return ( return (
<> <>
<h1 className="font-bold text-[30px] mb-[20px]"> <h1 className="font-bold text-[30px] mb-[20px]">
All Members In: {projectName}{" "} All Members In: {projectName}{" "}
</h1> </h1>
<div className="border-4 border-black bg-white flex flex-col items-center justify-center min-h-[65vh] h-fit w-[70vw] rounded-3xl content-center overflow-scroll space-y-[10vh] p-[30px] text-[20px]"> <div className="border-4 border-black bg-white flex flex-col items-center justify-center min-h-[65vh] h-fit w-[70vw] rounded-3xl content-center overflow-scroll space-y-[10vh] p-[30px] text-[20px]">
{projectMembers.map((projectMember: ProjectMember, index: number) => ( {projectMembers.map((projectMember: ProjectMember, index: number) => {
if (projectMember.Username === "admin") {
return null; // Skip rendering for admin user
}
return (
<h1 key={index} className="border-b-2 border-black w-full"> <h1 key={index} className="border-b-2 border-black w-full">
<div className="flex justify-between"> <div className="flex justify-between">
<div className="flex"> <div className="flex">
@ -27,10 +47,24 @@ function ProjectMembers(): JSX.Element {
</div> </div>
<div className="flex"> <div className="flex">
<div className="ml-auto flex space-x-4"> <div className="ml-auto flex space-x-4">
{projectMember.Username !==
localStorage.getItem("username") && (
<h1
className="cursor-pointer font-bold hover:font-extrabold hover:underline"
onClick={() => {
confirm(
"Are you sure you want to delete this user? This action cannot be undone.",
) &&
void handleUserDeleteClick(projectMember.Username);
}}
>
Delete User
</h1>
)}
<Link <Link
to={`/otherUsersTimeReports/${projectName}/${projectMember.Username}`} to={`/otherUsersTimeReports/${projectName}/${projectMember.Username}`}
> >
<h1 className="underline cursor-pointer font-bold"> <h1 className="cursor-pointer font-bold hover:font-extrabold hover:underline">
View Reports View Reports
</h1> </h1>
</Link> </Link>
@ -38,7 +72,8 @@ function ProjectMembers(): JSX.Element {
</div> </div>
</div> </div>
</h1> </h1>
))} );
})}
</div> </div>
</> </>
); );

View file

@ -14,6 +14,7 @@ export default function TimePerRole(): JSX.Element {
const [own_work, setOwnWork] = useState<number>(0); const [own_work, setOwnWork] = useState<number>(0);
const [study, setStudy] = useState<number>(0); const [study, setStudy] = useState<number>(0);
const [testing, setTesting] = useState<number>(0); const [testing, setTesting] = useState<number>(0);
const total = development + meeting + admin + own_work + study + testing;
const token = localStorage.getItem("accessToken") ?? ""; const token = localStorage.getItem("accessToken") ?? "";
const { projectName } = useParams(); const { projectName } = useParams();
@ -49,7 +50,7 @@ export default function TimePerRole(): JSX.Element {
return ( return (
<> <>
<h1 className="font-bold text-[30px] mb-[20px]"> <h1 className="font-bold text-[30px] mb-[20px]">
Total Time Per Activity In: {projectName}{" "} Total Time Per Activity For All Members In: {projectName}{" "}
</h1> </h1>
<div className="border-4 border-black bg-white flex flex-col justify-start min-h-[65vh] h-fit w-[50vw] rounded-3xl overflow-scroll space-y-[2vh] p-[30px] items-center"> <div className="border-4 border-black bg-white flex flex-col justify-start min-h-[65vh] h-fit w-[50vw] rounded-3xl overflow-scroll space-y-[2vh] p-[30px] items-center">
<div className="flex flex-col items-center"> <div className="flex flex-col items-center">
@ -129,6 +130,12 @@ export default function TimePerRole(): JSX.Element {
/> />
</td> </td>
</tr> </tr>
<tr className="h-[10vh] font-bold font-">
<td>In Total:</td>
<td>
<h1>{total}</h1>
</td>
</tr>
</tbody> </tbody>
</table> </table>
</div> </div>

View file

@ -16,12 +16,12 @@ function UserProjectMenu(): JSX.Element {
<h1 className="font-bold text-[30px] mb-[20px]">{projectName}</h1> <h1 className="font-bold text-[30px] mb-[20px]">{projectName}</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-scroll 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={`/timeReports/${projectName}/`}> <Link to={`/timeReports/${projectName}/`}>
<h1 className="font-bold underline text-[30px] cursor-pointer"> <h1 className="font-bold hover:underline text-[30px] cursor-pointer hover:font-extrabold">
Your Time Reports Your Time Reports
</h1> </h1>
</Link> </Link>
<Link to={`/newTimeReport/${projectName}`}> <Link to={`/newTimeReport/${projectName}`}>
<h1 className="font-bold underline text-[30px] cursor-pointer"> <h1 className="font-bold hover:underline text-[30px] cursor-pointer hover:font-extrabold">
New Time Report New Time Report
</h1> </h1>
</Link> </Link>

View file

@ -0,0 +1,150 @@
import { useState, useEffect } from "react";
import { useParams } from "react-router-dom";
import { api } from "../API/API";
import { Statistics } from "../Types/goTypes";
/**
* Renders the component for showing total time per role in a project.
* @returns JSX.Element
*/
export default function UserStatistics(): JSX.Element {
const [development, setDevelopment] = useState<number>(0);
const [meeting, setMeeting] = useState<number>(0);
const [admin, setAdmin] = useState<number>(0);
const [own_work, setOwnWork] = useState<number>(0);
const [study, setStudy] = useState<number>(0);
const [testing, setTesting] = useState<number>(0);
const total = development + meeting + admin + own_work + study + testing;
const token = localStorage.getItem("accessToken") ?? "";
const { projectName } = useParams();
const { username } = useParams();
const fetchTimePerActivity = async (): Promise<void> => {
const response = await api.getStatistics(
projectName ?? "",
token,
username ?? "",
);
{
if (response.success) {
const statistics: Statistics = response.data ?? {
totalDevelopmentTime: 0,
totalMeetingTime: 0,
totalAdminTime: 0,
totalOwnWorkTime: 0,
totalStudyTime: 0,
totalTestingTime: 0,
};
setDevelopment(statistics.totalDevelopmentTime);
setMeeting(statistics.totalMeetingTime);
setAdmin(statistics.totalAdminTime);
setOwnWork(statistics.totalOwnWorkTime);
setStudy(statistics.totalStudyTime);
setTesting(statistics.totalTestingTime);
} else {
console.error("Failed to fetch weekly report:", response.message);
}
}
};
useEffect(() => {
void fetchTimePerActivity();
});
return (
<>
<h1 className="font-bold text-[30px] mb-[20px]">
Total Time In: {projectName}{" "}
</h1>
<div className="border-4 border-black bg-white flex flex-col justify-start min-h-[65vh] h-fit w-[50vw] rounded-3xl overflow-scroll space-y-[2vh] p-[30px] items-center">
<div className="flex flex-col items-center">
<table className="w-full text-center divide-y divide-x divide-white text-[30px]">
<thead>
<tr>
<th className="w-1/2 py-2 border-b-2 border-black">Activity</th>
<th className="w-1/2 py-2 border-b-2 border-black">
Total Time (min)
</th>
</tr>
</thead>
<tbody className="divide-y divide-black">
<tr className="h-[10vh]">
<td>Development</td>
<td>
<input
type="string"
className="border-2 border-black rounded-md text-center w-1/2"
value={development}
readOnly
/>
</td>
</tr>
<tr className="h-[10vh]">
<td>Meeting</td>
<td>
<input
type="string"
className="border-2 border-black rounded-md text-center w-1/2"
value={meeting}
readOnly
/>
</td>
</tr>
<tr className="h-[10vh]">
<td>Administration</td>
<td>
<input
type="string"
className="border-2 border-black rounded-md text-center w-1/2"
value={admin}
readOnly
/>
</td>
</tr>
<tr className="h-[10vh]">
<td>Own Work</td>
<td>
<input
type="string"
className="border-2 border-black rounded-md text-center w-1/2"
value={own_work}
readOnly
/>
</td>
</tr>
<tr className="h-[10vh]">
<td>Studies</td>
<td>
<input
type="string"
className="border-2 border-black rounded-md text-center w-1/2"
value={study}
readOnly
/>
</td>
</tr>
<tr className="h-[10vh]">
<td>Testing</td>
<td>
<input
type="string"
className="border-2 border-black rounded-md text-center w-1/2"
value={testing}
readOnly
/>
</td>
</tr>
<tr className="h-[10vh] font-bold font-">
<td>In Total:</td>
<td>
<h1>{total}</h1>
</td>
</tr>
</tbody>
</table>
</div>
</div>
</>
);
}

View file

@ -1,8 +1,12 @@
import BasicWindow from "../../Components/BasicWindow"; import BasicWindow from "../../Components/BasicWindow";
import BackButton from "../../Components/BackButton"; import BackButton from "../../Components/BackButton";
import AllTimeReportsInProjectOtherUser from "../../Components/AllTimeReportsInProjectOtherUser"; import AllTimeReportsInProjectOtherUser from "../../Components/AllTimeReportsInProjectOtherUser";
import Button from "../../Components/Button";
import { useParams, Link } from "react-router-dom";
function PMOtherUsersTR(): JSX.Element { function PMOtherUsersTR(): JSX.Element {
const { projectName } = useParams();
const { username } = useParams();
const content = ( const content = (
<> <>
<AllTimeReportsInProjectOtherUser /> <AllTimeReportsInProjectOtherUser />
@ -11,6 +15,15 @@ function PMOtherUsersTR(): JSX.Element {
const buttons = ( const buttons = (
<> <>
<Link to={`/viewStatistics/${projectName}/${username}`}>
<Button
text={`Statistics: ${username}`}
onClick={(): void => {
return;
}}
type={"button"}
/>
</Link>
<BackButton /> <BackButton />
</> </>
); );

View file

@ -16,7 +16,7 @@ function PMProjectMembers(): JSX.Element {
<> <>
<Link to={`/PMtimeactivity/${projectName}`}> <Link to={`/PMtimeactivity/${projectName}`}>
<Button <Button
text="Time / Activity" text="Statistics"
onClick={(): void => { onClick={(): void => {
return; return;
}} }}

View file

@ -0,0 +1,20 @@
import BackButton from "../../Components/BackButton";
import BasicWindow from "../../Components/BasicWindow";
import UserStatistics from "../../Components/UserStatistics";
function UserNewTimeReportPage(): JSX.Element {
const content = (
<>
<UserStatistics />
</>
);
const buttons = (
<>
<BackButton />
</>
);
return <BasicWindow content={content} buttons={buttons} />;
}
export default UserNewTimeReportPage;

View file

@ -1,10 +1,12 @@
import BasicWindow from "../../Components/BasicWindow"; import BasicWindow from "../../Components/BasicWindow";
import BackButton from "../../Components/BackButton"; import BackButton from "../../Components/BackButton";
import { useParams } from "react-router-dom"; import { useParams, Link } from "react-router-dom";
import AllTimeReportsInProject from "../../Components/AllTimeReportsInProject"; import AllTimeReportsInProject from "../../Components/AllTimeReportsInProject";
import Button from "../../Components/Button";
function UserViewTimeReportsPage(): JSX.Element { function UserViewTimeReportsPage(): JSX.Element {
const { projectName } = useParams(); const { projectName } = useParams();
const username = localStorage.getItem("username");
const content = ( const content = (
<> <>
@ -17,6 +19,15 @@ function UserViewTimeReportsPage(): JSX.Element {
const buttons = ( const buttons = (
<> <>
<Link to={`/viewStatistics/${projectName}/${username}`}>
<Button
text="Statistics"
onClick={(): void => {
return;
}}
type={"button"}
/>
</Link>
<BackButton /> <BackButton />
</> </>
); );

View file

@ -9,6 +9,7 @@ import AdminMenuPage from "./Pages/AdminPages/AdminMenuPage.tsx";
import UserEditTimeReportPage from "./Pages/UserPages/UserEditTimeReportPage.tsx"; import UserEditTimeReportPage from "./Pages/UserPages/UserEditTimeReportPage.tsx";
import UserNewTimeReportPage from "./Pages/UserPages/UserNewTimeReportPage.tsx"; import UserNewTimeReportPage from "./Pages/UserPages/UserNewTimeReportPage.tsx";
import UserViewTimeReportsPage from "./Pages/UserPages/UserViewTimeReportsPage.tsx"; import UserViewTimeReportsPage from "./Pages/UserPages/UserViewTimeReportsPage.tsx";
import UserViewStatistics from "./Pages/UserPages/UserViewStatistics.tsx";
import PMChangeRole from "./Pages/ProjectManagerPages/PMChangeRole.tsx"; import PMChangeRole from "./Pages/ProjectManagerPages/PMChangeRole.tsx";
import PMOtherUsersTR from "./Pages/ProjectManagerPages/PMOtherUsersTR.tsx"; import PMOtherUsersTR from "./Pages/ProjectManagerPages/PMOtherUsersTR.tsx";
import PMProjectMembers from "./Pages/ProjectManagerPages/PMProjectMembers.tsx"; import PMProjectMembers from "./Pages/ProjectManagerPages/PMProjectMembers.tsx";
@ -54,9 +55,13 @@ const router = createBrowserRouter([
element: <UserViewTimeReportsPage />, element: <UserViewTimeReportsPage />,
}, },
{ {
path: "/editTimeReport/:projectName/:fetchedWeek", path: "/editTimeReport/:projectName/:fetchedWeek/:signedOrUnsigned",
element: <UserEditTimeReportPage />, element: <UserEditTimeReportPage />,
}, },
{
path: "/viewStatistics/:projectName/:username",
element: <UserViewStatistics />,
},
{ {
path: "/changeRole/:projectName/:username", path: "/changeRole/:projectName/:username",
element: <PMChangeRole />, element: <PMChangeRole />,
@ -66,7 +71,7 @@ const router = createBrowserRouter([
element: <PMOtherUsersTR />, element: <PMOtherUsersTR />,
}, },
{ {
path: "/editOthersTR/:projectName/:username/:fetchedWeek", path: "/editOthersTR/:projectName/:username/:fetchedWeek/:signedOrUnsigned",
element: <PMViewOtherUsersTR />, element: <PMViewOtherUsersTR />,
}, },
{ {