From ef6bf914c987419815edcd02ad0cb25603a6381b Mon Sep 17 00:00:00 2001 From: usserwoutV2 Date: Mon, 26 Feb 2024 12:11:44 +0100 Subject: [PATCH 01/40] Changed tenant-id to UGent id --- frontend/src/auth/AuthConfig.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/frontend/src/auth/AuthConfig.ts b/frontend/src/auth/AuthConfig.ts index 0c1368ff..9ee22102 100644 --- a/frontend/src/auth/AuthConfig.ts +++ b/frontend/src/auth/AuthConfig.ts @@ -5,7 +5,7 @@ export const msalConfig: Configuration = { auth: { clientId: "39136cda-f02f-4305-9b08-45f132bab07e", //For UGent auth: "https://login.microsoftonline.com/d7811cde-ecef-496c-8f91-a1786241b99c", - authority: "https://login.microsoftonline.com/62835335-e5c4-4d22-98f2-9d5b65a06d9d", + authority: "https://login.microsoftonline.com/d7811cde-ecef-496c-8f91-a1786241b99c", // "https://login.microsoftonline.com/62835335-e5c4-4d22-98f2-9d5b65a06d9d", redirectUri: "/dashboard", postLogoutRedirectUri: "/" }, From 7fa68720561047781638bc01e68b98ff305f9db8 Mon Sep 17 00:00:00 2001 From: usserwoutV2 Date: Mon, 26 Feb 2024 12:18:28 +0100 Subject: [PATCH 02/40] Updated tenant-id --- backend/app/src/main/resources/application.properties | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/backend/app/src/main/resources/application.properties b/backend/app/src/main/resources/application.properties index 864e1028..4d7742de 100644 --- a/backend/app/src/main/resources/application.properties +++ b/backend/app/src/main/resources/application.properties @@ -6,7 +6,8 @@ azure.activedirectory.client-id=39136cda-f02f-4305-9b08-45f132bab07e azure.activedirectory.b2c.client-secret=i1n8Q~57EDI.E2iLxzkW3Q.ixEtVIM4jwN7eDbxK # For UGent auth: d7811cde-ecef-496c-8f91-a1786241b99c -azure.activedirectory.tenant-id=62835335-e5c4-4d22-98f2-9d5b65a06d9d +# Test auth: 62835335-e5c4-4d22-98f2-9d5b65a06d9d +azure.activedirectory.tenant-id=d7811cde-ecef-496c-8f91-a1786241b99c #spring.security.oauth2.client.registration.azure.client-id=39136cda-f02f-4305-9b08-45f132bab07e #spring.security.oauth2.client.registration.azure.client-secret=i1n8Q~57EDI.E2iLxzkW3Q.ixEtVIM4jwN7eDbxK From 3eb5433d52bf09cf80ff422f294a99e6d360b1ef Mon Sep 17 00:00:00 2001 From: usserwoutV2 Date: Wed, 28 Feb 2024 13:33:39 +0100 Subject: [PATCH 03/40] Fixed auth only showing login window --- backend/app/Dockerfile | 2 +- .../config/AuthConfig.java | 7 ++++-- .../config/JwtAuthenticationFilter.java | 22 ++++++++++++------- .../config/OAuth2ClientConfig.java | 2 +- .../{selab2 => pidgeon}/config/WebConfig.java | 2 +- .../controllers/AuthTestController.java | 8 +++---- .../ugent/{selab2 => pidgeon}/model/Auth.java | 2 +- .../java/com/ugent/pidgeon/model/User.java | 22 +++++++++++++++++++ .../java/com/ugent/selab2/model/User.java | 18 --------------- .../main/resources/application-azuread.yml | 19 ---------------- frontend/src/App.tsx | 14 +----------- frontend/src/auth/MsGraphApiCall.ts | 2 ++ frontend/src/pages/profile/Profile.tsx | 21 ++++++++++++------ .../pages/profile/components/ProfileData.tsx | 2 ++ frontend/src/setupTests.ts | 5 ----- frontend/tsconfig.json | 2 +- 16 files changed, 69 insertions(+), 81 deletions(-) rename backend/app/src/main/java/com/ugent/{selab2 => pidgeon}/config/AuthConfig.java (83%) rename backend/app/src/main/java/com/ugent/{selab2 => pidgeon}/config/JwtAuthenticationFilter.java (83%) rename backend/app/src/main/java/com/ugent/{selab2 => pidgeon}/config/OAuth2ClientConfig.java (97%) rename backend/app/src/main/java/com/ugent/{selab2 => pidgeon}/config/WebConfig.java (93%) rename backend/app/src/main/java/com/ugent/{selab2 => pidgeon}/controllers/AuthTestController.java (77%) rename backend/app/src/main/java/com/ugent/{selab2 => pidgeon}/model/Auth.java (98%) create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/model/User.java delete mode 100644 backend/app/src/main/java/com/ugent/selab2/model/User.java delete mode 100644 backend/app/src/main/resources/application-azuread.yml delete mode 100644 frontend/src/setupTests.ts diff --git a/backend/app/Dockerfile b/backend/app/Dockerfile index 976b713b..7b6af4da 100644 --- a/backend/app/Dockerfile +++ b/backend/app/Dockerfile @@ -1,4 +1,4 @@ -FROM eclipse-temurin:17-jdk-alpine +FROM eclipse-temurin:17-alpine VOLUME /tmp COPY build/libs/*T.jar app.jar ENTRYPOINT ["java","-jar","/app.jar"] diff --git a/backend/app/src/main/java/com/ugent/selab2/config/AuthConfig.java b/backend/app/src/main/java/com/ugent/pidgeon/config/AuthConfig.java similarity index 83% rename from backend/app/src/main/java/com/ugent/selab2/config/AuthConfig.java rename to backend/app/src/main/java/com/ugent/pidgeon/config/AuthConfig.java index 973801cc..f0cdbef8 100644 --- a/backend/app/src/main/java/com/ugent/selab2/config/AuthConfig.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/config/AuthConfig.java @@ -1,13 +1,15 @@ -package com.ugent.selab2.config; +package com.ugent.pidgeon.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.boot.web.servlet.FilterRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; +import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; import org.springframework.security.web.SecurityFilterChain; @Configuration +@EnableWebSecurity public class AuthConfig { @Value("${azure.activedirectory.tenant-id}") @@ -16,6 +18,7 @@ public class AuthConfig { @Bean public FilterRegistrationBean filterRegistrationBean() { System.out.println("tenantId: " + tenantId); + FilterRegistrationBean filter = new FilterRegistrationBean<>(); filter.setFilter(new JwtAuthenticationFilter(tenantId)); filter.addUrlPatterns("/api/*"); @@ -23,7 +26,7 @@ public FilterRegistrationBean filterRegistrationBean() } @Bean - SecurityFilterChain web(HttpSecurity http) throws Exception { + public SecurityFilterChain web(HttpSecurity http) throws Exception { http .authorizeHttpRequests((authorize) -> authorize .anyRequest().permitAll() diff --git a/backend/app/src/main/java/com/ugent/selab2/config/JwtAuthenticationFilter.java b/backend/app/src/main/java/com/ugent/pidgeon/config/JwtAuthenticationFilter.java similarity index 83% rename from backend/app/src/main/java/com/ugent/selab2/config/JwtAuthenticationFilter.java rename to backend/app/src/main/java/com/ugent/pidgeon/config/JwtAuthenticationFilter.java index 04d0ded0..598d7897 100644 --- a/backend/app/src/main/java/com/ugent/selab2/config/JwtAuthenticationFilter.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/config/JwtAuthenticationFilter.java @@ -1,4 +1,4 @@ -package com.ugent.selab2.config; +package com.ugent.pidgeon.config; import com.auth0.jwk.Jwk; import com.auth0.jwk.JwkException; @@ -8,8 +8,8 @@ import com.auth0.jwt.algorithms.Algorithm; import com.auth0.jwt.exceptions.SignatureVerificationException; import com.auth0.jwt.interfaces.DecodedJWT; -import com.ugent.selab2.model.Auth; -import com.ugent.selab2.model.User; +import com.ugent.pidgeon.model.Auth; +import com.ugent.pidgeon.model.User; import org.springframework.http.HttpStatus; import org.springframework.security.core.context.SecurityContextHolder; import org.springframework.util.StringUtils; @@ -30,6 +30,7 @@ public class JwtAuthenticationFilter extends OncePerRequestFilter { public JwtAuthenticationFilter(String tenantId) { try { + logger.info("tenantId: " + tenantId); provider = new UrlJwkProvider(new URL("https://login.microsoftonline.com/"+tenantId+"/discovery/v2.0/keys")); } catch (MalformedURLException e) { e.printStackTrace(); @@ -55,11 +56,18 @@ protected void doFilterInternal(jakarta.servlet.http.HttpServletRequest request, algorithm.verify(jwt);// if the token signature is invalid, the method will throw SignatureVerificationException // get the data from the token - String name = jwt.getClaim("name").asString(); - String email = jwt.getClaim("email").asString(); + String displayName = jwt.getClaim("name").asString(); + String firstName = jwt.getClaim("given_name").asString(); + String lastName = jwt.getClaim("family_name").asString(); + String email = jwt.getClaim("unique_name").asString(); List groups = jwt.getClaim("groups").asList(String.class); String oid = jwt.getClaim("oid").asString(); - User user = new User(name, email, groups, oid); + + // print full object + //logger.info(jwt.getClaims()); + + + User user = new User(displayName,firstName,lastName, email, groups, oid); Auth authUser = new Auth(user, new ArrayList<>()); SecurityContextHolder.getContext().setAuthentication(authUser); @@ -73,8 +81,6 @@ protected void doFilterInternal(jakarta.servlet.http.HttpServletRequest request, response.setStatus(HttpStatus.UNAUTHORIZED.value()); // Forbidden } - logger.info("Token: " + token); - } else { logger.warn("No token found!"); response.setStatus(HttpStatus.UNAUTHORIZED.value()); // Unauthorized diff --git a/backend/app/src/main/java/com/ugent/selab2/config/OAuth2ClientConfig.java b/backend/app/src/main/java/com/ugent/pidgeon/config/OAuth2ClientConfig.java similarity index 97% rename from backend/app/src/main/java/com/ugent/selab2/config/OAuth2ClientConfig.java rename to backend/app/src/main/java/com/ugent/pidgeon/config/OAuth2ClientConfig.java index ea7c1212..863c56ab 100644 --- a/backend/app/src/main/java/com/ugent/selab2/config/OAuth2ClientConfig.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/config/OAuth2ClientConfig.java @@ -1,4 +1,4 @@ -package com.ugent.selab2.config; +package com.ugent.pidgeon.config; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; diff --git a/backend/app/src/main/java/com/ugent/selab2/config/WebConfig.java b/backend/app/src/main/java/com/ugent/pidgeon/config/WebConfig.java similarity index 93% rename from backend/app/src/main/java/com/ugent/selab2/config/WebConfig.java rename to backend/app/src/main/java/com/ugent/pidgeon/config/WebConfig.java index d56ad9c3..8b94ced5 100644 --- a/backend/app/src/main/java/com/ugent/selab2/config/WebConfig.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/config/WebConfig.java @@ -1,4 +1,4 @@ -package com.ugent.selab2.config; +package com.ugent.pidgeon.config; import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; diff --git a/backend/app/src/main/java/com/ugent/selab2/controllers/AuthTestController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/AuthTestController.java similarity index 77% rename from backend/app/src/main/java/com/ugent/selab2/controllers/AuthTestController.java rename to backend/app/src/main/java/com/ugent/pidgeon/controllers/AuthTestController.java index 50c05834..1ca65bc2 100644 --- a/backend/app/src/main/java/com/ugent/selab2/controllers/AuthTestController.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/controllers/AuthTestController.java @@ -1,6 +1,6 @@ -package com.ugent.selab2.controllers; -import com.ugent.selab2.model.Auth; -import com.ugent.selab2.model.User; +package com.ugent.pidgeon.controllers; +import com.ugent.pidgeon.model.Auth; +import com.ugent.pidgeon.model.User; import jakarta.servlet.http.HttpServletRequest; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @@ -21,7 +21,7 @@ public String ping() { @GetMapping("/") public String index() { - return "Running..."; + return "Running!!!..."; } } diff --git a/backend/app/src/main/java/com/ugent/selab2/model/Auth.java b/backend/app/src/main/java/com/ugent/pidgeon/model/Auth.java similarity index 98% rename from backend/app/src/main/java/com/ugent/selab2/model/Auth.java rename to backend/app/src/main/java/com/ugent/pidgeon/model/Auth.java index 944aca14..9e286d90 100644 --- a/backend/app/src/main/java/com/ugent/selab2/model/Auth.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/model/Auth.java @@ -1,4 +1,4 @@ -package com.ugent.selab2.model; +package com.ugent.pidgeon.model; import org.springframework.security.authentication.AbstractAuthenticationToken; import org.springframework.security.core.GrantedAuthority; diff --git a/backend/app/src/main/java/com/ugent/pidgeon/model/User.java b/backend/app/src/main/java/com/ugent/pidgeon/model/User.java new file mode 100644 index 00000000..d3c78a02 --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/model/User.java @@ -0,0 +1,22 @@ +package com.ugent.pidgeon.model; + +import java.util.List; + +public class User { + + public String name; + public String firstName; + public String lastName; + public String email; + public List groups; + public String oid; + + public User (String name, String firstName, String lastName, String email, List groups, String oid) { + this.name = name; + this.email = email; + this.groups = groups; + this.oid = oid; + this.firstName = firstName; + this.lastName = lastName; + } +} diff --git a/backend/app/src/main/java/com/ugent/selab2/model/User.java b/backend/app/src/main/java/com/ugent/selab2/model/User.java deleted file mode 100644 index 599db7f9..00000000 --- a/backend/app/src/main/java/com/ugent/selab2/model/User.java +++ /dev/null @@ -1,18 +0,0 @@ -package com.ugent.selab2.model; - -import java.util.List; - -public class User { - - public String name; - public String email; - public List groups; - public String oid; - - public User (String name, String email, List groups, String oid) { - this.name = name; - this.email = email; - this.groups = groups; - this.oid = oid; - } -} diff --git a/backend/app/src/main/resources/application-azuread.yml b/backend/app/src/main/resources/application-azuread.yml deleted file mode 100644 index 1a929321..00000000 --- a/backend/app/src/main/resources/application-azuread.yml +++ /dev/null @@ -1,19 +0,0 @@ -spring: - security: - oauth2: - client: - provider: - azure: - issuer-uri: https://login.microsoftonline.com/62835335-e5c4-4d22-98f2-9d5b65a06d9d/v2.0 - user-name-attribute: name - registration: - azure: - provider: azure - #client-id: "6035bfd4-22f0-437c-b76f-da729a916cbf" - #client-secret: "fo28Q~-aLbmQvonnZtzbgtSiqYstmBWEmGPAodmx" - client-id: 39136cda-f02f-4305-9b08-45f132bab07e - client-secret: i1n8Q~57EDI.E2iLxzkW3Q.ixEtVIM4jwN7eDbxK - scope: - - openid - - email - - profile \ No newline at end of file diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 8b172683..badc8bb6 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -16,22 +16,10 @@ function App({ pca }: AppProps) { const navigationClient = new CustomNavigation(navigate); pca.setNavigationClient(navigationClient); - // const handleLogin = async () => { - // try { - // // await promise; - // // await msalInstance.loginPopup(); // Initiate popup login - // // const account: AccountInfo | null = msalInstance.getActiveAccount(); - // // console.log(account); - // } catch (error) { - // console.error(error) - // } - // } return (
-
- {/* */} - +
diff --git a/frontend/src/auth/MsGraphApiCall.ts b/frontend/src/auth/MsGraphApiCall.ts index ee6e64ad..6e7ca923 100644 --- a/frontend/src/auth/MsGraphApiCall.ts +++ b/frontend/src/auth/MsGraphApiCall.ts @@ -7,6 +7,8 @@ export async function callMsGraph() { throw Error("No active account! Verify a user has been signed in and setActiveAccount has been called."); } + console.log(account); + const response = await msalInstance.acquireTokenSilent({ ...loginRequest, account: account diff --git a/frontend/src/pages/profile/Profile.tsx b/frontend/src/pages/profile/Profile.tsx index efc3271e..a2c03d87 100644 --- a/frontend/src/pages/profile/Profile.tsx +++ b/frontend/src/pages/profile/Profile.tsx @@ -24,15 +24,20 @@ const ProfileContent = () => { if (!graphData && inProgress === InteractionStatus.None) { callMsGraph().then(response => setGraphData(response)).catch((e) => { if (e instanceof InteractionRequiredAuthError) { - instance.acquireTokenRedirect({ - ...loginRequest, - account: instance.getActiveAccount() as AccountInfo - }); + + // instance.acquireTokenRedirect({ + // ...loginRequest, + // account: instance.getActiveAccount() as AccountInfo + // }); } - }); + }).catch(err => { + console.log(err); + }) ; } }, [inProgress, graphData, instance]); - + + + console.log(graphData); return (
{ graphData ? : null } @@ -41,10 +46,12 @@ const ProfileContent = () => { }; export function Profile() { + + + const authRequest = { ...loginRequest }; - return ( = ({ graphData }) = }) } + + return (
  • diff --git a/frontend/src/setupTests.ts b/frontend/src/setupTests.ts deleted file mode 100644 index 8f2609b7..00000000 --- a/frontend/src/setupTests.ts +++ /dev/null @@ -1,5 +0,0 @@ -// jest-dom adds custom jest matchers for asserting on DOM nodes. -// allows you to do things like: -// expect(element).toHaveTextContent(/react/i) -// learn more: https://github.com/testing-library/jest-dom -import '@testing-library/jest-dom'; diff --git a/frontend/tsconfig.json b/frontend/tsconfig.json index 2eec864a..6dcaa194 100644 --- a/frontend/tsconfig.json +++ b/frontend/tsconfig.json @@ -23,5 +23,5 @@ "include": [ "src", "test/App.test.tsx" - ] +, "test/setupTests.ts" ] } \ No newline at end of file From ac7f3fe3992a786524567ba3e8c01c3e8a1613c0 Mon Sep 17 00:00:00 2001 From: usserwoutV2 Date: Wed, 28 Feb 2024 13:34:48 +0100 Subject: [PATCH 04/40] Added test setup to /tests --- frontend/test/setupTests.ts | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 frontend/test/setupTests.ts diff --git a/frontend/test/setupTests.ts b/frontend/test/setupTests.ts new file mode 100644 index 00000000..8f2609b7 --- /dev/null +++ b/frontend/test/setupTests.ts @@ -0,0 +1,5 @@ +// jest-dom adds custom jest matchers for asserting on DOM nodes. +// allows you to do things like: +// expect(element).toHaveTextContent(/react/i) +// learn more: https://github.com/testing-library/jest-dom +import '@testing-library/jest-dom'; From 09f4fab36899922e3ac856b6744abc02a301abc8 Mon Sep 17 00:00:00 2001 From: Aqua-sc <108478185+Aqua-sc@users.noreply.github.com> Date: Wed, 28 Feb 2024 14:09:39 +0100 Subject: [PATCH 05/40] added jpa dependency --- backend/app/build.gradle | 1 + backend/db/password.txt | 0 2 files changed, 1 insertion(+) create mode 100644 backend/db/password.txt diff --git a/backend/app/build.gradle b/backend/app/build.gradle index 700530b7..9d467b8c 100644 --- a/backend/app/build.gradle +++ b/backend/app/build.gradle @@ -33,6 +33,7 @@ dependencies { implementation 'com.auth0:java-jwt:3.18.2' implementation 'com.auth0:jwks-rsa:0.18.0' implementation 'javax.servlet:javax.servlet-api:4.0.1' + implementation 'org.springframework.boot:spring-boot-starter-data-jpa' testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.security:spring-security-test' diff --git a/backend/db/password.txt b/backend/db/password.txt new file mode 100644 index 00000000..e69de29b From 213ab9b58f1e5f11403b799f2f9e2bc057b13243 Mon Sep 17 00:00:00 2001 From: Arthur Werbrouck Date: Wed, 28 Feb 2024 17:57:13 +0100 Subject: [PATCH 06/40] automatic build support --- backend/app/Dockerfile | 17 +++++++++++++---- .../{selab2 => pidgeon}/config/AuthConfig.java | 0 .../config/JwtAuthenticationFilter.java | 0 .../config/OAuth2ClientConfig.java | 0 .../{selab2 => pidgeon}/config/WebConfig.java | 0 .../controllers/AuthTestController.java | 0 .../ugent/{selab2 => pidgeon}/model/Auth.java | 0 .../ugent/{selab2 => pidgeon}/model/User.java | 0 docker-compose.yaml | 1 + 9 files changed, 14 insertions(+), 4 deletions(-) rename backend/app/src/main/java/com/ugent/{selab2 => pidgeon}/config/AuthConfig.java (100%) rename backend/app/src/main/java/com/ugent/{selab2 => pidgeon}/config/JwtAuthenticationFilter.java (100%) rename backend/app/src/main/java/com/ugent/{selab2 => pidgeon}/config/OAuth2ClientConfig.java (100%) rename backend/app/src/main/java/com/ugent/{selab2 => pidgeon}/config/WebConfig.java (100%) rename backend/app/src/main/java/com/ugent/{selab2 => pidgeon}/controllers/AuthTestController.java (100%) rename backend/app/src/main/java/com/ugent/{selab2 => pidgeon}/model/Auth.java (100%) rename backend/app/src/main/java/com/ugent/{selab2 => pidgeon}/model/User.java (100%) diff --git a/backend/app/Dockerfile b/backend/app/Dockerfile index 976b713b..0ad25ced 100644 --- a/backend/app/Dockerfile +++ b/backend/app/Dockerfile @@ -1,4 +1,13 @@ -FROM eclipse-temurin:17-jdk-alpine -VOLUME /tmp -COPY build/libs/*T.jar app.jar -ENTRYPOINT ["java","-jar","/app.jar"] +FROM gradle:jdk17 AS build +COPY --chown=gradle:gradle . /home/gradle/src +WORKDIR /home/gradle/src +RUN gradle build --no-daemon + +FROM eclipse-temurin:17 + +EXPOSE 8080 + +RUN mkdir /app + +COPY --from=build /home/gradle/src/build/libs/*.jar /app/spring-boot-application.jar +ENTRYPOINT ["java", "-jar","/app/spring-boot-application.jar"] \ No newline at end of file diff --git a/backend/app/src/main/java/com/ugent/selab2/config/AuthConfig.java b/backend/app/src/main/java/com/ugent/pidgeon/config/AuthConfig.java similarity index 100% rename from backend/app/src/main/java/com/ugent/selab2/config/AuthConfig.java rename to backend/app/src/main/java/com/ugent/pidgeon/config/AuthConfig.java diff --git a/backend/app/src/main/java/com/ugent/selab2/config/JwtAuthenticationFilter.java b/backend/app/src/main/java/com/ugent/pidgeon/config/JwtAuthenticationFilter.java similarity index 100% rename from backend/app/src/main/java/com/ugent/selab2/config/JwtAuthenticationFilter.java rename to backend/app/src/main/java/com/ugent/pidgeon/config/JwtAuthenticationFilter.java diff --git a/backend/app/src/main/java/com/ugent/selab2/config/OAuth2ClientConfig.java b/backend/app/src/main/java/com/ugent/pidgeon/config/OAuth2ClientConfig.java similarity index 100% rename from backend/app/src/main/java/com/ugent/selab2/config/OAuth2ClientConfig.java rename to backend/app/src/main/java/com/ugent/pidgeon/config/OAuth2ClientConfig.java diff --git a/backend/app/src/main/java/com/ugent/selab2/config/WebConfig.java b/backend/app/src/main/java/com/ugent/pidgeon/config/WebConfig.java similarity index 100% rename from backend/app/src/main/java/com/ugent/selab2/config/WebConfig.java rename to backend/app/src/main/java/com/ugent/pidgeon/config/WebConfig.java diff --git a/backend/app/src/main/java/com/ugent/selab2/controllers/AuthTestController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/AuthTestController.java similarity index 100% rename from backend/app/src/main/java/com/ugent/selab2/controllers/AuthTestController.java rename to backend/app/src/main/java/com/ugent/pidgeon/controllers/AuthTestController.java diff --git a/backend/app/src/main/java/com/ugent/selab2/model/Auth.java b/backend/app/src/main/java/com/ugent/pidgeon/model/Auth.java similarity index 100% rename from backend/app/src/main/java/com/ugent/selab2/model/Auth.java rename to backend/app/src/main/java/com/ugent/pidgeon/model/Auth.java diff --git a/backend/app/src/main/java/com/ugent/selab2/model/User.java b/backend/app/src/main/java/com/ugent/pidgeon/model/User.java similarity index 100% rename from backend/app/src/main/java/com/ugent/selab2/model/User.java rename to backend/app/src/main/java/com/ugent/pidgeon/model/User.java diff --git a/docker-compose.yaml b/docker-compose.yaml index 4bdb01ef..56e4273c 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -18,6 +18,7 @@ services: - 'POSTGRES_DB=pidegon_db' networks: - spring-postgres + restart: always postgres: container_name: pg_container image: 'postgres:latest' From 525208edbb1efded9cd7bb0dd8c14b0577bf5810 Mon Sep 17 00:00:00 2001 From: Arthur Werbrouck Date: Wed, 28 Feb 2024 17:57:38 +0100 Subject: [PATCH 07/40] preparing autorestart --- backend/app/build.gradle | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/backend/app/build.gradle b/backend/app/build.gradle index 700530b7..de6f5fbf 100644 --- a/backend/app/build.gradle +++ b/backend/app/build.gradle @@ -19,7 +19,6 @@ repositories { dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' - developmentOnly 'org.springframework.boot:spring-boot-docker-compose' runtimeOnly 'org.postgresql:postgresql' implementation 'org.springframework.boot:spring-boot-starter-oauth2-client' implementation 'org.springframework.boot:spring-boot-starter-web' @@ -33,7 +32,7 @@ dependencies { implementation 'com.auth0:java-jwt:3.18.2' implementation 'com.auth0:jwks-rsa:0.18.0' implementation 'javax.servlet:javax.servlet-api:4.0.1' - + implementation "org.springframework.boot:spring-boot-devtools" testImplementation 'org.springframework.boot:spring-boot-starter-test' testImplementation 'org.springframework.security:spring-security-test' } From c39317fdbc9e12388c6a2bda25a05b65dd703894 Mon Sep 17 00:00:00 2001 From: Aqua-sc <108478185+Aqua-sc@users.noreply.github.com> Date: Thu, 29 Feb 2024 09:48:22 +0100 Subject: [PATCH 08/40] start jpa database --- .../ugent/pidgeon/config/JwtAuthenticationFilter.java | 2 +- .../src/main/java/com/ugent/pidgeon/model/Auth.java | 2 +- .../src/main/java/com/ugent/pidgeon/model/User.java | 8 ++++++-- backend/app/src/main/resources/application.properties | 10 ++++++++++ backend/db/password.txt | 1 + 5 files changed, 19 insertions(+), 4 deletions(-) diff --git a/backend/app/src/main/java/com/ugent/pidgeon/config/JwtAuthenticationFilter.java b/backend/app/src/main/java/com/ugent/pidgeon/config/JwtAuthenticationFilter.java index 598d7897..4ef865e3 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/config/JwtAuthenticationFilter.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/config/JwtAuthenticationFilter.java @@ -67,7 +67,7 @@ protected void doFilterInternal(jakarta.servlet.http.HttpServletRequest request, //logger.info(jwt.getClaims()); - User user = new User(displayName,firstName,lastName, email, groups, oid); + User user = new User(displayName, firstName,lastName, email, groups, oid); Auth authUser = new Auth(user, new ArrayList<>()); SecurityContextHolder.getContext().setAuthentication(authUser); diff --git a/backend/app/src/main/java/com/ugent/pidgeon/model/Auth.java b/backend/app/src/main/java/com/ugent/pidgeon/model/Auth.java index 9e286d90..492ebe41 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/model/Auth.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/model/Auth.java @@ -5,7 +5,7 @@ import org.springframework.util.Assert; import java.util.Collection; - +import com.ugent.pidgeon.model.User; public class Auth extends AbstractAuthenticationToken { private static final long serialVersionUID = 620L; diff --git a/backend/app/src/main/java/com/ugent/pidgeon/model/User.java b/backend/app/src/main/java/com/ugent/pidgeon/model/User.java index 599db7f9..d3c78a02 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/model/User.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/model/User.java @@ -1,18 +1,22 @@ -package com.ugent.selab2.model; +package com.ugent.pidgeon.model; import java.util.List; public class User { public String name; + public String firstName; + public String lastName; public String email; public List groups; public String oid; - public User (String name, String email, List groups, String oid) { + public User (String name, String firstName, String lastName, String email, List groups, String oid) { this.name = name; this.email = email; this.groups = groups; this.oid = oid; + this.firstName = firstName; + this.lastName = lastName; } } diff --git a/backend/app/src/main/resources/application.properties b/backend/app/src/main/resources/application.properties index 4d7742de..ce1390e3 100644 --- a/backend/app/src/main/resources/application.properties +++ b/backend/app/src/main/resources/application.properties @@ -1,4 +1,14 @@ +spring.datasource.url=jdbc:postgresql://localhost:5432/pidgeon_db +spring.datasource.username=admin +spring.datasource.password=admin +spring.jpa.show-sql=true +## Hibernate Properties +# The SQL dialect makes Hibernate generate better SQL for the chosen database +spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect + +# Hibernate ddl auto (create, create-drop, validate, update) +spring.jpa.hibernate.ddl-auto = update server.port=8080 diff --git a/backend/db/password.txt b/backend/db/password.txt index e69de29b..f77b0040 100644 --- a/backend/db/password.txt +++ b/backend/db/password.txt @@ -0,0 +1 @@ +admin \ No newline at end of file From caba523bfac58b6b9d8b91676645d34d12451118 Mon Sep 17 00:00:00 2001 From: Aqua-sc <108478185+Aqua-sc@users.noreply.github.com> Date: Thu, 29 Feb 2024 10:51:54 +0100 Subject: [PATCH 09/40] Created entity+repo+route for user ! Nog niet kunnen testen door problemen met connectie databank ! --- .../controllers/JpaUserController.java | 18 +++++++ .../pidgeon/postgre/models/UserEntity.java | 48 +++++++++++++++++++ .../postgre/repository/UserRepository.java | 10 ++++ 3 files changed, 76 insertions(+) create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java diff --git a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java new file mode 100644 index 00000000..4bf0780b --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java @@ -0,0 +1,18 @@ +package com.ugent.pidgeon.controllers; + + +import com.ugent.pidgeon.postgre.repository.UserRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class JpaUserController { + /*@Autowired + private UserRepository userRepository;*/ + + @GetMapping("/api/users") + public String getUsers() { + return "kaas+: "; + } +} diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java new file mode 100644 index 00000000..bd3251be --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java @@ -0,0 +1,48 @@ +package com.ugent.pidgeon.postgre.models; + + +import jakarta.persistence.*; + +@Entity +public class UserEntity { + private long id; + private String name; + private String surname; + private String email; + + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "user_id", nullable = false) + public long getId() { + return id; + } + + @Column(name = "name", nullable=false) + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Column(name = "surname", nullable=false) + public String getSurname() { + return surname; + } + + public void setSurname(String surname) { + this.surname = surname; + } + + @Column(name = "email", nullable=false) + public String getEmail() { + return email; + } + + public void setEmail(String email) { + this.email = email; + } +} + diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java new file mode 100644 index 00000000..c686d37a --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java @@ -0,0 +1,10 @@ +package com.ugent.pidgeon.postgre.repository; + +import com.ugent.pidgeon.model.User; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface UserRepository extends JpaRepository { + +} From f900adea43249cf23121a0f2b04a656aa6e1f431 Mon Sep 17 00:00:00 2001 From: Arthur Werbrouck Date: Thu, 29 Feb 2024 11:28:29 +0100 Subject: [PATCH 10/40] Update docker-compose.yaml --- docker-compose.yaml | 1 + 1 file changed, 1 insertion(+) diff --git a/docker-compose.yaml b/docker-compose.yaml index 56e4273c..8a2c5a4f 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -25,6 +25,7 @@ services: secrets: - db-password environment: + - 'POSTGRES_PASSWORD=/run/secrets/db_password' - 'POSTGRES_DB=pidgeon_db' - 'POSTGRES_USER=admin' ports: From e69e92fc6330c78a0963502df75e27b40016f189 Mon Sep 17 00:00:00 2001 From: usserwoutV2 Date: Thu, 29 Feb 2024 22:05:06 +0100 Subject: [PATCH 11/40] Added ant design, improved frontend structure --- frontend/package-lock.json | 1622 ++++++++++++++++- frontend/package.json | 2 + frontend/public/index.html | 24 +- frontend/src/@types/requests.d.ts | 31 + frontend/src/@types/routes.ts | 17 + frontend/src/@types/types.ts | 46 +- frontend/src/App.tsx | 30 +- frontend/src/components/Logo.tsx | 14 + .../src/components/layout/nav/AuthNav.tsx | 74 + frontend/src/components/layout/nav/Layout.tsx | 31 + .../nav}/UnauthNav.tsx | 9 +- .../src/components/navigationBar/AuthNav.tsx | 14 - frontend/src/components/navigationBar/Nav.tsx | 27 - frontend/src/hooks/useApp.tsx | 11 + frontend/src/i18n/en/translation.json | 9 +- frontend/src/i18n/nl/translation.json | 9 +- frontend/src/pages/index/Home.tsx | 33 +- frontend/src/pages/profile/Profile.tsx | 3 - .../pages/profile/components/ProfileData.tsx | 2 +- frontend/src/providers/AppProvider.tsx | 42 + frontend/src/router/AppRouter.tsx | 2 +- frontend/src/styles.css | 6 + frontend/src/theme/ThemeProvider.tsx | 25 + frontend/src/theme/themes/dark.ts | 19 + frontend/src/theme/themes/dodona.ts | 22 + frontend/src/theme/themes/light.ts | 16 + frontend/src/util/apiFetch.ts | 2 +- 27 files changed, 1964 insertions(+), 178 deletions(-) create mode 100644 frontend/src/@types/requests.d.ts create mode 100644 frontend/src/@types/routes.ts create mode 100644 frontend/src/components/Logo.tsx create mode 100644 frontend/src/components/layout/nav/AuthNav.tsx create mode 100644 frontend/src/components/layout/nav/Layout.tsx rename frontend/src/components/{navigationBar => layout/nav}/UnauthNav.tsx (53%) delete mode 100644 frontend/src/components/navigationBar/AuthNav.tsx delete mode 100644 frontend/src/components/navigationBar/Nav.tsx create mode 100644 frontend/src/hooks/useApp.tsx create mode 100644 frontend/src/providers/AppProvider.tsx create mode 100644 frontend/src/theme/ThemeProvider.tsx create mode 100644 frontend/src/theme/themes/dark.ts create mode 100644 frontend/src/theme/themes/dodona.ts create mode 100644 frontend/src/theme/themes/light.ts diff --git a/frontend/package-lock.json b/frontend/package-lock.json index 9235a19e..e2eba6f1 100644 --- a/frontend/package-lock.json +++ b/frontend/package-lock.json @@ -8,6 +8,7 @@ "name": "frontend", "version": "0.1.0", "dependencies": { + "@ant-design/icons": "^5.3.1", "@azure/msal-browser": "^3.10.0", "@azure/msal-react": "^2.0.12", "@babel/plugin-proposal-private-property-in-object": "^7.21.11", @@ -18,6 +19,7 @@ "@types/node": "^16.18.82", "@types/react": "^18.2.56", "@types/react-dom": "^18.2.19", + "antd": "^5.14.2", "axios": "^1.6.7", "react": "^18.2.0", "react-dom": "^18.2.0", @@ -64,6 +66,71 @@ "node": ">=6.0.0" } }, + "node_modules/@ant-design/colors": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-7.0.2.tgz", + "integrity": "sha512-7KJkhTiPiLHSu+LmMJnehfJ6242OCxSlR3xHVBecYxnMW8MS/878NXct1GqYARyL59fyeFdKRxXTfvR9SnDgJg==", + "dependencies": { + "@ctrl/tinycolor": "^3.6.1" + } + }, + "node_modules/@ant-design/cssinjs": { + "version": "1.18.4", + "resolved": "https://registry.npmjs.org/@ant-design/cssinjs/-/cssinjs-1.18.4.tgz", + "integrity": "sha512-IrUAOj5TYuMG556C9gdbFuOrigyhzhU5ZYpWb3gYTxAwymVqRbvLzFCZg6OsjLBR6GhzcxYF3AhxKmjB+rA2xA==", + "dependencies": { + "@babel/runtime": "^7.11.1", + "@emotion/hash": "^0.8.0", + "@emotion/unitless": "^0.7.5", + "classnames": "^2.3.1", + "csstype": "^3.1.3", + "rc-util": "^5.35.0", + "stylis": "^4.0.13" + }, + "peerDependencies": { + "react": ">=16.0.0", + "react-dom": ">=16.0.0" + } + }, + "node_modules/@ant-design/icons": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-5.3.1.tgz", + "integrity": "sha512-85zROTJCCApQn0Ee6L9561+Vd7yVKtSWNm2TpmOsYMrumchbzaRK83x1WWHv2VG+Y1ZAaKkDwcnnSPS/eSwNHA==", + "dependencies": { + "@ant-design/colors": "^7.0.0", + "@ant-design/icons-svg": "^4.4.0", + "@babel/runtime": "^7.11.2", + "classnames": "^2.2.6", + "rc-util": "^5.31.1" + }, + "engines": { + "node": ">=8" + }, + "peerDependencies": { + "react": ">=16.0.0", + "react-dom": ">=16.0.0" + } + }, + "node_modules/@ant-design/icons-svg": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.4.2.tgz", + "integrity": "sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==" + }, + "node_modules/@ant-design/react-slick": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@ant-design/react-slick/-/react-slick-1.0.2.tgz", + "integrity": "sha512-Wj8onxL/T8KQLFFiCA4t8eIRGpRR+UPgOdac2sYzonv+i0n3kXHmvHLLiOYL655DQx2Umii9Y9nNgL7ssu5haQ==", + "dependencies": { + "@babel/runtime": "^7.10.4", + "classnames": "^2.2.5", + "json2mq": "^0.2.0", + "resize-observer-polyfill": "^1.5.1", + "throttle-debounce": "^5.0.0" + }, + "peerDependencies": { + "react": ">=16.9.0" + } + }, "node_modules/@azure/msal-browser": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-3.10.0.tgz", @@ -2343,6 +2410,24 @@ "postcss-selector-parser": "^6.0.10" } }, + "node_modules/@ctrl/tinycolor": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz", + "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==", + "engines": { + "node": ">=10" + } + }, + "node_modules/@emotion/hash": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", + "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" + }, + "node_modules/@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + }, "node_modules/@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -3393,6 +3478,118 @@ } } }, + "node_modules/@rc-component/color-picker": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@rc-component/color-picker/-/color-picker-1.5.2.tgz", + "integrity": "sha512-YJXujYzYFAEtlXJXy0yJUhwzUWPTcniBZto+wZ/vnACmFnUTNR7dH+NOeqSwMMsssh74e9H5Jfpr5LAH2PYqUw==", + "dependencies": { + "@babel/runtime": "^7.23.6", + "@ctrl/tinycolor": "^3.6.1", + "classnames": "^2.2.6", + "rc-util": "^5.38.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@rc-component/context": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@rc-component/context/-/context-1.4.0.tgz", + "integrity": "sha512-kFcNxg9oLRMoL3qki0OMxK+7g5mypjgaaJp/pkOis/6rVxma9nJBF/8kCIuTYHUQNr0ii7MxqE33wirPZLJQ2w==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "rc-util": "^5.27.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@rc-component/mini-decimal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rc-component/mini-decimal/-/mini-decimal-1.1.0.tgz", + "integrity": "sha512-jS4E7T9Li2GuYwI6PyiVXmxTiM6b07rlD9Ge8uGZSCz3WlzcG5ZK7g5bbuKNeZ9pgUuPK/5guV781ujdVpm4HQ==", + "dependencies": { + "@babel/runtime": "^7.18.0" + }, + "engines": { + "node": ">=8.x" + } + }, + "node_modules/@rc-component/mutate-observer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rc-component/mutate-observer/-/mutate-observer-1.1.0.tgz", + "integrity": "sha512-QjrOsDXQusNwGZPf4/qRQasg7UFEj06XiCJ8iuiq/Io7CrHrgVi6Uuetw60WAMG1799v+aM8kyc+1L/GBbHSlw==", + "dependencies": { + "@babel/runtime": "^7.18.0", + "classnames": "^2.3.2", + "rc-util": "^5.24.4" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@rc-component/portal": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@rc-component/portal/-/portal-1.1.2.tgz", + "integrity": "sha512-6f813C0IsasTZms08kfA8kPAGxbbkYToa8ALaiDIGGECU4i9hj8Plgbx0sNJDrey3EtHO30hmdaxtT0138xZcg==", + "dependencies": { + "@babel/runtime": "^7.18.0", + "classnames": "^2.3.2", + "rc-util": "^5.24.4" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@rc-component/tour": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/@rc-component/tour/-/tour-1.12.3.tgz", + "integrity": "sha512-U4mf1FiUxGCwrX4ed8op77Y8VKur+8Y/61ylxtqGbcSoh1EBC7bWd/DkLu0ClTUrKZInqEi1FL7YgFtnT90vHA==", + "dependencies": { + "@babel/runtime": "^7.18.0", + "@rc-component/portal": "^1.0.0-9", + "@rc-component/trigger": "^1.3.6", + "classnames": "^2.3.2", + "rc-util": "^5.24.4" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/@rc-component/trigger": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/@rc-component/trigger/-/trigger-1.18.3.tgz", + "integrity": "sha512-Ksr25pXreYe1gX6ayZ1jLrOrl9OAUHUqnuhEx6MeHnNa1zVM5Y2Aj3Q35UrER0ns8D2cJYtmJtVli+i+4eKrvA==", + "dependencies": { + "@babel/runtime": "^7.23.2", + "@rc-component/portal": "^1.1.0", + "classnames": "^2.3.2", + "rc-motion": "^2.0.0", + "rc-resize-observer": "^1.3.1", + "rc-util": "^5.38.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, "node_modules/@remix-run/router": { "version": "1.15.1", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.1.tgz", @@ -4958,6 +5155,68 @@ "node": ">=4" } }, + "node_modules/antd": { + "version": "5.14.2", + "resolved": "https://registry.npmjs.org/antd/-/antd-5.14.2.tgz", + "integrity": "sha512-ur0oBI9U7hAeON4ZRs1cAF1suIpTR+uj3YliTZacWkiVxNTZYPaaTdnLuAZDRMT9P2IZ007dCQTqxn5t1Z+Dxw==", + "dependencies": { + "@ant-design/colors": "^7.0.2", + "@ant-design/cssinjs": "^1.18.4", + "@ant-design/icons": "^5.3.0", + "@ant-design/react-slick": "~1.0.2", + "@ctrl/tinycolor": "^3.6.1", + "@rc-component/color-picker": "~1.5.2", + "@rc-component/mutate-observer": "^1.1.0", + "@rc-component/tour": "~1.12.3", + "@rc-component/trigger": "^1.18.3", + "classnames": "^2.5.1", + "copy-to-clipboard": "^3.3.3", + "dayjs": "^1.11.10", + "qrcode.react": "^3.1.0", + "rc-cascader": "~3.21.2", + "rc-checkbox": "~3.1.0", + "rc-collapse": "~3.7.2", + "rc-dialog": "~9.3.4", + "rc-drawer": "~7.0.0", + "rc-dropdown": "~4.1.0", + "rc-field-form": "~1.41.0", + "rc-image": "~7.5.1", + "rc-input": "~1.4.3", + "rc-input-number": "~9.0.0", + "rc-mentions": "~2.10.1", + "rc-menu": "~9.12.4", + "rc-motion": "^2.9.0", + "rc-notification": "~5.3.0", + "rc-pagination": "~4.0.4", + "rc-picker": "~4.1.4", + "rc-progress": "~3.5.1", + "rc-rate": "~2.12.0", + "rc-resize-observer": "^1.4.0", + "rc-segmented": "~2.3.0", + "rc-select": "~14.11.0", + "rc-slider": "~10.5.0", + "rc-steps": "~6.0.1", + "rc-switch": "~4.1.0", + "rc-table": "~7.39.0", + "rc-tabs": "~14.0.0", + "rc-textarea": "~1.6.3", + "rc-tooltip": "~6.1.3", + "rc-tree": "~5.8.5", + "rc-tree-select": "~5.17.0", + "rc-upload": "~4.5.2", + "rc-util": "^5.38.2", + "scroll-into-view-if-needed": "^3.1.0", + "throttle-debounce": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/ant-design" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, "node_modules/any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", @@ -5034,6 +5293,11 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/array-tree-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-tree-filter/-/array-tree-filter-2.1.0.tgz", + "integrity": "sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==" + }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", @@ -5178,6 +5442,11 @@ "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" }, + "node_modules/async-validator": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz", + "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==" + }, "node_modules/asynciterator.prototype": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", @@ -5947,6 +6216,11 @@ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==" }, + "node_modules/classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" + }, "node_modules/clean-css": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", @@ -6109,6 +6383,11 @@ "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==" }, + "node_modules/compute-scroll-into-view": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.0.tgz", + "integrity": "sha512-rj8l8pD4bJ1nx+dAkMhV1xB5RuZEyVysfxJqB1pRchh1KVvwOv9b7CGB8ZfjTImVv2oF+sYMUkMZq6Na5Ftmbg==" + }, "node_modules/concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -6164,6 +6443,14 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, + "node_modules/copy-to-clipboard": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", + "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", + "dependencies": { + "toggle-selection": "^1.0.6" + } + }, "node_modules/core-js": { "version": "3.36.0", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.36.0.tgz", @@ -6659,6 +6946,11 @@ "node": ">=10" } }, + "node_modules/dayjs": { + "version": "1.11.10", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -12025,6 +12317,14 @@ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" }, + "node_modules/json2mq": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz", + "integrity": "sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==", + "dependencies": { + "string-convert": "^0.2.0" + } + }, "node_modules/json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -14585,6 +14885,14 @@ "teleport": ">=0.2.0" } }, + "node_modules/qrcode.react": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-3.1.0.tgz", + "integrity": "sha512-oyF+Urr3oAMUG/OiOuONL3HXM+53wvuH3mtIWQrYmsXoAq0DkvZp2RYUWFSMFtbdOpuS++9v+WAkzNVkMlNW6Q==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -14652,32 +14960,609 @@ "resolved": "https://registry.npmjs.org/raw-body/-/raw-body-2.5.1.tgz", "integrity": "sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==", "dependencies": { - "bytes": "3.1.2", - "http-errors": "2.0.0", - "iconv-lite": "0.4.24", - "unpipe": "1.0.0" + "bytes": "3.1.2", + "http-errors": "2.0.0", + "iconv-lite": "0.4.24", + "unpipe": "1.0.0" + }, + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/bytes": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", + "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", + "engines": { + "node": ">= 0.8" + } + }, + "node_modules/raw-body/node_modules/iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/rc-cascader": { + "version": "3.21.2", + "resolved": "https://registry.npmjs.org/rc-cascader/-/rc-cascader-3.21.2.tgz", + "integrity": "sha512-J7GozpgsLaOtzfIHFJFuh4oFY0ePb1w10twqK6is3pAkqHkca/PsokbDr822KIRZ8/CK8CqevxohuPDVZ1RO/A==", + "dependencies": { + "@babel/runtime": "^7.12.5", + "array-tree-filter": "^2.1.0", + "classnames": "^2.3.1", + "rc-select": "~14.11.0", + "rc-tree": "~5.8.1", + "rc-util": "^5.37.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-checkbox": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/rc-checkbox/-/rc-checkbox-3.1.0.tgz", + "integrity": "sha512-PAwpJFnBa3Ei+5pyqMMXdcKYKNBMS+TvSDiLdDnARnMJHC8ESxwPfm4Ao1gJiKtWLdmGfigascnCpwrHFgoOBQ==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.3.2", + "rc-util": "^5.25.2" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-collapse": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/rc-collapse/-/rc-collapse-3.7.2.tgz", + "integrity": "sha512-ZRw6ipDyOnfLFySxAiCMdbHtb5ePAsB9mT17PA6y1mRD/W6KHRaZeb5qK/X9xDV1CqgyxMpzw0VdS74PCcUk4A==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.3.4", + "rc-util": "^5.27.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-dialog": { + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/rc-dialog/-/rc-dialog-9.3.4.tgz", + "integrity": "sha512-975X3018GhR+EjZFbxA2Z57SX5rnu0G0/OxFgMMvZK4/hQWEm3MHaNvP4wXpxYDoJsp+xUvVW+GB9CMMCm81jA==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "@rc-component/portal": "^1.0.0-8", + "classnames": "^2.2.6", + "rc-motion": "^2.3.0", + "rc-util": "^5.21.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-drawer": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rc-drawer/-/rc-drawer-7.0.0.tgz", + "integrity": "sha512-ePcS4KtQnn57bCbVXazHN2iC8nTPCXlWEIA/Pft87Pd9U7ZeDkdRzG47jWG2/TAFXFlFltRAMcslqmUM8NPCGA==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "@rc-component/portal": "^1.1.1", + "classnames": "^2.2.6", + "rc-motion": "^2.6.1", + "rc-util": "^5.36.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-dropdown": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rc-dropdown/-/rc-dropdown-4.1.0.tgz", + "integrity": "sha512-VZjMunpBdlVzYpEdJSaV7WM7O0jf8uyDjirxXLZRNZ+tAC+NzD3PXPEtliFwGzVwBBdCmGuSqiS9DWcOLxQ9tw==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "@rc-component/trigger": "^1.7.0", + "classnames": "^2.2.6", + "rc-util": "^5.17.0" + }, + "peerDependencies": { + "react": ">=16.11.0", + "react-dom": ">=16.11.0" + } + }, + "node_modules/rc-field-form": { + "version": "1.41.0", + "resolved": "https://registry.npmjs.org/rc-field-form/-/rc-field-form-1.41.0.tgz", + "integrity": "sha512-k9AS0wmxfJfusWDP/YXWTpteDNaQ4isJx9UKxx4/e8Dub4spFeZ54/EuN2sYrMRID/+hUznPgVZeg+Gf7XSYCw==", + "dependencies": { + "@babel/runtime": "^7.18.0", + "async-validator": "^4.1.0", + "rc-util": "^5.32.2" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-image": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/rc-image/-/rc-image-7.5.1.tgz", + "integrity": "sha512-Z9loECh92SQp0nSipc0MBuf5+yVC05H/pzC+Nf8xw1BKDFUJzUeehYBjaWlxly8VGBZJcTHYri61Fz9ng1G3Ag==", + "dependencies": { + "@babel/runtime": "^7.11.2", + "@rc-component/portal": "^1.0.2", + "classnames": "^2.2.6", + "rc-dialog": "~9.3.4", + "rc-motion": "^2.6.2", + "rc-util": "^5.34.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-input": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/rc-input/-/rc-input-1.4.3.tgz", + "integrity": "sha512-aHyQUAIRmTlOnvk5EcNqEpJ+XMtfMpYRAJayIlJfsvvH9cAKUWboh4egm23vgMA7E+c/qm4BZcnrDcA960GC1w==", + "dependencies": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-util": "^5.18.1" + }, + "peerDependencies": { + "react": ">=16.0.0", + "react-dom": ">=16.0.0" + } + }, + "node_modules/rc-input-number": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/rc-input-number/-/rc-input-number-9.0.0.tgz", + "integrity": "sha512-RfcDBDdWFFetouWFXBA+WPEC8LzBXyngr9b+yTLVIygfFu7HiLRGn/s/v9wwno94X7KFvnb28FNynMGj9XJlDQ==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "@rc-component/mini-decimal": "^1.0.1", + "classnames": "^2.2.5", + "rc-input": "~1.4.0", + "rc-util": "^5.28.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-mentions": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/rc-mentions/-/rc-mentions-2.10.1.tgz", + "integrity": "sha512-72qsEcr/7su+a07ndJ1j8rI9n0Ka/ngWOLYnWMMv0p2mi/5zPwPrEDTt6Uqpe8FWjWhueDJx/vzunL6IdKDYMg==", + "dependencies": { + "@babel/runtime": "^7.22.5", + "@rc-component/trigger": "^1.5.0", + "classnames": "^2.2.6", + "rc-input": "~1.4.0", + "rc-menu": "~9.12.0", + "rc-textarea": "~1.6.1", + "rc-util": "^5.34.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-menu": { + "version": "9.12.4", + "resolved": "https://registry.npmjs.org/rc-menu/-/rc-menu-9.12.4.tgz", + "integrity": "sha512-t2NcvPLV1mFJzw4F21ojOoRVofK2rWhpKPx69q2raUsiHPDP6DDevsBILEYdsIegqBeSXoWs2bf6CueBKg3BFg==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "@rc-component/trigger": "^1.17.0", + "classnames": "2.x", + "rc-motion": "^2.4.3", + "rc-overflow": "^1.3.1", + "rc-util": "^5.27.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-motion": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.9.0.tgz", + "integrity": "sha512-XIU2+xLkdIr1/h6ohPZXyPBMvOmuyFZQ/T0xnawz+Rh+gh4FINcnZmMT5UTIj6hgI0VLDjTaPeRd+smJeSPqiQ==", + "dependencies": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-util": "^5.21.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-notification": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/rc-notification/-/rc-notification-5.3.0.tgz", + "integrity": "sha512-WCf0uCOkZ3HGfF0p1H4Sgt7aWfipxORWTPp7o6prA3vxwtWhtug3GfpYls1pnBp4WA+j8vGIi5c2/hQRpGzPcQ==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.9.0", + "rc-util": "^5.20.1" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-overflow": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/rc-overflow/-/rc-overflow-1.3.2.tgz", + "integrity": "sha512-nsUm78jkYAoPygDAcGZeC2VwIg/IBGSodtOY3pMof4W3M9qRJgqaDYm03ZayHlde3I6ipliAxbN0RUcGf5KOzw==", + "dependencies": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.37.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-pagination": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/rc-pagination/-/rc-pagination-4.0.4.tgz", + "integrity": "sha512-GGrLT4NgG6wgJpT/hHIpL9nELv27A1XbSZzECIuQBQTVSf4xGKxWr6I/jhpRPauYEWEbWVw22ObG6tJQqwJqWQ==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.3.2", + "rc-util": "^5.38.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-picker": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/rc-picker/-/rc-picker-4.1.5.tgz", + "integrity": "sha512-dh2E9j7HomZW10RWIBsdyXs3geHkSslVqKTx3VZfmi9UEabiQrBBNKVIhqn2m0goia0dqyWJ4qRghAsBVLGzbw==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "@rc-component/trigger": "^1.5.0", + "classnames": "^2.2.1", + "rc-overflow": "^1.3.2", + "rc-resize-observer": "^1.4.0", + "rc-util": "^5.38.1" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "date-fns": ">= 2.x", + "dayjs": ">= 1.x", + "luxon": ">= 3.x", + "moment": ">= 2.x", + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + }, + "peerDependenciesMeta": { + "date-fns": { + "optional": true + }, + "dayjs": { + "optional": true + }, + "luxon": { + "optional": true + }, + "moment": { + "optional": true + } + } + }, + "node_modules/rc-progress": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/rc-progress/-/rc-progress-3.5.1.tgz", + "integrity": "sha512-V6Amx6SbLRwPin/oD+k1vbPrO8+9Qf8zW1T8A7o83HdNafEVvAxPV5YsgtKFP+Ud5HghLj33zKOcEHrcrUGkfw==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6", + "rc-util": "^5.16.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-rate": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/rc-rate/-/rc-rate-2.12.0.tgz", + "integrity": "sha512-g092v5iZCdVzbjdn28FzvWebK2IutoVoiTeqoLTj9WM7SjA/gOJIw5/JFZMRyJYYVe1jLAU2UhAfstIpCNRozg==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-util": "^5.0.1" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-resize-observer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/rc-resize-observer/-/rc-resize-observer-1.4.0.tgz", + "integrity": "sha512-PnMVyRid9JLxFavTjeDXEXo65HCRqbmLBw9xX9gfC4BZiSzbLXKzW3jPz+J0P71pLbD5tBMTT+mkstV5gD0c9Q==", + "dependencies": { + "@babel/runtime": "^7.20.7", + "classnames": "^2.2.1", + "rc-util": "^5.38.0", + "resize-observer-polyfill": "^1.5.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-segmented": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/rc-segmented/-/rc-segmented-2.3.0.tgz", + "integrity": "sha512-I3FtM5Smua/ESXutFfb8gJ8ZPcvFR+qUgeeGFQHBOvRiRKyAk4aBE5nfqrxXx+h8/vn60DQjOt6i4RNtrbOobg==", + "dependencies": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-motion": "^2.4.4", + "rc-util": "^5.17.0" + }, + "peerDependencies": { + "react": ">=16.0.0", + "react-dom": ">=16.0.0" + } + }, + "node_modules/rc-select": { + "version": "14.11.0", + "resolved": "https://registry.npmjs.org/rc-select/-/rc-select-14.11.0.tgz", + "integrity": "sha512-8J8G/7duaGjFiTXCBLWfh5P+KDWyA3KTlZDfV3xj/asMPqB2cmxfM+lH50wRiPIRsCQ6EbkCFBccPuaje3DHIg==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "@rc-component/trigger": "^1.5.0", + "classnames": "2.x", + "rc-motion": "^2.0.1", + "rc-overflow": "^1.3.1", + "rc-util": "^5.16.1", + "rc-virtual-list": "^3.5.2" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/rc-slider": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-10.5.0.tgz", + "integrity": "sha512-xiYght50cvoODZYI43v3Ylsqiw14+D7ELsgzR40boDZaya1HFa1Etnv9MDkQE8X/UrXAffwv2AcNAhslgYuDTw==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-util": "^5.27.0" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-steps": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/rc-steps/-/rc-steps-6.0.1.tgz", + "integrity": "sha512-lKHL+Sny0SeHkQKKDJlAjV5oZ8DwCdS2hFhAkIjuQt1/pB81M0cA0ErVFdHq9+jmPmFw1vJB2F5NBzFXLJxV+g==", + "dependencies": { + "@babel/runtime": "^7.16.7", + "classnames": "^2.2.3", + "rc-util": "^5.16.1" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-switch": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rc-switch/-/rc-switch-4.1.0.tgz", + "integrity": "sha512-TI8ufP2Az9oEbvyCeVE4+90PDSljGyuwix3fV58p7HV2o4wBnVToEyomJRVyTaZeqNPAp+vqeo4Wnj5u0ZZQBg==", + "dependencies": { + "@babel/runtime": "^7.21.0", + "classnames": "^2.2.1", + "rc-util": "^5.30.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-table": { + "version": "7.39.0", + "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.39.0.tgz", + "integrity": "sha512-7fHLMNsm/2DlGwyIMkdH2xIeRzb5I69bLsFaEVtX+gqmGhByy0wtOAgHkiOew3PtXozSJyh+iXifjLgQzWdczw==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "@rc-component/context": "^1.4.0", + "classnames": "^2.2.5", + "rc-resize-observer": "^1.1.0", + "rc-util": "^5.37.0", + "rc-virtual-list": "^3.11.1" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-tabs": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/rc-tabs/-/rc-tabs-14.0.0.tgz", + "integrity": "sha512-lp1YWkaPnjlyhOZCPrAWxK6/P6nMGX/BAZcAC3nuVwKz0Byfp+vNnQKK8BRCP2g/fzu+SeB5dm9aUigRu3tRkQ==", + "dependencies": { + "@babel/runtime": "^7.11.2", + "classnames": "2.x", + "rc-dropdown": "~4.1.0", + "rc-menu": "~9.12.0", + "rc-motion": "^2.6.2", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.34.1" + }, + "engines": { + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-textarea": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/rc-textarea/-/rc-textarea-1.6.3.tgz", + "integrity": "sha512-8k7+8Y2GJ/cQLiClFMg8kUXOOdvcFQrnGeSchOvI2ZMIVvX5a3zQpLxoODL0HTrvU63fPkRmMuqaEcOF9dQemA==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1", + "rc-input": "~1.4.0", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.27.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-tooltip": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-6.1.3.tgz", + "integrity": "sha512-HMSbSs5oieZ7XddtINUddBLSVgsnlaSb3bZrzzGWjXa7/B7nNedmsuz72s7EWFEro9mNa7RyF3gOXKYqvJiTcQ==", + "dependencies": { + "@babel/runtime": "^7.11.2", + "@rc-component/trigger": "^1.18.0", + "classnames": "^2.3.1" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" + } + }, + "node_modules/rc-tree": { + "version": "5.8.5", + "resolved": "https://registry.npmjs.org/rc-tree/-/rc-tree-5.8.5.tgz", + "integrity": "sha512-PRfcZtVDNkR7oh26RuNe1hpw11c1wfgzwmPFL0lnxGnYefe9lDAO6cg5wJKIAwyXFVt5zHgpjYmaz0CPy1ZtKg==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.0.1", + "rc-util": "^5.16.1", + "rc-virtual-list": "^3.5.1" + }, + "engines": { + "node": ">=10.x" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/rc-tree-select": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/rc-tree-select/-/rc-tree-select-5.17.0.tgz", + "integrity": "sha512-7sRGafswBhf7n6IuHyCEFCildwQIgyKiV8zfYyUoWfZEFdhuk7lCH+DN0aHt+oJrdiY9+6Io/LDXloGe01O8XQ==", + "dependencies": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-select": "~14.11.0-0", + "rc-tree": "~5.8.1", + "rc-util": "^5.16.1" + }, + "peerDependencies": { + "react": "*", + "react-dom": "*" + } + }, + "node_modules/rc-upload": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/rc-upload/-/rc-upload-4.5.2.tgz", + "integrity": "sha512-QO3ne77DwnAPKFn0bA5qJM81QBjQi0e0NHdkvpFyY73Bea2NfITiotqJqVjHgeYPOJu5lLVR32TNGP084aSoXA==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "classnames": "^2.2.5", + "rc-util": "^5.2.0" }, - "engines": { - "node": ">= 0.8" + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" } }, - "node_modules/raw-body/node_modules/bytes": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.1.2.tgz", - "integrity": "sha512-/Nf7TyzTx6S3yRJObOAV7956r8cr2+Oj8AC5dt8wSP3BQAoeX58NoHyCU8P8zGkNXStjTSi6fzO6F0pBdcYbEg==", - "engines": { - "node": ">= 0.8" + "node_modules/rc-util": { + "version": "5.38.2", + "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.38.2.tgz", + "integrity": "sha512-yRGRPKyi84H7NkRSP6FzEIYBdUt4ufdsmXUZ7qM2H5qoByPax70NnGPkfo36N+UKUnUBj2f2Q2eUbwYMuAsIOQ==", + "dependencies": { + "@babel/runtime": "^7.18.3", + "react-is": "^18.2.0" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" } }, - "node_modules/raw-body/node_modules/iconv-lite": { - "version": "0.4.24", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", - "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "node_modules/rc-util/node_modules/react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + }, + "node_modules/rc-virtual-list": { + "version": "3.11.4", + "resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.11.4.tgz", + "integrity": "sha512-NbBi0fvyIu26gP69nQBiWgUMTPX3mr4FcuBQiVqagU0BnuX8WQkiivnMs105JROeuUIFczLrlgUhLQwTWV1XDA==", "dependencies": { - "safer-buffer": ">= 2.1.2 < 3" + "@babel/runtime": "^7.20.0", + "classnames": "^2.2.6", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.36.0" }, "engines": { - "node": ">=0.10.0" + "node": ">=8.x" + }, + "peerDependencies": { + "react": ">=16.9.0", + "react-dom": ">=16.9.0" } }, "node_modules/react": { @@ -15184,6 +16069,11 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, + "node_modules/resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, "node_modules/resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -15550,6 +16440,14 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/scroll-into-view-if-needed": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-3.1.0.tgz", + "integrity": "sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==", + "dependencies": { + "compute-scroll-into-view": "^3.0.2" + } + }, "node_modules/select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -16083,6 +16981,11 @@ "safe-buffer": "~5.2.0" } }, + "node_modules/string-convert": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz", + "integrity": "sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==" + }, "node_modules/string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -16310,6 +17213,11 @@ "postcss": "^8.2.15" } }, + "node_modules/stylis": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.1.tgz", + "integrity": "sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ==" + }, "node_modules/sucrase": { "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", @@ -16717,6 +17625,14 @@ "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz", "integrity": "sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==" }, + "node_modules/throttle-debounce": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.0.tgz", + "integrity": "sha512-2iQTSgkkc1Zyk0MeVrt/3BvuOXYPl/R8Z0U2xxo9rjwNciaHDG3R+Lm6dh4EeUci49DanvBnuqI6jshoQQRGEg==", + "engines": { + "node": ">=12.22" + } + }, "node_modules/thunky": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", @@ -16746,6 +17662,11 @@ "node": ">=8.0" } }, + "node_modules/toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" + }, "node_modules/toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", @@ -18234,6 +19155,57 @@ "@jridgewell/trace-mapping": "^0.3.9" } }, + "@ant-design/colors": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/@ant-design/colors/-/colors-7.0.2.tgz", + "integrity": "sha512-7KJkhTiPiLHSu+LmMJnehfJ6242OCxSlR3xHVBecYxnMW8MS/878NXct1GqYARyL59fyeFdKRxXTfvR9SnDgJg==", + "requires": { + "@ctrl/tinycolor": "^3.6.1" + } + }, + "@ant-design/cssinjs": { + "version": "1.18.4", + "resolved": "https://registry.npmjs.org/@ant-design/cssinjs/-/cssinjs-1.18.4.tgz", + "integrity": "sha512-IrUAOj5TYuMG556C9gdbFuOrigyhzhU5ZYpWb3gYTxAwymVqRbvLzFCZg6OsjLBR6GhzcxYF3AhxKmjB+rA2xA==", + "requires": { + "@babel/runtime": "^7.11.1", + "@emotion/hash": "^0.8.0", + "@emotion/unitless": "^0.7.5", + "classnames": "^2.3.1", + "csstype": "^3.1.3", + "rc-util": "^5.35.0", + "stylis": "^4.0.13" + } + }, + "@ant-design/icons": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@ant-design/icons/-/icons-5.3.1.tgz", + "integrity": "sha512-85zROTJCCApQn0Ee6L9561+Vd7yVKtSWNm2TpmOsYMrumchbzaRK83x1WWHv2VG+Y1ZAaKkDwcnnSPS/eSwNHA==", + "requires": { + "@ant-design/colors": "^7.0.0", + "@ant-design/icons-svg": "^4.4.0", + "@babel/runtime": "^7.11.2", + "classnames": "^2.2.6", + "rc-util": "^5.31.1" + } + }, + "@ant-design/icons-svg": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/@ant-design/icons-svg/-/icons-svg-4.4.2.tgz", + "integrity": "sha512-vHbT+zJEVzllwP+CM+ul7reTEfBR0vgxFe7+lREAsAA7YGsYpboiq2sQNeQeRvh09GfQgs/GyFEvZpJ9cLXpXA==" + }, + "@ant-design/react-slick": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/@ant-design/react-slick/-/react-slick-1.0.2.tgz", + "integrity": "sha512-Wj8onxL/T8KQLFFiCA4t8eIRGpRR+UPgOdac2sYzonv+i0n3kXHmvHLLiOYL655DQx2Umii9Y9nNgL7ssu5haQ==", + "requires": { + "@babel/runtime": "^7.10.4", + "classnames": "^2.2.5", + "json2mq": "^0.2.0", + "resize-observer-polyfill": "^1.5.1", + "throttle-debounce": "^5.0.0" + } + }, "@azure/msal-browser": { "version": "3.10.0", "resolved": "https://registry.npmjs.org/@azure/msal-browser/-/msal-browser-3.10.0.tgz", @@ -19689,6 +20661,21 @@ "integrity": "sha512-+OJ9konv95ClSTOJCmMZqpd5+YGsB2S+x6w3E1oaM8UuR5j8nTNHYSz8c9BEPGDOCMQYIEEGlVPj/VY64iTbGw==", "requires": {} }, + "@ctrl/tinycolor": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/@ctrl/tinycolor/-/tinycolor-3.6.1.tgz", + "integrity": "sha512-SITSV6aIXsuVNV3f3O0f2n/cgyEDWoSqtZMYiAmcsYHydcKrOz3gUxB/iXd/Qf08+IZX4KpgNbvUdMBmWz+kcA==" + }, + "@emotion/hash": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.8.0.tgz", + "integrity": "sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow==" + }, + "@emotion/unitless": { + "version": "0.7.5", + "resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.7.5.tgz", + "integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==" + }, "@eslint-community/eslint-utils": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/@eslint-community/eslint-utils/-/eslint-utils-4.4.0.tgz", @@ -20433,6 +21420,79 @@ "source-map": "^0.7.3" } }, + "@rc-component/color-picker": { + "version": "1.5.2", + "resolved": "https://registry.npmjs.org/@rc-component/color-picker/-/color-picker-1.5.2.tgz", + "integrity": "sha512-YJXujYzYFAEtlXJXy0yJUhwzUWPTcniBZto+wZ/vnACmFnUTNR7dH+NOeqSwMMsssh74e9H5Jfpr5LAH2PYqUw==", + "requires": { + "@babel/runtime": "^7.23.6", + "@ctrl/tinycolor": "^3.6.1", + "classnames": "^2.2.6", + "rc-util": "^5.38.1" + } + }, + "@rc-component/context": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/@rc-component/context/-/context-1.4.0.tgz", + "integrity": "sha512-kFcNxg9oLRMoL3qki0OMxK+7g5mypjgaaJp/pkOis/6rVxma9nJBF/8kCIuTYHUQNr0ii7MxqE33wirPZLJQ2w==", + "requires": { + "@babel/runtime": "^7.10.1", + "rc-util": "^5.27.0" + } + }, + "@rc-component/mini-decimal": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rc-component/mini-decimal/-/mini-decimal-1.1.0.tgz", + "integrity": "sha512-jS4E7T9Li2GuYwI6PyiVXmxTiM6b07rlD9Ge8uGZSCz3WlzcG5ZK7g5bbuKNeZ9pgUuPK/5guV781ujdVpm4HQ==", + "requires": { + "@babel/runtime": "^7.18.0" + } + }, + "@rc-component/mutate-observer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@rc-component/mutate-observer/-/mutate-observer-1.1.0.tgz", + "integrity": "sha512-QjrOsDXQusNwGZPf4/qRQasg7UFEj06XiCJ8iuiq/Io7CrHrgVi6Uuetw60WAMG1799v+aM8kyc+1L/GBbHSlw==", + "requires": { + "@babel/runtime": "^7.18.0", + "classnames": "^2.3.2", + "rc-util": "^5.24.4" + } + }, + "@rc-component/portal": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/@rc-component/portal/-/portal-1.1.2.tgz", + "integrity": "sha512-6f813C0IsasTZms08kfA8kPAGxbbkYToa8ALaiDIGGECU4i9hj8Plgbx0sNJDrey3EtHO30hmdaxtT0138xZcg==", + "requires": { + "@babel/runtime": "^7.18.0", + "classnames": "^2.3.2", + "rc-util": "^5.24.4" + } + }, + "@rc-component/tour": { + "version": "1.12.3", + "resolved": "https://registry.npmjs.org/@rc-component/tour/-/tour-1.12.3.tgz", + "integrity": "sha512-U4mf1FiUxGCwrX4ed8op77Y8VKur+8Y/61ylxtqGbcSoh1EBC7bWd/DkLu0ClTUrKZInqEi1FL7YgFtnT90vHA==", + "requires": { + "@babel/runtime": "^7.18.0", + "@rc-component/portal": "^1.0.0-9", + "@rc-component/trigger": "^1.3.6", + "classnames": "^2.3.2", + "rc-util": "^5.24.4" + } + }, + "@rc-component/trigger": { + "version": "1.18.3", + "resolved": "https://registry.npmjs.org/@rc-component/trigger/-/trigger-1.18.3.tgz", + "integrity": "sha512-Ksr25pXreYe1gX6ayZ1jLrOrl9OAUHUqnuhEx6MeHnNa1zVM5Y2Aj3Q35UrER0ns8D2cJYtmJtVli+i+4eKrvA==", + "requires": { + "@babel/runtime": "^7.23.2", + "@rc-component/portal": "^1.1.0", + "classnames": "^2.3.2", + "rc-motion": "^2.0.0", + "rc-resize-observer": "^1.3.1", + "rc-util": "^5.38.0" + } + }, "@remix-run/router": { "version": "1.15.1", "resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.15.1.tgz", @@ -21619,6 +22679,60 @@ "color-convert": "^1.9.0" } }, + "antd": { + "version": "5.14.2", + "resolved": "https://registry.npmjs.org/antd/-/antd-5.14.2.tgz", + "integrity": "sha512-ur0oBI9U7hAeON4ZRs1cAF1suIpTR+uj3YliTZacWkiVxNTZYPaaTdnLuAZDRMT9P2IZ007dCQTqxn5t1Z+Dxw==", + "requires": { + "@ant-design/colors": "^7.0.2", + "@ant-design/cssinjs": "^1.18.4", + "@ant-design/icons": "^5.3.0", + "@ant-design/react-slick": "~1.0.2", + "@ctrl/tinycolor": "^3.6.1", + "@rc-component/color-picker": "~1.5.2", + "@rc-component/mutate-observer": "^1.1.0", + "@rc-component/tour": "~1.12.3", + "@rc-component/trigger": "^1.18.3", + "classnames": "^2.5.1", + "copy-to-clipboard": "^3.3.3", + "dayjs": "^1.11.10", + "qrcode.react": "^3.1.0", + "rc-cascader": "~3.21.2", + "rc-checkbox": "~3.1.0", + "rc-collapse": "~3.7.2", + "rc-dialog": "~9.3.4", + "rc-drawer": "~7.0.0", + "rc-dropdown": "~4.1.0", + "rc-field-form": "~1.41.0", + "rc-image": "~7.5.1", + "rc-input": "~1.4.3", + "rc-input-number": "~9.0.0", + "rc-mentions": "~2.10.1", + "rc-menu": "~9.12.4", + "rc-motion": "^2.9.0", + "rc-notification": "~5.3.0", + "rc-pagination": "~4.0.4", + "rc-picker": "~4.1.4", + "rc-progress": "~3.5.1", + "rc-rate": "~2.12.0", + "rc-resize-observer": "^1.4.0", + "rc-segmented": "~2.3.0", + "rc-select": "~14.11.0", + "rc-slider": "~10.5.0", + "rc-steps": "~6.0.1", + "rc-switch": "~4.1.0", + "rc-table": "~7.39.0", + "rc-tabs": "~14.0.0", + "rc-textarea": "~1.6.3", + "rc-tooltip": "~6.1.3", + "rc-tree": "~5.8.5", + "rc-tree-select": "~5.17.0", + "rc-upload": "~4.5.2", + "rc-util": "^5.38.2", + "scroll-into-view-if-needed": "^3.1.0", + "throttle-debounce": "^5.0.0" + } + }, "any-promise": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz", @@ -21680,6 +22794,11 @@ "is-string": "^1.0.7" } }, + "array-tree-filter": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/array-tree-filter/-/array-tree-filter-2.1.0.tgz", + "integrity": "sha512-4ROwICNlNw/Hqa9v+rk5h22KjmzB1JGTMVKP2AKJBOCgb0yL0ASf0+YvCcLNNwquOHNX48jkeZIJ3a+oOQqKcw==" + }, "array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", @@ -21785,6 +22904,11 @@ "resolved": "https://registry.npmjs.org/async/-/async-3.2.5.tgz", "integrity": "sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==" }, + "async-validator": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/async-validator/-/async-validator-4.2.5.tgz", + "integrity": "sha512-7HhHjtERjqlNbZtqNqy2rckN/SpOOlmDliet+lP7k+eKZEjPk3DgyeU9lIXLdeLz0uBbbVp+9Qdow9wJWgwwfg==" + }, "asynciterator.prototype": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/asynciterator.prototype/-/asynciterator.prototype-1.0.0.tgz", @@ -22339,6 +23463,11 @@ "resolved": "https://registry.npmjs.org/cjs-module-lexer/-/cjs-module-lexer-1.2.3.tgz", "integrity": "sha512-0TNiGstbQmCFwt4akjjBg5pLRTSyj/PkWQ1ZoO2zntmg9yLqSRxwEa4iCfQLGjqhiqBfOJa7W/E8wfGrTDmlZQ==" }, + "classnames": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.5.1.tgz", + "integrity": "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow==" + }, "clean-css": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/clean-css/-/clean-css-5.3.3.tgz", @@ -22477,6 +23606,11 @@ } } }, + "compute-scroll-into-view": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/compute-scroll-into-view/-/compute-scroll-into-view-3.1.0.tgz", + "integrity": "sha512-rj8l8pD4bJ1nx+dAkMhV1xB5RuZEyVysfxJqB1pRchh1KVvwOv9b7CGB8ZfjTImVv2oF+sYMUkMZq6Na5Ftmbg==" + }, "concat-map": { "version": "0.0.1", "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", @@ -22520,6 +23654,14 @@ "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz", "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==" }, + "copy-to-clipboard": { + "version": "3.3.3", + "resolved": "https://registry.npmjs.org/copy-to-clipboard/-/copy-to-clipboard-3.3.3.tgz", + "integrity": "sha512-2KV8NhB5JqC3ky0r9PMCAZKbUHSwtEo4CwCs0KXgruG43gX5PMqDEBbVU4OUzw2MuAWUfsuFmWvEKG5QRfSnJA==", + "requires": { + "toggle-selection": "^1.0.6" + } + }, "core-js": { "version": "3.36.0", "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.36.0.tgz", @@ -22842,6 +23984,11 @@ "whatwg-url": "^8.0.0" } }, + "dayjs": { + "version": "1.11.10", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" + }, "debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -26692,6 +27839,14 @@ "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==" }, + "json2mq": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/json2mq/-/json2mq-0.2.0.tgz", + "integrity": "sha512-SzoRg7ux5DWTII9J2qkrZrqV1gt+rTaoufMxEzXbS26Uid0NwaJd123HcoB80TgubEppxxIGdNxCx50fEoEWQA==", + "requires": { + "string-convert": "^0.2.0" + } + }, "json5": { "version": "2.2.3", "resolved": "https://registry.npmjs.org/json5/-/json5-2.2.3.tgz", @@ -28358,6 +29513,12 @@ "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", "integrity": "sha512-kV/CThkXo6xyFEZUugw/+pIOywXcDbFYgSct5cT3gqlbkBE1SJdwy6UQoZvodiWF/ckQLZyDE/Bu1M6gVu5lVw==" }, + "qrcode.react": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/qrcode.react/-/qrcode.react-3.1.0.tgz", + "integrity": "sha512-oyF+Urr3oAMUG/OiOuONL3HXM+53wvuH3mtIWQrYmsXoAq0DkvZp2RYUWFSMFtbdOpuS++9v+WAkzNVkMlNW6Q==", + "requires": {} + }, "qs": { "version": "6.11.0", "resolved": "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz", @@ -28423,6 +29584,398 @@ } } }, + "rc-cascader": { + "version": "3.21.2", + "resolved": "https://registry.npmjs.org/rc-cascader/-/rc-cascader-3.21.2.tgz", + "integrity": "sha512-J7GozpgsLaOtzfIHFJFuh4oFY0ePb1w10twqK6is3pAkqHkca/PsokbDr822KIRZ8/CK8CqevxohuPDVZ1RO/A==", + "requires": { + "@babel/runtime": "^7.12.5", + "array-tree-filter": "^2.1.0", + "classnames": "^2.3.1", + "rc-select": "~14.11.0", + "rc-tree": "~5.8.1", + "rc-util": "^5.37.0" + } + }, + "rc-checkbox": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/rc-checkbox/-/rc-checkbox-3.1.0.tgz", + "integrity": "sha512-PAwpJFnBa3Ei+5pyqMMXdcKYKNBMS+TvSDiLdDnARnMJHC8ESxwPfm4Ao1gJiKtWLdmGfigascnCpwrHFgoOBQ==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.3.2", + "rc-util": "^5.25.2" + } + }, + "rc-collapse": { + "version": "3.7.2", + "resolved": "https://registry.npmjs.org/rc-collapse/-/rc-collapse-3.7.2.tgz", + "integrity": "sha512-ZRw6ipDyOnfLFySxAiCMdbHtb5ePAsB9mT17PA6y1mRD/W6KHRaZeb5qK/X9xDV1CqgyxMpzw0VdS74PCcUk4A==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.3.4", + "rc-util": "^5.27.0" + } + }, + "rc-dialog": { + "version": "9.3.4", + "resolved": "https://registry.npmjs.org/rc-dialog/-/rc-dialog-9.3.4.tgz", + "integrity": "sha512-975X3018GhR+EjZFbxA2Z57SX5rnu0G0/OxFgMMvZK4/hQWEm3MHaNvP4wXpxYDoJsp+xUvVW+GB9CMMCm81jA==", + "requires": { + "@babel/runtime": "^7.10.1", + "@rc-component/portal": "^1.0.0-8", + "classnames": "^2.2.6", + "rc-motion": "^2.3.0", + "rc-util": "^5.21.0" + } + }, + "rc-drawer": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/rc-drawer/-/rc-drawer-7.0.0.tgz", + "integrity": "sha512-ePcS4KtQnn57bCbVXazHN2iC8nTPCXlWEIA/Pft87Pd9U7ZeDkdRzG47jWG2/TAFXFlFltRAMcslqmUM8NPCGA==", + "requires": { + "@babel/runtime": "^7.10.1", + "@rc-component/portal": "^1.1.1", + "classnames": "^2.2.6", + "rc-motion": "^2.6.1", + "rc-util": "^5.36.0" + } + }, + "rc-dropdown": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rc-dropdown/-/rc-dropdown-4.1.0.tgz", + "integrity": "sha512-VZjMunpBdlVzYpEdJSaV7WM7O0jf8uyDjirxXLZRNZ+tAC+NzD3PXPEtliFwGzVwBBdCmGuSqiS9DWcOLxQ9tw==", + "requires": { + "@babel/runtime": "^7.18.3", + "@rc-component/trigger": "^1.7.0", + "classnames": "^2.2.6", + "rc-util": "^5.17.0" + } + }, + "rc-field-form": { + "version": "1.41.0", + "resolved": "https://registry.npmjs.org/rc-field-form/-/rc-field-form-1.41.0.tgz", + "integrity": "sha512-k9AS0wmxfJfusWDP/YXWTpteDNaQ4isJx9UKxx4/e8Dub4spFeZ54/EuN2sYrMRID/+hUznPgVZeg+Gf7XSYCw==", + "requires": { + "@babel/runtime": "^7.18.0", + "async-validator": "^4.1.0", + "rc-util": "^5.32.2" + } + }, + "rc-image": { + "version": "7.5.1", + "resolved": "https://registry.npmjs.org/rc-image/-/rc-image-7.5.1.tgz", + "integrity": "sha512-Z9loECh92SQp0nSipc0MBuf5+yVC05H/pzC+Nf8xw1BKDFUJzUeehYBjaWlxly8VGBZJcTHYri61Fz9ng1G3Ag==", + "requires": { + "@babel/runtime": "^7.11.2", + "@rc-component/portal": "^1.0.2", + "classnames": "^2.2.6", + "rc-dialog": "~9.3.4", + "rc-motion": "^2.6.2", + "rc-util": "^5.34.1" + } + }, + "rc-input": { + "version": "1.4.3", + "resolved": "https://registry.npmjs.org/rc-input/-/rc-input-1.4.3.tgz", + "integrity": "sha512-aHyQUAIRmTlOnvk5EcNqEpJ+XMtfMpYRAJayIlJfsvvH9cAKUWboh4egm23vgMA7E+c/qm4BZcnrDcA960GC1w==", + "requires": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-util": "^5.18.1" + } + }, + "rc-input-number": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/rc-input-number/-/rc-input-number-9.0.0.tgz", + "integrity": "sha512-RfcDBDdWFFetouWFXBA+WPEC8LzBXyngr9b+yTLVIygfFu7HiLRGn/s/v9wwno94X7KFvnb28FNynMGj9XJlDQ==", + "requires": { + "@babel/runtime": "^7.10.1", + "@rc-component/mini-decimal": "^1.0.1", + "classnames": "^2.2.5", + "rc-input": "~1.4.0", + "rc-util": "^5.28.0" + } + }, + "rc-mentions": { + "version": "2.10.1", + "resolved": "https://registry.npmjs.org/rc-mentions/-/rc-mentions-2.10.1.tgz", + "integrity": "sha512-72qsEcr/7su+a07ndJ1j8rI9n0Ka/ngWOLYnWMMv0p2mi/5zPwPrEDTt6Uqpe8FWjWhueDJx/vzunL6IdKDYMg==", + "requires": { + "@babel/runtime": "^7.22.5", + "@rc-component/trigger": "^1.5.0", + "classnames": "^2.2.6", + "rc-input": "~1.4.0", + "rc-menu": "~9.12.0", + "rc-textarea": "~1.6.1", + "rc-util": "^5.34.1" + } + }, + "rc-menu": { + "version": "9.12.4", + "resolved": "https://registry.npmjs.org/rc-menu/-/rc-menu-9.12.4.tgz", + "integrity": "sha512-t2NcvPLV1mFJzw4F21ojOoRVofK2rWhpKPx69q2raUsiHPDP6DDevsBILEYdsIegqBeSXoWs2bf6CueBKg3BFg==", + "requires": { + "@babel/runtime": "^7.10.1", + "@rc-component/trigger": "^1.17.0", + "classnames": "2.x", + "rc-motion": "^2.4.3", + "rc-overflow": "^1.3.1", + "rc-util": "^5.27.0" + } + }, + "rc-motion": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/rc-motion/-/rc-motion-2.9.0.tgz", + "integrity": "sha512-XIU2+xLkdIr1/h6ohPZXyPBMvOmuyFZQ/T0xnawz+Rh+gh4FINcnZmMT5UTIj6hgI0VLDjTaPeRd+smJeSPqiQ==", + "requires": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-util": "^5.21.0" + } + }, + "rc-notification": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/rc-notification/-/rc-notification-5.3.0.tgz", + "integrity": "sha512-WCf0uCOkZ3HGfF0p1H4Sgt7aWfipxORWTPp7o6prA3vxwtWhtug3GfpYls1pnBp4WA+j8vGIi5c2/hQRpGzPcQ==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.9.0", + "rc-util": "^5.20.1" + } + }, + "rc-overflow": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/rc-overflow/-/rc-overflow-1.3.2.tgz", + "integrity": "sha512-nsUm78jkYAoPygDAcGZeC2VwIg/IBGSodtOY3pMof4W3M9qRJgqaDYm03ZayHlde3I6ipliAxbN0RUcGf5KOzw==", + "requires": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.37.0" + } + }, + "rc-pagination": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/rc-pagination/-/rc-pagination-4.0.4.tgz", + "integrity": "sha512-GGrLT4NgG6wgJpT/hHIpL9nELv27A1XbSZzECIuQBQTVSf4xGKxWr6I/jhpRPauYEWEbWVw22ObG6tJQqwJqWQ==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.3.2", + "rc-util": "^5.38.0" + } + }, + "rc-picker": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/rc-picker/-/rc-picker-4.1.5.tgz", + "integrity": "sha512-dh2E9j7HomZW10RWIBsdyXs3geHkSslVqKTx3VZfmi9UEabiQrBBNKVIhqn2m0goia0dqyWJ4qRghAsBVLGzbw==", + "requires": { + "@babel/runtime": "^7.10.1", + "@rc-component/trigger": "^1.5.0", + "classnames": "^2.2.1", + "rc-overflow": "^1.3.2", + "rc-resize-observer": "^1.4.0", + "rc-util": "^5.38.1" + } + }, + "rc-progress": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/rc-progress/-/rc-progress-3.5.1.tgz", + "integrity": "sha512-V6Amx6SbLRwPin/oD+k1vbPrO8+9Qf8zW1T8A7o83HdNafEVvAxPV5YsgtKFP+Ud5HghLj33zKOcEHrcrUGkfw==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.6", + "rc-util": "^5.16.1" + } + }, + "rc-rate": { + "version": "2.12.0", + "resolved": "https://registry.npmjs.org/rc-rate/-/rc-rate-2.12.0.tgz", + "integrity": "sha512-g092v5iZCdVzbjdn28FzvWebK2IutoVoiTeqoLTj9WM7SjA/gOJIw5/JFZMRyJYYVe1jLAU2UhAfstIpCNRozg==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-util": "^5.0.1" + } + }, + "rc-resize-observer": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/rc-resize-observer/-/rc-resize-observer-1.4.0.tgz", + "integrity": "sha512-PnMVyRid9JLxFavTjeDXEXo65HCRqbmLBw9xX9gfC4BZiSzbLXKzW3jPz+J0P71pLbD5tBMTT+mkstV5gD0c9Q==", + "requires": { + "@babel/runtime": "^7.20.7", + "classnames": "^2.2.1", + "rc-util": "^5.38.0", + "resize-observer-polyfill": "^1.5.1" + } + }, + "rc-segmented": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/rc-segmented/-/rc-segmented-2.3.0.tgz", + "integrity": "sha512-I3FtM5Smua/ESXutFfb8gJ8ZPcvFR+qUgeeGFQHBOvRiRKyAk4aBE5nfqrxXx+h8/vn60DQjOt6i4RNtrbOobg==", + "requires": { + "@babel/runtime": "^7.11.1", + "classnames": "^2.2.1", + "rc-motion": "^2.4.4", + "rc-util": "^5.17.0" + } + }, + "rc-select": { + "version": "14.11.0", + "resolved": "https://registry.npmjs.org/rc-select/-/rc-select-14.11.0.tgz", + "integrity": "sha512-8J8G/7duaGjFiTXCBLWfh5P+KDWyA3KTlZDfV3xj/asMPqB2cmxfM+lH50wRiPIRsCQ6EbkCFBccPuaje3DHIg==", + "requires": { + "@babel/runtime": "^7.10.1", + "@rc-component/trigger": "^1.5.0", + "classnames": "2.x", + "rc-motion": "^2.0.1", + "rc-overflow": "^1.3.1", + "rc-util": "^5.16.1", + "rc-virtual-list": "^3.5.2" + } + }, + "rc-slider": { + "version": "10.5.0", + "resolved": "https://registry.npmjs.org/rc-slider/-/rc-slider-10.5.0.tgz", + "integrity": "sha512-xiYght50cvoODZYI43v3Ylsqiw14+D7ELsgzR40boDZaya1HFa1Etnv9MDkQE8X/UrXAffwv2AcNAhslgYuDTw==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.5", + "rc-util": "^5.27.0" + } + }, + "rc-steps": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/rc-steps/-/rc-steps-6.0.1.tgz", + "integrity": "sha512-lKHL+Sny0SeHkQKKDJlAjV5oZ8DwCdS2hFhAkIjuQt1/pB81M0cA0ErVFdHq9+jmPmFw1vJB2F5NBzFXLJxV+g==", + "requires": { + "@babel/runtime": "^7.16.7", + "classnames": "^2.2.3", + "rc-util": "^5.16.1" + } + }, + "rc-switch": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/rc-switch/-/rc-switch-4.1.0.tgz", + "integrity": "sha512-TI8ufP2Az9oEbvyCeVE4+90PDSljGyuwix3fV58p7HV2o4wBnVToEyomJRVyTaZeqNPAp+vqeo4Wnj5u0ZZQBg==", + "requires": { + "@babel/runtime": "^7.21.0", + "classnames": "^2.2.1", + "rc-util": "^5.30.0" + } + }, + "rc-table": { + "version": "7.39.0", + "resolved": "https://registry.npmjs.org/rc-table/-/rc-table-7.39.0.tgz", + "integrity": "sha512-7fHLMNsm/2DlGwyIMkdH2xIeRzb5I69bLsFaEVtX+gqmGhByy0wtOAgHkiOew3PtXozSJyh+iXifjLgQzWdczw==", + "requires": { + "@babel/runtime": "^7.10.1", + "@rc-component/context": "^1.4.0", + "classnames": "^2.2.5", + "rc-resize-observer": "^1.1.0", + "rc-util": "^5.37.0", + "rc-virtual-list": "^3.11.1" + } + }, + "rc-tabs": { + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/rc-tabs/-/rc-tabs-14.0.0.tgz", + "integrity": "sha512-lp1YWkaPnjlyhOZCPrAWxK6/P6nMGX/BAZcAC3nuVwKz0Byfp+vNnQKK8BRCP2g/fzu+SeB5dm9aUigRu3tRkQ==", + "requires": { + "@babel/runtime": "^7.11.2", + "classnames": "2.x", + "rc-dropdown": "~4.1.0", + "rc-menu": "~9.12.0", + "rc-motion": "^2.6.2", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.34.1" + } + }, + "rc-textarea": { + "version": "1.6.3", + "resolved": "https://registry.npmjs.org/rc-textarea/-/rc-textarea-1.6.3.tgz", + "integrity": "sha512-8k7+8Y2GJ/cQLiClFMg8kUXOOdvcFQrnGeSchOvI2ZMIVvX5a3zQpLxoODL0HTrvU63fPkRmMuqaEcOF9dQemA==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "^2.2.1", + "rc-input": "~1.4.0", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.27.0" + } + }, + "rc-tooltip": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/rc-tooltip/-/rc-tooltip-6.1.3.tgz", + "integrity": "sha512-HMSbSs5oieZ7XddtINUddBLSVgsnlaSb3bZrzzGWjXa7/B7nNedmsuz72s7EWFEro9mNa7RyF3gOXKYqvJiTcQ==", + "requires": { + "@babel/runtime": "^7.11.2", + "@rc-component/trigger": "^1.18.0", + "classnames": "^2.3.1" + } + }, + "rc-tree": { + "version": "5.8.5", + "resolved": "https://registry.npmjs.org/rc-tree/-/rc-tree-5.8.5.tgz", + "integrity": "sha512-PRfcZtVDNkR7oh26RuNe1hpw11c1wfgzwmPFL0lnxGnYefe9lDAO6cg5wJKIAwyXFVt5zHgpjYmaz0CPy1ZtKg==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-motion": "^2.0.1", + "rc-util": "^5.16.1", + "rc-virtual-list": "^3.5.1" + } + }, + "rc-tree-select": { + "version": "5.17.0", + "resolved": "https://registry.npmjs.org/rc-tree-select/-/rc-tree-select-5.17.0.tgz", + "integrity": "sha512-7sRGafswBhf7n6IuHyCEFCildwQIgyKiV8zfYyUoWfZEFdhuk7lCH+DN0aHt+oJrdiY9+6Io/LDXloGe01O8XQ==", + "requires": { + "@babel/runtime": "^7.10.1", + "classnames": "2.x", + "rc-select": "~14.11.0-0", + "rc-tree": "~5.8.1", + "rc-util": "^5.16.1" + } + }, + "rc-upload": { + "version": "4.5.2", + "resolved": "https://registry.npmjs.org/rc-upload/-/rc-upload-4.5.2.tgz", + "integrity": "sha512-QO3ne77DwnAPKFn0bA5qJM81QBjQi0e0NHdkvpFyY73Bea2NfITiotqJqVjHgeYPOJu5lLVR32TNGP084aSoXA==", + "requires": { + "@babel/runtime": "^7.18.3", + "classnames": "^2.2.5", + "rc-util": "^5.2.0" + } + }, + "rc-util": { + "version": "5.38.2", + "resolved": "https://registry.npmjs.org/rc-util/-/rc-util-5.38.2.tgz", + "integrity": "sha512-yRGRPKyi84H7NkRSP6FzEIYBdUt4ufdsmXUZ7qM2H5qoByPax70NnGPkfo36N+UKUnUBj2f2Q2eUbwYMuAsIOQ==", + "requires": { + "@babel/runtime": "^7.18.3", + "react-is": "^18.2.0" + }, + "dependencies": { + "react-is": { + "version": "18.2.0", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.2.0.tgz", + "integrity": "sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==" + } + } + }, + "rc-virtual-list": { + "version": "3.11.4", + "resolved": "https://registry.npmjs.org/rc-virtual-list/-/rc-virtual-list-3.11.4.tgz", + "integrity": "sha512-NbBi0fvyIu26gP69nQBiWgUMTPX3mr4FcuBQiVqagU0BnuX8WQkiivnMs105JROeuUIFczLrlgUhLQwTWV1XDA==", + "requires": { + "@babel/runtime": "^7.20.0", + "classnames": "^2.2.6", + "rc-resize-observer": "^1.0.0", + "rc-util": "^5.36.0" + } + }, "react": { "version": "18.2.0", "resolved": "https://registry.npmjs.org/react/-/react-18.2.0.tgz", @@ -28801,6 +30354,11 @@ "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==" }, + "resize-observer-polyfill": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/resize-observer-polyfill/-/resize-observer-polyfill-1.5.1.tgz", + "integrity": "sha512-LwZrotdHOo12nQuZlHEmtuXdqGoOD0OhaxopaNFxWzInpEgaLWoVuAMbTzixuosCx2nEG58ngzW3vxdWoxIgdg==" + }, "resolve": { "version": "1.22.8", "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", @@ -29021,6 +30579,14 @@ "ajv-keywords": "^3.5.2" } }, + "scroll-into-view-if-needed": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/scroll-into-view-if-needed/-/scroll-into-view-if-needed-3.1.0.tgz", + "integrity": "sha512-49oNpRjWRvnU8NyGVmUaYG4jtTkNonFZI86MmGRDqBphEK2EXT9gdEUoQPZhuBM8yWHxCWbobltqYO5M4XrUvQ==", + "requires": { + "compute-scroll-into-view": "^3.0.2" + } + }, "select-hose": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/select-hose/-/select-hose-2.0.0.tgz", @@ -29451,6 +31017,11 @@ "safe-buffer": "~5.2.0" } }, + "string-convert": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/string-convert/-/string-convert-0.2.1.tgz", + "integrity": "sha512-u/1tdPl4yQnPBjnVrmdLo9gtuLvELKsAoRapekWggdiQNvvvum+jYF329d84NAa660KQw7pB2n36KrIKVoXa3A==" + }, "string-length": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/string-length/-/string-length-4.0.2.tgz", @@ -29614,6 +31185,11 @@ "postcss-selector-parser": "^6.0.4" } }, + "stylis": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/stylis/-/stylis-4.3.1.tgz", + "integrity": "sha512-EQepAV+wMsIaGVGX1RECzgrcqRRU/0sYOHkeLsZ3fzHaHXZy4DaOOX0vOlGQdlsjkh3mFHAIlVimpwAs4dslyQ==" + }, "sucrase": { "version": "3.35.0", "resolved": "https://registry.npmjs.org/sucrase/-/sucrase-3.35.0.tgz", @@ -29913,6 +31489,11 @@ "resolved": "https://registry.npmjs.org/throat/-/throat-6.0.2.tgz", "integrity": "sha512-WKexMoJj3vEuK0yFEapj8y64V0A6xcuPuK9Gt1d0R+dzCSJc0lHqQytAbSB4cDAK0dWh4T0E2ETkoLE2WZ41OQ==" }, + "throttle-debounce": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/throttle-debounce/-/throttle-debounce-5.0.0.tgz", + "integrity": "sha512-2iQTSgkkc1Zyk0MeVrt/3BvuOXYPl/R8Z0U2xxo9rjwNciaHDG3R+Lm6dh4EeUci49DanvBnuqI6jshoQQRGEg==" + }, "thunky": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/thunky/-/thunky-1.1.0.tgz", @@ -29936,6 +31517,11 @@ "is-number": "^7.0.0" } }, + "toggle-selection": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", + "integrity": "sha512-BiZS+C1OS8g/q2RRbJmy59xpyghNBqrr6k5L/uKBGRsTfxmu3ffiRnd8mlGPUVayg8pvfi5urfnu8TU7DVOkLQ==" + }, "toidentifier": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz", diff --git a/frontend/package.json b/frontend/package.json index 3e26ab42..ad979907 100644 --- a/frontend/package.json +++ b/frontend/package.json @@ -3,6 +3,7 @@ "version": "0.1.0", "private": true, "dependencies": { + "@ant-design/icons": "^5.3.1", "@azure/msal-browser": "^3.10.0", "@azure/msal-react": "^2.0.12", "@babel/plugin-proposal-private-property-in-object": "^7.21.11", @@ -13,6 +14,7 @@ "@types/node": "^16.18.82", "@types/react": "^18.2.56", "@types/react-dom": "^18.2.19", + "antd": "^5.14.2", "axios": "^1.6.7", "react": "^18.2.0", "react-dom": "^18.2.0", diff --git a/frontend/public/index.html b/frontend/public/index.html index aa069f27..b9226e11 100644 --- a/frontend/public/index.html +++ b/frontend/public/index.html @@ -10,34 +10,14 @@ content="Web site created using create-react-app" /> - + - - React App + Pidgeon
    - diff --git a/frontend/src/@types/requests.d.ts b/frontend/src/@types/requests.d.ts new file mode 100644 index 00000000..ac24a756 --- /dev/null +++ b/frontend/src/@types/requests.d.ts @@ -0,0 +1,31 @@ + + + +/** + * Routes used to make API calls + */ +export enum ApiRoutes { + COURSES = "api/courses", // example + TEST = "api/test" +} + + + +/** + * the body of the POST requests + */ +export type POST_Requests = { + [ApiRoutes.COURSES]: { + name: string + } +} + +/** + * the body of the PUT requests + */ +export type PUT_Requests = { + [ApiRoutes.COURSES]: { + name: string + } +} + diff --git a/frontend/src/@types/routes.ts b/frontend/src/@types/routes.ts new file mode 100644 index 00000000..1109638a --- /dev/null +++ b/frontend/src/@types/routes.ts @@ -0,0 +1,17 @@ + + +/** + * Routes used in the app + */ +export enum AppRoutes { + HOME = "/", + COURSES = "/courses", + DASHBOARD = "/dashboard", + COURSE = "/courses/:id", + LOGIN = "/login", + LOGOUT = "/logout", + PROFILE = "/profile", + ERROR = "/error", + NOT_FOUND = "/not-found" +} + diff --git a/frontend/src/@types/types.ts b/frontend/src/@types/types.ts index b92376e8..fd803f10 100644 --- a/frontend/src/@types/types.ts +++ b/frontend/src/@types/types.ts @@ -1,46 +1,14 @@ -/** - * Routes used to make API calls - */ -export enum ApiRoutes { - COURSES = "api/courses", // example - TEST = "api/test" -} - -/** - * Routes used in the app - */ -export enum AppRoutes { - HOME = "/", - COURSES = "/courses", - DASHBOARD = "/dashboard", - COURSE = "/courses/:id", - LOGIN = "/login", - LOGOUT = "/logout", - PROFILE = "/profile", - ERROR = "/error", - NOT_FOUND = "/not-found" +export enum Themes { + LIGHT = "light", + DARK = "dark", + DODONA = "dodona" } - - -/** - * the body of the POST requests - */ -export type POST_Requests = { - [ApiRoutes.COURSES]: { - name: string - } +export enum Language { + NL = "nl", + EN = "en" } - -/** - * the body of the PUT requests - */ -export type PUT_Requests = { - [ApiRoutes.COURSES]: { - name: string - } -} \ No newline at end of file diff --git a/frontend/src/App.tsx b/frontend/src/App.tsx index 901a0415..5a9649bd 100644 --- a/frontend/src/App.tsx +++ b/frontend/src/App.tsx @@ -3,29 +3,31 @@ import { IPublicClientApplication } from "@azure/msal-browser" import { MsalProvider } from "@azure/msal-react" import { useNavigate } from "react-router-dom" import CustomNavigation from "./auth/CustomNavigation" -import Nav from "./components/navigationBar/Nav" -import './i18n/config'; +import Layout from "./components/layout/nav/Layout" +import "./i18n/config" +import ThemeProvider from "./theme/ThemeProvider" +import { AppProvider } from "./providers/AppProvider" type AppProps = { pca: IPublicClientApplication } function App({ pca }: AppProps) { - - const navigate = useNavigate(); - const navigationClient = new CustomNavigation(navigate); - pca.setNavigationClient(navigationClient); - + const navigate = useNavigate() + const navigationClient = new CustomNavigation(navigate) + pca.setNavigationClient(navigationClient) return (
    -
    - - - -
    + + + + + + + + +
    ) } diff --git a/frontend/src/components/Logo.tsx b/frontend/src/components/Logo.tsx new file mode 100644 index 00000000..d0958709 --- /dev/null +++ b/frontend/src/components/Logo.tsx @@ -0,0 +1,14 @@ +import { Typography } from "antd" +import { TitleProps } from "antd/es/typography/Title" +import { FC } from "react" + + + +const Logo:FC = (props) => { + + + + return Pidgeon +} + +export default Logo \ No newline at end of file diff --git a/frontend/src/components/layout/nav/AuthNav.tsx b/frontend/src/components/layout/nav/AuthNav.tsx new file mode 100644 index 00000000..5a9341a2 --- /dev/null +++ b/frontend/src/components/layout/nav/AuthNav.tsx @@ -0,0 +1,74 @@ +import { useAccount } from "@azure/msal-react" +import { Dropdown, MenuProps, Typography } from "antd" +import { useTranslation } from "react-i18next" +import { BgColorsOutlined, DownOutlined, LogoutOutlined } from "@ant-design/icons" +import { msalInstance } from "../../../index" +import { Themes } from "../../../@types/types" +import useApp from "../../../hooks/useApp" + +const AuthNav = () => { + const { t } = useTranslation() + const app = useApp() + const auth = useAccount() + + const items: MenuProps["items"] = [ + { + key: "theme", + label: t("nav.theme"), + icon: , + children: [ + { + key: Themes.LIGHT, + label: t("nav.light"), + }, + { + key: Themes.DARK, + label: t("nav.dark"), + }, + { + key: Themes.DODONA, + label: "Dodona", + + }, + ] + }, + { + key: "logout", + label: t("nav.logout"), + icon: , + }, + ] + + const handleDropdownClick: MenuProps["onClick"] = (menu) => { + console.log(menu.keyPath,menu.key); + switch (menu.key) { + case "logout": + console.log(auth); + msalInstance.logoutPopup({ + account: auth, + }) + break + case Themes.DARK: + case Themes.DODONA: + case Themes.LIGHT: + app.setTheme(menu.key as Themes) + break + } + } + + return ( +
    + + {auth!.name} + +
    + ) +} + +export default AuthNav diff --git a/frontend/src/components/layout/nav/Layout.tsx b/frontend/src/components/layout/nav/Layout.tsx new file mode 100644 index 00000000..8e7b22ec --- /dev/null +++ b/frontend/src/components/layout/nav/Layout.tsx @@ -0,0 +1,31 @@ +import { AuthenticatedTemplate, UnauthenticatedTemplate } from "@azure/msal-react" +import UnauthNav from "./UnauthNav" +import AuthNav from "./AuthNav" +import { FC, PropsWithChildren } from "react" +import { Layout as AntLayout } from "antd" +import Logo from "../../Logo" + +const Layout: FC = ({ children }) => { + return ( +
    + + + + + + + + + + + {children} + + + +
    + ) +} + +export default Layout diff --git a/frontend/src/components/navigationBar/UnauthNav.tsx b/frontend/src/components/layout/nav/UnauthNav.tsx similarity index 53% rename from frontend/src/components/navigationBar/UnauthNav.tsx rename to frontend/src/components/layout/nav/UnauthNav.tsx index fabfb276..84b01434 100644 --- a/frontend/src/components/navigationBar/UnauthNav.tsx +++ b/frontend/src/components/layout/nav/UnauthNav.tsx @@ -1,5 +1,6 @@ -import { Trans, useTranslation } from "react-i18next"; -import { msalInstance } from "../../index" +import { useTranslation } from "react-i18next"; +import { msalInstance } from "../../../index" +import { Button } from "antd"; const UnauthNav = () => { const { t } = useTranslation(); @@ -12,9 +13,7 @@ const UnauthNav = () => { } return ( -
    - -
    + ) } diff --git a/frontend/src/components/navigationBar/AuthNav.tsx b/frontend/src/components/navigationBar/AuthNav.tsx deleted file mode 100644 index 2e40281f..00000000 --- a/frontend/src/components/navigationBar/AuthNav.tsx +++ /dev/null @@ -1,14 +0,0 @@ -import { useAccount } from "@azure/msal-react" - - -const AuthNav = () => { - const auth = useAccount() - - - return
    - {auth!.name} -
    - -} - -export default AuthNav \ No newline at end of file diff --git a/frontend/src/components/navigationBar/Nav.tsx b/frontend/src/components/navigationBar/Nav.tsx deleted file mode 100644 index f9402f4b..00000000 --- a/frontend/src/components/navigationBar/Nav.tsx +++ /dev/null @@ -1,27 +0,0 @@ -import { AuthenticatedTemplate, UnauthenticatedTemplate } from "@azure/msal-react" -import UnauthNav from "./UnauthNav" -import AuthNav from "./AuthNav" -import { FC, PropsWithChildren } from "react" - -const Nav: FC = ({ children }) => { - return ( -
    -
    - - - - - - - -
    - -
    - {children} - -
    -
    - ) -} - -export default Nav diff --git a/frontend/src/hooks/useApp.tsx b/frontend/src/hooks/useApp.tsx new file mode 100644 index 00000000..c0870c57 --- /dev/null +++ b/frontend/src/hooks/useApp.tsx @@ -0,0 +1,11 @@ +import { useContext } from "react" +import { AppContext } from "../providers/AppProvider" + + + +const useApp = () => { + const appContext = useContext(AppContext) + return appContext +} + +export default useApp diff --git a/frontend/src/i18n/en/translation.json b/frontend/src/i18n/en/translation.json index 07bf14bd..f2cd990f 100644 --- a/frontend/src/i18n/en/translation.json +++ b/frontend/src/i18n/en/translation.json @@ -1,5 +1,10 @@ { - "navBar": { - "login": "Login" + "nav": { + "login": "Login", + "logout": "Logout", + "accountSwitch": "Switch Account", + "theme": "Theme", + "dark": "Dark", + "light": "Light" } } \ No newline at end of file diff --git a/frontend/src/i18n/nl/translation.json b/frontend/src/i18n/nl/translation.json index 8bc30066..26646f80 100644 --- a/frontend/src/i18n/nl/translation.json +++ b/frontend/src/i18n/nl/translation.json @@ -1,5 +1,10 @@ { - "navBar": { - "login": "Inloggen" + "nav": { + "login": "Aanmelden", + "logout": "Afmelden", + "accountSwitch": "Account wisselen", + "theme": "Stijl", + "dark": "Donker", + "light": "Licht" } } \ No newline at end of file diff --git a/frontend/src/pages/index/Home.tsx b/frontend/src/pages/index/Home.tsx index d2d31022..781b589e 100644 --- a/frontend/src/pages/index/Home.tsx +++ b/frontend/src/pages/index/Home.tsx @@ -1,39 +1,14 @@ -import { AuthenticatedTemplate, UnauthenticatedTemplate } from "@azure/msal-react" -import { Link } from "react-router-dom" -import { msalInstance } from "../../index"; -const Home = () => { - - const handleLogin = async () => { - try { - await msalInstance.loginPopup(); // Initiate popup login - } catch (error) { - console.error(error) - } - } +const Home = () => { return ( <>

    HOME

    - -
    - - Request Profile Information - -
    -
    - - -
    -

    You're not signed in!

    - + + -
    -
    + ) } diff --git a/frontend/src/pages/profile/Profile.tsx b/frontend/src/pages/profile/Profile.tsx index 85151d88..474abfd4 100644 --- a/frontend/src/pages/profile/Profile.tsx +++ b/frontend/src/pages/profile/Profile.tsx @@ -1,11 +1,8 @@ import { useEffect, useState } from "react"; -// Msal imports import { MsalAuthenticationTemplate, useMsal,MsalAuthenticationResult } from "@azure/msal-react"; import { InteractionStatus, InteractionType, InteractionRequiredAuthError, AccountInfo } from "@azure/msal-browser"; import { loginRequest } from "../../auth/AuthConfig"; - -// Sample app imports import { ProfileData, GraphData } from "./components/ProfileData"; import { callMsGraph } from "../../auth/MsGraphApiCall"; diff --git a/frontend/src/pages/profile/components/ProfileData.tsx b/frontend/src/pages/profile/components/ProfileData.tsx index 7f1d7c84..17468a7c 100644 --- a/frontend/src/pages/profile/components/ProfileData.tsx +++ b/frontend/src/pages/profile/components/ProfileData.tsx @@ -1,5 +1,5 @@ import { useState } from "react" -import { ApiRoutes } from "../../../@types/types" +import { ApiRoutes } from "../../../@types/requests.d" import apiCall from "../../../util/apiFetch" export type GraphData = { diff --git a/frontend/src/providers/AppProvider.tsx b/frontend/src/providers/AppProvider.tsx new file mode 100644 index 00000000..91493e04 --- /dev/null +++ b/frontend/src/providers/AppProvider.tsx @@ -0,0 +1,42 @@ +import { FC, PropsWithChildren, createContext, useEffect, useState } from "react" +import { Language, Themes } from "../@types/types" + +export type AppContextT = { + theme: Themes + language: Language + setTheme: (theme: Themes) => void + setLanguage: (language: Language) => void +} + +const AppContext = createContext({} as AppContextT) + +const AppProvider: FC = ({ children }) => { + const [theme, setTheme] = useState(Themes.DARK) + const [language, setLanguage] = useState(Language.NL) + + useEffect(() => { + const localTheme = (window.localStorage.getItem("theme") as Themes) ?? Themes.DARK + const localLanguage =( window.localStorage.getItem("i18n") as Language) ?? Language.NL + setTheme(localTheme) + setLanguage(localLanguage) + + document.body.classList.add(localTheme + "-theme") + + }, []) + + const handleSetTheme = (theme: Themes) => { + setTheme(theme) + document.body.classList.remove(Themes.LIGHT + "-theme", Themes.DARK + "-theme", Themes.DODONA + "-theme") + document.body.classList.add(theme + "-theme") + window.localStorage.setItem("theme", theme) + } + + const handleSetLanguage = (language: Language) => { + setLanguage(language) + window.localStorage.setItem("i18n", language) + } + + return {children} +} + +export { AppProvider, AppContext } diff --git a/frontend/src/router/AppRouter.tsx b/frontend/src/router/AppRouter.tsx index 8bb8399e..b1b8c438 100644 --- a/frontend/src/router/AppRouter.tsx +++ b/frontend/src/router/AppRouter.tsx @@ -1,8 +1,8 @@ import { Routes, Route } from 'react-router-dom'; import Home from '../pages/index/Home'; -import { AppRoutes } from '../@types/types'; import Dashboard from '../pages/dashboard/Dashboard'; import Profile from '../pages/profile/Profile'; +import { AppRoutes } from '../@types/routes'; diff --git a/frontend/src/styles.css b/frontend/src/styles.css index 0100286d..f0efc281 100644 --- a/frontend/src/styles.css +++ b/frontend/src/styles.css @@ -3,4 +3,10 @@ body, html { padding:0; margin: 0; + width: 100%; + height: 100%; +} + +.dodona-theme .ant-layout-header .ant-typography { + color: #00325a } \ No newline at end of file diff --git a/frontend/src/theme/ThemeProvider.tsx b/frontend/src/theme/ThemeProvider.tsx new file mode 100644 index 00000000..62aa3cf5 --- /dev/null +++ b/frontend/src/theme/ThemeProvider.tsx @@ -0,0 +1,25 @@ +import { ConfigProvider, ThemeConfig } from "antd" +import { FC, PropsWithChildren } from "react" +import useApp from "../hooks/useApp" +import {darkTheme} from "./themes/dark" +import {lightTheme} from "./themes/light" +import { Themes } from "../@types/types" +import { dodonaTheme } from "./themes/dodona" + +const appThemes:Record = { + light: lightTheme, + dark: darkTheme, + dodona: dodonaTheme +} + +const ThemeProvider: FC = ({ children }) => { + const {theme} = useApp() + const selectedTheme = appThemes[theme] ?? appThemes.dark + + + return + {children} + +} + +export default ThemeProvider diff --git a/frontend/src/theme/themes/dark.ts b/frontend/src/theme/themes/dark.ts new file mode 100644 index 00000000..77350ce7 --- /dev/null +++ b/frontend/src/theme/themes/dark.ts @@ -0,0 +1,19 @@ +import { theme } from 'antd'; +import { ThemeConfig } from 'antd/es/config-provider'; + +export const darkTheme: ThemeConfig = { + algorithm: theme.darkAlgorithm , + token: { + fontFamily: "'Exo 2', sans-serif", + colorTextBase:"#efefef", + colorTextHeading: "#f0f0f0", + + }, + components: { + Layout: { + headerBg: "#1b1b1B", + headerHeight: 48, + + } + } +}; diff --git a/frontend/src/theme/themes/dodona.ts b/frontend/src/theme/themes/dodona.ts new file mode 100644 index 00000000..dc5faa6f --- /dev/null +++ b/frontend/src/theme/themes/dodona.ts @@ -0,0 +1,22 @@ +import { theme } from 'antd'; +import { ThemeConfig } from 'antd/es/config-provider'; + +export const dodonaTheme: ThemeConfig = { + algorithm: theme.darkAlgorithm , + token: { + fontFamily: "'Exo 2', sans-serif", + colorBgLayout: '#3c3b3f', + colorTextHeading: "#00325a", + colorPrimary: "#00497F" + }, + components: { + Layout: { + headerBg: "#9ccaff", + headerHeight: 48, + + }, + Button: { + primaryColor: "#D0E4FF" + }, + } +}; diff --git a/frontend/src/theme/themes/light.ts b/frontend/src/theme/themes/light.ts new file mode 100644 index 00000000..13d7149a --- /dev/null +++ b/frontend/src/theme/themes/light.ts @@ -0,0 +1,16 @@ +import { theme } from 'antd'; +import { ThemeConfig } from 'antd/es/config-provider'; + +export const lightTheme: ThemeConfig = { + algorithm: theme.defaultAlgorithm, + token: { + colorBgElevated: "#FBFBFA", + }, + components: { + Layout: { + headerBg: "#E9E9EA", + headerHeight: 48, + }, + + } +}; diff --git a/frontend/src/util/apiFetch.ts b/frontend/src/util/apiFetch.ts index cecf882e..4c7c98c5 100644 --- a/frontend/src/util/apiFetch.ts +++ b/frontend/src/util/apiFetch.ts @@ -1,4 +1,4 @@ -import { ApiRoutes, POST_Requests, PUT_Requests } from "../@types/types"; +import { ApiRoutes, POST_Requests, PUT_Requests } from "../@types/requests"; import axios, { AxiosResponse } from "axios"; import {msalInstance} from "../index"; import { AxiosRequestConfig } from "axios"; From e3af3a5f5ff69c9033bcc892291faf604f22b401 Mon Sep 17 00:00:00 2001 From: usserwoutV2 Date: Thu, 29 Feb 2024 22:33:19 +0100 Subject: [PATCH 12/40] Added i18n dropdown --- frontend/src/components/layout/nav/Layout.tsx | 35 +++++++++++++++---- frontend/src/i18n/config.ts | 1 - frontend/src/providers/AppProvider.tsx | 6 ++++ frontend/src/styles.css | 7 +++- frontend/src/theme/ThemeProvider.tsx | 14 ++++++-- 5 files changed, 52 insertions(+), 11 deletions(-) diff --git a/frontend/src/components/layout/nav/Layout.tsx b/frontend/src/components/layout/nav/Layout.tsx index 8e7b22ec..06f054f9 100644 --- a/frontend/src/components/layout/nav/Layout.tsx +++ b/frontend/src/components/layout/nav/Layout.tsx @@ -2,15 +2,33 @@ import { AuthenticatedTemplate, UnauthenticatedTemplate } from "@azure/msal-reac import UnauthNav from "./UnauthNav" import AuthNav from "./AuthNav" import { FC, PropsWithChildren } from "react" -import { Layout as AntLayout } from "antd" +import { Layout as AntLayout, Button, Dropdown, MenuProps, Typography } from "antd" import Logo from "../../Logo" +import { GlobalOutlined } from "@ant-design/icons" +import useApp from "../../../hooks/useApp" +import { Language } from "../../../@types/types" + +const items: MenuProps["items"] = [ + { + key: Language.EN, + label: "English", + }, + { + key: Language.NL, + label: "Nederlands", + }, +] const Layout: FC = ({ children }) => { + const app = useApp() + + const languageChange: MenuProps["onClick"] = (props) => { + app.setLanguage(props.key as Language) + } + return ( -
    - +
    + @@ -18,8 +36,13 @@ const Layout: FC = ({ children }) => { + + + {app.language} + + - + {children} diff --git a/frontend/src/i18n/config.ts b/frontend/src/i18n/config.ts index 348ffa8f..6c408b28 100644 --- a/frontend/src/i18n/config.ts +++ b/frontend/src/i18n/config.ts @@ -4,7 +4,6 @@ import translation_en from "./en/translation.json" import translation_nl from "./nl/translation.json" i18next.use(initReactI18next).init({ - lng: 'nl', // if you're using a language detector, do not define the lng option debug: true, resources: { en: { diff --git a/frontend/src/providers/AppProvider.tsx b/frontend/src/providers/AppProvider.tsx index 91493e04..79bf52aa 100644 --- a/frontend/src/providers/AppProvider.tsx +++ b/frontend/src/providers/AppProvider.tsx @@ -1,5 +1,6 @@ import { FC, PropsWithChildren, createContext, useEffect, useState } from "react" import { Language, Themes } from "../@types/types" +import { useTranslation } from "react-i18next" export type AppContextT = { theme: Themes @@ -11,6 +12,8 @@ export type AppContextT = { const AppContext = createContext({} as AppContextT) const AppProvider: FC = ({ children }) => { + const { i18n } = useTranslation() + const [theme, setTheme] = useState(Themes.DARK) const [language, setLanguage] = useState(Language.NL) @@ -19,6 +22,7 @@ const AppProvider: FC = ({ children }) => { const localLanguage =( window.localStorage.getItem("i18n") as Language) ?? Language.NL setTheme(localTheme) setLanguage(localLanguage) + i18n.changeLanguage(localLanguage) document.body.classList.add(localTheme + "-theme") @@ -34,6 +38,8 @@ const AppProvider: FC = ({ children }) => { const handleSetLanguage = (language: Language) => { setLanguage(language) window.localStorage.setItem("i18n", language) + i18n.changeLanguage(language) + } return {children} diff --git a/frontend/src/styles.css b/frontend/src/styles.css index f0efc281..47dc1c21 100644 --- a/frontend/src/styles.css +++ b/frontend/src/styles.css @@ -7,6 +7,11 @@ body, html { height: 100%; } -.dodona-theme .ant-layout-header .ant-typography { +.dodona-theme .ant-layout-header .ant-typography,.dodona-theme .ant-layout-header .ant-btn { color: #00325a +} + +.dodona-theme .ant-layout-header .ant-btn:hover { + color: #00325a; + background-color: transparent; } \ No newline at end of file diff --git a/frontend/src/theme/ThemeProvider.tsx b/frontend/src/theme/ThemeProvider.tsx index 62aa3cf5..47cf6afa 100644 --- a/frontend/src/theme/ThemeProvider.tsx +++ b/frontend/src/theme/ThemeProvider.tsx @@ -3,8 +3,16 @@ import { FC, PropsWithChildren } from "react" import useApp from "../hooks/useApp" import {darkTheme} from "./themes/dark" import {lightTheme} from "./themes/light" -import { Themes } from "../@types/types" +import { Language, Themes } from "../@types/types" import { dodonaTheme } from "./themes/dodona" +import nlNL from 'antd/locale/nl_NL'; +import enUS from 'antd/locale/en_US'; + + +const i18n_locale = { + [Language.NL]: nlNL, + [Language.EN]: enUS +} const appThemes:Record = { light: lightTheme, @@ -13,11 +21,11 @@ const appThemes:Record = { } const ThemeProvider: FC = ({ children }) => { - const {theme} = useApp() + const {theme,language} = useApp() const selectedTheme = appThemes[theme] ?? appThemes.dark - return + return {children} } From 9f971d0a60c3a084639da5c625ec94ec8d7bbb82 Mon Sep 17 00:00:00 2001 From: Aqua-sc <108478185+Aqua-sc@users.noreply.github.com> Date: Thu, 29 Feb 2024 22:51:34 +0100 Subject: [PATCH 13/40] fixed some issues with UserEntity&Repo --- .../java/com/ugent/pidgeon/postgre/models/UserEntity.java | 6 +++++- .../ugent/pidgeon/postgre/repository/UserRepository.java | 3 ++- backend/app/src/main/resources/application.properties | 2 +- docker-compose.yaml | 2 +- 4 files changed, 9 insertions(+), 4 deletions(-) diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java index bd3251be..a4a77a28 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java @@ -4,13 +4,13 @@ import jakarta.persistence.*; @Entity +@Table(name = "users") public class UserEntity { private long id; private String name; private String surname; private String email; - @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "user_id", nullable = false) @@ -18,6 +18,10 @@ public long getId() { return id; } + public void setId(long id) { + this.id = id; + } + @Column(name = "name", nullable=false) public String getName() { return name; diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java index c686d37a..e262c7f3 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java @@ -1,10 +1,11 @@ package com.ugent.pidgeon.postgre.repository; import com.ugent.pidgeon.model.User; +import com.ugent.pidgeon.postgre.models.UserEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository -public interface UserRepository extends JpaRepository { +public interface UserRepository extends JpaRepository { } diff --git a/backend/app/src/main/resources/application.properties b/backend/app/src/main/resources/application.properties index ce1390e3..69c60a6b 100644 --- a/backend/app/src/main/resources/application.properties +++ b/backend/app/src/main/resources/application.properties @@ -1,6 +1,6 @@ spring.datasource.url=jdbc:postgresql://localhost:5432/pidgeon_db spring.datasource.username=admin -spring.datasource.password=admin +spring.datasource.password=root spring.jpa.show-sql=true ## Hibernate Properties diff --git a/docker-compose.yaml b/docker-compose.yaml index 8a2c5a4f..42e9d046 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -15,7 +15,7 @@ services: ports: - 8080:8080 environment: - - 'POSTGRES_DB=pidegon_db' + - 'POSTGRES_DB=pidgeon_db' networks: - spring-postgres restart: always From 9b8ddbb35163864cba1511cae7b47cc23375f482 Mon Sep 17 00:00:00 2001 From: Arthur Werbrouck Date: Fri, 1 Mar 2024 10:56:51 +0100 Subject: [PATCH 14/40] postgres spring fix --- docker-compose.yaml | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/docker-compose.yaml b/docker-compose.yaml index 8a2c5a4f..697d077a 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -11,23 +11,28 @@ services: - ./certbot/www/:/var/www/certbot/:ro backend: container_name: spring_container + image: 'docker-spring-boot-postgres:latest' build: backend/app/ + depends_on: + - postgres ports: - 8080:8080 environment: - - 'POSTGRES_DB=pidegon_db' + - SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/pidgeon + - SPRING_DATASOURCE_USERNAME=pidgeon + - SPRING_DATASOURCE_PASSWORD=admin + - SPRING_JPA_HIBERNATE_DDL_AUTO=update networks: - spring-postgres restart: always postgres: - container_name: pg_container + container_name: db image: 'postgres:latest' secrets: - db-password environment: - - 'POSTGRES_PASSWORD=/run/secrets/db_password' - - 'POSTGRES_DB=pidgeon_db' - - 'POSTGRES_USER=admin' + - 'POSTGRES_PASSWORD=admin' + - 'POSTGRES_USER=pidgeon' ports: - '5432:5432' volumes: From 14799ac703eda77afe2b8e70fa15e4bb781f4985 Mon Sep 17 00:00:00 2001 From: Aqua-sc <108478185+Aqua-sc@users.noreply.github.com> Date: Fri, 1 Mar 2024 11:20:22 +0100 Subject: [PATCH 15/40] temp. commented out some not working code --- backend/app/build.gradle | 3 ++- .../pidgeon/controllers/JpaUserController.java | 14 +++++++------- .../app/src/main/resources/application.properties | 7 ++++--- .../com/ugent/pidgeon/PidgeonApplicationTests.java | 4 ++-- 4 files changed, 15 insertions(+), 13 deletions(-) diff --git a/backend/app/build.gradle b/backend/app/build.gradle index fb1a8537..e95a8f82 100644 --- a/backend/app/build.gradle +++ b/backend/app/build.gradle @@ -1,4 +1,4 @@ -plugins { + plugins { id 'java' id 'org.springframework.boot' version '3.2.2' id 'io.spring.dependency-management' version '1.1.4' @@ -33,6 +33,7 @@ dependencies { implementation 'com.auth0:jwks-rsa:0.18.0' implementation 'javax.servlet:javax.servlet-api:4.0.1' implementation 'org.springframework.boot:spring-boot-starter-data-jpa' + runtimeOnly 'org.postgresql:postgresql' implementation "org.springframework.boot:spring-boot-devtools" testImplementation 'org.springframework.boot:spring-boot-starter-test' diff --git a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java index 4bf0780b..a66b20e2 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java @@ -8,11 +8,11 @@ @RestController public class JpaUserController { - /*@Autowired - private UserRepository userRepository;*/ - - @GetMapping("/api/users") - public String getUsers() { - return "kaas+: "; - } +// @Autowired +// private UserRepository userRepository; +// +// @GetMapping("/api/users") +// public String getUsers() { +// return "kaas+: "; +// } } diff --git a/backend/app/src/main/resources/application.properties b/backend/app/src/main/resources/application.properties index 69c60a6b..47e0ead4 100644 --- a/backend/app/src/main/resources/application.properties +++ b/backend/app/src/main/resources/application.properties @@ -1,7 +1,8 @@ -spring.datasource.url=jdbc:postgresql://localhost:5432/pidgeon_db -spring.datasource.username=admin -spring.datasource.password=root +spring.datasource.url = jdbc:postgresql://db:5432/pidgeon +spring.datasource.username = pidgeon +spring.datasource.password = admin spring.jpa.show-sql=true +spring.jpa.database=postgresql ## Hibernate Properties # The SQL dialect makes Hibernate generate better SQL for the chosen database diff --git a/backend/app/src/test/java/com/ugent/pidgeon/PidgeonApplicationTests.java b/backend/app/src/test/java/com/ugent/pidgeon/PidgeonApplicationTests.java index 6b5f5d03..85846c69 100644 --- a/backend/app/src/test/java/com/ugent/pidgeon/PidgeonApplicationTests.java +++ b/backend/app/src/test/java/com/ugent/pidgeon/PidgeonApplicationTests.java @@ -6,8 +6,8 @@ @SpringBootTest class PidgeonApplicationTests { - @Test + /*@Test void contextLoads() { - } + }*/ } From 80b8acf36db58f870a7c8ec1db2eaf184da2502a Mon Sep 17 00:00:00 2001 From: usserwoutV2 Date: Fri, 1 Mar 2024 14:37:24 +0100 Subject: [PATCH 16/40] Fixed wrong button color --- frontend/src/components/Logo.tsx | 5 ++++- frontend/src/pages/index/Home.tsx | 1 - frontend/src/styles.css | 11 ++++++++--- 3 files changed, 12 insertions(+), 5 deletions(-) diff --git a/frontend/src/components/Logo.tsx b/frontend/src/components/Logo.tsx index d0958709..5bafa75c 100644 --- a/frontend/src/components/Logo.tsx +++ b/frontend/src/components/Logo.tsx @@ -1,6 +1,7 @@ import { Typography } from "antd" import { TitleProps } from "antd/es/typography/Title" import { FC } from "react" +import { Link } from "react-router-dom" @@ -8,7 +9,9 @@ const Logo:FC = (props) => { - return Pidgeon + return + Pidgeon + } export default Logo \ No newline at end of file diff --git a/frontend/src/pages/index/Home.tsx b/frontend/src/pages/index/Home.tsx index 781b589e..415aef9b 100644 --- a/frontend/src/pages/index/Home.tsx +++ b/frontend/src/pages/index/Home.tsx @@ -4,7 +4,6 @@ const Home = () => { return ( <> -

    HOME

    diff --git a/frontend/src/styles.css b/frontend/src/styles.css index 47dc1c21..68d33f3a 100644 --- a/frontend/src/styles.css +++ b/frontend/src/styles.css @@ -7,11 +7,16 @@ body, html { height: 100%; } -.dodona-theme .ant-layout-header .ant-typography,.dodona-theme .ant-layout-header .ant-btn { - color: #00325a +.dodona-theme .ant-layout-header .ant-typography,.dodona-theme .ant-layout-header .ant-btn { + color: #00325a; + +} + +.dodona-theme .ant-layout-header .ant-btn { + background-color: rgba(255,255,255,0.1); } .dodona-theme .ant-layout-header .ant-btn:hover { color: #00325a; - background-color: transparent; + background-color: rgba(255,255,255,0.2); } \ No newline at end of file From 3f4259530ade78b2ac2599a5c03276ee29e8f7f9 Mon Sep 17 00:00:00 2001 From: Arthur Werbrouck Date: Fri, 1 Mar 2024 15:47:11 +0100 Subject: [PATCH 17/40] ik miss tristan --- .../src/main/resources/application.properties | 6 +++--- docker-compose.yaml | 18 ++++++------------ 2 files changed, 9 insertions(+), 15 deletions(-) diff --git a/backend/app/src/main/resources/application.properties b/backend/app/src/main/resources/application.properties index 47e0ead4..a0eade67 100644 --- a/backend/app/src/main/resources/application.properties +++ b/backend/app/src/main/resources/application.properties @@ -1,6 +1,6 @@ -spring.datasource.url = jdbc:postgresql://db:5432/pidgeon -spring.datasource.username = pidgeon -spring.datasource.password = admin +spring.datasource.url = jdbc:postgresql://localhost:5432/postgres +spring.datasource.username = admin +spring.datasource.password = root spring.jpa.show-sql=true spring.jpa.database=postgresql diff --git a/docker-compose.yaml b/docker-compose.yaml index 697d077a..ccd4c855 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -11,28 +11,24 @@ services: - ./certbot/www/:/var/www/certbot/:ro backend: container_name: spring_container - image: 'docker-spring-boot-postgres:latest' build: backend/app/ depends_on: - postgres ports: - 8080:8080 environment: - - SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/pidgeon - - SPRING_DATASOURCE_USERNAME=pidgeon - - SPRING_DATASOURCE_PASSWORD=admin - - SPRING_JPA_HIBERNATE_DDL_AUTO=update - networks: - - spring-postgres + - SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/admin + - SPRING_DATASOURCE_USERNAME=admin + - SPRING_DATASOURCE_PASSWORD=root restart: always postgres: - container_name: db + container_name: postgres image: 'postgres:latest' secrets: - db-password environment: - - 'POSTGRES_PASSWORD=admin' - - 'POSTGRES_USER=pidgeon' + - 'POSTGRES_PASSWORD=root' + - 'POSTGRES_USER=admin' ports: - '5432:5432' volumes: @@ -58,5 +54,3 @@ volumes: secrets: db-password: file: backend/db/password.txt -networks: - spring-postgres: From 758abe5e59fdb8b8991b4036d24afd6a817d9bec Mon Sep 17 00:00:00 2001 From: Arthur Werbrouck Date: Fri, 1 Mar 2024 16:08:28 +0100 Subject: [PATCH 18/40] JDBC WERKT --- .../app/src/main/resources/application.properties | 12 ++++++------ docker-compose.yaml | 10 +++++----- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/backend/app/src/main/resources/application.properties b/backend/app/src/main/resources/application.properties index a0eade67..b622818b 100644 --- a/backend/app/src/main/resources/application.properties +++ b/backend/app/src/main/resources/application.properties @@ -1,9 +1,9 @@ -spring.datasource.url = jdbc:postgresql://localhost:5432/postgres -spring.datasource.username = admin -spring.datasource.password = root -spring.jpa.show-sql=true -spring.jpa.database=postgresql - +#spring.datasource.url = jdbc:postgresql://localhost:5432/postgres +#spring.datasource.username = admin +#spring.datasource.password = root +#spring.jpa.show-sql=true +#spring.jpa.database=postgresql +# ## Hibernate Properties # The SQL dialect makes Hibernate generate better SQL for the chosen database spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.PostgreSQLDialect diff --git a/docker-compose.yaml b/docker-compose.yaml index ccd4c855..f09124c1 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -13,16 +13,16 @@ services: container_name: spring_container build: backend/app/ depends_on: - - postgres + - db ports: - 8080:8080 environment: - - SPRING_DATASOURCE_URL=jdbc:postgresql://localhost:5432/admin + - SPRING_DATASOURCE_URL=jdbc:postgresql://db:5432/postgres - SPRING_DATASOURCE_USERNAME=admin - SPRING_DATASOURCE_PASSWORD=root restart: always - postgres: - container_name: postgres + db: + container_name: db image: 'postgres:latest' secrets: - db-password @@ -37,7 +37,7 @@ services: container_name: container-pgadmin image: dpage/pgadmin4 depends_on: - - postgres + - db ports: - "5050:80" environment: From 8ebaf7052381706f1aab289438becf6b3242630b Mon Sep 17 00:00:00 2001 From: Aqua-sc <108478185+Aqua-sc@users.noreply.github.com> Date: Fri, 1 Mar 2024 20:33:09 +0100 Subject: [PATCH 19/40] Added testroute and findUserById query --- .../com/ugent/pidgeon/config/AuthConfig.java | 2 +- .../controllers/AuthTestController.java | 8 +++++++ .../controllers/JpaUserController.java | 22 ++++++++++++------- .../postgre/repository/UserRepository.java | 4 +++- 4 files changed, 26 insertions(+), 10 deletions(-) diff --git a/backend/app/src/main/java/com/ugent/pidgeon/config/AuthConfig.java b/backend/app/src/main/java/com/ugent/pidgeon/config/AuthConfig.java index f0cdbef8..5868e59e 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/config/AuthConfig.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/config/AuthConfig.java @@ -21,7 +21,7 @@ public FilterRegistrationBean filterRegistrationBean() FilterRegistrationBean filter = new FilterRegistrationBean<>(); filter.setFilter(new JwtAuthenticationFilter(tenantId)); - filter.addUrlPatterns("/api/*"); + filter.addUrlPatterns("/api/ietswatiknietwiltesten"); return filter; } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/controllers/AuthTestController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/AuthTestController.java index 1ca65bc2..f02cd135 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/controllers/AuthTestController.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/controllers/AuthTestController.java @@ -1,18 +1,26 @@ package com.ugent.pidgeon.controllers; import com.ugent.pidgeon.model.Auth; import com.ugent.pidgeon.model.User; +import com.ugent.pidgeon.postgre.repository.UserRepository; import jakarta.servlet.http.HttpServletRequest; +import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class AuthTestController { + @Autowired + private UserRepository userRepository; @GetMapping("/api/test") public User testApi(HttpServletRequest request, Auth auth) { return auth.getUser(); } + @GetMapping("/api/users") + public String getUsers() { + return "kaas+: " /*+ userRepository.findAll().get(0).getName()*/; + } @GetMapping("/ping") public String ping() { diff --git a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java index a66b20e2..7d494b40 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java @@ -1,18 +1,24 @@ package com.ugent.pidgeon.controllers; - +import org.apache.commons.logging.LogFactory; +import org.apache.commons.logging.Log; import com.ugent.pidgeon.postgre.repository.UserRepository; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @RestController public class JpaUserController { -// @Autowired -// private UserRepository userRepository; -// -// @GetMapping("/api/users") -// public String getUsers() { -// return "kaas+: "; -// } + @Autowired + private UserRepository userRepository; + + Logger logger = LoggerFactory.getLogger(JpaUserController.class); + @GetMapping("/api/users2") + public String getUsers() { + logger.info("test"); + userRepository.findAll().forEach(user -> logger.info(user.getName())); + return "kaas+: " + userRepository.findById(2).get(0).getName(); + } } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java index e262c7f3..70e545fc 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java @@ -5,7 +5,9 @@ import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; +import java.util.List; + @Repository public interface UserRepository extends JpaRepository { - + List findById(long id); } From 72402162f1aa3a98efbfeb65ac894b95c800b8b2 Mon Sep 17 00:00:00 2001 From: Aqua-sc <108478185+Aqua-sc@users.noreply.github.com> Date: Fri, 1 Mar 2024 22:36:40 +0100 Subject: [PATCH 20/40] trying out the join so we can get all user courses doesn't work that --- .../controllers/JpaUserController.java | 40 +++++++-------- .../pidgeon/postgre/models/CourseEntity.java | 50 +++++++++++++++++++ .../postgre/models/CourseUserEntity.java | 33 ++++++++++++ .../pidgeon/postgre/models/UserEntity.java | 14 ++++++ .../postgre/repository/UserRepository.java | 5 ++ 5 files changed, 122 insertions(+), 20 deletions(-) create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseEntity.java create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java diff --git a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java index 7d494b40..b48ad523 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java @@ -1,24 +1,24 @@ -package com.ugent.pidgeon.controllers; + package com.ugent.pidgeon.controllers; -import org.apache.commons.logging.LogFactory; -import org.apache.commons.logging.Log; -import com.ugent.pidgeon.postgre.repository.UserRepository; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.RestController; + import org.apache.commons.logging.LogFactory; + import org.apache.commons.logging.Log; + import com.ugent.pidgeon.postgre.repository.UserRepository; + import org.slf4j.Logger; + import org.slf4j.LoggerFactory; + import org.springframework.beans.factory.annotation.Autowired; + import org.springframework.web.bind.annotation.GetMapping; + import org.springframework.web.bind.annotation.RestController; -@RestController -public class JpaUserController { - @Autowired - private UserRepository userRepository; + @RestController + public class JpaUserController { + @Autowired + private UserRepository userRepository; - Logger logger = LoggerFactory.getLogger(JpaUserController.class); - @GetMapping("/api/users2") - public String getUsers() { - logger.info("test"); - userRepository.findAll().forEach(user -> logger.info(user.getName())); - return "kaas+: " + userRepository.findById(2).get(0).getName(); + Logger logger = LoggerFactory.getLogger(JpaUserController.class); + @GetMapping("/api/users2") + public String getUsers() { + logger.info("coursessize: " + userRepository.findById(2).get(0).get); + userRepository.findAll().forEach(user -> user.courses.forEach(course -> logger.info(course.getName()))); + return "kaas+: " + userRepository.findById(2).get(0).getName(); + } } -} diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseEntity.java new file mode 100644 index 00000000..85f30dd2 --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseEntity.java @@ -0,0 +1,50 @@ +package com.ugent.pidgeon.postgre.models; + +import jakarta.persistence.*; + +import java.util.HashSet; +import java.util.Set; + + +@Entity +@Table(name = "courses") +public class CourseEntity { + private long id; + private String name; + private String description; + + @ManyToMany(mappedBy = "users") + private Set users = new HashSet<>(); + + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "course_id", nullable = false) + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + @Column(name = "course_name", nullable=false) + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + @Column(name = "description", nullable=false) + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + +} diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java new file mode 100644 index 00000000..567c65fb --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java @@ -0,0 +1,33 @@ +package com.ugent.pidgeon.postgre.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; + +@Entity +@Table(name="course_users") +public class CourseUserEntity { + private long course_id; + private long user_id; + + @Id + @Column(name="course_id", nullable=false) + public long getCourse_id() { + return course_id; + } + + public void setCourse_id(long course_id) { + this.course_id = course_id; + } + + @Id + @Column(name="user_id", nullable=false) + public long getUser_id() { + return user_id; + } + + public void setUser_id(long user_id) { + this.user_id = user_id; + } +} diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java index a4a77a28..d97e0603 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java @@ -3,6 +3,10 @@ import jakarta.persistence.*; +import java.util.HashSet; +import java.util.Set; +import com.ugent.pidgeon.postgre.models.CourseEntity; + @Entity @Table(name = "users") public class UserEntity { @@ -11,6 +15,14 @@ public class UserEntity { private String surname; private String email; + @ManyToMany + @JoinTable( + name = "course_users", + joinColumns = @JoinColumn(name = "user_id"), + inverseJoinColumns = @JoinColumn(name = "course_id") + ) + private Set courses = new HashSet<>(); + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "user_id", nullable = false) @@ -48,5 +60,7 @@ public String getEmail() { public void setEmail(String email) { this.email = email; } + + } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java index 70e545fc..ee6e003a 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java @@ -1,8 +1,11 @@ package com.ugent.pidgeon.postgre.repository; import com.ugent.pidgeon.model.User; +import com.ugent.pidgeon.postgre.models.CourseEntity; import com.ugent.pidgeon.postgre.models.UserEntity; import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; +import org.springframework.data.repository.query.Param; import org.springframework.stereotype.Repository; import java.util.List; @@ -10,4 +13,6 @@ @Repository public interface UserRepository extends JpaRepository { List findById(long id); + + } From a8810ed058dd5019cc0a8336507a02cf48ea0ebd Mon Sep 17 00:00:00 2001 From: Aqua-sc <108478185+Aqua-sc@users.noreply.github.com> Date: Sat, 2 Mar 2024 10:20:33 +0100 Subject: [PATCH 21/40] Added @Query for findCoursesByUserId --- .../ugent/pidgeon/controllers/JpaUserController.java | 9 ++++----- .../ugent/pidgeon/postgre/models/CourseEntity.java | 10 +++++++--- .../pidgeon/postgre/models/CourseUserEntity.java | 7 +++---- .../com/ugent/pidgeon/postgre/models/UserEntity.java | 11 +---------- .../pidgeon/postgre/repository/UserRepository.java | 3 ++- 5 files changed, 17 insertions(+), 23 deletions(-) diff --git a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java index b48ad523..3a498cb0 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java @@ -1,7 +1,6 @@ package com.ugent.pidgeon.controllers; - import org.apache.commons.logging.LogFactory; - import org.apache.commons.logging.Log; + import com.ugent.pidgeon.postgre.models.UserEntity; import com.ugent.pidgeon.postgre.repository.UserRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,8 +16,8 @@ public class JpaUserController { Logger logger = LoggerFactory.getLogger(JpaUserController.class); @GetMapping("/api/users2") public String getUsers() { - logger.info("coursessize: " + userRepository.findById(2).get(0).get); - userRepository.findAll().forEach(user -> user.courses.forEach(course -> logger.info(course.getName()))); - return "kaas+: " + userRepository.findById(2).get(0).getName(); + UserEntity user = userRepository.findById(2).get(0); + userRepository.findCoursesByUserId(user.getId()).forEach(course -> logger.info(course.getName())); + return "kaas+: " + user.getName(); } } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseEntity.java index 85f30dd2..a00ac49b 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseEntity.java @@ -13,9 +13,13 @@ public class CourseEntity { private String name; private String description; - @ManyToMany(mappedBy = "users") - private Set users = new HashSet<>(); - + @OneToMany + @JoinTable( + name = "course_users", + joinColumns = @JoinColumn(name = "course_id"), + inverseJoinColumns = @JoinColumn(name = "user_id") + ) + private Set courseusers = new HashSet<>(); @Id @GeneratedValue(strategy = GenerationType.IDENTITY) diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java index 567c65fb..37d11740 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java @@ -1,9 +1,6 @@ package com.ugent.pidgeon.postgre.models; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.Id; -import jakarta.persistence.Table; +import jakarta.persistence.*; @Entity @Table(name="course_users") @@ -17,6 +14,7 @@ public long getCourse_id() { return course_id; } + public void setCourse_id(long course_id) { this.course_id = course_id; } @@ -30,4 +28,5 @@ public long getUser_id() { public void setUser_id(long user_id) { this.user_id = user_id; } + } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java index d97e0603..745aa217 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java @@ -5,7 +5,6 @@ import java.util.HashSet; import java.util.Set; -import com.ugent.pidgeon.postgre.models.CourseEntity; @Entity @Table(name = "users") @@ -15,13 +14,7 @@ public class UserEntity { private String surname; private String email; - @ManyToMany - @JoinTable( - name = "course_users", - joinColumns = @JoinColumn(name = "user_id"), - inverseJoinColumns = @JoinColumn(name = "course_id") - ) - private Set courses = new HashSet<>(); + @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @@ -60,7 +53,5 @@ public String getEmail() { public void setEmail(String email) { this.email = email; } - - } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java index ee6e003a..22079ef7 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java @@ -14,5 +14,6 @@ public interface UserRepository extends JpaRepository { List findById(long id); - + @Query(value = "SELECT c FROM CourseEntity c JOIN CourseUserEntity cu ON c.id = cu.course_id WHERE cu.user_id = ?1") + List findCoursesByUserId(long id); } From db621cea0c66672afccd6aba3364509f8733afe7 Mon Sep 17 00:00:00 2001 From: Aqua-sc <108478185+Aqua-sc@users.noreply.github.com> Date: Sat, 2 Mar 2024 10:47:33 +0100 Subject: [PATCH 22/40] Added course: controller+repo --- .../controllers/AuthTestController.java | 4 --- .../controllers/JpaCourseController.java | 31 +++++++++++++++++++ .../controllers/JpaUserController.java | 16 +++++++--- .../postgre/repository/CourseRepository.java | 15 +++++++++ .../postgre/repository/UserRepository.java | 2 +- 5 files changed, 59 insertions(+), 9 deletions(-) create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaCourseController.java create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/CourseRepository.java diff --git a/backend/app/src/main/java/com/ugent/pidgeon/controllers/AuthTestController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/AuthTestController.java index f02cd135..95536323 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/controllers/AuthTestController.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/controllers/AuthTestController.java @@ -17,10 +17,6 @@ public User testApi(HttpServletRequest request, Auth auth) { return auth.getUser(); } - @GetMapping("/api/users") - public String getUsers() { - return "kaas+: " /*+ userRepository.findAll().get(0).getName()*/; - } @GetMapping("/ping") public String ping() { diff --git a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaCourseController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaCourseController.java new file mode 100644 index 00000000..d7688d66 --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaCourseController.java @@ -0,0 +1,31 @@ +package com.ugent.pidgeon.controllers; + +import com.ugent.pidgeon.postgre.models.CourseEntity; +import com.ugent.pidgeon.postgre.models.UserEntity; +import com.ugent.pidgeon.postgre.repository.CourseRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; +import org.springframework.web.bind.annotation.RestController; + +@RestController +public class JpaCourseController { + @Autowired + private CourseRepository courseRepository; + + @GetMapping("/api/courses") + public String getCourses() { + StringBuilder res = new StringBuilder(); + for (CourseEntity course : courseRepository.findAll()) { + res.append(course.getName()).append(" with users: "); + for (UserEntity user : courseRepository.findUsersByCourseId(course.getId())) { + res.append(user.getName()).append(", "); + } + res.append("\n"); + } + + return res.toString(); + } + + +} diff --git a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java index 3a498cb0..721f09e6 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java @@ -1,5 +1,6 @@ package com.ugent.pidgeon.controllers; + import com.ugent.pidgeon.postgre.models.CourseEntity; import com.ugent.pidgeon.postgre.models.UserEntity; import com.ugent.pidgeon.postgre.repository.UserRepository; import org.slf4j.Logger; @@ -14,10 +15,17 @@ public class JpaUserController { private UserRepository userRepository; Logger logger = LoggerFactory.getLogger(JpaUserController.class); - @GetMapping("/api/users2") + @GetMapping("/api/users") public String getUsers() { - UserEntity user = userRepository.findById(2).get(0); - userRepository.findCoursesByUserId(user.getId()).forEach(course -> logger.info(course.getName())); - return "kaas+: " + user.getName(); + StringBuilder res = new StringBuilder(); + for (UserEntity user : userRepository.findAll()) { + res.append(user.getName()).append(" in courses: "); + for (CourseEntity course : userRepository.findCoursesByUserId(user.getId())) { + res.append(course.getName()).append(", "); + } + res.append("\n"); + } + + return res.toString(); } } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/CourseRepository.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/CourseRepository.java new file mode 100644 index 00000000..9cd2d0b5 --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/CourseRepository.java @@ -0,0 +1,15 @@ +package com.ugent.pidgeon.postgre.repository; + +import com.ugent.pidgeon.postgre.models.CourseEntity; +import com.ugent.pidgeon.postgre.models.UserEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; + +public interface CourseRepository extends JpaRepository { + CourseEntity findById(long id); + + @Query(value = "SELECT u FROM UserEntity u JOIN CourseUserEntity cu ON u.id = cu.user_id WHERE cu.course_id = ?1") + List findUsersByCourseId(long id); +} diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java index 22079ef7..77278fe9 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java @@ -12,7 +12,7 @@ @Repository public interface UserRepository extends JpaRepository { - List findById(long id); + UserEntity findById(long id); @Query(value = "SELECT c FROM CourseEntity c JOIN CourseUserEntity cu ON c.id = cu.course_id WHERE cu.user_id = ?1") List findCoursesByUserId(long id); From 02892f41ca5f1efa257ca7f30f9925ad5bf77fbf Mon Sep 17 00:00:00 2001 From: Aqua-sc <108478185+Aqua-sc@users.noreply.github.com> Date: Sat, 2 Mar 2024 12:09:05 +0100 Subject: [PATCH 23/40] Added create/update for course uses GET mapping because there are some crsf issues with POST --- .../pidgeon/controllers/JpaCourseController.java | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaCourseController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaCourseController.java index d7688d66..85798359 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaCourseController.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaCourseController.java @@ -4,9 +4,7 @@ import com.ugent.pidgeon.postgre.models.UserEntity; import com.ugent.pidgeon.postgre.repository.CourseRepository; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.web.bind.annotation.GetMapping; -import org.springframework.web.bind.annotation.PostMapping; -import org.springframework.web.bind.annotation.RestController; +import org.springframework.web.bind.annotation.*; @RestController public class JpaCourseController { @@ -27,5 +25,13 @@ public String getCourses() { return res.toString(); } - + @GetMapping("/api/course") + public String addCourse(String name, String description) { + CourseEntity course = new CourseEntity(); + course.setId(1); + course.setName("Test"); + course.setDescription("Added for testing update purposes"); + courseRepository.save(course); + return "Course added"; + } } From a377eb3ef946f3f391d0540e71fa3e849dac1a0b Mon Sep 17 00:00:00 2001 From: Aqua-sc <108478185+Aqua-sc@users.noreply.github.com> Date: Sat, 2 Mar 2024 13:02:06 +0100 Subject: [PATCH 24/40] Added role to UserEntity --- .../controllers/JpaUserController.java | 2 +- .../pidgeon/postgre/models/CourseEntity.java | 21 +++++++-------- .../pidgeon/postgre/models/UserEntity.java | 26 ++++++++++++++----- .../pidgeon/postgre/models/UserRole.java | 7 +++++ 4 files changed, 37 insertions(+), 19 deletions(-) create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserRole.java diff --git a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java index 721f09e6..fdc33819 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java @@ -19,7 +19,7 @@ public class JpaUserController { public String getUsers() { StringBuilder res = new StringBuilder(); for (UserEntity user : userRepository.findAll()) { - res.append(user.getName()).append(" in courses: "); + res.append(user.getName()).append("(").append(user.getRole().toString()).append(") in courses: "); for (CourseEntity course : userRepository.findCoursesByUserId(user.getId())) { res.append(course.getName()).append(", "); } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseEntity.java index a00ac49b..008060e4 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseEntity.java @@ -9,21 +9,18 @@ @Entity @Table(name = "courses") public class CourseEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "course_id", nullable = false) private long id; + @Column(name = "course_name", nullable=false) private String name; + @Column(name = "description", nullable=false) private String description; - @OneToMany - @JoinTable( - name = "course_users", - joinColumns = @JoinColumn(name = "course_id"), - inverseJoinColumns = @JoinColumn(name = "user_id") - ) - private Set courseusers = new HashSet<>(); - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "course_id", nullable = false) + public long getId() { return id; } @@ -32,7 +29,7 @@ public void setId(long id) { this.id = id; } - @Column(name = "course_name", nullable=false) + public String getName() { return name; } @@ -41,7 +38,7 @@ public void setName(String name) { this.name = name; } - @Column(name = "description", nullable=false) + public String getDescription() { return description; } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java index 745aa217..b7c46f7a 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java @@ -9,16 +9,26 @@ @Entity @Table(name = "users") public class UserEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "user_id", nullable = false) private long id; + + @Column(name = "name", nullable=false) private String name; + + @Column(name = "surname", nullable=false) private String surname; + + @Column(name = "email", nullable=false) private String email; + @Column(name = "role") + @Enumerated(EnumType.STRING) + private UserRole role; - @Id - @GeneratedValue(strategy = GenerationType.IDENTITY) - @Column(name = "user_id", nullable = false) public long getId() { return id; } @@ -27,7 +37,7 @@ public void setId(long id) { this.id = id; } - @Column(name = "name", nullable=false) + public String getName() { return name; } @@ -36,7 +46,7 @@ public void setName(String name) { this.name = name; } - @Column(name = "surname", nullable=false) + public String getSurname() { return surname; } @@ -45,7 +55,7 @@ public void setSurname(String surname) { this.surname = surname; } - @Column(name = "email", nullable=false) + public String getEmail() { return email; } @@ -53,5 +63,9 @@ public String getEmail() { public void setEmail(String email) { this.email = email; } + + public UserRole getRole() { + return role; + } } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserRole.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserRole.java new file mode 100644 index 00000000..a27cfd40 --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserRole.java @@ -0,0 +1,7 @@ +package com.ugent.pidgeon.postgre.models; + +public enum UserRole { + student, + admin, + teacher +} From d1ae49990b97dcd02f0e35bb1796424c21a73ad0 Mon Sep 17 00:00:00 2001 From: Aqua-sc <108478185+Aqua-sc@users.noreply.github.com> Date: Sat, 2 Mar 2024 14:48:28 +0100 Subject: [PATCH 25/40] Added courserelation --- .../pidgeon/controllers/JpaCourseController.java | 6 ++++-- .../pidgeon/controllers/JpaUserController.java | 8 ++++++-- .../pidgeon/postgre/models/CourseRelation.java | 7 +++++++ .../pidgeon/postgre/models/CourseUserEntity.java | 16 ++++++++++++---- .../postgre/repository/CourseRepository.java | 12 ++++++++++-- .../postgre/repository/UserRepository.java | 15 +++++++++++++-- 6 files changed, 52 insertions(+), 12 deletions(-) create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseRelation.java diff --git a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaCourseController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaCourseController.java index 85798359..4b97c3a0 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaCourseController.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaCourseController.java @@ -16,8 +16,10 @@ public String getCourses() { StringBuilder res = new StringBuilder(); for (CourseEntity course : courseRepository.findAll()) { res.append(course.getName()).append(" with users: "); - for (UserEntity user : courseRepository.findUsersByCourseId(course.getId())) { - res.append(user.getName()).append(", "); + for (CourseRepository.UserWithRelation user : courseRepository.findUsersByCourseId(course.getId())) { + UserEntity userEntity = user.getUser(); + String relation = user.getRelation(); + res.append(userEntity.getName()).append("(").append(relation).append("), "); } res.append("\n"); } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java index fdc33819..97c494c8 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java @@ -1,11 +1,13 @@ package com.ugent.pidgeon.controllers; import com.ugent.pidgeon.postgre.models.CourseEntity; + import com.ugent.pidgeon.postgre.models.CourseRelation; import com.ugent.pidgeon.postgre.models.UserEntity; import com.ugent.pidgeon.postgre.repository.UserRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; + import org.springframework.data.util.Pair; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @@ -20,8 +22,10 @@ public String getUsers() { StringBuilder res = new StringBuilder(); for (UserEntity user : userRepository.findAll()) { res.append(user.getName()).append("(").append(user.getRole().toString()).append(") in courses: "); - for (CourseEntity course : userRepository.findCoursesByUserId(user.getId())) { - res.append(course.getName()).append(", "); + for (UserRepository.CourseWithRelation course : userRepository.findCoursesByUserId(user.getId())) { + CourseEntity courseEntity = course.getCourse(); + CourseRelation courseRelation = course.getRelation(); + res.append(courseEntity.getName()).append("(").append(courseRelation.toString()).append("), "); } res.append("\n"); } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseRelation.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseRelation.java new file mode 100644 index 00000000..fd58b851 --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseRelation.java @@ -0,0 +1,7 @@ +package com.ugent.pidgeon.postgre.models; + +public enum CourseRelation { + creator, + course_admin, + enrolled +} diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java index 37d11740..fcdfcb2e 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java @@ -5,11 +5,20 @@ @Entity @Table(name="course_users") public class CourseUserEntity { - private long course_id; - private long user_id; @Id @Column(name="course_id", nullable=false) + private long course_id; + + @Id + @Column(name="user_id", nullable=false) + private long user_id; + + @Column(name = "course_relation") + @Enumerated(EnumType.STRING) + private CourseRelation relation; + + public long getCourse_id() { return course_id; } @@ -19,8 +28,7 @@ public void setCourse_id(long course_id) { this.course_id = course_id; } - @Id - @Column(name="user_id", nullable=false) + public long getUser_id() { return user_id; } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/CourseRepository.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/CourseRepository.java index 9cd2d0b5..0dd5b89c 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/CourseRepository.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/CourseRepository.java @@ -8,8 +8,16 @@ import java.util.List; public interface CourseRepository extends JpaRepository { + CourseEntity findById(long id); - @Query(value = "SELECT u FROM UserEntity u JOIN CourseUserEntity cu ON u.id = cu.user_id WHERE cu.course_id = ?1") - List findUsersByCourseId(long id); + + public interface UserWithRelation { + UserEntity getUser(); + String getRelation(); + } + + /* The 'as' is important here, as it is used to map the result to the CourseWithRelation interface */ + @Query(value = "SELECT u as user, cu.relation as relation FROM UserEntity u JOIN CourseUserEntity cu ON u.id = cu.user_id WHERE cu.course_id = ?1") + List findUsersByCourseId(long id); } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java index 77278fe9..0e0b9b11 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java @@ -2,18 +2,29 @@ import com.ugent.pidgeon.model.User; import com.ugent.pidgeon.postgre.models.CourseEntity; +import com.ugent.pidgeon.postgre.models.CourseRelation; import com.ugent.pidgeon.postgre.models.UserEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; import org.springframework.data.repository.query.Param; +import org.springframework.data.util.Pair; import org.springframework.stereotype.Repository; import java.util.List; @Repository public interface UserRepository extends JpaRepository { + + UserEntity findById(long id); - @Query(value = "SELECT c FROM CourseEntity c JOIN CourseUserEntity cu ON c.id = cu.course_id WHERE cu.user_id = ?1") - List findCoursesByUserId(long id); + + public interface CourseWithRelation { + CourseEntity getCourse(); + CourseRelation getRelation(); + } + + /* The 'as' is important here, as it is used to map the result to the CourseWithRelation interface */ + @Query(value = "SELECT c as course, cu.relation as relation FROM CourseEntity c JOIN CourseUserEntity cu ON c.id = cu.course_id WHERE cu.user_id = ?1") + List findCoursesByUserId(long id); } From 3d12e86d92d2478d85b38af2b2ab04d02ea27e26 Mon Sep 17 00:00:00 2001 From: Aqua-sc <108478185+Aqua-sc@users.noreply.github.com> Date: Sat, 2 Mar 2024 16:20:43 +0100 Subject: [PATCH 26/40] Added group-related entities --- .../postgre/models/GroupClusterEntity.java | 66 +++++++++++++++++++ .../pidgeon/postgre/models/GroupEntity.java | 43 ++++++++++++ .../postgre/models/GroupUserEntity.java | 34 ++++++++++ 3 files changed, 143 insertions(+) create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupClusterEntity.java create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupEntity.java create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupUserEntity.java diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupClusterEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupClusterEntity.java new file mode 100644 index 00000000..7c94f7c2 --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupClusterEntity.java @@ -0,0 +1,66 @@ +package com.ugent.pidgeon.postgre.models; + +import jakarta.persistence.*; + +@Entity +@Table(name="group_clusters") +public class GroupClusterEntity { + + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name="group_cluster_id", nullable=false) + private int id; + + @Column(name="course_id", nullable=false) + private int course_id; + + @Column(name="max_size", nullable=false) + private int max_size; + + @Column(name="cluster_name", nullable=false) + private String cluster_name; + + @Column(name="group_amount", nullable=false) + private int group_amount; + + public int getId() { + return id; + } + + public void setId(int id) { + this.id = id; + } + + public int getCourse_id() { + return course_id; + } + + public void setCourse_id(int course_id) { + this.course_id = course_id; + } + + public int getMax_size() { + return max_size; + } + + public void setMax_size(int max_size) { + this.max_size = max_size; + } + + public String getCluster_name() { + return cluster_name; + } + + public void setCluster_name(String cluster_name) { + this.cluster_name = cluster_name; + } + + public int getGroup_amount() { + return group_amount; + } + + public void setGroup_amount(int group_amount) { + this.group_amount = group_amount; + } +} diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupEntity.java new file mode 100644 index 00000000..65e6c2d0 --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupEntity.java @@ -0,0 +1,43 @@ +package com.ugent.pidgeon.postgre.models; + +import jakarta.persistence.*; + +@Entity +@Table(name="groups") +public class GroupEntity { + + @Id + @GeneratedValue + @Column(name="group_id", nullable=false) + private long id; + + @Column(name="group_name", nullable=false) + private String name; + + @Column(name="group_cluster", nullable = false) + private int cluster; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public int getCluster() { + return cluster; + } + + public void setCluster(int cluster) { + this.cluster = cluster; + } +} diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupUserEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupUserEntity.java new file mode 100644 index 00000000..f48358c4 --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupUserEntity.java @@ -0,0 +1,34 @@ +package com.ugent.pidgeon.postgre.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; + +@Entity +@Table(name="group_users") +public class GroupUserEntity { + @Id + @Column(name="group_id", nullable=false) + private long group_id; + + @Id + @Column(name="user_id", nullable=false) + private long user_id; + + public long getGroup_id() { + return group_id; + } + + public void setGroup_id(long group_id) { + this.group_id = group_id; + } + + public long getUser_id() { + return user_id; + } + + public void setUser_id(long user_id) { + this.user_id = user_id; + } +} From 08caa4eb7138be087072b25405fd2879d888b5c9 Mon Sep 17 00:00:00 2001 From: Aqua-sc <108478185+Aqua-sc@users.noreply.github.com> Date: Sat, 2 Mar 2024 17:08:19 +0100 Subject: [PATCH 27/40] refactering names + group/groupcluster repo --- .../controllers/JpaCourseController.java | 9 +++++ .../controllers/JpaGroupController.java | 31 ++++++++++++++ .../postgre/models/CourseUserEntity.java | 23 +++++------ .../postgre/models/GroupClusterEntity.java | 40 +++++++++---------- .../postgre/models/GroupUserEntity.java | 20 +++++----- .../postgre/repository/CourseRepository.java | 2 +- .../repository/GroupClusterRepository.java | 10 +++++ .../postgre/repository/GroupRepository.java | 15 +++++++ .../postgre/repository/UserRepository.java | 2 +- 9 files changed, 107 insertions(+), 45 deletions(-) create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaGroupController.java create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/GroupClusterRepository.java create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/GroupRepository.java diff --git a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaCourseController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaCourseController.java index 4b97c3a0..519c5c28 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaCourseController.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaCourseController.java @@ -1,8 +1,10 @@ package com.ugent.pidgeon.controllers; import com.ugent.pidgeon.postgre.models.CourseEntity; +import com.ugent.pidgeon.postgre.models.GroupClusterEntity; import com.ugent.pidgeon.postgre.models.UserEntity; import com.ugent.pidgeon.postgre.repository.CourseRepository; +import com.ugent.pidgeon.postgre.repository.GroupClusterRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -11,6 +13,9 @@ public class JpaCourseController { @Autowired private CourseRepository courseRepository; + @Autowired + private GroupClusterRepository groupClusterRepository; + @GetMapping("/api/courses") public String getCourses() { StringBuilder res = new StringBuilder(); @@ -21,6 +26,10 @@ public String getCourses() { String relation = user.getRelation(); res.append(userEntity.getName()).append("(").append(relation).append("), "); } + res.append(" with group cluster"); + for (GroupClusterEntity groupcluster: groupClusterRepository.findByCourseId((int) course.getId())) { + res.append(groupcluster.getName()).append(" (").append(groupcluster.getGroupAmount()).append("), "); + } res.append("\n"); } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaGroupController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaGroupController.java new file mode 100644 index 00000000..6952a53b --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaGroupController.java @@ -0,0 +1,31 @@ +package com.ugent.pidgeon.controllers; + +import com.ugent.pidgeon.postgre.models.GroupEntity; +import com.ugent.pidgeon.postgre.models.UserEntity; +import com.ugent.pidgeon.postgre.repository.GroupRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.ArrayList; +import java.util.List; + +@RestController +public class JpaGroupController { + @Autowired + private GroupRepository groupRepository; + + @GetMapping("/api/groups") + public List getGroups() { + List res = new ArrayList<>(); + for (GroupEntity group : groupRepository.findAll()) { + StringBuilder groupString = new StringBuilder(); + groupString.append(group.getName()).append(" with users: "); + for (UserEntity user : groupRepository.findCourseUsersByGroupId(group.getId())) { + groupString.append(user.getName()).append(", "); + } + res.add(groupString.toString()); + } + return res; + } +} diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java index fcdfcb2e..79566b0c 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java @@ -8,33 +8,30 @@ public class CourseUserEntity { @Id @Column(name="course_id", nullable=false) - private long course_id; + private long courseId; @Id @Column(name="user_id", nullable=false) - private long user_id; + private long userId; @Column(name = "course_relation") @Enumerated(EnumType.STRING) private CourseRelation relation; - public long getCourse_id() { - return course_id; + public long getCourseId() { + return courseId; } - - public void setCourse_id(long course_id) { - this.course_id = course_id; + public void setCourseId(long courseId) { + this.courseId = courseId; } - - public long getUser_id() { - return user_id; + public long getUserId() { + return userId; } - public void setUser_id(long user_id) { - this.user_id = user_id; + public void setUserId(long userId) { + this.userId = userId; } - } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupClusterEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupClusterEntity.java index 7c94f7c2..342668e7 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupClusterEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupClusterEntity.java @@ -13,16 +13,16 @@ public class GroupClusterEntity { private int id; @Column(name="course_id", nullable=false) - private int course_id; + private int courseId; @Column(name="max_size", nullable=false) - private int max_size; + private int maxSize; @Column(name="cluster_name", nullable=false) - private String cluster_name; + private String name; @Column(name="group_amount", nullable=false) - private int group_amount; + private int groupAmount; public int getId() { return id; @@ -32,35 +32,35 @@ public void setId(int id) { this.id = id; } - public int getCourse_id() { - return course_id; + public int getCourseId() { + return courseId; } - public void setCourse_id(int course_id) { - this.course_id = course_id; + public void setCourseId(int course_id) { + this.courseId = course_id; } - public int getMax_size() { - return max_size; + public int getMaxSize() { + return maxSize; } - public void setMax_size(int max_size) { - this.max_size = max_size; + public void setMaxSize(int max_size) { + this.maxSize = max_size; } - public String getCluster_name() { - return cluster_name; + public String getName() { + return name; } - public void setCluster_name(String cluster_name) { - this.cluster_name = cluster_name; + public void setName(String cluster_name) { + this.name = cluster_name; } - public int getGroup_amount() { - return group_amount; + public int getGroupAmount() { + return groupAmount; } - public void setGroup_amount(int group_amount) { - this.group_amount = group_amount; + public void setGroupAmount(int group_amount) { + this.groupAmount = group_amount; } } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupUserEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupUserEntity.java index f48358c4..1b4d8b6d 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupUserEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupUserEntity.java @@ -10,25 +10,25 @@ public class GroupUserEntity { @Id @Column(name="group_id", nullable=false) - private long group_id; + private long groupId; @Id @Column(name="user_id", nullable=false) - private long user_id; + private long userId; - public long getGroup_id() { - return group_id; + public long getGroupId() { + return groupId; } - public void setGroup_id(long group_id) { - this.group_id = group_id; + public void setGroupId(long group_id) { + this.groupId = group_id; } - public long getUser_id() { - return user_id; + public long getUserId() { + return userId; } - public void setUser_id(long user_id) { - this.user_id = user_id; + public void setUserId(long user_id) { + this.userId = user_id; } } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/CourseRepository.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/CourseRepository.java index 0dd5b89c..fdf7ffac 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/CourseRepository.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/CourseRepository.java @@ -18,6 +18,6 @@ public interface UserWithRelation { } /* The 'as' is important here, as it is used to map the result to the CourseWithRelation interface */ - @Query(value = "SELECT u as user, cu.relation as relation FROM UserEntity u JOIN CourseUserEntity cu ON u.id = cu.user_id WHERE cu.course_id = ?1") + @Query(value = "SELECT u as user, cu.relation as relation FROM UserEntity u JOIN CourseUserEntity cu ON u.id = cu.userId WHERE cu.courseId = ?1") List findUsersByCourseId(long id); } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/GroupClusterRepository.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/GroupClusterRepository.java new file mode 100644 index 00000000..bb82247b --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/GroupClusterRepository.java @@ -0,0 +1,10 @@ +package com.ugent.pidgeon.postgre.repository; + +import com.ugent.pidgeon.postgre.models.GroupClusterEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface GroupClusterRepository extends JpaRepository { + List findByCourseId(int courseId); +} diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/GroupRepository.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/GroupRepository.java new file mode 100644 index 00000000..0712162e --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/GroupRepository.java @@ -0,0 +1,15 @@ +package com.ugent.pidgeon.postgre.repository; + +import com.ugent.pidgeon.postgre.models.GroupEntity; +import com.ugent.pidgeon.postgre.models.UserEntity; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.data.jpa.repository.Query; + +import java.util.List; + +public interface GroupRepository extends JpaRepository{ + GroupEntity findById(long id); + + @Query(value= "SELECT u FROM UserEntity u JOIN GroupUserEntity gu ON u.id = gu.userId WHERE gu.groupId = ?1") + List findCourseUsersByGroupId(long id); +} diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java index 0e0b9b11..615a7b1e 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java @@ -25,6 +25,6 @@ public interface CourseWithRelation { } /* The 'as' is important here, as it is used to map the result to the CourseWithRelation interface */ - @Query(value = "SELECT c as course, cu.relation as relation FROM CourseEntity c JOIN CourseUserEntity cu ON c.id = cu.course_id WHERE cu.user_id = ?1") + @Query(value = "SELECT c as course, cu.relation as relation FROM CourseEntity c JOIN CourseUserEntity cu ON c.id = cu.courseId WHERE cu.userId = ?1") List findCoursesByUserId(long id); } From f72c4aa42d64dacd67673b76a556904a53ab910f Mon Sep 17 00:00:00 2001 From: Aqua-sc <108478185+Aqua-sc@users.noreply.github.com> Date: Sun, 3 Mar 2024 10:35:34 +0100 Subject: [PATCH 28/40] Added projectEntity --- .../controllers/JpaCourseController.java | 15 +++- .../postgre/models/GroupClusterEntity.java | 12 +-- .../pidgeon/postgre/models/GroupEntity.java | 10 +-- .../pidgeon/postgre/models/ProjectEntity.java | 88 +++++++++++++++++++ .../repository/GroupClusterRepository.java | 2 +- .../postgre/repository/ProjectRepository.java | 10 +++ 6 files changed, 122 insertions(+), 15 deletions(-) create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/postgre/models/ProjectEntity.java create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/ProjectRepository.java diff --git a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaCourseController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaCourseController.java index 519c5c28..276040d8 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaCourseController.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaCourseController.java @@ -2,9 +2,11 @@ import com.ugent.pidgeon.postgre.models.CourseEntity; import com.ugent.pidgeon.postgre.models.GroupClusterEntity; +import com.ugent.pidgeon.postgre.models.ProjectEntity; import com.ugent.pidgeon.postgre.models.UserEntity; import com.ugent.pidgeon.postgre.repository.CourseRepository; import com.ugent.pidgeon.postgre.repository.GroupClusterRepository; +import com.ugent.pidgeon.postgre.repository.ProjectRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.*; @@ -16,6 +18,9 @@ public class JpaCourseController { @Autowired private GroupClusterRepository groupClusterRepository; + @Autowired + private ProjectRepository projectRepository; + @GetMapping("/api/courses") public String getCourses() { StringBuilder res = new StringBuilder(); @@ -26,11 +31,15 @@ public String getCourses() { String relation = user.getRelation(); res.append(userEntity.getName()).append("(").append(relation).append("), "); } - res.append(" with group cluster"); - for (GroupClusterEntity groupcluster: groupClusterRepository.findByCourseId((int) course.getId())) { + res.append("- with group clusters:"); + for (GroupClusterEntity groupcluster: groupClusterRepository.findByCourseId(course.getId())) { res.append(groupcluster.getName()).append(" (").append(groupcluster.getGroupAmount()).append("), "); } - res.append("\n"); + res.append("- with projects:"); + for (ProjectEntity project: projectRepository.findByCourseId(course.getId())) { + res.append(project.getName()).append(", "); + } + res.append("|\n"); } return res.toString(); diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupClusterEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupClusterEntity.java index 342668e7..0027d96a 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupClusterEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupClusterEntity.java @@ -10,10 +10,10 @@ public class GroupClusterEntity { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name="group_cluster_id", nullable=false) - private int id; + private long id; @Column(name="course_id", nullable=false) - private int courseId; + private long courseId; @Column(name="max_size", nullable=false) private int maxSize; @@ -24,19 +24,19 @@ public class GroupClusterEntity { @Column(name="group_amount", nullable=false) private int groupAmount; - public int getId() { + public long getId() { return id; } - public void setId(int id) { + public void setId(long id) { this.id = id; } - public int getCourseId() { + public long getCourseId() { return courseId; } - public void setCourseId(int course_id) { + public void setCourseId(long course_id) { this.courseId = course_id; } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupEntity.java index 65e6c2d0..ac15bf7f 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupEntity.java @@ -15,7 +15,7 @@ public class GroupEntity { private String name; @Column(name="group_cluster", nullable = false) - private int cluster; + private long clusterId; public long getId() { return id; @@ -33,11 +33,11 @@ public void setName(String name) { this.name = name; } - public int getCluster() { - return cluster; + public long getClusterId() { + return clusterId; } - public void setCluster(int cluster) { - this.cluster = cluster; + public void setClusterId(int cluster) { + this.clusterId = cluster; } } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/ProjectEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/ProjectEntity.java new file mode 100644 index 00000000..a87e2642 --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/ProjectEntity.java @@ -0,0 +1,88 @@ +package com.ugent.pidgeon.postgre.models; + +import jakarta.persistence.*; + +@Entity +@Table(name = "projects") +public class ProjectEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "project_id", nullable = false) + private long id; + + @Column(name="course_id", nullable = false) + private long courseId; + + @Column(name="project_name", nullable = false) + private String name; + + @Column(name="description", nullable = false) + private String description; + + @Column(name="group_cluster_id", nullable = false) + private long groupClusterId; + + @Column(name="test_id", nullable = false) + private long testId; + + @Column(name="visible", nullable = false) + private Boolean projectType; + + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public long getCourseId() { + return courseId; + } + + public void setCourseId(long courseId) { + this.courseId = courseId; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + public long getGroupClusterId() { + return groupClusterId; + } + + public void setGroupClusterId(long groupClusterId) { + this.groupClusterId = groupClusterId; + } + + public long getTestId() { + return testId; + } + + public void setTestId(long testId) { + this.testId = testId; + } + + public Boolean getProjectType() { + return projectType; + } + + public void setProjectType(Boolean projectType) { + this.projectType = projectType; + } +} diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/GroupClusterRepository.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/GroupClusterRepository.java index bb82247b..45d3b320 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/GroupClusterRepository.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/GroupClusterRepository.java @@ -6,5 +6,5 @@ import java.util.List; public interface GroupClusterRepository extends JpaRepository { - List findByCourseId(int courseId); + List findByCourseId(long courseId); } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/ProjectRepository.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/ProjectRepository.java new file mode 100644 index 00000000..7cacecb3 --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/ProjectRepository.java @@ -0,0 +1,10 @@ +package com.ugent.pidgeon.postgre.repository; + +import com.ugent.pidgeon.postgre.models.ProjectEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface ProjectRepository extends JpaRepository { + List findByCourseId(long courseId); +} From 06b053cc142a01acb411af9907e53b00b51bcdca Mon Sep 17 00:00:00 2001 From: Aqua-sc <108478185+Aqua-sc@users.noreply.github.com> Date: Sun, 3 Mar 2024 12:00:58 +0100 Subject: [PATCH 29/40] Added GroupFeedbackEntity + missing project fields --- .../controllers/JpaGroupController.java | 13 +++- .../pidgeon/postgre/models/FileEntity.java | 4 ++ .../postgre/models/GroupFeedbackEntity.java | 62 +++++++++++++++++++ .../pidgeon/postgre/models/ProjectEntity.java | 16 +++++ .../repository/GroupFeedbackRepository.java | 8 +++ .../postgre/repository/GroupRepository.java | 9 +++ 6 files changed, 111 insertions(+), 1 deletion(-) create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/postgre/models/FileEntity.java create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupFeedbackEntity.java create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/GroupFeedbackRepository.java diff --git a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaGroupController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaGroupController.java index 6952a53b..7a908d5b 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaGroupController.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaGroupController.java @@ -1,7 +1,9 @@ package com.ugent.pidgeon.controllers; import com.ugent.pidgeon.postgre.models.GroupEntity; +import com.ugent.pidgeon.postgre.models.GroupFeedbackEntity; import com.ugent.pidgeon.postgre.models.UserEntity; +import com.ugent.pidgeon.postgre.repository.GroupFeedbackRepository; import com.ugent.pidgeon.postgre.repository.GroupRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; @@ -12,18 +14,27 @@ @RestController public class JpaGroupController { + @Autowired private GroupRepository groupRepository; + @Autowired + private GroupFeedbackRepository groupFeedbackRepository; + @GetMapping("/api/groups") public List getGroups() { List res = new ArrayList<>(); for (GroupEntity group : groupRepository.findAll()) { StringBuilder groupString = new StringBuilder(); - groupString.append(group.getName()).append(" with users: "); + groupString.append(group.getName()).append("-with users: "); for (UserEntity user : groupRepository.findCourseUsersByGroupId(group.getId())) { groupString.append(user.getName()).append(", "); } + groupString.append("-with grades: "); + for (long projectId: groupRepository.findProjectsByGroupId(group.getId())) { + GroupFeedbackEntity feedback = groupFeedbackRepository.findByGroupIdAndProjectId(group.getId(), projectId); + groupString.append(feedback.getGrade()).append(", "); + } res.add(groupString.toString()); } return res; diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/FileEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/FileEntity.java new file mode 100644 index 00000000..65597385 --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/FileEntity.java @@ -0,0 +1,4 @@ +package com.ugent.pidgeon.postgre.models; + +public class FileEntity { +} diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupFeedbackEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupFeedbackEntity.java new file mode 100644 index 00000000..bf10ecaa --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupFeedbackEntity.java @@ -0,0 +1,62 @@ +package com.ugent.pidgeon.postgre.models; + +import jakarta.persistence.*; + +import java.io.Serializable; + +@Entity +@IdClass(GroupFeedBackId.class) +@Table(name = "group_feedback") +public class GroupFeedbackEntity { + + @Id + @Column(name = "group_id", nullable = false) + private long groupId; + + @Id + @Column(name = "project_id", nullable = false) + private long projectId; + + @Column(name = "grade") + private Float grade; + + @Column(name = "feedback") + private String feedback; + + public long getGroupId() { + return groupId; + } + + public void setGroupId(long groupId) { + this.groupId = groupId; + } + + public long getProjectId() { + return projectId; + } + + public void setProjectId(long projectId) { + this.projectId = projectId; + } + + public Float getGrade() { + return grade; + } + + public void setGrade(Float grade) { + this.grade = grade; + } + + public String getFeedback() { + return feedback; + } + + public void setFeedback(String feedback) { + this.feedback = feedback; + } +} + +class GroupFeedBackId implements Serializable { + private long groupId; + private long projectId; +} diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/ProjectEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/ProjectEntity.java index a87e2642..fd14afbe 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/ProjectEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/ProjectEntity.java @@ -1,6 +1,8 @@ package com.ugent.pidgeon.postgre.models; import jakarta.persistence.*; +import java.sql.Timestamp; + @Entity @Table(name = "projects") @@ -29,6 +31,12 @@ public class ProjectEntity { @Column(name="visible", nullable = false) private Boolean projectType; + @Column(name="deadline", nullable = false) + private Timestamp deadline; + + @Column(name="max_score") + private Integer maxScore; + public long getId() { return id; @@ -85,4 +93,12 @@ public Boolean getProjectType() { public void setProjectType(Boolean projectType) { this.projectType = projectType; } + + public Timestamp getDeadline() { + return deadline; + } + + public void setDeadline(Timestamp deadline) { + this.deadline = deadline; + } } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/GroupFeedbackRepository.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/GroupFeedbackRepository.java new file mode 100644 index 00000000..28ec8f56 --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/GroupFeedbackRepository.java @@ -0,0 +1,8 @@ +package com.ugent.pidgeon.postgre.repository; + +import com.ugent.pidgeon.postgre.models.GroupFeedbackEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface GroupFeedbackRepository extends JpaRepository { + GroupFeedbackEntity findByGroupIdAndProjectId(long groupId, long projectId); +} diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/GroupRepository.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/GroupRepository.java index 0712162e..a2fb8e4e 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/GroupRepository.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/GroupRepository.java @@ -1,6 +1,7 @@ package com.ugent.pidgeon.postgre.repository; import com.ugent.pidgeon.postgre.models.GroupEntity; +import com.ugent.pidgeon.postgre.models.ProjectEntity; import com.ugent.pidgeon.postgre.models.UserEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; @@ -12,4 +13,12 @@ public interface GroupRepository extends JpaRepository{ @Query(value= "SELECT u FROM UserEntity u JOIN GroupUserEntity gu ON u.id = gu.userId WHERE gu.groupId = ?1") List findCourseUsersByGroupId(long id); + + + @Query(value = """ + SELECT p.id FROM ProjectEntity p + JOIN GroupClusterEntity gc ON p.groupClusterId = gc.id + JOIN GroupEntity g ON g.clusterId = gc.id + WHERE g.id = ?1""") + List findProjectsByGroupId(long id); } From 108c2e266b17de602eba5c534eff94cdcd21a5ea Mon Sep 17 00:00:00 2001 From: Aqua-sc <108478185+Aqua-sc@users.noreply.github.com> Date: Sun, 3 Mar 2024 12:12:58 +0100 Subject: [PATCH 30/40] fixed pk for [Course|Group]UserEntity (pk = primary key) --- .../pidgeon/postgre/models/CourseUserEntity.java | 8 ++++++++ .../pidgeon/postgre/models/GroupUserEntity.java | 13 +++++++++---- 2 files changed, 17 insertions(+), 4 deletions(-) diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java index 79566b0c..84fe5e6c 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java @@ -2,7 +2,10 @@ import jakarta.persistence.*; +import java.io.Serializable; + @Entity +@IdClass(CourseUserId.class) @Table(name="course_users") public class CourseUserEntity { @@ -35,3 +38,8 @@ public void setUserId(long userId) { this.userId = userId; } } + +class CourseUserId implements Serializable { + private long courseId; + private long userId; +} \ No newline at end of file diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupUserEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupUserEntity.java index 1b4d8b6d..bff40866 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupUserEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupUserEntity.java @@ -1,11 +1,11 @@ package com.ugent.pidgeon.postgre.models; -import jakarta.persistence.Column; -import jakarta.persistence.Entity; -import jakarta.persistence.Id; -import jakarta.persistence.Table; +import jakarta.persistence.*; + +import java.io.Serializable; @Entity +@IdClass(GroupUserId.class) @Table(name="group_users") public class GroupUserEntity { @Id @@ -32,3 +32,8 @@ public void setUserId(long user_id) { this.userId = user_id; } } + +class GroupUserId implements Serializable { + private long groupId; + private long userId; +} \ No newline at end of file From 4801bf35587554a43382da3c7f939e0bd797b004 Mon Sep 17 00:00:00 2001 From: Arthur Werbrouck Date: Sun, 3 Mar 2024 12:26:00 +0100 Subject: [PATCH 31/40] Update README.md --- README.md | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/README.md b/README.md index 80c68613..eb843e8c 100644 --- a/README.md +++ b/README.md @@ -1,6 +1,3 @@ # UGent-6 - -WIP (ik ga korte uitleg schrijven hoe je dit lokaal kan opzetten) -# dependencies -docker compose +https://github.com/SELab-2/UGent-6/wiki From d09d743f8aae80e5fd595616a838e79b6cf11c03 Mon Sep 17 00:00:00 2001 From: Aqua-sc <108478185+Aqua-sc@users.noreply.github.com> Date: Sun, 3 Mar 2024 12:28:35 +0100 Subject: [PATCH 32/40] Added submissionEntity --- .../controllers/JpaGroupController.java | 15 ++++- .../postgre/models/SubmissionEntity.java | 58 +++++++++++++++++++ .../repository/SubmissionRepository.java | 10 ++++ 3 files changed, 82 insertions(+), 1 deletion(-) create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/postgre/models/SubmissionEntity.java create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/SubmissionRepository.java diff --git a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaGroupController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaGroupController.java index 7a908d5b..b3845a87 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaGroupController.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaGroupController.java @@ -2,9 +2,11 @@ import com.ugent.pidgeon.postgre.models.GroupEntity; import com.ugent.pidgeon.postgre.models.GroupFeedbackEntity; +import com.ugent.pidgeon.postgre.models.SubmissionEntity; import com.ugent.pidgeon.postgre.models.UserEntity; import com.ugent.pidgeon.postgre.repository.GroupFeedbackRepository; import com.ugent.pidgeon.postgre.repository.GroupRepository; +import com.ugent.pidgeon.postgre.repository.SubmissionRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; @@ -21,6 +23,9 @@ public class JpaGroupController { @Autowired private GroupFeedbackRepository groupFeedbackRepository; + @Autowired + SubmissionRepository submissionRepository; + @GetMapping("/api/groups") public List getGroups() { List res = new ArrayList<>(); @@ -30,11 +35,19 @@ public List getGroups() { for (UserEntity user : groupRepository.findCourseUsersByGroupId(group.getId())) { groupString.append(user.getName()).append(", "); } + List projectIds = groupRepository.findProjectsByGroupId(group.getId()); groupString.append("-with grades: "); - for (long projectId: groupRepository.findProjectsByGroupId(group.getId())) { + for (long projectId : projectIds) { GroupFeedbackEntity feedback = groupFeedbackRepository.findByGroupIdAndProjectId(group.getId(), projectId); groupString.append(feedback.getGrade()).append(", "); } + groupString.append("-with submissions: "); + for (long projectId : projectIds) { + for (SubmissionEntity submission : submissionRepository.findByGroupIdAndProjectId(group.getId(), projectId)) { + groupString.append(submission.getSubmissionTime()).append(", "); + } + } + groupString.append("|"); res.add(groupString.toString()); } return res; diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/SubmissionEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/SubmissionEntity.java new file mode 100644 index 00000000..b6a0abce --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/SubmissionEntity.java @@ -0,0 +1,58 @@ +package com.ugent.pidgeon.postgre.models; + +import jakarta.persistence.Column; +import jakarta.persistence.Entity; +import jakarta.persistence.Id; +import jakarta.persistence.Table; +import java.sql.Timestamp; + +@Entity +@Table(name="submissions") +public class SubmissionEntity { + @Id + @Column(name="submission_id", nullable=false) + private long id; + + @Column(name="project_id", nullable=false) + private long projectId; + + @Column(name="group_id", nullable=false) + private long groupId; + + @Column(name="file_id", nullable=false) + private long fileId; + + @Column(name="submission_time", nullable=false) + private Timestamp submissionTime; + + @Column(name="accepted", nullable=false) + private Boolean accepted; + + public long getGroupId() { + return groupId; + } + + public long getFileId() { + return fileId; + } + + public void setFileId(long fileId) { + this.fileId = fileId; + } + + public Timestamp getSubmissionTime() { + return submissionTime; + } + + public void setSubmissionTime(Timestamp submissionTime) { + this.submissionTime = submissionTime; + } + + public Boolean getAccepted() { + return accepted; + } + + public void setAccepted(Boolean accepted) { + this.accepted = accepted; + } +} diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/SubmissionRepository.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/SubmissionRepository.java new file mode 100644 index 00000000..6a107b86 --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/SubmissionRepository.java @@ -0,0 +1,10 @@ +package com.ugent.pidgeon.postgre.repository; + +import com.ugent.pidgeon.postgre.models.SubmissionEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +import java.util.List; + +public interface SubmissionRepository extends JpaRepository { + List findByGroupIdAndProjectId(long groupId, long projectId); +} From 4bf162dfc4150e4281415f83b988b9da99d09240 Mon Sep 17 00:00:00 2001 From: Aqua-sc <108478185+Aqua-sc@users.noreply.github.com> Date: Sun, 3 Mar 2024 13:18:57 +0100 Subject: [PATCH 33/40] Added testEntity --- .../controllers/JpaProjectController.java | 34 +++++++++++++++++ .../pidgeon/postgre/models/TestEntity.java | 37 +++++++++++++++++++ .../postgre/repository/TestRepository.java | 8 ++++ 3 files changed, 79 insertions(+) create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaProjectController.java create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/postgre/models/TestEntity.java create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/TestRepository.java diff --git a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaProjectController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaProjectController.java new file mode 100644 index 00000000..84835345 --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaProjectController.java @@ -0,0 +1,34 @@ +package com.ugent.pidgeon.controllers; + +import com.ugent.pidgeon.postgre.models.ProjectEntity; +import com.ugent.pidgeon.postgre.models.TestEntity; +import com.ugent.pidgeon.postgre.repository.ProjectRepository; +import com.ugent.pidgeon.postgre.repository.TestRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.ArrayList; +import java.util.List; + +@RestController +public class JpaProjectController { + @Autowired + private ProjectRepository projectRepository; + + @Autowired + private TestRepository testRepository; + + @GetMapping("/api/projects") + public List getProjects() { + List res = new ArrayList<>(); + for (ProjectEntity project : projectRepository.findAll()) { + StringBuilder projectString = new StringBuilder(project.getName()); + TestEntity test = testRepository.findById(project.getId()); + projectString.append(" with test: ").append(test.getId()); + + res.add(projectString.toString()); + } + return res; + } +} diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/TestEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/TestEntity.java new file mode 100644 index 00000000..394903a2 --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/TestEntity.java @@ -0,0 +1,37 @@ +package com.ugent.pidgeon.postgre.models; + +import jakarta.persistence.*; + +@Entity +@Table(name = "tests") +public class TestEntity { + + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "test_id", nullable = false) + private long id; + + @Column(name = "docker_image") + private String dockerImage; + + @Column(name = "file_test_id") + private long fileTestId; + + + public void setId(Long id) { + this.id = id; + } + + public Long getId() { + return id; + } + + public String getDockerImage() { + return dockerImage; + } + + public void setDockerImage(String dockerImage) { + this.dockerImage = dockerImage; + } +} diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/TestRepository.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/TestRepository.java new file mode 100644 index 00000000..b32403ef --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/TestRepository.java @@ -0,0 +1,8 @@ +package com.ugent.pidgeon.postgre.repository; + +import com.ugent.pidgeon.postgre.models.TestEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface TestRepository extends JpaRepository { + TestEntity findById(long id); +} From 18eb5d5f4e0d4bbb98447db17b3a706dc151d084 Mon Sep 17 00:00:00 2001 From: Aqua-sc <108478185+Aqua-sc@users.noreply.github.com> Date: Sun, 3 Mar 2024 13:30:07 +0100 Subject: [PATCH 34/40] Removed non-optionale findBy's + create FileEntity --- .../controllers/JpaProjectController.java | 5 +- .../controllers/JpaSubmissionController.java | 38 ++++++++++++++ .../pidgeon/postgre/models/FileEntity.java | 50 +++++++++++++++++++ .../postgre/repository/CourseRepository.java | 1 - .../postgre/repository/FileRepository.java | 7 +++ .../postgre/repository/GroupRepository.java | 1 - .../postgre/repository/TestRepository.java | 1 - .../postgre/repository/UserRepository.java | 3 -- 8 files changed, 98 insertions(+), 8 deletions(-) create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaSubmissionController.java create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/FileRepository.java diff --git a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaProjectController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaProjectController.java index 84835345..bcee992b 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaProjectController.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaProjectController.java @@ -10,6 +10,7 @@ import java.util.ArrayList; import java.util.List; +import java.util.Optional; @RestController public class JpaProjectController { @@ -24,8 +25,8 @@ public List getProjects() { List res = new ArrayList<>(); for (ProjectEntity project : projectRepository.findAll()) { StringBuilder projectString = new StringBuilder(project.getName()); - TestEntity test = testRepository.findById(project.getId()); - projectString.append(" with test: ").append(test.getId()); + Optional test = testRepository.findById(project.getId()); + test.ifPresent(testEntity -> projectString.append(" with test: ").append(testEntity.getId())); res.add(projectString.toString()); } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaSubmissionController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaSubmissionController.java new file mode 100644 index 00000000..4fabad41 --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaSubmissionController.java @@ -0,0 +1,38 @@ +package com.ugent.pidgeon.controllers; + +import com.ugent.pidgeon.postgre.models.FileEntity; +import com.ugent.pidgeon.postgre.models.SubmissionEntity; +import com.ugent.pidgeon.postgre.repository.FileRepository; +import com.ugent.pidgeon.postgre.repository.SubmissionRepository; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.RestController; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@RestController +public class JpaSubmissionController { + @Autowired + private SubmissionRepository submissionRepository; + + @Autowired + private FileRepository fileRepository; + + @GetMapping("/api/submissions") + public List getSubmissions() { + List res = new ArrayList<>(); + for (SubmissionEntity submission : submissionRepository.findAll()) { + StringBuilder submissionString = new StringBuilder(); + submissionString.append(submission.getSubmissionTime()).append(" with files: "); + Optional file = fileRepository.findById(submission.getFileId()); + file.ifPresent(fileEntity -> submissionString.append(fileEntity.getName()).append(", ")); + + submissionString.append("|"); + res.add(submissionString.toString()); + } + return res; + } + +} diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/FileEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/FileEntity.java index 65597385..3b16d1e2 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/FileEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/FileEntity.java @@ -1,4 +1,54 @@ package com.ugent.pidgeon.postgre.models; +import jakarta.persistence.*; + +@Entity +@Table(name = "files") public class FileEntity { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "file_id", nullable = false) + private long id; + + @Column(name = "file_name", nullable = false) + private String name; + + @Column(name = "file_path", nullable = false) + private String path; + + @Column(name = "uploaded_by", nullable = false) + private long uploadedBy; + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + + public String getName() { + return name; + } + + public void setName(String name) { + this.name = name; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public long getUploadedBy() { + return uploadedBy; + } + + public void setUploadedBy(long uploadedBy) { + this.uploadedBy = uploadedBy; + } } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/CourseRepository.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/CourseRepository.java index fdf7ffac..cf5fdeae 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/CourseRepository.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/CourseRepository.java @@ -9,7 +9,6 @@ public interface CourseRepository extends JpaRepository { - CourseEntity findById(long id); public interface UserWithRelation { diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/FileRepository.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/FileRepository.java new file mode 100644 index 00000000..b29e5711 --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/FileRepository.java @@ -0,0 +1,7 @@ +package com.ugent.pidgeon.postgre.repository; + +import com.ugent.pidgeon.postgre.models.FileEntity; +import org.springframework.data.jpa.repository.JpaRepository; + +public interface FileRepository extends JpaRepository { +} diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/GroupRepository.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/GroupRepository.java index a2fb8e4e..95c3cfb2 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/GroupRepository.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/GroupRepository.java @@ -9,7 +9,6 @@ import java.util.List; public interface GroupRepository extends JpaRepository{ - GroupEntity findById(long id); @Query(value= "SELECT u FROM UserEntity u JOIN GroupUserEntity gu ON u.id = gu.userId WHERE gu.groupId = ?1") List findCourseUsersByGroupId(long id); diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/TestRepository.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/TestRepository.java index b32403ef..cfa9cd32 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/TestRepository.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/TestRepository.java @@ -4,5 +4,4 @@ import org.springframework.data.jpa.repository.JpaRepository; public interface TestRepository extends JpaRepository { - TestEntity findById(long id); } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java index 615a7b1e..aa1f14d6 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java @@ -16,9 +16,6 @@ public interface UserRepository extends JpaRepository { - UserEntity findById(long id); - - public interface CourseWithRelation { CourseEntity getCourse(); CourseRelation getRelation(); From 23e3e2e723a4ce80083f1a712af116c066b18dbb Mon Sep 17 00:00:00 2001 From: Aqua-sc <108478185+Aqua-sc@users.noreply.github.com> Date: Sun, 3 Mar 2024 13:50:04 +0100 Subject: [PATCH 35/40] Added missing getters/setters/fields --- .../controllers/JpaUserController.java | 3 +-- .../pidgeon/postgre/models/CourseEntity.java | 11 ++++++++ .../postgre/models/CourseUserEntity.java | 9 +++++++ .../postgre/models/GroupClusterEntity.java | 13 ++++++++++ .../pidgeon/postgre/models/ProjectEntity.java | 8 ++++++ .../postgre/models/SubmissionEntity.java | 16 ++++++++++++ .../pidgeon/postgre/models/TestEntity.java | 8 ++++++ .../pidgeon/postgre/models/UserEntity.java | 26 +++++++++++++++++-- .../models/{ => types}/CourseRelation.java | 2 +- .../postgre/models/{ => types}/UserRole.java | 2 +- .../postgre/repository/UserRepository.java | 5 +--- 11 files changed, 93 insertions(+), 10 deletions(-) rename backend/app/src/main/java/com/ugent/pidgeon/postgre/models/{ => types}/CourseRelation.java (61%) rename backend/app/src/main/java/com/ugent/pidgeon/postgre/models/{ => types}/UserRole.java (56%) diff --git a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java index 97c494c8..7619473c 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaUserController.java @@ -1,13 +1,12 @@ package com.ugent.pidgeon.controllers; import com.ugent.pidgeon.postgre.models.CourseEntity; - import com.ugent.pidgeon.postgre.models.CourseRelation; + import com.ugent.pidgeon.postgre.models.types.CourseRelation; import com.ugent.pidgeon.postgre.models.UserEntity; import com.ugent.pidgeon.postgre.repository.UserRepository; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; - import org.springframework.data.util.Pair; import org.springframework.web.bind.annotation.GetMapping; import org.springframework.web.bind.annotation.RestController; diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseEntity.java index 008060e4..b5f0edf7 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseEntity.java @@ -2,6 +2,7 @@ import jakarta.persistence.*; +import java.sql.Timestamp; import java.util.HashSet; import java.util.Set; @@ -19,6 +20,9 @@ public class CourseEntity { @Column(name = "description", nullable=false) private String description; + @Column(name = "created_at") + private Timestamp createdAt; + public long getId() { @@ -48,4 +52,11 @@ public void setDescription(String description) { } + public Timestamp getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Timestamp createdAt) { + this.createdAt = createdAt; + } } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java index 84fe5e6c..37f5e5dc 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java @@ -1,5 +1,6 @@ package com.ugent.pidgeon.postgre.models; +import com.ugent.pidgeon.postgre.models.types.CourseRelation; import jakarta.persistence.*; import java.io.Serializable; @@ -37,6 +38,14 @@ public long getUserId() { public void setUserId(long userId) { this.userId = userId; } + + public CourseRelation getRelation() { + return relation; + } + + public void setRelation(CourseRelation relation) { + this.relation = relation; + } } class CourseUserId implements Serializable { diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupClusterEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupClusterEntity.java index 0027d96a..2fc49171 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupClusterEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupClusterEntity.java @@ -2,6 +2,8 @@ import jakarta.persistence.*; +import java.sql.Timestamp; + @Entity @Table(name="group_clusters") public class GroupClusterEntity { @@ -24,6 +26,9 @@ public class GroupClusterEntity { @Column(name="group_amount", nullable=false) private int groupAmount; + @Column(name = "created_at") + private Timestamp createdAt; + public long getId() { return id; } @@ -63,4 +68,12 @@ public int getGroupAmount() { public void setGroupAmount(int group_amount) { this.groupAmount = group_amount; } + + public Timestamp getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Timestamp createdAt) { + this.createdAt = createdAt; + } } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/ProjectEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/ProjectEntity.java index fd14afbe..74310bd6 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/ProjectEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/ProjectEntity.java @@ -101,4 +101,12 @@ public Timestamp getDeadline() { public void setDeadline(Timestamp deadline) { this.deadline = deadline; } + + public Integer getMaxScore() { + return maxScore; + } + + public void setMaxScore(Integer maxScore) { + this.maxScore = maxScore; + } } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/SubmissionEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/SubmissionEntity.java index b6a0abce..3e794f2c 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/SubmissionEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/SubmissionEntity.java @@ -55,4 +55,20 @@ public Boolean getAccepted() { public void setAccepted(Boolean accepted) { this.accepted = accepted; } + + public long getProjectId() { + return projectId; + } + + public void setProjectId(long projectId) { + this.projectId = projectId; + } + + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/TestEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/TestEntity.java index 394903a2..ed4bfe15 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/TestEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/TestEntity.java @@ -34,4 +34,12 @@ public String getDockerImage() { public void setDockerImage(String dockerImage) { this.dockerImage = dockerImage; } + + public long getFileTestId() { + return fileTestId; + } + + public void setFileTestId(long fileTestId) { + this.fileTestId = fileTestId; + } } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java index b7c46f7a..281789cc 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java @@ -1,10 +1,10 @@ package com.ugent.pidgeon.postgre.models; +import com.ugent.pidgeon.postgre.models.types.UserRole; import jakarta.persistence.*; -import java.util.HashSet; -import java.util.Set; +import java.sql.Timestamp; @Entity @Table(name = "users") @@ -28,6 +28,12 @@ public class UserEntity { @Enumerated(EnumType.STRING) private UserRole role; + @Column(name = "microsoft_token") + private String microsoftToken; + + @Column(name = "created_at") + private Timestamp createdAt; + public long getId() { return id; @@ -67,5 +73,21 @@ public void setEmail(String email) { public UserRole getRole() { return role; } + + public String getMicrosoftToken() { + return microsoftToken; + } + + public void setMicrosoftToken(String microsoftToken) { + this.microsoftToken = microsoftToken; + } + + public Timestamp getCreatedAt() { + return createdAt; + } + + public void setCreatedAt(Timestamp createdAt) { + this.createdAt = createdAt; + } } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseRelation.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/types/CourseRelation.java similarity index 61% rename from backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseRelation.java rename to backend/app/src/main/java/com/ugent/pidgeon/postgre/models/types/CourseRelation.java index fd58b851..8c0b254e 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseRelation.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/types/CourseRelation.java @@ -1,4 +1,4 @@ -package com.ugent.pidgeon.postgre.models; +package com.ugent.pidgeon.postgre.models.types; public enum CourseRelation { creator, diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserRole.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/types/UserRole.java similarity index 56% rename from backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserRole.java rename to backend/app/src/main/java/com/ugent/pidgeon/postgre/models/types/UserRole.java index a27cfd40..53997f1a 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserRole.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/types/UserRole.java @@ -1,4 +1,4 @@ -package com.ugent.pidgeon.postgre.models; +package com.ugent.pidgeon.postgre.models.types; public enum UserRole { student, diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java index aa1f14d6..bc1b5d86 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/repository/UserRepository.java @@ -1,13 +1,10 @@ package com.ugent.pidgeon.postgre.repository; -import com.ugent.pidgeon.model.User; import com.ugent.pidgeon.postgre.models.CourseEntity; -import com.ugent.pidgeon.postgre.models.CourseRelation; +import com.ugent.pidgeon.postgre.models.types.CourseRelation; import com.ugent.pidgeon.postgre.models.UserEntity; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.data.jpa.repository.Query; -import org.springframework.data.repository.query.Param; -import org.springframework.data.util.Pair; import org.springframework.stereotype.Repository; import java.util.List; From 5fe72ed4a6b2ebdcad2580a6df6290d1ef634c61 Mon Sep 17 00:00:00 2001 From: Aqua-sc <108478185+Aqua-sc@users.noreply.github.com> Date: Sun, 3 Mar 2024 14:04:15 +0100 Subject: [PATCH 36/40] Added multiple deadline support (Incase this isn't necessary we can always just go back to a single deadline field) --- .../controllers/JpaProjectController.java | 6 ++- .../postgre/models/DeadlineEntity.java | 45 +++++++++++++++++++ .../pidgeon/postgre/models/ProjectEntity.java | 14 +++--- 3 files changed, 55 insertions(+), 10 deletions(-) create mode 100644 backend/app/src/main/java/com/ugent/pidgeon/postgre/models/DeadlineEntity.java diff --git a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaProjectController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaProjectController.java index bcee992b..eb245d3d 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaProjectController.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaProjectController.java @@ -1,5 +1,6 @@ package com.ugent.pidgeon.controllers; +import com.ugent.pidgeon.postgre.models.DeadlineEntity; import com.ugent.pidgeon.postgre.models.ProjectEntity; import com.ugent.pidgeon.postgre.models.TestEntity; import com.ugent.pidgeon.postgre.repository.ProjectRepository; @@ -27,7 +28,10 @@ public List getProjects() { StringBuilder projectString = new StringBuilder(project.getName()); Optional test = testRepository.findById(project.getId()); test.ifPresent(testEntity -> projectString.append(" with test: ").append(testEntity.getId())); - + projectString.append(" with deadlines: "); + for (DeadlineEntity deadline : project.getDeadlines()) { + projectString.append(deadline.getDeadline()); + } res.add(projectString.toString()); } return res; diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/DeadlineEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/DeadlineEntity.java new file mode 100644 index 00000000..f1d78f9d --- /dev/null +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/DeadlineEntity.java @@ -0,0 +1,45 @@ +package com.ugent.pidgeon.postgre.models; + +import jakarta.persistence.*; + +import java.sql.Timestamp; + +@Entity +@Table(name = "deadlines") +public class DeadlineEntity { + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "deadline_id") + private Long deadlineId; + + @ManyToOne + @JoinColumn(name = "project_id") + private ProjectEntity project; + + @Column(name = "deadline") + private Timestamp deadline; + + public Long getDeadlineId() { + return deadlineId; + } + + public void setDeadlineId(Long deadlineId) { + this.deadlineId = deadlineId; + } + + public ProjectEntity getProject() { + return project; + } + + public void setProject(ProjectEntity project) { + this.project = project; + } + + public Timestamp getDeadline() { + return deadline; + } + + public void setDeadline(Timestamp deadline) { + this.deadline = deadline; + } +} diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/ProjectEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/ProjectEntity.java index 74310bd6..6cb8f3d2 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/ProjectEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/ProjectEntity.java @@ -2,6 +2,7 @@ import jakarta.persistence.*; import java.sql.Timestamp; +import java.util.List; @Entity @@ -31,8 +32,8 @@ public class ProjectEntity { @Column(name="visible", nullable = false) private Boolean projectType; - @Column(name="deadline", nullable = false) - private Timestamp deadline; + @OneToMany(mappedBy = "project") + private List deadlines; @Column(name="max_score") private Integer maxScore; @@ -94,14 +95,9 @@ public void setProjectType(Boolean projectType) { this.projectType = projectType; } - public Timestamp getDeadline() { - return deadline; + public List getDeadlines() { + return deadlines; } - - public void setDeadline(Timestamp deadline) { - this.deadline = deadline; - } - public Integer getMaxScore() { return maxScore; } From 51efb10292a2c78d336d756dc5a1e5115f3131af Mon Sep 17 00:00:00 2001 From: Aqua-sc <108478185+Aqua-sc@users.noreply.github.com> Date: Sun, 3 Mar 2024 14:18:57 +0100 Subject: [PATCH 37/40] Added constructors --- .../pidgeon/controllers/JpaCourseController.java | 16 +++++++--------- .../pidgeon/postgre/models/CourseEntity.java | 7 +++++++ .../pidgeon/postgre/models/CourseUserEntity.java | 11 +++++++++++ .../pidgeon/postgre/models/DeadlineEntity.java | 8 ++++++++ .../ugent/pidgeon/postgre/models/FileEntity.java | 9 +++++++++ .../postgre/models/GroupClusterEntity.java | 11 +++++++++++ .../pidgeon/postgre/models/GroupEntity.java | 9 +++++++++ .../postgre/models/GroupFeedbackEntity.java | 10 ++++++++++ .../pidgeon/postgre/models/GroupUserEntity.java | 8 ++++++++ .../pidgeon/postgre/models/ProjectEntity.java | 13 +++++++++++++ .../pidgeon/postgre/models/SubmissionEntity.java | 12 ++++++++++++ .../ugent/pidgeon/postgre/models/TestEntity.java | 8 ++++++++ .../ugent/pidgeon/postgre/models/UserEntity.java | 11 +++++++++++ 13 files changed, 124 insertions(+), 9 deletions(-) diff --git a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaCourseController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaCourseController.java index 276040d8..7991cf6f 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaCourseController.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/controllers/JpaCourseController.java @@ -45,13 +45,11 @@ public String getCourses() { return res.toString(); } - @GetMapping("/api/course") - public String addCourse(String name, String description) { - CourseEntity course = new CourseEntity(); - course.setId(1); - course.setName("Test"); - course.setDescription("Added for testing update purposes"); - courseRepository.save(course); - return "Course added"; - } +// @GetMapping("/api/course") +// public String addCourse(String name, String description) { +// CourseEntity course = new CourseEntity("test", "added to test creating with contstructing"); +// course.setId(1); +// courseRepository.save(course); +// return "Course added"; +// } } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseEntity.java index b5f0edf7..f5f6ebb5 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseEntity.java @@ -23,7 +23,14 @@ public class CourseEntity { @Column(name = "created_at") private Timestamp createdAt; + public CourseEntity(String name, String description) { + this.name = name; + this.description = description; + } + public CourseEntity() { + + } public long getId() { return id; diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java index 37f5e5dc..e29a5f56 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/CourseUserEntity.java @@ -22,6 +22,15 @@ public class CourseUserEntity { @Enumerated(EnumType.STRING) private CourseRelation relation; + public CourseUserEntity() { + } + + public CourseUserEntity(long courseId, long userId, CourseRelation relation) { + this.courseId = courseId; + this.userId = userId; + this.relation = relation; + } + public long getCourseId() { return courseId; @@ -46,6 +55,8 @@ public CourseRelation getRelation() { public void setRelation(CourseRelation relation) { this.relation = relation; } + + } class CourseUserId implements Serializable { diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/DeadlineEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/DeadlineEntity.java index f1d78f9d..b1db7050 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/DeadlineEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/DeadlineEntity.java @@ -19,6 +19,14 @@ public class DeadlineEntity { @Column(name = "deadline") private Timestamp deadline; + public DeadlineEntity() { + } + + public DeadlineEntity(ProjectEntity project, Timestamp deadline) { + this.project = project; + this.deadline = deadline; + } + public Long getDeadlineId() { return deadlineId; } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/FileEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/FileEntity.java index 3b16d1e2..f7e0acef 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/FileEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/FileEntity.java @@ -20,6 +20,15 @@ public class FileEntity { @Column(name = "uploaded_by", nullable = false) private long uploadedBy; + public FileEntity() { + } + + public FileEntity(String name, String path, long uploadedBy) { + this.name = name; + this.path = path; + this.uploadedBy = uploadedBy; + } + public long getId() { return id; } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupClusterEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupClusterEntity.java index 2fc49171..bc69f043 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupClusterEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupClusterEntity.java @@ -29,6 +29,17 @@ public class GroupClusterEntity { @Column(name = "created_at") private Timestamp createdAt; + public GroupClusterEntity(long courseId, int maxSize, String name, int groupAmount) { + this.courseId = courseId; + this.maxSize = maxSize; + this.name = name; + this.groupAmount = groupAmount; + } + + public GroupClusterEntity() { + + } + public long getId() { return id; } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupEntity.java index ac15bf7f..725aeea3 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupEntity.java @@ -17,6 +17,15 @@ public class GroupEntity { @Column(name="group_cluster", nullable = false) private long clusterId; + public GroupEntity(String name, long clusterId) { + this.name = name; + this.clusterId = clusterId; + } + + public GroupEntity() { + + } + public long getId() { return id; } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupFeedbackEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupFeedbackEntity.java index bf10ecaa..3bea7ca8 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupFeedbackEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupFeedbackEntity.java @@ -23,6 +23,16 @@ public class GroupFeedbackEntity { @Column(name = "feedback") private String feedback; + public GroupFeedbackEntity() { + } + + public GroupFeedbackEntity(long groupId, long projectId, Float grade, String feedback) { + this.groupId = groupId; + this.projectId = projectId; + this.grade = grade; + this.feedback = feedback; + } + public long getGroupId() { return groupId; } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupUserEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupUserEntity.java index bff40866..4b23d528 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupUserEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/GroupUserEntity.java @@ -16,6 +16,14 @@ public class GroupUserEntity { @Column(name="user_id", nullable=false) private long userId; + public GroupUserEntity() { + } + + public GroupUserEntity(long group_id, long user_id) { + this.groupId = group_id; + this.userId = user_id; + } + public long getGroupId() { return groupId; } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/ProjectEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/ProjectEntity.java index 6cb8f3d2..98a4de30 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/ProjectEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/ProjectEntity.java @@ -38,6 +38,19 @@ public class ProjectEntity { @Column(name="max_score") private Integer maxScore; + public ProjectEntity(long courseId, String name, String description, long groupClusterId, long testId, Boolean projectType, Integer maxScore) { + this.courseId = courseId; + this.name = name; + this.description = description; + this.groupClusterId = groupClusterId; + this.testId = testId; + this.projectType = projectType; + this.maxScore = maxScore; + } + + public ProjectEntity() { + } + public long getId() { return id; diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/SubmissionEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/SubmissionEntity.java index 3e794f2c..c43ba695 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/SubmissionEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/SubmissionEntity.java @@ -28,6 +28,17 @@ public class SubmissionEntity { @Column(name="accepted", nullable=false) private Boolean accepted; + public SubmissionEntity() { + } + + public SubmissionEntity(long projectId, long groupId, long fileId, Timestamp submissionTime, Boolean accepted) { + this.projectId = projectId; + this.groupId = groupId; + this.fileId = fileId; + this.submissionTime = submissionTime; + this.accepted = accepted; + } + public long getGroupId() { return groupId; } @@ -56,6 +67,7 @@ public void setAccepted(Boolean accepted) { this.accepted = accepted; } + public long getProjectId() { return projectId; } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/TestEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/TestEntity.java index ed4bfe15..a39cfb67 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/TestEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/TestEntity.java @@ -18,6 +18,14 @@ public class TestEntity { @Column(name = "file_test_id") private long fileTestId; + public TestEntity() { + } + + public TestEntity(String dockerImage, long fileTestId) { + this.dockerImage = dockerImage; + this.fileTestId = fileTestId; + } + public void setId(Long id) { this.id = id; diff --git a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java index 281789cc..76d629ab 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/postgre/models/UserEntity.java @@ -34,6 +34,17 @@ public class UserEntity { @Column(name = "created_at") private Timestamp createdAt; + public UserEntity(String name, String surname, String email, UserRole role, String microsoftToken) { + this.name = name; + this.surname = surname; + this.email = email; + this.role = role; + this.microsoftToken = microsoftToken; + } + + public UserEntity() { + + } public long getId() { return id; From 1e0135341a6d93a3fe04abcfaa7337371facb975 Mon Sep 17 00:00:00 2001 From: usserwoutV2 Date: Sun, 3 Mar 2024 15:22:33 +0100 Subject: [PATCH 38/40] Minor changes --- frontend/src/auth/AuthConfig.ts | 2 +- frontend/src/components/Logo.tsx | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/frontend/src/auth/AuthConfig.ts b/frontend/src/auth/AuthConfig.ts index 9ee22102..c5479d52 100644 --- a/frontend/src/auth/AuthConfig.ts +++ b/frontend/src/auth/AuthConfig.ts @@ -6,7 +6,7 @@ export const msalConfig: Configuration = { clientId: "39136cda-f02f-4305-9b08-45f132bab07e", //For UGent auth: "https://login.microsoftonline.com/d7811cde-ecef-496c-8f91-a1786241b99c", authority: "https://login.microsoftonline.com/d7811cde-ecef-496c-8f91-a1786241b99c", // "https://login.microsoftonline.com/62835335-e5c4-4d22-98f2-9d5b65a06d9d", - redirectUri: "/dashboard", + redirectUri: "/", postLogoutRedirectUri: "/" }, system: { diff --git a/frontend/src/components/Logo.tsx b/frontend/src/components/Logo.tsx index 5bafa75c..6a4636bc 100644 --- a/frontend/src/components/Logo.tsx +++ b/frontend/src/components/Logo.tsx @@ -10,7 +10,7 @@ const Logo:FC = (props) => { return - Pidgeon + Pidgeonhole } From 3a9591b83943c6b755889146e540487877b862e5 Mon Sep 17 00:00:00 2001 From: usserwoutV2 Date: Sun, 3 Mar 2024 20:53:20 +0100 Subject: [PATCH 39/40] Disabled csrf --- .../app/src/main/java/com/ugent/pidgeon/config/WebConfig.java | 1 + 1 file changed, 1 insertion(+) diff --git a/backend/app/src/main/java/com/ugent/pidgeon/config/WebConfig.java b/backend/app/src/main/java/com/ugent/pidgeon/config/WebConfig.java index 8b94ced5..738ea1d2 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/config/WebConfig.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/config/WebConfig.java @@ -2,6 +2,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.web.servlet.config.annotation.CorsRegistry; +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; @Configuration From 6494cc5edc72b62585fb4342132efc54a9bd9610 Mon Sep 17 00:00:00 2001 From: usserwoutV2 Date: Sun, 3 Mar 2024 20:54:10 +0100 Subject: [PATCH 40/40] Better types for api requests --- .../com/ugent/pidgeon/PidgeonApplication.java | 5 ---- .../com/ugent/pidgeon/config/AuthConfig.java | 3 ++- .../controllers/AuthTestController.java | 5 ++++ frontend/.env | 1 + frontend/src/@types/requests.d.ts | 26 +++++++++++++++++++ frontend/src/util/apiFetch.ts | 6 ++--- 6 files changed, 37 insertions(+), 9 deletions(-) create mode 100644 frontend/.env diff --git a/backend/app/src/main/java/com/ugent/pidgeon/PidgeonApplication.java b/backend/app/src/main/java/com/ugent/pidgeon/PidgeonApplication.java index 5ca00414..c600e2c2 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/PidgeonApplication.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/PidgeonApplication.java @@ -10,11 +10,6 @@ @SpringBootApplication public class PidgeonApplication { - @RequestMapping("/") - public String home(){ - return "hello world form spring!"; - } - public static void main(String[] args) { SpringApplication.run(PidgeonApplication.class, args); } diff --git a/backend/app/src/main/java/com/ugent/pidgeon/config/AuthConfig.java b/backend/app/src/main/java/com/ugent/pidgeon/config/AuthConfig.java index f0cdbef8..2ba50ca7 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/config/AuthConfig.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/config/AuthConfig.java @@ -6,6 +6,7 @@ import org.springframework.context.annotation.Configuration; import org.springframework.security.config.annotation.web.builders.HttpSecurity; import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity; +import org.springframework.security.config.annotation.web.configurers.AbstractHttpConfigurer; import org.springframework.security.web.SecurityFilterChain; @Configuration @@ -27,7 +28,7 @@ public FilterRegistrationBean filterRegistrationBean() @Bean public SecurityFilterChain web(HttpSecurity http) throws Exception { - http + http.csrf(AbstractHttpConfigurer::disable) .authorizeHttpRequests((authorize) -> authorize .anyRequest().permitAll() ); diff --git a/backend/app/src/main/java/com/ugent/pidgeon/controllers/AuthTestController.java b/backend/app/src/main/java/com/ugent/pidgeon/controllers/AuthTestController.java index 84c8082c..de342a07 100644 --- a/backend/app/src/main/java/com/ugent/pidgeon/controllers/AuthTestController.java +++ b/backend/app/src/main/java/com/ugent/pidgeon/controllers/AuthTestController.java @@ -3,6 +3,7 @@ import com.ugent.pidgeon.model.User; import jakarta.servlet.http.HttpServletRequest; import org.springframework.web.bind.annotation.GetMapping; +import org.springframework.web.bind.annotation.PostMapping; import org.springframework.web.bind.annotation.RestController; @RestController @@ -13,6 +14,10 @@ public User testApi(HttpServletRequest request, Auth auth) { return auth.getUser(); } + @PostMapping("/api/test2") + public String postTest(){ + return "Post test succeeded!"; + } @GetMapping("/ping") public String ping() { diff --git a/frontend/.env b/frontend/.env new file mode 100644 index 00000000..6a54b3e9 --- /dev/null +++ b/frontend/.env @@ -0,0 +1 @@ +PUBLIC_URL=/ \ No newline at end of file diff --git a/frontend/src/@types/requests.d.ts b/frontend/src/@types/requests.d.ts index ac24a756..6981ada0 100644 --- a/frontend/src/@types/requests.d.ts +++ b/frontend/src/@types/requests.d.ts @@ -20,6 +20,16 @@ export type POST_Requests = { } } + +/** + * The response you get from the POST request + */ +export type POST_Responses = { + [ApiRoutes.COURSES]: { + id: string + } +} + /** * the body of the PUT requests */ @@ -29,3 +39,19 @@ export type PUT_Requests = { } } +/** + * The response you get from the GET request + */ +export type GET_Responses = { + [ApiRoutes.COURSES]: { + id: string + name: string + }, + [ApiRoutes.TEST]: { + name: string + firstName: string + lastName: string + email: string + oid: string + } +} \ No newline at end of file diff --git a/frontend/src/util/apiFetch.ts b/frontend/src/util/apiFetch.ts index 4c7c98c5..d1808623 100644 --- a/frontend/src/util/apiFetch.ts +++ b/frontend/src/util/apiFetch.ts @@ -1,4 +1,4 @@ -import { ApiRoutes, POST_Requests, PUT_Requests } from "../@types/requests"; +import { ApiRoutes, GET_Responses, POST_Requests, POST_Responses, PUT_Requests } from "../@types/requests"; import axios, { AxiosResponse } from "axios"; import {msalInstance} from "../index"; import { AxiosRequestConfig } from "axios"; @@ -63,8 +63,8 @@ async function apiFetch(method: "GET" | "POST" | "PUT" | "D } const apiCall = { - get: async (route: T) => apiFetch("GET", route), - post: async (route: T, body: POST_Requests[T]) => apiFetch("POST", route, body), + get: async (route: T) => apiFetch("GET", route) as Promise>, + post: async (route: T, body: POST_Requests[T]) => apiFetch("POST", route, body) as Promise>, put: async (route: T, body: PUT_Requests[T]) => apiFetch("PUT", route, body), delete: async (route: T) => apiFetch("DELETE", route) }