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:
parent
95cad398b3
commit
a2dc9f36d9
@ -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 />
|
||||
|
||||
Loading…
Reference in New Issue
Block a user