Randomize widget and article order on page load

Imports `useMemo` and modifies the `Home` component to shuffle articles and widgets on each page render, ensuring a dynamic layout with varying content order.

Replit-Commit-Author: Agent
Replit-Commit-Session-Id: 517dfa7b-26ac-463d-a6e1-a58c6df97188
Replit-Commit-Checkpoint-Type: full_checkpoint
Replit-Commit-Event-Id: b9c72571-78fc-44d0-974e-6caa91a30a88
Replit-Commit-Screenshot-Url: https://storage.googleapis.com/screenshot-production-us-central1/f209e72a-0939-48fa-84fc-57854de71967/517dfa7b-26ac-463d-a6e1-a58c6df97188/0ZGabQy
Replit-Helium-Checkpoint-Created: true
This commit is contained in:
sebastjanartic 2026-02-28 22:07:31 +00:00
parent 95cad398b3
commit a2dc9f36d9

View File

@ -13,7 +13,7 @@ import { HoroscopeWidget } from "@/components/horoscope-widget";
import { RecipeWidget } from "@/components/recipe-widget";
import { NewsWidget } from "@/components/news-widget";
import { WeatherWidget } from "@/components/weather-widget";
import { useState, useEffect, useCallback, useRef } from "react";
import { useState, useEffect, useCallback, useRef, useMemo } from "react";
function useFocalPoints() {
const { data } = useQuery<Record<string, { x: number; y: number }>>({
@ -413,9 +413,54 @@ export default function Home() {
);
}
const row2 = articles.slice(0, 2);
const row3 = articles.slice(2, 4);
const remaining = articles.slice(4);
const shuffled = useMemo(() => {
const arr = [...articles];
for (let i = arr.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[arr[i], arr[j]] = [arr[j], arr[i]];
}
return arr;
}, [articles]);
const widgets = useMemo(() => {
const w = [
{ id: "recipe", el: <RecipeWidget key="recipe" /> },
{ id: "horoscope-weather", el: <div key="horoscope-weather" className="flex flex-col gap-4"><HoroscopeWidget /><WeatherWidget /></div> },
{ id: "gallery", el: <PhotoGalleryWidget key="gallery" /> },
{ id: "news", el: <div key="news" className="flex flex-col gap-4"><NewsWidget /></div> },
];
for (let i = w.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[w[i], w[j]] = [w[j], w[i]];
}
return w;
}, []);
const gridItems = useMemo(() => {
const items: { type: "article" | "widget"; article?: Article; widget?: typeof widgets[0] }[] = [];
let ai = 0;
let wi = 0;
items.push({ type: "article", article: shuffled[ai++] });
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++] });
items.push({ type: "article", article: shuffled[ai++] });
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++] });
while (ai < shuffled.length) {
items.push({ type: "article", article: shuffled[ai++] });
}
return items;
}, [shuffled, widgets]);
const gridRows: (typeof gridItems)[] = [];
for (let i = 0; i < gridItems.length; i += 4) {
gridRows.push(gridItems.slice(i, i + 4));
}
return (
<div className="min-h-screen bg-background">
@ -424,34 +469,17 @@ export default function Home() {
<FeaturedCarousel articles={articles} popular={popular} galleryImages={galleryImages} focalPoints={focalPoints} />
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
{row2.map((a) => (
<MediumCard key={a.id} article={a} focalPoints={focalPoints} />
))}
<RecipeWidget />
<div className="flex flex-col gap-4">
<HoroscopeWidget />
<WeatherWidget />
{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) =>
item.type === "widget"
? item.widget!.el
: item.article
? <MediumCard key={item.article.id} article={item.article} focalPoints={focalPoints} />
: null
)}
</div>
</div>
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
{row3.map((a) => (
<MediumCard key={a.id} article={a} focalPoints={focalPoints} />
))}
<PhotoGalleryWidget />
<div className="flex flex-col gap-4">
<NewsWidget />
</div>
</div>
{remaining.length > 0 && (
<div className="grid grid-cols-1 sm:grid-cols-2 lg:grid-cols-4 gap-4">
{remaining.map((a) => (
<MediumCard key={a.id} article={a} focalPoints={focalPoints} />
))}
</div>
)}
))}
</main>
<Footer />