Werde-Informatiklehrerin/www/Steuerungsdateien/personas.js
Sven Lubenau 3a2240b8a2 Implementiere Persona-System mit dynamischen Dropdowns
- Füge personas.js und personas.yml hinzu für Persona-Management
- Implementiere dynamische Bundesland/Ausbildung-Dropdowns in Persona-Texten
- Korrigiere Pfad-Handling in finder.js für Bundeslaender-repo Symlink
- Erweitere CSS für Persona-Auswahl und Dropdown-Styling
- Füge Persona-Bilder und Mapping-Dateien für alle Bundesländer hinzu
- Implementiere Button-basierte Empfehlungsanzeige
- Korrigiere Platzhalter in Persona-Texten (entferne ungefüllte Platzhalter)
2025-09-12 19:10:43 +02:00

707 lines
22 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// personas.js Logik für den Personas-Tab (Tab 1)
let personasData = {}; // Geladene Personas-Daten aus personas.yml
let currentPersona = 'birgit'; // Aktuell ausgewählte Persona
// Lädt Personas-Daten aus YML und speichert sie global
async function loadPersonasData() {
try {
const response = await fetch('Steuerungsdateien/personas.yml');
const text = await response.text();
personasData = jsyaml.load(text);
console.log('[DEBUG] Personas-Daten geladen:', personasData);
initializePersonas();
} catch (err) {
console.error("Fehler beim Laden der personas.yml:", err);
}
}
// Initialisiert die Personas-Funktionalität
function initializePersonas() {
console.log('[DEBUG] Initialisiere Personas mit Daten:', personasData);
// Event Listener für Persona-Klicks hinzufügen
const personaElements = document.querySelectorAll('.persona');
console.log('[DEBUG] Gefundene Persona-Elemente:', personaElements.length);
personaElements.forEach((persona, index) => {
const personaName = persona.getAttribute('data-name');
console.log(`[DEBUG] Persona ${index + 1}: ${personaName}`);
persona.addEventListener('click', function() {
console.log('[DEBUG] Persona geklickt:', personaName);
selectPersona(personaName);
});
});
// Aktuelle Persona als ausgewählt markieren
markPersonaAsSelected(currentPersona);
// Bundesland-Dropdown für aktuelle Persona
setupBundeslandDropdown();
// Initiale Persona-Daten laden
if (personasData[currentPersona]) {
updateMainPortrait(personasData[currentPersona]);
updateBundeslandDropdown(personasData[currentPersona]);
updatePersonaButton(personasData[currentPersona]);
}
}
// Wechselt zur ausgewählten Persona
function selectPersona(personaName) {
if (!personasData[personaName]) {
console.error('Persona nicht gefunden:', personaName);
return;
}
const persona = personasData[personaName];
const previousPersona = currentPersona;
currentPersona = personaName;
// Hauptportrait aktualisieren
updateMainPortrait(persona);
// Persona-Positionen tauschen
swapPersonaPositions(previousPersona, personaName);
// Persona als ausgewählt markieren
markPersonaAsSelected(personaName);
// Bundesland-Dropdown aktualisieren
updateBundeslandDropdown(persona);
// Button-Text aktualisieren
updatePersonaButton(persona);
console.log('[DEBUG] Persona gewechselt von', previousPersona, 'zu:', personaName);
}
// Aktualisiert das Hauptportrait mit Persona-Daten
function updateMainPortrait(persona) {
// Bild aktualisieren
const imageElement = document.getElementById('persona-image');
if (imageElement) {
imageElement.src = persona.bild;
imageElement.alt = persona.name;
}
// Name und Alter aktualisieren
const nameElement = document.getElementById('persona-name');
if (nameElement) {
nameElement.innerHTML = `${persona.name} <span class="meta">${persona.alter} Jahre</span>`;
}
// Titel aktualisieren
const titleElement = document.getElementById('persona-title');
if (titleElement) {
titleElement.textContent = persona.titel;
}
// Text aktualisieren (mit Placeholder-Ersetzungen)
const textElement = document.getElementById('persona-text');
if (textElement) {
let text = persona.text;
// Bundesland-Placeholder ersetzen
text = text.replace(/\{\{BUNDESLAND_SELECT\}\}/g, getBundeslandName(persona.bundesland));
// Ausbildung-Placeholder ersetzen
text = text.replace(/\{\{AUSBILDUNG_SELECT\}\}/g, persona.ausbildung);
// Informatik-Placeholder ersetzen
text = text.replace(/\{\{INFORMATIK_SELECT\}\}/g, persona.informatik || 'Informatik');
// Abschluss-Placeholder ersetzen
text = text.replace(/\{\{ABSCHLUSS_SELECT\}\}/g, getAbschlussName(persona['abschluss-value']));
textElement.innerHTML = text;
}
}
// Tauscht die Positionen von zwei Personas
function swapPersonaPositions(persona1, persona2) {
if (persona1 === persona2) return; // Kein Tausch nötig
const persona1Element = document.querySelector(`.persona[data-name="${persona1}"]`);
const persona2Element = document.querySelector(`.persona[data-name="${persona2}"]`);
if (!persona1Element || !persona2Element) {
console.error('Persona-Elemente nicht gefunden für Tausch:', persona1, persona2);
return;
}
// Temporäre Platzhalter erstellen
const temp1 = document.createElement('div');
const temp2 = document.createElement('div');
// Elemente tauschen
persona1Element.parentNode.insertBefore(temp1, persona1Element);
persona2Element.parentNode.insertBefore(temp2, persona2Element);
temp1.parentNode.insertBefore(persona2Element, temp1);
temp2.parentNode.insertBefore(persona1Element, temp2);
// Platzhalter entfernen
temp1.remove();
temp2.remove();
console.log('[DEBUG] Persona-Positionen getauscht:', persona1, '↔', persona2);
}
// Markiert eine Persona als ausgewählt (visuell)
function markPersonaAsSelected(personaName) {
// Alle Personas zurücksetzen
document.querySelectorAll('.persona').forEach(p => {
p.classList.remove('selected');
const img = p.querySelector('img');
if (img) {
img.style.filter = 'grayscale(100%)';
}
});
// Aktuelle Persona markieren
const selectedPersona = document.querySelector(`.persona[data-name="${personaName}"]`);
if (selectedPersona) {
selectedPersona.classList.add('selected');
const img = selectedPersona.querySelector('img');
if (img) {
img.style.filter = 'none';
}
}
}
// Bundesland-Code zu Name konvertieren
function getBundeslandName(code) {
const bundeslaender = {
'BW': 'Baden-Württemberg',
'BY': 'Bayern',
'BE': 'Berlin',
'BB': 'Brandenburg',
'HB': 'Bremen',
'HH': 'Hamburg',
'HE': 'Hessen',
'MV': 'Mecklenburg-Vorpommern',
'NI': 'Niedersachsen',
'NW': 'Nordrhein-Westfalen',
'RP': 'Rheinland-Pfalz',
'SL': 'Saarland',
'SN': 'Sachsen',
'ST': 'Sachsen-Anhalt',
'SH': 'Schleswig-Holstein',
'TH': 'Thüringen',
'NRW': 'Nordrhein-Westfalen'
};
return bundeslaender[code] || code;
}
// Abschluss-Code zu Name konvertieren
function getAbschlussName(code) {
const abschluesse = {
'B': 'Bachelor',
'M': 'Master',
'D': 'Doktorat',
'A': 'Ausbildung'
};
return abschluesse[code] || code;
}
// Bundesland-Dropdown einrichten
function setupBundeslandDropdown() {
const textElement = document.getElementById('persona-text');
if (!textElement) return;
// Event Listener für Bundesland-Änderungen
textElement.addEventListener('change', function(e) {
if (e.target.tagName === 'SELECT' && e.target.closest('#persona-text')) {
const newBundesland = e.target.value;
const persona = personasData[currentPersona];
if (persona) {
persona.bundesland = newBundesland;
updateMainPortrait(persona);
}
}
});
}
// Dropdown-Menüs für Bundesland und Ausbildung aktualisieren
function updateBundeslandDropdown(persona) {
const textElement = document.getElementById('persona-text');
if (!textElement) return;
// Prüfe, ob Dropdowns bereits existieren
const existingBundeslandSelect = document.getElementById('bundesland-select');
const existingAusbildungSelect = document.getElementById('ausbildung-select');
if (existingBundeslandSelect && existingAusbildungSelect) {
// Dropdowns existieren bereits - nur Werte aktualisieren
existingBundeslandSelect.value = persona.bundesland;
existingAusbildungSelect.value = persona['ausbildung-value'];
return;
}
// Ersetze die Platzhalter im Text mit echten Dropdowns
let textContent = persona.text;
// Bundesland-Dropdown einbauen (orange)
const bundeslandOptions = getAllBundeslandOptions(persona.bundesland);
const bundeslandSelect = `<select class="select orange" id="bundesland-select">${bundeslandOptions}</select>`;
textContent = textContent.replace('{{BUNDESLAND_SELECT}}', bundeslandSelect);
// Ausbildung-Dropdown einbauen (blau)
const ausbildungOptions = getAllAusbildungOptions(persona['ausbildung-value']);
const ausbildungSelect = `<select class="select blue" id="ausbildung-select">${ausbildungOptions}</select>`;
textContent = textContent.replace('{{AUSBILDUNG_SELECT}}', ausbildungSelect);
// Text aktualisieren
textElement.innerHTML = textContent;
// Event Listener hinzufügen (mit Verzögerung, damit die Elemente im DOM sind)
setTimeout(() => {
const bundeslandSelectElement = document.getElementById('bundesland-select');
if (bundeslandSelectElement) {
bundeslandSelectElement.removeEventListener('change', handleBundeslandChange);
bundeslandSelectElement.addEventListener('change', handleBundeslandChange);
}
const ausbildungSelectElement = document.getElementById('ausbildung-select');
if (ausbildungSelectElement) {
ausbildungSelectElement.removeEventListener('change', handleAusbildungChange);
ausbildungSelectElement.addEventListener('change', handleAusbildungChange);
}
// Button Event Listener hinzufügen
const empfehlungButton = document.getElementById('persona-empfehlung-button');
if (empfehlungButton) {
empfehlungButton.removeEventListener('click', handleEmpfehlungButtonClick);
empfehlungButton.addEventListener('click', handleEmpfehlungButtonClick);
}
}, 100);
}
// Event Handler für Bundesland-Änderung
function handleBundeslandChange() {
const persona = personasData[currentPersona];
if (persona) {
persona.bundesland = this.value;
console.log('[DEBUG] Bundesland geändert zu:', this.value);
// Lade nur die Texte, nicht die Dropdowns
loadPersonaMarkdownContentOnly(currentPersona);
}
}
// Event Handler für Ausbildung-Änderung
function handleAusbildungChange() {
const persona = personasData[currentPersona];
if (persona) {
persona['ausbildung-value'] = this.value;
console.log('[DEBUG] Ausbildung geändert zu:', this.value);
// Lade nur die Texte, nicht die Dropdowns
loadPersonaMarkdownContentOnly(currentPersona);
}
}
// Aktualisiert den Button-Text mit dem Persona-Namen
function updatePersonaButton(persona) {
const buttonNameElement = document.getElementById('persona-button-name');
if (buttonNameElement) {
buttonNameElement.textContent = persona.name;
}
}
// Event Handler für Empfehlung-Button
function handleEmpfehlungButtonClick() {
console.log('[DEBUG] Empfehlung-Button geklickt für:', currentPersona);
loadPersonaMarkdownContent(currentPersona);
}
// Bundesland-Namen aus Code generieren
function getBundeslandName(code) {
const bundeslandNames = {
'BW': 'Baden-Württemberg',
'BY': 'Bayern',
'BE': 'Berlin',
'BB': 'Brandenburg',
'HB': 'Bremen',
'HH': 'Hamburg',
'HE': 'Hessen',
'MV': 'Mecklenburg-Vorpommern',
'NI': 'Niedersachsen',
'NW': 'Nordrhein-Westfalen',
'NRW': 'Nordrhein-Westfalen',
'RP': 'Rheinland-Pfalz',
'SL': 'Saarland',
'SN': 'Sachsen',
'ST': 'Sachsen-Anhalt',
'SH': 'Schleswig-Holstein',
'TH': 'Thüringen'
};
return bundeslandNames[code] || code;
}
// Alle Bundesland-Optionen generieren
function getAllBundeslandOptions(selectedBundesland) {
const bundeslandOptions = {
'BW': 'Baden-Württemberg',
'BY': 'Bayern',
'BE': 'Berlin',
'BB': 'Brandenburg',
'HB': 'Bremen',
'HH': 'Hamburg',
'HE': 'Hessen',
'MV': 'Mecklenburg-Vorpommern',
'NI': 'Niedersachsen',
'NW': 'Nordrhein-Westfalen',
'NRW': 'Nordrhein-Westfalen',
'RP': 'Rheinland-Pfalz',
'SL': 'Saarland',
'SN': 'Sachsen',
'ST': 'Sachsen-Anhalt',
'SH': 'Schleswig-Holstein',
'TH': 'Thüringen'
};
let options = '';
Object.entries(bundeslandOptions).forEach(([value, text]) => {
const selected = selectedBundesland === value ? 'selected' : '';
options += `<option value="${value}" ${selected}>${text}</option>`;
});
return options;
}
// Alle Ausbildung-Optionen generieren
function getAllAusbildungOptions(selectedAusbildung) {
const ausbildungOptions = {
'B': 'Berufserfahrung',
'H': 'Hochschulstudium',
'S': 'Lehramtsstudium'
};
let options = '';
Object.entries(ausbildungOptions).forEach(([value, text]) => {
const selected = selectedAusbildung === value ? 'selected' : '';
options += `<option value="${value}" ${selected}>${text}</option>`;
});
return options;
}
// CSS für ausgewählte Persona hinzufügen
function addPersonasStyles() {
const style = document.createElement('style');
style.textContent = `
.meta {
font-size: 0.8em;
color: #666;
font-weight: normal;
}
.persona-content {
margin-top: 20px;
}
.content-section {
margin-bottom: 20px;
padding: 15px;
background-color: #f9f9f9;
border-left: 4px solid #e07047;
border-radius: 0 5px 5px 0;
}
.content-section h1,
.content-section h2,
.content-section h3 {
color: #333;
margin-top: 0;
}
.content-section p {
line-height: 1.6;
margin-bottom: 10px;
}
.content-section strong {
color: #e07047;
}
`;
document.head.appendChild(style);
}
// Initialisierung beim Laden der Seite
document.addEventListener('DOMContentLoaded', function() {
addPersonasStyles();
loadPersonasData();
});
// Globale Funktion für Tab-Wechsel
function showPersonasTab() {
// Lade Personas-Daten falls noch nicht geladen
if (Object.keys(personasData).length === 0) {
loadPersonasData();
}
// Verstecke Empfehlungsbereich beim Wechsel zu Personas-Tab
hideRecommendation();
}
// Globale Funktion für Finder-Tab-Wechsel
function showFinderTabWithPersona() {
// Lade Markdown-Inhalte für die aktuelle Persona
if (currentPersona && Object.keys(personasData).length > 0) {
loadPersonaMarkdownContent(currentPersona);
}
}
// Versteckt den Empfehlungsbereich
function hideRecommendation() {
const recommendation = document.querySelector('.recommendation');
if (recommendation) {
recommendation.style.display = 'none';
}
}
// Zeigt den Empfehlungsbereich an
function showRecommendation() {
const recommendation = document.querySelector('.recommendation');
if (recommendation) {
recommendation.style.display = 'block';
}
}
// Lädt nur die Markdown-Inhalte ohne Dropdowns zu ändern
async function loadPersonaMarkdownContentOnly(personaName) {
const persona = personasData[personaName];
if (!persona) {
console.error('Persona nicht gefunden:', personaName);
return;
}
try {
// Erstelle eine Kopie der Persona-Daten mit aktuellen Dropdown-Werten
const currentPersonaData = { ...persona };
// Aktuelle Werte aus den Dropdowns lesen
const textElement = document.getElementById('persona-text');
if (textElement) {
const selectElements = textElement.querySelectorAll('select');
if (selectElements.length >= 2) {
currentPersonaData.bundesland = selectElements[0].value;
currentPersonaData['ausbildung-value'] = selectElements[1].value;
}
}
console.log('[DEBUG] Lade Markdown für Persona mit Daten:', currentPersonaData);
// Bestimme die entsprechende Markdown-Datei basierend auf aktuellen Persona-Daten
const markdownFile = getMarkdownFileForPersona(currentPersonaData);
if (!markdownFile) {
console.log('Keine passende Markdown-Datei für Persona:', personaName);
return;
}
console.log('[DEBUG] Lade Markdown-Datei:', markdownFile);
// Lade die Markdown-Datei
const response = await fetch(markdownFile);
const markdownPaths = await response.text();
// Lade die verlinkten Inhalte
await loadLinkedMarkdownContent(markdownPaths);
} catch (error) {
console.error('Fehler beim Laden der Markdown-Inhalte:', error);
}
}
// Lädt Markdown-Inhalte für eine Persona im Finder-Tab
async function loadPersonaMarkdownContent(personaName) {
const persona = personasData[personaName];
if (!persona) {
console.error('Persona nicht gefunden:', personaName);
return;
}
try {
// Erstelle eine Kopie der Persona-Daten mit aktuellen Dropdown-Werten
const currentPersonaData = { ...persona };
// Aktuelle Werte aus den Dropdowns lesen
const textElement = document.getElementById('persona-text');
if (textElement) {
const selectElements = textElement.querySelectorAll('select');
if (selectElements.length >= 2) {
currentPersonaData.bundesland = selectElements[0].value;
currentPersonaData['ausbildung-value'] = selectElements[1].value;
}
}
console.log('[DEBUG] Lade Markdown für Persona mit Daten:', currentPersonaData);
// Bestimme die entsprechende Markdown-Datei basierend auf aktuellen Persona-Daten
const markdownFile = getMarkdownFileForPersona(currentPersonaData);
if (!markdownFile) {
console.log('Keine passende Markdown-Datei für Persona:', personaName);
return;
}
console.log('[DEBUG] Lade Markdown-Datei:', markdownFile);
// Lade die Markdown-Datei
const response = await fetch(markdownFile);
const markdownPaths = await response.text();
// Lade die verlinkten Inhalte
await loadLinkedMarkdownContent(markdownPaths);
} catch (error) {
console.error('Fehler beim Laden der Markdown-Inhalte:', error);
}
}
// Bestimmt die richtige Markdown-Datei basierend auf Persona-Daten
function getMarkdownFileForPersona(persona) {
// Bundesland-Mapping - korrigiert für die tatsächlichen Verzeichnisnamen
const bundeslandMapping = {
'BW': '1_BW',
'BY': '2_BY',
'BE': '3_BE',
'BB': '4_BB',
'HB': '5_HB',
'HH': '6_HH',
'HE': '7_HE',
'MV': '8_MV',
'NI': '9_NI',
'NW': '10_NW',
'NRW': '10_NW',
'RP': '11_RP',
'SL': '12_SL',
'SN': '13_SN',
'ST': '14_ST',
'SH': '15_SH',
'TH': '16_TH'
};
const bundeslandDir = bundeslandMapping[persona.bundesland];
if (!bundeslandDir) {
console.error('Unbekanntes Bundesland:', persona.bundesland);
return null;
}
// Bestimme den Dateinamen basierend auf Ausbildung und Informatik
let fileName = '';
// Ausbildung-basiert (Code-System)
if (persona['ausbildung-value'] === 'B') {
// Berufserfahrung
if (persona['informatik-value'] === 'J') {
fileName = 'HS-BA-1F.md'; // Informatik-Berufserfahrung
} else {
fileName = 'HS-BA-2F.md'; // Andere Berufserfahrung
}
} else if (persona['ausbildung-value'] === 'H') {
// Hochschule
if (persona['abschluss-value'] === 'B') {
fileName = 'HS-MA-0F.md'; // Bachelor
} else if (persona['abschluss-value'] === 'M') {
if (persona['informatik-value'] === 'J') {
fileName = 'HS-MA-1F.md'; // Master mit Informatik
} else {
fileName = 'HS-MA-2F.md'; // Master ohne Informatik (wie Birgit)
}
}
} else if (persona['ausbildung-value'] === 'S') {
// Studium/Lehramt
fileName = 'LA-BA.md';
}
if (!fileName) {
console.log('Keine passende Datei gefunden für Persona-Daten:', persona);
return null;
}
console.log(`[DEBUG] Persona ${persona.name}: Bundesland ${persona.bundesland} (${bundeslandDir}), Ausbildung ${persona['ausbildung-value']}, Abschluss ${persona['abschluss-value']}, Informatik ${persona['informatik-value']}${fileName}`);
return `Bundeslaender/${bundeslandDir}/${fileName}`;
}
// Lädt die verlinkten Markdown-Inhalte
async function loadLinkedMarkdownContent(markdownPaths) {
const paths = markdownPaths.trim().split('\n').filter(path => path.trim());
// Erstelle Container für die Inhalte
let contentHtml = '<div class="persona-content">';
for (const path of paths) {
try {
// Entferne führenden Slash falls vorhanden
const cleanPath = path.trim().startsWith('/') ? path.trim().substring(1) : path.trim();
// Füge Bundeslaender-repo/ hinzu, falls nicht bereits vorhanden
const fullPath = cleanPath.startsWith('Bundeslaender-repo/') ? cleanPath : `Bundeslaender-repo/${cleanPath}`;
const response = await fetch(fullPath);
const content = await response.text();
// Konvertiere Markdown zu HTML (vereinfacht)
const htmlContent = convertMarkdownToHtml(content);
contentHtml += `<div class="content-section">${htmlContent}</div>`;
} catch (error) {
console.error('Fehler beim Laden von:', path, error);
contentHtml += `<div class="content-section"><h2>Fehler</h2><p>Datei nicht gefunden: ${path}</p></div>`;
}
}
contentHtml += '</div>';
// Zeige den Inhalt im Empfehlungsbereich an
displayPersonaContent(contentHtml);
}
// Einfache Markdown-zu-HTML Konvertierung
function convertMarkdownToHtml(markdown) {
return markdown
.replace(/^# (.*$)/gim, '<h1>$1</h1>')
.replace(/^## (.*$)/gim, '<h2>$1</h2>')
.replace(/^### (.*$)/gim, '<h3>$1</h3>')
.replace(/\*\*(.*?)\*\*/g, '<strong>$1</strong>')
.replace(/\*(.*?)\*/g, '<em>$1</em>')
.replace(/\n\n/g, '</p><p>')
.replace(/^(?!<[h1-6])/gm, '<p>')
.replace(/$/gm, '</p>')
.replace(/<p><\/p>/g, '');
}
// Zeigt Persona-Inhalt im Empfehlungsbereich an (gleiche Struktur wie Finder)
function displayPersonaContent(contentHtml) {
// Verwende die gleiche Struktur wie der Finder
const resultDiv = document.getElementById('result');
if (resultDiv) {
// Headline setzen
const headlineElement = document.getElementById('finder-headline');
if (headlineElement) {
headlineElement.textContent = 'Empfehlung für ' + (currentPersona ? personasData[currentPersona].name : 'Persona');
}
// Content setzen
const textContentElement = document.getElementById('finder-text-content');
if (textContentElement) {
textContentElement.innerHTML = contentHtml;
}
// Tags und Marginal leeren (falls vorhanden)
const tagsElement = document.getElementById('finder-tags');
if (tagsElement) {
tagsElement.innerHTML = '';
}
const marginalElement = document.getElementById('finder-marginal');
if (marginalElement) {
marginalElement.innerHTML = '';
}
// Ergebnis-Bereich anzeigen
resultDiv.style.display = 'block';
}
}