Merge branch 'gruppDM' into frontend
This commit is contained in:
		
						commit
						6b880244a1
					
				
					 7 changed files with 287 additions and 254 deletions
				
			
		| 
						 | 
				
			
			@ -3,6 +3,7 @@ import { ProjectRoleChange } from "../Components/ChangeRole";
 | 
			
		|||
import { projectTimes } from "../Components/GetProjectTimes";
 | 
			
		||||
import { ProjectMember } from "../Components/GetUsersInProject";
 | 
			
		||||
import {
 | 
			
		||||
  UpdateWeeklyReport,
 | 
			
		||||
  NewWeeklyReport,
 | 
			
		||||
  NewUser,
 | 
			
		||||
  User,
 | 
			
		||||
| 
						 | 
				
			
			@ -87,6 +88,17 @@ interface API {
 | 
			
		|||
    token: string,
 | 
			
		||||
  ): Promise<APIResponse<string>>;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Updates a weekly report.
 | 
			
		||||
   * @param {UpdateWeeklyReport} weeklyReport The updated weekly report object.
 | 
			
		||||
   * @param {string} token The authentication token.
 | 
			
		||||
   * @returns {Promise<APIResponse<string>>} A promise containing the API response with the updated report.
 | 
			
		||||
   */
 | 
			
		||||
  updateWeeklyReport(
 | 
			
		||||
    weeklyReport: UpdateWeeklyReport,
 | 
			
		||||
    token: string,
 | 
			
		||||
  ): Promise<APIResponse<string>>;
 | 
			
		||||
 | 
			
		||||
  /** Gets a weekly report for a specific user, project and week
 | 
			
		||||
   * @param {string} projectName The name of the project.
 | 
			
		||||
   * @param {string} week The week number.
 | 
			
		||||
| 
						 | 
				
			
			@ -147,6 +159,17 @@ interface API {
 | 
			
		|||
    projectName: string,
 | 
			
		||||
    token: string,
 | 
			
		||||
  ): Promise<APIResponse<ProjectMember[]>>;
 | 
			
		||||
 | 
			
		||||
  /** Gets all unsigned reports in a project.
 | 
			
		||||
   * @param {string} projectName The name of the project.
 | 
			
		||||
   * @param {string} token The authentication token.
 | 
			
		||||
   * @returns {Promise<APIResponse<WeeklyReport[]>>} A promise resolving to an API response containing the list of unsigned reports.
 | 
			
		||||
   */
 | 
			
		||||
  getUnsignedReportsInProject(
 | 
			
		||||
    projectName: string,
 | 
			
		||||
    token: string,
 | 
			
		||||
  ): Promise<APIResponse<WeeklyReport[]>>;
 | 
			
		||||
 | 
			
		||||
  /**
 | 
			
		||||
   * Changes the username of a user in the database.
 | 
			
		||||
   * @param {StrNameChange} data The object containing the previous and new username.
 | 
			
		||||
| 
						 | 
				
			
			@ -458,6 +481,37 @@ export const api: API = {
 | 
			
		|||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  async updateWeeklyReport(
 | 
			
		||||
    weeklyReport: UpdateWeeklyReport,
 | 
			
		||||
    token: string,
 | 
			
		||||
  ): Promise<APIResponse<string>> {
 | 
			
		||||
    try {
 | 
			
		||||
      const response = await fetch("/api/updateWeeklyReport", {
 | 
			
		||||
        method: "PUT",
 | 
			
		||||
        headers: {
 | 
			
		||||
          "Content-Type": "application/json",
 | 
			
		||||
          Authorization: "Bearer " + token,
 | 
			
		||||
        },
 | 
			
		||||
        body: JSON.stringify(weeklyReport),
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      if (!response.ok) {
 | 
			
		||||
        return {
 | 
			
		||||
          success: false,
 | 
			
		||||
          message: "Failed to update weekly report",
 | 
			
		||||
        };
 | 
			
		||||
      }
 | 
			
		||||
 | 
			
		||||
      const data = await response.text();
 | 
			
		||||
      return { success: true, message: data };
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      return {
 | 
			
		||||
        success: false,
 | 
			
		||||
        message: "Failed to update weekly report",
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  async getWeeklyReport(
 | 
			
		||||
    projectName: string,
 | 
			
		||||
    week: string,
 | 
			
		||||
| 
						 | 
				
			
			@ -621,6 +675,38 @@ export const api: API = {
 | 
			
		|||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  async getUnsignedReportsInProject(
 | 
			
		||||
    projectName: string,
 | 
			
		||||
    token: string,
 | 
			
		||||
  ): Promise<APIResponse<WeeklyReport[]>> {
 | 
			
		||||
    try {
 | 
			
		||||
      const response = await fetch(`/api/getUnsignedReports/${projectName}`, {
 | 
			
		||||
        method: "GET",
 | 
			
		||||
        headers: {
 | 
			
		||||
          "Content-Type": "application/json",
 | 
			
		||||
          Authorization: "Bearer " + token,
 | 
			
		||||
        },
 | 
			
		||||
      });
 | 
			
		||||
 | 
			
		||||
      if (!response.ok) {
 | 
			
		||||
        return {
 | 
			
		||||
          success: false,
 | 
			
		||||
          message:
 | 
			
		||||
            "Failed to get unsigned reports for project: Response code " +
 | 
			
		||||
            response.status,
 | 
			
		||||
        };
 | 
			
		||||
      } else {
 | 
			
		||||
        const data = (await response.json()) as WeeklyReport[];
 | 
			
		||||
        return { success: true, data };
 | 
			
		||||
      }
 | 
			
		||||
    } catch (e) {
 | 
			
		||||
      return {
 | 
			
		||||
        success: false,
 | 
			
		||||
        message: "Failed to get unsigned reports for project, unknown error",
 | 
			
		||||
      };
 | 
			
		||||
    }
 | 
			
		||||
  },
 | 
			
		||||
 | 
			
		||||
  async changeUserName(
 | 
			
		||||
    data: StrNameChange,
 | 
			
		||||
    token: string,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,8 +1,9 @@
 | 
			
		|||
//Info: This component is used to display all the time reports for a project. It will display the week number,
 | 
			
		||||
//total time spent, and if the report has been signed or not. The user can click on a report to edit it.
 | 
			
		||||
import { useEffect, useState } from "react";
 | 
			
		||||
import { NewWeeklyReport } from "../Types/goTypes";
 | 
			
		||||
import { WeeklyReport } from "../Types/goTypes";
 | 
			
		||||
import { Link, useParams } from "react-router-dom";
 | 
			
		||||
import { api } from "../API/API";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Renders a component that displays all the time reports for a specific project.
 | 
			
		||||
| 
						 | 
				
			
			@ -11,14 +12,14 @@ import { Link, useParams } from "react-router-dom";
 | 
			
		|||
function AllTimeReportsInProject(): JSX.Element {
 | 
			
		||||
  const { username } = useParams();
 | 
			
		||||
  const { projectName } = useParams();
 | 
			
		||||
  const [weeklyReports, setWeeklyReports] = useState<NewWeeklyReport[]>([]);
 | 
			
		||||
  const [weeklyReports, setWeeklyReports] = useState<WeeklyReport[]>([]);
 | 
			
		||||
 | 
			
		||||
  /*   // Call getProjects when the component mounts
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    const getWeeklyReports = async (): Promise<void> => {
 | 
			
		||||
      const token = localStorage.getItem("accessToken") ?? "";
 | 
			
		||||
      const response = await api.getWeeklyReportsForUser(
 | 
			
		||||
      const response = await api.getWeeklyReportsForDifferentUser(
 | 
			
		||||
        projectName ?? "",
 | 
			
		||||
        username ?? "",
 | 
			
		||||
        token,
 | 
			
		||||
      );
 | 
			
		||||
      console.log(response);
 | 
			
		||||
| 
						 | 
				
			
			@ -27,39 +28,8 @@ function AllTimeReportsInProject(): JSX.Element {
 | 
			
		|||
      } else {
 | 
			
		||||
        console.error(response.message);
 | 
			
		||||
      }
 | 
			
		||||
    }; */
 | 
			
		||||
  // Mock data
 | 
			
		||||
  const getWeeklyReports = async (): Promise<void> => {
 | 
			
		||||
    // Simulate a delay
 | 
			
		||||
    await Promise.resolve();
 | 
			
		||||
    const mockWeeklyReports: NewWeeklyReport[] = [
 | 
			
		||||
      {
 | 
			
		||||
        projectName: "Project 1",
 | 
			
		||||
        week: 1,
 | 
			
		||||
        developmentTime: 10,
 | 
			
		||||
        meetingTime: 2,
 | 
			
		||||
        adminTime: 1,
 | 
			
		||||
        ownWorkTime: 3,
 | 
			
		||||
        studyTime: 4,
 | 
			
		||||
        testingTime: 5,
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        projectName: "Project 1",
 | 
			
		||||
        week: 2,
 | 
			
		||||
        developmentTime: 8,
 | 
			
		||||
        meetingTime: 2,
 | 
			
		||||
        adminTime: 1,
 | 
			
		||||
        ownWorkTime: 3,
 | 
			
		||||
        studyTime: 4,
 | 
			
		||||
        testingTime: 5,
 | 
			
		||||
      },
 | 
			
		||||
      // Add more reports as needed
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    // Use the mock data instead of the real data
 | 
			
		||||
    setWeeklyReports(mockWeeklyReports);
 | 
			
		||||
    };
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
 | 
			
		||||
    void getWeeklyReports();
 | 
			
		||||
  }, []);
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,12 +1,7 @@
 | 
			
		|||
import { useState, useEffect } from "react";
 | 
			
		||||
import { Link, useParams } from "react-router-dom";
 | 
			
		||||
 | 
			
		||||
interface UnsignedReports {
 | 
			
		||||
  projectName: string;
 | 
			
		||||
  username: string;
 | 
			
		||||
  week: number;
 | 
			
		||||
  signed: boolean;
 | 
			
		||||
}
 | 
			
		||||
import { api } from "../API/API";
 | 
			
		||||
import { WeeklyReport } from "../Types/goTypes";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Renders a component that displays the projects a user is a part of and links to the projects start-page.
 | 
			
		||||
| 
						 | 
				
			
			@ -14,80 +9,25 @@ interface UnsignedReports {
 | 
			
		|||
 */
 | 
			
		||||
function DisplayUserProject(): JSX.Element {
 | 
			
		||||
  const { projectName } = useParams();
 | 
			
		||||
  const [unsignedReports, setUnsignedReports] = useState<UnsignedReports[]>([]);
 | 
			
		||||
  const [unsignedReports, setUnsignedReports] = useState<WeeklyReport[]>([]);
 | 
			
		||||
  //const navigate = useNavigate();
 | 
			
		||||
 | 
			
		||||
  //   const getUnsignedReports = async (): Promise<void> => {
 | 
			
		||||
  //     const token = localStorage.getItem("accessToken") ?? "";
 | 
			
		||||
  //     const response = await api.getUserProjects(token);
 | 
			
		||||
  //     console.log(response);
 | 
			
		||||
  //     if (response.success) {
 | 
			
		||||
  //       setUnsignedReports(response.data ?? []);
 | 
			
		||||
  //     } else {
 | 
			
		||||
  //       console.error(response.message);
 | 
			
		||||
  //     }
 | 
			
		||||
  //   };
 | 
			
		||||
 | 
			
		||||
  //   const handleReportClick = async (projectName: string): Promise<void> => {
 | 
			
		||||
  //     const username = localStorage.getItem("username") ?? "";
 | 
			
		||||
  //     const token = localStorage.getItem("accessToken") ?? "";
 | 
			
		||||
  //     const response = await api.checkIfProjectManager(
 | 
			
		||||
  //       username,
 | 
			
		||||
  //       projectName,
 | 
			
		||||
  //       token,
 | 
			
		||||
  //     );
 | 
			
		||||
  //     if (response.success) {
 | 
			
		||||
  //       if (response.data) {
 | 
			
		||||
  //         navigate(`/PMProjectPage/${projectName}`);
 | 
			
		||||
  //       } else {
 | 
			
		||||
  //         navigate(`/project/${projectName}`);
 | 
			
		||||
  //       }
 | 
			
		||||
  //     } else {
 | 
			
		||||
  //       // handle error
 | 
			
		||||
  //       console.error(response.message);
 | 
			
		||||
  //     }
 | 
			
		||||
  //   };
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    const getUnsignedReports = async (): Promise<void> => {
 | 
			
		||||
    // Simulate a delay
 | 
			
		||||
    await Promise.resolve();
 | 
			
		||||
 | 
			
		||||
    // Use mock data
 | 
			
		||||
    const reports: UnsignedReports[] = [
 | 
			
		||||
      {
 | 
			
		||||
        projectName: "projecttest",
 | 
			
		||||
        username: "user1",
 | 
			
		||||
        week: 2,
 | 
			
		||||
        signed: false,
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        projectName: "projecttest",
 | 
			
		||||
        username: "user2",
 | 
			
		||||
        week: 2,
 | 
			
		||||
        signed: false,
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        projectName: "projecttest",
 | 
			
		||||
        username: "user3",
 | 
			
		||||
        week: 2,
 | 
			
		||||
        signed: false,
 | 
			
		||||
      },
 | 
			
		||||
      {
 | 
			
		||||
        projectName: "projecttest",
 | 
			
		||||
        username: "user4",
 | 
			
		||||
        week: 2,
 | 
			
		||||
        signed: false,
 | 
			
		||||
      },
 | 
			
		||||
    ];
 | 
			
		||||
 | 
			
		||||
    // Set the state with the mock data
 | 
			
		||||
    setUnsignedReports(reports);
 | 
			
		||||
      const token = localStorage.getItem("accessToken") ?? "";
 | 
			
		||||
      const response = await api.getUnsignedReportsInProject(
 | 
			
		||||
        projectName ?? "",
 | 
			
		||||
        token,
 | 
			
		||||
      );
 | 
			
		||||
      console.log(response);
 | 
			
		||||
      if (response.success) {
 | 
			
		||||
        setUnsignedReports(response.data ?? []);
 | 
			
		||||
      } else {
 | 
			
		||||
        console.error(response.message);
 | 
			
		||||
      }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
  // Call getProjects when the component mounts
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
    void getUnsignedReports();
 | 
			
		||||
  }, []);
 | 
			
		||||
  }, [projectName]); // Include 'projectName' in the dependency array
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <>
 | 
			
		||||
| 
						 | 
				
			
			@ -95,21 +35,30 @@ function DisplayUserProject(): JSX.Element {
 | 
			
		|||
        All Unsigned Reports In: {projectName}{" "}
 | 
			
		||||
      </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]">
 | 
			
		||||
        {unsignedReports.map(
 | 
			
		||||
          (unsignedReport: UnsignedReports, index: number) => (
 | 
			
		||||
        {unsignedReports.map((unsignedReport: WeeklyReport, index: number) => (
 | 
			
		||||
          <h1 key={index} className="border-b-2 border-black w-full">
 | 
			
		||||
            <div className="flex justify-between">
 | 
			
		||||
              <div className="flex">
 | 
			
		||||
                  <h1>{unsignedReport.username}</h1>
 | 
			
		||||
                <span className="ml-6 mr-2 font-bold">UserID:</span>
 | 
			
		||||
                <h1>{unsignedReport.userId}</h1>
 | 
			
		||||
                <span className="ml-6 mr-2 font-bold">Week:</span>
 | 
			
		||||
                <h1>{unsignedReport.week}</h1>
 | 
			
		||||
                <span className="ml-6 mr-2 font-bold">Total Time:</span>
 | 
			
		||||
                <h1>
 | 
			
		||||
                  {unsignedReport.developmentTime +
 | 
			
		||||
                    unsignedReport.meetingTime +
 | 
			
		||||
                    unsignedReport.adminTime +
 | 
			
		||||
                    unsignedReport.ownWorkTime +
 | 
			
		||||
                    unsignedReport.studyTime +
 | 
			
		||||
                    unsignedReport.testingTime}
 | 
			
		||||
                </h1>
 | 
			
		||||
                <span className="ml-6 mr-2 font-bold">Signed:</span>
 | 
			
		||||
                <h1>NO</h1>
 | 
			
		||||
              </div>
 | 
			
		||||
              <div className="flex">
 | 
			
		||||
                <div className="ml-auto flex space-x-4">
 | 
			
		||||
                  <Link
 | 
			
		||||
                      to={`/PMViewUnsignedReport/${projectName}/${unsignedReport.username}/${unsignedReport.week}`}
 | 
			
		||||
                    to={`/PMViewUnsignedReport/${projectName}/${unsignedReport.userId}/${unsignedReport.week}`}
 | 
			
		||||
                  >
 | 
			
		||||
                    <h1 className="underline cursor-pointer font-bold">
 | 
			
		||||
                      View Report
 | 
			
		||||
| 
						 | 
				
			
			@ -119,8 +68,7 @@ function DisplayUserProject(): JSX.Element {
 | 
			
		|||
              </div>
 | 
			
		||||
            </div>
 | 
			
		||||
          </h1>
 | 
			
		||||
          ),
 | 
			
		||||
        )}
 | 
			
		||||
        ))}
 | 
			
		||||
      </div>
 | 
			
		||||
    </>
 | 
			
		||||
  );
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
import { useState, useEffect } from "react";
 | 
			
		||||
import { WeeklyReport, NewWeeklyReport } from "../Types/goTypes";
 | 
			
		||||
import { WeeklyReport, UpdateWeeklyReport } from "../Types/goTypes";
 | 
			
		||||
import { api } from "../API/API";
 | 
			
		||||
import { useNavigate, useParams } from "react-router-dom";
 | 
			
		||||
import Button from "./Button";
 | 
			
		||||
| 
						 | 
				
			
			@ -22,6 +22,7 @@ export default function GetWeeklyReport(): JSX.Element {
 | 
			
		|||
    projectName: string;
 | 
			
		||||
    fetchedWeek: string;
 | 
			
		||||
  }>();
 | 
			
		||||
  const username = localStorage.getItem("userName") ?? "";
 | 
			
		||||
  console.log(projectName, fetchedWeek);
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
| 
						 | 
				
			
			@ -60,8 +61,9 @@ export default function GetWeeklyReport(): JSX.Element {
 | 
			
		|||
    void fetchWeeklyReport();
 | 
			
		||||
  }, [projectName, fetchedWeek, token]);
 | 
			
		||||
 | 
			
		||||
  const handleNewWeeklyReport = async (): Promise<void> => {
 | 
			
		||||
    const newWeeklyReport: NewWeeklyReport = {
 | 
			
		||||
  const handleUpdateWeeklyReport = async (): Promise<void> => {
 | 
			
		||||
    const updateWeeklyReport: UpdateWeeklyReport = {
 | 
			
		||||
      userName: username,
 | 
			
		||||
      projectName: projectName ?? "",
 | 
			
		||||
      week,
 | 
			
		||||
      developmentTime,
 | 
			
		||||
| 
						 | 
				
			
			@ -72,7 +74,7 @@ export default function GetWeeklyReport(): JSX.Element {
 | 
			
		|||
      testingTime,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    await api.submitWeeklyReport(newWeeklyReport, token);
 | 
			
		||||
    await api.updateWeeklyReport(updateWeeklyReport, token);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const navigate = useNavigate();
 | 
			
		||||
| 
						 | 
				
			
			@ -89,7 +91,8 @@ export default function GetWeeklyReport(): JSX.Element {
 | 
			
		|||
              return;
 | 
			
		||||
            }
 | 
			
		||||
            e.preventDefault();
 | 
			
		||||
            void handleNewWeeklyReport();
 | 
			
		||||
            void handleUpdateWeeklyReport();
 | 
			
		||||
            alert("Changes submitted");
 | 
			
		||||
            navigate(-1);
 | 
			
		||||
          }}
 | 
			
		||||
        >
 | 
			
		||||
| 
						 | 
				
			
			@ -128,7 +131,12 @@ export default function GetWeeklyReport(): JSX.Element {
 | 
			
		|||
                      }}
 | 
			
		||||
                      onKeyDown={(event) => {
 | 
			
		||||
                        const keyValue = event.key;
 | 
			
		||||
                        if (!/\d/.test(keyValue) && keyValue !== "Backspace")
 | 
			
		||||
                        if (
 | 
			
		||||
                          !/\d/.test(keyValue) &&
 | 
			
		||||
                          keyValue !== "Backspace" &&
 | 
			
		||||
                          keyValue !== "ArrowLeft" &&
 | 
			
		||||
                          keyValue !== "ArrowRight"
 | 
			
		||||
                        )
 | 
			
		||||
                          event.preventDefault();
 | 
			
		||||
                      }}
 | 
			
		||||
                    />
 | 
			
		||||
| 
						 | 
				
			
			@ -152,7 +160,12 @@ export default function GetWeeklyReport(): JSX.Element {
 | 
			
		|||
                      }}
 | 
			
		||||
                      onKeyDown={(event) => {
 | 
			
		||||
                        const keyValue = event.key;
 | 
			
		||||
                        if (!/\d/.test(keyValue) && keyValue !== "Backspace")
 | 
			
		||||
                        if (
 | 
			
		||||
                          !/\d/.test(keyValue) &&
 | 
			
		||||
                          keyValue !== "Backspace" &&
 | 
			
		||||
                          keyValue !== "ArrowLeft" &&
 | 
			
		||||
                          keyValue !== "ArrowRight"
 | 
			
		||||
                        )
 | 
			
		||||
                          event.preventDefault();
 | 
			
		||||
                      }}
 | 
			
		||||
                    />
 | 
			
		||||
| 
						 | 
				
			
			@ -176,7 +189,12 @@ export default function GetWeeklyReport(): JSX.Element {
 | 
			
		|||
                      }}
 | 
			
		||||
                      onKeyDown={(event) => {
 | 
			
		||||
                        const keyValue = event.key;
 | 
			
		||||
                        if (!/\d/.test(keyValue) && keyValue !== "Backspace")
 | 
			
		||||
                        if (
 | 
			
		||||
                          !/\d/.test(keyValue) &&
 | 
			
		||||
                          keyValue !== "Backspace" &&
 | 
			
		||||
                          keyValue !== "ArrowLeft" &&
 | 
			
		||||
                          keyValue !== "ArrowRight"
 | 
			
		||||
                        )
 | 
			
		||||
                          event.preventDefault();
 | 
			
		||||
                      }}
 | 
			
		||||
                    />
 | 
			
		||||
| 
						 | 
				
			
			@ -200,7 +218,12 @@ export default function GetWeeklyReport(): JSX.Element {
 | 
			
		|||
                      }}
 | 
			
		||||
                      onKeyDown={(event) => {
 | 
			
		||||
                        const keyValue = event.key;
 | 
			
		||||
                        if (!/\d/.test(keyValue) && keyValue !== "Backspace")
 | 
			
		||||
                        if (
 | 
			
		||||
                          !/\d/.test(keyValue) &&
 | 
			
		||||
                          keyValue !== "Backspace" &&
 | 
			
		||||
                          keyValue !== "ArrowLeft" &&
 | 
			
		||||
                          keyValue !== "ArrowRight"
 | 
			
		||||
                        )
 | 
			
		||||
                          event.preventDefault();
 | 
			
		||||
                      }}
 | 
			
		||||
                    />
 | 
			
		||||
| 
						 | 
				
			
			@ -224,7 +247,12 @@ export default function GetWeeklyReport(): JSX.Element {
 | 
			
		|||
                      }}
 | 
			
		||||
                      onKeyDown={(event) => {
 | 
			
		||||
                        const keyValue = event.key;
 | 
			
		||||
                        if (!/\d/.test(keyValue) && keyValue !== "Backspace")
 | 
			
		||||
                        if (
 | 
			
		||||
                          !/\d/.test(keyValue) &&
 | 
			
		||||
                          keyValue !== "Backspace" &&
 | 
			
		||||
                          keyValue !== "ArrowLeft" &&
 | 
			
		||||
                          keyValue !== "ArrowRight"
 | 
			
		||||
                        )
 | 
			
		||||
                          event.preventDefault();
 | 
			
		||||
                      }}
 | 
			
		||||
                    />
 | 
			
		||||
| 
						 | 
				
			
			@ -248,7 +276,12 @@ export default function GetWeeklyReport(): JSX.Element {
 | 
			
		|||
                      }}
 | 
			
		||||
                      onKeyDown={(event) => {
 | 
			
		||||
                        const keyValue = event.key;
 | 
			
		||||
                        if (!/\d/.test(keyValue) && keyValue !== "Backspace")
 | 
			
		||||
                        if (
 | 
			
		||||
                          !/\d/.test(keyValue) &&
 | 
			
		||||
                          keyValue !== "Backspace" &&
 | 
			
		||||
                          keyValue !== "ArrowLeft" &&
 | 
			
		||||
                          keyValue !== "ArrowRight"
 | 
			
		||||
                        )
 | 
			
		||||
                          event.preventDefault();
 | 
			
		||||
                      }}
 | 
			
		||||
                    />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -139,7 +139,12 @@ export default function NewWeeklyReport(): JSX.Element {
 | 
			
		|||
                      }}
 | 
			
		||||
                      onKeyDown={(event) => {
 | 
			
		||||
                        const keyValue = event.key;
 | 
			
		||||
                        if (!/\d/.test(keyValue) && keyValue !== "Backspace")
 | 
			
		||||
                        if (
 | 
			
		||||
                          !/\d/.test(keyValue) &&
 | 
			
		||||
                          keyValue !== "Backspace" &&
 | 
			
		||||
                          keyValue !== "ArrowLeft" &&
 | 
			
		||||
                          keyValue !== "ArrowRight"
 | 
			
		||||
                        )
 | 
			
		||||
                          event.preventDefault();
 | 
			
		||||
                      }}
 | 
			
		||||
                    />
 | 
			
		||||
| 
						 | 
				
			
			@ -163,7 +168,12 @@ export default function NewWeeklyReport(): JSX.Element {
 | 
			
		|||
                      }}
 | 
			
		||||
                      onKeyDown={(event) => {
 | 
			
		||||
                        const keyValue = event.key;
 | 
			
		||||
                        if (!/\d/.test(keyValue) && keyValue !== "Backspace")
 | 
			
		||||
                        if (
 | 
			
		||||
                          !/\d/.test(keyValue) &&
 | 
			
		||||
                          keyValue !== "Backspace" &&
 | 
			
		||||
                          keyValue !== "ArrowLeft" &&
 | 
			
		||||
                          keyValue !== "ArrowRight"
 | 
			
		||||
                        )
 | 
			
		||||
                          event.preventDefault();
 | 
			
		||||
                      }}
 | 
			
		||||
                    />
 | 
			
		||||
| 
						 | 
				
			
			@ -187,7 +197,12 @@ export default function NewWeeklyReport(): JSX.Element {
 | 
			
		|||
                      }}
 | 
			
		||||
                      onKeyDown={(event) => {
 | 
			
		||||
                        const keyValue = event.key;
 | 
			
		||||
                        if (!/\d/.test(keyValue) && keyValue !== "Backspace")
 | 
			
		||||
                        if (
 | 
			
		||||
                          !/\d/.test(keyValue) &&
 | 
			
		||||
                          keyValue !== "Backspace" &&
 | 
			
		||||
                          keyValue !== "ArrowLeft" &&
 | 
			
		||||
                          keyValue !== "ArrowRight"
 | 
			
		||||
                        )
 | 
			
		||||
                          event.preventDefault();
 | 
			
		||||
                      }}
 | 
			
		||||
                    />
 | 
			
		||||
| 
						 | 
				
			
			@ -211,7 +226,12 @@ export default function NewWeeklyReport(): JSX.Element {
 | 
			
		|||
                      }}
 | 
			
		||||
                      onKeyDown={(event) => {
 | 
			
		||||
                        const keyValue = event.key;
 | 
			
		||||
                        if (!/\d/.test(keyValue) && keyValue !== "Backspace")
 | 
			
		||||
                        if (
 | 
			
		||||
                          !/\d/.test(keyValue) &&
 | 
			
		||||
                          keyValue !== "Backspace" &&
 | 
			
		||||
                          keyValue !== "ArrowLeft" &&
 | 
			
		||||
                          keyValue !== "ArrowRight"
 | 
			
		||||
                        )
 | 
			
		||||
                          event.preventDefault();
 | 
			
		||||
                      }}
 | 
			
		||||
                    />
 | 
			
		||||
| 
						 | 
				
			
			@ -235,7 +255,12 @@ export default function NewWeeklyReport(): JSX.Element {
 | 
			
		|||
                      }}
 | 
			
		||||
                      onKeyDown={(event) => {
 | 
			
		||||
                        const keyValue = event.key;
 | 
			
		||||
                        if (!/\d/.test(keyValue) && keyValue !== "Backspace")
 | 
			
		||||
                        if (
 | 
			
		||||
                          !/\d/.test(keyValue) &&
 | 
			
		||||
                          keyValue !== "Backspace" &&
 | 
			
		||||
                          keyValue !== "ArrowLeft" &&
 | 
			
		||||
                          keyValue !== "ArrowRight"
 | 
			
		||||
                        )
 | 
			
		||||
                          event.preventDefault();
 | 
			
		||||
                      }}
 | 
			
		||||
                    />
 | 
			
		||||
| 
						 | 
				
			
			@ -259,7 +284,12 @@ export default function NewWeeklyReport(): JSX.Element {
 | 
			
		|||
                      }}
 | 
			
		||||
                      onKeyDown={(event) => {
 | 
			
		||||
                        const keyValue = event.key;
 | 
			
		||||
                        if (!/\d/.test(keyValue) && keyValue !== "Backspace")
 | 
			
		||||
                        if (
 | 
			
		||||
                          !/\d/.test(keyValue) &&
 | 
			
		||||
                          keyValue !== "Backspace" &&
 | 
			
		||||
                          keyValue !== "ArrowLeft" &&
 | 
			
		||||
                          keyValue !== "ArrowRight"
 | 
			
		||||
                        )
 | 
			
		||||
                          event.preventDefault();
 | 
			
		||||
                      }}
 | 
			
		||||
                    />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,70 +1,45 @@
 | 
			
		|||
import { useState, useEffect } from "react";
 | 
			
		||||
import { useParams } from "react-router-dom";
 | 
			
		||||
import { api } from "../API/API";
 | 
			
		||||
import { projectTimes } from "./GetProjectTimes";
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
 * Renders the component for showing total time per role in a project.
 | 
			
		||||
 * @returns JSX.Element
 | 
			
		||||
 */
 | 
			
		||||
export default function TimePerRole(): JSX.Element {
 | 
			
		||||
  const [developmentTime, setDevelopmentTime] = useState<number>();
 | 
			
		||||
  const [meetingTime, setMeetingTime] = useState<number>();
 | 
			
		||||
  const [adminTime, setAdminTime] = useState<number>();
 | 
			
		||||
  const [ownWorkTime, setOwnWorkTime] = useState<number>();
 | 
			
		||||
  const [studyTime, setStudyTime] = useState<number>();
 | 
			
		||||
  const [testingTime, setTestingTime] = useState<number>();
 | 
			
		||||
  const [development, setDevelopment] = useState<number>();
 | 
			
		||||
  const [meeting, setMeeting] = useState<number>();
 | 
			
		||||
  const [admin, setAdmin] = useState<number>();
 | 
			
		||||
  const [own_work, setOwnWork] = useState<number>();
 | 
			
		||||
  const [study, setStudy] = useState<number>();
 | 
			
		||||
  const [testing, setTesting] = useState<number>();
 | 
			
		||||
 | 
			
		||||
  //   const token = localStorage.getItem("accessToken") ?? "";
 | 
			
		||||
  //   const username = localStorage.getItem("username") ?? "";
 | 
			
		||||
  const token = localStorage.getItem("accessToken") ?? "";
 | 
			
		||||
  const { projectName } = useParams();
 | 
			
		||||
 | 
			
		||||
  //   const fetchTimePerRole = async (): Promise<void> => {
 | 
			
		||||
  //     const response = await api.getTimePerRole(
 | 
			
		||||
  //       username,
 | 
			
		||||
  //       projectName ?? "",
 | 
			
		||||
  //       token,
 | 
			
		||||
  //     );
 | 
			
		||||
  // {
 | 
			
		||||
  //     if (response.success) {
 | 
			
		||||
  //       const report: TimePerRole = response.data ?? {
 | 
			
		||||
  //         PManagerTime: 0,
 | 
			
		||||
  //         SManagerTime: 0,
 | 
			
		||||
  //         DeveloperTime: 0,
 | 
			
		||||
  //         TesterTime: 0,
 | 
			
		||||
  //       };
 | 
			
		||||
  //     } else {
 | 
			
		||||
  //       console.error("Failed to fetch weekly report:", response.message);
 | 
			
		||||
  //     }
 | 
			
		||||
  //   }
 | 
			
		||||
 | 
			
		||||
  interface TimePerActivity {
 | 
			
		||||
    developmentTime: number;
 | 
			
		||||
    meetingTime: number;
 | 
			
		||||
    adminTime: number;
 | 
			
		||||
    ownWorkTime: number;
 | 
			
		||||
    studyTime: number;
 | 
			
		||||
    testingTime: number;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  const fetchTimePerActivity = async (): Promise<void> => {
 | 
			
		||||
    // Use mock data
 | 
			
		||||
    const report: TimePerActivity = {
 | 
			
		||||
      developmentTime: 100,
 | 
			
		||||
      meetingTime: 200,
 | 
			
		||||
      adminTime: 300,
 | 
			
		||||
      ownWorkTime: 50,
 | 
			
		||||
      studyTime: 75,
 | 
			
		||||
      testingTime: 110,
 | 
			
		||||
    const response = await api.getProjectTimes(projectName ?? "", token);
 | 
			
		||||
    {
 | 
			
		||||
      if (response.success) {
 | 
			
		||||
        const report: projectTimes = response.data ?? {
 | 
			
		||||
          development: 0,
 | 
			
		||||
          meeting: 0,
 | 
			
		||||
          admin: 0,
 | 
			
		||||
          own_work: 0,
 | 
			
		||||
          study: 0,
 | 
			
		||||
          testing: 0,
 | 
			
		||||
        };
 | 
			
		||||
 | 
			
		||||
    // Set the state with the mock data
 | 
			
		||||
    setDevelopmentTime(report.developmentTime);
 | 
			
		||||
    setMeetingTime(report.meetingTime);
 | 
			
		||||
    setAdminTime(report.adminTime);
 | 
			
		||||
    setOwnWorkTime(report.ownWorkTime);
 | 
			
		||||
    setStudyTime(report.studyTime);
 | 
			
		||||
    setTestingTime(report.testingTime);
 | 
			
		||||
 | 
			
		||||
    await Promise.resolve();
 | 
			
		||||
        setDevelopment(report.development);
 | 
			
		||||
        setMeeting(report.meeting);
 | 
			
		||||
        setAdmin(report.admin);
 | 
			
		||||
        setOwnWork(report.own_work);
 | 
			
		||||
        setStudy(report.study);
 | 
			
		||||
        setTesting(report.testing);
 | 
			
		||||
      } else {
 | 
			
		||||
        console.error("Failed to fetch weekly report:", response.message);
 | 
			
		||||
      }
 | 
			
		||||
    }
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  useEffect(() => {
 | 
			
		||||
| 
						 | 
				
			
			@ -94,10 +69,8 @@ export default function TimePerRole(): JSX.Element {
 | 
			
		|||
                  <input
 | 
			
		||||
                    type="string"
 | 
			
		||||
                    className="border-2 border-black rounded-md text-center w-1/2"
 | 
			
		||||
                    value={developmentTime}
 | 
			
		||||
                    onKeyDown={(event) => {
 | 
			
		||||
                      event.preventDefault();
 | 
			
		||||
                    }}
 | 
			
		||||
                    value={development}
 | 
			
		||||
                    readOnly
 | 
			
		||||
                  />
 | 
			
		||||
                </td>
 | 
			
		||||
              </tr>
 | 
			
		||||
| 
						 | 
				
			
			@ -107,10 +80,8 @@ export default function TimePerRole(): JSX.Element {
 | 
			
		|||
                  <input
 | 
			
		||||
                    type="string"
 | 
			
		||||
                    className="border-2 border-black rounded-md text-center w-1/2"
 | 
			
		||||
                    value={meetingTime}
 | 
			
		||||
                    onKeyDown={(event) => {
 | 
			
		||||
                      event.preventDefault();
 | 
			
		||||
                    }}
 | 
			
		||||
                    value={meeting}
 | 
			
		||||
                    readOnly
 | 
			
		||||
                  />
 | 
			
		||||
                </td>
 | 
			
		||||
              </tr>
 | 
			
		||||
| 
						 | 
				
			
			@ -120,10 +91,8 @@ export default function TimePerRole(): JSX.Element {
 | 
			
		|||
                  <input
 | 
			
		||||
                    type="string"
 | 
			
		||||
                    className="border-2 border-black rounded-md text-center w-1/2"
 | 
			
		||||
                    value={adminTime}
 | 
			
		||||
                    onKeyDown={(event) => {
 | 
			
		||||
                      event.preventDefault();
 | 
			
		||||
                    }}
 | 
			
		||||
                    value={admin}
 | 
			
		||||
                    readOnly
 | 
			
		||||
                  />
 | 
			
		||||
                </td>
 | 
			
		||||
              </tr>
 | 
			
		||||
| 
						 | 
				
			
			@ -133,10 +102,8 @@ export default function TimePerRole(): JSX.Element {
 | 
			
		|||
                  <input
 | 
			
		||||
                    type="string"
 | 
			
		||||
                    className="border-2 border-black rounded-md text-center w-1/2"
 | 
			
		||||
                    value={ownWorkTime}
 | 
			
		||||
                    onKeyDown={(event) => {
 | 
			
		||||
                      event.preventDefault();
 | 
			
		||||
                    }}
 | 
			
		||||
                    value={own_work}
 | 
			
		||||
                    readOnly
 | 
			
		||||
                  />
 | 
			
		||||
                </td>
 | 
			
		||||
              </tr>
 | 
			
		||||
| 
						 | 
				
			
			@ -146,10 +113,8 @@ export default function TimePerRole(): JSX.Element {
 | 
			
		|||
                  <input
 | 
			
		||||
                    type="string"
 | 
			
		||||
                    className="border-2 border-black rounded-md text-center w-1/2"
 | 
			
		||||
                    value={studyTime}
 | 
			
		||||
                    onKeyDown={(event) => {
 | 
			
		||||
                      event.preventDefault();
 | 
			
		||||
                    }}
 | 
			
		||||
                    value={study}
 | 
			
		||||
                    readOnly
 | 
			
		||||
                  />
 | 
			
		||||
                </td>
 | 
			
		||||
              </tr>
 | 
			
		||||
| 
						 | 
				
			
			@ -159,10 +124,8 @@ export default function TimePerRole(): JSX.Element {
 | 
			
		|||
                  <input
 | 
			
		||||
                    type="string"
 | 
			
		||||
                    className="border-2 border-black rounded-md text-center w-1/2"
 | 
			
		||||
                    value={testingTime}
 | 
			
		||||
                    onKeyDown={(event) => {
 | 
			
		||||
                      event.preventDefault();
 | 
			
		||||
                    }}
 | 
			
		||||
                    value={testing}
 | 
			
		||||
                    readOnly
 | 
			
		||||
                  />
 | 
			
		||||
                </td>
 | 
			
		||||
              </tr>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,5 +1,5 @@
 | 
			
		|||
import { useState, useEffect } from "react";
 | 
			
		||||
import { WeeklyReport, NewWeeklyReport } from "../Types/goTypes";
 | 
			
		||||
import { WeeklyReport } from "../Types/goTypes";
 | 
			
		||||
import { api } from "../API/API";
 | 
			
		||||
import { useNavigate, useParams } from "react-router-dom";
 | 
			
		||||
import Button from "./Button";
 | 
			
		||||
| 
						 | 
				
			
			@ -18,6 +18,7 @@ export default function GetOtherUsersReport(): JSX.Element {
 | 
			
		|||
  const [ownWorkTime, setOwnWorkTime] = useState(0);
 | 
			
		||||
  const [studyTime, setStudyTime] = useState(0);
 | 
			
		||||
  const [testingTime, setTestingTime] = useState(0);
 | 
			
		||||
  const [reportId, setReportId] = useState(0);
 | 
			
		||||
 | 
			
		||||
  const token = localStorage.getItem("accessToken") ?? "";
 | 
			
		||||
  const { projectName } = useParams();
 | 
			
		||||
| 
						 | 
				
			
			@ -45,6 +46,7 @@ export default function GetOtherUsersReport(): JSX.Element {
 | 
			
		|||
          studyTime: 0,
 | 
			
		||||
          testingTime: 0,
 | 
			
		||||
        };
 | 
			
		||||
        setReportId(report.reportId);
 | 
			
		||||
        setWeek(report.week);
 | 
			
		||||
        setDevelopmentTime(report.developmentTime);
 | 
			
		||||
        setMeetingTime(report.meetingTime);
 | 
			
		||||
| 
						 | 
				
			
			@ -61,30 +63,23 @@ export default function GetOtherUsersReport(): JSX.Element {
 | 
			
		|||
  });
 | 
			
		||||
 | 
			
		||||
  const handleSignWeeklyReport = async (): Promise<void> => {
 | 
			
		||||
    const newWeeklyReport: NewWeeklyReport = {
 | 
			
		||||
      projectName: projectName ?? "",
 | 
			
		||||
      week,
 | 
			
		||||
      developmentTime,
 | 
			
		||||
      meetingTime,
 | 
			
		||||
      adminTime,
 | 
			
		||||
      ownWorkTime,
 | 
			
		||||
      studyTime,
 | 
			
		||||
      testingTime,
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    await api.submitWeeklyReport(newWeeklyReport, token);
 | 
			
		||||
    await api.signReport(reportId, token);
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  const navigate = useNavigate();
 | 
			
		||||
 | 
			
		||||
  return (
 | 
			
		||||
    <>
 | 
			
		||||
      <h1 className="text-[30px] font-bold">{username}'s Report</h1>
 | 
			
		||||
      <h1 className="text-[30px] font-bold">
 | 
			
		||||
        {" "}
 | 
			
		||||
        UserId: {username}'s Report
 | 
			
		||||
      </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">
 | 
			
		||||
        <form
 | 
			
		||||
          onSubmit={(e) => {
 | 
			
		||||
            e.preventDefault();
 | 
			
		||||
            void handleSignWeeklyReport();
 | 
			
		||||
            alert("Report successfully signed!");
 | 
			
		||||
            navigate(-1);
 | 
			
		||||
          }}
 | 
			
		||||
        >
 | 
			
		||||
| 
						 | 
				
			
			@ -112,7 +107,10 @@ export default function GetOtherUsersReport(): JSX.Element {
 | 
			
		|||
                      type="text"
 | 
			
		||||
                      min="0"
 | 
			
		||||
                      className="border-2 border-black rounded-md text-center w-1/2"
 | 
			
		||||
                      value={developmentTime === 0 ? "" : developmentTime}
 | 
			
		||||
                      defaultValue={
 | 
			
		||||
                        developmentTime === 0 ? "" : developmentTime
 | 
			
		||||
                      }
 | 
			
		||||
                      readOnly
 | 
			
		||||
                    />
 | 
			
		||||
                  </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
| 
						 | 
				
			
			@ -123,7 +121,8 @@ export default function GetOtherUsersReport(): JSX.Element {
 | 
			
		|||
                      type="text"
 | 
			
		||||
                      min="0"
 | 
			
		||||
                      className="border-2 border-black rounded-md text-center w-1/2"
 | 
			
		||||
                      value={meetingTime === 0 ? "" : meetingTime}
 | 
			
		||||
                      defaultValue={meetingTime === 0 ? "" : meetingTime}
 | 
			
		||||
                      readOnly
 | 
			
		||||
                    />
 | 
			
		||||
                  </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
| 
						 | 
				
			
			@ -134,7 +133,8 @@ export default function GetOtherUsersReport(): JSX.Element {
 | 
			
		|||
                      type="text"
 | 
			
		||||
                      min="0"
 | 
			
		||||
                      className="border-2 border-black rounded-md text-center w-1/2"
 | 
			
		||||
                      value={adminTime === 0 ? "" : adminTime}
 | 
			
		||||
                      defaultValue={adminTime === 0 ? "" : adminTime}
 | 
			
		||||
                      readOnly
 | 
			
		||||
                    />
 | 
			
		||||
                  </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
| 
						 | 
				
			
			@ -145,7 +145,8 @@ export default function GetOtherUsersReport(): JSX.Element {
 | 
			
		|||
                      type="text"
 | 
			
		||||
                      min="0"
 | 
			
		||||
                      className="border-2 border-black rounded-md text-center w-1/2"
 | 
			
		||||
                      value={ownWorkTime === 0 ? "" : ownWorkTime}
 | 
			
		||||
                      defaultValue={ownWorkTime === 0 ? "" : ownWorkTime}
 | 
			
		||||
                      readOnly
 | 
			
		||||
                    />
 | 
			
		||||
                  </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
| 
						 | 
				
			
			@ -156,7 +157,8 @@ export default function GetOtherUsersReport(): JSX.Element {
 | 
			
		|||
                      type="text"
 | 
			
		||||
                      min="0"
 | 
			
		||||
                      className="border-2 border-black rounded-md text-center w-1/2"
 | 
			
		||||
                      value={studyTime === 0 ? "" : studyTime}
 | 
			
		||||
                      defaultValue={studyTime === 0 ? "" : studyTime}
 | 
			
		||||
                      readOnly
 | 
			
		||||
                    />
 | 
			
		||||
                  </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
| 
						 | 
				
			
			@ -167,7 +169,8 @@ export default function GetOtherUsersReport(): JSX.Element {
 | 
			
		|||
                      type="text"
 | 
			
		||||
                      min="0"
 | 
			
		||||
                      className="border-2 border-black rounded-md text-center w-1/2"
 | 
			
		||||
                      value={testingTime === 0 ? "" : testingTime}
 | 
			
		||||
                      defaultValue={testingTime === 0 ? "" : testingTime}
 | 
			
		||||
                      readOnly
 | 
			
		||||
                    />
 | 
			
		||||
                  </td>
 | 
			
		||||
                </tr>
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue