Distribute advertisements across the homepage content grid

Update the homepage grid layout to intersperse advertisements among articles, add unique keys to grid items to prevent duplicate key warnings, and adjust grid padding for better visual presentation.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 517dfa7b-26ac-463d-a6e1-a58c6df97188
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: eb989520-c882-4176-8405-ca5d6ee6d1c3
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/f209e72a-0939-48fa-84fc-57854de71967/517dfa7b-26ac-463d-a6e1-a58c6df97188/nFw7xof
Replit-Helium-Checkpoint-Created: true
This commit is contained in:
sebastjanartic 2026-03-02 16:52:24 +00:00
parent 4b5b3e5d97
commit 1ece209d7f
2 changed files with 567 additions and 554 deletions

View File

@ -482,29 +482,44 @@ export default function Home() {
}, []);
const gridItems = useMemo(() => {
const items: { type: "article" | "widget"; article?: Article; widget?: typeof widgets[0] }[] = [];
const items: { type: "article" | "widget" | "ad"; key: string; article?: Article; widget?: typeof widgets[0] }[] = [];
let ai = 0;
let wi = 0;
const widgetRows = Math.ceil(widgets.length / 2);
for (let r = 0; r < widgetRows; r++) {
if (ai < shuffled.length) items.push({ type: "article", article: shuffled[ai++] });
if (ai < shuffled.length) items.push({ type: "article", article: shuffled[ai++] });
if (wi < widgets.length) items.push({ type: "widget", widget: widgets[wi++] });
if (wi < widgets.length) items.push({ type: "widget", widget: widgets[wi++] });
else if (ai < shuffled.length) items.push({ type: "article", article: shuffled[ai++] });
if (ai < shuffled.length) items.push({ type: "article", key: `a-${shuffled[ai].id}`, article: shuffled[ai++] });
if (ai < shuffled.length) items.push({ type: "article", key: `a-${shuffled[ai].id}`, article: shuffled[ai++] });
if (wi < widgets.length) items.push({ type: "widget", key: `w-${widgets[wi].id}`, widget: widgets[wi++] });
if (wi < widgets.length) items.push({ type: "widget", key: `w-${widgets[wi].id}`, widget: widgets[wi++] });
else if (ai < shuffled.length) items.push({ type: "article", key: `a-${shuffled[ai].id}`, article: shuffled[ai++] });
}
while (ai < shuffled.length) {
items.push({ type: "article", article: shuffled[ai++] });
items.push({ type: "article", key: `a-${shuffled[ai].id}`, article: shuffled[ai++] });
}
const totalSlots = Math.ceil(items.length / 4) * 4;
let fill = 0;
while (items.length < totalSlots && shuffled.length > 0) {
items.push({ type: "article", article: shuffled[fill % shuffled.length] });
fill++;
const adPositions = [3, 9, 17, 23];
let adIdx = 0;
for (const pos of adPositions) {
if (pos <= items.length) {
items.splice(pos, 0, { type: "ad", key: `ad-${adIdx++}` });
}
}
const remainder = items.length % 4;
if (remainder > 0 && shuffled.length > 0) {
let fill = 0;
const usedIds = new Set(items.filter(i => i.article).map(i => i.article!.id));
const fillPool = shuffled.filter(a => !usedIds.has(a.id));
while (items.length % 4 !== 0) {
const src = fillPool.length > 0 ? fillPool : shuffled;
const art = src[fill % src.length];
items.push({ type: "article", key: `fill-${fill}`, article: art });
fill++;
}
}
return items;
}, [shuffled, widgets]);
@ -578,23 +593,21 @@ export default function Home() {
</div>
{gridRows.map((row, ri) => (
<div key={ri} className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
{row.map((item, ci) =>
<div key={`row-${ri}`} className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
{row.map((item) =>
item.type === "widget"
? item.widget!.el
: item.article
? <MediumCard key={item.article.id} article={item.article} focalPoints={focalPoints} />
: null
? <div key={item.key}>{item.widget!.el}</div>
: item.type === "ad"
? <div key={item.key} data-testid={`ad-grid-${item.key}`}><ArticleCardAd /></div>
: item.article
? <MediumCard key={item.key} article={item.article} focalPoints={focalPoints} />
: null
)}
{ri === gridRows.length - 1 && widePickedArticles.length > 0 && (
<>
<div className="sm:col-span-2">
<WideCard article={widePickedArticles[0]} focalPoints={focalPoints} />
</div>
<div className="sm:col-span-2">
<ArticleCardAd />
</div>
</>
<div className="sm:col-span-2 lg:col-span-4 grid grid-cols-1 sm:grid-cols-2 gap-4">
<WideCard article={widePickedArticles[0]} focalPoints={focalPoints} />
{widePickedArticles[1] && <WideCard article={widePickedArticles[1]} focalPoints={focalPoints} />}
</div>
)}
</div>
))}

File diff suppressed because it is too large Load Diff