import { NextRequest, NextResponse } from 'next/server'
import { createClient } from '@supabase/supabase-js'
// Create server-side Supabase client with user session
function createServerSupabaseClient(request: Request) {
const authHeader = request.headers.get('authorization')
return createClient(
process.env.NEXT_PUBLIC_SUPABASE_URL!,
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
{
auth: {
autoRefreshToken: false,
persistSession: false
},
global: {
headers: authHeader ? {
Authorization: authHeader
} : {}
}
}
)
}
export async function POST(request: NextRequest) {
try {
const supabase = createServerSupabaseClient(request)
// Get current user session
const { data: { user }, error: authError } = await supabase.auth.getUser()
if (authError || !user) {
return NextResponse.json({ error: 'Authentication required' }, { status: 401 })
}
const formData = await request.formData()
const file = formData.get('file') as File
if (!file) {
return NextResponse.json({ error: 'No file provided' }, { status: 400 })
}
// Validate file type
if (!file.type.startsWith('image/')) {
return NextResponse.json({ error: 'File must be an image' }, { status: 400 })
}
// Validate file size (max 2MB for avatars)
if (file.size > 2 * 1024 * 1024) {
return NextResponse.json({ error: 'File size must be less than 2MB' }, { status: 400 })
}
// Generate unique filename
const fileExt = file.name.split('.').pop()
const fileName = `${user.id}/${Date.now()}-avatar.${fileExt}`
const filePath = `avatars/${fileName}`
// Convert file to buffer
const bytes = await file.arrayBuffer()
const buffer = Buffer.from(bytes)
// Delete old avatar if it exists
try {
const { data: oldFiles } = await supabase.storage
.from('avatars')
.list(user.id)
if (oldFiles && oldFiles.length > 0) {
const oldFilePaths = oldFiles.map(file => `${user.id}/${file.name}`)
await supabase.storage
.from('avatars')
.remove(oldFilePaths)
}
} catch (error) {
// Ignore errors when cleaning up old files
console.warn('Could not clean up old avatar files:', error)
}
// Upload to Supabase Storage
const { data, error } = await supabase.storage
.from('avatars')
.upload(filePath, buffer, {
contentType: file.type,
cacheControl: '3600',
upsert: false
})
if (error) {
console.error('Storage upload error:', error)
return NextResponse.json({ error: 'Failed to upload image' }, { status: 500 })
}
// Get public URL
const { data: { publicUrl } } = supabase.storage
.from('avatars')
.getPublicUrl(data.path)
// Update user profile with new avatar URL
const { error: updateError } = await supabase
.from('profiles')
.update({
avatar_url: publicUrl,
updated_at: new Date().toISOString()
})
.eq('id', user.id)
if (updateError) {
console.error('Profile update error:', updateError)
return NextResponse.json({ error: 'Failed to update profile' }, { status: 500 })
}
return NextResponse.json({
success: true,
imageUrl: publicUrl,
path: data.path
})
} catch (error) {
console.error('Upload API error:', error)
return NextResponse.json({ error: 'Internal server error' }, { status: 500 })
}
}