- public/assets/images/logo.png + public/brand/logo*.png replaced with the 1320x310 AV Beat logo
- public/assets/logos/avbeat.png added as the canonical source
- tailwind.config.js + src/styles/tailwind.css + src/styles/redesign-tokens.css palette swapped (primary #0F0E0E, secondary #1D1A1A, accent #E67E22 orange, foreground #F0EBE6 warm white)
- Layout / robots / sitemap / home-page / about / contact / press-kit / team / global-error metadata switched to AV Beat (Where AV Meets IT)
- Bulk replaced 'Broadcast Beat'/'BroadcastBeat.com'/'broadcastbeat.com' across user-facing news/forum/marketplace/advertise/search/newsletter pages
- src/lib/supabase/{admin,server,client} now default to schema 'avb' (was 'bb') — overridable via NEXT_PUBLIC_SUPABASE_SCHEMA
- package.json renamed to 'avbeat'
- Single d60701 reference in about/team swapped to E67E22
Design-only replica — no article content migrated.
113 lines
4.8 KiB
TypeScript
113 lines
4.8 KiB
TypeScript
'use client';
|
||
|
||
import { useState, useEffect } from 'react';
|
||
import Link from 'next/link';
|
||
import Header from '@/components/Header';
|
||
import Footer from '@/components/Footer';
|
||
import { createClient } from '@/lib/supabase/client';
|
||
|
||
export default function GigsPage() {
|
||
const supabase = createClient();
|
||
const [gigs, setGigs] = useState<any[]>([]);
|
||
const [loading, setLoading] = useState(true);
|
||
|
||
useEffect(() => {
|
||
const fetchGigs = async () => {
|
||
const { data } = await supabase
|
||
.from('marketplace_gigs')
|
||
.select('*, marketplace_profiles!inner(slug, subscription_tier)')
|
||
.eq('status', 'active')
|
||
.order('created_at', { ascending: false })
|
||
.limit(50);
|
||
setGigs(data || []);
|
||
setLoading(false);
|
||
};
|
||
fetchGigs();
|
||
}, []);
|
||
|
||
return (
|
||
<div className="min-h-screen bg-[#0d0d0d] text-white">
|
||
<Header />
|
||
<div className="max-w-5xl mx-auto px-4 py-24">
|
||
<div className="flex flex-col sm:flex-row sm:items-center justify-between gap-4 mb-8">
|
||
<div>
|
||
<div className="flex items-center gap-2 text-sm text-gray-500 mb-2">
|
||
<Link href="/marketplace" className="hover:text-[#CC0000]">Marketplace</Link>
|
||
<span>/</span>
|
||
<span className="text-white">Gigs</span>
|
||
</div>
|
||
<h1 className="text-3xl font-black uppercase tracking-wide">Gig Board</h1>
|
||
<p className="text-gray-400 mt-1">
|
||
{loading ? '...' : `${gigs.length} open gig${gigs.length !== 1 ? 's' : ''}`}
|
||
</p>
|
||
</div>
|
||
<Link
|
||
href="/marketplace/account"
|
||
className="bg-[#CC0000] hover:bg-red-700 text-white font-bold px-5 py-3 rounded-lg text-sm transition-colors whitespace-nowrap"
|
||
>
|
||
+ Post a Gig
|
||
</Link>
|
||
</div>
|
||
|
||
<div className="bg-[#1a1a1a] border border-yellow-500/30 rounded-lg p-4 text-sm text-yellow-400 mb-8">
|
||
💳 <strong>Gig posting requires a Pro subscription.</strong> Billing is coming soon —
|
||
create your free profile now and post gigs when payments launch.
|
||
</div>
|
||
|
||
{loading ? (
|
||
<div className="space-y-4">
|
||
{[...Array(4)].map((_, i) => (
|
||
<div key={i} className="bg-[#1a1a1a] rounded-xl p-6 animate-pulse h-28" />
|
||
))}
|
||
</div>
|
||
) : gigs.length === 0 ? (
|
||
<div className="text-center py-20 text-gray-500">
|
||
<div className="text-4xl mb-4">🎬</div>
|
||
<p className="text-lg font-semibold mb-2">No gigs posted yet</p>
|
||
<p className="text-sm">Be the first to post a crew call on AV Beat Marketplace.</p>
|
||
</div>
|
||
) : (
|
||
<div className="space-y-4">
|
||
{gigs.map((gig) => (
|
||
<Link
|
||
key={gig.id}
|
||
href={`/marketplace/gigs/${gig.id}`}
|
||
className="block bg-[#1a1a1a] hover:bg-[#222] border border-white/10 hover:border-[#CC0000]/30 rounded-xl p-6 transition-all"
|
||
>
|
||
<div className="flex flex-col sm:flex-row sm:items-start justify-between gap-4">
|
||
<div className="flex-1">
|
||
<div className="flex flex-wrap items-center gap-2 mb-1">
|
||
<h2 className="font-bold text-lg text-white">{gig.title}</h2>
|
||
{gig.marketplace_profiles?.subscription_tier === 'featured' && (
|
||
<span className="text-xs bg-yellow-500/20 text-yellow-400 border border-yellow-500/30 px-2 py-0.5 rounded-full font-bold">Featured</span>
|
||
)}
|
||
</div>
|
||
<div className="text-[#CC0000] font-semibold text-sm mb-2">{gig.company}</div>
|
||
<div className="flex flex-wrap gap-3 text-sm text-gray-400">
|
||
<span>📍 {gig.location}</span>
|
||
<span>🎬 {gig.gig_type}</span>
|
||
{gig.rate && <span>💵 {gig.rate}</span>}
|
||
{gig.start_date && (
|
||
<span>📅 {new Date(gig.start_date).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}
|
||
{gig.end_date && ` – ${new Date(gig.end_date).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}`}
|
||
</span>
|
||
)}
|
||
</div>
|
||
</div>
|
||
<div className="text-xs text-gray-500 whitespace-nowrap">
|
||
{new Date(gig.created_at).toLocaleDateString('en-US', { month: 'short', day: 'numeric' })}
|
||
</div>
|
||
</div>
|
||
{gig.description && (
|
||
<p className="text-sm text-gray-500 mt-3 line-clamp-2">{gig.description}</p>
|
||
)}
|
||
</Link>
|
||
))}
|
||
</div>
|
||
)}
|
||
</div>
|
||
<Footer />
|
||
</div>
|
||
);
|
||
}
|