Commit Graph
37 Commits
Author SHA1 Message Date
nmemmertandClaude Sonnet 4.6 538522cfe7 Fix 7 UX pain points: grading filter, next-item nav, lesson prose, gradebook calc, auto-schedule skip, lesson item defaults, planner improvements
- Grading: add student filter dropdown, Enter-to-save, and point max always defaults to 100
- Student side: show next-item/back-to-course actions after completing a lesson or assignment
- Lesson body: apply prose typography styles (headings, lists, blockquotes, links, hr)
- Gradebook: fix % display when points_possible is 0 (default to 100 on grade save)
- Auto-schedule: skip items that already have a submission
- Item editor: default new/existing item point values to 100 instead of 10
- Planner: friendly week date header, per-day short date, today highlight, course color on task pills, done toggle, within-day drag reorder, Today button

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-04 16:33:59 -04:00
nmemmertandClaude Sonnet 4.6 60a2a597c5 Planner UX improvements and grading max-points display
- Today button jumps planner to current week; today column highlighted with accent outline
- Week label now shows friendly format (Aug 3–7, 2026) instead of ISO dates
- Course color shown as left border on scheduled course items
- Parent-side done toggle on every planner task (works for offline + course items)
- Within-day drag-to-reorder tasks via new /api/schedule/reorder endpoint
- Grading queue shows visible "/ N pts" max-points label (defaults to 100 when unset)
- New item default points changed from 10 to 100

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-04 15:16:49 -04:00
nmemmertandClaude Sonnet 4.6 6b7b77829e Add school name, passing threshold, and week-start-day settings
- School/family name: saved to DB, appears in printed week/month report headers
- Passing grade threshold: replaces hardcoded 80% in all gradebook/history views
- Week start day (Mon vs Sun): shifts the planner 5-day grid and month view accordingly
- Settings are loaded at unlock time so they apply before any panel opens

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-04 14:11:23 -04:00
nmemmertandClaude Sonnet 4.6 a10239ead9 Remove page scanning / Ollama AI vision feature
Removes the scan-a-page workflow (photo → lesson/quiz content), all
Ollama/cloud provider code, the scan settings panel, and the related
DB seed values.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-04 13:52:55 -04:00
nmemmertandClaude Sonnet 4.6 61f9288aa5 Add student delight features: celebrations, sounds, animations, and background patterns
- Confetti + pop sound on lesson/assignment completion
- Done stamp animation (awaitable, shows below toast)
- Welcome toast on first login only (not back-navigation)
- Web Audio ding/buzz during spelling practice and flashcards
- Fanfare on all-day completion
- Score counter animate-up on practice/test results
- 3D flashcard flip animation (rotateY via CSS keyframes)
- Tab slide transition (Today/Courses/Spelling, directional)
- Staggered card entrance + time-of-day greeting on home screen
- Emoji wobble on kid card hover
- Word card green/red flash on correct/wrong spelling answer
- Combo streak celebration at milestones (3, 5, 7, 10 in a row)
- Random cheer messages for generic celebrations
- Button bounce on :active (scale + translateY)
- Progress bar smooth transition (0.5s ease-out)
- Background pattern picker: dots, stripes, grid, stars, bubbles
- bg_pattern persisted per-student via PATCH /api/students/:id/bg-pattern
- Theme switching preserves bg pattern class

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-04 13:15:53 -04:00
nmemmertandClaude Sonnet 4.6 6f73acd03e Add Worksheet item type with paste-and-parse authoring, digital submission, and print-blank
- New `worksheet` item type: admin pastes raw worksheet text, parser auto-detects fill-in-the-blank (___), true/false (T   F   ...), section headers (Part N —), and short-answer questions
- Admin editor shows each parsed question with inputs to set correct answers for FITB and T/F; short answers are marked parent-grades
- Kid view renders FITB as inline underline inputs, T/F as tap-to-toggle T/F buttons, and short answer as a textarea; Name/Date header auto-populated
- Auto-grades T/F (exact) and FITB (case-insensitive); worksheets with short answers go to grading queue as status=done
- Print blank button opens a formatted print window with underlines, circled T/F, and ruled lines for short answers
- "I handed in my paper copy" button lets kids mark a printed worksheet as turned in without digital submission, queuing it for parent grading

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-03 15:59:13 -04:00
nmemmertandClaude Sonnet 4.6 9abb107096 Perf, correctness, and data-integrity improvements
- requirePin: prepare pin-lookup statement once at module level instead of per-request
- Gradebook: replace O(students × items × 3) per-item queries with 2 bulk INs + in-memory Maps
- List/deck PUT: wrap DELETE + re-INSERT in a transaction to prevent partial-write corruption
- Print views: detect HTML vs plain-text lesson bodies before escaping, fixing rich-text output
- Planner add-task: parallelize course detail fetches with Promise.all
- Planner save-all: parallelize schedule inserts with Promise.all
- HOMESCHOOL_DIR: read from env var with existing path as fallback
- Remove unused isDown function in crossword-submit handler
- Remove dead empty-if stub in docx import change handler

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-03 14:58:56 -04:00
nmemmertandClaude Sonnet 4.6 eb4b713e9d Fix docx import missing lesson content — include h1-h6 block elements
mammoth outputs week/quiz headings as <h2>/<h1>, not <p><strong>. The
block-element regex only matched <p>, so all headings were skipped and no
lessons were ever created. Expand regex to h[1-6]|p|ul|ol and treat any
h-tag as a heading unconditionally.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-03 10:13:56 -04:00
nmemmertandClaude Sonnet 4.6 3197d29a28 Add course import/export: JSON bundle and direct Word docx upload
- Export any course as a .json bundle (GET /api/admin/courses/:id/export)
- Import a .json bundle as a new course (POST /api/admin/import-course)
- Import one or more unit .docx files directly in the browser — server
  parses each file with mammoth, extracts Week N: headings as lesson
  items and the Unit Quiz section as a graded quiz with answer key
  (POST /api/admin/import-course-docx, multer memory storage)
- Admin UI: Export button on course detail; Import card with JSON and
  Word docs tabs; multi-file picker for docx uploads
- scripts/import-kitchen-course.js: one-time converter that produced
  the Kitchen, Tools & Electrical Skills course JSON bundle (already
  imported as course id 3: 8 units, 44 items)

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-03 10:02:10 -04:00
Nate EmmertandClaude Sonnet 4.6 682534a061 Add crossword puzzle item type
Admin enters Across/Down words and clues; server auto-generates the grid
using a backtracking placement algorithm (longest-first, intersection-based).
Students fill in the interactive grid with click-to-select, direction toggle,
arrow-key navigation, and Tab-to-next-word. Auto-graded per word on submit,
with correct/wrong color highlighting on the results view. Includes a print
worksheet option for blank paper practice.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-01 17:56:46 -04:00
Nate EmmertandClaude Sonnet 4.6 05cfdf7b09 Add matching quiz type, more theme colors, animal icon picker, and fix color persistence
- Fix theme not saving across sessions: /api/state was missing `theme` in SELECT
- Add 4 new color themes: red, teal, yellow, indigo (student + admin)
- Add animal icon picker (32 animals) with PATCH /api/students/:id/emoji endpoint
- Add Matching item type: word bank (A, B, C… alphabetical) + clue blanks, auto-graded
- Matching submit button stays disabled until all blanks are filled

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-08-01 16:27:22 -04:00
nmemmertandClaude Sonnet 4.6 183bcf0ef2 Import .docx content directly into RTE editor as editable HTML
Instead of embedding an iframe, mammoth HTML is inserted straight into
the contenteditable body so the admin can edit it like any other content.
A download link to the original .docx sits above the content.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-30 12:26:55 -04:00
nmemmertandClaude Sonnet 4.6 6c9cfa84a8 Improve iframe document CSS: serif font, normalize bold
- Switch to Georgia to better match Word's serif rendering
- Explicit font-weight:normal on body/p so mammoth's <strong> wrapping
  doesn't bleed into paragraph text
- Tighter heading/paragraph spacing

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-30 11:40:38 -04:00
nmemmertandClaude Sonnet 4.6 fe29d25ddb Restore iframe embed with full-width, auto-height CSS
- Removed narrow max-width/margin from generated HTML page
- iframe now spans full card width (100%)
- onload JS auto-sizes iframe height to content so nothing is cut off
- Falls back to 500px if cross-origin restriction ever applies

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-30 11:37:58 -04:00
nmemmertandClaude Sonnet 4.6 2384fc9f7d Render document content inline instead of in iframe
Replace the <iframe> with an inline <div> containing the mammoth HTML.
Content now flows full-width with the page instead of being cramped in
a fixed-height scrolling box. Download link still available below.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-30 10:31:50 -04:00
nmemmertandClaude Sonnet 4.6 eff8cf5e60 Embed .docx as HTML iframe with download fallback
On upload, mammoth converts the doc to a styled HTML page saved alongside
the .docx. The item body gets an <iframe> pointing to the HTML so students
see the document inline. A download link below gives access to the original.
Falls back to a plain download link if HTML conversion fails.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-30 08:58:02 -04:00
nmemmertandClaude Sonnet 4.6 5de4cfa6cf Replace docx text extraction with file attachment upload
Instead of parsing .docx content via mammoth and inserting raw text/HTML,
the import flow now saves the file to data/attachments/ (UUID filename) and
inserts an <a> link into the item body so students can open/download the doc.

- Added GET /api/attachments/:filename (no PIN — students access directly)
- Added POST /api/admin/upload-attachment (PIN required)
- Removed mammoth dependency from server
- Updated admin.js import handler to POST to new endpoint and set link HTML

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-30 08:56:12 -04:00
nmemmertandClaude Sonnet 4.6 19f922c4ba Replace Ollama docx import with mammoth HTML conversion
Remove all AI processing from the import-docx endpoint. Instead:
- Convert the .docx to HTML with mammoth.convertToHtml (preserves
  bold, headings, lists, etc.) — the result goes straight into the
  item body and renders in the lesson viewer
- Extract raw text in parallel to pick the document title from the
  first non-empty line
- No external services, no AI, works on the deployed server

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-30 08:21:52 -04:00
nmemmertandClaude Sonnet 4.6 4100107c0a Use scan provider fallback for docx import (local → cloud)
The import-docx endpoint was hardcoded to local Ollama, which fails
on the deployed server where Ollama isn't running. Now mirrors the
image scan logic: tries local first, falls back to Ollama Cloud if
configured, using the same scan_primary setting.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-30 08:18:04 -04:00
nmemmertandClaude Sonnet 4.6 b048f51d46 Replace server-folder docx import with direct file picker
The old import scanned a hardcoded Seafile CloudStorage path that only
worked on one specific machine. Replaced with a standard <input type=file>
browser picker that reads the .docx as base64 and uploads it directly, so
the feature works everywhere. Server endpoint now accepts either a base64
payload or the legacy path. Also fixed a crash where resetImportSection()
still referenced the removed select element, which was breaking the item
editor for all item types.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-29 17:15:23 -04:00
nmemmertandClaude Sonnet 4.6 de598496bc Gradebook unit cards, scroll/state preservation on course edit
- Gradebook now groups items by unit with collapsible cards (same card
  style as course detail) and a Course overall summary table at the bottom
- server.js: add unit_id/unit_name to gradebook API so items can be grouped
- Course detail: preserve which units are open and scroll position across
  any in-place re-render (add unit, delete unit, save meta, return from
  item editor) — no more jumping to the top with everything reset

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-29 16:43:15 -04:00
nmemmertandClaude Sonnet 4.6 b048ebbd85 Add spelling test polish: date filter, CSV export, student history, planner badges
- Gradebook: period dropdown (all time / 30 / 90 days) and CSV export for
  Spelling Test History section
- Student portal spelling tab: shows last 10 tests as a Recent Tests list
- Planner: completed standalone spelling tests appear as read-only ⭐ badges
  on the day they were taken (week and month views)
- Removed dead s.tests query from /api/overview (now served by dedicated endpoints)
- New endpoints: GET /api/spelling-tests/csv, GET /api/students/:id/tests,
  GET /api/admin/students/:id/tests-range

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-27 14:26:47 -04:00
nmemmertandClaude Sonnet 4.6 183b43b452 Move spelling test results from Spelling panel into Gradebook
Adds a GET /api/spelling-tests endpoint that returns all standalone test
results grouped by student. The Gradebook panel now shows a "Spelling Test
History" section below the course gradebook table. Removed the "Test results"
section from the Spelling panel left column.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-27 13:55:23 -04:00
nmemmertandClaude Sonnet 4.6 774979f2e4 Add 4 UX improvements to spelling/flashcards panel
- Assign → button on each list row opens a popup to pick a kid directly
  without scrolling up to the assignment dropdowns
- Hide/Unhide button on built-in lists (stored in localStorage) keeps
  UNGROUPED clean; Show hidden toggle reveals them dimmed when needed
- Mastery progress bar on each kid showing X/Y words mastered for their
  current assigned list (server now returns listProgress in /api/overview)
- Filter-lists / filter-decks search input for fast lookup by name

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-27 13:47:27 -04:00
nmemmertandClaude Sonnet 4.6 9acd0a792f Add group/course labels to spelling lists and flashcard decks
- group_name column added to lists and decks tables
- GET/POST/PUT endpoints for both include group_name
- Admin Spelling and Flashcards panels render items grouped under
  labeled section headers (e.g. Bible 6, Bible 8) with ungrouped
  items shown last
- Group input in each form has datalist autocomplete from existing groups
- Edit/copy populates the group field; Clear resets it

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-27 12:22:27 -04:00
nmemmertandClaude Sonnet 4.6 0ae0db76bc Add course duplicate and compact list/roster layout
- POST /api/courses/:id/duplicate deep-copies a course with all units,
  items, and quiz questions; opens the copy immediately for renaming
- Roster changed from broken vertical stack to horizontal chip-pills
  (fixes admin-card label override that was collapsing inline-flex)
- item-row padding reduced for tighter lists throughout admin
- Courses and Kids admin panels now use a 2-column auto-fill grid

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-27 10:48:38 -04:00
nmemmertandClaude Sonnet 4.6 9889da3462 Show course name and assignment content in planner print
Week print: tasks grouped by day, each showing course name, type,
and full assignment body text. Month print: course name in calendar
cells + an Assignment Detail section below the calendar with body text.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 16:53:46 -04:00
nmemmertandClaude Sonnet 4.6 934919e392 Include assignment body and quiz questions in print course output
Course detail API now returns item body text and quiz questions.
Print course renders body paragraphs and numbered quiz questions
with lettered choices (correct answers marked with ✓).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 16:50:01 -04:00
nmemmertandClaude Sonnet 4.6 19fe0cb053 Add month planner view and print for courses and planner
- Month view toggle in planner (Mon-Fri calendar grid, 4-5 weeks)
- Prev/Next navigate by month when in month mode
- Print month report (landscape calendar layout)
- Print course button on course detail (all units + items)
- New GET /api/schedule-range endpoint for arbitrary date spans

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 16:47:28 -04:00
nmemmertandClaude Sonnet 4.6 3c22fe05f8 Add kid engagement features and planner drag-and-drop
- Streak tracker: server-side streak counting per kid, celebration overlay
  when all today's tasks are done for the first time that day
- Kid themes: 5 colour palettes (blue/green/purple/orange/pink), picked via
  colour dots on the kid home screen; parents can set it from the Kids panel
- Grading badge: Grading nav pill turns red and shows a pending count
- Print worksheets: 🖨 Worksheet button per word list in admin Spelling panel;
  kids also get "Print my words" on the Spelling tab
- Parent feedback: gold 💬 badge on Today rows with unread comments; more
  prominent callout styling inside the assignment view
- Planner drag-and-drop: tasks can be dragged between days; PATCH
  /api/schedule/:id moves the task, drop zones highlight on hover

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 16:40:07 -04:00
Nate EmmertandClaude Sonnet 4.6 984834e896 Add piper error detail to TTS response for debugging
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 10:35:03 -04:00
Nate EmmertandClaude Sonnet 4.6 fd88d964f7 Fix piper: add libespeak-ng1 dep and remove invalid spawnSync encoding
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 10:27:44 -04:00
Nate EmmertandClaude Sonnet 4.6 6f2281e2a7 Add spelling improvements and local Piper TTS
Practice: fire streak badge, first-letter hint on wrong answers, missed-words drill session after practice completes.
Test: audio-only mode with listening state before input appears, larger re-read button.
Words: definition field (DB migration + admin editor + TTS playback).
TTS: replace speechSynthesis with local Piper via /api/tts, WAV cached in data/tts-cache, falls back to browser voice when Piper is not installed.
Dockerfile: switched to node:26-slim, installs Piper binary + en_US-lessac-medium voice.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-21 08:47:10 -04:00
nmemmertandClaude Sonnet 4.6 544469d6c9 Add auto-schedule: fill planner from a course automatically
New "Auto-schedule a course" section in the Weekly Planner lets you pick
a course, start date, and items-per-day, then fills the planner in order
skipping weekends. POST /api/schedule/auto handles the logic server-side.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-14 14:19:13 -04:00
nmemmertandClaude Sonnet 4.6 a7de24b1da Add evidence submission, 3-state offline tasks, parent comments, and retake policies
- Evidence on assignments: photo upload + notes + student self-note (needs help / not sure)
- Evidence required/optional/none flag per item; grading queue shows evidence with lightbox thumbnail
- Parent comment field when grading; shown to student on graded items
- Offline tasks: 3-state status (not started → in progress → done) with inline evidence form
- Retake policy per item: latest / highest / average — gradebook computes effective score accordingly
- Grading queue expanded to include lessons and practices (not just assignments) when evidence present

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-14 13:33:42 -04:00
nmemmertandClaude Sonnet 4.6 02909e1edc Add retakes, quiz templates, score history, due dates, CSV export, and prerequisites
- allow_retakes flag on items: quizzes, spelling tests, and assignments can all be retaken
- Quiz templates: save any quiz as a reusable template and load it into new items
- Score history: every quiz/test attempt logged to submission_history; click a gradebook score to see all attempts
- Due dates: optional due date per item, shown in course view and gradebook (overdue flagged with ⚠️)
- Gradebook CSV export: one-click download of any course gradebook
- Prerequisites: lock an item until a prior one is completed; locked items show 🔒 in course view

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-14 13:22:58 -04:00
nmemmertandClaude Sonnet 4.6 23b24b5d21 Add GitHub Actions workflow and update docker-compose to use GHCR
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
2026-07-14 12:05:52 -04:00