using ArticleProvider (with default values for now)

This commit is contained in:
2025-10-28 22:44:43 +05:30
parent a5749d2bc2
commit 38fde1e35d
4 changed files with 212 additions and 157 deletions

View File

@@ -6,77 +6,10 @@ import MainContent from './components/MainContent';
import Article from './components/Article';
import Latest from './components/Latest';
import Footer from './components/Footer';
const cardData = [
{
img: 'https://picsum.photos/800/450?random=1',
tag: 'Engineering',
title: 'Revolutionizing software development with cutting-edge tools',
description:
'Our latest engineering tools are designed to streamline workflows and boost productivity. Discover how these innovations are transforming the software development landscape.',
content:
'Our latest engineering tools are designed to streamline workflows and boost productivity. Discover how these innovations are transforming the software development landscape.',
authors: [
{ name: 'Remy Sharp', avatar: '/static/images/avatar/1.jpg' },
{ name: 'Travis Howard', avatar: '/static/images/avatar/2.jpg' },
],
},
{
img: 'https://picsum.photos/800/450?random=2',
tag: 'Product',
title: 'Innovative product features that drive success',
description:
'Explore the key features of our latest product release that are helping businesses achieve their goals. From user-friendly interfaces to robust functionality, learn why our product stands out.',
content:
'Explore the key features of our latest product release that are helping businesses achieve their goals. From user-friendly interfaces to robust functionality, learn why our product stands out.',
authors: [{ name: 'Erica Johns', avatar: '/static/images/avatar/6.jpg' }],
},
{
img: 'https://picsum.photos/800/450?random=3',
tag: 'Design',
title: 'Designing for the future: trends and insights',
description:
'Stay ahead of the curve with the latest design trends and insights. Our design team shares their expertise on creating intuitive and visually stunning user experiences.',
content:
'Stay ahead of the curve with the latest design trends and insights. Our design team shares their expertise on creating intuitive and visually stunning user experiences.',
authors: [{ name: 'Kate Morrison', avatar: '/static/images/avatar/7.jpg' }],
},
{
img: 'https://picsum.photos/800/450?random=4',
tag: 'Company',
title: "Our company's journey: milestones and achievements",
description:
"Take a look at our company's journey and the milestones we've achieved along the way. From humble beginnings to industry leader, discover our story of growth and success.",
content:
"Take a look at our company's journey and the milestones we've achieved along the way. From humble beginnings to industry leader, discover our story of growth and success.",
authors: [{ name: 'Cindy Baker', avatar: '/static/images/avatar/3.jpg' }],
},
{
img: 'https://picsum.photos/800/450?random=45',
tag: 'Engineering',
title: 'Pioneering sustainable engineering solutions',
description:
"Learn about our commitment to sustainability and the innovative engineering solutions we're implementing to create a greener future. Discover the impact of our eco-friendly initiatives.",
content:
"Learn about our commitment to sustainability and the innovative engineering solutions we're implementing to create a greener future. Discover the impact of our eco-friendly initiatives.",
authors: [
{ name: 'Agnes Walker', avatar: '/static/images/avatar/4.jpg' },
{ name: 'Trevor Henderson', avatar: '/static/images/avatar/5.jpg' },
],
},
{
img: 'https://picsum.photos/800/450?random=6',
tag: 'Product',
title: 'Maximizing efficiency with our latest product updates',
description:
'Our recent product updates are designed to help you maximize efficiency and achieve more. Get a detailed overview of the new features and improvements that can elevate your workflow.',
content:
'Our recent product updates are designed to help you maximize efficiency and achieve more. Get a detailed overview of the new features and improvements that can elevate your workflow.',
authors: [{ name: 'Travis Howard', avatar: '/static/images/avatar/2.jpg' }],
},
];
import { useArticles } from './providers/Article'; // ✅ custom hook for global articles
export default function Blog(props: { disableCustomTheme?: boolean }) {
const { articles, loading, error } = useArticles(); // ✅ Hook must be inside component
const [selectedArticle, setSelectedArticle] = React.useState<number | null>(null);
const handleSelectArticle = (index: number) => {
@@ -86,6 +19,36 @@ export default function Blog(props: { disableCustomTheme?: boolean }) {
const handleBack = () => setSelectedArticle(null);
if (loading) {
return (
<AppTheme {...props}>
<CssBaseline enableColorScheme />
<Container
maxWidth="lg"
component="main"
sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100vh' }}
>
Loading articles...
</Container>
</AppTheme>
);
}
if (error) {
return (
<AppTheme {...props}>
<CssBaseline enableColorScheme />
<Container
maxWidth="lg"
component="main"
sx={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '100vh' }}
>
Failed to load articles: {error}
</Container>
</AppTheme>
);
}
return (
<AppTheme {...props}>
<CssBaseline enableColorScheme />
@@ -96,9 +59,9 @@ export default function Blog(props: { disableCustomTheme?: boolean }) {
sx={{ display: 'flex', flexDirection: 'column', my: 16, gap: 4 }}
>
{selectedArticle === null ? (
<MainContent onSelectArticle={handleSelectArticle} />
<MainContent articles={articles} onSelectArticle={handleSelectArticle} />
) : (
<Article article={cardData[selectedArticle]} onBack={handleBack} />
<Article article={articles[selectedArticle]} onBack={handleBack} />
)}
</Container>
<Footer />

View File

@@ -16,62 +16,7 @@ import { styled } from '@mui/material/styles';
import SearchRoundedIcon from '@mui/icons-material/SearchRounded';
import RssFeedRoundedIcon from '@mui/icons-material/RssFeedRounded';
const cardData = [
{
img: 'https://picsum.photos/800/450?random=1',
tag: 'Engineering',
title: 'Revolutionizing software development with cutting-edge tools',
description:
'Our latest engineering tools are designed to streamline workflows and boost productivity. Discover how these innovations are transforming the software development landscape.',
authors: [
{ name: 'Remy Sharp', avatar: '/static/images/avatar/1.jpg' },
{ name: 'Travis Howard', avatar: '/static/images/avatar/2.jpg' },
],
},
{
img: 'https://picsum.photos/800/450?random=2',
tag: 'Product',
title: 'Innovative product features that drive success',
description:
'Explore the key features of our latest product release that are helping businesses achieve their goals. From user-friendly interfaces to robust functionality, learn why our product stands out.',
authors: [{ name: 'Erica Johns', avatar: '/static/images/avatar/6.jpg' }],
},
{
img: 'https://picsum.photos/800/450?random=3',
tag: 'Design',
title: 'Designing for the future: trends and insights',
description:
'Stay ahead of the curve with the latest design trends and insights. Our design team shares their expertise on creating intuitive and visually stunning user experiences.',
authors: [{ name: 'Kate Morrison', avatar: '/static/images/avatar/7.jpg' }],
},
{
img: 'https://picsum.photos/800/450?random=4',
tag: 'Company',
title: "Our company's journey: milestones and achievements",
description:
"Take a look at our company's journey and the milestones we've achieved along the way. From humble beginnings to industry leader, discover our story of growth and success.",
authors: [{ name: 'Cindy Baker', avatar: '/static/images/avatar/3.jpg' }],
},
{
img: 'https://picsum.photos/800/450?random=45',
tag: 'Engineering',
title: 'Pioneering sustainable engineering solutions',
description:
"Learn about our commitment to sustainability and the innovative engineering solutions we're implementing to create a greener future. Discover the impact of our eco-friendly initiatives.",
authors: [
{ name: 'Agnes Walker', avatar: '/static/images/avatar/4.jpg' },
{ name: 'Trevor Henderson', avatar: '/static/images/avatar/5.jpg' },
],
},
{
img: 'https://picsum.photos/800/450?random=6',
tag: 'Product',
title: 'Maximizing efficiency with our latest product updates',
description:
'Our recent product updates are designed to help you maximize efficiency and achieve more. Get a detailed overview of the new features and improvements that can elevate your workflow.',
authors: [{ name: 'Travis Howard', avatar: '/static/images/avatar/2.jpg' }],
},
];
import { useArticles } from '../providers/Article';
const StyledCard = styled(Card)(({ theme }) => ({
display: 'flex',
@@ -164,7 +109,13 @@ export function Search() {
);
}
export default function MainContent({ onSelectArticle }: { onSelectArticle: (index: number) => void }) {
export default function MainContent({
articles,
onSelectArticle,
}: {
articles: any[];
onSelectArticle: (index: number) => void;
}) {
const [focusedCardIndex, setFocusedCardIndex] = React.useState<number | null>(
null,
);
@@ -288,7 +239,7 @@ export default function MainContent({ onSelectArticle }: { onSelectArticle: (ind
<CardMedia
component="img"
alt="green iguana"
image={cardData[0].img}
image={articles[0].img}
sx={{
aspectRatio: '16 / 9',
borderBottom: '1px solid',
@@ -297,16 +248,16 @@ export default function MainContent({ onSelectArticle }: { onSelectArticle: (ind
/>
<StyledCardContent>
<Typography gutterBottom variant="caption" component="div">
{cardData[0].tag}
{articles[0].tag}
</Typography>
<Typography gutterBottom variant="h6" component="div">
{cardData[0].title}
{articles[0].title}
</Typography>
<StyledTypography variant="body2" color="text.secondary" gutterBottom>
{cardData[0].description}
{articles[0].description}
</StyledTypography>
</StyledCardContent>
<Author authors={cardData[0].authors} />
<Author authors={articles[0].authors} />
</StyledCard>
</Grid>
<Grid size={{ xs: 12, md: 6 }}>
@@ -321,7 +272,7 @@ export default function MainContent({ onSelectArticle }: { onSelectArticle: (ind
<CardMedia
component="img"
alt="green iguana"
image={cardData[1].img}
image={articles[1].img}
aspect-ratio="16 / 9"
sx={{
borderBottom: '1px solid',
@@ -330,16 +281,16 @@ export default function MainContent({ onSelectArticle }: { onSelectArticle: (ind
/>
<StyledCardContent>
<Typography gutterBottom variant="caption" component="div">
{cardData[1].tag}
{articles[1].tag}
</Typography>
<Typography gutterBottom variant="h6" component="div">
{cardData[1].title}
{articles[1].title}
</Typography>
<StyledTypography variant="body2" color="text.secondary" gutterBottom>
{cardData[1].description}
{articles[1].description}
</StyledTypography>
</StyledCardContent>
<Author authors={cardData[1].authors} />
<Author authors={articles[1].authors} />
</StyledCard>
</Grid>
<Grid size={{ xs: 12, md: 4 }}>
@@ -355,7 +306,7 @@ export default function MainContent({ onSelectArticle }: { onSelectArticle: (ind
<CardMedia
component="img"
alt="green iguana"
image={cardData[2].img}
image={articles[2].img}
sx={{
height: { sm: 'auto', md: '50%' },
aspectRatio: { sm: '16 / 9', md: '' },
@@ -363,16 +314,16 @@ export default function MainContent({ onSelectArticle }: { onSelectArticle: (ind
/>
<StyledCardContent>
<Typography gutterBottom variant="caption" component="div">
{cardData[2].tag}
{articles[2].tag}
</Typography>
<Typography gutterBottom variant="h6" component="div">
{cardData[2].title}
{articles[2].title}
</Typography>
<StyledTypography variant="body2" color="text.secondary" gutterBottom>
{cardData[2].description}
{articles[2].description}
</StyledTypography>
</StyledCardContent>
<Author authors={cardData[2].authors} />
<Author authors={articles[2].authors} />
</StyledCard>
</Grid>
<Grid size={{ xs: 12, md: 4 }}>
@@ -398,21 +349,21 @@ export default function MainContent({ onSelectArticle }: { onSelectArticle: (ind
>
<div>
<Typography gutterBottom variant="caption" component="div">
{cardData[3].tag}
{articles[3].tag}
</Typography>
<Typography gutterBottom variant="h6" component="div">
{cardData[3].title}
{articles[3].title}
</Typography>
<StyledTypography
variant="body2"
color="text.secondary"
gutterBottom
>
{cardData[3].description}
{articles[3].description}
</StyledTypography>
</div>
</StyledCardContent>
<Author authors={cardData[3].authors} />
<Author authors={articles[3].authors} />
</StyledCard>
<StyledCard
variant="outlined"
@@ -433,21 +384,21 @@ export default function MainContent({ onSelectArticle }: { onSelectArticle: (ind
>
<div>
<Typography gutterBottom variant="caption" component="div">
{cardData[4].tag}
{articles[4].tag}
</Typography>
<Typography gutterBottom variant="h6" component="div">
{cardData[4].title}
{articles[4].title}
</Typography>
<StyledTypography
variant="body2"
color="text.secondary"
gutterBottom
>
{cardData[4].description}
{articles[4].description}
</StyledTypography>
</div>
</StyledCardContent>
<Author authors={cardData[4].authors} />
<Author authors={articles[4].authors} />
</StyledCard>
</Box>
</Grid>
@@ -464,7 +415,7 @@ export default function MainContent({ onSelectArticle }: { onSelectArticle: (ind
<CardMedia
component="img"
alt="green iguana"
image={cardData[5].img}
image={articles[5].img}
sx={{
height: { sm: 'auto', md: '50%' },
aspectRatio: { sm: '16 / 9', md: '' },
@@ -472,16 +423,16 @@ export default function MainContent({ onSelectArticle }: { onSelectArticle: (ind
/>
<StyledCardContent>
<Typography gutterBottom variant="caption" component="div">
{cardData[5].tag}
{articles[5].tag}
</Typography>
<Typography gutterBottom variant="h6" component="div">
{cardData[5].title}
{articles[5].title}
</Typography>
<StyledTypography variant="body2" color="text.secondary" gutterBottom>
{cardData[5].description}
{articles[5].description}
</StyledTypography>
</StyledCardContent>
<Author authors={cardData[5].authors} />
<Author authors={articles[5].authors} />
</StyledCard>
</Grid>
</Grid>

View File

@@ -0,0 +1,138 @@
import React, { createContext, useState, useContext, useEffect } from 'react';
import axios from 'axios';
interface Author {
name: string;
avatar: string;
}
export interface Article {
id: string;
tag: string;
title: string;
description: string;
img: string;
authors: Author[];
date?: string;
}
interface ArticleContextType {
articles: Article[];
loading: boolean;
error: string | null;
refreshArticles: () => Promise<void>;
}
const Article = createContext<ArticleContextType | undefined>(undefined);
export const ArticleProvider: React.FC<{ children: React.ReactNode }> = ({ children }) => {
const [articles, setArticles] = useState<Article[]>([]);
const [loading, setLoading] = useState<boolean>(true);
const [error, setError] = useState<string | null>(null);
const fetchArticles = async () => {
try {
// ✅ Use static defaults first
const defaults = [
{
img: 'https://picsum.photos/800/450?random=1',
tag: 'Engineering',
title: 'Revolutionizing software development with cutting-edge tools',
description:
'Our latest engineering tools are designed to streamline workflows and boost productivity. Discover how these innovations are transforming the software development landscape.',
content:
'Our latest engineering tools are designed to streamline workflows and boost productivity. Discover how these innovations are transforming the software development landscape.',
authors: [
{ name: 'Remy Sharp', avatar: '/static/images/avatar/1.jpg' },
{ name: 'Travis Howard', avatar: '/static/images/avatar/2.jpg' },
],
},
{
img: 'https://picsum.photos/800/450?random=2',
tag: 'Product',
title: 'Innovative product features that drive success',
description:
'Explore the key features of our latest product release that are helping businesses achieve their goals. From user-friendly interfaces to robust functionality, learn why our product stands out.',
content:
'Explore the key features of our latest product release that are helping businesses achieve their goals. From user-friendly interfaces to robust functionality, learn why our product stands out.',
authors: [{ name: 'Erica Johns', avatar: '/static/images/avatar/6.jpg' }],
},
{
img: 'https://picsum.photos/800/450?random=3',
tag: 'Design',
title: 'Designing for the future: trends and insights',
description:
'Stay ahead of the curve with the latest design trends and insights. Our design team shares their expertise on creating intuitive and visually stunning user experiences.',
content:
'Stay ahead of the curve with the latest design trends and insights. Our design team shares their expertise on creating intuitive and visually stunning user experiences.',
authors: [{ name: 'Kate Morrison', avatar: '/static/images/avatar/7.jpg' }],
},
{
img: 'https://picsum.photos/800/450?random=4',
tag: 'Company',
title: "Our company's journey: milestones and achievements",
description:
"Take a look at our company's journey and the milestones we've achieved along the way. From humble beginnings to industry leader, discover our story of growth and success.",
content:
"Take a look at our company's journey and the milestones we've achieved along the way. From humble beginnings to industry leader, discover our story of growth and success.",
authors: [{ name: 'Cindy Baker', avatar: '/static/images/avatar/3.jpg' }],
},
{
img: 'https://picsum.photos/800/450?random=45',
tag: 'Engineering',
title: 'Pioneering sustainable engineering solutions',
description:
"Learn about our commitment to sustainability and the innovative engineering solutions we're implementing to create a greener future. Discover the impact of our eco-friendly initiatives.",
content:
"Learn about our commitment to sustainability and the innovative engineering solutions we're implementing to create a greener future. Discover the impact of our eco-friendly initiatives.",
authors: [
{ name: 'Agnes Walker', avatar: '/static/images/avatar/4.jpg' },
{ name: 'Trevor Henderson', avatar: '/static/images/avatar/5.jpg' },
],
},
{
img: 'https://picsum.photos/800/450?random=6',
tag: 'Product',
title: 'Maximizing efficiency with our latest product updates',
description:
'Our recent product updates are designed to help you maximize efficiency and achieve more. Get a detailed overview of the new features and improvements that can elevate your workflow.',
content:
'Our recent product updates are designed to help you maximize efficiency and achieve more. Get a detailed overview of the new features and improvements that can elevate your workflow.',
authors: [{ name: 'Travis Howard', avatar: '/static/images/avatar/2.jpg' }],
},
];
// ✅ For now: only use defaults
// @ts-ignore
setArticles(defaults);
setLoading(false);
// 🔜 Optional: uncomment this to fetch from API when backend is ready
/*
setLoading(true);
const res = await axios.get('/articles');
setArticles(res.data);
*/
} catch (err: any) {
setError(err.message || 'Failed to fetch articles');
} finally {
setLoading(false);
}
};
useEffect(() => {
fetchArticles();
}, []);
return (
<Article.Provider value={{ articles, loading, error, refreshArticles: fetchArticles }}>
{children}
</Article.Provider>
);
};
export const useArticles = (): ArticleContextType => {
const ctx = useContext(Article);
if (!ctx) throw new Error('useArticles must be used inside ArticleProvider');
return ctx;
};

View File

@@ -1,12 +1,15 @@
import * as React from 'react';
import { createRoot } from 'react-dom/client';
import Blog from './blog/Blog';
import { ArticleProvider } from './blog/providers/Article';
const rootElement = document.getElementById('root');
const root = createRoot(rootElement);
root.render(
<React.StrictMode>
<Blog />
<ArticleProvider>
<Blog />
</ArticleProvider>
</React.StrictMode>,
);