kontenhumas-fe/components/form/content/document/teks-update-form.tsx

1094 lines
36 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"use client";
import React, {
ChangeEvent,
Fragment,
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 { v4 as uuidv4 } from "uuid";
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 { register } from "module";
import { Switch } from "@/components/ui/switch";
import Cookies from "js-cookie";
import {
createMedia,
getArticleDetail,
getTagsBySubCategoryId,
listEnableCategory,
updateArticle,
uploadThumbnail,
} from "@/service/content/content";
import { detailMedia } from "@/service/curated-content/curated-content";
import { Badge } from "@/components/ui/badge";
import { CloudUpload, MailIcon } from "lucide-react";
import { useDropzone } from "react-dropzone";
import { Icon } from "@iconify/react/dist/iconify.js";
import Image from "next/image";
import { error, loading } from "@/lib/swal";
import { Upload } from "tus-js-client";
import { getCsrfToken } from "@/service/auth";
import dynamic from "next/dynamic";
import { htmlToString } from "@/utils/globals";
import Link from "next/link";
import { listArticleCategories, uploadArticleFiles } from "@/service/content";
const teksSchema = 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" }),
files: z
.array(z.any())
.optional()
.refine(
(files) =>
!files ||
files.every(
(file: File) =>
[
"application/pdf",
"application/msword",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"text/plain",
].includes(file.type) && file.size <= 10 * 1024 * 1024,
),
{
message:
"Hanya file .pdf, .doc, .docx, atau .txt dengan ukuran maksimal 10MB yang diperbolehkan.",
},
),
publishedFor: z
.array(z.string())
.min(1, { message: "Minimal 1 target publish harus dipilih." }),
});
type Category = {
id: string;
title: string;
};
interface DetailFile {
id: number;
fileUrl: string;
fileName: string;
}
type Detail = {
id: string;
title: string;
description: string;
slug: string;
categoryId: number;
category: {
id: number;
name: string;
};
publishedForObject: {
id: number;
name: string;
};
creatorName: string;
categoryName: string;
thumbnailLink: string;
tags: string;
};
interface FileWithPreview extends File {
preview: string;
id: string;
}
type Option = {
id: string;
label: string;
};
const CustomEditor = dynamic(
() => {
return import("@/components/editor/custom-editor");
},
{ ssr: false },
);
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 TeksSchema = z.infer<typeof teksSchema>;
let progressInfo: any = [];
let counterUpdateProgress = 0;
const [progressList, setProgressList] = useState<any>([]);
let uploadPersen = 0;
const [isStartUpload, setIsStartUpload] = useState(false);
const [counterProgress, setCounterProgress] = useState(0);
const [selectedFiles, setSelectedFiles] = useState<File[]>([]);
const taskId = Cookies.get("taskId");
const scheduleId = Cookies.get("scheduleId");
const scheduleType = Cookies.get("scheduleType");
const [categories, setCategories] = useState<Category[]>([]);
const [selectedCategory, setSelectedCategory] = useState<any>();
const [tags, setTags] = useState<any[]>([]);
const [detail, setDetail] = useState<any>(null);
const [refresh, setRefresh] = useState(false);
const [selectedPublishers, setSelectedPublishers] = useState<number[]>([]);
const [files, setFiles] = useState<FileWithPreview[]>([]);
const [selectedOptions, setSelectedOptions] = useState<{
[fileId: number]: string[];
}>({});
const [selectedTarget, setSelectedTarget] = useState("");
const [detailFiles, setDetailFiles] = useState<DetailFile[]>([]);
const [unitSelection, setUnitSelection] = useState({
allUnit: false,
mabes: false,
polda: false,
polres: false,
});
const [publishedFor, setPublishedFor] = useState<string[]>([]);
const inputRef = useRef<HTMLInputElement>(null);
const [existingFiles, setExistingFiles] = useState<DetailFile[]>([]);
let fileTypeId = "3";
const { getRootProps, getInputProps } = useDropzone({
onDrop: (acceptedFiles) => {
setFiles(
acceptedFiles.map((file) =>
Object.assign(file, {
id: uuidv4(),
preview: URL.createObjectURL(file),
}),
),
);
},
accept: {
"application/pdf": [],
"application/msword": [],
"application/vnd.openxmlformats-officedocument.wordprocessingml.document":
[],
},
});
const options: Option[] = [
{ id: "all", label: "SEMUA" },
{ id: "4", label: "UMUM" },
{ id: "5", label: "JOURNALIS" },
];
const {
control,
handleSubmit,
setValue,
formState: { errors },
} = useForm<TeksSchema>({
resolver: zodResolver(teksSchema),
defaultValues: { publishedFor: [] },
});
useEffect(() => {
async function initState() {
getCategories();
}
initState();
}, []);
const getCategories = async () => {
const categoryRes = await listArticleCategories(1, 100);
setCategories(categoryRes?.data.data || []);
};
useEffect(() => {
async function initState() {
if (id) {
const response = await getArticleDetail(Number(id));
const details = response?.data?.data;
setDetail(details);
setSelectedCategory(String(details.categories[0].id));
console.log("CATEGORIIII", details.categories[0].id);
setValue("title", details.title);
setValue("description", details.htmlDescription);
setValue("creatorName", details.createdByName ?? "");
setTags(details.tags?.split(",").map((t: string) => t.trim()) || []);
setPublishedFor(details.publishedFor?.split(",") || []);
if (details?.publishedFor) {
const publishArr = details.publishedFor.split(",");
setPublishedFor(publishArr); // state lokal
setValue("publishedFor", publishArr); // ← WAJIB untuk react-hook-form
}
if (details?.files) {
setExistingFiles(details.files);
const initialOptions: { [key: number]: string[] } = {};
details.files.forEach((file: any) => {
if (file.placements) {
initialOptions[file.id] = mapPlacementsToOptions(file.placements);
}
});
setSelectedOptions(initialOptions);
}
if (details?.publishedFor) {
// Split string "7" to an array ["7"] if needed
setPublishedFor(details.publishedFor.split(","));
}
if (details?.tags) {
setTags(details.tags.split(",").map((tag: string) => tag.trim()));
}
// const matchingCategory = categories.find(
// (category) => category.id === details.categoryId
// );
// if (matchingCategory) {
// setSelectedTarget(matchingCategory.name);
// }
// setSelectedTarget(details.categoryId); // Untuk dropdown
}
}
initState();
}, [refresh, setValue]);
const mapPlacementsToOptions = (placements: string): string[] => {
const mapping: Record<string, string> = {
all: "all",
mabes: "nasional",
polda: "wilayah",
polres: "internasional",
};
// Jika placements hanya "all", langsung aktifkan semua checkbox
if (placements.trim() === "all") {
return ["all", "nasional", "wilayah", "internasional"];
}
const options = placements
.split(",")
.map((p) => mapping[p.trim()])
.filter(Boolean);
const allSelected = ["nasional", "wilayah", "internasional"].every((opt) =>
options.includes(opt),
);
return allSelected ? ["all", ...options] : options;
};
const handleCheckboxChange = (id: string) => {
if (id === "all") {
// Select all options except "all"
const allOptions = options
.filter((opt) => opt.id !== "all")
.map((opt) => opt.id);
setPublishedFor(
publishedFor.length === allOptions.length ? [] : allOptions,
);
} else {
// Toggle individual option
setPublishedFor((prev) =>
prev.includes(id) ? prev.filter((item) => item !== id) : [...prev, id],
);
}
};
const save = async (data: TeksSchema) => {
loading();
const finalTags = tags.join(", ");
// const requestData = {
// ...data,
// id: detail?.id,
// title: data.title,
// description: htmlToString(data.description),
// htmlDescription: data.description,
// fileTypeId,
// categoryId: selectedTarget,
// subCategoryId: selectedTarget,
// uploadedBy: "2b7c8d83-d298-4b19-9f74-b07924506b58",
// statusId: "1",
// publishedFor: publishedFor.join(","),
// creatorName: data.creatorName,
// tags: finalTags,
// isYoutube: false,
// isInternationalMedia: false,
// };
const payload = {
aiArticleId: detail.aiArticleId,
categoryIds: selectedCategory,
description: htmlToString(data.description),
htmlDescription: data.description,
tags: tags.join(","),
title: data.title,
typeId: detail.typeId,
slug: detail?.slug ?? data.title.toLowerCase().replace(/\s+/g, "-"),
publishedFor: data.publishedFor.join(","),
};
// const payload = {
// aiArticleId: detail?.aiArticleId ?? "",
// categoryIds: selectedCategory,
// createdById: detail?.createdById ?? "",
// description: htmlToString(data.description),
// htmlDescription: data.description,
// isDraft: false,
// isPublish: true,
// slug: detail?.slug ?? data.title.toLowerCase().replace(/\s+/g, "-"),
// statusId: detail?.statusId ?? 1,
// tags: tags.join(","),
// title: data.title,
// typeId: detail?.typeId ?? 3,
// };
const res = await updateArticle(Number(id), payload);
if (res?.error) {
error(res.message || "Gagal memperbarui data");
return;
}
if (files.length > 0) {
const formData = new FormData();
// Add all files to FormData
files.forEach((file, index) => {
formData.append("files", file);
});
const uploadResponse = await uploadArticleFiles(id, formData);
}
// const responseThumbnail = await uploadThumbnail(id, formMedia);
// if (responseThumbnail?.error == true) {
// error(responseThumbnail?.message);
// return false;
// }
// 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"
// );
// });
MySwal.fire({
title: "Sukses",
text: "Data berhasil disimpan.",
icon: "success",
confirmButtonColor: "#3085d6",
confirmButtonText: "OK",
}).then(() => {
router.push("/admin/content/text");
});
};
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 resCsrf = await getCsrfToken();
const csrfToken = resCsrf?.data?.token;
const headers = {
"X-XSRF-TOKEN": csrfToken,
};
if (!file.secondaryUrl || file.secondaryUrl == "") {
const upload = new Upload(file, {
endpoint: `${process.env.NEXT_PUBLIC_API}/media/file/upload`,
headers: headers,
retryDelays: [0, 3000, 6000, 12_000, 24_000],
chunkSize: 20_000,
metadata: {
mediaid: id,
filename: file.name,
filetype: file.type,
duration,
isWatermark: "true", // hardcode
},
onBeforeRequest: function (req) {
var xhr = req.getUnderlyingObject();
xhr.withCredentials = true;
},
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 onSubmit = (data: TeksSchema) => {
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);
}
});
};
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/teks");
}
}
const handleRemoveAllFiles = () => {
setFiles([]);
};
const renderFilePreview = (file: FileWithPreview) => {
if (file?.type?.startsWith("image")) {
return (
<Image
width={48}
height={48}
alt={file.name}
src={URL.createObjectURL(file)}
className=" rounded border p-0.5"
/>
);
} else {
return <Icon icon="tabler:file-description" />;
}
};
const handleRemoveFile = (file: FileWithPreview) => {
const uploadedFiles = files;
const filtered = uploadedFiles.filter((i) => i.name !== file.name);
setFiles([...filtered]);
};
const fileList = files.map((file) => (
<div
key={file.name}
className=" flex justify-between border px-3.5 py-3 my-6 rounded-md"
>
<div className="flex gap-3 items-center">
<div className="file-preview">{renderFilePreview(file)}</div>
<div>
<div className=" text-sm text-card-foreground">{file.name}</div>
<div className=" text-xs font-light text-muted-foreground">
{Math.round(file.size / 100) / 10 > 1000 ? (
<>{(Math.round(file.size / 100) / 10000).toFixed(1)}</>
) : (
<>{(Math.round(file.size / 100) / 10).toFixed(1)}</>
)}
{" kb"}
</div>
</div>
</div>
<Button
type="button"
size="icon"
color="destructive"
variant="outline"
className=" border-none rounded-full"
onClick={() => handleRemoveFile(file)}
>
<Icon icon="tabler:x" className=" h-5 w-5" />
</Button>
</div>
));
const handleCheckboxChangeImage = (fileId: number, value: string) => {
setSelectedOptions((prev: any) => {
const currentSelections = prev[fileId] || [];
if (value === "all") {
// If "all" is clicked, toggle all options
if (currentSelections.includes("all")) {
return { ...prev, [fileId]: [] }; // Deselect all
}
return {
...prev,
[fileId]: ["all", "nasional", "wilayah", "internasional"],
}; // Select all
} else {
// If any other checkbox is clicked, toggle that checkbox
const updatedSelections = currentSelections.includes(value)
? currentSelections.filter((option: any) => option !== value)
: [...currentSelections, value];
// If all individual options are selected, include "all" automatically
const isAllSelected = ["nasional", "wilayah", "internasional"].every(
(opt) => updatedSelections.includes(opt),
);
return {
...prev,
[fileId]: isAllSelected
? ["all", ...updatedSelections]
: updatedSelections.filter((opt: any) => opt !== "all"),
};
}
});
};
const handleAddTag = (e: React.KeyboardEvent<HTMLInputElement>) => {
if (e.key === "Enter" && e.currentTarget.value.trim()) {
e.preventDefault();
const newTag = e.currentTarget.value.trim();
if (!tags.includes(newTag)) {
setTags((prevTags) => [...prevTags, newTag]); // Tambahkan tag baru
if (inputRef.current) {
inputRef.current.value = ""; // Kosongkan input
}
}
}
};
const handleRemoveTag = (index: number) => {
setTags((prevTags) => prevTags.filter((_, i) => i !== index));
};
const handleEditTag = (index: number, newValue: string) => {
setTags((prevTags) =>
prevTags.map((tag, i) => (i === index ? newValue : tag)),
);
};
return (
<form onSubmit={handleSubmit(onSubmit)}>
{detail !== undefined ? (
<div className="flex flex-col lg:flex-row gap-10">
<Card className="w-full lg:w-8/12">
<div className="px-6 py-6">
<p className="text-lg font-semibold mb-3">Form Text</p>
<div className="gap-5 mb-5">
{/* Input Title */}
<div className="space-y-2 py-3">
<Label>Title</Label>
<Controller
control={control}
name="title"
render={({ field }) => (
<Input
type="text"
value={field?.value}
onChange={field.onChange}
placeholder="Enter Title"
/>
)}
/>
{errors.title?.message && (
<p className="text-red-400 text-sm">
{errors.title.message}
</p>
)}
</div>
<div className="flex items-center">
<div className="py-3 w-full space-y-2">
<Label>Category</Label>
<Select
value={selectedCategory}
onValueChange={setSelectedCategory}
>
<SelectTrigger>
<SelectValue placeholder="Pilih kategori" />
</SelectTrigger>
<SelectContent>
{categories?.map((cat) => (
<SelectItem key={cat.id} value={String(cat.id)}>
{cat.title}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
</div>
<div className="py-3 space-y-2">
<Label>Description</Label>
<Controller
control={control}
name="description"
render={({ field: { onChange, value } }) => (
<CustomEditor onChange={onChange} initialData={value} />
)}
/>
{errors.description?.message && (
<p className="text-red-400 text-sm">
{errors.description.message}
</p>
)}
</div>
<div className="py-3 space-y-2">
<Fragment>
<div className="py-3 space-y-2">
<Label>Select File</Label>
<Fragment>
<div {...getRootProps({ className: "dropzone" })}>
<input {...getInputProps()} />
<div className="w-full text-center border-dashed border border-black rounded-md py-[52px] flex items-center flex-col">
<CloudUpload className="w-10 h-10" />
<h4 className="text-2xl font-medium mt-3">
Drag File
</h4>
</div>
</div>
{/* 👇 TARUH DI SINI */}
{files.length > 0 && (
<div className="mt-4 space-y-2">
<Label className="text-lg font-semibold">
File Baru
</Label>
{files.map((file) => (
<div
key={file.name}
className="flex justify-between items-center border p-3 rounded-md"
>
<div>
<p className="font-medium">{file.name}</p>
<p className="text-xs text-muted-foreground">
{(file.size / 1024).toFixed(1)} KB
</p>
</div>
<Button
type="button"
size="icon"
variant="outline"
onClick={() =>
setFiles((prev) =>
prev.filter(
(item) => item.name !== file.name,
),
)
}
>
</Button>
</div>
))}
</div>
)}
</Fragment>
</div>
{/* {files.length > 0 && (
<div className="mt-4">
<Label className="text-md font-semibold">
File Media
</Label>
<div className="grid gap-4">
{files.map((file: any, index: number) => (
<div
key={file.id}
className="flex items-center border p-2 rounded-md"
>
{file.preview ? (
<img
src={file.preview}
alt={file.name}
className="w-16 h-16 object-cover rounded-md mr-4"
/>
) : (
<Icon
icon="tabler:file-description"
className="w-16 h-16"
/>
)}
<div className="flex-grow">
<p className="font-medium">
{file.fileName || file.name}
</p>
</div>
<Button
type="button"
variant="outline"
size="icon"
onClick={() =>
setFiles((prev) =>
prev.filter((f) => f.id !== file.id),
)
}
>
</Button>
</div>
))}
</div>
</div>
)} */}
{/* Existing Files */}
{existingFiles.length > 0 && (
<div className="mt-4 space-y-2">
<Label className="text-lg font-semibold">
File Sebelumnya
</Label>
{existingFiles.map((file) => (
<div
key={file.id}
className="flex justify-between items-center border p-3 rounded-md"
>
<div className="flex items-center gap-3">
<Icon
icon="tabler:file-description"
className="w-10 h-10"
/>
<div>
<p className="font-medium">{file.fileName}</p>
<a
href={file.fileUrl}
target="_blank"
rel="noopener noreferrer"
className="text-blue-500 text-sm"
>
Lihat File
</a>
</div>
</div>
</div>
))}
</div>
)}
</Fragment>
</div>
</div>
</div>
</Card>
<div className="w-full lg:w-4/12">
<Card className=" h-[800px]">
<div className="px-3 py-3">
<div className="space-y-2">
<Label>Creator</Label>
<Controller
control={control}
name="creatorName"
render={({ field }) => <Input {...field} />}
/>
{errors.creatorName?.message && (
<p className="text-red-400 text-sm">
{errors.creatorName.message}
</p>
)}
</div>
</div>
{/* <div className="mt-3 px-3">
<Label>Pratinjau Gambar Utama</Label>
<Card className="mt-2">
{files.preview ? (
<img
src={files.preview}
alt={files.name}
className="w-16 h-16 object-cover rounded-md mr-4"
/>
) : (
<Icon
icon="tabler:file-description"
className="w-16 h-16"
/>
)}
</Card>
</div> */}
<div className="px-3 py-3">
<div className="space-y-2">
<Label>Tags</Label>
<Input
type="text"
id="tags"
placeholder="Add a tag and press Enter"
onKeyDown={handleAddTag}
ref={inputRef}
/>
<div className="mt-3 flex flex-wrap gap-2">
{tags.map((tag: any, index: any) => (
<span
key={index}
className="flex items-center gap-2 px-2 py-1 rounded-lg bg-black text-white text-sm"
>
<input
type="text"
value={tag}
onChange={(e) => handleEditTag(index, e.target.value)}
className="bg-black text-white border-none focus:outline-none w-auto"
/>
<button
value={tag}
type="button"
onClick={() => handleRemoveTag(index)}
className="remove-tag-button text-white"
>
×
</button>
</span>
))}
</div>
</div>
</div>
<div className="px-3 py-3">
<div className="mt-4 space-y-2">
<Label>Publish Target</Label>
<Controller
control={control}
name="publishedFor"
render={({ field }) => {
const currentValue = field.value || [];
const isAllChecked =
currentValue.length ===
options.filter((opt) => opt.id !== "all").length;
return (
<div className="flex flex-col gap-3">
{options.map((option) => {
const isChecked =
option.id === "all"
? isAllChecked
: currentValue.includes(option.id);
const handleChange = (checked: boolean) => {
let updated: string[] = [];
if (option.id === "all") {
updated = checked
? options
.filter((opt) => opt.id !== "all")
.map((opt) => opt.id)
: [];
} else {
updated = checked
? [...currentValue, option.id]
: currentValue.filter(
(val) => val !== option.id,
);
}
field.onChange(updated);
setPublishedFor(updated);
};
return (
<div
key={option.id}
className="flex items-center gap-2"
>
<input
type="checkbox"
id={option.id}
checked={isChecked}
onChange={(e) =>
handleChange(e.target.checked)
}
/>
<Label htmlFor={option.id}>
{option.label}
</Label>
</div>
);
})}
{errors.publishedFor && (
<p className="text-red-500 text-sm">
{errors.publishedFor.message}
</p>
)}
</div>
);
}}
/>
{/* <Controller
control={control}
name="publishedFor"
render={({ field }) => (
<div className="py-3">
<div className="flex flex-col gap-3 space-y-2">
{options.map((option) => {
const isAllChecked =
field.value.length ===
options.filter((opt: any) => opt.id !== "all")
.length;
const isChecked =
option.id === "all"
? isAllChecked
: field.value.includes(option.id);
const handleChange = () => {
let updated: string[] = [];
if (option.id === "all") {
updated = isAllChecked
? []
: options
.filter((opt: any) => opt.id !== "all")
.map((opt: any) => opt.id);
} else {
updated = isChecked
? field.value.filter(
(val) => val !== option.id,
)
: [...field.value, option.id];
if (isAllChecked && option.id !== "all") {
updated = updated.filter(
(val) => val !== "all",
);
}
}
field.onChange(updated);
setPublishedFor(updated);
};
return (
<div
key={option.id}
className="flex gap-2 items-center"
>
<Checkbox
id={option.id}
checked={isChecked}
onCheckedChange={handleChange}
className="border"
/>
<Label htmlFor={option.id}>
{option.label}
</Label>
</div>
);
})}
{errors.publishedFor && (
<p className="text-red-500 text-sm">
{errors.publishedFor.message}
</p>
)}
</div>
</div>
)}
/> */}
</div>
</div>
<div className="px-3 py-3 flex flex-row items-center text-blue-500 gap-2 text-sm">
<MailIcon />
<p className="">Suggestion Box (0)</p>
</div>
<div className="px-3 py-3">
<p>Information:</p>
{/* <p>{detail?.status}</p> */}
</div>
</Card>
<div className="flex flex-row justify-end gap-3">
<div className="mt-4">
<Button type="submit" color="primary">
Submit
</Button>
</div>
<div className="mt-4">
<Link href={"/admin/content/document"}>
<Button type="button" color="primary" variant="outline">
Cancel
</Button>
</Link>
</div>
</div>
</div>
</div>
) : (
""
)}
</form>
);
}