Compare commits
	
		
			18 commits
		
	
	
		
			1a412dc8a0
			...
			5696310a68
		
	
	| Author | SHA1 | Date | |
|---|---|---|---|
| 
							 | 
						5696310a68 | ||
| 
							 | 
						40caa2d158 | ||
| 
							 | 
						37bbbb6098 | ||
| 
							 | 
						e03727613d | ||
| 
							 | 
						8a34fc07fa | ||
| 
							 | 
						b93df693d2 | ||
| 
							 | 
						447f2b73eb | ||
| 
							 | 
						3683552af8 | ||
| 
							 | 
						c7fe5e8775 | ||
| 
							 | 
						402b0ac08b | ||
| 
							 | 
						9240d5e052 | ||
| 
							 | 
						1977125923 | ||
| 
							 | 
						b999e47f94 | ||
| 
							 | 
						e7e79ced13 | ||
| 
							 | 
						141e5c8bb6 | ||
| 
							 | 
						b7fcafd75c | ||
| 
							 | 
						060dc1ee3d | ||
| 
							 | 
						79eb59ad46 | 
					 10 changed files with 228 additions and 39 deletions
				
			
		| 
						 | 
				
			
			@ -2,6 +2,7 @@ package database
 | 
			
		|||
 | 
			
		||||
import (
 | 
			
		||||
	"embed"
 | 
			
		||||
	"errors"
 | 
			
		||||
	"path/filepath"
 | 
			
		||||
	"ttime/internal/types"
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -30,6 +31,7 @@ type Database interface {
 | 
			
		|||
	GetProject(projectId int) (types.Project, error)
 | 
			
		||||
	GetUserRole(username string, projectname string) (string, error)
 | 
			
		||||
	GetWeeklyReport(username string, projectName string, week int) (types.WeeklyReport, error)
 | 
			
		||||
	SignWeeklyReport(reportId int, projectManagerId int) error
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// This struct is a wrapper type that holds the database connection
 | 
			
		||||
| 
						 | 
				
			
			@ -270,7 +272,8 @@ func (d *Db) GetWeeklyReport(username string, projectName string, week int) (typ
 | 
			
		|||
            admin_time,
 | 
			
		||||
            own_work_time,
 | 
			
		||||
            study_time,
 | 
			
		||||
            testing_time
 | 
			
		||||
            testing_time,
 | 
			
		||||
			signed_by
 | 
			
		||||
        FROM
 | 
			
		||||
            weekly_reports
 | 
			
		||||
        WHERE
 | 
			
		||||
| 
						 | 
				
			
			@ -282,6 +285,34 @@ func (d *Db) GetWeeklyReport(username string, projectName string, week int) (typ
 | 
			
		|||
	return report, err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// SignWeeklyReport signs a weekly report by updating the signed_by field
 | 
			
		||||
// with the provided project manager's ID, but only if the project manager
 | 
			
		||||
// is in the same project as the report
 | 
			
		||||
func (d *Db) SignWeeklyReport(reportId int, projectManagerId int) error {
 | 
			
		||||
	// Retrieve the project ID associated with the report
 | 
			
		||||
	var reportProjectID int
 | 
			
		||||
	err := d.Get(&reportProjectID, "SELECT project_id FROM weekly_reports WHERE report_id = ?", reportId)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Retrieve the project ID associated with the project manager
 | 
			
		||||
	var managerProjectID int
 | 
			
		||||
	err = d.Get(&managerProjectID, "SELECT project_id FROM user_roles WHERE user_id = ? AND p_role = 'project_manager'", projectManagerId)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		return err
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Check if the project manager is in the same project as the report
 | 
			
		||||
	if reportProjectID != managerProjectID {
 | 
			
		||||
		return errors.New("project manager doesn't have permission to sign the report")
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Update the signed_by field of the specified report
 | 
			
		||||
	_, err = d.Exec("UPDATE weekly_reports SET signed_by = ? WHERE report_id = ?", projectManagerId, reportId)
 | 
			
		||||
	return err
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Reads a directory of migration files and applies them to the database.
 | 
			
		||||
// This will eventually be used on an embedded directory
 | 
			
		||||
func (d *Db) Migrate() error {
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,6 +1,7 @@
 | 
			
		|||
package database
 | 
			
		||||
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"testing"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -410,3 +411,128 @@ func TestGetWeeklyReport(t *testing.T) {
 | 
			
		|||
	}
 | 
			
		||||
	// Check other fields similarly
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestSignWeeklyReport(t *testing.T) {
 | 
			
		||||
	db, err := setupState()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error("setupState failed:", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Add project manager
 | 
			
		||||
	err = db.AddUser("projectManager", "password")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error("AddUser failed:", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Add a regular user
 | 
			
		||||
	err = db.AddUser("testuser", "password")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error("AddUser failed:", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Add project
 | 
			
		||||
	err = db.AddProject("testproject", "description", "projectManager")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error("AddProject failed:", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Add both regular users as members to the project
 | 
			
		||||
	err = db.AddUserToProject("testuser", "testproject", "member")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error("AddUserToProject failed:", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = db.AddUserToProject("projectManager", "testproject", "project_manager")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error("AddUserToProject failed:", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Add a weekly report for one of the regular users
 | 
			
		||||
	err = db.AddWeeklyReport("testproject", "testuser", 1, 1, 1, 1, 1, 1, 1)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error("AddWeeklyReport failed:", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Retrieve the added report
 | 
			
		||||
	report, err := db.GetWeeklyReport("testuser", "testproject", 1)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error("GetWeeklyReport failed:", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Print project manager's ID
 | 
			
		||||
	projectManagerID, err := db.GetUserId("projectManager")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error("GetUserId failed:", err)
 | 
			
		||||
	}
 | 
			
		||||
	fmt.Println("Project Manager's ID:", projectManagerID)
 | 
			
		||||
 | 
			
		||||
	// Sign the report with the project manager
 | 
			
		||||
	err = db.SignWeeklyReport(report.ReportId, projectManagerID)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error("SignWeeklyReport failed:", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Retrieve the report again to check if it's signed
 | 
			
		||||
	signedReport, err := db.GetWeeklyReport("testuser", "testproject", 1)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error("GetWeeklyReport failed:", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Ensure the report is signed by the project manager
 | 
			
		||||
	if *signedReport.SignedBy != projectManagerID {
 | 
			
		||||
		t.Errorf("Expected SignedBy to be %d, got %d", projectManagerID, *signedReport.SignedBy)
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func TestSignWeeklyReportByAnotherProjectManager(t *testing.T) {
 | 
			
		||||
	db, err := setupState()
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error("setupState failed:", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Add project manager
 | 
			
		||||
	err = db.AddUser("projectManager", "password")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error("AddUser failed:", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Add a regular user
 | 
			
		||||
	err = db.AddUser("testuser", "password")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error("AddUser failed:", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Add project
 | 
			
		||||
	err = db.AddProject("testproject", "description", "projectManager")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error("AddProject failed:", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Add the regular user as a member to the project
 | 
			
		||||
	err = db.AddUserToProject("testuser", "testproject", "member")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error("AddUserToProject failed:", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Add a weekly report for the regular user
 | 
			
		||||
	err = db.AddWeeklyReport("testproject", "testuser", 1, 1, 1, 1, 1, 1, 1)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error("AddWeeklyReport failed:", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// Retrieve the added report
 | 
			
		||||
	report, err := db.GetWeeklyReport("testuser", "testproject", 1)
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error("GetWeeklyReport failed:", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	anotherManagerID, err := db.GetUserId("projectManager")
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		t.Error("GetUserId failed:", err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	err = db.SignWeeklyReport(report.ReportId, anotherManagerID)
 | 
			
		||||
	if err == nil {
 | 
			
		||||
		t.Error("Expected SignWeeklyReport to fail with a project manager who is not in the project, but it didn't")
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,4 +1,4 @@
 | 
			
		|||
CREATE TABLE weekly_reports (
 | 
			
		||||
CREATE TABLE IF NOT EXISTS weekly_reports (
 | 
			
		||||
  report_id INTEGER PRIMARY KEY AUTOINCREMENT,
 | 
			
		||||
  user_id INTEGER NOT NULL,
 | 
			
		||||
  project_id INTEGER NOT NULL,
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -22,13 +22,16 @@ import (
 | 
			
		|||
func (gs *GState) Register(c *fiber.Ctx) error {
 | 
			
		||||
	u := new(types.NewUser)
 | 
			
		||||
	if err := c.BodyParser(u); err != nil {
 | 
			
		||||
		println("Error parsing body")
 | 
			
		||||
		return c.Status(400).SendString(err.Error())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	println("Adding user:", u.Username)
 | 
			
		||||
	if err := gs.Db.AddUser(u.Username, u.Password); err != nil {
 | 
			
		||||
		return c.Status(500).SendString(err.Error())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	println("User added:", u.Username)
 | 
			
		||||
	return c.Status(200).SendString("User added")
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -57,9 +60,11 @@ func (gs *GState) Login(c *fiber.Ctx) error {
 | 
			
		|||
	// The body type is identical to a NewUser
 | 
			
		||||
	u := new(types.NewUser)
 | 
			
		||||
	if err := c.BodyParser(u); err != nil {
 | 
			
		||||
		println("Error parsing body")
 | 
			
		||||
		return c.Status(400).SendString(err.Error())
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	println("Username:", u.Username)
 | 
			
		||||
	if !gs.Db.CheckUser(u.Username, u.Password) {
 | 
			
		||||
		println("User not found")
 | 
			
		||||
		return c.SendStatus(fiber.StatusUnauthorized)
 | 
			
		||||
| 
						 | 
				
			
			@ -74,13 +79,16 @@ func (gs *GState) Login(c *fiber.Ctx) error {
 | 
			
		|||
 | 
			
		||||
	// Create token
 | 
			
		||||
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, claims)
 | 
			
		||||
	println("Token created for user:", u.Username)
 | 
			
		||||
 | 
			
		||||
	// Generate encoded token and send it as response.
 | 
			
		||||
	t, err := token.SignedString([]byte("secret"))
 | 
			
		||||
	if err != nil {
 | 
			
		||||
		println("Error signing token")
 | 
			
		||||
		return c.SendStatus(fiber.StatusInternalServerError)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	println("Successfully signed token for user:", u.Username)
 | 
			
		||||
	return c.JSON(fiber.Map{"token": t})
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -41,4 +41,6 @@ type WeeklyReport struct {
 | 
			
		|||
	StudyTime int `json:"studyTime" db:"study_time"`
 | 
			
		||||
	// Total time spent on testing
 | 
			
		||||
	TestingTime int `json:"testingTime" db:"testing_time"`
 | 
			
		||||
	// The project manager who signed it
 | 
			
		||||
	SignedBy *int `json:"signedBy" db:"signed_by"`
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -8,9 +8,8 @@ describe("API", () => {
 | 
			
		|||
      username: "lol", // Add the username property
 | 
			
		||||
      password: "lol",
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    const response = await api.registerUser(user);
 | 
			
		||||
 | 
			
		||||
    console.log(response.message);
 | 
			
		||||
    expect(response.success).toBe(true);
 | 
			
		||||
    expect(response.data).toHaveProperty("userId");
 | 
			
		||||
  });
 | 
			
		||||
| 
						 | 
				
			
			@ -24,7 +23,7 @@ describe("API", () => {
 | 
			
		|||
      "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZG1pbiI6ZmFsc2UsImV4cCI6MTcxMDk0MDIwMywibmFtZSI6InJyZ3VtZHpwbWMifQ.V9NHoYMYV61t";
 | 
			
		||||
 | 
			
		||||
    const response = await api.createProject(project, token);
 | 
			
		||||
 | 
			
		||||
    console.log(response.message);
 | 
			
		||||
    expect(response.success).toBe(true);
 | 
			
		||||
    expect(response.data).toHaveProperty("projectId");
 | 
			
		||||
  });
 | 
			
		||||
| 
						 | 
				
			
			@ -34,7 +33,7 @@ describe("API", () => {
 | 
			
		|||
      "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZG1pbiI6ZmFsc2UsImV4cCI6MTcxMDk0MDIwMywibmFtZSI6InJyZ3VtZHpwbWMifQ.V9NHoYMYV61t";
 | 
			
		||||
 | 
			
		||||
    const response = await api.renewToken(refreshToken);
 | 
			
		||||
 | 
			
		||||
    console.log(response.message);
 | 
			
		||||
    expect(response.success).toBe(true);
 | 
			
		||||
    expect(response.data).toHaveProperty("accessToken");
 | 
			
		||||
    expect(response.data).toHaveProperty("refreshToken");
 | 
			
		||||
| 
						 | 
				
			
			@ -45,7 +44,7 @@ describe("API", () => {
 | 
			
		|||
      "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZG1pbiI6ZmFsc2UsImV4cCI6MTcxMDk0MDIwMywibmFtZSI6InJyZ3VtZHpwbWMifQ.V9NHoYMYV61t";
 | 
			
		||||
    const username = "rrgumdzpmc";
 | 
			
		||||
    const response = await api.getUserProjects(username, token);
 | 
			
		||||
 | 
			
		||||
    console.log(response.message);
 | 
			
		||||
    expect(response.success).toBe(true);
 | 
			
		||||
    expect(response.data).toHaveProperty("projects");
 | 
			
		||||
  });
 | 
			
		||||
| 
						 | 
				
			
			@ -65,7 +64,7 @@ describe("API", () => {
 | 
			
		|||
      "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhZG1pbiI6ZmFsc2UsImV4cCI6MTcxMDk0MDIwMywibmFtZSI6InJyZ3VtZHpwbWMifQ.V9NHoYMYV61t";
 | 
			
		||||
 | 
			
		||||
    const response = await api.submitWeeklyReport(report, token);
 | 
			
		||||
 | 
			
		||||
    console.log(response.message);
 | 
			
		||||
    expect(response.success).toBe(true);
 | 
			
		||||
    expect(response.data).toHaveProperty(
 | 
			
		||||
      "message",
 | 
			
		||||
| 
						 | 
				
			
			@ -80,7 +79,7 @@ describe("API", () => {
 | 
			
		|||
    };
 | 
			
		||||
 | 
			
		||||
    const response = await api.login(user);
 | 
			
		||||
 | 
			
		||||
    console.log(response.message);
 | 
			
		||||
    expect(response.success).toBe(true);
 | 
			
		||||
    expect(response.data).toHaveProperty("accessToken");
 | 
			
		||||
    expect(response.data).toHaveProperty("refreshToken");
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -7,7 +7,7 @@ import {
 | 
			
		|||
} from "../Types/goTypes";
 | 
			
		||||
 | 
			
		||||
// This type of pattern should be hard to misuse
 | 
			
		||||
interface APIResponse<T> {
 | 
			
		||||
export interface APIResponse<T> {
 | 
			
		||||
  success: boolean;
 | 
			
		||||
  message?: string;
 | 
			
		||||
  data?: T;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,34 +1,54 @@
 | 
			
		|||
import { NewUser } from "../Types/goTypes";
 | 
			
		||||
import { api, APIResponse } from "../API/API";
 | 
			
		||||
import { Dispatch, SetStateAction } from "react";
 | 
			
		||||
 | 
			
		||||
function LoginCheck(props: { username: string; password: string }): number {
 | 
			
		||||
  //Example users for testing without backend, remove when using backend
 | 
			
		||||
  const admin: NewUser = {
 | 
			
		||||
    username: "admin",
 | 
			
		||||
    password: "123",
 | 
			
		||||
  };
 | 
			
		||||
  const pmanager: NewUser = {
 | 
			
		||||
    username: "pmanager",
 | 
			
		||||
    password: "123",
 | 
			
		||||
  };
 | 
			
		||||
/*
 | 
			
		||||
 * Checks if user is in database with api.login and then sets proper authority level
 | 
			
		||||
 * TODO: change so that it checks for user type (admin, user, pm) somehow instead
 | 
			
		||||
 **/
 | 
			
		||||
function LoginCheck(props: {
 | 
			
		||||
  username: string;
 | 
			
		||||
  password: string;
 | 
			
		||||
  setAuthority: Dispatch<SetStateAction<number>>;
 | 
			
		||||
}): number {
 | 
			
		||||
  const user: NewUser = {
 | 
			
		||||
    username: "user",
 | 
			
		||||
    password: "123",
 | 
			
		||||
    username: props.username,
 | 
			
		||||
    password: props.password,
 | 
			
		||||
  };
 | 
			
		||||
 | 
			
		||||
  //TODO: Compare with db instead when finished
 | 
			
		||||
  if (props.username === admin.username && props.password === admin.password) {
 | 
			
		||||
    return 1;
 | 
			
		||||
  } else if (
 | 
			
		||||
    props.username === pmanager.username &&
 | 
			
		||||
    props.password === pmanager.password
 | 
			
		||||
  ) {
 | 
			
		||||
    return 2;
 | 
			
		||||
  } else if (
 | 
			
		||||
    props.username === user.username &&
 | 
			
		||||
    props.password === user.password
 | 
			
		||||
  ) {
 | 
			
		||||
    return 3;
 | 
			
		||||
  api
 | 
			
		||||
    .login(user)
 | 
			
		||||
    .then((response: APIResponse<string>) => {
 | 
			
		||||
      if (response.success) {
 | 
			
		||||
        if (response.data !== undefined) {
 | 
			
		||||
          const token = response.data;
 | 
			
		||||
          //TODO: change so that it checks for user type (admin, user, pm) instead
 | 
			
		||||
          if (token !== "" && props.username === "admin") {
 | 
			
		||||
            props.setAuthority((prevAuth) => {
 | 
			
		||||
              prevAuth = 1;
 | 
			
		||||
              return prevAuth;
 | 
			
		||||
            });
 | 
			
		||||
          } else if (token !== "" && props.username === "pm") {
 | 
			
		||||
            props.setAuthority((prevAuth) => {
 | 
			
		||||
              prevAuth = 2;
 | 
			
		||||
              return prevAuth;
 | 
			
		||||
            });
 | 
			
		||||
          } else if (token !== "" && props.username === "user") {
 | 
			
		||||
            props.setAuthority((prevAuth) => {
 | 
			
		||||
              prevAuth = 3;
 | 
			
		||||
              return prevAuth;
 | 
			
		||||
            });
 | 
			
		||||
          }
 | 
			
		||||
        } else {
 | 
			
		||||
          console.error("Token was undefined");
 | 
			
		||||
        }
 | 
			
		||||
      } else {
 | 
			
		||||
        console.error("Token could not be fetched");
 | 
			
		||||
      }
 | 
			
		||||
    })
 | 
			
		||||
    .catch((error) => {
 | 
			
		||||
      console.error("An error occurred during login:", error);
 | 
			
		||||
    });
 | 
			
		||||
 | 
			
		||||
  return 0;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -15,9 +15,10 @@ function LoginPage(props: {
 | 
			
		|||
   and if so, redirect to correct page */
 | 
			
		||||
  function handleSubmit(event: FormEvent<HTMLFormElement>): void {
 | 
			
		||||
    event.preventDefault();
 | 
			
		||||
    props.setAuthority((prevAuth) => {
 | 
			
		||||
      prevAuth = LoginCheck({ username: username, password: password });
 | 
			
		||||
      return prevAuth;
 | 
			
		||||
    LoginCheck({
 | 
			
		||||
      username: username,
 | 
			
		||||
      password: password,
 | 
			
		||||
      setAuthority: props.setAuthority,
 | 
			
		||||
    });
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,6 +14,7 @@ function PMProjectMembers(): JSX.Element {
 | 
			
		|||
          onClick={(): void => {
 | 
			
		||||
            return;
 | 
			
		||||
          }}
 | 
			
		||||
          type={"button"}
 | 
			
		||||
        />
 | 
			
		||||
      </Link>
 | 
			
		||||
      <Link to="/PM-time-role">
 | 
			
		||||
| 
						 | 
				
			
			@ -22,6 +23,7 @@ function PMProjectMembers(): JSX.Element {
 | 
			
		|||
          onClick={(): void => {
 | 
			
		||||
            return;
 | 
			
		||||
          }}
 | 
			
		||||
          type={"button"}
 | 
			
		||||
        />
 | 
			
		||||
      </Link>
 | 
			
		||||
      <BackButton />
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue