From e75beaac4828a042e71b8f5b2dd4bc942b78717f Mon Sep 17 00:00:00 2001 From: Vishesh 'ironeagle' Bangotra Date: Wed, 12 Nov 2025 04:43:21 +0530 Subject: [PATCH] using ArticleCards of various sizes of 6,4,2 instead of hardcoded repeated code --- .../ArticleCards/ArticleCardSize2.tsx | 126 ++++++++++ .../ArticleCards/ArticleCardSize4.tsx | 122 +++++++++ .../ArticleCards/ArticleCardSize6.tsx | 123 +++++++++ src/blog/components/MainContent.tsx | 233 ++++-------------- src/blog/types/props.ts | 11 + 5 files changed, 427 insertions(+), 188 deletions(-) create mode 100644 src/blog/components/ArticleCards/ArticleCardSize2.tsx create mode 100644 src/blog/components/ArticleCards/ArticleCardSize4.tsx create mode 100644 src/blog/components/ArticleCards/ArticleCardSize6.tsx diff --git a/src/blog/components/ArticleCards/ArticleCardSize2.tsx b/src/blog/components/ArticleCards/ArticleCardSize2.tsx new file mode 100644 index 0000000..5a5170b --- /dev/null +++ b/src/blog/components/ArticleCards/ArticleCardSize2.tsx @@ -0,0 +1,126 @@ +import React from 'react'; +import { Typography } from '@mui/material'; +import Box from "@mui/material/Box"; +import AvatarGroup from "@mui/material/AvatarGroup"; +import Avatar from "@mui/material/Avatar"; +import { styled } from "@mui/material/styles"; +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import { ArticleCardProps } from "../../types/props"; + + +const StyledCard = styled(Card)(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + padding: 0, + height: '100%', + backgroundColor: (theme.vars || theme).palette.background.paper, + '&:hover': { + backgroundColor: 'transparent', + cursor: 'pointer', + }, + '&:focus-visible': { + outline: '3px solid', + outlineColor: 'hsla(210, 98%, 48%, 0.5)', + outlineOffset: '2px', + }, +})); + +const StyledCardContent = styled(CardContent)({ + display: 'flex', + flexDirection: 'column', + gap: 4, + padding: 16, + flexGrow: 1, + '&:last-child': { + paddingBottom: 16, + }, +}); + +const StyledTypography = styled(Typography)({ + display: '-webkit-box', + WebkitBoxOrient: 'vertical', + WebkitLineClamp: 2, + overflow: 'hidden', + textOverflow: 'ellipsis', +}); + +function Author({ authors }: { authors: { name: string; avatar: string }[] }) { + return ( + + + + {authors.map((author, index) => ( + + ))} + + + {authors.map((author) => author.name).join(', ')} + + + July 14, 2021 + + ); +} + +export default function ArticleCardSize2({ + article, + index, + focusedCardIndex, + onSelectArticle, + onFocus, + onBlur, +}: ArticleCardProps) { + return ( + onSelectArticle(index)} + onFocus={() => onFocus(index)} + onBlur={onBlur} + tabIndex={0} + className={focusedCardIndex === index ? 'Mui-focused' : ''} + > + +
+ + {article.tag} + + + {article.title} + + + {article.description} + +
+
+ +
+ ); +}; diff --git a/src/blog/components/ArticleCards/ArticleCardSize4.tsx b/src/blog/components/ArticleCards/ArticleCardSize4.tsx new file mode 100644 index 0000000..83a8cad --- /dev/null +++ b/src/blog/components/ArticleCards/ArticleCardSize4.tsx @@ -0,0 +1,122 @@ +import React from 'react'; +import { CardMedia, Typography } from '@mui/material'; +import Box from "@mui/material/Box"; +import AvatarGroup from "@mui/material/AvatarGroup"; +import Avatar from "@mui/material/Avatar"; +import { styled } from "@mui/material/styles"; +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import { ArticleCardProps } from "../../types/props"; + + +const StyledCard = styled(Card)(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + padding: 0, + height: '100%', + backgroundColor: (theme.vars || theme).palette.background.paper, + '&:hover': { + backgroundColor: 'transparent', + cursor: 'pointer', + }, + '&:focus-visible': { + outline: '3px solid', + outlineColor: 'hsla(210, 98%, 48%, 0.5)', + outlineOffset: '2px', + }, +})); + +const StyledCardContent = styled(CardContent)({ + display: 'flex', + flexDirection: 'column', + gap: 4, + padding: 16, + flexGrow: 1, + '&:last-child': { + paddingBottom: 16, + }, +}); + +const StyledTypography = styled(Typography)({ + display: '-webkit-box', + WebkitBoxOrient: 'vertical', + WebkitLineClamp: 2, + overflow: 'hidden', + textOverflow: 'ellipsis', +}); + +function Author({ authors }: { authors: { name: string; avatar: string }[] }) { + return ( + + + + {authors.map((author, index) => ( + + ))} + + + {authors.map((author) => author.name).join(', ')} + + + July 14, 2021 + + ); +} + +export default function ArticleCardSize4({ + article, + index, + focusedCardIndex, + onSelectArticle, + onFocus, + onBlur, +}: ArticleCardProps) { + return ( + onSelectArticle(index)} + onFocus={() => onFocus(index)} + onBlur={onBlur} + tabIndex={0} + className={focusedCardIndex === index ? 'Mui-focused' : ''} + > + + + + {article.tag} + + + {article.title} + + + {article.description} + + + + + ); +}; diff --git a/src/blog/components/ArticleCards/ArticleCardSize6.tsx b/src/blog/components/ArticleCards/ArticleCardSize6.tsx new file mode 100644 index 0000000..656de05 --- /dev/null +++ b/src/blog/components/ArticleCards/ArticleCardSize6.tsx @@ -0,0 +1,123 @@ +import React from 'react'; +import { CardMedia, Typography } from '@mui/material'; +import Box from "@mui/material/Box"; +import AvatarGroup from "@mui/material/AvatarGroup"; +import Avatar from "@mui/material/Avatar"; +import { styled } from "@mui/material/styles"; +import Card from "@mui/material/Card"; +import CardContent from "@mui/material/CardContent"; +import { ArticleCardProps } from "../../types/props"; + + +const StyledCard = styled(Card)(({ theme }) => ({ + display: 'flex', + flexDirection: 'column', + padding: 0, + height: '100%', + backgroundColor: (theme.vars || theme).palette.background.paper, + '&:hover': { + backgroundColor: 'transparent', + cursor: 'pointer', + }, + '&:focus-visible': { + outline: '3px solid', + outlineColor: 'hsla(210, 98%, 48%, 0.5)', + outlineOffset: '2px', + }, +})); + +const StyledCardContent = styled(CardContent)({ + display: 'flex', + flexDirection: 'column', + gap: 4, + padding: 16, + flexGrow: 1, + '&:last-child': { + paddingBottom: 16, + }, +}); + +const StyledTypography = styled(Typography)({ + display: '-webkit-box', + WebkitBoxOrient: 'vertical', + WebkitLineClamp: 2, + overflow: 'hidden', + textOverflow: 'ellipsis', +}); + +function Author({ authors }: { authors: { name: string; avatar: string }[] }) { + return ( + + + + {authors.map((author, index) => ( + + ))} + + + {authors.map((author) => author.name).join(', ')} + + + July 14, 2021 + + ); +} + +export default function ArticleCardSize6({ + article, + index, + focusedCardIndex, + onSelectArticle, + onFocus, + onBlur, +}: ArticleCardProps) { + return ( + onSelectArticle(index)} + onFocus={() => onFocus(index)} + onBlur={onBlur} + tabIndex={0} + className={focusedCardIndex === index ? 'Mui-focused' : ''} + > + + + + {article.tag} + + + {article.title} + + + {article.description} + + + + + ); +}; diff --git a/src/blog/components/MainContent.tsx b/src/blog/components/MainContent.tsx index 360497c..4195318 100644 --- a/src/blog/components/MainContent.tsx +++ b/src/blog/components/MainContent.tsx @@ -17,6 +17,9 @@ import SearchRoundedIcon from '@mui/icons-material/SearchRounded'; import RssFeedRoundedIcon from '@mui/icons-material/RssFeedRounded'; import { ArticleModel } from "../types/models"; +import ArticleCardSize6 from "./ArticleCards/ArticleCardSize6"; +import ArticleCardSize4 from "./ArticleCards/ArticleCardSize4"; +import ArticleCardSize2 from "./ArticleCards/ArticleCardSize2"; const StyledCard = styled(Card)(({ theme }) => ({ @@ -274,212 +277,66 @@ export default function MainContent({ - onSelectArticle(0)} - onFocus={() => handleFocus(0)} + - - - - {visibleArticles[0].tag} - - - {visibleArticles[0].title} - - - {visibleArticles[0].description} - - - - + /> - onSelectArticle(1)} - onFocus={() => handleFocus(1)} + - - - - {visibleArticles[1].tag} - - - {visibleArticles[1].title} - - - {visibleArticles[1].description} - - - - + /> - onSelectArticle(2)} - onFocus={() => handleFocus(2)} + - - - - {visibleArticles[2].tag} - - - {visibleArticles[2].title} - - - {visibleArticles[2].description} - - - - + /> - onSelectArticle(3)} - onFocus={() => handleFocus(3)} + - -
- - {visibleArticles[3].tag} - - - {visibleArticles[3].title} - - - {visibleArticles[3].description} - -
-
- -
- onSelectArticle(4)} - onFocus={() => handleFocus(4)} + /> + - -
- - {visibleArticles[4].tag} - - - {visibleArticles[4].title} - - - {visibleArticles[4].description} - -
-
- -
+ />
- onSelectArticle(5)} - onFocus={() => handleFocus(5)} + - - - - {visibleArticles[5].tag} - - - {visibleArticles[5].title} - - - {visibleArticles[5].description} - - - - + />
diff --git a/src/blog/types/props.ts b/src/blog/types/props.ts index 91cb30c..115b2cc 100644 --- a/src/blog/types/props.ts +++ b/src/blog/types/props.ts @@ -1,4 +1,6 @@ import { ArticleModel } from "./models"; +import {styled} from "@mui/material/styles"; +import Card from "@mui/material/Card"; export interface LatestProps { articles: ArticleModel[]; @@ -10,3 +12,12 @@ export interface ArticleProps { article: ArticleModel; onBack: () => void; } + +export interface ArticleCardProps { + article: ArticleModel; + index: number; + focusedCardIndex: number | null; + onSelectArticle: (index: number) => void; + onFocus: (index: number) => void; + onBlur: () => void; +}