From aacff36893a823a39a71d1747805082ccfcde9b4 Mon Sep 17 00:00:00 2001 From: None of your business Date: Fri, 13 Jun 2025 14:16:48 +0200 Subject: [PATCH 01/11] fixes(fe): added translation for pending request, added translation for matching swipe right request modal headline, added text to swiping to make it more clear and improve ux, delete data gives a (fake) toast that data is deleted --- Frontend/changelog.md | 4 + .../SwipeContainer/SwipeContainer.vue | 195 ++++++++++-------- Frontend/i18n/locales/de-DE.json | 8 +- Frontend/i18n/locales/en-GB.json | 8 +- Frontend/pages/admin/data-protection.vue | 50 +++-- Frontend/pages/student/data-protection.vue | 95 +++++---- Frontend/pages/student/matching.vue | 12 +- Frontend/pages/student/requests.vue | 119 ++++++----- Frontend/pages/supervisor/data-protection.vue | 95 +++++---- 9 files changed, 326 insertions(+), 260 deletions(-) create mode 100644 Frontend/changelog.md diff --git a/Frontend/changelog.md b/Frontend/changelog.md new file mode 100644 index 00000000..f7394663 --- /dev/null +++ b/Frontend/changelog.md @@ -0,0 +1,4 @@ +- added translation for pending request +- added translation for matching swipe right request modal headline +- added text to swiping to make it more clear and improve ux +- delete data gives a (fake) toast that data is deleted \ No newline at end of file diff --git a/Frontend/components/SwipeContainer/SwipeContainer.vue b/Frontend/components/SwipeContainer/SwipeContainer.vue index ffaf82de..03d8ae81 100644 --- a/Frontend/components/SwipeContainer/SwipeContainer.vue +++ b/Frontend/components/SwipeContainer/SwipeContainer.vue @@ -1,113 +1,132 @@ \ No newline at end of file + + diff --git a/Frontend/i18n/locales/de-DE.json b/Frontend/i18n/locales/de-DE.json index 79b944ab..ee359678 100644 --- a/Frontend/i18n/locales/de-DE.json +++ b/Frontend/i18n/locales/de-DE.json @@ -152,7 +152,8 @@ "dataDeletionSubtitle": "🗑 Datenlöschung", "deleteMyData": "Meine Daten löschen", "generalInfoText": "Bei SuperWise nehmen wir Ihre Privatsphäre und den Schutz Ihrer persönlichen Daten sehr ernst. Diese Richtlinie beschreibt, wie wir Ihre Daten erfassen, verwenden und verwalten – für maximale Transparenz und Ihr beruhigtes Gewissen.", - "generalInfoTitle": "🛡️ SuperWise Datenschutzrichtlinie" + "generalInfoTitle": "🛡️ SuperWise Datenschutzrichtlinie", + "dataDeleted": "Daten erfolgreich gelöscht" }, "student&supervisor": { "changesAndOverwritesText": "Wenn Sie persönliche Daten wie Ihren Namen, Ihr Profilbild, die Themenbeschreibung oder die Biografie aktualisieren, wird die vorherige Version dauerhaft überschrieben. Wir speichern keine früheren Versionen oder Backups Ihrer persönlichen Daten.", @@ -226,6 +227,9 @@ "sentRequest": "Betreuungsanfrage wurde gesendet", "supervisionRequest": "{name} will von dir betreut werden!", "supervisorDismissed": "Betreuer wurde abgelehnt", + "swipeRightHeadline": "{firstName} {lastName} anfragen", + "swipeLeftText": "Anfragen", + "swipeRightText": "Entfernen", "swipeLeft": { "description": "Wenn Sie {firstName} {lastName} entfernen, wird er nie wieder vorgeschlagen, Sie können jedoch weiterhin nach ihm suchen. Sind Sie sicher, dass Sie fortfahren möchten?", "headline": "Betreuer entfernen", @@ -241,7 +245,7 @@ "confirm": "Bestätigen", "dontShowAgain": "Nicht mehr anzeigen", "sendSupervisionRequestHeadline": "Betreuungsanfrage senden", - "supervisionInfo": "Wenn du eine Anfrage zur Betreuung einer Abschlussarbeit sendest, wird diese an die ausgewählten Betreuenden weitergeleitet. Sie können dann entscheiden, ob sie die Anfrage annehmen oder ablehnen möchten. Wenn sie die Anfrage annehmen, wird eine Bestätigung erstellt, die du herunterladen kannst.", + "supervisionInfo": "Wenn du eine Anfrage an {firstName} {lastName} sendest, wird er/sie benachrichtigt und kann die Anfrage annehmen oder ablehnen. Wenn er/sie die Anfrage annimmt, erhältst Du eine automatisch erstellte Bestätigung, die du herunterladen kannst. Wenn er/sie ablehnt, solltest du einen weiteren Betreuer anfragen.", "withdrawSupervisionConfirm": "Anfrage zurückziehen", "withdrawSupervisionDescription": "Möchten Sie die Betreuungsanfrage von {name} zurückziehen? Nach dem Zurückziehen kann der Betreuer diese Anfrage nicht mehr sehen.", "withdrawSupervisionHeadline": "Betreuungsanfrage zurückziehen" diff --git a/Frontend/i18n/locales/en-GB.json b/Frontend/i18n/locales/en-GB.json index f20f67e1..712850a7 100644 --- a/Frontend/i18n/locales/en-GB.json +++ b/Frontend/i18n/locales/en-GB.json @@ -152,7 +152,8 @@ "dataDeletionSubtitle": "🗑 Data Deletion", "deleteMyData": "Delete my data", "generalInfoText": "At SuperWise, we take your privacy and the protection of your personal data seriously. This policy outlines how we collect, use, and manage your information to ensure transparency and your peace of mind.", - "generalInfoTitle": "🛡 SuperWise Data Protection Policy" + "generalInfoTitle": "🛡 SuperWise Data Protection Policy", + "dataDeleted": "Data deleted successfully" }, "student&supervisor": { "changesAndOverwritesText": "When you update your personal data, such as your name, profile picture, topic description, or bio, the previous version is permanently overwritten. We do not retain copies or backups of your previous personal data.", @@ -226,6 +227,9 @@ "sentRequest": "Supervision request has been sent", "supervisionRequest": "{name} wants to be supervised by you!", "supervisorDismissed": "Supervisor has been dismissed", + "swipeRightHeadline": "Request {firstName} {lastName}", + "swipeLeftText": "Request", + "swipeRightText": "Reject", "swipeLeft": { "description": "By dismissing {firstName} {lastName}, they will never get suggested again, but you can still search for them. Are you sure you want to do this?", "headline": "Dismiss Supervisor", @@ -241,7 +245,7 @@ "confirm": "Confirm", "dontShowAgain": "Don't show again", "sendSupervisionRequestHeadline": "Send supervision request", - "supervisionInfo": "When you send a thesis supervision request, it will be forwarded to the selected supervisors. They can then decide whether to accept or decline the request. If they accept the request, a confirmation will be created that you can download.", + "supervisionInfo": "When you send a thesis supervision request to {firstName} {lastName}, they will be notified and can accept or deny your request. If they accept the request, a confirmation will be created that you can download, otherwise you will need to choose a different supervisor.", "withdrawSupervisionConfirm": "Withdraw Request", "withdrawSupervisionDescription": "Would you like to withdraw the supervision request from {name}? Once withdrawn, the supervisor will no longer see this request.", "withdrawSupervisionHeadline": "Withdraw Supervision Request" diff --git a/Frontend/pages/admin/data-protection.vue b/Frontend/pages/admin/data-protection.vue index 31cdce25..53539f3b 100644 --- a/Frontend/pages/admin/data-protection.vue +++ b/Frontend/pages/admin/data-protection.vue @@ -1,5 +1,4 @@ diff --git a/Frontend/pages/student/matching.vue b/Frontend/pages/student/matching.vue index 05939c97..4b575b62 100644 --- a/Frontend/pages/student/matching.vue +++ b/Frontend/pages/student/matching.vue @@ -6,6 +6,8 @@ :key="supervisor.supervisor_userId || index" :ref="(el) => setItemRef(el, supervisor.supervisor_userId)" class="mb-4" + :swipe-left-text="t('matching.swipeLeftText')" + :swipe-right-text="t('matching.swipeRightText')" @swipe-left="handleSwipeLeft(supervisor)" @swipe-right="handleSwipeRight(supervisor)" > @@ -170,10 +172,16 @@ const handleSwipeRight = async (supervisor: SupervisorData) => { removedSupervisor.value = supervisor; modalInformation.value = { type: supervisionRequestType.CONFIRM, - headline: `Request ${supervisor.firstName} ${supervisor.lastName}`, + headline: t("matching.swipeRightHeadline", { + firstName: supervisor.firstName, + lastName: supervisor.lastName, + }), icon: "", warning: "", - description: t("modal.supervisionInfo"), + description: t("modal.supervisionInfo", { + firstName: supervisor.firstName, + lastName: supervisor.lastName, + }), confirmButtonText: t("modal.confirm"), confirmButtonColor: "primary", supervisor: supervisor, diff --git a/Frontend/pages/student/requests.vue b/Frontend/pages/student/requests.vue index afd2c355..c9fed4ec 100644 --- a/Frontend/pages/student/requests.vue +++ b/Frontend/pages/student/requests.vue @@ -1,7 +1,11 @@ From b034ccab24d99c2ceb47556f8d42f1fa437afbff Mon Sep 17 00:00:00 2001 From: None of your business Date: Tue, 17 Jun 2025 20:13:06 +0200 Subject: [PATCH 02/11] fix(fe): toast for add student error --- Frontend/changelog.md | 4 -- Frontend/i18n/locales/de-DE.json | 4 +- Frontend/i18n/locales/en-GB.json | 4 +- .../supervisor/currently-supervising.vue | 53 +++++++++++--- Frontend/pages/supervisor/dashboard.vue | 70 ++++++++++--------- 5 files changed, 88 insertions(+), 47 deletions(-) delete mode 100644 Frontend/changelog.md diff --git a/Frontend/changelog.md b/Frontend/changelog.md deleted file mode 100644 index f7394663..00000000 --- a/Frontend/changelog.md +++ /dev/null @@ -1,4 +0,0 @@ -- added translation for pending request -- added translation for matching swipe right request modal headline -- added text to swiping to make it more clear and improve ux -- delete data gives a (fake) toast that data is deleted \ No newline at end of file diff --git a/Frontend/i18n/locales/de-DE.json b/Frontend/i18n/locales/de-DE.json index ee359678..40218514 100644 --- a/Frontend/i18n/locales/de-DE.json +++ b/Frontend/i18n/locales/de-DE.json @@ -129,7 +129,7 @@ "supervisor": { "manageStudents": "Studenten Verwalten", "noRequests": "Es gibt keine offenen Anfragen...", - "slotsFilled": "Belegte Slots" + "slotsFilled": "Freie Slots" } }, "dataProtection": { @@ -178,6 +178,7 @@ "done": "Fertig", "download": "Herunterladen", "edit": "Bearbeiten", + "error": "Fehler", "english": "🇬🇧 English", "french": "🇫🇷 Français", "german": "🇩🇪 Deutsch", @@ -197,6 +198,7 @@ "showLess": "Weniger anzeigen", "spanish": "🇪🇸 Español", "student": "Studierende", + "success": "Erfolgreich ausgeführt", "supervise": "Betreuen", "supervisionRequest": "Betreuungsanfrage", "supervisor": "Betreuende", diff --git a/Frontend/i18n/locales/en-GB.json b/Frontend/i18n/locales/en-GB.json index 712850a7..2d2a9031 100644 --- a/Frontend/i18n/locales/en-GB.json +++ b/Frontend/i18n/locales/en-GB.json @@ -129,7 +129,7 @@ "supervisor": { "manageStudents": "Manage Students", "noRequests": "There are no open requests...", - "slotsFilled": "Slots filled" + "slotsFilled": "Free slots" } }, "dataProtection": { @@ -178,6 +178,7 @@ "done": "Done", "download": "Download", "edit": "Edit", + "error": "Error", "english": "🇬🇧 English", "french": "🇫🇷 Français", "german": "🇩🇪 Deutsch", @@ -197,6 +198,7 @@ "showLess": "Show less", "spanish": "🇪🇸 Español", "student": "Student", + "success": "Success", "supervise": "Supervise", "supervisionRequest": "Supervision request", "supervisor": "Supervisor", diff --git a/Frontend/pages/supervisor/currently-supervising.vue b/Frontend/pages/supervisor/currently-supervising.vue index de66145a..d413645a 100644 --- a/Frontend/pages/supervisor/currently-supervising.vue +++ b/Frontend/pages/supervisor/currently-supervising.vue @@ -17,6 +17,8 @@ const { getUserByEmail } = useUserApi(); const current_user = ref(null); const supervisor_data = ref(null); +const { t } = useI18n(); + const { data: requests, pending, @@ -24,6 +26,12 @@ const { refresh, } = useSupervisionRequests("ACCEPTED"); +const toastData = ref({ + visible: false, + type: "success", + message: "", +}); + const students = computed(() => (requests.value ?? []).map((request) => ({ id: request.student.user_id, @@ -83,14 +91,33 @@ async function addStudent(email: string) { ); if (!existingStudent) { - await $fetch("/api/supervision-requests", { - method: "POST", - body: { - // This "id" usage is correct based on the current backend, even if you ide says its not - supervisor_id: supervisor_data.value.id, - student_email: email, - }, - }); + try { + await $fetch("/api/supervision-requests", { + method: "POST", + body: { + // This "id" usage is correct based on the current backend, even if you ide says its not + supervisor_id: supervisor_data.value.id, + student_email: email, + }, + }); + toastData.value = { + visible: true, + type: "success", + message: t("generic.success"), // or any other suitable success message + }; + } catch (err) { + const errorMessage = + (err as { data?: { message?: string }; message?: string })?.data + ?.message || + (err as { message?: string })?.message || + t("generic.error"); + + toastData.value = { + visible: true, + type: "error", + message: errorMessage, + }; + } } await refresh(); } @@ -109,7 +136,7 @@ definePageMeta({ v-if="pending || error" class="w-full h-fit min-h-64 p-4 border border-base-300 rounded-3xl flex flex-col justify-center items-center" > -
Loading…
+
{{ t("generic.loading") }}
{{ error.message }}
@@ -120,6 +147,14 @@ definePageMeta({ @add-student="addStudent" @remove-student="removeStudent" /> + diff --git a/Frontend/pages/supervisor/dashboard.vue b/Frontend/pages/supervisor/dashboard.vue index 9e73ec02..99c7a80a 100644 --- a/Frontend/pages/supervisor/dashboard.vue +++ b/Frontend/pages/supervisor/dashboard.vue @@ -7,8 +7,8 @@ import { useSupervisionRequests } from "~/composables/useSupervisionRequests"; import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"; import EmptyPagePlaceholder from "~/components/Placeholder/EmptyPagePlaceholder.vue"; -const authStore = useAuthStore() -const { user } = storeToRefs(authStore) +const authStore = useAuthStore(); +const { user } = storeToRefs(authStore); const { getUserByEmail } = useUserApi(); const { getSupervisorByUserId } = useSupervisorApi(); const userStore = useUserStore(); @@ -33,15 +33,15 @@ const visibleRequests = computed( ); watch( - () => user.value?.primaryEmailAddress?.emailAddress, - async (email) => { - if (!email) return; + () => user.value?.primaryEmailAddress?.emailAddress, + async (email) => { + if (!email) return; - if (!userStore.user) { - const fetched = (await getUserByEmail(email)) as UserData; - userStore.setUser(fetched); - } - current_user.value = userStore.user; + if (!userStore.user) { + const fetched = (await getUserByEmail(email)) as UserData; + userStore.setUser(fetched); + } + current_user.value = userStore.user; if (current_user.value?.id) { const data = (await getSupervisorByUserId( @@ -73,14 +73,14 @@ definePageMeta({ From e238e0632490be878aafa2502f3b069985015e7a Mon Sep 17 00:00:00 2001 From: None of your business Date: Tue, 17 Jun 2025 20:17:57 +0200 Subject: [PATCH 03/11] fix(fe): fixed translation keys --- .../SupervisorStudentList.vue | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/Frontend/components/SupervisorStudentList/SupervisorStudentList.vue b/Frontend/components/SupervisorStudentList/SupervisorStudentList.vue index aac551b5..2e984aea 100644 --- a/Frontend/components/SupervisorStudentList/SupervisorStudentList.vue +++ b/Frontend/components/SupervisorStudentList/SupervisorStudentList.vue @@ -226,8 +226,10 @@ watch( lastName: studentToRemove?.lastName, }) " - :confirm-text="t('supervisorStudentList.removeStudent.confirmText')" - :checkbox-label="t('supervisorStudentList.checkboxLabel')" + :confirm-text=" + t('settings.supervisorStudentList.removeStudent.confirmText') + " + :checkbox-label="t('settings.supervisorStudentList.checkboxLabel')" setting-key="showRemoveStudentModal" :title="t('supervisorStudentList.removeStudent.title')" icon="trash" @@ -254,8 +256,10 @@ watch( }) " :show-checkbox="true" - :checkbox-label="t('supervisorStudentList.checkboxLabel')" - :confirm-text="t('supervisorStudentList.addExistingStudent.confirmText')" + :checkbox-label="t('settings.supervisorStudentList.checkboxLabel')" + :confirm-text=" + t('settings.supervisorStudentList.addExistingStudent.confirmText') + " icon="user-group" setting-key="showAddStudentModal" :sub-text="t('supervisorStudentList.addExistingStudent.subText')" @@ -273,14 +277,18 @@ watch( }) " :show-checkbox="true" - :checkbox-label="t('supervisorStudentList.checkboxLabel')" - confirm-text="" + :checkbox-label="t('settings.supervisorStudentList.checkboxLabel')" + :confirm-text=" + t('settings.supervisorStudentList.addNotExistingStudent.confirmText') + " icon="user-group" image-alt="Logo" image-src="../images/Superwise_Logo.svg" setting-key="showAddStudentModal" - :sub-text="t('supervisorStudentList.addExistingStudent.subText')" - :title="t('supervisorStudentList.addNewStudent.title')" + :sub-text=" + t('settings.supervisorStudentList.addNotExistingStudent.subText') + " + :title="t('settings.supervisorStudentList.addNewStudent.title')" @confirm="addStudent" /> From 532011594a56563067a3d62ec4ca05872792bda5 Mon Sep 17 00:00:00 2001 From: None of your business Date: Fri, 13 Jun 2025 14:16:48 +0200 Subject: [PATCH 04/11] fixes(fe): added translation for pending request, added translation for matching swipe right request modal headline, added text to swiping to make it more clear and improve ux, delete data gives a (fake) toast that data is deleted --- Frontend/changelog.md | 4 + .../SwipeContainer/SwipeContainer.vue | 195 ++++++++++-------- Frontend/i18n/locales/de-DE.json | 8 +- Frontend/i18n/locales/en-GB.json | 8 +- Frontend/pages/admin/data-protection.vue | 50 +++-- Frontend/pages/student/data-protection.vue | 95 +++++---- Frontend/pages/student/matching.vue | 12 +- Frontend/pages/student/requests.vue | 119 ++++++----- Frontend/pages/supervisor/data-protection.vue | 95 +++++---- 9 files changed, 326 insertions(+), 260 deletions(-) create mode 100644 Frontend/changelog.md diff --git a/Frontend/changelog.md b/Frontend/changelog.md new file mode 100644 index 00000000..f7394663 --- /dev/null +++ b/Frontend/changelog.md @@ -0,0 +1,4 @@ +- added translation for pending request +- added translation for matching swipe right request modal headline +- added text to swiping to make it more clear and improve ux +- delete data gives a (fake) toast that data is deleted \ No newline at end of file diff --git a/Frontend/components/SwipeContainer/SwipeContainer.vue b/Frontend/components/SwipeContainer/SwipeContainer.vue index ffaf82de..03d8ae81 100644 --- a/Frontend/components/SwipeContainer/SwipeContainer.vue +++ b/Frontend/components/SwipeContainer/SwipeContainer.vue @@ -1,113 +1,132 @@ \ No newline at end of file + + diff --git a/Frontend/i18n/locales/de-DE.json b/Frontend/i18n/locales/de-DE.json index 79b944ab..ee359678 100644 --- a/Frontend/i18n/locales/de-DE.json +++ b/Frontend/i18n/locales/de-DE.json @@ -152,7 +152,8 @@ "dataDeletionSubtitle": "🗑 Datenlöschung", "deleteMyData": "Meine Daten löschen", "generalInfoText": "Bei SuperWise nehmen wir Ihre Privatsphäre und den Schutz Ihrer persönlichen Daten sehr ernst. Diese Richtlinie beschreibt, wie wir Ihre Daten erfassen, verwenden und verwalten – für maximale Transparenz und Ihr beruhigtes Gewissen.", - "generalInfoTitle": "🛡️ SuperWise Datenschutzrichtlinie" + "generalInfoTitle": "🛡️ SuperWise Datenschutzrichtlinie", + "dataDeleted": "Daten erfolgreich gelöscht" }, "student&supervisor": { "changesAndOverwritesText": "Wenn Sie persönliche Daten wie Ihren Namen, Ihr Profilbild, die Themenbeschreibung oder die Biografie aktualisieren, wird die vorherige Version dauerhaft überschrieben. Wir speichern keine früheren Versionen oder Backups Ihrer persönlichen Daten.", @@ -226,6 +227,9 @@ "sentRequest": "Betreuungsanfrage wurde gesendet", "supervisionRequest": "{name} will von dir betreut werden!", "supervisorDismissed": "Betreuer wurde abgelehnt", + "swipeRightHeadline": "{firstName} {lastName} anfragen", + "swipeLeftText": "Anfragen", + "swipeRightText": "Entfernen", "swipeLeft": { "description": "Wenn Sie {firstName} {lastName} entfernen, wird er nie wieder vorgeschlagen, Sie können jedoch weiterhin nach ihm suchen. Sind Sie sicher, dass Sie fortfahren möchten?", "headline": "Betreuer entfernen", @@ -241,7 +245,7 @@ "confirm": "Bestätigen", "dontShowAgain": "Nicht mehr anzeigen", "sendSupervisionRequestHeadline": "Betreuungsanfrage senden", - "supervisionInfo": "Wenn du eine Anfrage zur Betreuung einer Abschlussarbeit sendest, wird diese an die ausgewählten Betreuenden weitergeleitet. Sie können dann entscheiden, ob sie die Anfrage annehmen oder ablehnen möchten. Wenn sie die Anfrage annehmen, wird eine Bestätigung erstellt, die du herunterladen kannst.", + "supervisionInfo": "Wenn du eine Anfrage an {firstName} {lastName} sendest, wird er/sie benachrichtigt und kann die Anfrage annehmen oder ablehnen. Wenn er/sie die Anfrage annimmt, erhältst Du eine automatisch erstellte Bestätigung, die du herunterladen kannst. Wenn er/sie ablehnt, solltest du einen weiteren Betreuer anfragen.", "withdrawSupervisionConfirm": "Anfrage zurückziehen", "withdrawSupervisionDescription": "Möchten Sie die Betreuungsanfrage von {name} zurückziehen? Nach dem Zurückziehen kann der Betreuer diese Anfrage nicht mehr sehen.", "withdrawSupervisionHeadline": "Betreuungsanfrage zurückziehen" diff --git a/Frontend/i18n/locales/en-GB.json b/Frontend/i18n/locales/en-GB.json index f20f67e1..712850a7 100644 --- a/Frontend/i18n/locales/en-GB.json +++ b/Frontend/i18n/locales/en-GB.json @@ -152,7 +152,8 @@ "dataDeletionSubtitle": "🗑 Data Deletion", "deleteMyData": "Delete my data", "generalInfoText": "At SuperWise, we take your privacy and the protection of your personal data seriously. This policy outlines how we collect, use, and manage your information to ensure transparency and your peace of mind.", - "generalInfoTitle": "🛡 SuperWise Data Protection Policy" + "generalInfoTitle": "🛡 SuperWise Data Protection Policy", + "dataDeleted": "Data deleted successfully" }, "student&supervisor": { "changesAndOverwritesText": "When you update your personal data, such as your name, profile picture, topic description, or bio, the previous version is permanently overwritten. We do not retain copies or backups of your previous personal data.", @@ -226,6 +227,9 @@ "sentRequest": "Supervision request has been sent", "supervisionRequest": "{name} wants to be supervised by you!", "supervisorDismissed": "Supervisor has been dismissed", + "swipeRightHeadline": "Request {firstName} {lastName}", + "swipeLeftText": "Request", + "swipeRightText": "Reject", "swipeLeft": { "description": "By dismissing {firstName} {lastName}, they will never get suggested again, but you can still search for them. Are you sure you want to do this?", "headline": "Dismiss Supervisor", @@ -241,7 +245,7 @@ "confirm": "Confirm", "dontShowAgain": "Don't show again", "sendSupervisionRequestHeadline": "Send supervision request", - "supervisionInfo": "When you send a thesis supervision request, it will be forwarded to the selected supervisors. They can then decide whether to accept or decline the request. If they accept the request, a confirmation will be created that you can download.", + "supervisionInfo": "When you send a thesis supervision request to {firstName} {lastName}, they will be notified and can accept or deny your request. If they accept the request, a confirmation will be created that you can download, otherwise you will need to choose a different supervisor.", "withdrawSupervisionConfirm": "Withdraw Request", "withdrawSupervisionDescription": "Would you like to withdraw the supervision request from {name}? Once withdrawn, the supervisor will no longer see this request.", "withdrawSupervisionHeadline": "Withdraw Supervision Request" diff --git a/Frontend/pages/admin/data-protection.vue b/Frontend/pages/admin/data-protection.vue index 31cdce25..53539f3b 100644 --- a/Frontend/pages/admin/data-protection.vue +++ b/Frontend/pages/admin/data-protection.vue @@ -1,5 +1,4 @@ diff --git a/Frontend/pages/student/matching.vue b/Frontend/pages/student/matching.vue index 05939c97..4b575b62 100644 --- a/Frontend/pages/student/matching.vue +++ b/Frontend/pages/student/matching.vue @@ -6,6 +6,8 @@ :key="supervisor.supervisor_userId || index" :ref="(el) => setItemRef(el, supervisor.supervisor_userId)" class="mb-4" + :swipe-left-text="t('matching.swipeLeftText')" + :swipe-right-text="t('matching.swipeRightText')" @swipe-left="handleSwipeLeft(supervisor)" @swipe-right="handleSwipeRight(supervisor)" > @@ -170,10 +172,16 @@ const handleSwipeRight = async (supervisor: SupervisorData) => { removedSupervisor.value = supervisor; modalInformation.value = { type: supervisionRequestType.CONFIRM, - headline: `Request ${supervisor.firstName} ${supervisor.lastName}`, + headline: t("matching.swipeRightHeadline", { + firstName: supervisor.firstName, + lastName: supervisor.lastName, + }), icon: "", warning: "", - description: t("modal.supervisionInfo"), + description: t("modal.supervisionInfo", { + firstName: supervisor.firstName, + lastName: supervisor.lastName, + }), confirmButtonText: t("modal.confirm"), confirmButtonColor: "primary", supervisor: supervisor, diff --git a/Frontend/pages/student/requests.vue b/Frontend/pages/student/requests.vue index afd2c355..c9fed4ec 100644 --- a/Frontend/pages/student/requests.vue +++ b/Frontend/pages/student/requests.vue @@ -1,7 +1,11 @@ From 834692aa187e99d1b0cbc3f1399af60bea639c43 Mon Sep 17 00:00:00 2001 From: None of your business Date: Tue, 17 Jun 2025 20:13:06 +0200 Subject: [PATCH 05/11] fix(fe): toast for add student error --- Frontend/changelog.md | 4 -- Frontend/i18n/locales/de-DE.json | 4 +- Frontend/i18n/locales/en-GB.json | 4 +- .../supervisor/currently-supervising.vue | 53 +++++++++++--- Frontend/pages/supervisor/dashboard.vue | 70 ++++++++++--------- 5 files changed, 88 insertions(+), 47 deletions(-) delete mode 100644 Frontend/changelog.md diff --git a/Frontend/changelog.md b/Frontend/changelog.md deleted file mode 100644 index f7394663..00000000 --- a/Frontend/changelog.md +++ /dev/null @@ -1,4 +0,0 @@ -- added translation for pending request -- added translation for matching swipe right request modal headline -- added text to swiping to make it more clear and improve ux -- delete data gives a (fake) toast that data is deleted \ No newline at end of file diff --git a/Frontend/i18n/locales/de-DE.json b/Frontend/i18n/locales/de-DE.json index ee359678..40218514 100644 --- a/Frontend/i18n/locales/de-DE.json +++ b/Frontend/i18n/locales/de-DE.json @@ -129,7 +129,7 @@ "supervisor": { "manageStudents": "Studenten Verwalten", "noRequests": "Es gibt keine offenen Anfragen...", - "slotsFilled": "Belegte Slots" + "slotsFilled": "Freie Slots" } }, "dataProtection": { @@ -178,6 +178,7 @@ "done": "Fertig", "download": "Herunterladen", "edit": "Bearbeiten", + "error": "Fehler", "english": "🇬🇧 English", "french": "🇫🇷 Français", "german": "🇩🇪 Deutsch", @@ -197,6 +198,7 @@ "showLess": "Weniger anzeigen", "spanish": "🇪🇸 Español", "student": "Studierende", + "success": "Erfolgreich ausgeführt", "supervise": "Betreuen", "supervisionRequest": "Betreuungsanfrage", "supervisor": "Betreuende", diff --git a/Frontend/i18n/locales/en-GB.json b/Frontend/i18n/locales/en-GB.json index 712850a7..2d2a9031 100644 --- a/Frontend/i18n/locales/en-GB.json +++ b/Frontend/i18n/locales/en-GB.json @@ -129,7 +129,7 @@ "supervisor": { "manageStudents": "Manage Students", "noRequests": "There are no open requests...", - "slotsFilled": "Slots filled" + "slotsFilled": "Free slots" } }, "dataProtection": { @@ -178,6 +178,7 @@ "done": "Done", "download": "Download", "edit": "Edit", + "error": "Error", "english": "🇬🇧 English", "french": "🇫🇷 Français", "german": "🇩🇪 Deutsch", @@ -197,6 +198,7 @@ "showLess": "Show less", "spanish": "🇪🇸 Español", "student": "Student", + "success": "Success", "supervise": "Supervise", "supervisionRequest": "Supervision request", "supervisor": "Supervisor", diff --git a/Frontend/pages/supervisor/currently-supervising.vue b/Frontend/pages/supervisor/currently-supervising.vue index de66145a..d413645a 100644 --- a/Frontend/pages/supervisor/currently-supervising.vue +++ b/Frontend/pages/supervisor/currently-supervising.vue @@ -17,6 +17,8 @@ const { getUserByEmail } = useUserApi(); const current_user = ref(null); const supervisor_data = ref(null); +const { t } = useI18n(); + const { data: requests, pending, @@ -24,6 +26,12 @@ const { refresh, } = useSupervisionRequests("ACCEPTED"); +const toastData = ref({ + visible: false, + type: "success", + message: "", +}); + const students = computed(() => (requests.value ?? []).map((request) => ({ id: request.student.user_id, @@ -83,14 +91,33 @@ async function addStudent(email: string) { ); if (!existingStudent) { - await $fetch("/api/supervision-requests", { - method: "POST", - body: { - // This "id" usage is correct based on the current backend, even if you ide says its not - supervisor_id: supervisor_data.value.id, - student_email: email, - }, - }); + try { + await $fetch("/api/supervision-requests", { + method: "POST", + body: { + // This "id" usage is correct based on the current backend, even if you ide says its not + supervisor_id: supervisor_data.value.id, + student_email: email, + }, + }); + toastData.value = { + visible: true, + type: "success", + message: t("generic.success"), // or any other suitable success message + }; + } catch (err) { + const errorMessage = + (err as { data?: { message?: string }; message?: string })?.data + ?.message || + (err as { message?: string })?.message || + t("generic.error"); + + toastData.value = { + visible: true, + type: "error", + message: errorMessage, + }; + } } await refresh(); } @@ -109,7 +136,7 @@ definePageMeta({ v-if="pending || error" class="w-full h-fit min-h-64 p-4 border border-base-300 rounded-3xl flex flex-col justify-center items-center" > -
Loading…
+
{{ t("generic.loading") }}
{{ error.message }}
@@ -120,6 +147,14 @@ definePageMeta({ @add-student="addStudent" @remove-student="removeStudent" /> + diff --git a/Frontend/pages/supervisor/dashboard.vue b/Frontend/pages/supervisor/dashboard.vue index 9e73ec02..99c7a80a 100644 --- a/Frontend/pages/supervisor/dashboard.vue +++ b/Frontend/pages/supervisor/dashboard.vue @@ -7,8 +7,8 @@ import { useSupervisionRequests } from "~/composables/useSupervisionRequests"; import { FontAwesomeIcon } from "@fortawesome/vue-fontawesome"; import EmptyPagePlaceholder from "~/components/Placeholder/EmptyPagePlaceholder.vue"; -const authStore = useAuthStore() -const { user } = storeToRefs(authStore) +const authStore = useAuthStore(); +const { user } = storeToRefs(authStore); const { getUserByEmail } = useUserApi(); const { getSupervisorByUserId } = useSupervisorApi(); const userStore = useUserStore(); @@ -33,15 +33,15 @@ const visibleRequests = computed( ); watch( - () => user.value?.primaryEmailAddress?.emailAddress, - async (email) => { - if (!email) return; + () => user.value?.primaryEmailAddress?.emailAddress, + async (email) => { + if (!email) return; - if (!userStore.user) { - const fetched = (await getUserByEmail(email)) as UserData; - userStore.setUser(fetched); - } - current_user.value = userStore.user; + if (!userStore.user) { + const fetched = (await getUserByEmail(email)) as UserData; + userStore.setUser(fetched); + } + current_user.value = userStore.user; if (current_user.value?.id) { const data = (await getSupervisorByUserId( @@ -73,14 +73,14 @@ definePageMeta({ From 7c1894857ff76554440b797bc6958a380b04ddca Mon Sep 17 00:00:00 2001 From: None of your business Date: Tue, 17 Jun 2025 20:17:57 +0200 Subject: [PATCH 06/11] fix(fe): fixed translation keys --- .../SupervisorStudentList.vue | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/Frontend/components/SupervisorStudentList/SupervisorStudentList.vue b/Frontend/components/SupervisorStudentList/SupervisorStudentList.vue index aac551b5..2e984aea 100644 --- a/Frontend/components/SupervisorStudentList/SupervisorStudentList.vue +++ b/Frontend/components/SupervisorStudentList/SupervisorStudentList.vue @@ -226,8 +226,10 @@ watch( lastName: studentToRemove?.lastName, }) " - :confirm-text="t('supervisorStudentList.removeStudent.confirmText')" - :checkbox-label="t('supervisorStudentList.checkboxLabel')" + :confirm-text=" + t('settings.supervisorStudentList.removeStudent.confirmText') + " + :checkbox-label="t('settings.supervisorStudentList.checkboxLabel')" setting-key="showRemoveStudentModal" :title="t('supervisorStudentList.removeStudent.title')" icon="trash" @@ -254,8 +256,10 @@ watch( }) " :show-checkbox="true" - :checkbox-label="t('supervisorStudentList.checkboxLabel')" - :confirm-text="t('supervisorStudentList.addExistingStudent.confirmText')" + :checkbox-label="t('settings.supervisorStudentList.checkboxLabel')" + :confirm-text=" + t('settings.supervisorStudentList.addExistingStudent.confirmText') + " icon="user-group" setting-key="showAddStudentModal" :sub-text="t('supervisorStudentList.addExistingStudent.subText')" @@ -273,14 +277,18 @@ watch( }) " :show-checkbox="true" - :checkbox-label="t('supervisorStudentList.checkboxLabel')" - confirm-text="" + :checkbox-label="t('settings.supervisorStudentList.checkboxLabel')" + :confirm-text=" + t('settings.supervisorStudentList.addNotExistingStudent.confirmText') + " icon="user-group" image-alt="Logo" image-src="../images/Superwise_Logo.svg" setting-key="showAddStudentModal" - :sub-text="t('supervisorStudentList.addExistingStudent.subText')" - :title="t('supervisorStudentList.addNewStudent.title')" + :sub-text=" + t('settings.supervisorStudentList.addNotExistingStudent.subText') + " + :title="t('settings.supervisorStudentList.addNewStudent.title')" @confirm="addStudent" /> From 7a57fdc9e04bd90fb887ac3e40ec6278fb47e494 Mon Sep 17 00:00:00 2001 From: None of your business Date: Thu, 19 Jun 2025 18:35:59 +0200 Subject: [PATCH 07/11] delte data actually deletes the user now and logs them out --- Frontend/composables/useUserApi.ts | 17 ++++++++----- Frontend/pages/admin/data-protection.vue | 24 ++++++++++++------ Frontend/pages/student/data-protection.vue | 25 +++++++++++++------ .../supervisor/currently-supervising.vue | 6 ++--- Frontend/pages/supervisor/data-protection.vue | 25 +++++++++++++------ 5 files changed, 63 insertions(+), 34 deletions(-) diff --git a/Frontend/composables/useUserApi.ts b/Frontend/composables/useUserApi.ts index fe93ad67..3bbf267e 100644 --- a/Frontend/composables/useUserApi.ts +++ b/Frontend/composables/useUserApi.ts @@ -1,11 +1,11 @@ -import {makeRequest} from './useApi' -import type {UserCreateData, UserRegistrationData} from "~/shared/types/userInterfaces"; +import { makeRequest } from './useApi' +import type { UserCreateData, UserRegistrationData } from "~/shared/types/userInterfaces"; export const useUserApi = () => { const getUserRegistrationStatus = async (email: string) => { - const data = await $fetch(`/api/users/check-registration?email=${email}`); - return data as UserRegistrationData; + const data = await $fetch(`/api/users/check-registration?email=${email}`); + return data as UserRegistrationData; } const createUser = async (data: UserCreateData) => { return await makeRequest('users', 'POST', data) @@ -40,13 +40,17 @@ export const useUserApi = () => { const getRecommendedSupervisors = async (data: string) => { return await makeRequest(`match/${data}`, 'GET'); } - + const createStudentProfile = async (data: string) => { return await makeRequest('students', 'POST', { thesis_description: data }) } + const deleteUser = async (data: Record) => { + return await makeRequest(`users/${data.id}`, 'DELETE') + } + return { getUserRegistrationStatus, createUser, @@ -56,7 +60,8 @@ export const useUserApi = () => { getUserById, addUserTag, getRecommendedSupervisors, - createStudentProfile + createStudentProfile, + deleteUser } } \ No newline at end of file diff --git a/Frontend/pages/admin/data-protection.vue b/Frontend/pages/admin/data-protection.vue index 53539f3b..166d9023 100644 --- a/Frontend/pages/admin/data-protection.vue +++ b/Frontend/pages/admin/data-protection.vue @@ -1,4 +1,7 @@