fix: the "Add to library" block in a question preview was three faults at once
Some checks failed
Tests / backend (push) Failing after 4s
Tests / frontend (push) Failing after 26s
Tests / e2e (push) Failing after 37s

It said library and meant collection. Its dropdown was always empty,
because the only page that renders this preview passes no collections —
so it read "Choose collection…" with nothing under it. And the "New
library…" input called setCollections, which does not exist in that
component: typing a name and pressing Enter created the collection,
added the question to it, and then threw a ReferenceError. Twelve lines,
none of which worked as written.

Removed rather than repaired. This preview is a moderator's editing
surface; putting a question aside is a learner's act and already lives
in the session and reading flows, where the collections are actually
loaded.

While there, the same word elsewhere: the Collections page called its
own contents "the question libraries you keep", which is the mislabel
the user spotted, on the page named after the other word. A library here
is the article library or an image library; a collection is what a
learner puts aside.

Found by the ped-ai session; the ReferenceError is mine to have missed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TqXevQJhxFrM7jJg82cgZN
This commit is contained in:
Daniel 2026-09-13 15:35:14 +02:00
parent a8cc0c40df
commit 77361816d8
3 changed files with 13 additions and 26 deletions

View file

@ -5,7 +5,7 @@ import './FolderPicker.css'
/**
* File the selected questions into a folder, for assignment.
*
* A folder is not a library. A library is what a learner puts aside for
* A folder is not a collection. A collection is what a learner puts aside for
* themselves and the API says so on every row; a folder is a list an educator
* assembles so that a grant can point at it, which is the one shape the access
* tree exam, discipline, category cannot express.

View file

@ -18,7 +18,15 @@ const TeachChat = lazyPage(() => import('./TeachChat'))
* Favourites and personal folders are optional and off by default those
* belong to studying a question, not to looking through the bank.
*/
export default function QuestionPreview({ question, onClose, isFavorited, onToggleFavorite, collections = [] }) {
/* No "Add to library" here any more. It was three faults in one twelve-line
block: it said library and meant collection; its dropdown was always empty,
because the only page that renders this preview passes no collections; and
the "New library…" input called setCollections, which does not exist in this
component so typing a name and pressing Enter created the collection,
added the question, and then threw a ReferenceError. Putting a question
aside belongs to the reading and session flows, where the collections are
actually loaded; this is a moderator's editing preview. */
export default function QuestionPreview({ question, onClose, isFavorited, onToggleFavorite }) {
return (
<>
<div style={{ position: 'fixed', inset: 0, background: 'rgba(0,0,0,0.55)', zIndex: 1000, display: 'flex', alignItems: 'center', justifyContent: 'center', padding: 16 }}
@ -101,27 +109,6 @@ export default function QuestionPreview({ question, onClose, isFavorited, onTogg
</div>
)}
<QuestionReadingLinks questionId={question.id} />
<div style={{ marginTop: 12, borderTop: '1px solid var(--border)', paddingTop: 10, fontSize: '0.85rem' }}>
<strong>Add to library</strong>
<div style={{ display: 'flex', gap: 8, marginTop: 6, flexWrap: 'wrap' }}>
<select defaultValue="" onChange={async e => {
if (!e.target.value) return
await api.put(`/collections/${e.target.value}/questions/${question.id}`)
e.target.value = ''
}} aria-label="Add to collection">
<option value="">Choose collection</option>
{collections.map(c => <option key={c.id} value={c.id}>{c.title}</option>)}
</select>
<input placeholder="New library…" aria-label="New library name" onKeyDown={async e => {
if (e.key === 'Enter' && e.target.value.trim()) {
const res = await api.post('/collections/', { title: e.target.value.trim() })
await api.put(`/collections/${res.data.id}/questions/${question.id}`)
setCollections(prev => [...prev, res.data])
e.target.value = ''
}
}} style={{ padding: '4px 10px', border: '1px solid var(--border)', borderRadius: 6, fontSize: '0.8rem' }} />
</div>
</div>
<div style={{ marginTop: 14, display: 'flex', gap: 8 }}>
<button className="btn btn-secondary btn-sm" onClick={onClose}>Close</button>
</div>

View file

@ -42,11 +42,11 @@ function Shelf({ rows, onDrop }) {
}
/**
* Everything a learner has put aside: the star, and the libraries they made.
* Everything a learner has put aside: the star, and the collections they made.
*
* Sorted by when each was last used rather than when it was made, because the
* order things were created in is nobody's mental model of their own shelf.
* A library nobody has opened falls back to its age it is newer to the
* A collection nobody has opened falls back to its age it is newer to the
* learner than it is to the database.
*/
export default function CollectionsPage() {
@ -179,7 +179,7 @@ export default function CollectionsPage() {
<div className="col-head">
<h1>Collections</h1>
<p>
The question libraries you keep. Favourites are not here they are
The question collections you keep. Favourites are not here they are
marked while you sit a session, and sat again from the session
builder, filtered by system or discipline like anything else.
</p>