diff --git a/components/form/content/spit-convert-form.tsx b/components/form/content/spit-convert-form.tsx
index fdaee85d..8d7f85e5 100644
--- a/components/form/content/spit-convert-form.tsx
+++ b/components/form/content/spit-convert-form.tsx
@@ -28,13 +28,13 @@ import { Checkbox } from "@/components/ui/checkbox";
import { RadioGroup, RadioGroupItem } from "@/components/ui/radio-group";
// Icons
-import {
- AlertCircle,
- FileText,
- Image,
- Loader2,
- Save,
- Trash2,
+import {
+ AlertCircle,
+ FileText,
+ Image,
+ Loader2,
+ Save,
+ Trash2,
Edit3,
Globe,
Users,
@@ -42,7 +42,7 @@ import {
Eye,
Settings,
CheckCircle,
- XCircle
+ XCircle,
} from "lucide-react";
// Swiper
@@ -62,10 +62,7 @@ import {
getTagsBySubCategoryId,
listEnableCategory,
} from "@/service/content/content";
-import {
- generateDataRewrite,
- getDetailArticle,
-} from "@/service/content/ai";
+import { generateDataRewrite, getDetailArticle } from "@/service/content/ai";
// Utils
import { getCookiesDecrypt } from "@/lib/utils";
@@ -150,14 +147,14 @@ const PLACEMENT_OPTIONS = [
// Dynamic imports
const CustomEditor = dynamic(
() => import("@/components/editor/custom-editor"),
- {
+ {
ssr: false,
loading: () => (
Loading editor...
- )
+ ),
}
);
@@ -190,24 +187,31 @@ export default function FormConvertSPIT() {
const [isDeleting, setIsDeleting] = useState(false);
const [detail, setDetail] = useState(null);
const [categories, setCategories] = useState([]);
- const [selectedCategoryId, setSelectedCategoryId] = useState(null);
- const [selectedFileType, setSelectedFileType] = useState<"original" | "rewrite">("original");
- const [selectedWritingStyle, setSelectedWritingStyle] = useState("professional");
+ const [selectedCategoryId, setSelectedCategoryId] = useState(
+ null
+ );
+ const [selectedFileType, setSelectedFileType] = useState<
+ "original" | "rewrite"
+ >("original");
+ const [selectedWritingStyle, setSelectedWritingStyle] =
+ useState("professional");
const [showRewriteEditor, setShowRewriteEditor] = useState(false);
const [isGeneratingRewrite, setIsGeneratingRewrite] = useState(false);
const [isLoadingRewrite, setIsLoadingRewrite] = useState(false);
-
+
// Media state
const [detailThumb, setDetailThumb] = useState([]);
const [thumbsSwiper, setThumbsSwiper] = useState(null);
const [files, setFiles] = useState([]);
const [filePlacements, setFilePlacements] = useState([]);
-
+
// Content rewrite state
const [articleIds, setArticleIds] = useState([]);
- const [selectedArticleId, setSelectedArticleId] = useState(null);
+ const [selectedArticleId, setSelectedArticleId] = useState(
+ null
+ );
const [articleBody, setArticleBody] = useState("");
-
+
// Form data state
const [tags, setTags] = useState([]);
const [publishedFor, setPublishedFor] = useState([]);
@@ -262,7 +266,7 @@ export default function FormConvertSPIT() {
// Auto-select "Pers Rilis" category if schedule type is 3
const scheduleId = Cookies.get("scheduleId");
const scheduleType = Cookies.get("scheduleType");
-
+
if (scheduleId && scheduleType === "3") {
const persRilisCategory = categories.find((cat: Category) =>
cat.name.toLowerCase().includes("pers rilis")
@@ -281,7 +285,7 @@ export default function FormConvertSPIT() {
try {
const response = await getTagsBySubCategoryId(categoryId);
if (response?.data?.data?.length > 0) {
- const tagsMerge = [...tags, response?.data?.data]
+ const tagsMerge = [...tags, response?.data?.data];
setTags(tagsMerge);
}
} catch (error) {
@@ -293,7 +297,7 @@ export default function FormConvertSPIT() {
try {
const response = await detailSPIT(id);
const details = response?.data?.data;
-
+
if (!details) {
throw new Error("Detail not found");
}
@@ -301,11 +305,11 @@ export default function FormConvertSPIT() {
setDetail(details);
setFiles(details.contentList || []);
setDetailThumb(
- (details.contentList || []).map((file: FileType) =>
- file.contentFile || "default-image.jpg"
+ (details.contentList || []).map(
+ (file: FileType) => file.contentFile || "default-image.jpg"
)
);
-
+
// Initialize file placements
const fileCount = details.contentList?.length || 0;
setFilePlacements(Array(fileCount).fill([]));
@@ -314,7 +318,10 @@ export default function FormConvertSPIT() {
setValue("contentTitle", details.contentTitle || "");
setValue("contentDescription", details.contentDescription || "");
setValue("contentCreator", details.contentCreator || "");
- setValue("contentRewriteDescription", details.contentRewriteDescription || "");
+ setValue(
+ "contentRewriteDescription",
+ details.contentRewriteDescription || ""
+ );
// Set category
if (details.categoryId) {
@@ -324,7 +331,9 @@ export default function FormConvertSPIT() {
// Set tags
if (details.contentTag) {
- const initialTags = details.contentTag.split(",").map((tag: string) => tag.trim());
+ const initialTags = details.contentTag
+ .split(",")
+ .map((tag: string) => tag.trim());
setTags(initialTags);
}
} catch (error) {
@@ -365,13 +374,13 @@ export default function FormConvertSPIT() {
};
const response = await generateDataRewrite(request);
-
+
if (response?.error) {
throw new Error(response.message);
}
const newArticleId = response?.data?.data?.id;
- setArticleIds(prev => {
+ setArticleIds((prev) => {
const updated = [...prev];
if (updated.length < 3) {
updated.push(newArticleId);
@@ -405,23 +414,26 @@ export default function FormConvertSPIT() {
try {
setIsLoadingRewrite(true);
setSelectedArticleId(articleId);
-
+
let retryCount = 0;
const maxRetries = 20;
-
+
while (retryCount < maxRetries) {
const response = await getDetailArticle(articleId);
const articleData = response?.data?.data;
if (articleData?.status === 2) {
- const cleanArticleBody = articleData.articleBody?.replace(/
]*>/g, "");
+ const cleanArticleBody = articleData.articleBody?.replace(
+ /
]*>/g,
+ ""
+ );
setArticleBody(cleanArticleBody || "");
setValue("contentRewriteDescription", cleanArticleBody || "");
break;
}
retryCount++;
- await new Promise(resolve => setTimeout(resolve, 5000));
+ await new Promise((resolve) => setTimeout(resolve, 5000));
}
if (retryCount >= maxRetries) {
@@ -444,40 +456,46 @@ export default function FormConvertSPIT() {
if (e.key === "Enter" && inputRef.current?.value.trim()) {
e.preventDefault();
const newTag = inputRef.current.value.trim();
-
+
if (!tags.includes(newTag)) {
- setTags(prev => [...prev, newTag]);
+ setTags((prev) => [...prev, newTag]);
}
-
+
inputRef.current.value = "";
}
};
const handleRemoveTag = (index: number) => {
- setTags(prev => prev.filter((_, i) => i !== index));
+ setTags((prev) => prev.filter((_, i) => i !== index));
};
const handlePublishTargetChange = (optionId: string) => {
if (optionId === "all") {
- setPublishedFor(prev =>
- prev.length === PUBLISH_OPTIONS.filter(opt => opt.id !== "all").length
- ? []
- : PUBLISH_OPTIONS.filter(opt => opt.id !== "all").map(opt => opt.id)
+ setPublishedFor((prev) =>
+ prev.length === PUBLISH_OPTIONS.filter((opt) => opt.id !== "all").length
+ ? []
+ : PUBLISH_OPTIONS.filter((opt) => opt.id !== "all").map(
+ (opt) => opt.id
+ )
);
} else {
- setPublishedFor(prev =>
- prev.includes(optionId)
- ? prev.filter(id => id !== optionId && id !== "all")
- : [...prev.filter(id => id !== "all"), optionId]
+ setPublishedFor((prev) =>
+ prev.includes(optionId)
+ ? prev.filter((id) => id !== optionId && id !== "all")
+ : [...prev.filter((id) => id !== "all"), optionId]
);
}
};
- const handleFilePlacementChange = (fileIndex: number, placement: string, checked: boolean) => {
- setFilePlacements(prev => {
+ const handleFilePlacementChange = (
+ fileIndex: number,
+ placement: string,
+ checked: boolean
+ ) => {
+ setFilePlacements((prev) => {
const updated = [...prev];
const currentPlacements = updated[fileIndex] || [];
-
+
if (checked) {
if (placement === "all") {
updated[fileIndex] = ["all", "mabes", "polda", "international"];
@@ -492,25 +510,27 @@ export default function FormConvertSPIT() {
if (placement === "all") {
updated[fileIndex] = [];
} else {
- const newPlacements = currentPlacements.filter(p => p !== placement);
+ const newPlacements = currentPlacements.filter(
+ (p) => p !== placement
+ );
if (newPlacements.length === 3 && newPlacements.includes("all")) {
- updated[fileIndex] = newPlacements.filter(p => p !== "all");
+ updated[fileIndex] = newPlacements.filter((p) => p !== "all");
} else {
updated[fileIndex] = newPlacements;
}
}
}
-
+
return updated;
});
};
const handleSelectAllPlacements = (placement: string, checked: boolean) => {
- setFilePlacements(prev =>
- prev.map(filePlacements =>
- checked
+ setFilePlacements((prev) =>
+ prev.map((filePlacements) =>
+ checked
? Array.from(new Set([...filePlacements, placement]))
- : filePlacements.filter(p => p !== placement)
+ : filePlacements.filter((p) => p !== placement)
)
);
};
@@ -520,7 +540,7 @@ export default function FormConvertSPIT() {
console.log("filePlacements : ", filePlacements);
for (let i = 0; i < filePlacements.length; i++) {
if (filePlacements[i].length > 0) {
- const placements = filePlacements[i];
+ const placements = filePlacements[i];
placementData.push({
mediaFileId: files[i].contentId,
placements: placements.join(","),
@@ -530,15 +550,38 @@ export default function FormConvertSPIT() {
return placementData;
};
+ const checkPlacement = (data: any) => {
+ let temp = true;
+ for (const element of data) {
+ if (element.length < 1) {
+ temp = false;
+ break;
+ }
+ }
+
+ return temp;
+ };
+
// Form submission
const onSubmit = async (data: FormData) => {
+ if (!checkPlacement(filePlacements)) {
+ error("Select File Placement");
+ return false;
+ }
+
+ if (publishedFor.length < 1) {
+ error("Select Publish Target");
+ return false;
+ }
+
try {
setIsSaving(true);
-
- const description = selectedFileType === "original"
- ? data.contentDescription
- : data.contentRewriteDescription;
-
+
+ const description =
+ selectedFileType === "original"
+ ? data.contentDescription
+ : data.contentRewriteDescription;
+
const requestData = {
spitId: id,
title: data.contentTitle,
@@ -552,7 +595,7 @@ export default function FormConvertSPIT() {
};
await convertSPIT(requestData);
-
+
MySwal.fire({
title: "Success",
text: "Data saved successfully",
@@ -590,7 +633,7 @@ export default function FormConvertSPIT() {
try {
setIsDeleting(true);
await deleteSPIT(id);
-
+
MySwal.fire({
title: "Success",
text: "Content deleted successfully",
@@ -630,17 +673,15 @@ export default function FormConvertSPIT() {
{/* Header */}
-
SPIT Convert Form
+
+ SPIT Convert Form
+
Convert and manage your SPIT content
-