Merge branch 'dev' into '50-lerninhalte-interface'
# Conflicts: # webseite/topic.php
This commit is contained in:
@@ -282,3 +282,67 @@ body {
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Einzelne Toast Styles */
|
||||
.toast-content {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
border-radius: 12px; /* Abgerundete Ecken */
|
||||
padding: 20px;
|
||||
box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
|
||||
min-width: 200px;
|
||||
max-width: 80%;
|
||||
transition: opacity 0.5s ease, transform 0.5s ease;
|
||||
opacity: 0;
|
||||
transform: translateY(-20px);
|
||||
}
|
||||
|
||||
/* Spezifische Klassen für verschiedene Toast-Typen */
|
||||
.toast-success {
|
||||
background-color: #38a169; /* Grüner Hintergrund */
|
||||
}
|
||||
|
||||
.toast-error {
|
||||
background-color: #e53e3e; /* Roter Hintergrund */
|
||||
}
|
||||
|
||||
.toast-info {
|
||||
background-color: #4299e1; /* Blauer Hintergrund */
|
||||
}
|
||||
|
||||
/* Sichtbarkeit */
|
||||
.toast-content.show {
|
||||
opacity: 1;
|
||||
transform: translateY(0);
|
||||
}
|
||||
|
||||
/* Icon Styling */
|
||||
.toast-icon {
|
||||
font-size: 32px; /* Größeres Icon */
|
||||
margin-right: 20px; /* Abstand zwischen Icon und Text */
|
||||
color: white; /* Icons sollen immer weiß sein */
|
||||
}
|
||||
|
||||
/* Nachrichten-Text Styling */
|
||||
.toast-message {
|
||||
color: white;
|
||||
font-size: 18px; /* Größere Schriftgröße */
|
||||
}
|
||||
|
||||
|
||||
.task-container {
|
||||
border-radius: 20px;
|
||||
padding: 2rem;
|
||||
margin-bottom: 2rem;
|
||||
/*box-shadow: 0 4px 6px -1px rgba(0, 0, 0, 0.1);*/
|
||||
box-shadow: 2px 4px 6px 2px rgba(0, 0, 0, 0.1);
|
||||
transition: all 0.4s cubic-bezier(0.4, 0, 0.2, 1);
|
||||
}
|
||||
|
||||
.variable-input{
|
||||
border: 2px solid;
|
||||
border-radius: 8px;
|
||||
text-align: center;
|
||||
}
|
||||
118
webseite/assets/js/tasks.js
Normal file
118
webseite/assets/js/tasks.js
Normal file
@@ -0,0 +1,118 @@
|
||||
document.addEventListener('DOMContentLoaded', function () {
|
||||
console.log('tasks.js wurde geladen.');
|
||||
|
||||
// Funktion zum Anzeigen des Toasts
|
||||
function showToast(message, type = 'success') {
|
||||
const toastsContainer = document.getElementById('toasts');
|
||||
|
||||
// Erstellen eines neuen Toast-Elements
|
||||
const toast = document.createElement('div');
|
||||
toast.classList.add('toast-content', `toast-${type}`);
|
||||
|
||||
// Erstellen des Icons
|
||||
const icon = document.createElement('i');
|
||||
icon.classList.add('fa-solid');
|
||||
switch (type) {
|
||||
case 'success':
|
||||
icon.classList.add('fa-check');
|
||||
break;
|
||||
case 'error':
|
||||
icon.classList.add('fa-times');
|
||||
break;
|
||||
case 'info':
|
||||
icon.classList.add('fa-info-circle');
|
||||
break;
|
||||
default:
|
||||
icon.classList.add('fa-check');
|
||||
}
|
||||
icon.classList.add('toast-icon'); // Hinzufügen der CSS-Klasse für das Icon
|
||||
|
||||
// Erstellen des Nachrichten-Elements
|
||||
const toastMessage = document.createElement('span');
|
||||
toastMessage.textContent = message;
|
||||
toastMessage.classList.add('toast-message'); // Hinzufügen der CSS-Klasse für den Text
|
||||
|
||||
// Fügen Sie Icon und Nachricht zum Toast hinzu
|
||||
toast.appendChild(icon);
|
||||
toast.appendChild(toastMessage);
|
||||
|
||||
// Fügen Sie den Toast zum Container hinzu
|
||||
toastsContainer.appendChild(toast);
|
||||
|
||||
// Anzeigen des Toasts mit Animation
|
||||
requestAnimationFrame(() => {
|
||||
toast.classList.add('show');
|
||||
});
|
||||
|
||||
// Automatisches Ausblenden nach 3 Sekunden
|
||||
setTimeout(() => {
|
||||
toast.classList.remove('show');
|
||||
// Entfernen des Toasts nach der Animation
|
||||
setTimeout(() => {
|
||||
toast.remove();
|
||||
}, 500); // Muss mit der CSS-Transition übereinstimmen
|
||||
}, 3000);
|
||||
}
|
||||
|
||||
// Event-Delegation für "Antwort prüfen" Buttons
|
||||
document.querySelectorAll('.check-answer').forEach(function (button, index) {
|
||||
button.addEventListener('click', function () {
|
||||
console.log(`Antwort prüfen Button geklickt. Button Index: ${index}`);
|
||||
const variableContainer = this.closest('.variable-container');
|
||||
if (!variableContainer) {
|
||||
console.error('Variable Container nicht gefunden für Button:', this);
|
||||
showToast('Interner Fehler: Container nicht gefunden.', 'error');
|
||||
return;
|
||||
}
|
||||
const input = variableContainer.querySelector('input');
|
||||
if (!input) {
|
||||
console.error('Input Feld nicht gefunden in Variable Container:', variableContainer);
|
||||
showToast('Interner Fehler: Eingabefeld nicht gefunden.', 'error');
|
||||
return;
|
||||
}
|
||||
const userAnswer = input.value.trim();
|
||||
const correctAnswer = input.getAttribute('data-correct-answer');
|
||||
if (!correctAnswer) {
|
||||
console.error('Data-Correct-Answer Attribut fehlt im Input:', input);
|
||||
showToast('Interner Fehler: Richtige Antwort nicht verfügbar.', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`Benutzerantwort: "${userAnswer}", Richtige Antwort: "${correctAnswer}"`);
|
||||
|
||||
if (userAnswer.toLowerCase() === correctAnswer.trim().toLowerCase()) {
|
||||
showToast('Richtig!', 'success');
|
||||
} else {
|
||||
showToast('Falsch.', 'error');
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
// Event-Delegation für "Antwort anzeigen" Buttons
|
||||
document.querySelectorAll('.show-answer').forEach(function (button, index) {
|
||||
button.addEventListener('click', function () {
|
||||
console.log(`Antwort anzeigen Button geklickt. Button Index: ${index}`);
|
||||
const variableContainer = this.closest('.variable-container');
|
||||
if (!variableContainer) {
|
||||
console.error('Variable Container nicht gefunden für Button:', this);
|
||||
showToast('Interner Fehler: Container nicht gefunden.', 'error');
|
||||
return;
|
||||
}
|
||||
const input = variableContainer.querySelector('input');
|
||||
if (!input) {
|
||||
console.error('Input Feld nicht gefunden in Variable Container:', variableContainer);
|
||||
showToast('Interner Fehler: Eingabefeld nicht gefunden.', 'error');
|
||||
return;
|
||||
}
|
||||
const correctAnswer = input.getAttribute('data-correct-answer');
|
||||
if (!correctAnswer) {
|
||||
console.error('Data-Correct-Answer Attribut fehlt im Input:', input);
|
||||
showToast('Interner Fehler: Richtige Antwort nicht verfügbar.', 'error');
|
||||
return;
|
||||
}
|
||||
|
||||
console.log(`Richtige Antwort: "${correctAnswer}"`);
|
||||
showToast(`Richtige Antwort: ${correctAnswer}`, 'info');
|
||||
});
|
||||
});
|
||||
});
|
||||
@@ -1,24 +1,26 @@
|
||||
[
|
||||
{
|
||||
"text": "34 + 26 = ?",
|
||||
"text": "$$\\frac{3}{5} + \\frac{1}{5} = ? $$",
|
||||
"vars": {
|
||||
"?": "60",
|
||||
"x": "5",
|
||||
"y": "2"
|
||||
"?": "4/5"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": "a + b = c",
|
||||
"text": "$$\\frac{4}{7} - \\frac{2}{7} = ? $$",
|
||||
"vars": {
|
||||
"a": "1",
|
||||
"b": "2",
|
||||
"c": "4"
|
||||
"?": "2/7"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": "Wie schreibt man nähmlich richtig?",
|
||||
"text": "Kürze $$\\frac{6}{9}$$",
|
||||
"vars": {
|
||||
"?": "nämlich"
|
||||
"?": "1/3"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": "Erweitere $$\\frac{1}{3}$$ mit 5",
|
||||
"vars": {
|
||||
"?": "5/15"
|
||||
}
|
||||
}
|
||||
]
|
||||
16
webseite/config/subjects/mathe/topics/geometrie/article.html
Normal file
16
webseite/config/subjects/mathe/topics/geometrie/article.html
Normal file
@@ -0,0 +1,16 @@
|
||||
Erklaerung: Die Flaeche eines Rechtecks oder Quadrats berechnet sich durch Laenge x Breite.
|
||||
Formel: A = l x b
|
||||
Beispiel: Rechteck mit l = 5 cm und b = 3 cm: A = 5 x 3 = 15 cm2
|
||||
<br> <br>
|
||||
|
||||
Thema: Berechnung des Umfangs von Rechtecken und Quadraten
|
||||
Formel: U = 2 x (l + b)
|
||||
Beispiel: Rechteck mit l = 5 cm und b = 3 cm: U = 2 x (5 + 3) = 16 cm
|
||||
<br> <br>
|
||||
|
||||
|
||||
Thema: Flaechenberechnung bei Dreiecken
|
||||
Formel: A = (1/2) x Grundlinie x Hoehe
|
||||
Beispiel: Ein Dreieck mit einer Grundlinie von 6 cm und einer Hoehe von 4 cm: A = (1/2) x 6 x 4 = 12
|
||||
cm2
|
||||
Uebungsa
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"displayName": "Geometrie",
|
||||
"icon": "fa-chart-pie",
|
||||
"description": "",
|
||||
"relatedTopics": [
|
||||
"schriftliches-multiplizieren",
|
||||
"schriftliches-dividieren",
|
||||
"punkt-vor-strichrechnung",
|
||||
"rechnen-mit-klammern"
|
||||
]
|
||||
}
|
||||
38
webseite/config/subjects/mathe/topics/geometrie/tasks.json
Normal file
38
webseite/config/subjects/mathe/topics/geometrie/tasks.json
Normal file
@@ -0,0 +1,38 @@
|
||||
[
|
||||
{
|
||||
"text": "Ein Quadrat mit Seitenlänge $$a = 4 cm$$ berechne die Fläche",
|
||||
"vars": {
|
||||
"Fläche in cm^2": "16"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": "Ein Rechteck mit $$l = 7 cm$$ und $$b = 2 cm$$ berechne die Fläche",
|
||||
"vars": {
|
||||
"Fläche in cm^2": "14"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": "Berechne den Umfang $$U$$ eines Quadrats mit $$a = 6 cm$$",
|
||||
"vars": {
|
||||
"U in cm": "24"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": "Berechne den Umfang $$U$$ eines Rechteck mit $$l = 8 cm$$ und $$b = 4 cm$$",
|
||||
"vars": {
|
||||
"?": "24"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": "Ein Dreieck mit der Grundlinie $$G = 8cm$$ und einer Höhe $$h= 5cm$$ berechne die Fläche",
|
||||
"vars": {
|
||||
"Fläche in cm^2": "20"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": "Ein Dreieck mit der Grundlinie $$G = 10cm$$ und einer Höhe $$h= 7cm$$ berechne die Fläche",
|
||||
"vars": {
|
||||
"Fläche in cm^2": "35"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -0,0 +1 @@
|
||||
Lorem Ipsum
|
||||
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,11 @@
|
||||
{
|
||||
"displayName": "schriftliche Addition und Subtraktion",
|
||||
"icon": "fa-chart-pie",
|
||||
"description": "Die Bruchrechnung ist ein Teil der Mathematik, der das Rechnen mit Brüchen beinhaltet, also das Teilen eines Ganzen in gleich große Teile, und umfasst Operationen wie Addition, Subtraktion, Multiplikation und Division von Brüchen.",
|
||||
"relatedTopics": [
|
||||
"schriftliches-multiplizieren",
|
||||
"schriftliches-dividieren",
|
||||
"punkt-vor-strichrechnung",
|
||||
"rechnen-mit-klammern"
|
||||
]
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
[
|
||||
{
|
||||
"text": "$$6342 + 9873 = ?$$",
|
||||
"vars": {
|
||||
"?": "16215"
|
||||
}
|
||||
},
|
||||
{
|
||||
"text": "$$4521 - 1234 = ?$$",
|
||||
"vars": {
|
||||
"?": "3287"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -1 +1,8 @@
|
||||
[]
|
||||
[
|
||||
{
|
||||
"text": "$$560 : 7 = ?$$",
|
||||
"vars": {
|
||||
"?": "80"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -1 +1,8 @@
|
||||
[]
|
||||
[
|
||||
{
|
||||
"text": "$$432 \\times 23 = ?$$",
|
||||
"vars": {
|
||||
"?": "9936"
|
||||
}
|
||||
}
|
||||
]
|
||||
@@ -95,6 +95,7 @@ if (!isset($topicData)) {
|
||||
<div class="max-w-7xl mx-auto mt-5">
|
||||
<div class="mt-16"></div>
|
||||
|
||||
<!-- Related Topics -->
|
||||
<div class="related-topics bg-gray-100 p-4 rounded-lg">
|
||||
<h4>Verwandte Themen:</h4>
|
||||
<ul class="flex flex-wrap gap-2">
|
||||
@@ -118,6 +119,7 @@ if (!isset($topicData)) {
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
<!-- Topic Content -->
|
||||
<div class="content-card mt-[8px]">
|
||||
<h1 class="content-title"><?php echo($topicData->displayName); ?></h1>
|
||||
<p class="content-text">
|
||||
@@ -148,6 +150,63 @@ if (!isset($topicData)) {
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Tasks -->
|
||||
<?php
|
||||
$tasks = $topicData->getTasks();
|
||||
// nur anzeigen, wenn Aufgaben vorhanden sind
|
||||
if ($tasks != null) {
|
||||
?>
|
||||
<div class="content-card mt-[8px]">
|
||||
<h1 class="content-title">Aufgaben</h1>
|
||||
<div style="display: flex; flex-wrap: wrap; gap: 0.5rem;">
|
||||
<?php
|
||||
foreach ($tasks as $taskIndex => $task) {
|
||||
$taskId = $taskIndex;
|
||||
?>
|
||||
<div class="task-container"
|
||||
data-task-id="<?php echo htmlspecialchars($taskId, ENT_QUOTES, 'UTF-8'); ?>">
|
||||
<p>
|
||||
<?php echo '<b>Aufgabe ' . ($taskIndex + 1) . ':</b> ' . htmlspecialchars($task->getText(), ENT_QUOTES, 'UTF-8'); ?>
|
||||
</p>
|
||||
<!-- Diesen Bereich für jeden Eintrag in Variables anzeigen lassen, z.B. x = [Textfeld] ... -->
|
||||
<?php
|
||||
$variables = $task->getVariables();
|
||||
foreach ($variables as $variableIndex => $variable) {
|
||||
$correctAnswer = $variable;
|
||||
?>
|
||||
<div class="variable-container" style="display: flex; flex-wrap: wrap; gap: 0.5rem; ">
|
||||
<label for="answer<?php echo $taskId . '_' . $variableIndex; ?>"></label>
|
||||
<input class="variable-input border-2 border-[var(--primary-color)]" id="answer<?php echo $taskId . '_' . $variableIndex; ?>" type="text"
|
||||
placeholder="<?php echo $variableIndex; ?>" data-correct-answer="<?php echo $correctAnswer; ?>"/>
|
||||
<button class="check-answer bg-white text-[var(--primary-color)] border-2 border-[var(--primary-color)] w-10 h-10 flex items-center justify-center rounded-lg hover:bg-[var(--primary-color)] hover:text-white transition duration-300">
|
||||
<i class="fa-solid fa-check"></i>
|
||||
</button>
|
||||
<button class="show-answer bg-white text-[var(--primary-color)] border-2 border-[var(--primary-color)] w-10 h-10 flex items-center justify-center rounded-lg hover:bg-[var(--primary-color)] hover:text-white transition duration-300">
|
||||
<i class="fa-solid fa-eye"></i>
|
||||
</button>
|
||||
</div>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
</div>
|
||||
<hr>
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Toasts Container -->
|
||||
<div id="toasts" class="fixed top-5 right-5 flex flex-col items-end space-y-4 z-50">
|
||||
<!-- Einzelne Toasts werden hier dynamisch hinzugefügt -->
|
||||
</div>
|
||||
|
||||
<?php
|
||||
}
|
||||
?>
|
||||
|
||||
|
||||
<!-- Related Topics -->
|
||||
<div class="related-topics bg-gray-100 p-4 rounded-lg">
|
||||
<h4>Verwandte Themen:</h4>
|
||||
<ul class="flex flex-wrap gap-2">
|
||||
|
||||
Reference in New Issue
Block a user