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