"use client"; import IconTrashLines from "@/components/icon/icon-trash-lines"; import dynamic from "next/dynamic"; import React, { useMemo, useState } from "react"; import "react-quill/dist/quill.snow.css"; import axios from "axios"; import Cookies from "universal-cookie"; import { useRouter } from "next/navigation"; import { showMessage } from "@/utils/CommonFunction.utils"; import { buildApiUrl } from "@/utils/BaseUrl.utils"; const ReactQuill = dynamic(() => import("react-quill"), { ssr: false, }); const formats = [ "header", "bold", "italic", "underline", "strike", "blockquote", "code-block", "list", "bullet", "align", "link", "image", "video", ]; const PostForm = () => { const router = useRouter(); const [formData, setFormData] = useState({ title: "", slug: "", coverImage: null as File | null, description: "", date: "", author: "", }); const modules = useMemo( () => ({ toolbar: { container: [ [{ header: [1, 2, 3, false] }], ["bold", "italic", "underline", "strike"], [{ list: "ordered" }, { list: "bullet" }], ["blockquote", "code-block"], [{ align: [] }], ["link", "image", "video"], ["clean"], ], handlers: { image: function (this: any) { const input = document.createElement("input"); input.setAttribute("type", "file"); input.setAttribute("accept", "image/*"); input.click(); input.onchange = async () => { const file = input.files?.[0]; if (file) { const reader = new FileReader(); reader.onload = () => { const quill = this.quill; const range = quill.getSelection(true); quill.insertEmbed( range.index, "image", reader.result ); }; reader.readAsDataURL(file); } }; }, }, }, }), [] ); const handleChange = (e: React.ChangeEvent) => { const { name, value } = e.target; setFormData((prev) => ({ ...prev, [name]: value, })); }; const handleImageChange = (e: React.ChangeEvent) => { const file = e.target.files?.[0] || null; setFormData((prev) => ({ ...prev, coverImage: file, })); }; const handleRemoveImage = () => { setFormData((prev) => ({ ...prev, coverImage: null, })); }; const handleDescriptionChange = (value: string) => { setFormData((prev) => ({ ...prev, description: value, })); }; const handleSubmit = async (e: React.FormEvent) => { e.preventDefault(); if (!formData.title.trim()) { showMessage("Title is required", "error"); return; } try { const cookies = new Cookies(); const token = cookies.get('token'); if (!token) { showMessage('Access denied. Please sign in first.', 'error'); router.push('/login'); return; } let coverImageUrl = ""; if (formData.coverImage) { const data = new FormData(); data.append("file", formData.coverImage); const imageUpload = await axios.post(buildApiUrl('upload/single'), data, { headers: { "Content-Type": "multipart/form-data", Authorization: `Bearer ${token}`, }, }); if (imageUpload.data && imageUpload.data.success) { coverImageUrl = imageUpload.data.data.fullUrl; } } // Generate clean slug from title if not specified const cleanSlug = formData.slug.trim() ? formData.slug.trim().toLowerCase().replace(/\s+/g, '-').replace(/[^\w\-]+/g, '') : formData.title.trim().toLowerCase().replace(/\s+/g, '-').replace(/[^\w\-]+/g, ''); const createData = { title: formData.title, slug: cleanSlug, image: coverImageUrl, description: formData.description, date: formData.date, author: formData.author, }; const res = await axios.post(buildApiUrl('blogs'), createData, { headers: { Authorization: `Bearer ${token}`, }, }); console.log("Create blog response:", res.data); showMessage("Blog Created Successfully", "success"); router.push("/blog"); } catch (error: any) { console.error("Error creating blog:", error); showMessage(error?.response?.data?.message || "Error creating blog", "error"); } }; return (

Create Blog

{formData.coverImage && (

Preview:

Selected
)}
); }; export default PostForm;