const assets = {
calendar: "assets/materials/mq3zhq9n-clipboard.png",
slide: "assets/materials/mq3zhqat-clipboard.png",
notes: "assets/materials/mq3zhqbu-clipboard.png",
evidence: "assets/materials/mq3zhqdk-clipboard.png",
recent: [
"assets/materials/mq3zhqe0-clipboard.png",
"assets/materials/mq3zhqe3-clipboard.png",
"assets/materials/mq3zhqea-clipboard.png",
"assets/materials/mq3zhqeg-clipboard.png"
]
};
const routes = ["overview", "uploads", "canvas", "calendar", "learning-plan", "gaps", "flashcards", "quiz", "reminders"];
const app = document.querySelector("#app");
const navList = document.querySelector("#navList");
const toast = document.querySelector("#toast");
const pageHead = (title, subtitle, actions = "") => `
`;
const panel = (title, body, extra = "", className = "") => `
${title} ${extra || '... '}
${body}
`;
function overviewPage() {
const agenda = [
["09:00", "Mehrsprachigkeitsdidaktik", "Seminar im Hörsaal 3 · Sprachbewusstsein & Transferstrategien", "book-open", "green"],
["11:30", "Englischdidaktik", "Übung · Classroom Interaction & Feedback", "globe", "blue"],
["13:00", "Mittagspause", "Zeit für gutes Essen und einen kurzen Spaziergang am Rhein", "fork-knife", "rose"],
["15:00", "Lernblock Bildungspsychologie", "Kapitel 4: Motivation & Selbstregulation · Karteikarten erstellen", "brain", "aubergine"],
["17:30", "Familie & Freunde", "Abendessen bei Mama & Papa", "users-three", "gold"]
].map(([time, title, sub, icon, tone]) => `
${time}
${title} ${sub}
`).join("");
return `
Dienstag, 7. Juni · Mainz · 18°
Josephine Wendland
Lehren. Verstehen. Verbinden.
Guten Morgen, Josephine
Heute ist ein guter Tag, etwas zu lernen, zu wachsen und Menschen zu inspirieren.
`;
}
function uploadsPage() {
const extracted = `Sprachbewusstheit fördern (VL 07)
Begriff: Fähigkeit, Sprache(n) als System(e) wahrzunehmen und über Sprache(n) nachzudenken.
Ziele:
- Sensibilisierung für sprachliche Strukturen und Variation
- Vergleich von Sprachen als Ressourcen nutzen
- Transferstrategien entwickeln
Vergleich DE - FR
DE: Ich gehe in die Schule.
FR: Je vais à l'école.
Gemeinsamkeiten: Subjekt - Verb - Objekt
Unterschiede: Artikel, Präpositionen, Akkordanz
Didaktische Prinzipien:
1) Sprachenvergleich
2) Bewusstmachung
3) Funktionaler Einsatz im Fachunterricht`;
return pageHead("Materialien", "Notizen, Folien und Kalender an einem ruhigen Ort.", `
Dateien hinzufügen
In Arbeitsfläche öffnen
`) + `
${panel("Upload-Queue (3)", `
Mehrsprachigkeitsdidaktik_VL07.pdf 100%
OCR abgeschlossen · 32 Seiten
Englischdidaktik_Orthografie.pdf 76%
OCR läuft · Seite 3 von 11
Bildungspsychologie_Notizen.jpg 0%
Wartet in der Queue
Dateien hier ablegen PDF, JPG oder PNG · Verarbeitung bleibt lokal
`, '
Lokal ', "upload-queue")}
${panel("Mehrsprachigkeitsdidaktik_VL07.pdf", `
`, '
Seite 4 verknüpft ')}
${panel("OCR-Extraktion", `
Deutsch 99% Französisch 82% Englisch 12%
Konfidenz der Seite: 93% · 7 Markierungen prüfen
Extrahierter Text
Niedrige Konfidenz: Akkordanz Alle prüfen
Verwerfen Übernehmen & speichern
Speichern in: Mehrsprachigkeitsdidaktik · nur lokal
`, '
Abgeschlossen ')}
`;
}
function canvasPage() {
const thumbs = [assets.recent[0], assets.recent[1], assets.slide, assets.recent[2], assets.recent[3]]
.map((src, i) => ` `).join("");
return `
${panel("Vorlesungsfolien", `
`)}
${panel("Handschriftliche Notizen", `
`, '
4 semantische Links ')}
${panel("AI-Copilot", `
Wie hängen Translanguaging und Scaffolding zusammen?
Maya Scaffolding schafft temporäre sprachliche und kognitive Stützen. Translanguaging erlaubt Lernenden, ihr gesamtes sprachliches Repertoire für Bedeutungsbildung zu nutzen. Zusammen fördern sie fachliche Teilhabe, ohne die Zielsprache auszublenden.
Folie 14 Notiz S. 1
Fehlendes Konzept erkannt: Interlanguage Die Unterscheidung zur Interlanguage fehlt in deinen verknüpften Notizen.
Konzept erklären Quelle suchen Karte erstellen
`, '
Lokal · Quellengebunden ')}
`;
}
function calendarPage() {
const cells = Array.from({length: 35}, () => "
").join("");
const roadmapRows = [
["Mehrsprachigkeitsdidaktik","on,on,on,,blue,blue,,"],
["Englischdidaktik","blue,blue,,on,on,,,"],
["Französischdidaktik",",amber,amber,,on,on,,"],
["Bildungspsychologie","on,,blue,blue,,on,on,on"]
].map(([name, states]) => `${name} ${states.split(",").map(s => ` `).join("")}`).join("");
return pageHead("Kalender & Lernplan", "Geprüfte Termine, realistische Lernblöcke und dein 8-Tage-Fokus.", `
Lernblock planen
`) + `
${panel("Wochenplan · 7.-11. Juni", `
${["Di 7.","Mi 8.","Do 9.","Fr 10.","Sa 11."].map(d=>`
${d}
`).join("")}
${["09:00","10:00","11:00","12:00","13:00","14:00","15:00"].map(t=>`
${t}
`).join("")}${cells}
09:00 Mehrsprachigkeitsdidaktik Seminar
10:00 Hausarbeit Quellenarbeit
11:00 Französischdidaktik Séance 5
09:00 Fachdidaktik Deutsch Portfolio
10:00 Lerngruppe Bibliothek
8-Tage-Prüfungsroadmap ${["Di 7","Mi 8","Do 9","Fr 10","Sa 11","So 12","Mo 13","Di 14"].map(d=>`${d} `).join("")}${roadmapRows}
Fokus: Hausarbeit abschließen → Französischdidaktik wiederholen → Prüfungssimulation
`, '
72% geplant ', "week-calendar")}
${panel("Heute · 5 Std. 30 Min.", `
09:00-10:30 · Seminarfolien Translanguaging und Scaffolding verknüpfen
11:30-13:00 · Reading response Englischdidaktik · Kapitel 4
15:00-16:30 · Retrieval Practice Bildungspsychologie · Lernkarten 31-54
`, '
Im Plan ')}
${panel("Geprüfte Extraktionen", `
`, '
3 aus PDF ')}
`;
}
function flashcardsPage() {
const decks = [
["Mehrsprachigkeitsdidaktik",48,"18 fällig · zuletzt heute",72],
["Englischdidaktik",36,"Nächste Wiederholung morgen",58],
["Französischdidaktik",42,"Nächste Wiederholung morgen",44],
["Bildungspsychologie",61,"Nächste Wiederholung morgen",81],
["Fachdidaktik Deutsch",27,"Nächste Wiederholung morgen",36]
].map(([name,count,sub,pct],i)=>`${name} · ${count} Karten ${sub}
`).join("");
return pageHead("Karteikarten", "Quellengebundene Karten bearbeiten, lernen und exportieren.", `
Aus Quellen generieren
12 Karten lernen
`) + `
${panel("Meine Decks", `
${decks}
`)}
${panel("Karte bearbeiten · 12 von 48", `
Frage
Antwort
Quellen ▣ Mehrsprachigkeitsdidaktik_Woche_7.pdf · Folie 14 ▤ Notizen_Scaffolding_03-06.jpg · Seite 1
Translanguaging Code-Switching Woche 7
Karte löschen Änderungen speichern
`)}
${panel("Vorschau & Export", `
Vorderseite Wie unterscheidet sich Translanguaging vom klassischen Code-Switching? Klicken zum Umdrehen
Rückseite Translanguaging nutzt das gesamte sprachliche Repertoire flexibel. Code-Switching beschreibt den situativen Wechsel zwischen getrennt gedachten Sprachen.
Deck exportieren 48 Karten · Quellen enthalten · DE Anki (.apkg) CSV PDF zum Drucken
Letzte Generierung: heute, 10:42 · vollständig lokal `)}
`;
}
function quizPage() {
return pageHead("Quizmodus", "Prüfungssimulation · Mehrsprachigkeitsdidaktik", `Simulation beenden `) + `
${panel("Frage 7 von 12", `
Fortschritt · 58% Schwierigkeit: Anspruchsvoll
Welche Aussage beschreibt den didaktischen Nutzen von Translanguaging am präzisesten?
A Es verhindert den Wechsel zwischen Unterrichtssprachen vollständig.
B Es aktiviert das gesamte sprachliche Repertoire zur Bedeutungsbildung und fachlichen Teilhabe.
C Es ersetzt fachsprachliche Lernziele durch alltagssprachliche Kommunikation.
D Es ist ausschließlich für den Fremdsprachenunterricht geeignet.
Richtig beantwortet Translanguaging nutzt vorhandene sprachliche Ressourcen gezielt als Brücke zum fachlichen Verstehen. Die Zielsprache bleibt wichtig, wird aber nicht als isoliertes System behandelt.
Quelle: Mehrsprachigkeitsdidaktik_Woche_7.pdf · Folie 14 „Dynamische Nutzung des gesamten sprachlichen Repertoires zur Bedeutungskonstruktion.“
Nächste Frage →
`, '
... ', "quiz-card")}
${panel("Simulationsstatus", `
5 richtig
1 falsch
82% Trefferquote
06:42 verbleibend
`)}
${panel("Schwierigkeit", `
Adaptiv Mittel Anspruchsvoll
Die nächsten Fragen gewichten deine Wissenslücken stärker.
`)}
${panel("Prüfungsfokus", `
Lücke Interlanguage
Prüfen Scaffolding
Sicher Translanguaging
12 Fragen · 15 Minuten Nur aus 3 ausgewählten lokalen Quellen `)}
`;
}
function learningPlanPage() {
return pageHead("Mein Lernplan", "Ein realistischer Plan, der zu Josephines Woche passt.", `
Kalender ansehen
Lernblock starten
`) + `
Prüfung in 8 Tagen
Diese Woche zählt Beständigkeit, nicht Perfektion.
StudyFlow verbindet deine Termine, Materialien und offenen Themen zu kleinen, machbaren Schritten.
Heute Grundlagen wiederholen Mehrsprachigkeitsdidaktik · 75 Min.
Morgen Scaffolding vertiefen Folien, Notizen und 12 Karten · 60 Min.
Donnerstag Formative Bewertung üben Quiz und Reflexion · 45 Min.
Freitag Wissenslücken schließen Selbstwirksamkeit und Interlanguage · 60 Min.
`;
}
function gapsPage() {
return pageHead("Wissenslücken", "Was noch unsicher ist, wird hier verständlich und machbar.", `
Kurzes Quiz starten
`) + `
Heute empfohlen
Selbstwirksamkeit verstehen
In deinen Notizen fehlt noch die Verbindung zwischen Selbstwirksamkeit, Motivation und Lernerfolg.
Mit Quellen erklären
Interlanguage Nur indirekt in drei Quellen erklärt Hoch
Scaffolding Zwei unsichere Karten Mittel
Translanguaging Quellenlage vollständig Sicher
`;
}
function remindersPage() {
return pageHead("Erinnerungen", "Freundliche Hinweise, damit Wichtiges nicht im Alltag untergeht.", `
Erinnerung hinzufügen
`) + `
Heute 7. Juni Du hast einen ruhigen Abend ohne Studienfrist.
Reflexionsbericht Mehrsprachigkeit Freitag, 10. Juni · 23:59 In 3 Tagen
Französische Präsentation Montag, 13. Juni · 10:00 In 6 Tagen
Bildungspsychologie wiederholen Morgen · 15:00 Geplant
`;
}
const renderers = {
overview: overviewPage,
uploads: uploadsPage,
canvas: canvasPage,
calendar: calendarPage,
"learning-plan": learningPlanPage,
gaps: gapsPage,
flashcards: flashcardsPage,
quiz: quizPage,
reminders: remindersPage
};
function normalizeRoute() {
const route = location.hash.replace("#/", "").replace("#", "");
return routes.includes(route) ? route : "overview";
}
function navigate(route) {
if (!routes.includes(route)) return;
if (location.hash !== `#/${route}`) location.hash = `#/${route}`;
else render();
}
function render() {
const route = normalizeRoute();
app.innerHTML = renderers[route]();
navList.querySelectorAll("[data-route]").forEach(btn => btn.classList.toggle("active", btn.dataset.route === route));
document.title = `${route === "overview" ? "Heute" : app.querySelector("h1")?.textContent || "StudyFlow"} · StudyFlow AI`;
closeMenu();
app.focus({ preventScroll: true });
bindPage(route);
}
function bindPage(route) {
app.querySelectorAll("[data-route]").forEach(el => el.addEventListener("click", () => navigate(el.dataset.route)));
if (route === "uploads") bindUploads();
if (route === "canvas") bindCanvas();
if (route === "calendar") bindCalendar();
if (route === "flashcards") bindFlashcards();
if (route === "quiz") bindQuiz();
if (route === "reminders") {
document.querySelector("#newReminder")?.addEventListener("click", () => showToast("Neue Erinnerung wird lokal angelegt."));
}
app.querySelector("[data-action='open-plan']")?.addEventListener("click", () => navigate("calendar"));
}
function bindUploads() {
const dropzone = document.querySelector("#dropzone");
["dragenter", "dragover"].forEach(type => dropzone.addEventListener(type, event => { event.preventDefault(); dropzone.classList.add("drag"); }));
["dragleave", "drop"].forEach(type => dropzone.addEventListener(type, event => { event.preventDefault(); dropzone.classList.remove("drag"); }));
dropzone.addEventListener("drop", () => showToast("Datei zur lokalen Queue hinzugefügt."));
document.querySelector("#addFiles").addEventListener("click", () => showToast("Dateiauswahl geöffnet. Demo bleibt lokal."));
document.querySelector("#reviewAll").addEventListener("click", () => {
document.querySelector("#ocrText").focus();
showToast("7 unsichere Stellen sind zur Prüfung markiert.");
});
document.querySelector("#saveOcr").addEventListener("click", () => showToast("OCR-Text lokal gespeichert und verknüpft."));
}
function bindCanvas() {
const mainSlide = document.querySelector("#mainSlide");
const slideAssets = [assets.recent[0], assets.recent[1], assets.slide, assets.recent[2], assets.recent[3]];
document.querySelectorAll(".slide-thumb").forEach(button => button.addEventListener("click", () => {
document.querySelectorAll(".slide-thumb").forEach(item => item.classList.remove("active"));
button.classList.add("active");
mainSlide.src = slideAssets[Number(button.dataset.slide)];
}));
document.querySelector("#chatForm").addEventListener("submit", event => {
event.preventDefault();
const input = document.querySelector("#chatInput");
const text = input.value.trim();
if (!text) return;
const messages = document.querySelector("#messages");
messages.insertAdjacentHTML("beforeend", `${escapeHtml(text)}
Maya Ich prüfe diese Frage gegen die lokal verknüpften Folien und Notizen. Die relevanten Stellen liegen auf Folie 14 und in deiner Scaffolding-Notiz.
`);
input.value = "";
messages.scrollTop = messages.scrollHeight;
});
}
function bindCalendar() {
document.querySelector("#planBlock").addEventListener("click", () => showToast("Neuer Lernblock für 17:15 vorgeschlagen."));
document.querySelector("#reviewExtractions").addEventListener("click", () => showToast("Drei bestätigte Termine aus lokalen Quellen."));
}
function bindFlashcards() {
const preview = document.querySelector("#cardPreview");
preview.addEventListener("click", () => preview.classList.toggle("flipped"));
document.querySelector("#saveCard").addEventListener("click", () => showToast("Karte lokal gespeichert."));
document.querySelector("#deleteCard").addEventListener("click", () => showToast("Karte zur Löschung vorgemerkt."));
document.querySelector("#generateCards").addEventListener("click", () => showToast("6 Kartenvorschläge aus zwei Quellen erzeugt."));
document.querySelector("#learnCards").addEventListener("click", () => showToast("Lernsession mit 12 fälligen Karten gestartet."));
document.querySelectorAll("[data-export]").forEach(button => button.addEventListener("click", () => showToast(`${button.dataset.export}-Export lokal vorbereitet.`)));
document.querySelectorAll(".deck-row").forEach(row => row.addEventListener("click", () => {
document.querySelectorAll(".deck-row").forEach(item => item.classList.remove("selected"));
row.classList.add("selected");
showToast(`${row.dataset.deck} ausgewählt.`);
}));
}
function bindQuiz() {
const options = [...document.querySelectorAll(".answer-option")];
const explanation = document.querySelector("#quizExplanation");
options.forEach(option => option.addEventListener("click", () => {
options.forEach(item => item.classList.remove("selected", "wrong"));
const correct = option.dataset.answer === "B";
option.classList.add(correct ? "selected" : "wrong");
explanation.hidden = false;
document.querySelector("#answerState").textContent = correct ? "Richtig beantwortet" : "Noch nicht richtig";
document.querySelector("#answerState").style.color = correct ? "var(--emerald-dark)" : "var(--red)";
document.querySelector("#chosenAnswer").textContent = `Antwort gewählt · ${option.dataset.answer}`;
}));
document.querySelectorAll("[data-level]").forEach(button => button.addEventListener("click", () => {
document.querySelectorAll("[data-level]").forEach(item => item.classList.remove("active"));
button.classList.add("active");
showToast(`Schwierigkeit auf ${button.dataset.level} gesetzt.`);
}));
document.querySelector("#nextQuestion")?.addEventListener("click", () => {
document.querySelector(".panel-head h2").textContent = "Frage 8 von 12";
document.querySelector("#quizProgress").style.width = "67%";
document.querySelector("#quizProgressText").textContent = "67%";
showToast("Nächste Frage geladen.");
});
document.querySelector("#endQuiz").addEventListener("click", () => showToast("Simulation pausiert. Dein Stand bleibt lokal gespeichert."));
}
function showToast(message) {
toast.textContent = message;
toast.classList.add("show");
clearTimeout(showToast.timer);
showToast.timer = setTimeout(() => toast.classList.remove("show"), 2600);
}
function escapeHtml(value) {
return value.replace(/[&<>"']/g, char => ({ "&": "&", "<": "<", ">": ">", '"': """, "'": "'" }[char]));
}
const sidebar = document.querySelector("#sidebar");
const scrim = document.querySelector("#scrim");
const menuButton = document.querySelector("#menuButton");
function closeMenu() {
sidebar.classList.remove("open");
scrim.classList.remove("show");
menuButton.setAttribute("aria-expanded", "false");
}
menuButton.addEventListener("click", () => {
const open = sidebar.classList.toggle("open");
scrim.classList.toggle("show", open);
menuButton.setAttribute("aria-expanded", String(open));
});
scrim.addEventListener("click", closeMenu);
navList.addEventListener("click", event => {
const button = event.target.closest("[data-route]");
if (button) navigate(button.dataset.route);
});
document.querySelector("#askButton").addEventListener("click", () => document.querySelector("#aiDialog").showModal());
document.querySelector("#aiSubmit").addEventListener("click", () => {
const prompt = document.querySelector("#aiPrompt").value.trim();
showToast(prompt ? "Lokale Antwort wird aus 12 Materialien erzeugt." : "Bitte gib zuerst eine Frage ein.");
});
document.querySelector("#globalSearch").addEventListener("keydown", event => {
if (event.key === "Enter" && event.currentTarget.value.trim()) showToast(`Lokale Suche nach „${event.currentTarget.value.trim()}“`);
});
document.addEventListener("keydown", event => {
if ((event.metaKey || event.ctrlKey) && event.key.toLowerCase() === "k") {
event.preventDefault();
document.querySelector("#globalSearch").focus();
}
if (event.key === "Escape") closeMenu();
});
window.addEventListener("hashchange", render);
render();