Skip to content
58 changes: 50 additions & 8 deletions src/components/Schedule/CardConference.astro
Original file line number Diff line number Diff line change
@@ -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<
Expand All @@ -27,6 +29,9 @@ const speakers = (
},
}));
const people = [...hosts, ...speakers];
const scheduleItem = (event.data.schedule?.items ?? []).find(
(conference) => conference.slug?.id === talk?.id,
);
---

{
Expand All @@ -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",
)}
>
<p class="text-balance font-heading text-base font-medium leading-tight tracking-wider text-white transition group-hover:text-primary">
{talk.data.title}
</p>
<div class="flex justify-between">
<p
class={cn(
"text-balance font-heading text-base font-medium leading-tight tracking-wider text-white transition group-hover:text-primary",
scheduleItem?.status === "cancelled" ? "line-through" : "",
)}
>
{talk.data.title}
</p>
{scheduleItem?.status === "cancelled" && (
<div class="h-full w-fit rounded-full bg-white/10 px-2 py-1 text-white">
<div class="flex items-center gap-1">
<FiXCircle className="h-3 w-3" />
<span class="text-xs font-medium">Cancelled</span>
</div>
</div>
)}
{scheduleItem?.status === "replacement" && (
<div class="isolate h-full w-fit justify-center rounded-full bg-white from-accent px-2 py-1 text-background">
<div class="flex items-center gap-1">
<IoSparklesSharp className="h-3 w-3" />
<span class="text-xs font-medium">New</span>
</div>
</div>
)}
</div>

{!!people.length && (
<div class="grid grid-cols-2 gap-3 md:grid-cols-3">
<div
class={cn(
"grid grid-cols-2 gap-3 md:grid-cols-3",
scheduleItem?.status === "cancelled" ? "grayscale" : "",
)}
>
{speakers.map((speaker) => (
<SpeakerForCard
name={speaker.data.name}
Expand All @@ -53,8 +90,13 @@ const people = [...hosts, ...speakers];
</div>
)}

<div class="flex flex-row gap-2">
<span class="flex w-fit items-center gap-1.5 rounded-full border border-black/60 bg-black/40 px-2 py-0.5 text-2xs font-bold uppercase leading-none opacity-60 transition group-hover:opacity-100">
<div
class={cn(
"flex flex-row gap-2",
scheduleItem?.status === "cancelled" ? "grayscale" : "",
)}
>
<span class="flex w-fit items-center gap-1.5 rounded-full border border-black/60 bg-black/40 px-2 py-0.5 text-2xs font-bold uppercase leading-none opacity-60 grayscale transition group-hover:opacity-100">
<IoLanguageSharp className="text-base" />
<span>Talk in {talk.data.language}</span>
</span>
Expand Down
7 changes: 7 additions & 0 deletions src/lib/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
12 changes: 9 additions & 3 deletions src/pages/events/[id].html.md/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) =>
Expand All @@ -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,
Expand Down
6 changes: 4 additions & 2 deletions src/pages/events/[id]/assets/_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 3 additions & 0 deletions src/schemas/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(),
Expand Down