Skip to content

Commit

Permalink
Merge pull request #57 from IV1201-Group-2/develop
Browse files Browse the repository at this point in the history
Merge latest changes into main
hannesmann authored Mar 4, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature.
2 parents 49939cf + 3f3cac8 commit 613039d
Showing 30 changed files with 651 additions and 440 deletions.
Original file line number Diff line number Diff line change
@@ -2,11 +2,15 @@

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;
import lombok.extern.slf4j.Slf4j;
import jakarta.servlet.http.HttpServletRequest;

@Slf4j
@Controller
public class ServerController {
@GetMapping("")
public String acceptConnection() {
@GetMapping("/{path:[^\\.]*}")
public String acceptConnection(HttpServletRequest request) {
log.info("{} requested by {}", request.getRequestURI(), request.getRemoteAddr());
return "index.html";
}
}
19 changes: 19 additions & 0 deletions service/src/main/resources/logback.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="UTF-8"?>
<configuration>

<appender name="Console" class="ch.qos.logback.core.ConsoleAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>INFO</level>
</filter>
<encoder>
<pattern>
%-30(%d %p) %-30.30([%t] %C): %msg%n%throwable
</pattern>
</encoder>
</appender>

<root level="DEBUG">
<appender-ref ref="Console" />
</root>

</configuration>
85 changes: 5 additions & 80 deletions src/App.vue
Original file line number Diff line number Diff line change
@@ -1,86 +1,11 @@
<script setup lang="ts">
import { useI18n } from "vue-i18n";
import { RouterLink, RouterView } from "vue-router";
import { storeToRefs } from "pinia";
import { useAuthStore } from "./stores/auth";
const authStore = useAuthStore();
const { isAuthenticated } = storeToRefs(authStore);
const i18n = useI18n();
function changeLocale(locale: string) {
i18n.locale.value = locale;
}
import { RouterView } from "vue-router";
import Header from "./components/generic/PageHeader.vue";
import GenericError from "@/components/generic/GenericError.vue";
</script>

<template>
<header>
<nav>
<RouterLink v-if="isAuthenticated" @click="authStore.logout()" to="">{{ $t("navigation.logout") }}</RouterLink>
<RouterLink v-if="!isAuthenticated" to="/">{{ $t("navigation.login") }}</RouterLink>
<RouterLink v-if="!isAuthenticated" to="/register">{{ $t("navigation.register") }}</RouterLink>
</nav>
<v-btn>
<v-icon icon="mdi-translate" />
<v-menu activator="parent">
<v-list>
<v-list-item
v-for="language in i18n.availableLocales"
:key="language"
:value="language"
@click="() => changeLocale(language)"
>
<v-list-item-title>
{{ $t("languages." + language) }}
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-btn>
</header>

<Header />
<RouterView />
<GenericError />
</template>

<style scoped>
header {
line-height: 1.5;
max-height: 100vh;
width: 100%;
}
nav a.router-link-exact-active {
color: var(--color-text);
}
nav a.router-link-exact-active:hover {
background-color: transparent;
}
nav a {
display: inline-block;
padding: 0 1rem;
border-left: 1px solid var(--color-border);
}
nav a:first-of-type {
border: 0;
}
@media (min-width: 1024px) {
header {
display: flex;
flex-direction: row;
place-items: center;
justify-content: space-between;
}
.logo {
margin: 0 2rem 0 0;
}
nav {
text-align: left;
font-size: 1rem;
}
}
</style>
1 change: 0 additions & 1 deletion src/assets/logo.svg

This file was deleted.

41 changes: 41 additions & 0 deletions src/components/generic/GenericError.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<script setup lang="ts">
import { storeToRefs } from "pinia";
import { useErrorStore } from "@/stores/error";
import { useAuthStore } from "@/stores/auth";
import { useI18n } from "vue-i18n";
import router from "@/router";
import { computed } from "vue";
const errorStore = useErrorStore();
const authStore = useAuthStore();
const { t } = useI18n();
const { genericErrorMsgIsVisible, specificMsg } = storeToRefs(errorStore);
const { logout } = authStore;
const { hideGenericErrorMsg } = errorStore;
const basePath = "generic-error.";
const msg = computed(() => t(basePath + (specificMsg.value ? specificMsg.value : "generic-msg")));
function resetPage() {
logout();
router.push("/");
hideGenericErrorMsg();
}
</script>

<template>
<v-dialog persistent v-model="genericErrorMsgIsVisible" width="auto">
<v-card>
<v-card-title>
{{ $t(basePath + "header") }}
</v-card-title>
<v-card-text>
<div v-html="msg" />
</v-card-text>
<v-card-actions>
<v-spacer></v-spacer>
<v-btn @click="resetPage">{{ $t(basePath + "take-me-back") }}</v-btn>
</v-card-actions>
</v-card>
</v-dialog>
</template>
84 changes: 84 additions & 0 deletions src/components/generic/PageHeader.vue
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
<script setup lang="ts">
import { RouterLink } from "vue-router";
import { useI18n } from "vue-i18n";
import { storeToRefs } from "pinia";
import { useAuthStore } from "@/stores/auth";
const authStore = useAuthStore();
const { isAuthenticated } = storeToRefs(authStore);
const i18n = useI18n();
function changeLocale(locale: string) {
i18n.locale.value = locale;
}
</script>

<template>
<header>
<nav>
<RouterLink v-if="isAuthenticated" @click="authStore.logout()" to="">{{ $t("navigation.logout") }}</RouterLink>
<RouterLink v-if="!isAuthenticated" to="/">{{ $t("navigation.login") }}</RouterLink>
<RouterLink v-if="!isAuthenticated" to="/register">{{ $t("navigation.register") }}</RouterLink>
</nav>
<v-btn>
<v-icon icon="mdi-translate" />
<v-menu activator="parent">
<v-list>
<v-list-item
v-for="language in i18n.availableLocales"
:key="language"
:value="language"
@click="() => changeLocale(language)"
>
<v-list-item-title>
{{ $t("languages." + language) }}
</v-list-item-title>
</v-list-item>
</v-list>
</v-menu>
</v-btn>
</header>
</template>

<style scoped>
header {
line-height: 1.5;
max-height: 100vh;
width: 100%;
}
nav a.router-link-exact-active {
color: var(--color-text);
}
nav a.router-link-exact-active:hover {
background-color: transparent;
}
nav a {
display: inline-block;
padding: 0 1rem;
border-left: 1px solid var(--color-border);
}
nav a:first-of-type {
border: 0;
}
@media (min-width: 1024px) {
header {
display: flex;
flex-direction: row;
place-items: center;
justify-content: space-between;
}
.logo {
margin: 0 2rem 0 0;
}
nav {
text-align: left;
font-size: 1rem;
}
}
</style>
31 changes: 18 additions & 13 deletions src/components/generic/PersonalInformation.vue
Original file line number Diff line number Diff line change
@@ -3,7 +3,10 @@ import { ApplicationTestId } from "@/util/enums";
import { ref } from "vue";
import { storeToRefs } from "pinia";
import { useAuthStore } from "@/stores/auth";
import { useErrorStore } from "@/stores/error";
import { BASE_URL } from "@/util/api";
const { loginToken, role } = storeToRefs(useAuthStore());
const { showGenericErrorMsg } = useErrorStore();
const props = defineProps({
basePath: {
type: String,
@@ -34,7 +37,7 @@ function getPersonalInformation() {
params = props.personId;
}
const url = "https://personal-info-service-f25ca556a7c9.herokuapp.com/api/applicant/personal-info/" + params;
const url = BASE_URL.PERSONAL_INFORMATION + "/api/applicant/personal-info/" + params;
let options = {
method: "GET",
headers: {
@@ -43,18 +46,20 @@ function getPersonalInformation() {
}
};
fetch(url, options).then((response) => {
if (response.status !== 200) {
throw "could not get personal information, status code: " + response.status;
} else {
response.json().then((result) => {
firstNameInput.value = result.name;
lastNameInput.value = result.surname;
personNumberInput.value = result.pnr;
emailInput.value = result.email;
});
}
});
fetch(url, options)
.then((response) => {
if (response.status !== 200) {
showGenericErrorMsg();
} else {
response.json().then((result) => {
firstNameInput.value = result.name;
lastNameInput.value = result.surname;
personNumberInput.value = result.pnr;
emailInput.value = result.email;
});
}
})
.catch(() => showGenericErrorMsg("cannot-fetch-data"));
}
</script>

46 changes: 39 additions & 7 deletions src/components/handle_application/StatusCard.vue
Original file line number Diff line number Diff line change
@@ -1,29 +1,38 @@
<script setup lang="ts">
import type { Statuses, StatusKeys } from "@/util/types";
import { statuses } from "@/util/constants";
import { computed, ref } from "vue";
import { storeToRefs } from "pinia";
import { useAuthStore } from "@/stores/auth";
import { useStatusStore } from "@/stores/status";
import { useErrorStore } from "@/stores/error";
import { useI18n } from "vue-i18n";
import { BASE_URL } from "@/util/api";
const { loginToken } = storeToRefs(useAuthStore());
const { applicantId, status } = storeToRefs(useStatusStore());
const { showGenericErrorMsg } = useErrorStore();
const { t } = useI18n();
const basePath = "recruiter.handle-application.";
const statusPath = basePath + "status.";
const actionsPath = statusPath + "actions.";
const undoMsgPath = statusPath + "undo-message.";
const status = ref(statuses.pending);
const isHandled = computed(() => status.value.i18nPath !== statuses.pending.i18nPath);
const applicantStatus = ref(statuses[(status.value.charAt(0).toLowerCase() + status.value.slice(1)) as keyof Statuses]);
const isHandled = computed(() => applicantStatus.value.i18nPath !== statuses.pending.i18nPath);
const dialogIsVisible = ref(false);
const undoMsgBody = computed(() => t(undoMsgPath + "body"));
function accept() {
status.value = statuses.accepted;
submitStatus(statuses.accept.i18nPath as keyof Statuses);
}
function reject() {
status.value = statuses.rejected;
submitStatus(statuses.reject.i18nPath as keyof Statuses);
}
function undo() {
status.value = statuses.pending;
submitStatus(statuses.pending.i18nPath as keyof Statuses);
hideDialog();
}
@@ -34,6 +43,29 @@ function showDialog() {
function hideDialog() {
dialogIsVisible.value = false;
}
function submitStatus(statusKey: StatusKeys) {
fetch(BASE_URL.APPLICATION_STATUS + "/api/applicant", {
method: "POST",
headers: {
"Content-Type": "application/json",
Authorization: `Bearer:${loginToken.value}`
},
body: JSON.stringify({ person_id: applicantId.value, status: captializeFirstLetter(statuses[statusKey].i18nPath) })
})
.then((response) => {
if (response.status !== 200) {
showGenericErrorMsg();
} else {
applicantStatus.value = statuses[statusKey];
}
})
.catch(() => showGenericErrorMsg());
function captializeFirstLetter(str: string): string {
return str.charAt(0).toUpperCase() + str.slice(1);
}
}
</script>

<template>
@@ -42,8 +74,8 @@ function hideDialog() {
{{ $t(statusPath + "header") }}
</template>
<v-card-item>
<v-chip :color="status.color" :append-icon="status.icon">
{{ $t(statusPath + status.i18nPath) }}
<v-chip :color="applicantStatus.color" :append-icon="applicantStatus.icon">
{{ $t(statusPath + applicantStatus.i18nPath) }}
</v-chip>
</v-card-item>
<v-card-actions>
Loading

0 comments on commit 613039d

Please sign in to comment.