Skip to content

Commit 90ea2d9

Browse files
committed
fix(fe): toast for add student error
1 parent 513908b commit 90ea2d9

5 files changed

Lines changed: 88 additions & 47 deletions

File tree

Frontend/changelog.md

Lines changed: 0 additions & 4 deletions
This file was deleted.

Frontend/i18n/locales/de-DE.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
"supervisor": {
5656
"manageStudents": "Studenten Verwalten",
5757
"noRequests": "Es gibt keine offenen Anfragen...",
58-
"slotsFilled": "Belegte Slots"
58+
"slotsFilled": "Freie Slots"
5959
}
6060
},
6161
"dataProtection": {
@@ -102,6 +102,7 @@
102102
"delete": "Löschen",
103103
"download": "Herunterladen",
104104
"edit": "Bearbeiten",
105+
"error": "Fehler",
105106
"english": "🇬🇧 English",
106107
"french": "🇫🇷 Français",
107108
"german": "🇩🇪 Deutsch",
@@ -120,6 +121,7 @@
120121
"showLess": "Weniger anzeigen",
121122
"spanish": "🇪🇸 Español",
122123
"student": "Studierende",
124+
"success": "Erfolgreich ausgeführt",
123125
"supervise": "Betreuen",
124126
"supervisionRequest": "Betreuungsanfrage",
125127
"supervisor": "Betreuende",

Frontend/i18n/locales/en-GB.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@
5555
"supervisor": {
5656
"manageStudents": "Manage Students",
5757
"noRequests": "There are no open requests...",
58-
"slotsFilled": "Slots filled"
58+
"slotsFilled": "Free slots"
5959
}
6060
},
6161
"dataProtection": {
@@ -102,6 +102,7 @@
102102
"delete": "delete",
103103
"download": "download",
104104
"edit": "Edit",
105+
"error": "Error",
105106
"english": "🇬🇧 English",
106107
"french": "🇫🇷 Français",
107108
"german": "🇩🇪 Deutsch",
@@ -120,6 +121,7 @@
120121
"showLess": "Show less",
121122
"spanish": "🇪🇸 Español",
122123
"student": "Student",
124+
"success": "Success",
123125
"supervise": "Supervise",
124126
"supervisionRequest": "Supervision request",
125127
"supervisor": "Supervisor",

Frontend/pages/supervisor/currently-supervising.vue

Lines changed: 44 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -16,13 +16,21 @@ const { getUserByEmail } = useUserApi();
1616
const current_user = ref<UserData | null>(null);
1717
const supervisor_data = ref<SupervisorData | null>(null);
1818
19+
const { t } = useI18n();
20+
1921
const {
2022
data: requests,
2123
pending,
2224
error,
2325
refresh,
2426
} = useSupervisionRequests("ACCEPTED");
2527
28+
const toastData = ref({
29+
visible: false,
30+
type: "success",
31+
message: "",
32+
});
33+
2634
const students = computed(() =>
2735
(requests.value ?? []).map((request) => ({
2836
id: request.student.user_id,
@@ -82,14 +90,33 @@ async function addStudent(email: string) {
8290
);
8391
8492
if (!existingStudent) {
85-
await $fetch("/api/supervision-requests", {
86-
method: "POST",
87-
body: {
88-
// This "id" usage is correct based on the current backend, even if you ide says its not
89-
supervisor_id: supervisor_data.value.id,
90-
student_email: email,
91-
},
92-
});
93+
try {
94+
await $fetch("/api/supervision-requests", {
95+
method: "POST",
96+
body: {
97+
// This "id" usage is correct based on the current backend, even if you ide says its not
98+
supervisor_id: supervisor_data.value.id,
99+
student_email: email,
100+
},
101+
});
102+
toastData.value = {
103+
visible: true,
104+
type: "success",
105+
message: t("generic.success"), // or any other suitable success message
106+
};
107+
} catch (err) {
108+
const errorMessage =
109+
(err as { data?: { message?: string }; message?: string })?.data
110+
?.message ||
111+
(err as { message?: string })?.message ||
112+
t("generic.error");
113+
114+
toastData.value = {
115+
visible: true,
116+
type: "error",
117+
message: errorMessage,
118+
};
119+
}
93120
}
94121
await refresh();
95122
}
@@ -106,7 +133,7 @@ definePageMeta({
106133
v-if="pending || error"
107134
class="w-full h-fit min-h-64 p-4 border border-base-300 rounded-3xl flex flex-col justify-center items-center"
108135
>
109-
<div v-if="pending">Loading…</div>
136+
<div v-if="pending">{{ t("generic.loading") }}</div>
110137
<div v-else-if="error" class="text-red-600">{{ error.message }}</div>
111138
</div>
112139
<!-- your IDE says that total_spots doesnt exists. Its lying. The interfaces are fucked up, we gotta fix that later-->
@@ -117,6 +144,14 @@ definePageMeta({
117144
@add-student="addStudent"
118145
@remove-student="removeStudent"
119146
/>
147+
<Toast
148+
v-if="toastData.visible"
149+
:duration="3000"
150+
:message="toastData.message"
151+
:type="toastData.type"
152+
@close="toastData.visible = false"
153+
@button-click="toastData.visible = false"
154+
/>
120155
</div>
121156
</template>
122157

Frontend/pages/supervisor/dashboard.vue

Lines changed: 38 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ import { useSupervisionRequests } from "~/composables/useSupervisionRequests";
77
import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome";
88
import EmptyPagePlaceholder from "~/components/Placeholder/EmptyPagePlaceholder.vue";
99
10-
const authStore = useAuthStore()
11-
const { user } = storeToRefs(authStore)
10+
const authStore = useAuthStore();
11+
const { user } = storeToRefs(authStore);
1212
const { getUserByEmail } = useUserApi();
1313
const { getSupervisorByUserId } = useSupervisorApi();
1414
const userStore = useUserStore();
@@ -33,15 +33,15 @@ const visibleRequests = computed(
3333
);
3434
3535
watch(
36-
() => user.value?.primaryEmailAddress?.emailAddress,
37-
async (email) => {
38-
if (!email) return;
36+
() => user.value?.primaryEmailAddress?.emailAddress,
37+
async (email) => {
38+
if (!email) return;
3939
40-
if (!userStore.user) {
41-
const fetched = (await getUserByEmail(email)) as UserData;
42-
userStore.setUser(fetched);
43-
}
44-
current_user.value = userStore.user;
40+
if (!userStore.user) {
41+
const fetched = (await getUserByEmail(email)) as UserData;
42+
userStore.setUser(fetched);
43+
}
44+
current_user.value = userStore.user;
4545
4646
if (current_user.value?.id) {
4747
const data = (await getSupervisorByUserId(
@@ -73,14 +73,14 @@ definePageMeta({
7373
<template>
7474
<div class="flex flex-col w-full gap-8 p-8">
7575
<ActionCard
76-
:button-text="t('dashboard.supervisor.manageStudents')"
77-
card-type="primary"
78-
class="w-full text-center"
79-
@action-button-clicked="navigate('/supervisor/currently-supervising')"
76+
:button-text="t('dashboard.supervisor.manageStudents')"
77+
card-type="primary"
78+
class="w-full text-center"
79+
@action-button-clicked="navigate('/supervisor/currently-supervising')"
8080
>
8181
<div class="py-8 px-16 w-full">
8282
<h2 class="text-xl">
83-
<FontAwesomeIcon icon="user-group"/>
83+
<FontAwesomeIcon icon="user-group" />
8484
{{
8585
// this works, even though the IDE tells you it doesnt. The frontend interface types are not consitent with the backend types. Dont ask why.
8686
(supervisor_data?.total_spots ?? 0) - (supervisor_data?.available_spots ?? 0)
@@ -93,31 +93,37 @@ definePageMeta({
9393
</ActionCard>
9494

9595
<ActionCard
96-
:button-text="t('generic.showAll')"
97-
:disabled="visibleCount >= (pendingRequests?.length ?? 0)"
98-
:header-text="t('generic.requests')"
99-
card-type="ghost"
100-
@action-button-clicked="navigateTo('/supervisor/matching')"
96+
:button-text="t('generic.showAll')"
97+
:disabled="visibleCount >= (pendingRequests?.length ?? 0)"
98+
:header-text="t('generic.requests')"
99+
card-type="ghost"
100+
@action-button-clicked="navigateTo('/supervisor/matching')"
101101
>
102102
<EmptyPagePlaceholder
103-
:render-condition="visibleRequests"
104-
:text="t('dashboard.supervisor.noRequests')"
103+
:render-condition="visibleRequests"
104+
:text="t('dashboard.supervisor.noRequests')"
105105
/>
106106
<NuxtLink
107-
v-for="request in visibleRequests"
108-
:key="request.id"
109-
:to="`/profiles/${request.student.user_id}`"
107+
v-for="request in visibleRequests"
108+
:key="request.id"
109+
:to="`/profiles/${request.student.user_id}`"
110110
>
111111
<MiniCard
112-
:bottom-text="formatTimeString(request.updated_at, undefined)"
113-
:first-name="request.student.user.first_name"
114-
:image="request.student.user.profile_image || getPlaceholderImage(request.student.user.first_name, request.student.user.last_name) || ''"
115-
:last-name="request.student.user.last_name"
116-
:preview-text="request.student.thesis_description"
117-
top-icon="message"
112+
:bottom-text="formatTimeString(request.updated_at, undefined)"
113+
:first-name="request.student.user.first_name"
114+
:image="
115+
request.student.user.profile_image ||
116+
getPlaceholderImage(
117+
request.student.user.first_name,
118+
request.student.user.last_name
119+
) ||
120+
''
121+
"
122+
:last-name="request.student.user.last_name"
123+
:preview-text="request.student.thesis_description"
124+
top-icon="message"
118125
/>
119126
</NuxtLink>
120-
121127
</ActionCard>
122128
</div>
123129
</template>

0 commit comments

Comments
 (0)