feat: fix rewrite section
This commit is contained in:
parent
b05884384e
commit
ca14a7271a
|
|
@ -4,7 +4,7 @@ import HeaderManagement from "@/components/landing-page/header-management";
|
||||||
import SidebarManagement from "@/components/landing-page/sidebar-management";
|
import SidebarManagement from "@/components/landing-page/sidebar-management";
|
||||||
import { useRouter } from "@/i18n/routing";
|
import { useRouter } from "@/i18n/routing";
|
||||||
import { getCookiesDecrypt, setCookiesEncrypt } from "@/lib/utils";
|
import { getCookiesDecrypt, setCookiesEncrypt } from "@/lib/utils";
|
||||||
import { useSearchParams } from "next/navigation";
|
import { useParams, useSearchParams } from "next/navigation";
|
||||||
import React, { useEffect, useState } from "react";
|
import React, { useEffect, useState } from "react";
|
||||||
import Swal from "sweetalert2";
|
import Swal from "sweetalert2";
|
||||||
import withReactContent from "sweetalert2-react-content";
|
import withReactContent from "sweetalert2-react-content";
|
||||||
|
|
@ -15,7 +15,7 @@ import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import CustomEditor from "@/components/editor/custom-editor";
|
import CustomEditor from "@/components/editor/custom-editor";
|
||||||
import { generateDataArticle, getDetailArticle } from "@/service/content/ai";
|
import { generateDataArticle, getDetailArticle } from "@/service/content/ai";
|
||||||
import { Button } from "@/components/ui/button";
|
import { Button } from "@/components/ui/button";
|
||||||
import { error, loading } from "@/config/swal";
|
import { close, error, loading } from "@/config/swal";
|
||||||
import { saveContentRewrite } from "@/service/content/content";
|
import { saveContentRewrite } from "@/service/content/content";
|
||||||
import { getPublicSuggestionList } from "@/service/landing/landing";
|
import { getPublicSuggestionList } from "@/service/landing/landing";
|
||||||
import { getDetail } from "@/service/detail/detail";
|
import { getDetail } from "@/service/detail/detail";
|
||||||
|
|
@ -23,9 +23,13 @@ import { yupResolver } from "@hookform/resolvers/yup";
|
||||||
import * as Yup from "yup";
|
import * as Yup from "yup";
|
||||||
import { htmlToString } from "@/utils/globals";
|
import { htmlToString } from "@/utils/globals";
|
||||||
import Cookies from "js-cookie";
|
import Cookies from "js-cookie";
|
||||||
|
import { Input } from "@/components/ui/input";
|
||||||
|
import { Textarea } from "@/components/ui/textarea";
|
||||||
|
|
||||||
const imageSchema = z.object({
|
const imageSchema = z.object({
|
||||||
title: z.string().min(1, { message: "Judul diperlukan" }),
|
title: z.string().min(1, { message: "Judul diperlukan" }),
|
||||||
|
mainKeyword: z.string().min(1, { message: "Keyword diperlukan" }),
|
||||||
|
seo: z.string().min(1, { message: "Tuliskan kata kunci atau frasa yang relevan dengan blog Anda, lalu tekan enter" }),
|
||||||
description: z.string().min(2, { message: "Narasi Penugasan harus lebih dari 2 karakter." }),
|
description: z.string().min(2, { message: "Narasi Penugasan harus lebih dari 2 karakter." }),
|
||||||
creatorName: z.string().min(1, { message: "Creator diperlukan" }),
|
creatorName: z.string().min(1, { message: "Creator diperlukan" }),
|
||||||
// tags: z.string().min(1, { message: "Judul diperlukan" }),
|
// tags: z.string().min(1, { message: "Judul diperlukan" }),
|
||||||
|
|
@ -33,12 +37,12 @@ const imageSchema = z.object({
|
||||||
|
|
||||||
const page = (props: { states?: any }) => {
|
const page = (props: { states?: any }) => {
|
||||||
const { states } = props;
|
const { states } = props;
|
||||||
const [profile, setProfile] = useState();
|
|
||||||
const MySwal = withReactContent(Swal);
|
const MySwal = withReactContent(Swal);
|
||||||
const router = useRouter();
|
const router = useRouter();
|
||||||
const [, setLoadingState] = useState(false);
|
const [, setLoadingState] = useState(false);
|
||||||
const searchParams = useSearchParams();
|
const searchParams = useSearchParams();
|
||||||
const id: any = searchParams?.get("title");
|
const getParams = useParams();
|
||||||
|
const id: any = getParams?.id;
|
||||||
const [content, setContent] = useState<any>([]);
|
const [content, setContent] = useState<any>([]);
|
||||||
const [isFromSPIT, setIsFromSPIT] = useState(false);
|
const [isFromSPIT, setIsFromSPIT] = useState(false);
|
||||||
const [listSuggestion, setListSuggestion] = useState();
|
const [listSuggestion, setListSuggestion] = useState();
|
||||||
|
|
@ -54,21 +58,22 @@ const page = (props: { states?: any }) => {
|
||||||
const [selectedContextType, setSelectedContextType] = useState("");
|
const [selectedContextType, setSelectedContextType] = useState("");
|
||||||
const [selectedLanguage, setSelectedLanguage] = useState("");
|
const [selectedLanguage, setSelectedLanguage] = useState("");
|
||||||
const [selectedTitle, setSelectedTitle] = useState("");
|
const [selectedTitle, setSelectedTitle] = useState("");
|
||||||
const [selectedMainKeyword, setSelectedMainKeyword] = useState("");
|
|
||||||
const [selectedSEO, setSelectedSEO] = useState("");
|
|
||||||
const [selectedSize, setSelectedSize] = useState("");
|
const [selectedSize, setSelectedSize] = useState("");
|
||||||
const [detailArticle, setDetailArticle] = useState<any>(null);
|
const [detailArticle, setDetailArticle] = useState<any>(null);
|
||||||
const [contentType, setContentType] = useState("all");
|
|
||||||
const [isLoadingData, setIsLoadingData] = useState<boolean>(false);
|
const [isLoadingData, setIsLoadingData] = useState<boolean>(false);
|
||||||
const [detailData, setDetailData] = useState<any>(null);
|
const [detailData, setDetailData] = useState<any>(null);
|
||||||
const [articleImages, setArticleImages] = useState<string[]>([]);
|
const [articleImages, setArticleImages] = useState<string[]>([]);
|
||||||
|
|
||||||
const userLevelId = getCookiesDecrypt("ulie");
|
const userLevelId = getCookiesDecrypt("ulie");
|
||||||
const roleId = getCookiesDecrypt("urie");
|
const roleId = getCookiesDecrypt("urie");
|
||||||
|
|
||||||
type ImageSchema = z.infer<typeof imageSchema>;
|
type ImageSchema = z.infer<typeof imageSchema>;
|
||||||
|
|
||||||
const validationSchema = Yup.object().shape({
|
const validationSchema = Yup.object().shape({
|
||||||
title: Yup.string().required("Judul tidak boleh kosong"),
|
title: Yup.string().required("Judul tidak boleh kosong"),
|
||||||
|
mainKeyword: Yup.string().required("Keyword tidak boleh kosong"),
|
||||||
|
seo: Yup.string().required("Tuliskan kata kunci atau frasa yang relevan dengan blog Anda, lalu tekan enter"),
|
||||||
|
description: Yup.string().required("Narasi Penugasan harus lebih dari 2 karakter."),
|
||||||
});
|
});
|
||||||
|
|
||||||
let componentMounted = true;
|
let componentMounted = true;
|
||||||
|
|
@ -87,43 +92,9 @@ const page = (props: { states?: any }) => {
|
||||||
reset,
|
reset,
|
||||||
formState: { errors },
|
formState: { errors },
|
||||||
setValue,
|
setValue,
|
||||||
|
getValues,
|
||||||
} = useForm(formOptions);
|
} = useForm(formOptions);
|
||||||
|
|
||||||
const handleArticleIdClick = async (id: string) => {
|
|
||||||
setIsLoadingData(true);
|
|
||||||
let retryCount = 0;
|
|
||||||
const maxRetries = 20;
|
|
||||||
|
|
||||||
try {
|
|
||||||
const waitForStatusUpdate = async () => {
|
|
||||||
while (retryCount < maxRetries) {
|
|
||||||
const res = await getDetailArticle(id);
|
|
||||||
const articleData = res?.data?.data;
|
|
||||||
|
|
||||||
if (articleData?.status === 2) {
|
|
||||||
return articleData;
|
|
||||||
}
|
|
||||||
|
|
||||||
retryCount++;
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 5000));
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error("Timeout: Artikel belum selesai diproses.");
|
|
||||||
};
|
|
||||||
const articleData = await waitForStatusUpdate();
|
|
||||||
const cleanArticleBody = articleData?.articleBody?.replace(/<img[^>]*>/g, "");
|
|
||||||
const articleImagesData = articleData?.imagesUrl?.split(",");
|
|
||||||
setArticleBody(cleanArticleBody || "");
|
|
||||||
setDetailData(articleData);
|
|
||||||
setSelectedArticleId(id);
|
|
||||||
setArticleImages(articleImagesData || []);
|
|
||||||
} catch (error) {
|
|
||||||
console.error("Error fetching article details:", error);
|
|
||||||
} finally {
|
|
||||||
setIsLoadingData(false);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const save = async (data: any) => {
|
const save = async (data: any) => {
|
||||||
const request = {
|
const request = {
|
||||||
title: data.title,
|
title: data.title,
|
||||||
|
|
@ -176,6 +147,7 @@ const page = (props: { states?: any }) => {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
async function initState() {
|
async function initState() {
|
||||||
setLoadingState(true);
|
setLoadingState(true);
|
||||||
|
|
@ -188,10 +160,13 @@ const page = (props: { states?: any }) => {
|
||||||
|
|
||||||
// close();
|
// close();
|
||||||
if (componentMounted) {
|
if (componentMounted) {
|
||||||
|
setValue("title", response?.data?.data?.title);
|
||||||
|
setValue("mainKeyword", response?.data?.data?.title);
|
||||||
|
setValue("seo", response?.data?.data?.description);
|
||||||
setContent(response?.data.data);
|
setContent(response?.data.data);
|
||||||
setIsFromSPIT(response?.data.data?.isFromSPIT);
|
setIsFromSPIT(response?.data.data?.isFromSPIT);
|
||||||
setListSuggestion(responseGet?.data?.data);
|
setListSuggestion(responseGet?.data?.data);
|
||||||
console.log("data list file", response?.data.data?.files);
|
console.log("data list file", response?.data?.data);
|
||||||
// const mainUrl = response?.data.data?.files[0]?.url;
|
// const mainUrl = response?.data.data?.files[0]?.url;
|
||||||
// const ticket = response?.data.data?.files[0]?.ticket;
|
// const ticket = response?.data.data?.files[0]?.ticket;
|
||||||
// const urlBlob = await getBlobContent(mainUrl, ticket);
|
// const urlBlob = await getBlobContent(mainUrl, ticket);
|
||||||
|
|
@ -232,23 +207,24 @@ const page = (props: { states?: any }) => {
|
||||||
const handleGenerateArtikel = async () => {
|
const handleGenerateArtikel = async () => {
|
||||||
loading();
|
loading();
|
||||||
const request = {
|
const request = {
|
||||||
advConfig: selectedAdvConfig,
|
advConfig: "",
|
||||||
style: selectedWritingStyle,
|
style: selectedWritingStyle,
|
||||||
website: "None",
|
website: "None",
|
||||||
connectToWeb: true,
|
connectToWeb: true,
|
||||||
lang: selectedLanguage,
|
lang: selectedLanguage,
|
||||||
pointOfView: "None",
|
pointOfView: "None",
|
||||||
title: content?.title,
|
title: getValues("title"),
|
||||||
imageSource: "Web",
|
imageSource: "Web",
|
||||||
mainKeyword: content?.title,
|
mainKeyword: getValues("mainKeyword"),
|
||||||
additionalKeywords: content?.htmlDescription,
|
additionalKeywords: getValues("seo"),
|
||||||
targetCountry: null,
|
targetCountry: null,
|
||||||
articleSize: selectedSize,
|
articleSize: selectedSize,
|
||||||
projectId: 2,
|
projectId: 2,
|
||||||
createdBy: roleId,
|
createdBy: roleId,
|
||||||
clientId: "ngDLPPiorplznw2jTqVe3YFCz5xqKfUJ",
|
// clientId: "ngDLPPiorplznw2jTqVe3YFCz5xqKfUJ",
|
||||||
|
clientId: "mediahubClientId",
|
||||||
};
|
};
|
||||||
|
console.log("Request", request);
|
||||||
const res = await generateDataArticle(request);
|
const res = await generateDataArticle(request);
|
||||||
close();
|
close();
|
||||||
|
|
||||||
|
|
@ -273,17 +249,41 @@ const page = (props: { states?: any }) => {
|
||||||
Cookies.set("nulisAIArticleIdTemp", articleIds);
|
Cookies.set("nulisAIArticleIdTemp", articleIds);
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleArticleClick = async (id: any) => {
|
const handleArticleIdClick = async (id: string) => {
|
||||||
const res = await getDetailArticle(id);
|
setIsLoadingData(true);
|
||||||
const articleData = res?.data?.data;
|
let retryCount = 0;
|
||||||
const cleanArticleBody = articleData?.articleBody?.replace(/<img[^>]*>/g, "");
|
const maxRetries = 20;
|
||||||
|
|
||||||
const articleImagesData = articleData?.imagesUrl?.split(","); // Split URLs into an array
|
try {
|
||||||
|
const waitForStatusUpdate = async () => {
|
||||||
|
while (retryCount < maxRetries) {
|
||||||
|
const res = await getDetailArticle(id);
|
||||||
|
const articleData = res?.data?.data;
|
||||||
|
|
||||||
setArticleBody(cleanArticleBody || ""); // Set articleBody for CKEditor
|
if (articleData?.status === 2) {
|
||||||
setDetailArticle(articleData);
|
return articleData;
|
||||||
setSelectedArticleId(id);
|
}
|
||||||
// setArticleImages(articleImagesData || []); // Set images array in state
|
|
||||||
|
retryCount++;
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 5000));
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new Error("Timeout: Artikel belum selesai diproses.");
|
||||||
|
};
|
||||||
|
const articleData = await waitForStatusUpdate();
|
||||||
|
const cleanArticleBody = articleData?.articleBody?.replace(/<img[^>]*>/g, "");
|
||||||
|
console.log("lalalala", cleanArticleBody);
|
||||||
|
const articleImagesData = articleData?.imagesUrl?.split(",");
|
||||||
|
setValue("description", cleanArticleBody || "");
|
||||||
|
setArticleBody(cleanArticleBody || "");
|
||||||
|
setDetailData(articleData);
|
||||||
|
setSelectedArticleId(id);
|
||||||
|
setArticleImages(articleImagesData || []);
|
||||||
|
} catch (error) {
|
||||||
|
console.error("Error fetching article details:", error);
|
||||||
|
} finally {
|
||||||
|
setIsLoadingData(false);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
return (
|
return (
|
||||||
|
|
@ -297,165 +297,156 @@ const page = (props: { states?: any }) => {
|
||||||
<div className="text-xl font-bold mb-5">Content Rewrite</div>
|
<div className="text-xl font-bold mb-5">Content Rewrite</div>
|
||||||
<div className="p-8 border border-black rounded-lg">
|
<div className="p-8 border border-black rounded-lg">
|
||||||
<form method="POST" onSubmit={handleSubmit(onSubmit)}>
|
<form method="POST" onSubmit={handleSubmit(onSubmit)}>
|
||||||
{/* {content && ( */}
|
{content && (
|
||||||
<div className="flex flex-col gap-2 ">
|
<div className="flex flex-col gap-2 ">
|
||||||
<div className="flex flex-row gap-2">
|
<div className="flex flex-row gap-2">
|
||||||
<div className="gap-1 flex flex-col mb-3">
|
<div className="gap-1 flex flex-col mb-3">
|
||||||
<p className="font-semibold">Bahasa</p>
|
<p className="font-semibold">Bahasa</p>
|
||||||
<Select value={selectedLanguage} onValueChange={(e: any) => setSelectedLanguage(e.target.value)}>
|
<Select value={selectedLanguage} onValueChange={setSelectedLanguage}>
|
||||||
<SelectTrigger className="w-[180px]">
|
<SelectTrigger className="w-[180px]">
|
||||||
<SelectValue placeholder="Pilih Bahasa" />
|
<SelectValue placeholder="Pilih Bahasa" />
|
||||||
</SelectTrigger>
|
</SelectTrigger>
|
||||||
<SelectContent>
|
<SelectContent>
|
||||||
<SelectGroup>
|
<SelectGroup>
|
||||||
<SelectLabel>Pilih Bahasa</SelectLabel>
|
<SelectLabel>Pilih Bahasa</SelectLabel>
|
||||||
<SelectItem value="indonesia">Indonesia</SelectItem>
|
<SelectItem value="id">Indonesia</SelectItem>
|
||||||
<SelectItem value="english">English</SelectItem>
|
<SelectItem value="en">English</SelectItem>
|
||||||
</SelectGroup>
|
</SelectGroup>
|
||||||
</SelectContent>
|
</SelectContent>
|
||||||
</Select>
|
</Select>
|
||||||
</div>
|
|
||||||
<div className="gap-1 flex flex-col mb-3">
|
|
||||||
<p className="font-semibold">Context Type</p>
|
|
||||||
<Select value={selectedContextType} onValueChange={(e: any) => setSelectedContextType(e.target.value)}>
|
|
||||||
<SelectTrigger className="w-[180px]">
|
|
||||||
<SelectValue placeholder="Select Context" />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
<SelectGroup>
|
|
||||||
<SelectLabel>Select Context Type</SelectLabel>
|
|
||||||
<SelectItem value="text">Text</SelectItem>
|
|
||||||
<SelectItem value="article">Article</SelectItem>
|
|
||||||
<SelectItem value="transcript">Transcript</SelectItem>
|
|
||||||
<SelectItem value="url">URL</SelectItem>
|
|
||||||
</SelectGroup>
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
<div className="gap-1 flex flex-col mb-3">
|
|
||||||
<p className="font-semibold">Writing Style</p>
|
|
||||||
<Select value={selectedWritingStyle} onValueChange={(e: any) => setSelectedWritingStyle(e.target.value)}>
|
|
||||||
<SelectTrigger className="w-[180px]">
|
|
||||||
<SelectValue placeholder="Select Writing" />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
<SelectGroup>
|
|
||||||
<SelectLabel>Select Writing Style</SelectLabel>
|
|
||||||
<SelectItem value="firendly">Friendly</SelectItem>
|
|
||||||
<SelectItem value="profesional">Profesional</SelectItem>
|
|
||||||
<SelectItem value="informational">Informational</SelectItem>
|
|
||||||
<SelectItem value="neutral">Neutral</SelectItem>
|
|
||||||
<SelectItem value="witty">Witty</SelectItem>
|
|
||||||
</SelectGroup>
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
<div className="gap-1 flex flex-col mb-3">
|
|
||||||
<p className="font-semibold">Article Size</p>
|
|
||||||
<Select value={selectedSize} onValueChange={(e: any) => setSelectedSize(e.target.value)}>
|
|
||||||
<SelectTrigger className="w-[180px]">
|
|
||||||
<SelectValue placeholder="Select Size" />
|
|
||||||
</SelectTrigger>
|
|
||||||
<SelectContent>
|
|
||||||
<SelectGroup>
|
|
||||||
<SelectLabel>Select Article Size</SelectLabel>
|
|
||||||
<SelectItem value="news">News (300 - 900 words)</SelectItem>
|
|
||||||
<SelectItem value="info">Info (900 - 2000 words)</SelectItem>
|
|
||||||
<SelectItem value="detail">Detail (2000 - 5000 words)</SelectItem>
|
|
||||||
</SelectGroup>
|
|
||||||
</SelectContent>
|
|
||||||
</Select>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className="mb-3">
|
|
||||||
<p className="font-semibold">Judul</p>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
// className="w-full border py-3 rounded-lg"
|
|
||||||
className={`w-full border py-3 rounded-lg ${errors.title ? "is-invalid" : ""}`}
|
|
||||||
{...register("title", {
|
|
||||||
value: content?.title,
|
|
||||||
})}
|
|
||||||
id="title"
|
|
||||||
defaultValue={content?.title}
|
|
||||||
// onChange={(e) => setSelectedTitle(e.target.value)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="mb-3">
|
|
||||||
<p className="font-semibold">Main Keyword</p>
|
|
||||||
<input
|
|
||||||
type="text"
|
|
||||||
className="w-full border py-3 rounded-lg mb-4"
|
|
||||||
id="mainKeyword"
|
|
||||||
name="mainKeyword"
|
|
||||||
// onChange={(e) =>
|
|
||||||
// setSelectedMainKeyword(e.target.value)
|
|
||||||
// }
|
|
||||||
placeholder="Masukan Main Keyword disini!"
|
|
||||||
defaultValue={content?.title}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="mb-3">
|
|
||||||
<p className="font-semibold">SEO</p>
|
|
||||||
<textarea
|
|
||||||
className="border py-15 w-full rounded-lg"
|
|
||||||
id="seo"
|
|
||||||
name="seo"
|
|
||||||
placeholder="Tuliskan kata kunci atau frasa yang relevan dengan blog Anda, lalu tekan enter"
|
|
||||||
// value={selectedSEO}
|
|
||||||
// onChange={(e) => setSelectedSEO(e.target.value)}
|
|
||||||
defaultValue={htmlToString(content?.htmlDescription)}
|
|
||||||
/>
|
|
||||||
</div>
|
|
||||||
<div className="mb-4">
|
|
||||||
<a onClick={handleGenerateArtikel} className="text-blue-500 hover:bg-blue-700 hover:text-white border border-blue-500 rounded-md p-2">
|
|
||||||
Generate Artikel
|
|
||||||
</a>
|
|
||||||
{isGeneratedArticle && (
|
|
||||||
<div className="mt-3 ml-2 pb-0">
|
|
||||||
{articleIds.map((id: any, index: any) => (
|
|
||||||
<p key={index} className={`text-black m-1 ${selectedArticleId === id ? "bg-[#31ce36] border border-[#31ce36]" : "bg-[#48abf7] border border-[#48abf7]"}`} onClick={() => handleArticleClick(id)}>
|
|
||||||
{id}
|
|
||||||
</p>
|
|
||||||
))}
|
|
||||||
</div>
|
</div>
|
||||||
)}
|
<div className="gap-1 flex flex-col mb-3">
|
||||||
</div>
|
<p className="font-semibold">Context Type</p>
|
||||||
<div className=" mb-3">
|
<Select value={selectedContextType} onValueChange={setSelectedContextType}>
|
||||||
<p className="font-semibold">Deskripsi Baru</p>
|
<SelectTrigger className="w-[180px]">
|
||||||
<Controller
|
<SelectValue placeholder="Select Context" />
|
||||||
control={control}
|
</SelectTrigger>
|
||||||
name="description"
|
<SelectContent>
|
||||||
render={({ field: { onChange, value } }) =>
|
<SelectGroup>
|
||||||
isLoadingData ? (
|
<SelectLabel>Select Context Type</SelectLabel>
|
||||||
<div className="flex justify-center items-center h-40">
|
<SelectItem value="text">Text</SelectItem>
|
||||||
<p className="text-gray-500">Loading Proses Data...</p>
|
<SelectItem value="article">Article</SelectItem>
|
||||||
</div>
|
<SelectItem value="transcript">Transcript</SelectItem>
|
||||||
) : (
|
<SelectItem value="url">URL</SelectItem>
|
||||||
<CustomEditor onChange={(event: any) => setArticleBody(event.editor.getData())} initialData={articleBody || value} />
|
</SelectGroup>
|
||||||
)
|
</SelectContent>
|
||||||
}
|
</Select>
|
||||||
/>
|
</div>
|
||||||
{articleBody === null || articleBody === "" ? <div className="text-red-400 px-0 text-sm">Deskripsi tidak boleh kosong*</div> : ""}
|
<div className="gap-1 flex flex-col mb-3">
|
||||||
</div>
|
<p className="font-semibold">Writing Style</p>
|
||||||
<div className="flex flex-row gap-3">
|
<Select value={selectedWritingStyle} onValueChange={setSelectedWritingStyle}>
|
||||||
<Button
|
<SelectTrigger className="w-[180px]">
|
||||||
onClick={(e) => {
|
<SelectValue placeholder="Select Writing" />
|
||||||
e.preventDefault();
|
</SelectTrigger>
|
||||||
window.close();
|
<SelectContent>
|
||||||
}}
|
<SelectGroup>
|
||||||
className="border border-blue-400 hover:bg-blue-400 hover:text-white text-blue-400"
|
<SelectLabel>Select Writing Style</SelectLabel>
|
||||||
>
|
<SelectItem value="firendly">Friendly</SelectItem>
|
||||||
Batal
|
<SelectItem value="profesional">Profesional</SelectItem>
|
||||||
</Button>
|
<SelectItem value="informational">Informational</SelectItem>
|
||||||
<Button type="submit" className="border border-blue-500 bg-blue-500 text-white">
|
<SelectItem value="neutral">Neutral</SelectItem>
|
||||||
Simpan
|
<SelectItem value="witty">Witty</SelectItem>
|
||||||
</Button>
|
</SelectGroup>
|
||||||
</div>
|
</SelectContent>
|
||||||
</div>
|
</Select>
|
||||||
|
</div>
|
||||||
|
<div className="gap-1 flex flex-col mb-3">
|
||||||
|
<p className="font-semibold">Article Size</p>
|
||||||
|
<Select value={selectedSize} onValueChange={setSelectedSize}>
|
||||||
|
<SelectTrigger className="w-[180px]">
|
||||||
|
<SelectValue placeholder="Select Size" />
|
||||||
|
</SelectTrigger>
|
||||||
|
<SelectContent>
|
||||||
|
<SelectGroup>
|
||||||
|
<SelectLabel>Select Article Size</SelectLabel>
|
||||||
|
<SelectItem value="news">News (300 - 900 words)</SelectItem>
|
||||||
|
<SelectItem value="info">Info (900 - 2000 words)</SelectItem>
|
||||||
|
<SelectItem value="detail">Detail (2000 - 5000 words)</SelectItem>
|
||||||
|
</SelectGroup>
|
||||||
|
</SelectContent>
|
||||||
|
</Select>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<p className="font-semibold">Judul</p>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="title"
|
||||||
|
render={({ field: { onChange, value } }) => <Input type="text" className={`w-full border py-3 rounded-lg ${errors.title ? "is-invalid" : ""}`} {...register("title")} id="title" value={value} onChange={onChange} />}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<p className="font-semibold">Main Keyword</p>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="mainKeyword"
|
||||||
|
render={({ field: { onChange, value } }) => (
|
||||||
|
<Input type="text" className={`w-full border py-3 rounded-lg ${errors.mainKeyword ? "is-invalid" : ""}`} {...register("mainKeyword")} id="mainKeyword" value={value} onChange={onChange} />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-3">
|
||||||
|
<p className="font-semibold">SEO</p>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="seo"
|
||||||
|
render={({ field: { onChange, value } }) => (
|
||||||
|
<Textarea className="py-20" id="seo" placeholder="Tuliskan kata kunci atau frasa yang relevan dengan blog Anda, lalu tekan enter" {...register("seo")} onChange={onChange} value={value} />
|
||||||
|
)}
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div className="mb-4">
|
||||||
|
<a onClick={handleGenerateArtikel} className="text-blue-500 cursor-pointer hover:bg-blue-700 hover:text-white border border-blue-500 rounded-md p-2">
|
||||||
|
Generate Artikel
|
||||||
|
</a>
|
||||||
|
{isGeneratedArticle && (
|
||||||
|
<div className="mt-3 ml-2 pb-0">
|
||||||
|
{articleIds.map((id: any, index: any) => (
|
||||||
|
<p
|
||||||
|
key={index}
|
||||||
|
className={`text-black m-1 ${selectedArticleId === id ? "bg-[#31ce36] cursor-pointer border border-[#31ce36]" : "bg-[#48abf7] cursor-pointer border border-[#48abf7]"}`}
|
||||||
|
onClick={() => handleArticleIdClick(id)}
|
||||||
|
>
|
||||||
|
{id}
|
||||||
|
</p>
|
||||||
|
))}
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* )} */}
|
<div className=" mb-3">
|
||||||
|
<p className="font-semibold">Deskripsi Baru</p>
|
||||||
|
<Controller
|
||||||
|
control={control}
|
||||||
|
name="description"
|
||||||
|
render={({ field: { onChange, value } }) =>
|
||||||
|
isLoadingData ? (
|
||||||
|
<div className="flex justify-center items-center h-40">
|
||||||
|
<p className="text-gray-500">Loading Proses Data...</p>
|
||||||
|
</div>
|
||||||
|
) : (
|
||||||
|
<CustomEditor onChange={onChange} initialData={articleBody || value} />
|
||||||
|
)
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
{articleBody === null || articleBody === "" ? <div className="text-red-400 px-0 text-sm">Deskripsi tidak boleh kosong*</div> : ""}
|
||||||
|
</div>
|
||||||
|
<div className="flex flex-row gap-3">
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
onClick={() => {
|
||||||
|
router.back();
|
||||||
|
}}
|
||||||
|
className="border border-blue-400 hover:bg-blue-400 hover:text-white text-blue-400"
|
||||||
|
>
|
||||||
|
Kembali
|
||||||
|
</Button>
|
||||||
|
<Button type="submit" className="border border-blue-500 bg-blue-500 text-white">
|
||||||
|
Simpan
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</form>
|
</form>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue