'use server' import { revalidatePath } from 'next/cache' import prisma from '@/lib/prisma' import { auth } from '@/auth' import bcrypt from 'bcryptjs' import { z } from 'zod' const ProfileSchema = z.object({ name: z.string().min(2, "Name must be at least 2 characters"), email: z.string().email().optional(), // Email change might require verification logic, keeping it simple for now or read-only }) const PasswordSchema = z.object({ currentPassword: z.string().min(1, "Current password is required"), newPassword: z.string().min(6, "New password must be at least 6 characters"), confirmPassword: z.string().min(6, "Confirm password must be at least 6 characters"), }).refine((data) => data.newPassword === data.confirmPassword, { message: "Passwords don't match", path: ["confirmPassword"], }) export async function updateProfile(data: { name: string }) { const session = await auth() if (!session?.user?.id) throw new Error('Unauthorized') const validated = ProfileSchema.safeParse(data) if (!validated.success) { return { error: validated.error.flatten().fieldErrors } } try { await prisma.user.update({ where: { id: session.user.id }, data: { name: validated.data.name }, }) revalidatePath('/settings/profile') return { success: true } } catch (error) { return { error: { _form: ['Failed to update profile'] } } } } export async function changePassword(formData: FormData) { const session = await auth() if (!session?.user?.id) throw new Error('Unauthorized') const rawData = { currentPassword: formData.get('currentPassword'), newPassword: formData.get('newPassword'), confirmPassword: formData.get('confirmPassword'), } const validated = PasswordSchema.safeParse(rawData) if (!validated.success) { return { error: validated.error.flatten().fieldErrors } } const { currentPassword, newPassword } = validated.data const user = await prisma.user.findUnique({ where: { id: session.user.id }, }) if (!user || !user.password) { return { error: { _form: ['User not found'] } } } const passwordsMatch = await bcrypt.compare(currentPassword, user.password) if (!passwordsMatch) { return { error: { currentPassword: ['Incorrect current password'] } } } const hashedPassword = await bcrypt.hash(newPassword, 10) try { await prisma.user.update({ where: { id: session.user.id }, data: { password: hashedPassword }, }) return { success: true } } catch (error) { return { error: { _form: ['Failed to change password'] } } } } export async function updateTheme(theme: string) { const session = await auth() if (!session?.user?.id) return { error: 'Unauthorized' } try { await prisma.user.update({ where: { id: session.user.id }, data: { theme }, }) return { success: true } } catch (error) { return { error: 'Failed to update theme' } } } export async function updateLanguage(language: string) { const session = await auth() if (!session?.user?.id) return { error: 'Unauthorized' } try { // Update or create UserAISettings with the preferred language await prisma.userAISettings.upsert({ where: { userId: session.user.id }, create: { userId: session.user.id, preferredLanguage: language, }, update: { preferredLanguage: language, }, }) // Note: The language will be applied on next page load // The client component should handle updating localStorage and reloading revalidatePath('/settings/profile') return { success: true, language } } catch (error) { console.error('Failed to update language:', error) return { error: 'Failed to update language' } } } export async function updateFontSize(fontSize: string) { const session = await auth() if (!session?.user?.id) return { error: 'Unauthorized' } try { // Check if UserAISettings exists const existing = await prisma.userAISettings.findUnique({ where: { userId: session.user.id } }) let result if (existing) { // Update existing - only update fontSize field result = await prisma.userAISettings.update({ where: { userId: session.user.id }, data: { fontSize: fontSize } }) } else { // Create new with all required fields result = await prisma.userAISettings.create({ data: { userId: session.user.id, fontSize: fontSize, // Set default values for required fields titleSuggestions: true, semanticSearch: true, paragraphRefactor: true, memoryEcho: true, memoryEchoFrequency: 'daily', aiProvider: 'auto', preferredLanguage: 'auto' } }) } revalidatePath('/settings/profile') return { success: true, fontSize } } catch (error) { console.error('[updateFontSize] Failed to update font size:', error) return { error: 'Failed to update font size' } } }