Add paper/print alternatives for off-screen learning
Build and Push Docker Image / build-and-push (push) Successful in 3m35s

- Spelling: "Blank test" print button per word list (numbered lines, no words shown) for dictated paper tests
- Spelling: "Record Paper Test" form in admin to log a paper test score to the gradebook
- Gradebook: "Record Paper Score" form to log a paper quiz/assignment score for any course item
- Flashcards: "Print" button per deck generates a cut-and-fold card sheet (fronts page + backs page)
- Crossword: print now includes a second page with a filled answer key
- Lessons + Assignments: 🖨 Print button in student view generates a clean printable page
- Word lists: new "CSV file" import tab — upload a .csv with word, sentence, definition columns

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Sonnet 4.6 committed 2026-10-19 12:43:38 -04:00
1 parent 6baea15986
commit a92db291c7
5 files changed
+392 -3

No files matched your search

+60
View File
@@ -396,6 +396,28 @@
<button id="gradebook-csv-btn" class="secondary">⬇ Export CSV</button>
</div>
<div id="gradebook-table"></div>
<details class="admin-card" id="paper-score-details" style="margin:1.5rem 0">
<summary style="cursor:pointer;font-weight:600">📝 Record Paper Score</summary>
<p class="hint" style="margin:.5rem 0 .75rem">Use this to log a score from a paper quiz, assignment, or other item done off-screen.</p>
<div class="inline-form" style="flex-direction:column;gap:.6rem">
<div class="inline-form" style="gap:.5rem;flex-wrap:wrap">
<label>Student <select id="paper-score-student"></select></label>
<label>Course <select id="paper-score-course"></select></label>
</div>
<label>Item <select id="paper-score-item"><option value="">— select a course first —</option></select></label>
<div class="inline-form" style="gap:.5rem;align-items:center">
<label>Score <input type="number" id="paper-score-score" min="0" style="width:4.5rem" placeholder="0"></label>
<span style="padding-top:1.4rem">out of</span>
<label>Total <input type="number" id="paper-score-total" min="1" style="width:4.5rem"></label>
<label>Date <input type="date" id="paper-score-date"></label>
</div>
<div>
<button type="button" id="paper-score-save">Record score</button>
<span id="paper-score-status" class="hint" style="margin-left:.5rem"></span>
</div>
</div>
</details>
<h2>Spelling Test History</h2>
<div class="inline-form">
<label>Period <select id="spelling-tests-since">
@@ -432,6 +454,26 @@
<section id="panel-spelling" class="panel">
<h1>Spelling</h1>
<details class="admin-card" id="paper-test-details" style="margin-bottom:1.5rem">
<summary style="cursor:pointer;font-weight:600">📝 Record Paper Test</summary>
<div class="inline-form" style="flex-direction:column;gap:.6rem;margin-top:.75rem">
<div class="inline-form" style="gap:.5rem;flex-wrap:wrap">
<label>Student <select id="paper-test-student"></select></label>
<label>Word list <select id="paper-test-list"></select></label>
</div>
<div class="inline-form" style="gap:.5rem;align-items:center">
<label>Score <input type="number" id="paper-test-score" min="0" style="width:4.5rem" placeholder="0"></label>
<span style="padding-top:1.4rem">out of</span>
<label>Total <input type="number" id="paper-test-total" min="1" style="width:4.5rem"></label>
<label>Date <input type="date" id="paper-test-date"></label>
</div>
<div>
<button type="button" id="paper-test-save">Record test</button>
<span id="paper-test-status" class="hint" style="margin-left:.5rem"></span>
</div>
</div>
</details>
<h2>Practice Sessions</h2>
<div class="inline-form">
<label>Period <select id="sessions-since">
@@ -475,6 +517,7 @@
<div class="toggle-btns">
<button type="button" id="list-new-btn" class="secondary">+ New list</button>
<button type="button" id="list-bulk-btn" class="secondary">⬆ Bulk import</button>
<button type="button" id="list-csv-btn" class="secondary">📄 CSV file</button>
</div>
<div id="list-editor-section" hidden>
<h3 id="list-editor-title" class="section-form-title">New list</h3>
@@ -505,6 +548,23 @@
<p id="list-bulk-status" class="hint" style="margin:0.4rem 0 0"></p>
</div>
</div>
<div id="list-csv-section" hidden>
<h3 class="section-form-title">Import from CSV file</h3>
<div class="admin-card">
<p class="hint" style="margin:0 0 0.5rem">Upload a <code>.csv</code> or <code>.txt</code> file. Each row is one word. Columns: <code>word</code> (required), <code>sentence</code> (optional), <code>definition</code> (optional). A header row is ignored automatically.</p>
<div class="inline-form" style="flex-direction:column;gap:.5rem">
<input id="list-csv-name" placeholder="List name (required)" aria-label="List name for CSV import">
<input id="list-csv-group" placeholder="Group (optional)" aria-label="Group for CSV import" list="list-groups-datalist">
</div>
<input type="file" id="list-csv-file" accept=".csv,.txt" hidden>
<div class="inline-form" style="align-items:center;gap:.5rem;margin-top:.5rem">
<button type="button" id="list-csv-browse" class="secondary">📂 Choose file…</button>
<span id="list-csv-filename" class="hint" style="flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap"></span>
<button type="button" id="list-csv-go" class="secondary" disabled>📥 Import</button>
</div>
<p id="list-csv-status" class="hint" style="margin:0.4rem 0 0"></p>
</div>
</div>
</div>
</div>
</section>