"use client"; import React, { ChangeEvent, useEffect, useRef, Fragment, 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 } from "@/components/ui/card"; import { zodResolver } from "@hookform/resolvers/zod"; import * as z from "zod"; import { Upload } from "tus-js-client"; import Swal from "sweetalert2"; import withReactContent from "sweetalert2-react-content"; import { redirect, useRouter } from "next/navigation"; import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue, } from "@/components/ui/select"; import { Checkbox } from "@/components/ui/checkbox"; import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group"; import JoditEditor from "jodit-react"; import { register } from "module"; import { Switch } from "@/components/ui/switch"; import Cookies from "js-cookie"; import { createMedia, getTagsBySubCategoryId, listEnableCategory, uploadThumbnail, } from "@/service/content/content"; import { uploadThumbnailBlog } from "@/service/blog/blog"; import { Textarea } from "@/components/ui/textarea"; import { generateDataArticle, getDetailArticle, getGenerateKeywords, getGenerateTitle, } from "@/service/content/ai"; import { getCookiesDecrypt } from "@/lib/utils"; import { useDropzone } from "react-dropzone"; import { Icon } from "@iconify/react"; import { CloudUpload } from "lucide-react"; import Image from "next/image"; import { error, loading } from "@/config/swal"; import { Item } from "@radix-ui/react-dropdown-menu"; 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" }), }); interface FileWithPreview extends File { preview: string; } type Category = { id: string; name: string; }; export default function FormTeks() { const MySwal = withReactContent(Swal); const router = useRouter(); const editor = useRef(null); type ImageSchema = z.infer; const [selectedFiles, setSelectedFiles] = useState([]); const taskId = Cookies.get("taskId"); const scheduleId = Cookies.get("scheduleId"); const scheduleType = Cookies.get("scheduleType"); const roleId = getCookiesDecrypt("urie"); const [categories, setCategories] = useState([]); const [selectedCategory, setSelectedCategory] = useState(); const [tags, setTags] = useState([]); const [thumbnail, setThumbnail] = useState(null); const [preview, setPreview] = useState(null); const [selectedLanguage, setSelectedLanguage] = useState(""); const [selectedSEO, setSelectedSEO] = useState(""); const [title, setTitle] = useState(""); const [selectedAdvConfig, setSelectedAdvConfig] = useState(""); const [editingArticleId, setEditingArticleId] = useState(null); const [isLoading, setIsLoading] = useState(false); const [articleIds, setArticleIds] = useState([]); const [isGeneratedArticle, setIsGeneratedArticle] = useState(false); const [articleBody, setArticleBody] = useState(""); const [selectedArticleId, setSelectedArticleId] = useState( null ); const [selectedMainKeyword, setSelectedMainKeyword] = useState(""); const [selectedWritingStyle, setSelectedWritingStyle] = useState(""); const [selectedSize, setSelectedSize] = useState(""); const [detailData, setDetailData] = useState(null); const [articleImages, setArticleImages] = useState([]); const [isSwitchOn, setIsSwitchOn] = useState(false); const [selectedTarget, setSelectedTarget] = useState(""); const [unitSelection, setUnitSelection] = useState({ allUnit: false, mabes: false, polda: false, polres: false, }); let fileTypeId = "3"; let progressInfo: any = []; let counterUpdateProgress = 0; const [progressList, setProgressList] = useState([]); let uploadPersen = 0; const [isStartUpload, setIsStartUpload] = useState(false); const [counterProgress, setCounterProgress] = useState(0); const [files, setFiles] = useState([]); const { getRootProps, getInputProps } = useDropzone({ onDrop: (acceptedFiles) => { setFiles(acceptedFiles.map((file) => Object.assign(file))); }, }); const { control, handleSubmit, setValue, formState: { errors }, } = useForm({ resolver: zodResolver(imageSchema), }); const doGenerateMainKeyword = async () => { console.log(selectedMainKeyword); if (selectedMainKeyword?.length > 1) { try { setIsLoading(true); const titleData = { keyword: selectedMainKeyword, style: selectedWritingStyle, website: "0", connectToWeb: true, lang: selectedLanguage, pointOfView: "None", clientId: "", }; console.log("Sending request for title with data:", titleData); const titleRes = await getGenerateTitle(titleData); setTitle(titleRes?.data?.data || ""); console.log("Generated title:", titleRes?.data?.data); const keywordsData = { keyword: selectedMainKeyword, style: selectedWritingStyle, website: "0", connectToWeb: true, lang: selectedLanguage, pointOfView: "None", clientId: "", }; console.log("Sending request for keywords with data:", keywordsData); const keywordsRes = await getGenerateKeywords(keywordsData); setSelectedSEO(keywordsRes?.data?.data || []); console.log("Generated keywords:", keywordsRes?.data?.data); } catch (error) { console.error("Error during generation process:", error); } finally { setIsLoading(false); } } else { console.error("Please provide a valid main keyword."); } }; const doGenerateTitle = async () => { if (selectedMainKeyword?.length > 1) { try { setIsLoading(true); const titleData = { keyword: selectedMainKeyword, style: selectedWritingStyle, website: "0", connectToWeb: true, lang: selectedLanguage, pointOfView: "None", clientId: "", }; console.log("Sending request for title with data:", titleData); const titleRes = await getGenerateTitle(titleData); setTitle(titleRes?.data?.data || ""); console.log("Generated title:", titleRes?.data?.data); } catch (error) { console.error("Error generating title:", error); } finally { setIsLoading(false); } } else { console.error("Please provide a valid main keyword."); } }; const doGenerateKeyword = async () => { if (selectedMainKeyword?.length > 1) { try { setIsLoading(true); const keywordsData = { keyword: selectedMainKeyword, style: selectedWritingStyle, website: "0", connectToWeb: true, lang: selectedLanguage, pointOfView: "None", clientId: "", }; console.log("Sending request for keywords with data:", keywordsData); const keywordsRes = await getGenerateKeywords(keywordsData); setSelectedSEO(keywordsRes?.data?.data || []); console.log("Generated keywords:", keywordsRes?.data?.data); } catch (error) { console.error("Error generating keywords:", error); } finally { setIsLoading(false); } } else { console.error("Please provide a valid main keyword."); } }; const handleGenerateArtikel = async () => { const request = { advConfig: selectedAdvConfig, style: selectedWritingStyle, website: "None", connectToWeb: true, lang: selectedLanguage, pointOfView: "None", title: title, imageSource: "Web", mainKeyword: selectedMainKeyword, additionalKeywords: selectedSEO, targetCountry: null, articleSize: selectedSize, projectId: 2, createdBy: roleId, clientId: "ngDLPPiorplznw2jTqVe3YFCz5xqKfUJ", }; const res = await generateDataArticle(request); close(); if (res?.error) { console.error(res.message); return false; } const newArticleId = res?.data?.data?.id; setIsGeneratedArticle(true); setArticleIds((prevIds: string[]) => { if (prevIds.length < 5) { return [...prevIds, newArticleId]; } else { const updatedIds = [...prevIds]; updatedIds[4] = newArticleId; return updatedIds; } }); Cookies.set("nulisAIArticleIdTemp", JSON.stringify(articleIds)); }; const handleArticleIdClick = async (id: string) => { const res = await getDetailArticle(id); const articleData = res?.data?.data; const cleanArticleBody = articleData?.articleBody?.replace( /]*>/g, "" ); const articleImagesData = articleData?.imagesUrl?.split(","); setArticleBody(cleanArticleBody || ""); setDetailData(articleData); setSelectedArticleId(id); setArticleImages(articleImagesData || []); }; const handleAddTag = (e: React.KeyboardEvent) => { if (e.key === "Enter" && e.currentTarget.value.trim()) { e.preventDefault(); const newTag = e.currentTarget.value.trim(); if (!tags.includes(newTag)) { setTags((prevTags) => [...prevTags, newTag]); // Add new tag // setValue("tags", ""); // Clear input field } } }; const handleRemoveTag = (index: number) => { setTags((prevTags) => prevTags.filter((_, i) => i !== index)); // Remove tag }; const handleRemoveImage = (index: number) => { setSelectedFiles((prevImages) => prevImages.filter((_, i) => i !== index)); }; useEffect(() => { async function initState() { getCategories(); // setVideoActive(fileTypeId == '2'); // getRoles(); } 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); } }; const save = async (data: ImageSchema) => { loading(); const finalTags = tags.join(", "); const finalTitle = isSwitchOn ? title : data.title; const requestData = { ...data, title: finalTitle, description: data.description, htmlDescription: data.description, fileTypeId, categoryId: selectedCategory, subCategoryId: selectedCategory, uploadedBy: "2b7c8d83-d298-4b19-9f74-b07924506b58", statusId: "1", publishedFor: "6", creatorName: data.creatorName, tags: finalTags, isYoutube: false, isInternationalMedia: false, }; let id = Cookies.get("idCreate"); if (id == undefined) { const response = await createMedia(requestData); console.log("Form Data Submitted:", requestData); if (response?.error) { MySwal.fire("Error", response?.message, "error"); return; } Cookies.set("idCreate", response?.data.data, { expires: 1 }); id = response?.data?.data; // Upload Thumbnail const formMedia = new FormData(); console.log("Thumbnail : ", files[0]); formMedia.append("file", files[0]); const responseThumbnail = await uploadThumbnail(id, formMedia); if (responseThumbnail?.error == true) { error(responseThumbnail?.message); return false; } } // Upload File 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" ); }); Cookies.remove("idCreate"); // MySwal.fire("Sukses", "Data berhasil disimpan.", "success"); }; 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); } }); }; 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 upload = new Upload(file, { endpoint: `${process.env.NEXT_PUBLIC_API}/media/file/upload`, retryDelays: [0, 3000, 6000, 12_000, 24_000], chunkSize: 20_000, metadata: { mediaid: id, filename: file.name, filetype: file.type, duration, isWatermark: "true", // hardcode }, 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 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 handleImageChange = (e: React.ChangeEvent) => { const file = e.target.files?.[0]; if (file) { setThumbnail(file); console.log("Selected Thumbnail:", file); } if (file) { setPreview(URL.createObjectURL(file)); } }; const renderFilePreview = (file: FileWithPreview) => { if (file.type.startsWith("image")) { return ( {file.name} ); } else { return ; } }; const handleRemoveFile = (file: FileWithPreview) => { const uploadedFiles = files; const filtered = uploadedFiles.filter((i) => i.name !== file.name); setFiles([...filtered]); }; const fileList = files.map((file) => (
{renderFilePreview(file)}
{file.name}
{Math.round(file.size / 100) / 10 > 1000 ? ( <>{(Math.round(file.size / 100) / 10000).toFixed(1)} ) : ( <>{(Math.round(file.size / 100) / 10).toFixed(1)} )} {" kb"}
)); const handleRemoveAllFiles = () => { setFiles([]); }; return (

Form Konten Teks

{/* Input Title */}
( )} /> {errors.title?.message && (

{errors.title.message}

)}
setIsSwitchOn(checked) } />
{isSwitchOn && (
setSelectedMainKeyword(e.target.value)} placeholder="Enter Main Keyword" /> {/* )} /> */}
setTitle(e.target.value)} placeholder="Generated Title" />

Kata kunci untuk disertakan dalam teks

JIka Anda tidak Memberikan kata kunci, kami akan secara otomatis membuat kata kunci yang relevan dari kata kunci utama untuk setiap bagian dan menggunakannya untuk membuat artikel. Untuk menambahkan kata kunci baru, ketik ', + kata kunci'.