Commit Graph

11 Commits

Author SHA1 Message Date
Maxim Dolgolyov 58cff2285e refactor(dashboard): use ls.css design tokens
Replaced 42 hardcoded brand colors with var() tokens:

CSS rules:
- linear-gradient(135deg,#9B5DE5,#06D6E0) → var(--grad-1) in dh-avatar, lb-avatar, gam-level
- #0F172A → var(--text) in 28 CSS rules (text colors for all major widget labels,
  titles, buttons: dh-greeting, ac-title, qa-btn, grade-subj, act-tab.active,
  hm-footer strong, hm-tip bg, hdp-date/subj, assign-search, sc-month,
  qs-subj-btn, qs-select/input, adm-act, adm-sess-name, cs-name, assign-chip.active,
  ae-btn, ar-title, ar-btn, hist-subj, subj-chart-name, weak-name,
  ms-title, empty-cta-title, btn-join, stats-bar tooltip bg, stats-chip-val,
  tc-title, lb-title, lb-name, lb-class-sel, ch-title, gam-rank, gam-chip-val)
- #3D4F6B → var(--text-2) in hist-score, ae-submit-note
- #9B5DE5 → var(--violet) in lb-xp, ar-sub-chip.s-none, lb-tab.active,
  ch-pct, ch-xp, dash-cfg-title, dash-cfg-fab, dash-cfg-checkbox accent-color
- #06D6E0 / #F15BB5 → var(--cyan) / var(--pink) in stat rings and progress fills

JS-generated HTML/SVG:
- var(--violet)/var(--cyan) in SVG statRingSvg calls, goal ring SVG, barColor
- weak-fill gradient partial replacement (--pink)

Kept: 90deg progress bar gradients, domain palette colors (#E0335E/#059652/#7c3aed
/#05aab3/etc.), Chart.js hex configs (CSS vars unsupported there), canvas fillStyle,
action banner dark gradients, heatmap cell alphas, adm-act-icon domain navcolors.

Before: ~65 hardcodes | After: ~20 hardcodes (Chart.js, canvas, domain/dark theme)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-22 22:19:02 +03:00
Maxim Dolgolyov d3b1cd75a0 feat(dashboard): teacher view polish — chips, bars, KPIs, groups, mobile
P0 visual polish:
- adm-actions: grouped layout (teaching/content/admin) with 3-col grid at wide, responsive
- thick 8px colored progress bars (green ≥75 / amber 50-74 / pink <50)
- session % rendered as colored chip (tinted bg + border)
- hover state on .adm-sess-row and .asgn-row in admin-grid
- empty states with Lucide icon + CTA button (inbox/users/clock)
- class-name badge on assignment row (disambiguates duplicates)
- relative timestamp on session rows via relativeAgo()
- search input above assignment list (filterAdminAssignments())
- adm-act-icon bumped 16px → 20px; card hover: scale + shadow

P1 header KPIs + urgency:
- dh-kpi-row: classes / students / active-asgn / pending chips under greeting
- isTeacherUrgent(): assignments within 48h get pink border + срочно badge
- adm-act-badge: count badge on Мои классы and Работы cards
- loadTeacherKPIs() fetches /api/classes + teacherAssignments() in parallel

P2 grouping + mobile + micro:
- chevron-right icons on Все/Все классы section links
- mobile ≤640: single-column groups, KPI chips wrap, sess-rows wrap
- mobile ≤480: adm-act-group single column
- dark mode rules for new elements

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-05-17 15:25:34 +03:00
Maxim Dolgolyov 5c66105fc2 refactor: ещё 6 модалок → LS.modal (dashboard, theory, course)
dashboard.html: 2 → 0 
  - join-modal — вступить в класс
  - qs-modal — быстрый тест с выбором предмета + режим + кол-во

theory.html: 1 → 0 
  - new-course-modal — создание нового курса учителем

course.html: 4 → 0 
  - add-section-modal — новый раздел курса
  - edit-course-modal — редактирование курса
  - add-lesson-modal — новый урок
  - save-course-tpl-modal — сохранить курс как шаблон

Везде:
  - Inline <div class=\"modal-overlay\">...</div> → удалён
  - openX(): создаёт modal через LS.modal({content, actions})
  - closeX() удалена — _xModal.close()
  - Глобальный selectQsSubject() inline'нут как listener на body модалки
  - Enter-handler на главных inputs сохранён

Не трогаю:
  - biochem.html#lib-modal — кастомная тёмная тема, не подходит под
    светлый LS.modal без редизайна
  - library.html — 3 сложные модалки (folder-access, assign, upload)
    с tabs и dynamic state — отдельный заход
  - classes.html — modal-assign (128 строк, complex) + review-modal
  - flashcards.html — fc-modal (не modal-overlay, своя CSS)

Прогресс миграции: 12 простых модалок → LS.modal за серию (4 ранее
+ 2 ранее + 6 сейчас). 4 страницы полностью очищены от
modal-overlay. Унифицированы:
  - ESC/backdrop/focus поведение
  - z-index (9000)
  - Анимация (scale .22s)
  - Адаптив на мобилке
2026-05-16 19:33:39 +03:00
Maxim Dolgolyov 3ff2f01178 feat: textbooks Phase 4 — A1+A2+A3+B4+C7 + назначение ученику
A1 — карточка ДЗ-чтения у ученика на /dashboard:
  - Новая ветка в buildAssignCard для assignments с textbook_id
  - Прогресс-бар «X из Y §», цвет берётся из textbook.color
  - Кнопка «Открыть / Продолжить» с deep-link на первый требуемый параграф
  - В classify(): textbook_all_read → done, deadline → overdue

A2 — авто-проверка выполнения:
  - При POST /:slug/progress с mark_read: проверяются активные textbook-assignments
  - Если все требуемые § прочитаны → INSERT в assignment_completion
  - SSE-уведомление учителю «Ученик завершил чтение: <title>»
  - myAssignments возвращает completed_at и textbook_all_read

A3 — учительский UI прогресса класса:
  - Новая страница /textbook-progress (учитель/админ)
  - Селекторы «учебник × класс» → таблица учеников с прогрессом
  - Сортировка по количеству прочитанного, дата last_at
  - Кнопка «Прогресс класса» добавлена в /textbooks (видна учителям)

B4 — admin-UI управления учебниками:
  - /admin-textbooks (только admin) — таблица всех учебников
  - Inline-редактирование title/author, тоггл is_active
  - Колонка «Читателей» (count из textbook_progress)
  - Endpoints: GET /api/textbooks/admin/all, PATCH /admin/:id

C7 — закладки/заметки внутри учебника:
  - Таблица textbook_bookmarks (user, textbook, para, text, note, color)
  - API: GET/POST/PATCH/DELETE для CRUD закладок
  - В tracker: при выделении текста (8-400 симв) появляется плавающая «+ Закладка»
  - Кнопка-иконка в overlay top-left открывает панель «Мои закладки»
  - Хранится paragraph-якорь, цвет, заметка, кнопка удалить

Назначение ученику (в дополнение к классу):
  - В модалке /textbooks — переключатель «Классу / Ученику»
  - Поиск ученика по имени/email через /api/classes/students
  - Submit использует POST /api/assignments (createDirectAssignment)
  - createDirectAssignment расширен textbook_slug + textbook_paragraphs
  - Учитель может назначать только ученикам своих классов

myAssignments расширен: возвращает textbook fields + post-process
  считает textbook_required_count, textbook_read_count, textbook_all_read.

Deep-link поддержка: /textbook/<slug>#pN в tracker.js — на load и hashchange
вызывает setParaTab(pN) (нативная функция учебника).

Миграция 005: assignment_completion + textbook_bookmarks + индексы.
2026-05-16 16:37:11 +03:00
Maxim Dolgolyov 26ba289019 a11y: WCAG AA contrast + ARIA roles + focus management across all pages
- css/ls.css: --text-3 #8898AA → #56687A (5.1:1 contrast), min-height 44px on .btn-primary/.btn-ghost/.sb-link, new .icon-btn utility (44×44px)
- js/api.js: lsConfirm — role=dialog, aria-modal, aria-labelledby, Tab focus trap, restore focus on close; lsToast — aria-live=polite on container, role=alert on errors; live quiz — role=dialog, role=radiogroup, role=radio, aria-checked, keyboard support
- test-run.html: q-opt divs — role=radio/checkbox, aria-checked, tabindex, keyboard enter/space; confirm modal — role=dialog, aria-modal; btn-flag — aria-pressed; dots — aria-label, aria-current; touch targets 44px
- board.html: btn-del-ann — aria-label; reaction buttons — aria-label, aria-pressed
- All 18 HTML files: replace hardcoded color:#8898AA with color:var(--text-3)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 11:42:38 +03:00
Maxim Dolgolyov f3c9ab860e feat: sound system — 12 new sounds + navigation category; dashboard FAB widget button
Sounds:
- UI: modal_open, modal_close, tab_switch, delete
- Navigation (new category): page_enter, section_reveal
- Classroom: timer_warning, wb_clear, file_shared
- Gamification: challenge_complete, daily_login
- Quiz: time_up, quiz_bonus

Dashboard:
- Widget configurator moved from header to fixed FAB (bottom-right)
  no longer pushed off-screen by wide sidebar

Profile settings:
- Added Navigation category toggle
- Expanded preview section: 12 test buttons covering all categories

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 20:26:04 +03:00
Maxim Dolgolyov 89ba25cd20 feat: user preferences sync — server-side storage, whiteboard defaults, dashboard widget visibility
- New table `user_preferences` (user_id PK, JSON blob, updated_at)
- GET/PATCH/DELETE /api/preferences with deep-merge UPSERT
- LS.prefs singleton in api.js: dot-notation get/set, debounced flush (1.5s), server sync
- classroom.html: load wb.color/width/lineStyle/theme from prefs on init; save on change
- dashboard.html: widget configurator panel (gear button) — toggle visibility per-user, persisted server-side

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 20:17:25 +03:00
Maxim Dolgolyov 29aa985504 feat: add sound system (LS.sfx) — synthesized Web Audio API sounds for classroom, gamification, quiz
- New js/sound.js: shared LS.sfx module with 21 synthesized sounds (ADSR envelope, sequences, sweeps, noise)
- Classroom: lesson_start/end, user_joined/left, hand_raise, chat_message, muted, draw_permitted
- Dashboard: achievement, level_up, xp_gain, coin via SSE events
- Live quiz: quiz_start, quiz_end on question launch and results
- Settings panel: global enable toggle + volume slider + localStorage persistence
- Replaces old _crBeep() in classroom.html

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-14 19:43:13 +03:00
Maxim Dolgolyov edb4c211a0 feat: universal sidebar via sidebar.js + stale ID cleanup
- Add js/sidebar.js: generates full sidebar HTML into #app-sidebar,
  handles role-based visibility, active link (with prefix matching),
  toggle wiring, collapsed state, board/features/notif init
- Replace <aside class="sidebar">...</aside> with <aside id="app-sidebar">
  across all 35 standard-layout pages via scripts/apply-sidebar.js
- Add notifications.js to 5 pages that were missing it
- Fix api.js initPage(): skip toggle re-wiring if data-sb-wired set,
  fix active link selector .sb-item → .sb-link
- Remove stale sbl-*/nav-admin/btn-upload-nav getElementById calls
  that crashed after sidebar replacement (lab, classes, collection,
  crossword, hangman, knowledge-map, library, pet, profile)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 21:22:21 +03:00
Maxim Dolgolyov fd29acbbdd feat: WebSocket real-time + rAF render gate + guest board + screen picker
Classroom performance:
- WebSocket server (ws-server.js) for low-latency cursor & stroke preview
  Replaces HTTP POST per event → eliminates per-message auth overhead
  Session member cache (30s TTL) avoids SQLite query per WS message
  Fallback to HTTP POST when WS not connected
- Cursor throttle reduced 100ms → 33ms (~30fps)
- Stroke preview throttle reduced 50ms → 20ms
- whiteboard.js: render() is now rAF-gated (_doRender/_rafPending)
  Multiple render() calls within one frame collapse into one repaint
  document.hidden check — zero CPU when tab is in background
  visibilitychange listener restores canvas on tab focus

Guest board:
- guestClassroom.js route: public token-based read-only access
- guest-board.html: name entry + read-only whiteboard + SSE
- SSE: addGuestClient/removeGuestClient/emitToGuests

Screen share picker:
- Discord-style modal with tab switching (screen/window/tab)
- Live video preview before confirming share
- useExistingScreenStream() in ClassroomRTC

Fullscreen exit overlay:
- #cr-fs-exit-overlay button inside cr-board-wrap
- Visible only via CSS :fullscreen selector (touchpad users)

File sharing from library:
- Teacher picks file from library, sends as styled card in chat
- crDownloadLibraryFile() fetches with Bearer auth

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-13 18:04:59 +03:00
Maxim Dolgolyov be4d43105e LearnSpace: full-stack educational whiteboard platform
Node.js/Express backend + vanilla JS frontend.
Features: real-time collaborative whiteboard (SSE), multi-page support,
LaTeX formulas, shapes/connectors, coordinate systems, number lines,
compass, zoom/pan, Catmull-Rom pencil smoothing, ruler/protractor with
rotation & resize controls, minimap navigation overlay, auto-measurements,
multi-page thumbnails sidebar, PNG export, page templates.
Student/teacher workflows: classes, assignments, library, dashboard.
Mobile responsive. SQLite (better-sqlite3).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-04-12 10:10:37 +03:00