apps/web/src/lib/recentArticles.ts
1import { EDITORIAL_TYPES } from '@local/config'
2import { getPublishedSanityClient } from '@local/sanity/client'
3import { sanityFetch } from '@local/sanity/utils/fetch'
4import {
5 RESOURCE_DATE_RAW_GROQ,
6 RESOURCE_DATETIME_GROQ,
7} from '@local/sanity/utils/query'
8
9export const ARTICLE_TYPES = EDITORIAL_TYPES.filter(
10 (type) =>
11 !['video', 'report', 'research', 'data', 'testimonials'].includes(type),
12)
13
14export const RECENT_ARTICLES_QUERY = `*[
15 _type in $types && defined(fullSlug) && defined(title) &&
16 (${RESOURCE_DATETIME_GROQ}) <= dateTime(now()) &&
17 ($topic == "" || title match $topic || excerpt match $topic || topics[]->title match $topic)
18] | order((${RESOURCE_DATETIME_GROQ}) desc, _id asc) [0...8] {
19 title, "url": fullSlug, excerpt,
20 "publishedAt": ${RESOURCE_DATE_RAW_GROQ},
21 "topics": topics[]->title
22}`
23
24type RecentArticle = {
25 title: string
26 url: string
27 excerpt: string | null
28 publishedAt: string
29 topics: string[] | null
30}
31
32/** Sort the complete matching published catalogue before limiting results. */
33export async function fetchRecentArticles(
34 topic: string,
35): Promise<RecentArticle[]> {
36 return sanityFetch<RecentArticle[]>(
37 getPublishedSanityClient(),
38 RECENT_ARTICLES_QUERY,
39 { types: ARTICLE_TYPES, topic: topic.trim().slice(0, 120) },
40 { tag: 'media' },
41 )
42}
43