Files
campfire-dashboard/src/pages/Dashboard.jsx

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;