Files
biblical-guide.com/app/api/user/settings/route.ts
Andrei 63082c825a 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>
2025-10-12 23:07:47 +00:00

104 lines
2.9 KiB
TypeScript

import { NextResponse } from 'next/server'
import { getUserFromToken } from '@/lib/auth'
import { prisma } from '@/lib/db'
export const runtime = 'nodejs'
function getErrorMessages(locale: string = 'ro') {
const messages = {
ro: {
unauthorized: 'Nu esti autentificat',
updateFailed: 'Actualizarea setărilor a eșuat',
success: 'Setări actualizate cu succes',
invalidData: 'Date invalide'
},
en: {
unauthorized: 'Unauthorized',
updateFailed: 'Settings update failed',
success: 'Settings updated successfully',
invalidData: 'Invalid data'
}
}
return messages[locale as keyof typeof messages] || messages.ro
}
export async function PUT(request: Request) {
try {
const url = new URL(request.url)
const locale = url.searchParams.get('locale') || 'ro'
const messages = getErrorMessages(locale)
// Get token from authorization header
const authHeader = request.headers.get('authorization')
const token = authHeader?.replace('Bearer ', '')
if (!token) {
return NextResponse.json({ error: messages.unauthorized }, { status: 401 })
}
// Verify token and get user
const user = await getUserFromToken(token)
if (!user) {
return NextResponse.json({ error: messages.unauthorized }, { status: 401 })
}
// Parse request body
const body = await request.json()
const { theme, fontSize, notifications, emailUpdates, language } = body
// Validate input - allow partial updates
const updateData: any = {}
if (theme !== undefined) {
if (!['light', 'dark', 'auto'].includes(theme)) {
return NextResponse.json({ error: messages.invalidData }, { status: 400 })
}
updateData.theme = theme
}
if (fontSize !== undefined) {
if (!['small', 'medium', 'large'].includes(fontSize)) {
return NextResponse.json({ error: messages.invalidData }, { status: 400 })
}
updateData.fontSize = fontSize
}
// Note: notifications and emailUpdates would need additional columns in User model
// For now, we'll skip them or store in a JSON field if needed
// Update user settings
const updatedUser = await prisma.user.update({
where: { id: user.id },
data: updateData,
select: {
id: true,
email: true,
name: true,
role: true,
theme: true,
fontSize: true,
subscriptionTier: true,
subscriptionStatus: true,
conversationLimit: true,
conversationCount: true,
limitResetDate: true
}
})
return NextResponse.json({
success: true,
message: messages.success,
user: updatedUser
})
} catch (error) {
console.error('Settings update error:', error)
const url = new URL(request.url)
const locale = url.searchParams.get('locale') || 'ro'
const messages = getErrorMessages(locale)
return NextResponse.json({ error: messages.updateFailed }, { status: 500 })
}
}