fix incorrect score setup

This commit is contained in:
2026-07-03 13:28:26 +03:00
parent 45ff877017
commit 15c3ec2018
6 changed files with 352 additions and 12 deletions
+118
View File
@@ -0,0 +1,118 @@
import { getHistory } from './history.ts';
import type { RepetitionRecord } from './history.ts';
import { execute } from './sqlite-manager.ts';
export interface HistoryViewCallbacks {
onBack: () => void;
}
/**
* Показывает страницу истории повторений для указанной колоды.
*/
export async function renderHistoryView(
container: HTMLElement,
setId: number,
callbacks: HistoryViewCallbacks,
): Promise<void> {
container.innerHTML = `
<div class="history-header">
<button id="btnHistoryBack" class="btn" style="flex:none; padding:0.4rem 0.8rem;">← Назад</button>
<span style="font-size:0.85rem;color:var(--text);">Загрузка...</span>
</div>
<div class="history-card">
<div id="history-content" style="text-align:center;padding:2rem;opacity:0.6;">Загрузка истории...</div>
</div>
`;
document.getElementById('btnHistoryBack')?.addEventListener('click', () => {
callbacks.onBack();
});
try {
const records = await getHistory(setId, 2000);
// Получаем слова для отображения
const wordIds = [...new Set(records.map((r) => r.word_id))];
const wordMap = await getWordMap(wordIds);
const headerSpan = container.querySelector('.history-header span');
if (headerSpan) {
headerSpan.textContent = `записей: ${records.length}`;
}
const contentEl = document.getElementById('history-content');
if (!contentEl) return;
if (records.length === 0) {
contentEl.innerHTML = '<div style="text-align:center;padding:2rem;opacity:0.6;">История пуста</div>';
return;
}
contentEl.innerHTML = '';
for (const record of records) {
const word = wordMap.get(record.word_id);
const wordText = word ? word : `#${record.word_id}`;
const date = new Date(record.timestamp);
const dateStr = date.toLocaleString('ru-RU', {
day: '2-digit',
month: '2-digit',
hour: '2-digit',
minute: '2-digit',
});
const modeLabels: Record<string, string> = {
easy: '🟢 Легко',
ok: '🟡 Нормально',
hard: '🟠 Тяжело',
none: '🔴 Не знаю',
};
const row = document.createElement('div');
row.className = 'history-row';
row.innerHTML = `
<div class="history-row-word">${escapeHtml(wordText)}</div>
<div class="history-row-mode">${modeLabels[record.mode] || record.mode}</div>
<div class="history-row-scores">
<span class="history-score-before">${record.score_before.toFixed(1)}</span>
<span class="history-score-arrow">→</span>
<span class="history-score-after">${record.score_after.toFixed(1)}</span>
</div>
<div class="history-row-date">${dateStr}</div>
`;
contentEl.appendChild(row);
}
} catch (err) {
console.error('[History] Ошибка загрузки:', err);
const contentEl = document.getElementById('history-content');
if (contentEl) {
contentEl.innerHTML = '<div style="text-align:center;padding:2rem;color:var(--error);">Ошибка загрузки истории</div>';
}
}
}
async function getWordMap(wordIds: number[]): Promise<Map<number, string>> {
const map = new Map<number, string>();
if (wordIds.length === 0) return map;
try {
const placeholders = wordIds.map(() => '?').join(',');
const rows: any[] = await execute(
`SELECT id, key FROM words WHERE id IN (${placeholders})`,
wordIds,
);
for (const row of rows) {
// rows — массив массивов [id, key]
map.set(row[0], row[1]);
}
} catch {
// ignore
}
return map;
}
function escapeHtml(text: string): string {
const div = document.createElement('div');
div.textContent = text;
return div.innerHTML;
}