Refactor image processing and add image file serving functionality
- Updated image directory handling to prioritize mounted volume for persistence. - Enhanced logging for directory write tests and fallback mechanisms. - Introduced a new endpoint to serve image files directly from local paths. - Added error handling for file serving, including checks for file existence and readability. - Updated the frontend to include a new ContentView component and corresponding route.
This commit is contained in:
71
frontend/src/pages/Writer/ContentView.tsx
Normal file
71
frontend/src/pages/Writer/ContentView.tsx
Normal file
@@ -0,0 +1,71 @@
|
||||
/**
|
||||
* ContentView Page - Displays individual content using ContentViewTemplate
|
||||
* Route: /writer/content/:id
|
||||
*/
|
||||
|
||||
import { useState, useEffect } from 'react';
|
||||
import { useParams, useNavigate } from 'react-router';
|
||||
import ContentViewTemplate from '../../templates/ContentViewTemplate';
|
||||
import { fetchContentById, Content } from '../../services/api';
|
||||
import { useToast } from '../../components/ui/toast/ToastContainer';
|
||||
import PageMeta from '../../components/common/PageMeta';
|
||||
|
||||
export default function ContentView() {
|
||||
const { id } = useParams<{ id: string }>();
|
||||
const navigate = useNavigate();
|
||||
const toast = useToast();
|
||||
|
||||
const [content, setContent] = useState<Content | null>(null);
|
||||
const [loading, setLoading] = useState(true);
|
||||
|
||||
useEffect(() => {
|
||||
const loadContent = async () => {
|
||||
// Validate ID parameter - must be a number
|
||||
if (!id) {
|
||||
toast.error('Content ID is required');
|
||||
navigate('/writer/content');
|
||||
return;
|
||||
}
|
||||
|
||||
const contentId = parseInt(id, 10);
|
||||
if (isNaN(contentId) || contentId <= 0) {
|
||||
toast.error('Invalid content ID');
|
||||
navigate('/writer/content');
|
||||
return;
|
||||
}
|
||||
|
||||
setLoading(true);
|
||||
try {
|
||||
const data = await fetchContentById(contentId);
|
||||
setContent(data);
|
||||
} catch (error: any) {
|
||||
console.error('Error loading content:', error);
|
||||
toast.error(`Failed to load content: ${error.message || 'Unknown error'}`);
|
||||
setContent(null);
|
||||
} finally {
|
||||
setLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
loadContent();
|
||||
}, [id, navigate, toast]);
|
||||
|
||||
const handleBack = () => {
|
||||
navigate('/writer/content');
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<PageMeta
|
||||
title={content ? `${content.meta_title || content.title || `Content #${content.id}`} - IGNY8` : 'Content View - IGNY8'}
|
||||
description={content?.meta_description || 'View content details and metadata'}
|
||||
/>
|
||||
<ContentViewTemplate
|
||||
content={content}
|
||||
loading={loading}
|
||||
onBack={handleBack}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user