Skip to content

Commit 7038e05

Browse files
committed
feat: add dynamic hero preview and update component
Add a new getHeroPreview data fetch function in lib/data/stories.ts to load homepage hero stories, update the home page to fetch this data and pass it to the Hero component, and modify the Hero component to accept optional stories prop that falls back to the static HERO_PREVIEW when no dynamic stories are provided.
1 parent e4204a1 commit 7038e05

3 files changed

Lines changed: 21 additions & 6 deletions

File tree

app/page.tsx

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,12 @@ import { WhatsappBanner } from "@/components/home/WhatsappBanner";
88
import { Impact } from "@/components/ui/Impact";
99
import { CONTENT_DESKS } from "@/lib/content-desks";
1010
import { getContentDesks } from "@/lib/data/desks";
11-
import { getLatest, getSpotlight, getTrending } from "@/lib/data/stories";
11+
import {
12+
getHeroPreview,
13+
getLatest,
14+
getSpotlight,
15+
getTrending,
16+
} from "@/lib/data/stories";
1217
import {
1318
LATEST_FEATURE,
1419
LATEST_GRID,
@@ -21,16 +26,17 @@ import {
2126
export default async function Home() {
2227
// Pages own fetching; fall back to the static content when Hasura is
2328
// unreachable or unconfigured. Fetched in parallel — each falls back alone.
24-
const [desks, spotlight, trending, latest] = await Promise.all([
29+
const [desks, heroPreview, spotlight, trending, latest] = await Promise.all([
2530
getContentDesks().catch(() => null),
31+
getHeroPreview().catch(() => null),
2632
getSpotlight().catch(() => null),
2733
getTrending().catch(() => null),
2834
getLatest().catch(() => null),
2935
]);
3036

3137
return (
3238
<>
33-
<Hero />
39+
<Hero stories={heroPreview ?? undefined} />
3440
<Impact />
3541
<Spotlight
3642
stories={

components/home/Hero.tsx

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,10 @@ import { DateRow } from "@/components/ui/MetaRow";
1010
import { Container } from "@/components/ui/SectionHeading";
1111
import { HERO, HERO_PREVIEW, type Story } from "@/lib/home-content";
1212

13+
interface HeroProps {
14+
stories?: Story[];
15+
}
16+
1317
const HERO_GRADIENT =
1418
"linear-gradient(100.768deg, rgba(4, 26, 109, 0.9) 45.439%, rgba(102, 102, 102, 0) 66.403%)";
1519

@@ -49,7 +53,8 @@ function calcDotCount(s: SwiperType): number {
4953
return Math.max(1, s.slides.length - visible + 1);
5054
}
5155

52-
export function Hero() {
56+
export function Hero({ stories }: HeroProps = {}) {
57+
const preview = stories?.length ? stories : HERO_PREVIEW;
5358
const [swiperInstance, setSwiperInstance] = useState<SwiperType | null>(null);
5459
const [activeIndex, setActiveIndex] = useState(0);
5560
const [dotCount, setDotCount] = useState(0);
@@ -110,7 +115,7 @@ export function Hero() {
110115
onRealIndexChange={(s: SwiperType) => setActiveIndex(s.realIndex)}
111116
onResize={(s: SwiperType) => setDotCount(calcDotCount(s))}
112117
>
113-
{HERO_PREVIEW.map((story) => (
118+
{preview.map((story) => (
114119
<SwiperSlide
115120
key={`${story.image}-${story.date}`}
116121
className="!w-auto"
@@ -122,7 +127,7 @@ export function Hero() {
122127
</div>
123128

124129
<div className={`mt-4 flex items-center gap-2 ${INDENT}`}>
125-
{HERO_PREVIEW.slice(0, dotCount).map((story, i) => (
130+
{preview.slice(0, dotCount).map((story, i) => (
126131
<button
127132
key={`dot-${story.image}-${story.date}`}
128133
type="button"

lib/data/stories.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,3 +59,7 @@ export function getTrending(): Promise<Story[]> {
5959
export function getLatest(): Promise<Story[]> {
6060
return getContentListStories("Top news");
6161
}
62+
63+
export function getHeroPreview(): Promise<Story[]> {
64+
return getContentListStories("Homepage — Hero");
65+
}

0 commit comments

Comments
 (0)