initial commit: rocket.new export of broadcastbeat

This commit is contained in:
Ryan Salazar
2026-05-07 16:39:17 +00:00
commit 70aa1ad46e
302 changed files with 60710 additions and 0 deletions

View File

@@ -0,0 +1,153 @@
import { NextRequest, NextResponse } from 'next/server';
import { createClient } from '@/lib/supabase/server';
// GET: Fetch threads and replies for moderation
export async function GET(req: NextRequest) {
try {
const supabase = await createClient();
const { data: { user } } = await supabase.auth.getUser();
if (!user) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
const { searchParams } = new URL(req.url);
const tab = searchParams.get('tab') || 'threads';
const filter = searchParams.get('filter') || 'all';
const page = parseInt(searchParams.get('page') || '1');
const limit = 20;
const offset = (page - 1) * limit;
if (tab === 'replies') {
let query = supabase
.from('forum_replies')
.select('*, forum_threads(id, title)', { count: 'exact' })
.order('created_at', { ascending: false })
.range(offset, offset + limit - 1);
if (filter === 'flagged') query = query.eq('is_flagged', true);
if (filter === 'ai_flagged') query = query.eq('is_flagged', true).like('flag_reason', '[AI]%');
if (filter === 'hidden') query = query.eq('is_hidden', true);
const { data, error, count } = await query;
if (error) throw error;
return NextResponse.json({ replies: data, total: count, page, limit });
}
// threads tab
let query = supabase
.from('forum_threads')
.select('*, forum_categories(name, slug)', { count: 'exact' })
.order('created_at', { ascending: false })
.range(offset, offset + limit - 1);
if (filter === 'flagged') query = query.eq('is_flagged', true);
if (filter === 'ai_flagged') query = query.eq('is_flagged', true).like('flag_reason', '[AI]%');
if (filter === 'pinned') query = query.eq('is_pinned', true);
if (filter === 'featured') query = query.eq('is_featured', true);
if (filter === 'locked') query = query.eq('is_locked', true);
const { data, error, count } = await query;
if (error) throw error;
return NextResponse.json({ threads: data, total: count, page, limit });
} catch (err: any) {
return NextResponse.json({ error: err.message }, { status: 500 });
}
}
// PATCH: Apply moderation action
export async function PATCH(req: NextRequest) {
try {
const supabase = await createClient();
const { data: { user } } = await supabase.auth.getUser();
if (!user) return NextResponse.json({ error: 'Unauthorized' }, { status: 401 });
const body = await req.json();
const { type, id, action, flag_reason } = body;
if (!type || !id || !action) {
return NextResponse.json({ error: 'type, id, and action are required' }, { status: 400 });
}
const now = new Date().toISOString();
if (type === 'thread') {
let updateData: Record<string, any> = { moderated_by: user.id, moderated_at: now };
switch (action) {
case 'pin':
updateData.is_pinned = true;
break;
case 'unpin':
updateData.is_pinned = false;
break;
case 'feature':
updateData.is_featured = true;
break;
case 'unfeature':
updateData.is_featured = false;
break;
case 'lock':
updateData.is_locked = true;
break;
case 'unlock':
updateData.is_locked = false;
break;
case 'flag':
updateData.is_flagged = true;
updateData.flag_reason = flag_reason || null;
break;
case 'unflag':
updateData.is_flagged = false;
updateData.flag_reason = null;
break;
default:
return NextResponse.json({ error: 'Invalid action' }, { status: 400 });
}
const { data, error } = await supabase
.from('forum_threads')
.update(updateData)
.eq('id', id)
.select()
.single();
if (error) throw error;
return NextResponse.json({ thread: data });
}
if (type === 'reply') {
let updateData: Record<string, any> = { moderated_by: user.id, moderated_at: now };
switch (action) {
case 'hide':
updateData.is_hidden = true;
break;
case 'unhide':
updateData.is_hidden = false;
break;
case 'flag':
updateData.is_flagged = true;
updateData.flag_reason = flag_reason || null;
break;
case 'unflag':
updateData.is_flagged = false;
updateData.flag_reason = null;
break;
default:
return NextResponse.json({ error: 'Invalid action' }, { status: 400 });
}
const { data, error } = await supabase
.from('forum_replies')
.update(updateData)
.eq('id', id)
.select()
.single();
if (error) throw error;
return NextResponse.json({ reply: data });
}
return NextResponse.json({ error: 'Invalid type' }, { status: 400 });
} catch (err: any) {
return NextResponse.json({ error: err.message }, { status: 500 });
}
}