diff --git a/client/src/pages/home.tsx b/client/src/pages/home.tsx index dd55be9..7749963 100644 --- a/client/src/pages/home.tsx +++ b/client/src/pages/home.tsx @@ -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>({ @@ -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: }, + { id: "horoscope-weather", el:
}, + { id: "gallery", el: }, + { id: "news", el:
}, + ]; + 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 (
@@ -424,34 +469,17 @@ export default function Home() { -
- {row2.map((a) => ( - - ))} - -
- - + {gridRows.map((row, ri) => ( +
+ {row.map((item, ci) => + item.type === "widget" + ? item.widget!.el + : item.article + ? + : null + )}
-
- -
- {row3.map((a) => ( - - ))} - -
- -
-
- - {remaining.length > 0 && ( -
- {remaining.map((a) => ( - - ))} -
- )} + ))}