Fix profile name update persistence

Replace placeholder implementation with proper API integration:
- Create /api/user/profile PUT endpoint with JWT validation
- Update profile page to call actual API instead of setTimeout
- Use refreshUser() to update UI immediately after changes
- Ensure name changes persist to database and across page refreshes

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
andupetcu
2025-09-21 01:13:32 +03:00
parent 196ca00194
commit e4acac270e
2 changed files with 108 additions and 5 deletions

View File

@@ -28,7 +28,7 @@ import {
} from '@mui/icons-material'
export default function ProfilePage() {
const { user } = useAuth()
const { user, refreshUser } = useAuth()
const t = useTranslations('profile')
const [isEditing, setIsEditing] = useState(false)
const [name, setName] = useState(user?.name || '')
@@ -40,10 +40,31 @@ export default function ProfilePage() {
setMessage('')
try {
// TODO: Implement profile update API
await new Promise(resolve => setTimeout(resolve, 1000)) // Placeholder
setMessage(t('profileUpdated'))
setIsEditing(false)
const token = localStorage.getItem('authToken')
if (!token) {
setMessage(t('updateError'))
return
}
const response = await fetch(`/api/user/profile?locale=${navigator.language.split('-')[0]}`, {
method: 'PUT',
headers: {
'Content-Type': 'application/json',
'Authorization': `Bearer ${token}`
},
body: JSON.stringify({ name })
})
const data = await response.json()
if (response.ok) {
setMessage(t('profileUpdated'))
setIsEditing(false)
// Refresh user data in context to show updated name
await refreshUser()
} else {
setMessage(data.error || t('updateError'))
}
} catch (error) {
setMessage(t('updateError'))
} finally {

View File

@@ -0,0 +1,82 @@
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',
nameRequired: 'Numele este obligatoriu',
updateFailed: 'Actualizarea a eșuat',
success: 'Profil actualizat cu succes'
},
en: {
unauthorized: 'Unauthorized',
nameRequired: 'Name is required',
updateFailed: 'Update failed',
success: 'Profile updated successfully'
}
}
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 { name } = await request.json()
// Validate input
if (!name || typeof name !== 'string' || name.trim().length === 0) {
return NextResponse.json({ error: messages.nameRequired }, { status: 400 })
}
// Update user profile using raw query
await prisma.$executeRaw`
UPDATE "User"
SET name = ${name.trim()}, "updatedAt" = CURRENT_TIMESTAMP
WHERE id = ${user.id}
`
// Get updated user data
const updatedUsers = await prisma.$queryRaw`
SELECT id, email, name, role, theme, "fontSize", "createdAt", "updatedAt", "lastLoginAt"
FROM "User"
WHERE id = ${user.id}
`
const updatedUser = Array.isArray(updatedUsers) && updatedUsers.length > 0 ? updatedUsers[0] : null
return NextResponse.json({
message: messages.success,
user: updatedUser
})
} catch (error) {
console.error('Profile 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 })
}
}