--- import { getCollection } from 'astro:content'; import { Image } from 'astro:assets'; import BaseLayout from '../layouts/BaseLayout.astro'; import Masonry from '../components/Masonry.astro'; import { heroes } from '../lib/hero'; import { bundleMosaic } from '../lib/bundle-mosaic'; import { buildOgImage, buildItemList, WEBSITE, ORGANIZATION } from '../lib/seo'; import pick from '../data/pick.json'; // Pick of the day. Set in src/data/pick.json; null falls back to the latest review. const HERO_SLUG: string | null = pick.hero; const INITIAL_GRID = 24; const BATCH_SIZE = 7; type Tile = | { kind: 'review'; href: string; id: string; name: string; subtitle: string; date: Date; hero: ReturnType; } | { kind: 'bundle'; href: string; id: string; name: string; subtitle: string | undefined; date: Date; itemCount: number; mosaic: ReturnType; }; function getReviewHero(slug: string) { return heroes[slug]; } const [reviews, bundles] = await Promise.all([ getCollection('reviews'), getCollection('bundles'), ]); const reviewTiles: Tile[] = reviews.map((review) => ({ kind: 'review' as const, href: `/reviews/${review.id}/`, id: review.id, name: review.data.name, subtitle: review.data.subtitle, date: review.data.date, hero: getReviewHero(review.id), })); const bundleTiles: Tile[] = bundles.map((bundle) => ({ kind: 'bundle' as const, href: `/bundles/${bundle.id}/`, id: bundle.id, name: bundle.data.title, subtitle: bundle.data.blurb, date: bundle.data.date, itemCount: bundle.data.items.length, mosaic: bundleMosaic(bundle.id), })); const tiles: Tile[] = [...reviewTiles, ...bundleTiles].sort( (a, b) => b.date.valueOf() - a.date.valueOf() ); const heroIndex = tiles.findIndex( (t) => t.kind === 'review' && t.href === `/reviews/${HERO_SLUG}/` ); // Fall back to the newest review (tiles are sorted by date desc). const hero = heroIndex >= 0 ? tiles[heroIndex] : tiles.find((t) => t.kind === 'review'); const rest = tiles.filter((t) => t !== hero); const lastUpdated = tiles[0]?.date; const ogImage = buildOgImage(hero?.id, 'reviews', `${hero?.name ?? 'Unique'} hero image`); const itemList = buildItemList( tiles.slice(0, INITIAL_GRID).map((t) => ({ url: t.href, name: t.name })), 'Latest entries' ); --- {hero && hero.kind === 'review' && ( {hero.hero?.kind === 'image' && ( {hero.name} )} {hero.hero?.kind === 'video' && ( )} { rest.map((tile) => { const visual = tile.kind === 'review' ? tile.hero : tile.mosaic ? { kind: 'image' as const, src: tile.mosaic } : undefined; return ( ); }) }