apps/web/src/lib/upcomingWebinars.ts

1import { getSanityClient } from '@local/sanity/client'
2import { sanityFetch } from '@local/sanity/utils/fetch'
3import {
4	RESOURCE_EVENT_UTC_RAW_GROQ,
5	ROUNDTABLE_EVENT_DATETIME_GROQ,
6} from '@local/sanity/utils/query'
7
8export type UpcomingWebinar = {
9	title?: string
10	url?: string
11	startsAtUtc?: string
12	excerpt?: string
13	speakers?: Array<{ name?: string; role?: string; company?: string }>
14}
15
16/**
17 * Webinar `eventSchedule.utcDateTime` is a Studio datetime — always full ISO
18 * when set (probed on prod: 212/212 parseable), so the no-padding event-UTC
19 * helper is the right comparator. Speaker names live in profile `title`;
20 * company names in the referenced company's `title` (probed likewise).
21 */
22const UPCOMING_WEBINARS_QUERY = `*[
23	_type == "webinar" &&
24	defined(fullSlug) &&
25	defined(${RESOURCE_EVENT_UTC_RAW_GROQ}) &&
26	(${ROUNDTABLE_EVENT_DATETIME_GROQ}) > dateTime(now())
27] | order(${RESOURCE_EVENT_UTC_RAW_GROQ} asc) [0...10] {
28	title,
29	"url": fullSlug,
30	"startsAtUtc": ${RESOURCE_EVENT_UTC_RAW_GROQ},
31	excerpt,
32	"speakers": speakers[]->{"name": title, role, "company": company[0]->title}
33}`
34
35/** Webinars that have not aired yet, soonest first (max 10). */
36export async function fetchUpcomingWebinars(): Promise<UpcomingWebinar[]> {
37	return sanityFetch<UpcomingWebinar[]>(
38		getSanityClient(),
39		UPCOMING_WEBINARS_QUERY,
40		undefined,
41		{ tag: 'webinars' },
42	)
43}
44