-
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+ {options.map((option) => (
+
+ opt.id !== "all")
+ .length
+ : publishedFor.includes(option.id)
+ }
+ onChange={() => handleCheckboxChange(option.id)}
+ />
+
+
+ ))}
diff --git a/components/form/content/teks-detail-form.tsx b/components/form/content/teks-detail-form.tsx
new file mode 100644
index 00000000..f491251b
--- /dev/null
+++ b/components/form/content/teks-detail-form.tsx
@@ -0,0 +1,761 @@
+"use client";
+import React, { ChangeEvent, 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 } 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 {
+ 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,
+ rejectFiles,
+ submitApproval,
+} from "@/service/content/content";
+import { detailMedia } from "@/service/curated-content/curated-content";
+import { Badge } from "@/components/ui/badge";
+import { MailIcon } from "lucide-react";
+import { Swiper, SwiperSlide } from "swiper/react";
+import "swiper/css";
+import "swiper/css/free-mode";
+import "swiper/css/navigation";
+import "swiper/css/pagination";
+import "swiper/css/thumbs";
+import "swiper/css";
+import "swiper/css/navigation";
+import { FreeMode, Navigation, Pagination, Thumbs } from "swiper/modules";
+import {
+ DialogHeader,
+ DialogFooter,
+ Dialog,
+ DialogContent,
+ DialogTitle,
+} from "@/components/ui/dialog";
+import { Textarea } from "@/components/ui/textarea";
+import { loading } from "@/config/swal";
+import { getCookiesDecrypt } from "@/lib/utils";
+import { Icon } from "@iconify/react/dist/iconify.js";
+import { error } from "@/lib/swal";
+
+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 FileType = {
+ id: number;
+ url: string;
+ thumbnailFileUrl: string;
+ fileName: string;
+};
+
+type Detail = {
+ id: string;
+ title: string;
+ description: string;
+ slug: string;
+ category: {
+ id: number;
+ name: string;
+ };
+ categoryName: string;
+ creatorName: string;
+ thumbnailLink: string;
+ tags: string;
+ statusName: string;
+ isPublish: boolean;
+ needApprovalFromLevel: number;
+ files: FileType[];
+ uploadedById: number;
+};
+
+export default function FormTeksDetail() {
+ const MySwal = withReactContent(Swal);
+ const router = useRouter();
+ const userId = getCookiesDecrypt("uie");
+ const userLevelId = getCookiesDecrypt("ulie");
+ const roleId = getCookiesDecrypt("urie");
+
+ const [modalOpen, setModalOpen] = useState(false);
+ const { id } = useParams() as { id: string };
+ console.log(id);
+ 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 [status, setStatus] = useState("");
+ 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 [description, setDescription] = useState("");
+ const [main, setMain] = useState([]);
+ const [detailThumb, setDetailThumb] = useState([]);
+ const [thumbsSwiper, setThumbsSwiper] = useState(null);
+
+ const [selectedTarget, setSelectedTarget] = useState("");
+ const [files, setFiles] = useState([]);
+ const [rejectedFiles, setRejectedFiles] = useState([]);
+ const [isMabesApprover, setIsMabesApprover] = useState(false);
+
+ let fileTypeId = "3";
+
+ 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
+ // }
+ // }
+ // };
+
+ useEffect(() => {
+ if (
+ userLevelId != undefined &&
+ roleId != undefined &&
+ userLevelId == "216" &&
+ roleId == "3"
+ ) {
+ setIsMabesApprover(true);
+ }
+ }, [userLevelId, roleId]);
+
+ 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(() => {
+ async function initState() {
+ if (id) {
+ const response = await detailMedia(id);
+ const details = response.data?.data;
+ console.log("detail", details);
+ setFiles(details?.files);
+ setDetail(details);
+ setMain({
+ type: details?.fileType.name,
+ url: details?.files[0]?.url,
+ names: details?.files[0]?.fileName,
+ format: details?.files[0]?.format,
+ });
+
+ if (details.publishedForObject) {
+ const publisherIds = details.publishedForObject.map(
+ (obj: any) => obj.id
+ );
+ setSelectedPublishers(publisherIds);
+ }
+
+ const matchingCategory = categories.find(
+ (category) => category.id === details.categoryId
+ );
+
+ if (matchingCategory) {
+ setSelectedTarget(matchingCategory.name);
+ }
+
+ setSelectedTarget(details.categoryId); // Untuk dropdown
+
+ const filesData = details.files || [];
+ const fileUrls = filesData.map((file: { thumbnailFileUrl: string }) =>
+ file.thumbnailFileUrl ? file.thumbnailFileUrl : "default-image.jpg"
+ );
+ setDetailThumb(fileUrls);
+ }
+ }
+ initState();
+ }, [refresh, setValue]);
+
+ const actionApproval = (e: string) => {
+ setStatus(e);
+ setModalOpen(true);
+ setDescription("");
+ };
+
+ const submit = async () => {
+ if (
+ (description?.length > 1 && Number(status) == 3) ||
+ Number(status) == 2 ||
+ Number(status) == 4
+ ) {
+ MySwal.fire({
+ title: "Simpan Approval",
+ text: "",
+ icon: "warning",
+ showCancelButton: true,
+ cancelButtonColor: "#d33",
+ confirmButtonColor: "#3085d6",
+ confirmButtonText: "Simpan",
+ }).then((result) => {
+ if (result.isConfirmed) {
+ save();
+ }
+ });
+ }
+ };
+
+ async function save() {
+ const data = {
+ mediaUploadId: id,
+ statusId: status,
+ message: description,
+ files: [],
+ // files: isMabesApprover ? getPlacement() : [],
+ };
+
+ loading();
+ const response = await submitApproval(data);
+
+ if (response?.error) {
+ error(response.message);
+ return false;
+ }
+
+ const dataReject = {
+ listFiles: rejectedFiles,
+ };
+
+ const resReject = await rejectFiles(dataReject);
+
+ if (resReject?.error) {
+ error(resReject.message);
+ return false;
+ }
+
+ close();
+
+ return false;
+ }
+
+ function handleDeleteFileApproval(id: number) {
+ const selectedFiles = files.filter((file) => file.id != id);
+ setFiles(selectedFiles);
+ const rejects = rejectedFiles;
+ rejects.push(id);
+ setRejectedFiles(rejects);
+ }
+ const handleMain = (
+ type: string,
+ url: string,
+ names: string,
+ format: string
+ ) => {
+ console.log("Test 3 :", type, url, names, format);
+ setMain({
+ type,
+ url,
+ names,
+ format,
+ });
+ return false;
+ };
+
+ const submitApprovalSuccesss = () => {
+ MySwal.fire({
+ title: "Sukses",
+ text: "Data berhasil disimpan.",
+ icon: "success",
+ confirmButtonColor: "#3085d6",
+ confirmButtonText: "OK",
+ }).then(() => {
+ router.push("/in/contributor/content/image");
+ });
+ };
+
+ return (
+
+ );
+}
diff --git a/components/form/content/teks-form.tsx b/components/form/content/teks-form.tsx
new file mode 100644
index 00000000..c6da3c7f
--- /dev/null
+++ b/components/form/content/teks-form.tsx
@@ -0,0 +1,1021 @@
+"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 (
+
+ );
+ } 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 (
+
+ );
+}
diff --git a/components/form/content/teks-update-form.tsx b/components/form/content/teks-update-form.tsx
new file mode 100644
index 00000000..70bb68d0
--- /dev/null
+++ b/components/form/content/teks-update-form.tsx
@@ -0,0 +1,440 @@
+"use client";
+import React, { ChangeEvent, 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 } 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 {
+ 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,
+} from "@/service/content/content";
+import { detailMedia } from "@/service/curated-content/curated-content";
+import { Badge } from "@/components/ui/badge";
+import { MailIcon } from "lucide-react";
+
+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;
+ categoryId: {
+ id: number;
+ name: string;
+ };
+ creatorName: string;
+ categoryName: string;
+ thumbnailLink: string;
+ tags: string;
+};
+
+export default function FormTeksUpdate() {
+ const MySwal = withReactContent(Swal);
+ const router = useRouter();
+
+ const { id } = useParams() as { id: string };
+ console.log(id);
+ 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 [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 [selectedTarget, setSelectedTarget] = useState("");
+ const [unitSelection, setUnitSelection] = useState({
+ allUnit: false,
+ mabes: false,
+ polda: false,
+ polres: false,
+ });
+
+ let fileTypeId = "3";
+
+ 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 handleRemoveTag = (index: any) => {
+ setTags((prevTags) => prevTags.filter((_, i) => i !== index));
+ };
+
+ 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(() => {
+ async function initState() {
+ if (id) {
+ const response = await detailMedia(id);
+ const details = response.data?.data;
+
+ setDetail(details);
+
+ if (details.publishedForObject) {
+ const publisherIds = details.publishedForObject.map(
+ (obj: any) => obj.id
+ );
+ setSelectedPublishers(publisherIds);
+ }
+
+ const matchingCategory = categories.find(
+ (category) => category.id === details.categoryId
+ );
+
+ if (matchingCategory) {
+ setSelectedTarget(matchingCategory.name);
+ }
+
+ setSelectedTarget(details.categoryId); // Untuk dropdown
+ }
+ }
+ initState();
+ }, [refresh, setValue]);
+
+ const save = async (data: ImageSchema) => {
+ 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: "6",
+ creatorName: data.creatorName,
+ tags: "siap",
+ isYoutube: false,
+ isInternationalMedia: false,
+ };
+
+ const response = await createMedia(requestData);
+ console.log("Form Data Submitted:", requestData);
+
+ MySwal.fire({
+ title: "Sukses",
+ text: "Data berhasil disimpan.",
+ icon: "success",
+ confirmButtonColor: "#3085d6",
+ confirmButtonText: "OK",
+ }).then(() => {
+ router.push("/en/contributor/content/image");
+ });
+ };
+
+ 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);
+ }
+ });
+ };
+
+ return (
+
+ );
+}
diff --git a/components/form/content/video-detail-form.tsx b/components/form/content/video-detail-form.tsx
new file mode 100644
index 00000000..f95ac1c4
--- /dev/null
+++ b/components/form/content/video-detail-form.tsx
@@ -0,0 +1,764 @@
+"use client";
+import React, { ChangeEvent, 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 } 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 {
+ 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,
+ rejectFiles,
+ submitApproval,
+} from "@/service/content/content";
+import { detailMedia } from "@/service/curated-content/curated-content";
+import { Badge } from "@/components/ui/badge";
+import { MailIcon } from "lucide-react";
+import { Swiper, SwiperSlide } from "swiper/react";
+import "swiper/css";
+import "swiper/css/free-mode";
+import "swiper/css/navigation";
+import "swiper/css/pagination";
+import "swiper/css/thumbs";
+import "swiper/css";
+import "swiper/css/navigation";
+import { FreeMode, Navigation, Pagination, Thumbs } from "swiper/modules";
+import {
+ DialogHeader,
+ DialogFooter,
+ Dialog,
+ DialogContent,
+ DialogTitle,
+} from "@/components/ui/dialog";
+import { Textarea } from "@/components/ui/textarea";
+import { loading } from "@/config/swal";
+import { getCookiesDecrypt } from "@/lib/utils";
+import { Icon } from "@iconify/react/dist/iconify.js";
+import { error } from "@/lib/swal";
+
+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 FileType = {
+ id: number;
+ url: string;
+ thumbnailFileUrl: string;
+ fileName: string;
+};
+
+type Detail = {
+ id: string;
+ title: string;
+ description: string;
+ slug: string;
+ category: {
+ id: number;
+ name: string;
+ };
+ categoryName: string;
+ creatorName: string;
+ thumbnailLink: string;
+ url: string;
+ tags: string;
+ statusName: string;
+ isPublish: boolean;
+ needApprovalFromLevel: number;
+ files: FileType[];
+ uploadedById: number;
+};
+
+export default function FormVideoDetail() {
+ const MySwal = withReactContent(Swal);
+ const router = useRouter();
+ const userId = getCookiesDecrypt("uie");
+ const userLevelId = getCookiesDecrypt("ulie");
+ const roleId = getCookiesDecrypt("urie");
+
+ const [modalOpen, setModalOpen] = useState(false);
+ const { id } = useParams() as { id: string };
+ console.log(id);
+ 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 [status, setStatus] = useState("");
+ 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 [description, setDescription] = useState("");
+ const [main, setMain] = useState([]);
+ const [detailVideo, setDetailVideo] = useState([]);
+ const [thumbsSwiper, setThumbsSwiper] = useState(null);
+
+ const [selectedTarget, setSelectedTarget] = useState("");
+ const [files, setFiles] = useState([]);
+ const [rejectedFiles, setRejectedFiles] = useState([]);
+ const [isMabesApprover, setIsMabesApprover] = useState(false);
+
+ let fileTypeId = "2";
+
+ 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
+ // }
+ // }
+ // };
+
+ useEffect(() => {
+ if (
+ userLevelId != undefined &&
+ roleId != undefined &&
+ userLevelId == "216" &&
+ roleId == "3"
+ ) {
+ setIsMabesApprover(true);
+ }
+ }, [userLevelId, roleId]);
+
+ 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(() => {
+ async function initState() {
+ if (id) {
+ const response = await detailMedia(id);
+ const details = response.data?.data;
+ console.log("detail", details);
+ setFiles(details?.files);
+ setDetail(details);
+ setMain({
+ type: details?.fileType.name,
+ url: details?.files[0]?.url,
+ names: details?.files[0]?.fileName,
+ format: details?.files[0]?.format,
+ });
+
+ if (details.publishedForObject) {
+ const publisherIds = details.publishedForObject.map(
+ (obj: any) => obj.id
+ );
+ setSelectedPublishers(publisherIds);
+ }
+
+ const matchingCategory = categories.find(
+ (category) => category.id === details.categoryId
+ );
+
+ if (matchingCategory) {
+ setSelectedTarget(matchingCategory.name);
+ }
+
+ setSelectedTarget(details.categoryId); // Untuk dropdown
+
+ const filesData = details.files || [];
+ const fileUrls = filesData.map((files: { url: string }) =>
+ files.url ? files.url : "default-image.jpg"
+ );
+ setDetailVideo(fileUrls);
+ }
+ }
+ initState();
+ }, [refresh, setValue]);
+
+ const actionApproval = (e: string) => {
+ setStatus(e);
+ setModalOpen(true);
+ setDescription("");
+ };
+
+ const submit = async () => {
+ if (
+ (description?.length > 1 && Number(status) == 3) ||
+ Number(status) == 2 ||
+ Number(status) == 4
+ ) {
+ MySwal.fire({
+ title: "Simpan Approval",
+ text: "",
+ icon: "warning",
+ showCancelButton: true,
+ cancelButtonColor: "#d33",
+ confirmButtonColor: "#3085d6",
+ confirmButtonText: "Simpan",
+ }).then((result) => {
+ if (result.isConfirmed) {
+ save();
+ }
+ });
+ }
+ };
+
+ async function save() {
+ const data = {
+ mediaUploadId: id,
+ statusId: status,
+ message: description,
+ files: [],
+ // files: isMabesApprover ? getPlacement() : [],
+ };
+
+ loading();
+ const response = await submitApproval(data);
+
+ if (response?.error) {
+ error(response.message);
+ return false;
+ }
+
+ const dataReject = {
+ listFiles: rejectedFiles,
+ };
+
+ const resReject = await rejectFiles(dataReject);
+
+ if (resReject?.error) {
+ error(resReject.message);
+ return false;
+ }
+
+ close();
+
+ return false;
+ }
+
+ function handleDeleteFileApproval(id: number) {
+ const selectedFiles = files.filter((file) => file.id != id);
+ setFiles(selectedFiles);
+ const rejects = rejectedFiles;
+ rejects.push(id);
+ setRejectedFiles(rejects);
+ }
+ const handleMain = (
+ type: string,
+ url: string,
+ names: string,
+ format: string
+ ) => {
+ console.log("Test 3 :", type, url, names, format);
+ setMain({
+ type,
+ url,
+ names,
+ format,
+ });
+ return false;
+ };
+
+ const submitApprovalSuccesss = () => {
+ MySwal.fire({
+ title: "Sukses",
+ text: "Data berhasil disimpan.",
+ icon: "success",
+ confirmButtonColor: "#3085d6",
+ confirmButtonText: "OK",
+ }).then(() => {
+ router.push("/in/contributor/content/image");
+ });
+ };
+
+ return (
+
+ );
+}
diff --git a/components/form/content/video-form.tsx b/components/form/content/video-form.tsx
index 2b82c1ff..5d1331ef 100644
--- a/components/form/content/video-form.tsx
+++ b/components/form/content/video-form.tsx
@@ -1,5 +1,11 @@
"use client";
-import React, { ChangeEvent, useEffect, useRef, useState } from "react";
+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";
@@ -7,9 +13,10 @@ 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 { useRouter } from "next/navigation";
+import { redirect, useRouter } from "next/navigation";
import {
Select,
SelectContent,
@@ -27,9 +34,25 @@ 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 taskSchema = z.object({
+const imageSchema = z.object({
title: z.string().min(1, { message: "Judul diperlukan" }),
description: z
.string()
@@ -38,6 +61,10 @@ const taskSchema = z.object({
// tags: z.string().min(1, { message: "Judul diperlukan" }),
});
+interface FileWithPreview extends File {
+ preview: string;
+}
+
type Category = {
id: string;
name: string;
@@ -47,16 +74,39 @@ export default function FormVideo() {
const MySwal = withReactContent(Swal);
const router = useRouter();
const editor = useRef(null);
- type TaskSchema = z.infer;
+ 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({
@@ -67,39 +117,200 @@ export default function FormVideo() {
});
let fileTypeId = "2";
+ 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(taskSchema),
+ } = 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 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 handleRemoveTag = (index: any) => {
- setTags((prevTags) => prevTags.filter((_, i) => i !== index));
+ 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 handleImageChange = (event: ChangeEvent) => {
- if (event.target.files) {
- const files = Array.from(event.target.files);
- setSelectedFiles((prevImages: any) => [...prevImages, ...files]);
- console.log("DATAFILE::", selectedFiles);
+ 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));
};
@@ -139,39 +350,90 @@ export default function FormVideo() {
}
};
- const save = async (data: TaskSchema) => {
+ const save = async (data: ImageSchema) => {
+ loading();
+ const finalTags = tags.join(", ");
+ const finalTitle = isSwitchOn ? title : data.title;
const requestData = {
...data,
- title: data.title,
+ title: finalTitle,
description: data.description,
htmlDescription: data.description,
fileTypeId,
- categoryId: selectedTarget,
- subCategoryId: selectedTarget,
+ categoryId: selectedCategory,
+ subCategoryId: selectedCategory,
uploadedBy: "2b7c8d83-d298-4b19-9f74-b07924506b58",
statusId: "1",
- publishedFor: 1,
+ publishedFor: "6",
creatorName: data.creatorName,
- tags: "siap",
+ tags: finalTags,
isYoutube: false,
isInternationalMedia: false,
};
- const response = await createMedia(requestData);
- console.log("Form Data Submitted:", requestData);
+ let id = Cookies.get("idCreate");
- MySwal.fire({
- title: "Sukses",
- text: "Data berhasil disimpan.",
- icon: "success",
- confirmButtonColor: "#3085d6",
- confirmButtonText: "OK",
- }).then(() => {
- router.push("/contributor/content/audio-visual");
+ 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;
+ }
+
+ const videoId = response?.data.data.id;
+ if (videoId && thumbnail) {
+ const formMedia = new FormData();
+ formMedia.append("file", thumbnail);
+
+ const responseThumbnail = await uploadThumbnail(videoId, formMedia);
+
+ if (responseThumbnail?.error) {
+ MySwal.fire("Error", responseThumbnail?.message, "error");
+ return;
+ }
+ }
+ }
+
+ // 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: TaskSchema) => {
+ const onSubmit = (data: ImageSchema) => {
MySwal.fire({
title: "Simpan Data",
text: "Apakah Anda yakin ingin menyimpan data ini?",
@@ -187,6 +449,152 @@ export default function FormVideo() {
});
};
+ 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 (
+
+ );
+ } 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 (