From b09900f8ec668c78a72003e38ec54ef135ed9bcc Mon Sep 17 00:00:00 2001 From: Vishesh 'ironeagle' Bangotra Date: Wed, 12 Nov 2025 05:06:29 +0530 Subject: [PATCH] dynamic listing of top 6 or less upto 2 articles --- .../ArticleCards/ArticleCardsGrid.tsx | 190 +++++++++++------- src/blog/types/props.ts | 9 + 2 files changed, 125 insertions(+), 74 deletions(-) diff --git a/src/blog/components/ArticleCards/ArticleCardsGrid.tsx b/src/blog/components/ArticleCards/ArticleCardsGrid.tsx index d59e459..fcea26f 100644 --- a/src/blog/components/ArticleCards/ArticleCardsGrid.tsx +++ b/src/blog/components/ArticleCards/ArticleCardsGrid.tsx @@ -1,20 +1,23 @@ -import * as React from 'react'; -import Box from '@mui/material/Box'; -import Grid from '@mui/material/Grid'; - +import React from 'react'; +import { Grid, Box } from '@mui/material'; +import ArticleCardSize6 from './ArticleCardSize6'; +import ArticleCardSize4 from './ArticleCardSize4'; +import ArticleCardSize2 from './ArticleCardSize2'; import { ArticleModel } from "../../types/models"; -import ArticleCardSize6 from "../ArticleCards/ArticleCardSize6"; -import ArticleCardSize4 from "../ArticleCards/ArticleCardSize4"; -import ArticleCardSize2 from "../ArticleCards/ArticleCardSize2"; - +import { ArticleGridProps } from "../../types/props"; export default function ArticleCardsGrid({ articles, onSelectArticle, -}: { - articles: any[]; - onSelectArticle: (index: number) => void; -}) { + xs = 12, + md6 = 6, + md4 = 4, + nested = 2, +}: ArticleGridProps ) { + + const visibleArticles = articles.slice(0, 6) + const count = visibleArticles.length; + const [focusedCardIndex, setFocusedCardIndex] = React.useState( null, ); @@ -27,70 +30,109 @@ export default function ArticleCardsGrid({ setFocusedCardIndex(null); }; + const renderCard = (article: ArticleModel, index: number, type: '6' | '4' | '2' = '6') => { + const CardComponent = + type === '6' ? ArticleCardSize6 : + type === '4' ? ArticleCardSize4 : + ArticleCardSize2; + + return ( + + ); + }; + return ( - - - - - - - - - - - - - - - - - - + {/* ---- 2 articles: 6 | 6 ---- */} + {count === 2 && ( + <> + {visibleArticles.map((a, i) => ( + + {renderCard(a, i, '6')} + + ))} + + )} + + {/* ---- 3 articles: 4 | 4 | 4 ---- */} + {count === 3 && ( + <> + {visibleArticles.map((a, i) => ( + + {renderCard(a, i, '4')} + + ))} + + )} + + {/* ---- 4 articles: (6|6) + (6|6) ---- */} + {count === 4 && ( + <> + {visibleArticles.map((a, i) => ( + + {renderCard(a, i, '6')} + + ))} + + )} + + {/* ---- 5 articles: (6|6) + (4|4|4) ---- */} + {count === 5 && ( + <> + {/* Row 1: 2 x size6 */} + {visibleArticles.slice(0, 2).map((a, i) => ( + + {renderCard(a, i, '6')} + + ))} + + {/* Row 2: 3 x size4 */} + {visibleArticles.slice(2).map((a, i) => ( + + {renderCard(a, i + 2, '4')} + + ))} + + )} + + {/* ---- 6 articles: (6|6) + (4|2x2|4) ---- */} + {count === 6 && ( + <> + {/* Top row: 2 x size6 */} + {visibleArticles.slice(0, 2).map((a, i) => ( + + {renderCard(a, i, '6')} + + ))} + + {/* Bottom row: 4 + 2x2 + 4 */} + + {renderCard(visibleArticles[2], 2, '4')} + + + + + {visibleArticles.slice(3, 3 + nested).map((a, i) => + renderCard(a, i + 3, '2') + )} + + + + + {renderCard(visibleArticles[5], 5, '4')} + + + )} ); } diff --git a/src/blog/types/props.ts b/src/blog/types/props.ts index 115b2cc..f0b7c3b 100644 --- a/src/blog/types/props.ts +++ b/src/blog/types/props.ts @@ -21,3 +21,12 @@ export interface ArticleCardProps { onFocus: (index: number) => void; onBlur: () => void; } + +export interface ArticleGridProps { + articles: ArticleModel[]; + onSelectArticle: (index: number) => void; + xs?: number; // default 12 for mobile full-width + md6?: number; // default 6 (half-width) + md4?: number; // default 4 (third-width) + nested?: 1 | 2; // number of stacked cards in a nested column +}