diff --git a/src/components/Schedule/CardConference.astro b/src/components/Schedule/CardConference.astro index 2f86cd24..c7493e74 100644 --- a/src/components/Schedule/CardConference.astro +++ b/src/components/Schedule/CardConference.astro @@ -1,10 +1,12 @@ --- import { type CollectionEntry, getEntries, getEntry } from "astro:content"; -import { IoLanguageSharp } from "react-icons/io5"; +import { IoLanguageSharp, IoSparklesSharp } from "react-icons/io5"; import SpeakerForCard from "./SpeakerForCard.astro"; import { lunalink } from "@bearstudio/lunalink"; import { ROUTES } from "@/routes.gen"; import { LuSquarePlay } from "react-icons/lu"; +import { FiXCircle } from "react-icons/fi"; +import { cn } from "@/lib/utils-client"; interface Props { activity: NonNullable< @@ -27,6 +29,9 @@ const speakers = ( }, })); const people = [...hosts, ...speakers]; +const scheduleItem = (event.data.schedule?.items ?? []).find( + (conference) => conference.slug?.id === talk?.id, +); --- { @@ -36,13 +41,45 @@ const people = [...hosts, ...speakers]; id: event.id, talkId: talk.id, })} - class="group flex w-full flex-col gap-4 rounded-lg bg-white/5 p-4 backdrop-blur-md transition hover:bg-white/10 sm:px-6 sm:py-5" + class={cn( + "group flex w-full flex-col gap-4 rounded-lg bg-white/5 p-4 backdrop-blur-md transition hover:bg-white/10 sm:px-6 sm:py-5", + scheduleItem?.status === "cancelled" && "opacity-60", + )} > -

- {talk.data.title} -

+
+

+ {talk.data.title} +

+ {scheduleItem?.status === "cancelled" && ( +
+
+ + Cancelled +
+
+ )} + {scheduleItem?.status === "replacement" && ( +
+
+ + New +
+
+ )} +
+ {!!people.length && ( -
+
{speakers.map((speaker) => ( )} -
- +
+ Talk in {talk.data.language} diff --git a/src/lib/events.ts b/src/lib/events.ts index 3c62619d..922b96f2 100644 --- a/src/lib/events.ts +++ b/src/lib/events.ts @@ -69,6 +69,13 @@ export async function eventWithComputed< (talk) => talk.data.speakers?.map(async (speaker) => { if (!speaker) return; + const scheduleTalk = event.data.schedule?.items?.find( + (item) => item.slug?.id === talk.id, + ); + const isSpeakerTalkCanceled = scheduleTalk?.status === "cancelled"; + if (isSpeakerTalkCanceled) { + return; + } const person = await getEntry("people", speaker.id.id); if (!person) { diff --git a/src/pages/events/[id].html.md/index.ts b/src/pages/events/[id].html.md/index.ts index 6ad5c6a6..15d3ab51 100644 --- a/src/pages/events/[id].html.md/index.ts +++ b/src/pages/events/[id].html.md/index.ts @@ -67,12 +67,18 @@ ${event.data.location?.name}, ${event.data.location?.address}`; const displaySchedule = async (event: EventWithComputed) => { if (isEmpty(event.data._computed.talks)) return ""; - + const talks = event.data._computed.talks.filter((talk) => { + const scheduleTalk = event.data.schedule?.items?.find( + (item) => item.slug?.id === talk.id, + ); + return scheduleTalk?.status !== "cancelled"; + }); const itemsWithTime = event.data.schedule?.items?.filter( (item) => (item.type === "conference" || item.type === "roundtable") && - item.startTime, + item.startTime && + item.status !== "cancelled", ) ?? []; const formattedItems = itemsWithTime.map((item) => @@ -83,7 +89,7 @@ const displaySchedule = async (event: EventWithComputed) => { ${( await Promise.all( - event.data._computed.talks.map(async (item, index) => { + talks.map(async (item, index) => { const timeStart = formattedItems[index]; return `- [${item.data.title}](${lunalink( ROUTES.events[":id"].talks[":talkId"].__path, diff --git a/src/pages/events/[id]/assets/_utils.ts b/src/pages/events/[id]/assets/_utils.ts index 16fae8e6..94ed9ae3 100644 --- a/src/pages/events/[id]/assets/_utils.ts +++ b/src/pages/events/[id]/assets/_utils.ts @@ -45,12 +45,14 @@ export const getEventAssetsSources = (event: CollectionEntry<"events">) => { const sponsors = event.data.sponsors?.map((s) => s.slug) ?? []; const partners = event.data.partners ?? []; const coOrganizers = event.data.coOrganizers ?? []; - + const talks = event.data.schedule?.items?.filter( + (talk) => talk.status !== "cancelled", + ); return [ eventFilesNames.map( (fileName) => `/events/${event.id}/assets/${fileName}.jpg`, ), - event.data.schedule?.items?.flatMap((talk) => + talks?.flatMap((talk) => talkFilesNames.map((fileName) => !talk.slug ? null diff --git a/src/schemas/events.ts b/src/schemas/events.ts index 5fbe4145..9f2c3318 100644 --- a/src/schemas/events.ts +++ b/src/schemas/events.ts @@ -152,6 +152,9 @@ const zEventBase = ({ image }: SchemaContext) => startTime: z.date().optional(), duration: z.number().optional().describe("Number of minutes"), location: z.string().optional(), + status: z + .enum(["cancelled", "replacement", "published"]) + .default("published"), }), ) .optional(),