Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 101 additions & 6 deletions apps/cms/seed/page-content.ts
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@ async function ensureMedia(
payload: Payload,
href: string | null | undefined,
alt: string | null | undefined,
// Names the caller in the soft-miss warning below.
context = "kickoff",
): Promise<number | null> {
const filename = localMediaFilename(href);
if (!filename) return null;
Expand All @@ -103,7 +105,7 @@ async function ensureMedia(
const sourcePath = path.join(webMediaDir, filename);
if (!fs.existsSync(sourcePath)) {
console.warn(
` kickoff media missing on disk (${filename}); leaving upload unset until the file is added through Payload`,
` ${context} media missing on disk (${filename}); leaving upload unset until the file is added through Payload`,
);
return null;
}
Expand All @@ -121,24 +123,85 @@ async function run() {
const payload = await getPayload({ config });
const content = readJson("page-content");

// page-home
// page-home. The 2027 fields (hero badge and lead lines, countdown, partner
// row descriptions, audience tile links and photos, speaker highlights and
// lineup, social) are optional in the fixture and in the schema. A field
// the fixture does not carry is written as empty rather than skipped, so a
// re-seed always ends on exactly what the fixture says.
{
const home = content.home;

// JSON carries a tile photo as a media filename (WhyCard.imageFile); the
// CMS field is the upload `image`. Soft-miss like the kickoff images.
const cards = [];
for (const card of home.whyAttend.cards) {
const image = card.imageFile
? await ensureMedia(
payload,
`/media/${card.imageFile}`,
card.imageAlt,
"home audience tile",
)
: null;
cards.push({
title: card.title,
description: card.description,
eyebrow: card.eyebrow ?? null,
href: card.href ?? null,
linkLabel: card.linkLabel ?? null,
...(image !== null ? { image } : {}),
imageAlt: card.imageAlt ?? null,
});
}

// A post row requires its image, so a post whose file is not on disk is
// left out instead of failing the whole seed.
const posts = [];
for (const post of home.social?.posts ?? []) {
const image = post.imageFile
? await ensureMedia(
payload,
`/media/${post.imageFile}`,
post.imageAlt,
"home social post",
)
: null;
if (image === null) continue;
posts.push({
platform: post.platform,
href: post.href,
image,
imageAlt: post.imageAlt ?? null,
});
}

const speakers = home.previousSpeakers;
await payload.updateGlobal({
slug: "page-home",
data: {
title: home.title,
metaDescription: home.metaDescription,
hero: {
badge: home.hero.badge ?? null,
headline: home.hero.headline,
tagline: home.hero.tagline,
leadLines: toTextRows(home.hero.leadLines ?? []),
announcementLines: toTextRows(home.hero.announcementLines),
cta: home.hero.cta,
},
event: {
startDate: home.event.startDate,
endDate: home.event.endDate,
},
countdown: {
label: home.countdown?.label ?? null,
daysLabel: home.countdown?.daysLabel ?? null,
hoursLabel: home.countdown?.hoursLabel ?? null,
minutesLabel: home.countdown?.minutesLabel ?? null,
secondsLabel: home.countdown?.secondsLabel ?? null,
spokenLabel: home.countdown?.spokenLabel ?? null,
liveLabel: home.countdown?.liveLabel ?? null,
},
stats: {
heading: home.stats.heading,
intro: home.stats.intro,
Expand All @@ -149,27 +212,59 @@ async function run() {
})),
},
partnerBand: {
eyebrow: home.partnerBand.eyebrow ?? null,
heading: home.partnerBand.heading ?? null,
items: home.partnerBand.items.map((item: any) => ({
value: item.value,
// May be empty: the 2027 partner rows show no count.
value: item.value ?? null,
label: item.label,
description: item.description ?? null,
logos: toTextRows(item.logos ?? []),
})),
cta: home.partnerBand.cta,
},
previousSpeakers: home.previousSpeakers,
previousSpeakers: {
eyebrow: speakers.eyebrow ?? null,
heading: speakers.heading,
intro: speakers.intro,
alumniLabel: speakers.alumniLabel ?? null,
highlights: toTextRows(speakers.highlights ?? []),
lineup: {
label: speakers.lineup?.label ?? null,
year: speakers.lineup?.year ?? null,
slots: speakers.lineup?.slots ?? 4,
showPlaceholders: speakers.lineup?.showPlaceholders ?? false,
placeholderName: speakers.lineup?.placeholderName ?? null,
placeholderRole: speakers.lineup?.placeholderRole ?? null,
},
standIns: toTextRows(speakers.standIns ?? []),
standInLabel: speakers.standInLabel ?? null,
cta: speakers.cta,
},
whyAttend: {
eyebrow: home.whyAttend.eyebrow ?? null,
heading: home.whyAttend.heading,
intro: home.whyAttend.intro,
cards: home.whyAttend.cards,
cards,
cta: home.whyAttend.cta,
},
social: {
eyebrow: home.social?.eyebrow ?? null,
heading: home.social?.heading ?? null,
intro: home.social?.intro ?? null,
linkedinLabel: home.social?.linkedinLabel ?? null,
instagramLabel: home.social?.instagramLabel ?? null,
posts,
},
faqSection: home.faqSection,
_status: "published",
},
user: seedUser,
overrideAccess: true,
});
console.log("page-home: updated and published");
console.log(
`page-home: updated and published (${cards.length} audience tiles, ${posts.length} social posts)`,
);
}

// page-whyq (resolves each audience's photo to a media doc when present)
Expand Down
20 changes: 18 additions & 2 deletions apps/cms/seed/site-settings.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,14 @@ interface SocialLink extends PageLink {
"tiktok" | "instagram-qsummit" | "instagram-qhack" | "linkedin" | "youtube";
}

/** Nav item with its optional submenu (NavLink in apps/web site-settings.ts). */
interface NavLink extends PageLink {
children?: PageLink[] | null;
}

interface SiteSettingsSource {
siteTitle: string;
nav: PageLink[];
nav: NavLink[];
footer: {
tagline: string;
links: PageLink[];
Expand Down Expand Up @@ -54,7 +59,15 @@ async function run() {
slug: "site-settings",
data: {
siteTitle: data.siteTitle,
nav: data.nav,
// Sub-items are optional: an item without them seeds as a plain link.
nav: data.nav.map((item) => ({
label: item.label,
href: item.href,
children: (item.children ?? []).map((child) => ({
label: child.label,
href: child.href,
})),
})),
footer: {
tagline: data.footer.tagline,
links: data.footer.links,
Expand All @@ -80,6 +93,9 @@ async function run() {
console.log("site-settings global: updated and published");
console.log(` - siteTitle: "${data.siteTitle}"`);
console.log(` - nav items: ${data.nav.length}`);
console.log(
` - nav sub-items: ${data.nav.reduce((sum, item) => sum + (item.children?.length ?? 0), 0)}`,
);
console.log(` - footer links: ${data.footer.links.length}`);
console.log(` - social links: ${data.footer.socialLinks.length}`);
console.log(` - llms key facts: ${data.llms?.keyFacts?.length ?? 0}`);
Expand Down
Loading
Loading