forum: rebrand to The Crew Lounge + scaffold Credits system
UI (targeted edits, no identifier renames): - forum/layout.tsx: metadata title/OG/twitter/schema.org + breadcrumb name → The Crew Lounge - forum/page.tsx: H1 + intro copy → The Crew Lounge (swapped 💬 for /logos/crew-lounge-logo.svg) New assets: - public/logos/crew-lounge-logo.svg — film-reel + CREW logo, #5B7C8D → #8FB0C3 gradient - src/components/crew-lounge/CreditsDisplay.tsx — per-category totals + Crew Leader badge - src/components/crew-lounge/CrewLoungeLogo.tsx — wrapper component Database (4 new tables on supabase01, all TIMESTAMPTZ, IF NOT EXISTS guards): - bb.user_credits — per-user/per-category daily credit ledger - bb.user_credits_totals — cached leaderboard totals - bb.crew_leader_badges — awarded at 10+ credits/category - bb.credits_monthly_snapshot — monthly leaderboard captures Docs: - docs/guides/FORUM_SETUP_COMPLETE.md — replication guide - docs/guides/FORUM_SETUP_CHECKLIST.md — per-property checklist Forum tables (bb.forum_*) and TypeScript identifiers untouched. Routes (/forum) unchanged — display-name rebrand only. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
32
docs/guides/FORUM_SETUP_CHECKLIST.md
Normal file
32
docs/guides/FORUM_SETUP_CHECKLIST.md
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
# Forum Setup Checklist (By Property)
|
||||||
|
|
||||||
|
Use this for each new property setup.
|
||||||
|
|
||||||
|
## [ ] Property: ________________
|
||||||
|
|
||||||
|
### Parameters
|
||||||
|
- [ ] Property name: _______________
|
||||||
|
- [ ] Forum URL: /forum
|
||||||
|
- [ ] Display name: "The ______ Lounge"
|
||||||
|
- [ ] Categories: ___ (count)
|
||||||
|
- [ ] Initial personas: ___ (recommend 150-200)
|
||||||
|
- [ ] Target posts/day: ___ (recommend 250-400)
|
||||||
|
|
||||||
|
### Setup Steps
|
||||||
|
- [ ] Phase 1: Create logo (SVG)
|
||||||
|
- [ ] Phase 2: Create credits schema (SQL)
|
||||||
|
- [ ] Phase 3: Add React components
|
||||||
|
- [ ] Phase 4: Update page titles
|
||||||
|
- [ ] Phase 5: Insert categories
|
||||||
|
- [ ] Phase 6: Generate personas
|
||||||
|
- [ ] Phase 7: Generate posts
|
||||||
|
- [ ] Phase 8: Award credits
|
||||||
|
- [ ] Phase 9: Set up cron
|
||||||
|
- [ ] Phase 10: Add to monitoring
|
||||||
|
|
||||||
|
### Verification
|
||||||
|
- [ ] `SELECT COUNT(*) FROM bb.forum_categories;`
|
||||||
|
- [ ] `SELECT COUNT(*) FROM bb.user_profiles;`
|
||||||
|
- [ ] `SELECT COUNT(*) FROM bb.forum_threads;`
|
||||||
|
- [ ] First post generated at: _______
|
||||||
|
- [ ] Posts generating every 30 min: YES / NO
|
||||||
53
docs/guides/FORUM_SETUP_COMPLETE.md
Normal file
53
docs/guides/FORUM_SETUP_COMPLETE.md
Normal file
@@ -0,0 +1,53 @@
|
|||||||
|
# Community Forum Setup Guide (From Scratch)
|
||||||
|
|
||||||
|
**Complete replicable guide for deploying forums with credits system across RMP properties.**
|
||||||
|
|
||||||
|
> Updated: May 16, 2026
|
||||||
|
> Template: The Crew Lounge (BroadcastBeat)
|
||||||
|
> Replicable to: AV Beat, BroadcastEngineering, SportsMediaIntel, etc.
|
||||||
|
|
||||||
|
## Quick Summary
|
||||||
|
|
||||||
|
- **Database**: 4 new tables for credits system (bb.user_credits, totals, badges, monthly)
|
||||||
|
- **UI**: CreditsDisplay component + CrewLoungeLogo
|
||||||
|
- **Schema**: Forum categories, user profiles, threads, credits tracking
|
||||||
|
- **Generation**: 200 personas, 1,500+ posts via Ollama, continuous generation
|
||||||
|
- **Timeline**: ~2 hours per property
|
||||||
|
|
||||||
|
## Database Schema
|
||||||
|
|
||||||
|
```sql
|
||||||
|
bb.user_credits -- Track earned credits per user/category
|
||||||
|
bb.user_credits_totals -- Cache totals for leaderboards
|
||||||
|
bb.crew_leader_badges -- 10+ credits = category expert
|
||||||
|
bb.credits_monthly_snapshot -- Monthly leaderboard snapshots
|
||||||
|
```
|
||||||
|
|
||||||
|
## Setup Phases
|
||||||
|
|
||||||
|
1. **Logo** — Create property-specific SVG
|
||||||
|
2. **Schema** — New credits tables in Supabase
|
||||||
|
3. **Components** — CreditsDisplay, CrewLoungeLogo React components
|
||||||
|
4. **Forum Pages** — Update title text (keep code structure)
|
||||||
|
5. **Categories** — Insert your 35-50 domain-specific categories
|
||||||
|
6. **Personas** — Generate 150-200 realistic user profiles
|
||||||
|
7. **Posts** — Generate 1,000-1,500 seed posts via Ollama
|
||||||
|
8. **Credits** — Award 1 credit per post, calculate badges
|
||||||
|
9. **Cron** — Set up continuous generation (every 30 min)
|
||||||
|
10. **Monitoring** — Add to control panel watchdog
|
||||||
|
|
||||||
|
## For Other Properties
|
||||||
|
|
||||||
|
Copy this guide and customize:
|
||||||
|
|
||||||
|
- **Category list** - Use domain-specific categories
|
||||||
|
- **Logo colors** - Match property branding
|
||||||
|
- **Persona archetypes** - Specialize for your community
|
||||||
|
- **Post generation prompt** - Domain vocabulary
|
||||||
|
- **Target velocity** - Adjust posts/day based on community size
|
||||||
|
|
||||||
|
## Files in This Directory
|
||||||
|
|
||||||
|
- `FORUM_SETUP_COMPLETE.md` — Full guide
|
||||||
|
- `FORUM_SETUP_CHECKLIST.md` — Per-property checklist
|
||||||
|
- Scripts for category/persona generation available
|
||||||
26
public/logos/crew-lounge-logo.svg
Normal file
26
public/logos/crew-lounge-logo.svg
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
<svg viewBox="0 0 200 200" xmlns="http://www.w3.org/2000/svg">
|
||||||
|
<circle cx="100" cy="100" r="98" fill="#0d0d0d" stroke="#5B7C8D" stroke-width="2"/>
|
||||||
|
<defs>
|
||||||
|
<linearGradient id="crewGradient" x1="0%" y1="0%" x2="100%" y2="100%">
|
||||||
|
<stop offset="0%" style="stop-color:#5B7C8D;stop-opacity:1" />
|
||||||
|
<stop offset="100%" style="stop-color:#8FB0C3;stop-opacity:1" />
|
||||||
|
</linearGradient>
|
||||||
|
</defs>
|
||||||
|
<circle cx="100" cy="100" r="75" fill="none" stroke="url(#crewGradient)" stroke-width="3"/>
|
||||||
|
<circle cx="100" cy="100" r="50" fill="none" stroke="url(#crewGradient)" stroke-width="2"/>
|
||||||
|
<g stroke="url(#crewGradient)" stroke-width="2.5">
|
||||||
|
<line x1="100" y1="30" x2="100" y2="50" />
|
||||||
|
<line x1="151.96" y1="50" x2="137.1" y2="62.5" />
|
||||||
|
<line x1="151.96" y1="150" x2="137.1" y2="137.5" />
|
||||||
|
<line x1="100" y1="170" x2="100" y2="150" />
|
||||||
|
<line x1="48.04" y1="150" x2="62.9" y2="137.5" />
|
||||||
|
<line x1="48.04" y1="50" x2="62.9" y2="62.5" />
|
||||||
|
</g>
|
||||||
|
<circle cx="100" cy="100" r="6" fill="url(#crewGradient)"/>
|
||||||
|
<text x="100" y="115" font-family="Arial, sans-serif" font-size="20" font-weight="bold" fill="#8FB0C3" text-anchor="middle" letter-spacing="2">CREW</text>
|
||||||
|
<line x1="75" y1="125" x2="125" y2="125" stroke="url(#crewGradient)" stroke-width="1.5"/>
|
||||||
|
<rect x="25" y="25" width="3" height="8" fill="#5B7C8D"/>
|
||||||
|
<rect x="172" y="25" width="3" height="8" fill="#5B7C8D"/>
|
||||||
|
<rect x="25" y="167" width="3" height="8" fill="#5B7C8D"/>
|
||||||
|
<rect x="172" y="167" width="3" height="8" fill="#5B7C8D"/>
|
||||||
|
</svg>
|
||||||
|
After Width: | Height: | Size: 1.5 KiB |
@@ -1,19 +1,19 @@
|
|||||||
import type { Metadata } from 'next';
|
import type { Metadata } from 'next';
|
||||||
|
|
||||||
export const metadata: Metadata = {
|
export const metadata: Metadata = {
|
||||||
title: 'Industry Forum — Broadcast Beat',
|
title: 'The Crew Lounge — Broadcast Beat',
|
||||||
description: 'Connect with broadcast, motion picture and post production professionals worldwide. Discuss live production, IP workflows, streaming, audio, cameras, AI automation, and more.',
|
description: 'The Crew Lounge: connect with broadcast, motion picture and post production professionals worldwide. Discuss live production, IP workflows, streaming, audio, cameras, AI automation, and more.',
|
||||||
alternates: { canonical: '/forum' },
|
alternates: { canonical: '/forum' },
|
||||||
openGraph: {
|
openGraph: {
|
||||||
title: 'Industry Forum — Broadcast Beat',
|
title: 'The Crew Lounge — Broadcast Beat',
|
||||||
description: 'Connect with broadcast, motion picture and post production professionals worldwide. Ask questions, share expertise, and discuss broadcast technology.',
|
description: 'The Crew Lounge: connect with broadcast, motion picture and post production professionals worldwide. Ask questions, share expertise, and discuss broadcast technology.',
|
||||||
url: '/forum',
|
url: '/forum',
|
||||||
type: 'website',
|
type: 'website',
|
||||||
},
|
},
|
||||||
twitter: {
|
twitter: {
|
||||||
card: 'summary',
|
card: 'summary',
|
||||||
title: 'Industry Forum — Broadcast Beat',
|
title: 'The Crew Lounge — Broadcast Beat',
|
||||||
description: 'Connect with broadcast, motion picture and post production professionals worldwide on Broadcast Beat.',
|
description: 'The Crew Lounge: connect with broadcast, motion picture and post production professionals worldwide on Broadcast Beat.',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -21,8 +21,8 @@ export default function ForumLayout({ children }: { children: React.ReactNode })
|
|||||||
const schema = {
|
const schema = {
|
||||||
'@context': 'https://schema.org',
|
'@context': 'https://schema.org',
|
||||||
'@type': 'WebPage',
|
'@type': 'WebPage',
|
||||||
name: 'Broadcast Beat Industry Forum',
|
name: 'Broadcast Beat — The Crew Lounge',
|
||||||
description: 'Industry forum for broadcast, motion picture and post production professionals worldwide.',
|
description: 'The Crew Lounge: an industry community for broadcast, motion picture and post production professionals worldwide.',
|
||||||
url: 'https://broadcastb5322.builtwithrocket.new/forum',
|
url: 'https://broadcastb5322.builtwithrocket.new/forum',
|
||||||
isPartOf: {
|
isPartOf: {
|
||||||
'@type': 'WebSite',
|
'@type': 'WebSite',
|
||||||
@@ -33,7 +33,7 @@ export default function ForumLayout({ children }: { children: React.ReactNode })
|
|||||||
'@type': 'BreadcrumbList',
|
'@type': 'BreadcrumbList',
|
||||||
itemListElement: [
|
itemListElement: [
|
||||||
{ '@type': 'ListItem', position: 1, name: 'Home', item: 'https://broadcastb5322.builtwithrocket.new' },
|
{ '@type': 'ListItem', position: 1, name: 'Home', item: 'https://broadcastb5322.builtwithrocket.new' },
|
||||||
{ '@type': 'ListItem', position: 2, name: 'Forum', item: 'https://broadcastb5322.builtwithrocket.new/forum' },
|
{ '@type': 'ListItem', position: 2, name: 'The Crew Lounge', item: 'https://broadcastb5322.builtwithrocket.new/forum' },
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -262,11 +262,11 @@ export default function ForumIndexPage() {
|
|||||||
<div className="bg-[#1a2535] border-b border-[#2a3a50]">
|
<div className="bg-[#1a2535] border-b border-[#2a3a50]">
|
||||||
<div className="max-w-container mx-auto px-4 py-10">
|
<div className="max-w-container mx-auto px-4 py-10">
|
||||||
<div className="flex items-center gap-3 mb-2">
|
<div className="flex items-center gap-3 mb-2">
|
||||||
<span className="text-2xl">💬</span>
|
<img src="/logos/crew-lounge-logo.svg" alt="The Crew Lounge" className="w-8 h-8" />
|
||||||
<h1 className="text-3xl font-heading font-bold text-white">Industry Forum</h1>
|
<h1 className="text-3xl font-heading font-bold text-white">The Crew Lounge</h1>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-[#aab4c4] font-body text-base max-w-2xl">
|
<p className="text-[#aab4c4] font-body text-base max-w-2xl">
|
||||||
Connect with broadcast, motion picture and post production professionals worldwide. Ask questions, share expertise, and discuss the technology shaping the industry.
|
The Crew Lounge: connect with broadcast, motion picture and post production professionals worldwide. Ask questions, share expertise, and discuss the technology shaping the industry.
|
||||||
</p>
|
</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
56
src/components/crew-lounge/CreditsDisplay.tsx
Normal file
56
src/components/crew-lounge/CreditsDisplay.tsx
Normal file
@@ -0,0 +1,56 @@
|
|||||||
|
'use client';
|
||||||
|
|
||||||
|
interface CreditsDisplayProps {
|
||||||
|
userName: string;
|
||||||
|
totalCredits: number;
|
||||||
|
categoryCredits: Record<string, number>;
|
||||||
|
isLeader: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
|
export default function CreditsDisplay({
|
||||||
|
userName,
|
||||||
|
totalCredits,
|
||||||
|
categoryCredits,
|
||||||
|
isLeader,
|
||||||
|
}: CreditsDisplayProps) {
|
||||||
|
return (
|
||||||
|
<div className="bg-[#111] border border-[#2a3f5f] rounded-lg p-6">
|
||||||
|
<div className="flex items-center justify-between mb-6">
|
||||||
|
<div>
|
||||||
|
<h2 className="text-2xl font-bold text-white">{userName}</h2>
|
||||||
|
{isLeader && (
|
||||||
|
<span className="inline-block mt-2 px-3 py-1 bg-gradient-to-r from-[#5B7C8D] to-[#8FB0C3] text-white rounded-full text-xs font-bold">
|
||||||
|
⭐ Crew Leader
|
||||||
|
</span>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<div className="text-right">
|
||||||
|
<p className="text-[#666] text-sm">Total Credits</p>
|
||||||
|
<p className="text-4xl font-bold text-[#5B7C8D]">{totalCredits}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
{Object.keys(categoryCredits).length > 0 && (
|
||||||
|
<div className="border-t border-[#2a3f5f] pt-6">
|
||||||
|
<p className="text-[#8FB0C3] font-bold mb-4">By Category</p>
|
||||||
|
<div className="grid grid-cols-2 gap-4">
|
||||||
|
{Object.entries(categoryCredits)
|
||||||
|
.sort(([, a], [, b]) => b - a)
|
||||||
|
.slice(0, 6)
|
||||||
|
.map(([category, credits]) => (
|
||||||
|
<div key={category} className="bg-[#0d0d0d] rounded p-3">
|
||||||
|
<p className="text-[#666] text-xs">{category}</p>
|
||||||
|
<p className="text-lg font-bold text-[#8FB0C3]">{credits}</p>
|
||||||
|
</div>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
|
||||||
|
<div className="mt-6 text-[#666] text-xs">
|
||||||
|
<p>💡 Earn 1 credit per post in each category</p>
|
||||||
|
<p>⭐ Earn "Crew Leader" badge at 10+ credits</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
}
|
||||||
10
src/components/crew-lounge/CrewLoungeLogo.tsx
Normal file
10
src/components/crew-lounge/CrewLoungeLogo.tsx
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
export default function CrewLoungeLogo({ size = 40 }: { size?: number }) {
|
||||||
|
return (
|
||||||
|
<img
|
||||||
|
src="/logos/crew-lounge-logo.svg"
|
||||||
|
alt="The Crew Lounge"
|
||||||
|
style={{ width: size, height: size }}
|
||||||
|
className="inline-block"
|
||||||
|
/>
|
||||||
|
);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user