import { NextRequest, NextResponse } from 'next/server'; import { getServerSession } from 'next-auth'; import { authOptions } from '@/lib/auth'; import { prisma } from '@/lib/prisma'; import bcrypt from 'bcryptjs'; // Get user profile export async function GET(request: NextRequest) { const session = await getServerSession(authOptions); if (!session?.user?.email) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); const user = await prisma.user.findUnique({ where: { email: session.user.email }, select: { name: true, email: true, timezone: true, autoRolling: true, protectEventTimes: true, language: true, dateFormat: true, timeFormat: true, startHour: true, endHour: true, showNextTask: true, calendarEditMode: true, focusTimerDuration: true, focusBreakDuration: true, showTimeGrid: true, showSomeday: true, showAllDayEvents: true, showSchedule: true, cellDuration: true, viewStyle: true, viewDays: true, fontSize: true, goalFallbackType: true, goalDefaultSentence: true, goalFontFamily: true, goalFontSize: true, goalFontWeight: true, goalScope: true, dateLayout: true, headlineFont: true, headlineFontSize: true, headlineFontWeight: true, dateFontFamily: true, dateFontSize: true, dateFontWeight: true, timeTaskFontFamily: true, timeTaskFontSize: true, timeTaskFontWeight: true, bodyFont: true, taskFontFamily: true, taskFontSize: true, taskFontWeight: true, eventFontFamily: true, eventFontSize: true, eventFontWeight: true, fontWeight: true, weekdayColor: true, dateColor: true, taskColor: true, todayHighlightColor: true, weekendColorSat: true, weekendColorSun: true, pastDayColor: true, hourLabelFormat: true, showSubHourSlots: true, allDayPosition: true, cwFontFamily: true, cwFontSize: true, cwFontWeight: true, cwColor: true, yearFontFamily: true, yearFontSize: true, yearFontWeight: true, yearColor: true, createdAt: true } }); if (!user) { return NextResponse.json({ error: 'User not found' }, { status: 404 }); } return NextResponse.json({ user }); } // Update user profile export async function PATCH(request: NextRequest) { const session = await getServerSession(authOptions); if (!session || !session.user?.email) { return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); } try { const body = await request.json(); const { name, timezone, password, autoRolling, protectEventTimes, language, dateFormat, timeFormat, startHour, endHour, showNextTask, calendarEditMode, focusTimerDuration, focusBreakDuration, showTimeGrid, showSomeday, showAllDayEvents, showSchedule, cellDuration, viewStyle, viewDays, fontSize, headlineFont, headlineFontSize, headlineFontWeight, dateFontFamily, dateFontSize, dateFontWeight, timeTaskFontFamily, timeTaskFontSize, timeTaskFontWeight, bodyFont, taskFontFamily, taskFontSize, taskFontWeight, eventFontFamily, eventFontSize, eventFontWeight, fontWeight, weekendColorSat, weekendColorSun, weekdayColor, dateColor, taskColor, todayHighlightColor, pastDayColor, goalFallbackType, goalDefaultSentence, goalFontFamily, goalFontSize, goalFontWeight, goalScope, dateLayout, hourLabelFormat, showSubHourSlots, allDayPosition, cwFontFamily, cwFontSize, cwFontWeight, cwColor, yearFontFamily, yearFontSize, yearFontWeight, yearColor } = body; const updateData: any = { ...(name !== undefined && { name }), ...(timezone !== undefined && { timezone }), ...(autoRolling !== undefined && { autoRolling }), ...(protectEventTimes !== undefined && { protectEventTimes }), ...(language !== undefined && { language }), ...(dateFormat !== undefined && { dateFormat }), ...(timeFormat !== undefined && { timeFormat }), ...(startHour !== undefined && !isNaN(startHour) && { startHour }), ...(endHour !== undefined && !isNaN(endHour) && { endHour }), ...(showNextTask !== undefined && { showNextTask }), ...(calendarEditMode !== undefined && { calendarEditMode }), ...(focusTimerDuration !== undefined && !isNaN(focusTimerDuration) && { focusTimerDuration }), ...(focusBreakDuration !== undefined && !isNaN(focusBreakDuration) && { focusBreakDuration }), ...(showTimeGrid !== undefined && { showTimeGrid }), ...(showSomeday !== undefined && { showSomeday }), ...(showAllDayEvents !== undefined && { showAllDayEvents }), ...(showSchedule !== undefined && { showSchedule }), ...(cellDuration !== undefined && !isNaN(cellDuration) && { cellDuration }), ...(viewStyle !== undefined && { viewStyle }), ...(viewDays !== undefined && !isNaN(viewDays) && { viewDays }), ...(fontSize !== undefined && { fontSize }), ...(headlineFont !== undefined && { headlineFont }), ...(headlineFontSize !== undefined && { headlineFontSize }), ...(headlineFontWeight !== undefined && { headlineFontWeight }), ...(dateFontFamily !== undefined && { dateFontFamily }), ...(dateFontSize !== undefined && { dateFontSize }), ...(dateFontWeight !== undefined && { dateFontWeight }), ...(timeTaskFontFamily !== undefined && { timeTaskFontFamily }), ...(timeTaskFontSize !== undefined && { timeTaskFontSize }), ...(timeTaskFontWeight !== undefined && { timeTaskFontWeight }), ...(bodyFont !== undefined && { bodyFont }), ...(taskFontFamily !== undefined && { taskFontFamily }), ...(taskFontSize !== undefined && { taskFontSize }), ...(taskFontWeight !== undefined && { taskFontWeight }), ...(eventFontFamily !== undefined && { eventFontFamily }), ...(eventFontSize !== undefined && { eventFontSize }), ...(eventFontWeight !== undefined && { eventFontWeight }), ...(fontWeight !== undefined && { fontWeight }), ...(weekdayColor !== undefined && { weekdayColor }), ...(dateColor !== undefined && { dateColor }), ...(taskColor !== undefined && { taskColor }), ...(todayHighlightColor !== undefined && { todayHighlightColor }), ...(weekendColorSat !== undefined && { weekendColorSat }), ...(weekendColorSun !== undefined && { weekendColorSun }), ...(pastDayColor !== undefined && { pastDayColor }), ...(goalFallbackType !== undefined && { goalFallbackType }), ...(goalDefaultSentence !== undefined && { goalDefaultSentence }), ...(goalFontFamily !== undefined && { goalFontFamily }), ...(goalFontSize !== undefined && { goalFontSize }), ...(goalFontWeight !== undefined && { goalFontWeight }), ...(goalScope !== undefined && { goalScope }), ...(dateLayout !== undefined && { dateLayout }), ...(hourLabelFormat !== undefined && { hourLabelFormat }), ...(showSubHourSlots !== undefined && { showSubHourSlots }), ...(allDayPosition !== undefined && { allDayPosition }), ...(cwFontFamily !== undefined && { cwFontFamily }), ...(cwFontSize !== undefined && { cwFontSize }), ...(cwFontWeight !== undefined && { cwFontWeight }), ...(cwColor !== undefined && { cwColor }), ...(yearFontFamily !== undefined && { yearFontFamily }), ...(yearFontSize !== undefined && { yearFontSize }), ...(yearFontWeight !== undefined && { yearFontWeight }), ...(yearColor !== undefined && { yearColor }), }; if (password && password.trim() !== "") { updateData.passwordHash = await bcrypt.hash(password, 10); } const user = await prisma.user.update({ where: { email: session.user.email }, data: updateData, select: { id: true, name: true, email: true, timezone: true, autoRolling: true, protectEventTimes: true, language: true, dateFormat: true, timeFormat: true, startHour: true, endHour: true, showNextTask: true, calendarEditMode: true, focusTimerDuration: true, focusBreakDuration: true, showTimeGrid: true, showSomeday: true, showAllDayEvents: true, showSchedule: true, cellDuration: true, viewStyle: true, viewDays: true, fontSize: true, headlineFont: true, headlineFontSize: true, headlineFontWeight: true, dateFontFamily: true, dateFontSize: true, dateFontWeight: true, timeTaskFontFamily: true, timeTaskFontSize: true, timeTaskFontWeight: true, bodyFont: true, taskFontFamily: true, taskFontSize: true, taskFontWeight: true, eventFontFamily: true, eventFontSize: true, eventFontWeight: true, fontWeight: true, weekdayColor: true, dateColor: true, taskColor: true, todayHighlightColor: true, weekendColorSat: true, weekendColorSun: true, pastDayColor: true, hourLabelFormat: true, showSubHourSlots: true, allDayPosition: true, goalFallbackType: true, goalDefaultSentence: true, goalFontFamily: true, goalFontSize: true, goalFontWeight: true, goalScope: true, dateLayout: true, cwFontFamily: true, cwFontSize: true, cwFontWeight: true, cwColor: true, yearFontFamily: true, yearFontSize: true, yearFontWeight: true, yearColor: true, } }); return NextResponse.json({ success: true, user }); } catch (e) { console.error('Error updating profile:', e); return NextResponse.json( { error: 'Failed to update profile', details: (e as Error).message }, { status: 500 } ); } } // Delete account export async function DELETE(request: NextRequest) { const session = await getServerSession(authOptions); if (!session?.user?.email) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 }); try { await prisma.user.delete({ where: { email: session.user.email } }); return NextResponse.json({ success: true }); } catch (error) { console.error('Error deleting account:', error); return NextResponse.json({ error: 'Failed to delete account' }, { status: 500 }); } }