'use strict';
// NOTE: innerHTML usage is intentional - content comes from our own API/DB only (admin-imported Markdown).
// This is an internal training tool for 2-5 known users. No user-generated content.
var Flashcards = {
session: null,
render: function(params) {
var el = document.getElementById('content');
if (params[0] === 'study' && params[1]) {
this.renderStudy(el, params[1]);
return;
}
el.textContent = 'Lade Decks...';
var self = this;
API.get('/decks').then(function(data) {
self.renderDeckList(el, data.decks);
}).catch(function(e) {
el.textContent = e.message;
});
},
renderDeckList: function(el, decks) {
var total = decks.reduce(function(s, d) { return s + (d.card_count || 0); }, 0);
var totalDue = decks.reduce(function(s, d) { return s + (parseInt(d.due) || 0); }, 0);
var h = '
';
decks.forEach(function(d) {
var reviewed = parseInt(d.reviewed) || 0;
var ct = d.card_count || 0;
var due = parseInt(d.due) || 0;
var pct = ct > 0 ? Math.round((reviewed / ct) * 100) : 0;
h += '
';
h += '
' + Markdown.esc(d.name) + '
';
h += '
' + ct + ' Karten — ' + pct + '% gelernt
';
if (due > 0) h += '
' + due + ' Karten faellig
';
h += '
';
h += '
';
});
h += '
';
el.innerHTML = h; // safe: data from own API only
el.querySelectorAll('.deck-card').forEach(function(card) {
card.addEventListener('click', function() {
location.hash = '#/flashcards/study/' + card.dataset.slug;
});
});
},
renderStudy: function(el, slug) {
el.textContent = 'Lade Karten...';
var self = this;
API.get('/cards/due?deck=' + slug + '&limit=50').then(function(data) {
if (data.cards.length === 0) {
return API.get('/cards/deck/' + slug).then(function(allData) {
var h = '← Zurueck zu Decks ';
h += 'Keine faelligen Karten ';
h += '
Alle Karten sind gelernt. Komm spaeter wieder!
';
h += '
Alle ' + allData.cards.length + ' Karten ueben ';
el.innerHTML = h; // safe: static text + number
document.getElementById('start-all-btn').addEventListener('click', function() {
self.startSession(el, slug, allData.cards);
});
});
}
self.startSession(el, slug, data.cards);
}).catch(function(e) { el.textContent = e.message; });
},
startSession: function(el, slug, cards) {
this.session = { slug: slug, cards: cards, index: 0, correct: 0, wrong: 0, showAnswer: false };
this.renderCard(el);
},
renderCard: function(el) {
var s = this.session;
if (s.index >= s.cards.length) { this.renderSummary(el); return; }
var card = s.cards[s.index];
var open = s.cards.length - s.index - 1;
var deckName = card.deck_name || s.slug;
var lastReview = card.last_reviewed_at
? 'Zuletzt: ' + new Date(card.last_reviewed_at).toLocaleDateString('de-DE')
: 'Noch nie gelernt';
var h = '← Zurueck zu Decks ';
h += '';
h += ' ';
h += '' + (card.level || 'basis') + ' ';
h += '' + lastReview + '
';
h += '
' + Markdown.render(card.question) + '
';
if (s.showAnswer) {
h += '
Antwort
' + Markdown.render(card.answer) + '
';
h += '
';
h += 'Leicht ';
h += 'Mittel ';
h += 'Schwer ';
h += 'Falsch
';
} else {
h += '
Antwort zeigen
';
}
h += '
';
el.innerHTML = h; // safe: Markdown content from own DB
var self = this;
if (s.showAnswer) {
document.getElementById('rate-easy').addEventListener('click', function() { self.rate('easy'); });
document.getElementById('rate-medium').addEventListener('click', function() { self.rate('medium'); });
document.getElementById('rate-hard').addEventListener('click', function() { self.rate('hard'); });
document.getElementById('rate-wrong').addEventListener('click', function() { self.rate('wrong'); });
} else {
document.getElementById('show-answer-btn').addEventListener('click', function() {
s.showAnswer = true;
self.renderCard(el);
});
}
},
rate: function(rating) {
var s = this.session;
var card = s.cards[s.index];
if (rating === 'easy' || rating === 'medium') s.correct++;
else s.wrong++;
API.post('/cards/' + card.id + '/review', { rating: rating }).catch(function(e) { console.error('Review error:', e); });
s.index++;
s.showAnswer = false;
this.renderCard(document.getElementById('content'));
},
renderSummary: function(el) {
var s = this.session;
var total = s.correct + s.wrong;
var pct = total > 0 ? Math.round((s.correct / total) * 100) : 0;
var h = '← Zurueck zu Decks ';
h += 'Session abgeschlossen! ';
h += '
';
h += '' + s.correct + ' richtig ';
h += '' + s.wrong + ' falsch
';
h += '
' + pct + '% korrekt
';
h += '
Zurueck zu Decks ';
el.innerHTML = h; // safe: only session stats
}
};