aethex.live/app/api/donations/route.ts

152 lines
3.7 KiB
TypeScript

import { createClient } from '@/lib/supabase/server'
import { PrismaClient } from '@prisma/client'
import { NextRequest, NextResponse } from 'next/server'
const prisma = new PrismaClient()
// POST /api/donations - Create a donation
export async function POST(req: NextRequest) {
const supabase = await createClient()
const { data: { user: supabaseUser }, error: authError } = await supabase.auth.getUser()
if (authError || !supabaseUser) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
try {
const body = await req.json()
const { channelId, amountCents, message, streamId } = body
if (!channelId || !amountCents) {
return NextResponse.json(
{ error: 'Channel ID and amount are required' },
{ status: 400 }
)
}
if (amountCents < 100) {
return NextResponse.json(
{ error: 'Minimum donation is $1.00' },
{ status: 400 }
)
}
const user = await prisma.user.findUnique({
where: { supabaseId: supabaseUser.id },
})
if (!user) {
return NextResponse.json({ error: 'User not found' }, { status: 404 })
}
// TODO: Integrate with Stripe for payment processing
// For now, just create the donation record
const donation = await prisma.donation.create({
data: {
donorId: user.id,
channelId,
amountCents,
message,
streamId,
},
include: {
donor: {
select: {
displayName: true,
avatarUrl: true,
},
},
},
})
return NextResponse.json(
{ message: 'Donation received', donation },
{ status: 201 }
)
} catch (error) {
console.error('Error processing donation:', error)
return NextResponse.json(
{ error: 'Failed to process donation' },
{ status: 500 }
)
}
}
// GET /api/donations - Get a channel's donations (for creator dashboard)
export async function GET(req: NextRequest) {
const supabase = await createClient()
const { data: { user: supabaseUser }, error: authError } = await supabase.auth.getUser()
if (authError || !supabaseUser) {
return NextResponse.json({ error: 'Unauthorized' }, { status: 401 })
}
try {
const channelId = req.nextUrl.searchParams.get('channelId')
if (!channelId) {
return NextResponse.json(
{ error: 'Channel ID is required' },
{ status: 400 }
)
}
const user = await prisma.user.findUnique({
where: { supabaseId: supabaseUser.id },
})
if (!user) {
return NextResponse.json({ error: 'User not found' }, { status: 404 })
}
// Verify user owns this channel
const channel = await prisma.channel.findFirst({
where: {
id: channelId,
userId: user.id,
},
})
if (!channel) {
return NextResponse.json(
{ error: 'Channel not found or unauthorized' },
{ status: 403 }
)
}
const donations = await prisma.donation.findMany({
where: {
channelId,
status: 'completed',
},
select: {
id: true,
amountCents: true,
message: true,
createdAt: true,
donor: {
select: {
displayName: true,
avatarUrl: true,
},
},
},
orderBy: { createdAt: 'desc' },
take: 50,
})
const total = donations.reduce((sum, d) => sum + d.amountCents, 0)
return NextResponse.json(
{ donations, totalCents: total },
{ status: 200 }
)
} catch (error) {
console.error('Error fetching donations:', error)
return NextResponse.json(
{ error: 'Failed to fetch donations' },
{ status: 500 }
)
}
}