import { useState, useRef } from 'react'; import { useNavigate } from 'react-router-dom'; import Layout from '../components/Layout'; import BlogEditor, { type BlogEditorRef } from '../blog/BlogEditor'; import { uploadImage, createBlogPost } from '../blog/api'; import { Toast } from '../components/Toast'; import { useToast } from '../hooks/useToast'; import '../App.css'; function CreatePost() { const navigate = useNavigate(); const editorRef = useRef(null); const { toasts, removeToast, success, error } = useToast(); const [title, setTitle] = useState(''); const [coverImage, setCoverImage] = useState(null); const [coverImageKey, setCoverImageKey] = useState(''); const [uploadProgress, setUploadProgress] = useState(0); const [isUploading, setIsUploading] = useState(false); const [uploadError, setUploadError] = useState(''); const [isSubmitting, setIsSubmitting] = useState(false); const fileInputRef = useRef(null); const handleCoverImageChange = async (event: React.ChangeEvent) => { const file = event.target.files?.[0]; if (!file) return; // Validate file type if (!file.type.startsWith('image/')) { setUploadError('Please select an image file'); return; } // Show preview immediately const reader = new FileReader(); reader.onload = (e) => { setCoverImage(e.target?.result as string); }; reader.readAsDataURL(file); // Upload to S3 setIsUploading(true); setUploadError(''); setUploadProgress(0); try { const { fileKey, url } = await uploadImage(file, (progress) => { setUploadProgress(progress); }); setCoverImageKey(fileKey); setCoverImage(url); setUploadProgress(100); success('Cover image uploaded successfully!'); } catch (err) { const errorMessage = err instanceof Error ? err.message : 'Upload failed'; setUploadError(errorMessage); error(`Cover image upload failed: ${errorMessage}`); } finally { setIsUploading(false); } }; const handleSubmit = async () => { if (!title.trim()) { alert('Please enter a title'); return; } if (!coverImageKey) { alert('Please upload a cover image'); return; } // Get editor content if (!editorRef.current) { alert('Editor not initialized'); return; } setIsSubmitting(true); try { // Get the actual editor state as JSON const content = editorRef.current.getEditorState(); await createBlogPost(title, content, coverImageKey); success('Blog post published successfully!', 2000); // Navigate to the blog page after a short delay setTimeout(() => { navigate('/blog'); }, 1500); } catch (err) { const errorMessage = err instanceof Error ? err.message : 'Failed to create blog post'; error(`Failed to publish post: ${errorMessage}`); } finally { setIsSubmitting(false); } }; return (
{/* Header */}

Create New Post

Share your thoughts with the community

{/* Title Input */}
setTitle(e.target.value)} placeholder="Enter your blog post title..." style={{ width: '100%', padding: '1rem', fontSize: '1.2rem', border: '2px solid var(--border-color)', borderRadius: '8px', background: 'var(--bg-card)', color: 'var(--text-primary)', outline: 'none', transition: 'border-color 0.3s ease' }} onFocus={(e) => { e.currentTarget.style.borderColor = 'var(--accent-color)'; }} onBlur={(e) => { e.currentTarget.style.borderColor = 'var(--border-color)'; }} />
{/* Cover Image Upload */}
fileInputRef.current?.click()} onMouseEnter={(e) => { e.currentTarget.style.borderColor = 'var(--accent-color)'; }} onMouseLeave={(e) => { e.currentTarget.style.borderColor = 'var(--border-color)'; }} > {coverImage ? (
Cover {isUploading && (
Uploading... {Math.round(uploadProgress)}%
)}
) : (
📷

Click to upload cover image

PNG, JPG, GIF up to 10MB

)}
{uploadError && (
❌ {uploadError}
)}
{/* Content Editor */}
{/* Action Buttons */}
); } export default CreatePost;