import React, { useState } from 'react'; import { AuthenticatedLayout } from '../layout/AuthenticatedLayout'; import { Card, CardContent, CardHeader, CardTitle } from '../ui/card'; import { Button } from '../ui/button'; import { Input } from '../ui/input'; import { Label } from '../ui/label'; import { Textarea } from '../ui/textarea'; import { Badge } from '../ui/badge'; import { toast } from "sonner"; import { ArrowLeft, Upload, X, Plus } from 'lucide-react'; import { Route } from '../../types/routes'; import { useCreateBlogMutation } from '../../store/services/contentManager.service'; interface NewBlogProps { onNavigate: (route: Route) => void; onLogout: () => void; user: any; formData?: any; onAutoSave?: (data: any) => void; onClearAutoSave?: (route?: string) => void; } export function NewBlog({ onNavigate, onLogout, user, formData, onAutoSave, onClearAutoSave }: NewBlogProps) { const [blogData, setBlogData] = useState(() => ({ title: formData?.title || '', urlSlug: formData?.urlSlug || '', content: formData?.content || '', bannerImage: formData?.bannerImage || '', category: formData?.category || '', tags: formData?.tags || [], metaTitle: formData?.metaTitle || '', metaDesc: formData?.metaDesc || '', publishedAt: formData?.publishedAt || new Date().toISOString() })); const [newTag, setNewTag] = useState(''); const [isUploading, setIsUploading] = useState(false); // Use the RTK Query mutation hook const [createBlog, { isLoading: isSubmitting }] = useCreateBlogMutation(); // Auto-save functionality React.useEffect(() => { if (onAutoSave) { const timer = setTimeout(() => { onAutoSave(blogData); }, 1000); return () => clearTimeout(timer); } }, [blogData, onAutoSave]); const handleInputChange = (field: string, value: any) => { setBlogData(prev => ({ ...prev, [field]: value })); // Auto-generate URL slug from title if (field === 'title' && !blogData.urlSlug) { const slug = value.toLowerCase() .replace(/[^a-z0-9\s-]/g, '') .replace(/\s+/g, '-') .replace(/-+/g, '-') .trim(); setBlogData(prev => ({ ...prev, urlSlug: slug })); } }; const handleImageUpload = async (event: React.ChangeEvent) => { const file = event.target.files?.[0]; if (!file) return; if (!file.type.startsWith('image/')) { toast.error('Please select a valid image file'); return; } setIsUploading(true); try { // Simulate upload - replace with actual image upload API await new Promise(resolve => setTimeout(resolve, 1500)); // For now, we'll use a placeholder. In production, you'd upload to your server/CDN const imageUrl = URL.createObjectURL(file); handleInputChange('bannerImage', imageUrl); toast.success('Banner image uploaded successfully'); } catch (error) { toast.error('Failed to upload image'); } finally { setIsUploading(false); } }; const addTag = () => { if (newTag.trim() && !blogData.tags.includes(newTag.trim())) { handleInputChange('tags', [...blogData.tags, newTag.trim()]); setNewTag(''); } }; const removeTag = (tagToRemove: string) => { handleInputChange('tags', blogData.tags.filter((tag: string) => tag !== tagToRemove)); }; const handleCreateBlog = async (status: 'draft' | 'published') => { if (!blogData.title.trim()) { toast.error('Please enter a blog title'); return; } if (!blogData.content.trim()) { toast.error('Please enter blog content'); return; } if (!blogData.category) { toast.error('Please select a category'); return; } try { const blogPayload = { title: blogData.title, urlSlug: blogData.urlSlug, content: blogData.content, bannerImage: blogData.bannerImage, category: blogData.category, tags: blogData.tags, metaTitle: blogData.metaTitle, metaDesc: blogData.metaDesc, publishedAt: status === 'published' ? new Date().toISOString() : null }; // Use the RTK Query mutation await createBlog(blogPayload).unwrap(); if (onClearAutoSave) { onClearAutoSave(); } toast.success(`Blog ${status === 'draft' ? 'saved as draft' : 'published'} successfully`); onNavigate('/content'); } catch (error: any) { console.error('Error creating blog:', error); // Handle different error formats if (error.data?.message) { if (Array.isArray(error.data.message)) { error.data.message.forEach((msg: string) => toast.error(msg)); } else { toast.error(error.data.message); } } else { toast.error(error.message || 'Failed to save blog. Please try again.'); } } }; const categories = ['Technology', 'Business', 'Marketing', 'Design', 'Development', 'Personal Development', 'Leadership', 'Other']; return (

Create New Blog Post

Write and publish a new blog post for your audience

{/* Main Content */}
Blog Content
handleInputChange('title', e.target.value)} placeholder="Enter blog title" className="min-h-[44px] focus-visible:ring-2 focus-visible:ring-[var(--color-brand-primary)] focus-visible:ring-opacity-50" disabled={isSubmitting} />
handleInputChange('urlSlug', e.target.value)} placeholder="blog-url-slug" className="min-h-[44px] focus-visible:ring-2 focus-visible:ring-[var(--color-brand-primary)] focus-visible:ring-opacity-50" disabled={isSubmitting} />

URL: /blog/{blogData.urlSlug || 'blog-url-slug'}