From 09b68ee61e2e952bc393d5d04973633d9ee3f3d8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Florian=20W=C3=B6rister?= <31357619+fwoerister@users.noreply.github.com> Date: Sun, 8 Feb 2026 00:32:03 +0100 Subject: [PATCH] make challenge cards translateable --- src/api/exercises.ts | 9 ++++++ src/components/BlocksemblerChallengeCard.vue | 31 ++++++++++++++++++-- src/components/icons/TranslateIcon.vue | 8 +++++ 3 files changed, 45 insertions(+), 3 deletions(-) create mode 100644 src/components/icons/TranslateIcon.vue diff --git a/src/api/exercises.ts b/src/api/exercises.ts index 661d85a..4eccb7b 100644 --- a/src/api/exercises.ts +++ b/src/api/exercises.ts @@ -6,6 +6,7 @@ const EXERCISES_ENDPOINT = `${BACKEND_API_URL}/exercises/` export interface Exercise { title: string, markdown: string, + markdown_de: string, skip_delay: number, next_exercise_id: number | null, id: number, @@ -19,9 +20,17 @@ let allExercisesSolvedPage = "# 🎉 Congratulations! 🎉\n" + "Thank you for participating! \n" + "Keep learning, keep exploring — and see you in the next competition. 🚀 "; +let allExercisesSolvedPageDe = "# 🎉 Glückwunsch! 🎉\n" + + "\n" + + "Du hast es geschafft — du hast erfolgreich **alle Aufgaben** in diesem Wettbewerb gelöst! 🏆 \n\n" + + "Vielen Dank für deine Teilnahme! \n" + + "Lerne weiter, entdecke weiter — und wir sehen uns im nächsten Wettbewerb. 🚀 "; + + export const FINAL_EXERCISE: Exercise = { title: "🚀 Congratulations, you finished all exercises!", markdown: allExercisesSolvedPage, + markdown_de: allExercisesSolvedPageDe, skip_delay: 0, next_exercise_id: null, id: -1, diff --git a/src/components/BlocksemblerChallengeCard.vue b/src/components/BlocksemblerChallengeCard.vue index ceb841a..59cf364 100644 --- a/src/components/BlocksemblerChallengeCard.vue +++ b/src/components/BlocksemblerChallengeCard.vue @@ -10,6 +10,7 @@ import BlocksemblerCodeSubmissionButton from "@/components/BlocksemblerCodeSubmi import {codingWorkspaceState} from "@/state"; import {getCurrentExercise} from "@/api/exercises"; import BlocksemblerChallengeSkipButton from "@/components/BlocksemblerChallengeSkipButton.vue"; +import TranslateIcon from "@/components/icons/TranslateIcon.vue"; let nextSkipAllowedAt: Ref = ref(null); let remainingTimeToNextSkip: Ref = ref(null); @@ -19,6 +20,8 @@ let nextSubmissionAllowedAt: Ref = ref(new Date(Date.now() + 1000 * 60 * 6 let remainingTimeToNextSubmission: Ref = ref(null); let timeToNextSubmissionTimer: Ref = ref(null); +let language = ref("en"); + onMounted(async () => { marked.use( katexExtension({ @@ -31,11 +34,20 @@ onMounted(async () => { let markdownToHtml = computed(() => { - if (codingWorkspaceState.currentExercise === null) { - return "" + let currentMarkdown = ""; + + if (!codingWorkspaceState.currentExercise) { + return ""; } - return marked(codingWorkspaceState.currentExercise.markdown); + if (language.value === "en") { + currentMarkdown = codingWorkspaceState.currentExercise.markdown + } else { + currentMarkdown = codingWorkspaceState.currentExercise.markdown_de; + } + + return marked.parse(currentMarkdown); + }) const updateRemainingtimeToNextSkip = () => { @@ -147,6 +159,14 @@ const skipFailed = () => { }, 10000); } +const changeLanguage = () => { + if (language.value === "en") { + language.value = "de"; + } else { + language.value = "en"; + } +} +