"use client"; import { FormEvent, Fragment, useEffect, useRef, useState } from "react"; import { Controller, useForm } from "react-hook-form"; import * as z from "zod"; import { zodResolver } from "@hookform/resolvers/zod"; import Swal from "sweetalert2"; import withReactContent from "sweetalert2-react-content"; import { Input, Textarea } from "@nextui-org/input"; import dynamic from "next/dynamic"; import JoditEditor from "jodit-react"; import { useDropzone } from "react-dropzone"; import { Button } from "@nextui-org/button"; import { CloudUploadIcon, TimesIcon } from "@/components/icons"; import Image from "next/image"; import { Switch } from "@nextui-org/switch"; import { getArticleByCategory } from "@/service/article"; import ReactSelect from "react-select"; import makeAnimated from "react-select/animated"; import { Chip } from "@nextui-org/react"; // const CustomEditor = dynamic( // () => { // return import("@/components/editor/custom-editor"); // }, // { ssr: false } // ); interface FileWithPreview extends File { preview: string; } interface CategoryType { id: number; label: string; value: number; } const categorySchema = z.object({ id: z.number(), label: z.string(), value: z.number(), }); const createArticleSchema = z.object({ title: z.string().min(2, { message: "Judul harus diisi", }), slug: z.string().min(2, { message: "Slug harus diisi", }), categoryId: z.string().min(2, { message: "Pilih Kategori", }), description: z.string().min(2, { message: "Deskripsi harus diisi", }), category: z.array(categorySchema).nonempty({ message: "Kategori harus memiliki setidaknya satu item", }), tags: z.array(z.string()).nonempty({ message: "Minimal 1 tag", }), // Array berisi string }); export default function CreateArticleForm() { const animatedComponents = makeAnimated(); const MySwal = withReactContent(Swal); const editor = useRef(null); const [files, setFiles] = useState([]); const [useAi, setUseAI] = useState(false); const [listCategory, setListCategory] = useState([]); const [tag, setTag] = useState(""); const { getRootProps, getInputProps } = useDropzone({ onDrop: (acceptedFiles) => { setFiles(acceptedFiles.map((file) => Object.assign(file))); }, }); const formOptions = { resolver: zodResolver(createArticleSchema), defaultValues: { title: "", description: "", category: [], tags: [] }, }; type UserSettingSchema = z.infer; const { register, control, handleSubmit, formState: { errors }, setValue, getValues, watch, setError, clearErrors, } = useForm(formOptions); useEffect(() => { fetchCategory(); }, []); const fetchCategory = async () => { const res = await getArticleByCategory(); if (res?.data?.data) { setupCategory(res?.data?.data); } }; const setupCategory = (data: any) => { const temp = []; for (const element of data) { temp.push({ id: element.id, label: element.title, value: element.id, }); } setListCategory(temp); }; const onSubmit = async (values: z.infer) => { MySwal.fire({ title: "Simpan Data", text: "", icon: "warning", showCancelButton: true, cancelButtonColor: "#d33", confirmButtonColor: "#3085d6", confirmButtonText: "Simpan", }).then((result) => { if (result.isConfirmed) { save(values); } }); }; const save = async (values: z.infer) => { console.log("values"); }; const watchTitle = watch("title"); const generateSlug = (title: string) => { return title .toLowerCase() .trim() .replace(/[^\w\s-]/g, "") .replace(/\s+/g, "-"); }; useEffect(() => { setValue("slug", generateSlug(watchTitle)); }, [watchTitle]); const renderFilePreview = (file: FileWithPreview) => { if (file.type.startsWith("image")) { return ( {file.name} ); } else { return "Not Found"; } }; 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"}
)); return (

Judul

( )} /> {errors?.title && (

{errors.title?.message}

)}

Slug

( )} /> {errors?.slug && (

{errors.slug?.message}

)}

Bantuan AI

Deskripsi

( // )} />

File Media

{/* Drop files here or click to upload. */} Tarik file disini atau klik untuk upload.

( Upload file dengan format .jpg, .jpeg, atau .png. Ukuran maksimal 100mb.)
{files.length ? (
{fileList}
{/*
*/}
) : null}

Thubmnail

Kategori

( "!rounded-xl bg-white !border-1 !border-gray-200", }} classNamePrefix="select" onChange={onChange} closeMenuOnSelect={false} components={animatedComponents} isClearable={true} isSearchable={true} isMulti={true} placeholder="Kategori..." name="sub-module" options={listCategory} /> )} /> {errors?.category && (

{errors.category?.message}

)}

Tags

(