working mvp for tag selection. fails when not enough articles for a particular tag

This commit is contained in:
2025-11-12 04:19:41 +05:30
parent 6abdd443e0
commit 6d951b9ab5
2 changed files with 97 additions and 49 deletions

View File

@@ -16,6 +16,8 @@ import { styled } from '@mui/material/styles';
import SearchRoundedIcon from '@mui/icons-material/SearchRounded';
import RssFeedRoundedIcon from '@mui/icons-material/RssFeedRounded';
import { ArticleModel } from "../types/models";
const StyledCard = styled(Card)(({ theme }) => ({
display: 'flex',
@@ -119,6 +121,33 @@ export default function MainContent({
null,
);
const [visibleArticles, setVisibleArticles] = React.useState<ArticleModel[]>(articles);
const [activeTag, setActiveTag] = React.useState<string | null>(null);
const filterArticlesByTag = (tag: string) => {
if (tag === 'all') {
// 🟢 Show all articles
setVisibleArticles(articles);
setActiveTag('all');
return;
}
if (activeTag === tag) {
// 🟡 Toggle off current tag → reset to all
setVisibleArticles(articles);
setActiveTag('all');
return;
}
// 🔵 Filter by selected tag
const filtered = articles.filter((article) => article.tag === tag);
console.log('👀 All Articles:', articles);
console.log(`👀 Filtered (${tag}):`, filtered);
setVisibleArticles(filtered);
setActiveTag(tag);
};
const handleFocus = (index: number) => {
setFocusedCardIndex(index);
};
@@ -127,8 +156,9 @@ export default function MainContent({
setFocusedCardIndex(null);
};
const handleClick = () => {
console.info('You clicked the filter chip.');
const handleTagClick = (tag: string) => {
setActiveTag((prev) => (prev === tag ? 'all' : tag));
filterArticlesByTag(tag)
};
return (
@@ -171,41 +201,59 @@ export default function MainContent({
overflow: 'auto',
}}
>
<Chip onClick={handleClick} size="medium" label="All categories" />
<Chip
onClick={handleClick}
onClick={() => handleTagClick('all')}
size="medium"
label="Company"
label="All categories"
color={activeTag === 'all' ? 'primary' : 'default'}
variant={activeTag === 'all' ? 'filled' : 'outlined'}
sx={{
backgroundColor: 'transparent',
border: 'none',
borderRadius: '8px',
fontWeight: activeTag === 'all' ? 600 : 400,
}}
/>
<Chip
onClick={handleClick}
onClick={() => handleTagClick('infra')}
size="medium"
label="Product"
label="Infra"
color={activeTag === 'infra' ? 'primary' : 'default'}
variant={activeTag === 'infra' ? 'filled' : 'outlined'}
sx={{
backgroundColor: 'transparent',
border: 'none',
borderRadius: '8px',
fontWeight: activeTag === 'infra' ? 600 : 400,
}}
/>
<Chip
onClick={handleClick}
onClick={() => handleTagClick('code')}
size="medium"
label="Design"
label="Code"
color={activeTag === 'code' ? 'primary' : 'default'}
variant={activeTag === 'code' ? 'filled' : 'outlined'}
sx={{
backgroundColor: 'transparent',
border: 'none',
borderRadius: '8px',
fontWeight: activeTag === 'code' ? 600 : 400,
}}
/>
<Chip
onClick={handleClick}
onClick={() => handleTagClick('media')}
size="medium"
label="Engineering"
label="Media"
color={activeTag === 'media' ? 'primary' : 'default'}
variant={activeTag === 'media' ? 'filled' : 'outlined'}
sx={{
backgroundColor: 'transparent',
border: 'none',
borderRadius: '8px',
fontWeight: activeTag === 'media' ? 600 : 400,
}}
/>
<Chip
onClick={() => handleTagClick('monitoring')}
size="medium"
label="Monitoring"
color={activeTag === 'monitoring' ? 'primary' : 'default'}
variant={activeTag === 'monitoring' ? 'filled' : 'outlined'}
sx={{
borderRadius: '8px',
fontWeight: activeTag === 'all' ? 600 : 400,
}}
/>
</Box>
@@ -237,7 +285,7 @@ export default function MainContent({
<CardMedia
component="img"
alt="green iguana"
image={articles[0].img}
image={visibleArticles[0].img}
sx={{
aspectRatio: '16 / 9',
borderBottom: '1px solid',
@@ -246,16 +294,16 @@ export default function MainContent({
/>
<StyledCardContent>
<Typography gutterBottom variant="caption" component="div">
{articles[0].tag}
{visibleArticles[0].tag}
</Typography>
<Typography gutterBottom variant="h6" component="div">
{articles[0].title}
{visibleArticles[0].title}
</Typography>
<StyledTypography variant="body2" color="text.secondary" gutterBottom>
{articles[0].description}
{visibleArticles[0].description}
</StyledTypography>
</StyledCardContent>
<Author authors={articles[0].authors} />
<Author authors={visibleArticles[0].authors} />
</StyledCard>
</Grid>
<Grid size={{ xs: 12, md: 6 }}>
@@ -270,7 +318,7 @@ export default function MainContent({
<CardMedia
component="img"
alt="green iguana"
image={articles[1].img}
image={visibleArticles[1].img}
aspect-ratio="16 / 9"
sx={{
borderBottom: '1px solid',
@@ -279,16 +327,16 @@ export default function MainContent({
/>
<StyledCardContent>
<Typography gutterBottom variant="caption" component="div">
{articles[1].tag}
{visibleArticles[1].tag}
</Typography>
<Typography gutterBottom variant="h6" component="div">
{articles[1].title}
{visibleArticles[1].title}
</Typography>
<StyledTypography variant="body2" color="text.secondary" gutterBottom>
{articles[1].description}
{visibleArticles[1].description}
</StyledTypography>
</StyledCardContent>
<Author authors={articles[1].authors} />
<Author authors={visibleArticles[1].authors} />
</StyledCard>
</Grid>
<Grid size={{ xs: 12, md: 4 }}>
@@ -304,7 +352,7 @@ export default function MainContent({
<CardMedia
component="img"
alt="green iguana"
image={articles[2].img}
image={visibleArticles[2].img}
sx={{
height: { sm: 'auto', md: '50%' },
aspectRatio: { sm: '16 / 9', md: '' },
@@ -312,16 +360,16 @@ export default function MainContent({
/>
<StyledCardContent>
<Typography gutterBottom variant="caption" component="div">
{articles[2].tag}
{visibleArticles[2].tag}
</Typography>
<Typography gutterBottom variant="h6" component="div">
{articles[2].title}
{visibleArticles[2].title}
</Typography>
<StyledTypography variant="body2" color="text.secondary" gutterBottom>
{articles[2].description}
{visibleArticles[2].description}
</StyledTypography>
</StyledCardContent>
<Author authors={articles[2].authors} />
<Author authors={visibleArticles[2].authors} />
</StyledCard>
</Grid>
<Grid size={{ xs: 12, md: 4 }}>
@@ -347,21 +395,21 @@ export default function MainContent({
>
<div>
<Typography gutterBottom variant="caption" component="div">
{articles[3].tag}
{visibleArticles[3].tag}
</Typography>
<Typography gutterBottom variant="h6" component="div">
{articles[3].title}
{visibleArticles[3].title}
</Typography>
<StyledTypography
variant="body2"
color="text.secondary"
gutterBottom
>
{articles[3].description}
{visibleArticles[3].description}
</StyledTypography>
</div>
</StyledCardContent>
<Author authors={articles[3].authors} />
<Author authors={visibleArticles[3].authors} />
</StyledCard>
<StyledCard
variant="outlined"
@@ -382,21 +430,21 @@ export default function MainContent({
>
<div>
<Typography gutterBottom variant="caption" component="div">
{articles[4].tag}
{visibleArticles[4].tag}
</Typography>
<Typography gutterBottom variant="h6" component="div">
{articles[4].title}
{visibleArticles[4].title}
</Typography>
<StyledTypography
variant="body2"
color="text.secondary"
gutterBottom
>
{articles[4].description}
{visibleArticles[4].description}
</StyledTypography>
</div>
</StyledCardContent>
<Author authors={articles[4].authors} />
<Author authors={visibleArticles[4].authors} />
</StyledCard>
</Box>
</Grid>
@@ -413,7 +461,7 @@ export default function MainContent({
<CardMedia
component="img"
alt="green iguana"
image={articles[5].img}
image={visibleArticles[5].img}
sx={{
height: { sm: 'auto', md: '50%' },
aspectRatio: { sm: '16 / 9', md: '' },
@@ -421,16 +469,16 @@ export default function MainContent({
/>
<StyledCardContent>
<Typography gutterBottom variant="caption" component="div">
{articles[5].tag}
{visibleArticles[5].tag}
</Typography>
<Typography gutterBottom variant="h6" component="div">
{articles[5].title}
{visibleArticles[5].title}
</Typography>
<StyledTypography variant="body2" color="text.secondary" gutterBottom>
{articles[5].description}
{visibleArticles[5].description}
</StyledTypography>
</StyledCardContent>
<Author authors={articles[5].authors} />
<Author authors={visibleArticles[5].authors} />
</StyledCard>
</Grid>
</Grid>

View File

@@ -10,7 +10,7 @@ export const ArticleProvider: React.FC<{ children: React.ReactNode }> = ({ child
const [articles, setArticles] = useState<ArticleModel[]>([]);
const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null);
const { token } = useAuth(); // ✅ access token if needed
const { token } = useAuth();
/** 🔹 Fetch articles (JWT automatically attached by api.ts interceptor) */
const fetchArticles = async () => {
@@ -18,7 +18,7 @@ export const ArticleProvider: React.FC<{ children: React.ReactNode }> = ({ child
setLoading(true);
setError(null);
const res = await api.get<ArticleModel[]>('/articles', { params: { skip: 0, limit: 10 } });
const res = await api.get<ArticleModel[]>('/articles', { params: { skip: 0, limit: 100 } });
const formatted = res.data.map((a) => ({ ...a, id: a._id || undefined }));
setArticles(formatted);
} catch (err: any) {