-
-
Reading Plan
-
Set a goal to read through a book, track chapters as you go.
+
+ {active.map((progress) => {
+ const plan = getPlan(progress.planId);
+ if (!plan) return null;
+ const schedule = getPlanSchedule(progress.planId);
+ const pct = plan.days > 0 ? Math.round((progress.completedDays.length / plan.days) * 100) : 0;
+ const nextDay = nextUnreadDayIndex(plan, progress.completedDays);
+ const nextRefs = nextDay != null ? schedule[nextDay] : null;
+ return (
+
+
+
+
Reading Plan
+
{plan.title}
+
+ {progress.completedDays.length} / {plan.days} days
+ {nextRefs && <> · Next: {formatDayReadings(nextRefs)}>}
+
+
+
+ {nextRefs && (
+
+ )}
+
+
+
+
+
{pct}%
-
-
- )}
+ );
+ })}
);
}
diff --git a/src/pages/ReaderPage.jsx b/src/pages/ReaderPage.jsx
index af9f083..50150ee 100644
--- a/src/pages/ReaderPage.jsx
+++ b/src/pages/ReaderPage.jsx
@@ -4,6 +4,7 @@ import { formatCrossRef, speakOriginalWord } from '../utils/wordStudy.js';
import AuthStatus from '../components/AuthStatus.jsx';
import AudioPlayer from '../components/AudioPlayer.jsx';
import { bookOptions, BookmarkIcon, CopyIcon } from '../utils/bibleUtils.jsx';
+import { getPlan, getPlanSchedule, findDayIndexForRef } from '../utils/readingPlans.js';
import DrawCanvas from './DrawCanvas.jsx';
const NO_STROKES = []; // stable fallback so DrawCanvas doesn't redraw every render
@@ -57,11 +58,26 @@ export default function ReaderPage() {
readerTextHighlights,
addTextHighlight,
removeTextHighlight,
- readingPlan,
- markChapterRead,
+ planProgress,
+ toggleDay,
} = useApp();
const readerBook = bookOptions.find((b) => b.abbrev === readerBookAbbrev);
+
+ // Active reading plans whose schedule includes the chapter currently on screen.
+ const planMatches = useMemo(() => {
+ return planProgress
+ .filter((p) => !p.completedAt)
+ .map((p) => {
+ const plan = getPlan(p.planId);
+ if (!plan) return null;
+ const dayIndex = findDayIndexForRef(getPlanSchedule(p.planId), readerBookAbbrev, readerChapter);
+ if (dayIndex === -1) return null;
+ return { progressId: p.id, plan, dayIndex, done: p.completedDays.includes(dayIndex) };
+ })
+ .filter(Boolean);
+ }, [planProgress, readerBookAbbrev, readerChapter]);
+
const [readerDrawMode, setReaderDrawMode] = useState(false);
const [readerWideLayout, setReaderWideLayout] = useState(() => localStorage.getItem('reader-wide') === '1');
const readerPageInkStrokes = readerInkByPage?.[`${readerBookAbbrev}_${readerChapter}`] ?? NO_STROKES;
@@ -316,19 +332,17 @@ export default function ReaderPage() {
- {readingPlan && readingPlan.bookAbbrev === readerBookAbbrev && (() => {
- const done = readingPlan.chaptersRead.includes(readerChapter);
- return (
-
- );
- })()}
+ {planMatches.map(({ progressId, plan, dayIndex, done }) => (
+
+ ))}