From f59557da3213239200282743f11fdcf0bbf656bc Mon Sep 17 00:00:00 2001 From: Daniel Roe Date: Fri, 4 Jul 2025 21:23:30 +0100 Subject: [PATCH] refactor: move talks into CMS (#1659) --- app/components/TheHome.server.vue | 68 +- app/components/TheTalks.server.vue | 81 +- app/data/talks.json | 1014 ------------------------ cms/components/GitHubReleaseInput.tsx | 201 +++++ cms/package.json | 1 + cms/schemaTypes/index.ts | 4 +- cms/schemaTypes/talk.ts | 172 ++++ cms/schemaTypes/talkGroup.ts | 33 + modules/slides.ts | 17 +- modules/sync/runtime/utils/items.ts | 37 +- nuxt.config.ts | 7 +- pnpm-lock.yaml | 44 +- server/api/talks.get.ts | 40 + server/api/upcoming-conferences.get.ts | 10 +- test/unit/bundle.spec.ts | 4 +- 15 files changed, 615 insertions(+), 1118 deletions(-) delete mode 100644 app/data/talks.json create mode 100644 cms/components/GitHubReleaseInput.tsx create mode 100644 cms/schemaTypes/talk.ts create mode 100644 cms/schemaTypes/talkGroup.ts create mode 100644 server/api/talks.get.ts diff --git a/app/components/TheHome.server.vue b/app/components/TheHome.server.vue index 894129a1..44557643 100644 --- a/app/components/TheHome.server.vue +++ b/app/components/TheHome.server.vue @@ -45,52 +45,46 @@ const [{ data: currentLocation }, { data: upcomingConferences }, { data: streams .sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()) .slice(0, 4) }), - useAsyncData( - () => - ((import.meta.server || import.meta.dev) as true) - && import('../data/talks.json').then(r => r.default as any as Talk[]), - { - transform: talks => { - const groupedTalks: Record = {} - for (const talk of talks) { - const slug = talk.group || talk.slug - if (groupedTalks[slug]) { - groupedTalks[slug]!.push(talk) - } - else { - groupedTalks[slug] = [talk] - } + useFetch('/api/talks', { + transform: talks => { + // Group talks by group or individual ID + const groupedTalks: Record = {} + + for (const talk of talks) { + const groupKey = talk.group?._id || talk._id + if (groupedTalks[groupKey]) { + groupedTalks[groupKey]!.push(talk) + } + else { + groupedTalks[groupKey] = [talk] } + } - for (const group in groupedTalks) { - groupedTalks[group]!.sort( + // Sort and get the most recent talk from each group + const groups = Object.entries(groupedTalks) + .map(([_groupKey, talksInGroup]) => { + const sortedTalks = talksInGroup.sort( (a, b) => new Date(b.date).getTime() - new Date(a.date).getTime(), ) - } - - const groups = Object.entries(groupedTalks).sort( - ([_s1, [a]], [_s2, [b]]) => { - return new Date(b.date).getTime() - new Date(a.date).getTime() - }, - ) + return sortedTalks[0] // Get most recent talk from each group + }) + .sort((a, b) => new Date(b.date).getTime() - new Date(a.date).getTime()) - return groups.slice(0, 4).map(([_slug, [firstTalk]]) => firstTalk) - }, + return groups.slice(0, 4) }, - ), + }), ]) interface Talk { - slug: string - group?: string + _id: string title: string source: string - tags: string - link: string - date: string - type: 'talk' | 'podcast' | 'meetup' | 'talk' | 'conference' | 'mini-workshop' + tags: string[] + link?: string video?: string - release?: string + date: string + type: 'conference' | 'podcast' | 'meetup' | 'workshop' | 'mini-workshop' | 'stream' + slides?: string repo?: string demo?: string } @@ -267,7 +261,7 @@ interface Talk {
  • diff --git a/app/components/TheTalks.server.vue b/app/components/TheTalks.server.vue index 3b8a66ba..cf1479d6 100644 --- a/app/components/TheTalks.server.vue +++ b/app/components/TheTalks.server.vue @@ -1,48 +1,55 @@ @@ -64,8 +75,8 @@ const { data: groups } = await useAsyncData(