import React, { useEffect, useState } from "react"; import { useForm } from "@inertiajs/react"; import AuthenticatedLayout from "@/layouts/authenticated-layout"; import { Button } from "@/components/ui/button"; import { Input } from "@/components/ui/input"; import { Textarea } from "@/components/ui/textarea"; import { useToast } from "@/hooks/use-toast"; import { Head } from "@inertiajs/react"; import { Editor } from "@tinymce/tinymce-react"; import { Alert, AlertDescription, AlertTitle } from "@/components/ui/alert"; import { AlertCircle } from "lucide-react"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; const slugify = (text: string) => { return text .toLowerCase() .replace(/[^\w\s-]/g, "") // Remove special characters except hyphens .replace(/\s+/g, "-") // Replace spaces with hyphens .replace(/-+/g, "-") // Replace multiple hyphens with single hyphen .trim(); // Remove leading/trailing spaces }; interface ExistingPost { JudulPost: string; KategoriId: number; } interface Kategori { KategoriId: number; NamaKategori: string; } interface SubKategori { SubKategoriId: number; KategoriId: number; NamaSubKategori: string; } interface AddPostProps { kategori: Kategori[]; subkategori: SubKategori[]; existingPosts: ExistingPost[]; } export default function AddPost({ kategori, subkategori, existingPosts, }: AddPostProps) { const { toast } = useToast(); const { data, setData, post, reset } = useForm({ KategoriId: "", SubKategoriId: "", JudulPost: "", SlugPost: "", DescPost: "", ImagePost: null as File | null, IsPublish: true, }); const [showAlert, setShowAlert] = useState(false); const [imagePreview, setImagePreview] = useState(null); const [errors, setErrors] = useState>({}); useEffect(() => { setData("SlugPost", slugify(data.JudulPost)); }, [data.JudulPost]); const validateForm = () => { const newErrors: Record = {}; const titleExists = existingPosts.some( (post) => post.JudulPost.toLowerCase() === data.JudulPost.toLowerCase() && post.KategoriId === Number(data.KategoriId) ); if (titleExists) { setShowAlert(true); newErrors.JudulPost = "Judul sudah ada dalam kategori ini"; // Auto-hide alert after 5 seconds setTimeout(() => setShowAlert(false), 5000); } if (!data.KategoriId) { newErrors.KategoriId = "Kategori harus dipilih"; } if (!data.SubKategoriId) { newErrors.SubKategoriId = "Sub Kategori harus dipilih"; } if (!data.JudulPost || data.JudulPost.trim() === "") { newErrors.JudulPost = "Judul Post harus diisi"; } if (!data.DescPost || data.DescPost.trim() === "") { newErrors.DescPost = "Deskripsi Post harus diisi"; } if (!data.ImagePost) { newErrors.ImagePost = "Gambar harus diunggah"; } setErrors(newErrors); return Object.keys(newErrors).length === 0; }; const handleImageChange = (e: React.ChangeEvent) => { if (e.target.files && e.target.files[0]) { const file = e.target.files[0]; setData("ImagePost", file); // Create preview URL const reader = new FileReader(); reader.onloadend = () => { setImagePreview(reader.result as string); }; reader.readAsDataURL(file); } }; const handleSubmit = (e: React.FormEvent) => { e.preventDefault(); if (!validateForm()) { toast({ title: "Validasi Gagal", description: "Silakan periksa kembali form anda", variant: "destructive", }); return; } const formData = new FormData(); formData.append("KategoriId", data.KategoriId); formData.append("SubKategoriId", data.SubKategoriId); formData.append("JudulPost", data.JudulPost); formData.append("SlugPost", data.SlugPost); formData.append("DescPost", data.DescPost); formData.append("IsPublish", data.IsPublish.toString()); if (data.ImagePost) { formData.append("ImagePost", data.ImagePost); } // Debug logs console.log("Form Data yang dikirim:"); console.log("KategoriId:", data.KategoriId); console.log("SubKategoriId:", data.SubKategoriId); console.log("JudulPost:", data.JudulPost); console.log("SlugPost:", data.SlugPost); console.log("DescPost:", data.DescPost); console.log("IsPublish:", data.IsPublish); console.log("ImagePost:", data.ImagePost); // Log FormData entries console.log("FormData entries:"); for (let pair of formData.entries()) { console.log(pair[0], pair[1]); } post("/admin/post", { data: formData, forceFormData: true, onSuccess: (response) => { console.log("Response Success:", response); toast({ title: "Berhasil", description: "Post berhasil dibuat", variant: "default", }); setImagePreview(null); reset(); }, onError: (errors) => { console.error("Error submitting post:", errors); toast({ title: "Gagal", description: "Terjadi kesalahan saat membuat Post. Cek console untuk detail error.", variant: "destructive", }); }, }); }; return (
setData("JudulPost", e.target.value) } /> {errors.JudulPost && (

{errors.JudulPost}

)}
{errors.KategoriId && (

{errors.KategoriId}

)}
{data.KategoriId && (
{errors.SubKategoriId && (

{errors.SubKategoriId}

)}
)}
{ setData("DescPost", content); }} init={{ plugins: [ // Core editing features "anchor", "autolink", "charmap", "codesample", "emoticons", "image", "link", "lists", "media", "searchreplace", "table", "visualblocks", "wordcount", "checklist", "mediaembed", "casechange", "export", "formatpainter", "pageembed", "a11ychecker", "tinymcespellchecker", "permanentpen", "powerpaste", "advtable", "advcode", "editimage", "advtemplate", "ai", "mentions", "tinycomments", "tableofcontents", "footnotes", "mergetags", "autocorrect", "typography", "inlinecss", "markdown", "importword", "exportword", "exportpdf", ], toolbar: "undo redo | blocks fontfamily fontsize | bold italic underline strikethrough | link image media table mergetags | addcomment showcomments | spellcheckdialog a11ycheck typography | align lineheight | checklist numlist bullist indent outdent | emoticons charmap | removeformat", tinycomments_mode: "embedded", tinycomments_author: "Author name", mergetags_list: [ { value: "First.Name", title: "First Name", }, { value: "Email", title: "Email" }, ], ai_request: ( _request: any, respondWith: { string: ( callback: () => Promise ) => void; } ) => respondWith.string(() => Promise.reject( "See docs to implement AI Assistant" ) ), }} initialValue="Welcome to TinyMCE!" />
{errors.DescPost && (

{errors.DescPost}

)}
{errors.ImagePost && (

{errors.ImagePost}

)}
); }