feat: add user settings save and reading plans with progress tracking
User Settings: - Add /api/user/settings endpoint for persisting theme and fontSize preferences - Update settings page with working save functionality - Add validation and localized error messages Reading Plans: - Add database schema with ReadingPlan, UserReadingPlan, and UserReadingProgress models - Create CRUD API endpoints for reading plans and progress tracking - Build UI for browsing available plans and managing user enrollments - Implement progress tracking with daily reading schedule - Add streak calculation and statistics display - Create seed data with 5 predefined plans (Bible in 1 year, 90 days, NT 30 days, Psalms 30, Gospels 30) - Add navigation link with internationalization support Technical: - Update to MUI v7 Grid API (using size prop instead of xs/sm/md and removing item prop) - Fix Next.js 15 dynamic route params (await params pattern) - Add translations for readingPlans in all languages (en, ro, es, it) 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -40,6 +40,8 @@ model User {
|
||||
userPrayers UserPrayer[]
|
||||
readingHistory ReadingHistory[]
|
||||
preferences UserPreference[]
|
||||
userReadingPlans UserReadingPlan[]
|
||||
readingProgress UserReadingProgress[]
|
||||
createdPages Page[] @relation("PageCreator")
|
||||
updatedPages Page[] @relation("PageUpdater")
|
||||
uploadedFiles MediaFile[]
|
||||
@@ -500,3 +502,87 @@ enum SubscriptionStatus {
|
||||
INCOMPLETE_EXPIRED
|
||||
UNPAID
|
||||
}
|
||||
|
||||
// Reading Plans
|
||||
model ReadingPlan {
|
||||
id String @id @default(uuid())
|
||||
name String // "Bible in One Year", "New Testament in 30 Days"
|
||||
description String? @db.Text
|
||||
type ReadingPlanType @default(PREDEFINED)
|
||||
duration Int // Number of days
|
||||
schedule Json // Daily reading schedule: {day: 1, readings: [{book, chapter, verses}]}
|
||||
difficulty String @default("beginner") // beginner, intermediate, advanced
|
||||
language String @default("en")
|
||||
isActive Boolean @default(true)
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
userPlans UserReadingPlan[]
|
||||
|
||||
@@index([type])
|
||||
@@index([language])
|
||||
@@index([isActive])
|
||||
}
|
||||
|
||||
enum ReadingPlanType {
|
||||
PREDEFINED
|
||||
CUSTOM
|
||||
}
|
||||
|
||||
model UserReadingPlan {
|
||||
id String @id @default(uuid())
|
||||
userId String
|
||||
planId String? // Null for custom plans
|
||||
name String // Plan name (especially for custom plans)
|
||||
startDate DateTime @default(now())
|
||||
targetEndDate DateTime // Expected completion date
|
||||
actualEndDate DateTime? // When actually completed
|
||||
status ReadingPlanStatus @default(ACTIVE)
|
||||
currentDay Int @default(1) // Current day in plan
|
||||
completedDays Int @default(0) // Total days completed
|
||||
streak Int @default(0) // Current consecutive days
|
||||
longestStreak Int @default(0) // Best streak achieved
|
||||
customSchedule Json? // For custom plans: same format as ReadingPlan.schedule
|
||||
reminderEnabled Boolean @default(true)
|
||||
reminderTime String? // "08:00" - time of day for reminder
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
plan ReadingPlan? @relation(fields: [planId], references: [id], onDelete: SetNull)
|
||||
progress UserReadingProgress[]
|
||||
|
||||
@@index([userId])
|
||||
@@index([status])
|
||||
@@index([userId, status])
|
||||
}
|
||||
|
||||
enum ReadingPlanStatus {
|
||||
ACTIVE
|
||||
COMPLETED
|
||||
PAUSED
|
||||
CANCELLED
|
||||
}
|
||||
|
||||
model UserReadingProgress {
|
||||
id String @id @default(uuid())
|
||||
userId String
|
||||
userPlanId String
|
||||
planDay Int // Day number in the reading plan
|
||||
date DateTime @default(now()) // Date of reading
|
||||
bookId String // Bible book read
|
||||
chapterNum Int
|
||||
versesRead String? // "1-10" or "all" or null for whole chapter
|
||||
completed Boolean @default(true)
|
||||
notes String? @db.Text
|
||||
createdAt DateTime @default(now())
|
||||
updatedAt DateTime @updatedAt
|
||||
|
||||
user User @relation(fields: [userId], references: [id], onDelete: Cascade)
|
||||
userPlan UserReadingPlan @relation(fields: [userPlanId], references: [id], onDelete: Cascade)
|
||||
|
||||
@@unique([userPlanId, planDay, bookId, chapterNum]) // One entry per chapter per day per plan
|
||||
@@index([userId])
|
||||
@@index([userPlanId])
|
||||
@@index([userId, date])
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user