Move study editor state into StudyPage and hooks

- StudyPage owns layout/tabs/collapsed sections, tags, DOCX script
  import, chunk navigation, keyboard shortcuts, and the selected-chunk
  values derived from the project.
- useStudyResources: commentary + interlinear for the selected chunk's
  chapter. These now load only on the study page (they previously also
  fetched while on Setup).
- useCrossRefs: typed refs, dataset suggestions, verse text.
- useWordStudy: word entries, Strong's lookups, suggestion picker.
- Fix: study-page messages (word suggestions, DOCX import, lookups) set a
  status that only SetupPage displayed, so they were never seen. They
  now show as a toast on the study page.
- copyVerse moves into ReaderPage.
- Tests: toast, arrow-key navigation, cross-refs, tags.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
nmemmertandClaude Opus 5.5 committed 2026-09-22 14:59:22 -04:00
1 parent 4b14b3fbe6
commit bf02e071fa
8 files changed
+749 -771

No files matched your search

+40
View File
@@ -631,3 +631,43 @@ describe('Project header and sharing', () => {
}
});
});
// ---------------------------------------------------------------------------
// Study editor (StudyPage local state + useCrossRefs / useWordStudy hooks)
// ---------------------------------------------------------------------------
describe('Study editor', () => {
test('study-page messages now show as a status toast', async () => {
await goToStudyWith3Chunks();
// Titus is a New Testament book, so the Hebrew picker explains why it can't help.
fireEvent.click(screen.getByRole('button', { name: /suggest hebrew/i }));
expect(await screen.findByRole('status')).toHaveTextContent(/old testament/i);
});
test('arrow keys move between chunks', async () => {
await goToStudyWith3Chunks();
fireEvent.keyDown(window, { key: 'ArrowRight' });
expect(await findChunkCounter(2, 3)).toBeInTheDocument();
fireEvent.keyDown(window, { key: 'ArrowLeft' });
expect(await findChunkCounter(1, 3)).toBeInTheDocument();
});
test('a typed cross-reference is added, and the input clears on chunk change', async () => {
await goToStudyWith3Chunks();
const input = screen.getByPlaceholderText(/john 1:1 or rom 3:23/i);
fireEvent.change(input, { target: { value: 'Rom 3:23' } });
fireEvent.keyDown(input, { key: 'Enter' });
expect(await screen.findByText('Rom 3:23')).toBeInTheDocument();
fireEvent.change(input, { target: { value: 'half typed' } });
fireEvent.click(screen.getByRole('button', { name: /next chunk/i }));
await waitFor(() => expect(input).toHaveValue(''));
});
test('a tag can be added with Enter', async () => {
await goToStudyWith3Chunks();
const input = screen.getByPlaceholderText(/add a tag/i);
fireEvent.change(input, { target: { value: 'grace' } });
fireEvent.keyDown(input, { key: 'Enter' });
expect(await screen.findByText(/#?grace/)).toBeInTheDocument();
expect(input).toHaveValue('');
});
});