feat(dashboard): карточка чтения наполняется данными (фон+инфо учебника)
Раньше при отсутствии начатого курса карточка оставалась статичной заглушкой («Учебники»). Теперь: - при прогрессе — «Продолжить чтение»: курс, урок, прогресс-бар, %; - иначе — рекомендованный учебник из /api/courses: название, описание, число параграфов; - фон-градиент карточки по предмету (SUBJ_GRADIENT, как обложки). Синтаксис всех инлайн-скриптов проверен (0 ошибок). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+62
-12
@@ -3201,23 +3201,73 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* ══ HERO: Reading card (continue or start) ══════════════════════ */
|
/* ══ HERO: Reading card (continue or start) ══════════════════════ */
|
||||||
|
// Градиент-обложка карточки чтения по предмету (как обложки учебников)
|
||||||
|
const SUBJ_GRADIENT = {
|
||||||
|
chemistry:'linear-gradient(135deg,#d9742a 0%,#b3531a 100%)',
|
||||||
|
physics:'linear-gradient(135deg,#3b6fd4 0%,#26408a 100%)',
|
||||||
|
biology:'linear-gradient(135deg,#2fa86a 0%,#1c6e44 100%)',
|
||||||
|
math:'linear-gradient(135deg,#7a5cf0 0%,#4b32b3 100%)',
|
||||||
|
informatics:'linear-gradient(135deg,#0f9aa8 0%,#0a6470 100%)',
|
||||||
|
english:'linear-gradient(135deg,#e0557f 0%,#a82f57 100%)',
|
||||||
|
russian:'linear-gradient(135deg,#d64545 0%,#8a2626 100%)',
|
||||||
|
belarus:'linear-gradient(135deg,#d64545 0%,#8a2626 100%)',
|
||||||
|
history:'linear-gradient(135deg,#b5862a 0%,#7a571a 100%)',
|
||||||
|
geography:'linear-gradient(135deg,#2f9aa8 0%,#1c6470 100%)',
|
||||||
|
astronomy:'linear-gradient(135deg,#5a4fd4 0%,#2e2680 100%)',
|
||||||
|
social:'linear-gradient(135deg,#c2682a 0%,#8a4519 100%)',
|
||||||
|
};
|
||||||
|
function _renderReadCard(o) {
|
||||||
|
const card = document.getElementById('hc-read');
|
||||||
|
if (!card) return;
|
||||||
|
if (o.href) card.href = o.href;
|
||||||
|
if (SUBJ_GRADIENT[o.slug]) card.style.background = SUBJ_GRADIENT[o.slug];
|
||||||
|
document.getElementById('hc-read-tag').textContent = o.tag;
|
||||||
|
document.getElementById('hc-read-title').textContent = o.title;
|
||||||
|
document.getElementById('hc-read-sub').textContent = o.sub || '';
|
||||||
|
document.getElementById('hc-read-meta').textContent = o.meta || '';
|
||||||
|
const pw = document.getElementById('hc-read-prog-wrap');
|
||||||
|
const pe = document.getElementById('hc-read-pct');
|
||||||
|
if (o.showProg) {
|
||||||
|
if (pw) { pw.style.display = ''; document.getElementById('hc-read-prog').style.width = (o.pct || 0) + '%'; }
|
||||||
|
if (pe) { pe.style.display = ''; pe.textContent = (o.pct || 0) + '%'; }
|
||||||
|
} else {
|
||||||
|
if (pw) pw.style.display = 'none';
|
||||||
|
if (pe) pe.style.display = 'none';
|
||||||
|
}
|
||||||
|
}
|
||||||
async function loadContinueWidget() {
|
async function loadContinueWidget() {
|
||||||
const card = document.getElementById('hc-read');
|
const card = document.getElementById('hc-read');
|
||||||
if (!card) return;
|
if (!card) return;
|
||||||
try {
|
try {
|
||||||
const data = await LS.api('/api/courses/continue');
|
const data = await LS.api('/api/courses/continue');
|
||||||
if (!data || !data.courseId) return; // оставляем дефолт «Начать чтение → Учебники»
|
if (data && data.courseId) {
|
||||||
const pct = data.lessonCount > 0 ? Math.round((data.doneCount || 0) / data.lessonCount * 100) : 0;
|
const pct = data.lessonCount > 0 ? Math.round((data.doneCount || 0) / data.lessonCount * 100) : 0;
|
||||||
card.href = `/lesson?course=${data.courseId}&lesson=${data.lessonId}`;
|
_renderReadCard({
|
||||||
document.getElementById('hc-read-tag').textContent = 'Продолжить чтение';
|
tag: 'Продолжить чтение',
|
||||||
document.getElementById('hc-read-title').textContent = data.courseTitle || 'Продолжить';
|
href: `/lesson?course=${data.courseId}&lesson=${data.lessonId}`,
|
||||||
document.getElementById('hc-read-sub').textContent = data.lessonTitle || '';
|
title: data.courseTitle || 'Продолжить',
|
||||||
document.getElementById('hc-read-meta').textContent = `${data.doneCount || 0} / ${data.lessonCount || 0} уроков`;
|
sub: data.lessonTitle || '',
|
||||||
const progWrap = document.getElementById('hc-read-prog-wrap');
|
meta: `${data.doneCount || 0} / ${data.lessonCount || 0} уроков`,
|
||||||
if (progWrap) { progWrap.style.display = ''; document.getElementById('hc-read-prog').style.width = pct + '%'; }
|
slug: data.subjectSlug, pct, showProg: true,
|
||||||
const pctEl = document.getElementById('hc-read-pct');
|
});
|
||||||
if (pctEl) { pctEl.style.display = ''; pctEl.textContent = pct + '%'; }
|
return;
|
||||||
} catch { /* нет курса в процессе — карточка остаётся в дефолте */ }
|
}
|
||||||
|
} catch { /* нет прогресса — покажем рекомендованный учебник */ }
|
||||||
|
try {
|
||||||
|
const courses = await LS.api('/api/courses');
|
||||||
|
if (Array.isArray(courses) && courses.length) {
|
||||||
|
const c = courses[0];
|
||||||
|
const cnt = c.lesson_count || 0;
|
||||||
|
_renderReadCard({
|
||||||
|
tag: 'Начать чтение',
|
||||||
|
href: `/course?id=${c.id}`,
|
||||||
|
title: c.title || 'Учебник',
|
||||||
|
sub: c.description || 'Открой учебник и начни курс.',
|
||||||
|
meta: cnt ? `${cnt} § · новый учебник` : 'новый учебник',
|
||||||
|
slug: c.subject_slug, pct: 0, showProg: false,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch { /* дефолт «Учебники» */ }
|
||||||
}
|
}
|
||||||
|
|
||||||
/* ══ HERO: Lab of the day (deterministic daily pick) ═════════════ */
|
/* ══ HERO: Lab of the day (deterministic daily pick) ═════════════ */
|
||||||
|
|||||||
Reference in New Issue
Block a user