Rename the Export stage to Finish
It now holds files, sharing, handouts, slides, importing notes, schedule, co-teachers and earlier versions, not just exports. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
2c7c7145c4
commit
0f1a181d87
12 files changed
+18
-18
No files matched your search
+1
-1
@@ -167,7 +167,7 @@ const AppInner = () => {
|
|||||||
// The browser tab and history show where you are ("Romans 8 · Bible Study", "Luke — Outline · Bible Study")
|
// The browser tab and history show where you are ("Romans 8 · Bible Study", "Luke — Outline · Bible Study")
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const names = {
|
const names = {
|
||||||
home: 'My Studies', setup: 'Chunks', study: 'Study', outline: 'Outline', script: 'Script', export: 'Export',
|
home: 'My Studies', setup: 'Chunks', study: 'Study', outline: 'Outline', script: 'Script', export: 'Finish',
|
||||||
import: 'Import', pronunciation: 'Pronunciation Guide', settings: 'Settings', admin: 'Admin', 'reading-plans': 'Reading Plans', prayer: 'Prayer journal', insights: 'Insights',
|
import: 'Import', pronunciation: 'Pronunciation Guide', settings: 'Settings', admin: 'Admin', 'reading-plans': 'Reading Plans', prayer: 'Prayer journal', insights: 'Insights',
|
||||||
};
|
};
|
||||||
let page = names[currentPage] ?? '';
|
let page = names[currentPage] ?? '';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Export → Co-teachers: let other accounts edit this study with you. You make a single-use invite link;
|
// Finish → Co-teachers: let other accounts edit this study with you. You make a single-use invite link;
|
||||||
// whoever opens it (signed in) can edit the study, and you can remove them any time. Edits from both of you
|
// whoever opens it (signed in) can edit the study, and you can remove them any time. Edits from both of you
|
||||||
// sync through the account; if you both change the same study, "Combine both" keeps everything.
|
// sync through the account; if you both change the same study, "Combine both" keeps everything.
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Export → Lesson handout: a printable page for each session (or one session), for a group to follow along.
|
// Finish → Lesson handout: a printable page for each session (or one session), for a group to follow along.
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { HANDOUT_LAYOUTS, printHandout, sessionsFor } from '../utils/handout.js';
|
import { HANDOUT_LAYOUTS, printHandout, sessionsFor } from '../utils/handout.js';
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Export → Import notes: bring notes from a Word or Markdown file into this study, matched to its chunks by passage.
|
// Finish → Import notes: bring notes from a Word or Markdown file into this study, matched to its chunks by passage.
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useApp } from '../context/AppContext.js';
|
import { useApp } from '../context/AppContext.js';
|
||||||
import { useToast } from './Toasts.jsx';
|
import { useToast } from './Toasts.jsx';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Export → Schedule: the study's sessions (one per chunk) as a calendar file, starting on a date you pick.
|
// Finish → Schedule: the study's sessions (one per chunk) as a calendar file, starting on a date you pick.
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { formatChunkReference } from '../utils/bibleUtils.jsx';
|
import { formatChunkReference } from '../utils/bibleUtils.jsx';
|
||||||
import { buildIcs, downloadIcs, sessionDates } from '../utils/icsFile.js';
|
import { buildIcs, downloadIcs, sessionDates } from '../utils/icsFile.js';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Export → Slides: a printable slide deck for a session or the whole study (Save as PDF in the print dialog).
|
// Finish → Slides: a printable slide deck for a session or the whole study (Save as PDF in the print dialog).
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { sessionsFor } from '../utils/handout.js';
|
import { sessionsFor } from '../utils/handout.js';
|
||||||
import { printSlides } from '../utils/slides.js';
|
import { printSlides } from '../utils/slides.js';
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// Export → Earlier versions: the copies the server kept of this study as you worked. Look at what is different
|
// Finish → Earlier versions: the copies the server kept of this study as you worked. Look at what is different
|
||||||
// from now, and put one back. The version you replace is kept, so putting one back can be undone too.
|
// from now, and put one back. The version you replace is kept, so putting one back can be undone too.
|
||||||
import { useCallback, useEffect, useState } from 'react';
|
import { useCallback, useEffect, useState } from 'react';
|
||||||
import { getStudyVersion, listStudyVersions } from '../syncService.js';
|
import { getStudyVersion, listStudyVersions } from '../syncService.js';
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ export const STAGES = [
|
|||||||
{ id: 'study', label: 'Study' },
|
{ id: 'study', label: 'Study' },
|
||||||
{ id: 'outline', label: 'Outline' },
|
{ id: 'outline', label: 'Outline' },
|
||||||
{ id: 'script', label: 'Script' },
|
{ id: 'script', label: 'Script' },
|
||||||
{ id: 'export', label: 'Export' },
|
{ id: 'export', label: 'Finish' },
|
||||||
];
|
];
|
||||||
const THEME_ORDER = ['paper', 'sepia', 'dark'];
|
const THEME_ORDER = ['paper', 'sepia', 'dark'];
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
// The Export stage: take the finished study out as a file, or share it read-only.
|
// The Finish stage: everything for when a study is ready to use: files, sharing, handouts, slides, importing notes, schedule, co-teachers and earlier versions.
|
||||||
import { useApp } from '../context/AppContext.js';
|
import { useApp } from '../context/AppContext.js';
|
||||||
import { useShareLink } from '../hooks/useShareLink.js';
|
import { useShareLink } from '../hooks/useShareLink.js';
|
||||||
import SlidesExport from '../components/SlidesExport.jsx';
|
import SlidesExport from '../components/SlidesExport.jsx';
|
||||||
@@ -32,7 +32,7 @@ export default function ExportPage() {
|
|||||||
<StudioShell stage="export">
|
<StudioShell stage="export">
|
||||||
<main className="mx-auto max-w-2xl space-y-5 px-4 py-8">
|
<main className="mx-auto max-w-2xl space-y-5 px-4 py-8">
|
||||||
<div>
|
<div>
|
||||||
<h1 className="text-xl font-medium">Export</h1>
|
<h1 className="text-xl font-medium">Finish</h1>
|
||||||
<p className="mt-1 text-sm text-[var(--r-sub)]">{allChunks.length} chunk{allChunks.length === 1 ? '' : 's'} · {filled} script{filled === 1 ? '' : 's'} written</p>
|
<p className="mt-1 text-sm text-[var(--r-sub)]">{allChunks.length} chunk{allChunks.length === 1 ? '' : 's'} · {filled} script{filled === 1 ? '' : 's'} written</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// Every Greek and Hebrew word in the study with its transliteration, so a
|
// Every Greek and Hebrew word in the study with its transliteration, so a
|
||||||
// speaker can rehearse them. Reached from the Script and Export stages.
|
// speaker can rehearse them. Reached from the Script and Finish stages.
|
||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { useApp } from '../context/AppContext.js';
|
import { useApp } from '../context/AppContext.js';
|
||||||
import StudioShell from '../components/study/StudioShell.jsx';
|
import StudioShell from '../components/study/StudioShell.jsx';
|
||||||
|
|||||||
@@ -190,16 +190,16 @@ describe('Home page', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Export stage (useShareLink) and the shared read-only view
|
// Finish stage (useShareLink) and the shared read-only view
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
describe('Project header and sharing', () => {
|
describe('Project header and sharing', () => {
|
||||||
const json = (status, data) => Promise.resolve({ ok: status < 400, status, json: () => Promise.resolve(data) });
|
const json = (status, data) => Promise.resolve({ ok: status < 400, status, json: () => Promise.resolve(data) });
|
||||||
|
|
||||||
test('Export stage → Markdown downloads a file', async () => {
|
test('Finish stage → Markdown downloads a file', async () => {
|
||||||
const user = await loadChapter();
|
const user = await loadChapter();
|
||||||
addChunk('Paul, a servant', 'Paul, a servant');
|
addChunk('Paul, a servant', 'Paul, a servant');
|
||||||
await screen.findByText('1 created');
|
await screen.findByText('1 created');
|
||||||
await user.click(screen.getByRole('button', { name: /^export$/i }));
|
await user.click(screen.getByRole('button', { name: /^finish$/i }));
|
||||||
await user.click(await screen.findByRole('button', { name: /export markdown/i }));
|
await user.click(await screen.findByRole('button', { name: /export markdown/i }));
|
||||||
expect(URL.createObjectURL).toHaveBeenCalled();
|
expect(URL.createObjectURL).toHaveBeenCalled();
|
||||||
});
|
});
|
||||||
@@ -216,7 +216,7 @@ describe('Project header and sharing', () => {
|
|||||||
const user = await loadChapter();
|
const user = await loadChapter();
|
||||||
addChunk('Paul, a servant', 'Paul, a servant');
|
addChunk('Paul, a servant', 'Paul, a servant');
|
||||||
await screen.findByText('1 created');
|
await screen.findByText('1 created');
|
||||||
await user.click(screen.getByRole('button', { name: /^export$/i }));
|
await user.click(screen.getByRole('button', { name: /^finish$/i }));
|
||||||
await user.click(await screen.findByRole('button', { name: /enable sharing/i }));
|
await user.click(await screen.findByRole('button', { name: /enable sharing/i }));
|
||||||
expect(await screen.findByDisplayValue(/\?share=tok123$/)).toBeInTheDocument();
|
expect(await screen.findByDisplayValue(/\?share=tok123$/)).toBeInTheDocument();
|
||||||
});
|
});
|
||||||
@@ -310,12 +310,12 @@ describe('Chunk builder', () => {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
// Stage bar (Chunks / Study / Outline / Script / Export)
|
// Stage bar (Chunks / Study / Outline / Script / Finish)
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
describe('Stage bar', () => {
|
describe('Stage bar', () => {
|
||||||
test('later stages are disabled until a chunk exists', async () => {
|
test('later stages are disabled until a chunk exists', async () => {
|
||||||
await loadChapter();
|
await loadChapter();
|
||||||
for (const name of [/^study$/i, /^outline$/i, /^script$/i, /^export$/i]) {
|
for (const name of [/^study$/i, /^outline$/i, /^script$/i, /^finish$/i]) {
|
||||||
expect(screen.getByRole('button', { name })).toBeDisabled();
|
expect(screen.getByRole('button', { name })).toBeDisabled();
|
||||||
}
|
}
|
||||||
expect(screen.getByRole('button', { name: /^chunks$/i })).not.toBeDisabled();
|
expect(screen.getByRole('button', { name: /^chunks$/i })).not.toBeDisabled();
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ describe('Back to the dashboard', () => {
|
|||||||
await dashboard();
|
await dashboard();
|
||||||
});
|
});
|
||||||
|
|
||||||
test.each(['Chunks', 'Study', 'Outline', 'Script', 'Export'])('the %s stage of a study', async (stage) => {
|
test.each(['Chunks', 'Study', 'Outline', 'Script', 'Finish'])('the %s stage of a study', async (stage) => {
|
||||||
const u = await loadChapter();
|
const u = await loadChapter();
|
||||||
addChunk('Paul, a servant', 'In hope of eternal');
|
addChunk('Paul, a servant', 'In hope of eternal');
|
||||||
await screen.findByText('1 created');
|
await screen.findByText('1 created');
|
||||||
|
|||||||
Reference in new issue
Block a user