Studying: daily five minutes, reading list, plan-day studies use your template
- Home: "Your five minutes": a rotating Observe/Interpret/Apply prompt on the passage whose matching note is thinnest in your own words, a 5:00 clock and a box that appends to that note. Pasting is blocked; sessions show in Insights. - Study: a Reading list tab (R) for the study: books and articles to consult, with a note and a tick; merges across devices. - Starting a study from a reading-plan day now uses the notes template you last picked when starting a study by hand (logic moved to utils/planStudy.js). Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
0781fa3476
commit
eccc5e509d
20 files changed
+376
-32
No files matched your search
@@ -0,0 +1,32 @@
|
||||
// A reading list for the whole study: the books, commentaries and articles you plan to consult, with a note on
|
||||
// each and a tick when done. It belongs to the study, not one chunk.
|
||||
import { makeId } from '../../utils/bibleUtils.jsx';
|
||||
|
||||
export default function ReadingListTab({ project, updateProject }) {
|
||||
const items = project?.readingList ?? [];
|
||||
const set = (next) => updateProject((current) => ({ ...current, readingList: next(current.readingList ?? []) }));
|
||||
const add = (title) => { const t = title.trim(); if (t) set((list) => [...list, { id: makeId(), title: t, note: '', done: false }]); };
|
||||
const patch = (id, change) => set((list) => list.map((i) => (i.id === id ? { ...i, ...change } : i)));
|
||||
const open = items.filter((i) => !i.done).length;
|
||||
return (
|
||||
<div className="space-y-3 text-sm">
|
||||
<p className="text-xs text-[var(--r-sub)]">Books and articles to consult for this study{items.length ? ` · ${open} to read, ${items.length - open} done` : ''}. Read the passage and write your own notes first; this list is for afterwards.</p>
|
||||
<ul className="space-y-2">
|
||||
{items.map((i) => (
|
||||
<li key={i.id} className="rounded-xl border border-[var(--r-line)] p-2.5">
|
||||
<div className="flex items-center gap-2">
|
||||
<input type="checkbox" aria-label={`Read: ${i.title}`} checked={!!i.done} onChange={() => patch(i.id, { done: !i.done })} className="accent-[var(--r-accent)]" />
|
||||
<span className={`min-w-0 flex-1 ${i.done ? 'text-[var(--r-sub)] line-through' : 'font-medium'}`}>{i.title}</span>
|
||||
<button type="button" aria-label={`Remove ${i.title}`} onClick={() => set((list) => list.filter((x) => x.id !== i.id))} className="text-xs text-[var(--r-sub)] hover:text-[var(--r-danger,#b42318)]">×</button>
|
||||
</div>
|
||||
<input aria-label={`Note on ${i.title}`} value={i.note ?? ''} onChange={(e) => patch(i.id, { note: e.target.value })} placeholder="Where in it, or what to look for"
|
||||
className="mt-1.5 w-full rounded-lg border border-transparent bg-transparent px-2 py-1 text-xs text-[var(--r-text)] placeholder:text-[var(--r-sub)] placeholder:opacity-60 hover:border-[var(--r-line)] focus:border-[var(--r-line)] focus:bg-[var(--r-bg)] focus:outline-none" />
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<input aria-label="Add to the reading list" placeholder="Add a book or article, then Enter"
|
||||
onKeyDown={(e) => { if (e.key === 'Enter') { e.preventDefault(); add(e.target.value); e.target.value = ''; } }}
|
||||
className="w-full rounded-lg border border-[var(--r-line)] bg-[var(--r-bg)] px-2.5 py-1.5 text-sm text-[var(--r-text)] focus:outline-none" />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user