121 lines
4.9 KiB
JavaScript
121 lines
4.9 KiB
JavaScript
// DashboardPage.jsx
|
|
// Main dashboard component
|
|
import React, { useState, useEffect } from 'react';
|
|
import { useNavigate, useLocation } from 'react-router-dom';
|
|
import { Button } from '@progress/kendo-react-buttons';
|
|
import { Card, CardImage, CardBody, GridLayout } from '@progress/kendo-react-layout';
|
|
import PostCard from '../components/Cards/PostCard';
|
|
import { getPublishedPosts, getDraftPosts } from '../data/postsCache';
|
|
|
|
const Dashboard = React.forwardRef((props, ref) => {
|
|
// State management for blog post data and loading states
|
|
const [publishedPosts, setPublishedPosts] = useState([]);
|
|
const [draftPosts, setDraftPosts] = useState([]);
|
|
const [isLoading, setIsLoading] = useState(true);
|
|
const navigate = useNavigate();
|
|
const location = useLocation();
|
|
|
|
// Load blog post data on component mount
|
|
useEffect(() => {
|
|
const loadData = async () => {
|
|
setIsLoading(true);
|
|
try {
|
|
// Parallel data loading for better performance
|
|
const [published, drafts] = await Promise.all([
|
|
getPublishedPosts(),
|
|
getDraftPosts()
|
|
]);
|
|
setPublishedPosts(published);
|
|
setDraftPosts(drafts);
|
|
} catch (error) {
|
|
console.error('Error loading posts:', error);
|
|
} finally {
|
|
setIsLoading(false);
|
|
}
|
|
};
|
|
loadData();
|
|
}, []);
|
|
|
|
const handleEdit = (slug) => {
|
|
navigate(`/editor/${slug}`);
|
|
};
|
|
|
|
// Determine filter from URL path
|
|
const getFilterFromPath = () => {
|
|
if (location.pathname === '/posts') return 'published';
|
|
if (location.pathname === '/drafts') return 'drafts';
|
|
return null; // Show both
|
|
};
|
|
|
|
const filter = getFilterFromPath();
|
|
// Show sections based on URL filter or show both if no filter
|
|
const showPublished = !filter || filter === 'published';
|
|
const showDrafts = !filter || filter === 'drafts';
|
|
|
|
if (isLoading) {
|
|
return (
|
|
<div className="content-wrapper" style={{ textAlign: 'center', padding: '50px' }} ref={ref}>
|
|
<div>Loading posts...</div>
|
|
</div>
|
|
);
|
|
}
|
|
|
|
return (
|
|
<div
|
|
className="dashboard-content content-wrapper"
|
|
style={{
|
|
textAlign: 'center',
|
|
padding: '20px 0' // Consistent padding
|
|
}}
|
|
ref={ref}
|
|
>
|
|
{showPublished && (
|
|
<section style={{ marginBottom: '40px' }}>
|
|
<h2 style={{ textAlign: 'center', marginBottom: '20px' }}>Published Posts</h2>
|
|
{publishedPosts.length ? (
|
|
<div style={{ display: 'flex', justifyContent: 'center' }}>
|
|
<GridLayout
|
|
cols={[{ width: "1fr" }, { width: "1fr" }, { width: "1fr" }]}
|
|
gap={{ rows: 30, cols: 20 }}
|
|
style={{ width: '900px' }}
|
|
>
|
|
{publishedPosts.map(post => (
|
|
// The PostCard automatically becomes a grid item (cell)
|
|
<PostCard
|
|
key={post.slug}
|
|
post={post}
|
|
onEdit={handleEdit}
|
|
/>
|
|
))}
|
|
</GridLayout>
|
|
</div>
|
|
) : (
|
|
<p style={{ textAlign: 'center' }}>No published posts.</p>
|
|
)}
|
|
</section>
|
|
)}
|
|
|
|
{showDrafts && (
|
|
<section style={{ marginBottom: '40px', marginTop: showPublished ? '0' : '20px' }}>
|
|
<h2 style={{ textAlign: 'center', marginBottom: '20px' }}>Drafts</h2>
|
|
{draftPosts.length ? (
|
|
<div style={{ display: 'flex', justifyContent: 'center' }}>
|
|
<ul style={{ listStyle: 'none', padding: 0, width: '900px' }}>
|
|
{draftPosts.map(post => (
|
|
<li key={post.slug} style={{ marginBottom: '10px', textAlign: 'center' }}>
|
|
{post.title}{' '}
|
|
<Button style={{ marginLeft: '30px', padding: '0 20px' }} onClick={() => handleEdit(post.slug)}>Edit</Button>
|
|
</li>
|
|
))}
|
|
</ul>
|
|
</div>
|
|
) : (
|
|
<p style={{ textAlign: 'center' }}>No drafts.</p>
|
|
)}
|
|
</section>
|
|
)}
|
|
</div>
|
|
);
|
|
});
|
|
|
|
export default Dashboard; |