av: clone broadcastbeat sources + AV Beat rebrand (Phase 1)
- Replaces the prior Rocket scaffold (saved on pre-bb-clone-rollback branch) - Domain: broadcastbeat.com -> avbeat.com - Brand: Broadcast Beat -> AV Beat - Slug: broadcastbeat -> avbeat (package, identifiers) - Schema fallback: bb -> av (env var name unchanged) - Placeholder AV BEAT logo (gold->red gradient) at /assets/logos/av.svg - All BB/RMP logo references repointed Outstanding before public DNS swap: - Supabase av schema bootstrap (mirror of bb tables) - WordPress archive import (avbeat-com -> av.articles) - Coolify env vars - dev-avbeat.onsethost.com staging deploy + visual review
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
// Shared lib for RMP accounting — Supabase helpers and types
|
||||
import { createClient } from '@/lib/supabase/server';
|
||||
|
||||
export const RMP_SITES = ['broadcastbeat', 'avbeat', 'backlotbeat', 'broadcastengineering'] as const;
|
||||
export const RMP_SITES = ['avbeat', 'avbeat', 'backlotbeat', 'broadcastengineering'] as const;
|
||||
export type RmpSite = typeof RMP_SITES[number];
|
||||
|
||||
export const EXPENSE_CATEGORIES = [
|
||||
|
||||
@@ -3,13 +3,13 @@
|
||||
* Publications, placement zones, sender whitelist, rules
|
||||
*/
|
||||
|
||||
export const ADOPS_MONITORED_EMAIL = 'adops@broadcastbeat.com';
|
||||
export const ADOPS_MONITORED_EMAIL = 'adops@avbeat.com';
|
||||
export const RYAN_EMAIL = 'ryan.salazar@relevantmediaproperties.com';
|
||||
export const JEFF_EMAIL = 'jeff@broadcastbeat.com';
|
||||
export const JEFF_EMAIL = 'jeff@avbeat.com';
|
||||
|
||||
export const SENDER_WHITELIST = [
|
||||
'jeff@broadcastbeat.com',
|
||||
'sales@broadcastbeat.com',
|
||||
'jeff@avbeat.com',
|
||||
'sales@avbeat.com',
|
||||
'ryan.salazar@relevantmediaproperties.com',
|
||||
];
|
||||
|
||||
@@ -47,9 +47,9 @@ export interface Publication {
|
||||
export const PUBLICATIONS: Publication[] = [
|
||||
{
|
||||
id: 'broadcast-beat',
|
||||
name: 'Broadcast Beat',
|
||||
name: 'AV Beat',
|
||||
shortName: 'BB',
|
||||
domain: 'broadcastbeat.com',
|
||||
domain: 'avbeat.com',
|
||||
enabled: true,
|
||||
zones: [
|
||||
{ id: 'bb_leaderboard_top', label: 'Leaderboard Top', width: 728, height: 90 },
|
||||
|
||||
@@ -63,7 +63,7 @@ export async function sendToJeffAndRyan(params: {
|
||||
attachments?: SendEmailParams['attachments'];
|
||||
}): Promise<{ success: boolean; error?: string }> {
|
||||
return sendAdOpsEmail({
|
||||
to: 'jeff@broadcastbeat.com',
|
||||
to: 'jeff@avbeat.com',
|
||||
cc: [RYAN_EMAIL],
|
||||
subject: params.subject,
|
||||
html: params.html,
|
||||
|
||||
@@ -289,15 +289,15 @@ export function postSendReportEmailJeff(params: {
|
||||
|
||||
export function jeffWelcomeEmail(): { subject: string; html: string; to: string; cc: string } {
|
||||
return {
|
||||
to: 'jeff@broadcastbeat.com',
|
||||
to: 'jeff@avbeat.com',
|
||||
cc: 'ryan.salazar@relevantmediaproperties.com',
|
||||
subject: 'Your New Ad Ops System is Ready',
|
||||
html: emailWrapper(`
|
||||
<p>Hi Jeff — your new advertising operations system is ready. Here's how to use it:</p>
|
||||
<h3 style="color: #2c3e50; margin-top: 20px;">BANNER ADS</h3>
|
||||
<p>Email <a href="mailto:adops@broadcastbeat.com">adops@broadcastbeat.com</a> with the banner image attached and tell me: which publication, which placement, the click-through URL, and the campaign dates. I'll handle the rest and send you a screenshot for approval before anything goes live.</p>
|
||||
<p>Email <a href="mailto:adops@avbeat.com">adops@avbeat.com</a> with the banner image attached and tell me: which publication, which placement, the click-through URL, and the campaign dates. I'll handle the rest and send you a screenshot for approval before anything goes live.</p>
|
||||
<h3 style="color: #2c3e50; margin-top: 20px;">EMAIL DISTRIBUTIONS</h3>
|
||||
<p>Email <a href="mailto:adops@broadcastbeat.com">adops@broadcastbeat.com</a> with the HTML file attached along with the subject line, send date, and recipient list. I'll send you a test email for approval before sending to the full list.</p>
|
||||
<p>Email <a href="mailto:adops@avbeat.com">adops@avbeat.com</a> with the HTML file attached along with the subject line, send date, and recipient list. I'll send you a test email for approval before sending to the full list.</p>
|
||||
<h3 style="color: #2c3e50; margin-top: 20px;">INSERTION ORDERS</h3>
|
||||
<p>Please attach the signed IO to your campaign email. I'll store it automatically and create the invoice.</p>
|
||||
<p style="margin-top: 20px;">Questions? Just reply to this email and I'll take care of everything.</p>
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
/**
|
||||
* IMAP Email Monitor
|
||||
* Polls adops@broadcastbeat.com via Kerio Connect IMAP every 5 minutes.
|
||||
* Polls adops@avbeat.com via Kerio Connect IMAP every 5 minutes.
|
||||
* Credentials stored as env vars (to be added after deployment).
|
||||
*/
|
||||
|
||||
@@ -216,7 +216,7 @@ async function handleBannerRequest(
|
||||
|
||||
const requiredFields = [
|
||||
{ key: 'clientName', label: 'Client/advertiser name' },
|
||||
{ key: 'publication', label: 'Which publication(s) to run on (Broadcast Beat / AV Beat)' },
|
||||
{ key: 'publication', label: 'Which publication(s) to run on (AV Beat / AV Beat)' },
|
||||
{ key: 'placementZone', label: 'Ad placement zone (leaderboard, sidebar, in-article, etc.)' },
|
||||
{ key: 'destinationUrl', label: 'Click-through URL' },
|
||||
{ key: 'startDate', label: 'Campaign start date' },
|
||||
@@ -351,7 +351,7 @@ async function handleDistributionRequest(
|
||||
|
||||
const requiredFields = [
|
||||
{ key: 'subject', label: 'Email subject line' },
|
||||
{ key: 'listName', label: 'Recipient list (e.g. "Broadcast Beat full list")' },
|
||||
{ key: 'listName', label: 'Recipient list (e.g. "AV Beat full list")' },
|
||||
{ key: 'sendDate', label: 'Preferred send date and time (default: Thursday 11:00 AM ET)' },
|
||||
{ key: 'clientName', label: 'Client name (for tracking and invoicing)' },
|
||||
];
|
||||
|
||||
@@ -23,7 +23,7 @@ export interface Ad {
|
||||
|
||||
const SUPABASE_URL = process.env.NEXT_PUBLIC_SUPABASE_URL!;
|
||||
const SUPABASE_ANON = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!;
|
||||
const SCHEMA = process.env.NEXT_PUBLIC_SUPABASE_SCHEMA || "bb";
|
||||
const SCHEMA = process.env.NEXT_PUBLIC_SUPABASE_SCHEMA || "av";
|
||||
|
||||
// 30s in-process cache so admin uploads show on the site within ~30s.
|
||||
// The /api/banners endpoint also caps at 30s, so worst-case from upload
|
||||
@@ -80,7 +80,7 @@ interface DbRow {
|
||||
// We fetch all three sizes once and merge.
|
||||
const RMP_API = process.env.NEXT_PUBLIC_RMP_ADS_API
|
||||
|| "https://advertising.relevantmediaproperties.com";
|
||||
const PROPERTY = process.env.NEXT_PUBLIC_RMP_PROPERTY || "broadcastbeat";
|
||||
const PROPERTY = process.env.NEXT_PUBLIC_RMP_PROPERTY || "avbeat";
|
||||
|
||||
interface RmpBanner {
|
||||
campaign_id: string;
|
||||
|
||||
@@ -75,16 +75,16 @@ Length:
|
||||
|
||||
export function buildSystemPrompt(p: Persona): string {
|
||||
const writingStyle = p.writing_style || "Trade-press, plain English, AP style.";
|
||||
const bio = p.bio || "Broadcast Beat staff writer.";
|
||||
const bio = p.bio || "AV Beat staff writer.";
|
||||
const beat = p.beat || "broadcast technology";
|
||||
|
||||
return `You are ${p.name}, a staff journalist for Broadcast Beat covering ${beat}.
|
||||
return `You are ${p.name}, a staff journalist for AV Beat covering ${beat}.
|
||||
|
||||
Bio: ${bio}
|
||||
|
||||
Writing style: ${writingStyle}
|
||||
|
||||
You are rewriting a vendor-supplied press release into an independent journalism piece for the Broadcast Beat newsroom. You are NOT copywriting for the vendor; you are reporting on their announcement. The Broadcast Beat audience are broadcast engineers, post-production supervisors, streaming architects, and broadcast executives — they read trade press to find out what is true, not to be sold to.
|
||||
You are rewriting a vendor-supplied press release into an independent journalism piece for the AV Beat newsroom. You are NOT copywriting for the vendor; you are reporting on their announcement. The AV Beat audience are broadcast engineers, post-production supervisors, streaming architects, and broadcast executives — they read trade press to find out what is true, not to be sold to.
|
||||
|
||||
Hard rules:
|
||||
- Never use the literal text from the source as the lede. Rewrite the lede.
|
||||
|
||||
@@ -170,7 +170,7 @@ export async function rewriteSubmission(opts: RewriteOptions): Promise<RewriteOu
|
||||
// so the rewrite doesn't collide with WP-imported sequence values.
|
||||
try {
|
||||
const featuredImage = sub.metadata?.featured_image_url || null;
|
||||
const authorName = persona.name || sub.contributor_name || "Broadcast Beat";
|
||||
const authorName = persona.name || sub.contributor_name || "AV Beat";
|
||||
const finalSlug = `${slug}-rw-${(art as any).id.toString().slice(0, 6)}`;
|
||||
const wpRow = {
|
||||
wp_id: -Math.floor(Date.now() / 1000) - attempt,
|
||||
|
||||
@@ -4,7 +4,7 @@ import { rewriteLegacyImageUrl, cleanLegacyImages } from "@/lib/legacy-image";
|
||||
|
||||
const SUPABASE_URL = process.env.NEXT_PUBLIC_SUPABASE_URL!;
|
||||
const SUPABASE_ANON = process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!;
|
||||
const SCHEMA = process.env.NEXT_PUBLIC_SUPABASE_SCHEMA || "bb";
|
||||
const SCHEMA = process.env.NEXT_PUBLIC_SUPABASE_SCHEMA || "av";
|
||||
|
||||
function client() {
|
||||
return createClient(SUPABASE_URL, SUPABASE_ANON, {
|
||||
@@ -129,7 +129,7 @@ function rowToArticle(row: ImportedPostRow, section: Section = "news"): Article
|
||||
? rewriteLegacyImageUrl(row.featured_image)
|
||||
: FALLBACK_IMAGE;
|
||||
const content = cleanLegacyImages(row.content || "");
|
||||
const author = row.author_name || "Broadcast Beat";
|
||||
const author = row.author_name || "AV Beat";
|
||||
return {
|
||||
slug: row.wp_slug,
|
||||
section,
|
||||
@@ -162,7 +162,7 @@ function inferSectionFromCategory(cat: string | null): Section {
|
||||
function rewriteRowToArticle(row: RewriteRow, sectionOverride?: Section): Article {
|
||||
const sortedPublishedAt = row.published_at || row.created_at;
|
||||
const persona = Array.isArray(row.persona) ? row.persona[0] || null : row.persona || null;
|
||||
const author = persona?.name || "Broadcast Beat";
|
||||
const author = persona?.name || "AV Beat";
|
||||
const personaSlug = persona?.slug || "staff-reporter";
|
||||
const avatar = persona?.avatar_url || FALLBACK_IMAGE;
|
||||
return {
|
||||
@@ -174,7 +174,7 @@ function rewriteRowToArticle(row: RewriteRow, sectionOverride?: Section): Articl
|
||||
date: formatDate(sortedPublishedAt),
|
||||
author,
|
||||
authorSlug: personaSlug,
|
||||
authorTitle: persona?.beat ? humanBeat(persona.beat) : "Broadcast Beat",
|
||||
authorTitle: persona?.beat ? humanBeat(persona.beat) : "AV Beat",
|
||||
authorAvatar: avatar,
|
||||
image: REWRITE_FALLBACK_IMAGE,
|
||||
alt: row.title,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Role-based permission utilities for Broadcast Beat
|
||||
* Role-based permission utilities for AV Beat
|
||||
* Mirrors the WordPress role structure exactly.
|
||||
*/
|
||||
|
||||
@@ -224,7 +224,7 @@ export function getCategoriesForSite(role: string, siteId: number): string[] {
|
||||
}
|
||||
|
||||
export const SITE_CONFIG = {
|
||||
[SITE_IDS.BROADCAST_BEAT]: { name: 'Broadcast Beat', badge: 'BB', color: '#0ea5e9' },
|
||||
[SITE_IDS.BROADCAST_BEAT]: { name: 'AV Beat', badge: 'BB', color: '#0ea5e9' },
|
||||
[SITE_IDS.AV_BEAT]: { name: 'AV Beat', badge: 'AV', color: '#f97316' },
|
||||
} as const;
|
||||
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* RMP Content Pipeline — Article Generation Engine
|
||||
*
|
||||
* Handles article generation for all 4 RMP sites:
|
||||
* - Broadcast Beat (15-25/day)
|
||||
* - AV Beat (15-25/day)
|
||||
* - AV Beat (10-15/day)
|
||||
* - Backlot Beat (10-15/day)
|
||||
* - BroadcastEngineering.com (10-15/day)
|
||||
@@ -47,7 +47,7 @@ export interface PressReleaseRewrite {
|
||||
export const SITE_CONFIGS: Record<RMPSite, SiteConfig> = {
|
||||
'broadcast-beat': {
|
||||
name: 'broadcast-beat',
|
||||
displayName: 'Broadcast Beat',
|
||||
displayName: 'AV Beat',
|
||||
dailyTarget: { min: 15, max: 25 },
|
||||
topics: [
|
||||
'broadcast technology', 'production gear', 'industry news', 'NAB Show coverage',
|
||||
|
||||
@@ -49,6 +49,6 @@ export function verifyEmailToken(token: string): string | null {
|
||||
return `${hex.slice(0, 8)}-${hex.slice(8, 12)}-${hex.slice(12, 16)}-${hex.slice(16, 20)}-${hex.slice(20)}`;
|
||||
}
|
||||
|
||||
export function pixelUrl(trackedEmailId: string, baseUrl = "https://broadcastbeat.com"): string {
|
||||
export function pixelUrl(trackedEmailId: string, baseUrl = "https://avbeat.com"): string {
|
||||
return `${baseUrl.replace(/\/+$/, "")}/pix/${signEmailToken(trackedEmailId)}.png`;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -3,22 +3,22 @@ import map from "./legacy-image-map.json";
|
||||
const LEGACY_MAP = map as Record<string, string>;
|
||||
|
||||
const LEGACY_HOSTS = [
|
||||
"https://www.broadcastbeat.com",
|
||||
"https://broadcastbeat.com",
|
||||
"http://www.broadcastbeat.com",
|
||||
"http://broadcastbeat.com",
|
||||
"https://www.avbeat.com",
|
||||
"https://avbeat.com",
|
||||
"http://www.avbeat.com",
|
||||
"http://avbeat.com",
|
||||
];
|
||||
|
||||
export function rewriteLegacyImageUrl(url: string | null | undefined): string {
|
||||
if (!url) return "";
|
||||
// Direct map hit (canonical https://www.broadcastbeat.com/...)
|
||||
// Direct map hit (canonical https://www.avbeat.com/...)
|
||||
const direct = LEGACY_MAP[url];
|
||||
if (direct) return direct;
|
||||
// Try alternate-host normalization
|
||||
for (const host of LEGACY_HOSTS) {
|
||||
if (url.startsWith(host)) {
|
||||
const path = url.slice(host.length);
|
||||
const canonical = `https://www.broadcastbeat.com${path}`;
|
||||
const canonical = `https://www.avbeat.com${path}`;
|
||||
const hit = LEGACY_MAP[canonical];
|
||||
if (hit) return hit;
|
||||
}
|
||||
@@ -28,7 +28,7 @@ export function rewriteLegacyImageUrl(url: string | null | undefined): string {
|
||||
|
||||
export function rewriteLegacyImageUrlsInHtml(html: string): string {
|
||||
let out = html.replace(
|
||||
/(https?:\/\/(?:www\.)?broadcastbeat\.com\/wp-content\/uploads\/[^"'\s)]+)/g,
|
||||
/(https?:\/\/(?:www\.)?avbeat\.com\/wp-content\/uploads\/[^"'\s)]+)/g,
|
||||
(m) => rewriteLegacyImageUrl(m),
|
||||
);
|
||||
// Rewrite raw Supabase Storage URLs to clean first-party /img/<bucket>/<path>
|
||||
@@ -51,21 +51,21 @@ export function stripDeadLegacyImages(html: string): string {
|
||||
if (!html) return html;
|
||||
|
||||
// Match <img> tags whose src still hits the dead WP host.
|
||||
const DEAD_HOST_RE = /https?:\/\/(?:www\.)?broadcastbeat\.com\/wp-content\/uploads\//i;
|
||||
const DEAD_HOST_RE = /https?:\/\/(?:www\.)?avbeat\.com\/wp-content\/uploads\//i;
|
||||
|
||||
// Drop entire <figure>...</figure> blocks whose only inner content is a
|
||||
// dead-image <img>. Preserves figures that wrap working images.
|
||||
let out = html.replace(/<figure\b[^>]*>([\s\S]*?)<\/figure>/gi, (full, inner) => {
|
||||
if (!/<img\b[^>]*\bsrc\s*=\s*["'][^"']*broadcastbeat\.com\/wp-content\/uploads\/[^"']*["']/i.test(inner)) return full;
|
||||
if (!/<img\b[^>]*\bsrc\s*=\s*["'][^"']*avbeat\.com\/wp-content\/uploads\/[^"']*["']/i.test(inner)) return full;
|
||||
// figure contains a dead image — drop entirely
|
||||
return "";
|
||||
});
|
||||
|
||||
// Drop <a>…<img dead …>…</a> wrappers
|
||||
out = out.replace(/<a\b[^>]*>\s*<img\b[^>]*\bsrc\s*=\s*["'][^"']*broadcastbeat\.com\/wp-content\/uploads\/[^"']*["'][^>]*\/?>\s*<\/a>/gi, "");
|
||||
out = out.replace(/<a\b[^>]*>\s*<img\b[^>]*\bsrc\s*=\s*["'][^"']*avbeat\.com\/wp-content\/uploads\/[^"']*["'][^>]*\/?>\s*<\/a>/gi, "");
|
||||
|
||||
// Drop bare <img dead …>
|
||||
out = out.replace(/<img\b[^>]*\bsrc\s*=\s*["'][^"']*broadcastbeat\.com\/wp-content\/uploads\/[^"']*["'][^>]*\/?>/gi, "");
|
||||
out = out.replace(/<img\b[^>]*\bsrc\s*=\s*["'][^"']*avbeat\.com\/wp-content\/uploads\/[^"']*["'][^>]*\/?>/gi, "");
|
||||
|
||||
// Drop empty <figure></figure> left over after image removal.
|
||||
out = out.replace(/<figure\b[^>]*>\s*(?:<figcaption\b[^>]*>\s*<\/figcaption>\s*)?<\/figure>/gi, "");
|
||||
|
||||
@@ -22,7 +22,7 @@ async function sendEmail(payload: MarketplaceEmailPayload): Promise<void> {
|
||||
export async function sendProfileApprovedEmail(to: string, name: string): Promise<void> {
|
||||
await sendEmail({
|
||||
to,
|
||||
subject: 'Your Broadcast Beat Marketplace Profile is Approved!',
|
||||
subject: 'Your AV Beat Marketplace Profile is Approved!',
|
||||
html: `
|
||||
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; background: #0d0d0d; color: #fff; padding: 32px; border-radius: 8px;">
|
||||
<div style="text-align: center; margin-bottom: 24px;">
|
||||
@@ -32,7 +32,7 @@ export async function sendProfileApprovedEmail(to: string, name: string): Promis
|
||||
<h2 style="color: #fff; font-size: 20px;">Welcome to the Marketplace, ${name}!</h2>
|
||||
<p style="color: #ccc; line-height: 1.6;">
|
||||
Your profile has been reviewed and approved by our team. You are now live in the
|
||||
Broadcast Beat Production Marketplace and visible to clients, employers, and production companies.
|
||||
AV Beat Production Marketplace and visible to clients, employers, and production companies.
|
||||
</p>
|
||||
<div style="background: #1a1a1a; border-left: 4px solid #CC0000; padding: 16px; margin: 24px 0; border-radius: 4px;">
|
||||
<p style="color: #fff; margin: 0; font-weight: bold;">Next Steps:</p>
|
||||
@@ -47,8 +47,8 @@ export async function sendProfileApprovedEmail(to: string, name: string): Promis
|
||||
View Your Profile
|
||||
</a>
|
||||
<p style="color: #666; font-size: 12px; margin-top: 32px;">
|
||||
Broadcast Beat — Official NAB Show Media Partner<br>
|
||||
<a href="${process.env.NEXT_PUBLIC_SITE_URL}" style="color: #CC0000;">broadcastbeat.com</a>
|
||||
AV Beat — Official NAB Show Media Partner<br>
|
||||
<a href="${process.env.NEXT_PUBLIC_SITE_URL}" style="color: #CC0000;">avbeat.com</a>
|
||||
</p>
|
||||
</div>
|
||||
`,
|
||||
@@ -62,7 +62,7 @@ export async function sendProfileRejectedEmail(
|
||||
): Promise<void> {
|
||||
await sendEmail({
|
||||
to,
|
||||
subject: 'Update Required: Your Broadcast Beat Marketplace Profile',
|
||||
subject: 'Update Required: Your AV Beat Marketplace Profile',
|
||||
html: `
|
||||
<div style="font-family: Arial, sans-serif; max-width: 600px; margin: 0 auto; background: #0d0d0d; color: #fff; padding: 32px; border-radius: 8px;">
|
||||
<div style="text-align: center; margin-bottom: 24px;">
|
||||
@@ -86,7 +86,7 @@ export async function sendProfileRejectedEmail(
|
||||
Update My Profile
|
||||
</a>
|
||||
<p style="color: #666; font-size: 12px; margin-top: 32px;">
|
||||
Questions? Reply to this email or contact us at <a href="mailto:marketplace@broadcastbeat.com" style="color: #CC0000;">marketplace@broadcastbeat.com</a>
|
||||
Questions? Reply to this email or contact us at <a href="mailto:marketplace@avbeat.com" style="color: #CC0000;">marketplace@avbeat.com</a>
|
||||
</p>
|
||||
</div>
|
||||
`,
|
||||
@@ -112,7 +112,7 @@ export async function sendListingConfirmationEmail(
|
||||
Your ${listingType === 'job' ? 'Job Post' : 'Gig Request'} is Live!
|
||||
</h2>
|
||||
<p style="color: #ccc; line-height: 1.6;">
|
||||
<strong style="color: #fff;">"${title}"</strong> has been posted to the Broadcast Beat Marketplace
|
||||
<strong style="color: #fff;">"${title}"</strong> has been posted to the AV Beat Marketplace
|
||||
and is now visible to our network of broadcast and production professionals.
|
||||
</p>
|
||||
<a href="${process.env.NEXT_PUBLIC_SITE_URL}/marketplace/${listingType === 'job' ? 'jobs' : 'gigs'}"
|
||||
@@ -120,7 +120,7 @@ export async function sendListingConfirmationEmail(
|
||||
View ${listingType === 'job' ? 'Job Board' : 'Gig Board'}
|
||||
</a>
|
||||
<p style="color: #666; font-size: 12px; margin-top: 32px;">
|
||||
Broadcast Beat — Official NAB Show Media Partner
|
||||
AV Beat — Official NAB Show Media Partner
|
||||
</p>
|
||||
</div>
|
||||
`,
|
||||
|
||||
@@ -18,6 +18,6 @@ export function createAdminClient(schema?: string) {
|
||||
}
|
||||
return createClient(url, key, {
|
||||
auth: { persistSession: false, autoRefreshToken: false },
|
||||
db: { schema: schema || process.env.NEXT_PUBLIC_SUPABASE_SCHEMA || "avb" },
|
||||
db: { schema: schema || process.env.NEXT_PUBLIC_SUPABASE_SCHEMA || "av" },
|
||||
});
|
||||
}
|
||||
|
||||
@@ -5,7 +5,7 @@ export function createClient() {
|
||||
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
||||
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
||||
{
|
||||
db: { schema: process.env.NEXT_PUBLIC_SUPABASE_SCHEMA || 'avb' },
|
||||
db: { schema: process.env.NEXT_PUBLIC_SUPABASE_SCHEMA || 'bb' },
|
||||
cookies: {
|
||||
getAll() {
|
||||
if (typeof document === 'undefined') return [];
|
||||
|
||||
@@ -8,7 +8,7 @@ export async function createClient() {
|
||||
process.env.NEXT_PUBLIC_SUPABASE_URL!,
|
||||
process.env.NEXT_PUBLIC_SUPABASE_ANON_KEY!,
|
||||
{
|
||||
db: { schema: process.env.NEXT_PUBLIC_SUPABASE_SCHEMA || 'avb' },
|
||||
db: { schema: process.env.NEXT_PUBLIC_SUPABASE_SCHEMA || 'bb' },
|
||||
cookies: {
|
||||
getAll() {
|
||||
return cookieStore.getAll();
|
||||
|
||||
Reference in New Issue
Block a user