"use client"; import React, { ChangeEvent, Fragment, useEffect, useRef, useState, } from "react"; import { useForm, Controller } from "react-hook-form"; import { Input } from "@/components/ui/input"; import { Button } from "@/components/ui/button"; import { Label } from "@/components/ui/label"; import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle, } from "@/components/ui/card"; import { zodResolver } from "@hookform/resolvers/zod"; import * as z from "zod"; import Swal from "sweetalert2"; import withReactContent from "sweetalert2-react-content"; import { useParams, useRouter } from "next/navigation"; import Cookies from "js-cookie"; import { createMedia, deleteFile, deleteMedia, getTagsBySubCategoryId, listEnableCategory, uploadThumbnail, } from "@/service/content/content"; import { detailMedia } from "@/service/curated-content/curated-content"; import { Badge } from "@/components/ui/badge"; import { CloudUpload, MailIcon, PieChart, XIcon } from "lucide-react"; import dynamic from "next/dynamic"; import { useDropzone } from "react-dropzone"; import { Icon } from "@iconify/react/dist/iconify.js"; import Image from "next/image"; import { error, loading } from "@/lib/swal"; import { getCsrfToken } from "@/service/auth"; import { Upload } from "tus-js-client"; import { Tabs, TabsContent, TabsList, TabsTrigger } from "@/components/ui/tabs"; import { Textarea } from "@/components/ui/textarea"; import ViewEditor from "@/components/editor/view-editor"; import { getDetailArticle, getSeoScore } from "@/service/content/ai"; import { Gauge } from "@mui/x-charts/Gauge"; import { Accordion, AccordionContent, AccordionItem, AccordionTrigger, } from "@/components/ui/accordion"; import { Pie } from "react-chartjs-2"; import { Chart as ChartJS, ArcElement, Tooltip, Legend, ChartOptions, } from "chart.js"; ChartJS.register(ArcElement, Tooltip, Legend); const imageSchema = z.object({ title: z.string().min(1, { message: "Judul diperlukan" }), description: z .string() .min(2, { message: "Narasi Penugasan harus lebih dari 2 karakter." }), creatorName: z.string().min(1, { message: "Creator diperlukan" }), // tags: z.string().min(1, { message: "Judul diperlukan" }), }); type Category = { id: string; name: string; }; type Detail = { id: string; title: string; description: string; slug: string; category: { id: string; name: string; }; publishedFor: string; publishedForObject: { id: number; name: string; }; htmlDescription: string; creatorName: string; categoryName: string; thumbnailLink: string; tags: string; }; type Option = { id: string; name: string; }; const CustomEditor = dynamic( () => { return import("@/components/editor/custom-editor"); }, { ssr: false } ); interface FileWithPreview extends File { preview: string; } export default function FormAudioSeo() { const MySwal = withReactContent(Swal); const router = useRouter(); const { id } = useParams() as { id: string }; console.log(id); const editor = useRef(null); type ImageSchema = z.infer; let progressInfo: any = []; let counterUpdateProgress = 0; const [progressList, setProgressList] = useState([]); let uploadPersen = 0; const [isStartUpload, setIsStartUpload] = useState(false); const [counterProgress, setCounterProgress] = useState(0); const [selectedFiles, setSelectedFiles] = useState([]); const taskId = Cookies.get("taskId"); const scheduleId = Cookies.get("scheduleId"); const scheduleType = Cookies.get("scheduleType"); const [categories, setCategories] = useState([]); const [selectedCategory, setSelectedCategory] = useState(); const [tags, setTags] = useState([]); const [detail, setDetail] = useState(); const [refresh, setRefresh] = useState(false); const [selectedPublishers, setSelectedPublishers] = useState([]); const [articleBody, setArticleBody] = useState(""); const [files, setFiles] = useState([]); const [filesTemp, setFilesTemp] = useState([]); const [publishedFor, setPublishedFor] = useState([]); const inputRef = useRef(null); const [selectedOptions, setSelectedOptions] = useState<{ [fileId: number]: string; }>({}); const [articleData, setArticleData] = useState({ title: "", mainKeyword: "", additionalKeywords: "", metaTitle: "", metaDescription: "", }); const [totalScoreSEO, setTotalScoreSEO] = useState(0); const [errorSEO, setErrorSEO] = useState([]); const [warningSEO, setWarningSEO] = useState([]); const [optimizedSEO, setOptimizedSEO] = useState([]); // const [errorData, setErrorData] = useState([]); const [warningData, setWarningData] = useState([]); const [optimizedData, setOptimizedData] = useState([]); const [errorsData, setErrorData] = useState([]); const [selectedTarget, setSelectedTarget] = useState( detail?.category.id ); const [unitSelection, setUnitSelection] = useState({ allUnit: false, mabes: false, polda: false, polres: false, }); let fileTypeId = "1"; const { getRootProps, getInputProps } = useDropzone({ onDrop: (acceptedFiles) => { setFiles(acceptedFiles.map((file) => Object.assign(file))); }, }); const { control, handleSubmit, setValue, formState: { errors }, } = useForm({ resolver: zodResolver(imageSchema), }); // const handleKeyDown = (e: any) => { // const newTag = e.target.value.trim(); // Ambil nilai input // if (e.key === "Enter" && newTag) { // e.preventDefault(); // Hentikan submit form // if (!tags.includes(newTag)) { // setTags((prevTags) => [...prevTags, newTag]); // Tambah tag baru // setValue("tags", ""); // Kosongkan input // } // } // }; const handleImageChange = (event: ChangeEvent) => { if (event.target.files) { const files = Array.from(event.target.files); setSelectedFiles((prevImages: any) => [...prevImages, ...files]); console.log("DATAFILE::", selectedFiles); } }; const handleRemoveImage = (index: number) => { setSelectedFiles((prevImages) => prevImages.filter((_, i) => i !== index)); }; // const handleCheckboxChange = (id: number) => { // setSelectedPublishers((prev) => // prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id] // ); // }; useEffect(() => { async function initState() { getCategories(); } initState(); }, []); const getCategories = async () => { try { const category = await listEnableCategory(fileTypeId); const resCategory: Category[] = category?.data?.data?.content; setCategories(resCategory); console.log("data category", resCategory); if (scheduleId && scheduleType === "3") { const findCategory = resCategory.find((o) => o.name.toLowerCase().includes("pers rilis") ); if (findCategory) { // setValue("categoryId", findCategory.id); setSelectedCategory(findCategory.id); // Set the selected category const response = await getTagsBySubCategoryId(findCategory.id); setTags(response?.data?.data); } } } catch (error) { console.error("Failed to fetch categories:", error); } }; useEffect(() => { const fetchArticleData = async () => { try { const response = await getDetailArticle(id); const data = response?.data?.data; const cleanArticleBody = data.articleBody.replace(/]*>/g, ""); setArticleData({ title: data.title || "", mainKeyword: data.mainKeyword || "", additionalKeywords: data.additionalKeywords || "", metaTitle: data.metaTitle || "", metaDescription: data.metaDescription || "", }); setArticleBody(cleanArticleBody || ""); // reset({ // title: data.title, // mainKeyword: data.mainKeyword, // additionalKeywords: data.additionalKeywords, // metaTitle: data.metaTitle, // metaDescription: data.metaDescription, // }); setArticleBody(cleanArticleBody || ""); } catch (error) { console.error("Failed to fetch article data:", error); } }; if (id) { fetchArticleData(); } }, [id]); useEffect(() => { const fetchSeoScore = async () => { const res = await getSeoScore(id); if (res.error) { error(res.message); return false; } setTotalScoreSEO(res.data.data?.seo_analysis?.score || 0); let errorList = [ ...res.data.data?.seo_analysis?.analysis?.keyword_optimization?.error, ...res.data.data?.seo_analysis?.analysis?.content_quality?.error, ]; setErrorSEO(errorList); let warningList = [ ...res.data.data?.seo_analysis?.analysis?.keyword_optimization?.warning, ...res.data.data?.seo_analysis?.analysis?.content_quality?.warning, ]; setWarningSEO(warningList); let optimizedList = [ ...res.data.data?.seo_analysis?.analysis?.keyword_optimization ?.optimized, ...res.data.data?.seo_analysis?.analysis?.content_quality?.optimized, ]; setOptimizedSEO(optimizedList); setErrorData(errorList); setWarningData(warningList); setOptimizedData(optimizedList); }; fetchSeoScore(); }); const data = { labels: ["SEO Score (" + totalScoreSEO + "%)"], datasets: [ { data: [totalScoreSEO], backgroundColor: ["#4CAF50"], hoverBackgroundColor: ["#388E3C"], }, ], }; const options: ChartOptions<"pie"> = { responsive: true, maintainAspectRatio: false, plugins: { legend: { position: "bottom", // TypeScript now correctly recognizes this as a valid option }, }, }; const save = async (data: ImageSchema) => { loading(); const finalTags = tags.join(", "); const requestData = { ...data, id: detail?.id, title: data.title, description: data.description, htmlDescription: data.description, fileTypeId, categoryId: selectedTarget, subCategoryId: selectedTarget, uploadedBy: "2b7c8d83-d298-4b19-9f74-b07924506b58", statusId: "1", publishedFor: publishedFor.join(","), creatorName: data.creatorName, tags: finalTags, isYoutube: false, isInternationalMedia: false, }; const response = await createMedia(requestData); console.log("Form Data Submitted:", requestData); const formMedia = new FormData(); const thumbnail = files[0]; formMedia.append("file", thumbnail); const responseThumbnail = await uploadThumbnail(id, formMedia); if (responseThumbnail?.error == true) { error(responseThumbnail?.message); return false; } const progressInfoArr = []; for (const item of files) { progressInfoArr.push({ percentage: 0, fileName: item.name }); } progressInfo = progressInfoArr; setIsStartUpload(true); setProgressList(progressInfoArr); close(); // showProgress(); files.map(async (item: any, index: number) => { await uploadResumableFile( index, String(id), item, fileTypeId == "2" || fileTypeId == "4" ? item.duration : "0" ); }); MySwal.fire({ title: "Sukses", text: "Data berhasil disimpan.", icon: "success", confirmButtonColor: "#3085d6", confirmButtonText: "OK", }).then(() => { router.push("/en/contributor/content/image"); }); }; async function uploadResumableFile( idx: number, id: string, file: any, duration: string ) { console.log(idx, id, file, duration); // const placements = getPlacement(file.placements); // console.log("Placementttt: : ", placements); const resCsrf = await getCsrfToken(); const csrfToken = resCsrf?.data?.token; console.log("CSRF TOKEN : ", csrfToken); const headers = { "X-XSRF-TOKEN": csrfToken, }; const upload = new Upload(file, { endpoint: `${process.env.NEXT_PUBLIC_API}/media/file/upload`, headers: headers, retryDelays: [0, 3000, 6000, 12_000, 24_000], chunkSize: 20_000, metadata: { mediaid: id, filename: file.name, filetype: file.type, duration, isWatermark: "true", // hardcode }, onBeforeRequest: function (req) { var xhr = req.getUnderlyingObject(); xhr.withCredentials = true; }, onError: async (e: any) => { console.log("Error upload :", e); error(e); }, onChunkComplete: ( chunkSize: any, bytesAccepted: any, bytesTotal: any ) => { const uploadPersen = Math.floor((bytesAccepted / bytesTotal) * 100); progressInfo[idx].percentage = uploadPersen; counterUpdateProgress++; console.log(counterUpdateProgress); setProgressList(progressInfo); setCounterProgress(counterUpdateProgress); }, onSuccess: async () => { uploadPersen = 100; progressInfo[idx].percentage = 100; counterUpdateProgress++; setCounterProgress(counterUpdateProgress); successTodo(); }, }); upload.start(); } const onSubmit = (data: ImageSchema) => { MySwal.fire({ title: "Simpan Data", text: "Apakah Anda yakin ingin menyimpan data ini?", icon: "warning", showCancelButton: true, cancelButtonColor: "#d33", confirmButtonColor: "#3085d6", confirmButtonText: "Simpan", }).then((result) => { if (result.isConfirmed) { save(data); } }); }; const successSubmit = (redirect: string) => { MySwal.fire({ title: "Sukses", text: "Data berhasil disimpan.", icon: "success", confirmButtonColor: "#3085d6", confirmButtonText: "OK", }).then(() => { router.push(redirect); }); }; function successTodo() { let counter = 0; for (const element of progressInfo) { if (element.percentage == 100) { counter++; } } if (counter == progressInfo.length) { setIsStartUpload(false); // hideProgress(); Cookies.remove("idCreate"); successSubmit("/in/contributor/content/image/"); } } const handleRemoveFile = (file: FileWithPreview) => { const uploadedFiles = files; const filtered = uploadedFiles.filter((i) => i.name !== file.name); setFiles([...filtered]); }; function success() { MySwal.fire({ title: "Sukses", icon: "success", confirmButtonColor: "#3085d6", confirmButtonText: "OK", }).then((result) => { if (result.isConfirmed) { // window.location.reload(); } }); } const handleDeleteFile = (id: number) => { MySwal.fire({ title: "Hapus file", text: "Apakah Anda yakin ingin menghapus file ini?", icon: "warning", showCancelButton: true, cancelButtonColor: "#3085d6", confirmButtonColor: "#d33", confirmButtonText: "Hapus", }).then((result) => { if (result.isConfirmed) { doDelete(id); } }); }; async function doDelete(id: number) { const data = { id }; try { const response = await deleteFile(data); if (response?.error) { error(response.message); return; } // Jika berhasil, hapus file dari state lokal setFiles((prevFiles: any) => prevFiles.filter((file: any) => file.id !== id) ); success(); } catch (err) { error("Terjadi kesalahan saat menghapus file"); } } return (
Konten Checker {articleData !== undefined ? (