feat: integrate reading plans with Bible reader
Bible Reader Integration: - Fetch and display active reading plan progress in Bible reader - Progress bar shows plan completion percentage when user has active plan - Progress bar color changes to green for active plans - Display "Plan Name Progress" with days completed below bar Reading Plan Navigation: - Add "Read the Bible" button to active reading plan detail page - Button shows current/next reading selection (Day X: Book Chapter) - Navigate directly to Bible reader with correct book and chapter - Smart selection: current day if incomplete, next incomplete day if current is done - Only shown for ACTIVE plans Technical: - Load active plans via /api/user/reading-plans endpoint - Calculate progress from completedDays vs plan duration - Use getCurrentReading() helper to determine next reading - URL encoding for book names with spaces 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -40,7 +40,8 @@ import {
|
||||
EmojiEvents,
|
||||
TrendingUp,
|
||||
Edit,
|
||||
Save
|
||||
Save,
|
||||
MenuBook
|
||||
} from '@mui/icons-material'
|
||||
import Link from 'next/link'
|
||||
|
||||
@@ -210,6 +211,39 @@ export default function ReadingPlanDetailPage() {
|
||||
return entry?.notes || ''
|
||||
}
|
||||
|
||||
const getCurrentReading = () => {
|
||||
if (!plan) return null
|
||||
|
||||
const schedule = plan.plan?.schedule || plan.customSchedule
|
||||
if (!schedule || !Array.isArray(schedule)) return null
|
||||
|
||||
// Get the current day's reading (or first incomplete day)
|
||||
let dayToRead = plan.currentDay
|
||||
|
||||
// If current day is completed, find the next incomplete day
|
||||
if (isDayCompleted(dayToRead)) {
|
||||
for (let i = dayToRead; i <= schedule.length; i++) {
|
||||
if (!isDayCompleted(i)) {
|
||||
dayToRead = i
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const daySchedule = schedule[dayToRead - 1]
|
||||
if (!daySchedule || !daySchedule.readings || daySchedule.readings.length === 0) {
|
||||
return null
|
||||
}
|
||||
|
||||
const reading = daySchedule.readings[0]
|
||||
return {
|
||||
day: dayToRead,
|
||||
book: reading.book,
|
||||
chapter: reading.chapter,
|
||||
verses: reading.verses
|
||||
}
|
||||
}
|
||||
|
||||
if (loading) {
|
||||
return (
|
||||
<ProtectedRoute>
|
||||
@@ -363,6 +397,38 @@ export default function ReadingPlanDetailPage() {
|
||||
</Grid>
|
||||
</Grid>
|
||||
|
||||
{/* Read the Bible Button */}
|
||||
{plan.status === 'ACTIVE' && (() => {
|
||||
const currentReading = getCurrentReading()
|
||||
return currentReading ? (
|
||||
<Box sx={{ mb: 4, textAlign: 'center' }}>
|
||||
<Button
|
||||
variant="contained"
|
||||
size="large"
|
||||
startIcon={<MenuBook />}
|
||||
component={Link}
|
||||
href={`/${locale}/bible?book=${encodeURIComponent(currentReading.book)}&chapter=${currentReading.chapter}`}
|
||||
sx={{
|
||||
py: 2,
|
||||
px: 4,
|
||||
fontSize: '1.1rem',
|
||||
fontWeight: 600,
|
||||
boxShadow: 3,
|
||||
'&:hover': {
|
||||
boxShadow: 6
|
||||
}
|
||||
}}
|
||||
>
|
||||
Read Today's Selection: {currentReading.book} {currentReading.chapter}
|
||||
{currentReading.verses && `:${currentReading.verses}`}
|
||||
</Button>
|
||||
<Typography variant="caption" display="block" color="text.secondary" sx={{ mt: 1 }}>
|
||||
Day {currentReading.day} of {duration}
|
||||
</Typography>
|
||||
</Box>
|
||||
) : null
|
||||
})()}
|
||||
|
||||
{/* Reading Schedule */}
|
||||
<Paper elevation={2} sx={{ p: 3 }}>
|
||||
<Typography variant="h6" gutterBottom fontWeight="600">
|
||||
|
||||
Reference in New Issue
Block a user