'use client'; import React, { useState } from 'react'; import Link from 'next/link'; import Header from '@/components/Header'; import Footer from '@/components/Footer'; interface SeedThread { category_slug: string; title: string; body: string; author_name: string; replies: Array<{ author_name: string; body: string }>; } const SEED_TEMPLATES: SeedThread[] = [ { category_slug: 'live-production', title: 'Comparing production switchers for large-scale live events', author_name: 'ProductionEngineer_A', body: 'We are evaluating production switchers for a major live event series. Looking at Ross, Grass Valley, and Sony options. What are the key differentiators teams are finding in 2025? Particularly interested in IP integration and graphics playout capabilities.', replies: [ { author_name: 'LiveProdVet', body: 'Ross has the best ecosystem integration if you are already in their world. The XPression graphics integration is seamless.' }, { author_name: 'SwitcherPro', body: 'Grass Valley Korona is worth a serious look for large-scale. The multiviewer flexibility alone is worth the evaluation time.' }, ], }, { category_slug: 'ip-cloud', title: 'PTP grandmaster redundancy strategies for ST 2110 facilities', author_name: 'NetworkBroadcast_T', body: 'We are designing our PTP infrastructure for a new ST 2110 facility. Looking for advice on grandmaster redundancy — specifically whether to use BMCA automatic failover or manual switchover with monitoring. What are people deploying in production environments?', replies: [ { author_name: 'TimingExpert', body: 'BMCA failover works but the transition can cause brief sync issues. We use manual switchover with automated alerting for our tier-1 facilities.' }, ], }, { category_slug: 'streaming', title: 'Low-latency streaming for live sports — architecture deep dive', author_name: 'StreamArchitect_B', body: 'Building a low-latency streaming architecture for a sports rights holder. Target is under 3 seconds glass-to-glass. Currently evaluating LL-HLS vs DASH-LL vs WebRTC for the last mile. What are the real-world trade-offs at scale?', replies: [ { author_name: 'CDNExpert', body: 'LL-HLS is the most practical for scale right now. WebRTC gets you lower latency but the infrastructure complexity at 100k+ concurrent viewers is significant.' }, { author_name: 'StreamingEng', body: 'We run LL-HLS with a 2-second target and achieve it consistently. The key is segment duration — we use 500ms segments with 3-segment playlist.' }, ], }, { category_slug: 'audio', title: 'Immersive audio for broadcast — Dolby Atmos workflow questions', author_name: 'AudioMixer_C', body: 'We are adding Dolby Atmos delivery to our broadcast workflow. Looking for advice on monitoring setups, DAW integration, and the loudness compliance implications of object-based audio. Anyone running Atmos in a live broadcast environment?', replies: [ { author_name: 'AtmosEngineer', body: 'Live Atmos is challenging but doable. We use the Dolby Atmos Production Suite with a 7.1.4 monitoring setup. The loudness compliance is handled by the Dolby encoder — it normalizes the bed and objects separately.' }, ], }, { category_slug: 'ai-automation', title: 'AI-powered sports highlights generation — production workflow', author_name: 'SportsTechPro', body: 'We are evaluating AI highlight generation tools for a sports network. The promise is automated clip selection and packaging within minutes of live events ending. Has anyone deployed Grabyo, WSC Sports, or similar platforms in production? What is the editorial quality like?', replies: [ { author_name: 'DigitalSports_M', body: 'WSC Sports is genuinely impressive for structured sports like basketball and soccer. The AI understands game events well. For less structured sports the results are more variable.' }, { author_name: 'SportsTechPro', body: 'Good to know. We cover a mix of sports. Did you find the customization options adequate for brand compliance?' }, ], }, ]; export default function AdminForumSeedPage() { const [seedData, setSeedData] = useState(JSON.stringify(SEED_TEMPLATES, null, 2)); const [importing, setImporting] = useState(false); const [results, setResults] = useState>([]); const [activeTab, setActiveTab] = useState<'import' | 'json'>('import'); const handleImport = async () => { setImporting(true); setResults([]); let threads: SeedThread[] = []; try { threads = JSON.parse(seedData); } catch { setResults([{ title: 'Parse Error', status: 'error', message: 'Invalid JSON. Please check your seed data.' }]); setImporting(false); return; } // Fetch categories first const catRes = await fetch('/api/forum/categories'); const catData = await catRes.json(); const categories: Record = {}; (catData.categories || []).forEach((c: any) => { categories[c.slug] = c.id; }); const newResults: typeof results = []; for (const thread of threads) { const categoryId = categories[thread.category_slug]; if (!categoryId) { newResults.push({ title: thread.title, status: 'error', message: `Category "${thread.category_slug}" not found` }); continue; } try { // Create thread const threadRes = await fetch('/api/forum/threads', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ category_id: categoryId, title: thread.title, body: thread.body, author_name: thread.author_name, }), }); const threadData = await threadRes.json(); if (!threadData.thread) throw new Error(threadData.error || 'Failed to create thread'); // Create replies for (const reply of thread.replies || []) { await fetch('/api/forum/replies', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify({ thread_id: threadData.thread.id, body: reply.body, author_name: reply.author_name, }), }); } newResults.push({ title: thread.title, status: 'success', message: `Created with ${thread.replies?.length || 0} replies` }); } catch (err: any) { newResults.push({ title: thread.title, status: 'error', message: err.message }); } } setResults(newResults); setImporting(false); }; const successCount = results.filter(r => r.status === 'success').length; const errorCount = results.filter(r => r.status === 'error').length; return ( <>

Forum Seed Tool

Import editorial starter threads in bulk. Edit the JSON below or paste your own seed data.

{/* Left: Editor */}
{activeTab === 'import' && (

Edit the JSON array below. Each object creates one thread with replies. Category slugs must match existing forum categories.