feat:fix komunikasi,indeks

This commit is contained in:
Anang Yusman 2025-06-12 14:43:42 +08:00
parent 16c6d2f565
commit cfbc6349cc
12 changed files with 501 additions and 382 deletions

View File

@ -1,13 +1,12 @@
import SiteBreadcrumb from "@/components/site-breadcrumb";
import FormBlogDetail from "@/components/form/blog/blog--detail-form";
import FormSurveyDetailPage from "@/components/form/survey/survey-detail";
const BlogDetailPage = async () => {
return (
<div>
<SiteBreadcrumb />
<div className="space-y-4">
<FormSurveyDetailPage />
<FormBlogDetail />
</div>
</div>
);

View File

@ -303,7 +303,7 @@ export default function FormBlogDetail() {
</div>
</Card>
<div className="w-full lg:w-4/12">
<Card className=" h-[650px]">
<Card className=" h-[650px] px-3 py-3">
<div className="px-3 py-3">
<Label htmlFor="fileInput">Gambar Utama</Label>
<Input

View File

@ -1,6 +1,6 @@
"use client";
import React, { ChangeEvent, useEffect, useRef, useState } from "react";
import { useForm, Controller } from "react-hook-form";
import { useForm, Controller, useWatch } from "react-hook-form";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
@ -133,6 +133,19 @@ export default function FormBlogUpdate() {
setSelectedFiles((prevImages) => prevImages.filter((_, i) => i !== index));
};
const titleValue = useWatch({ control, name: "title" });
useEffect(() => {
if (titleValue) {
const slugified = titleValue
.toLowerCase()
.trim()
.replace(/\s+/g, "-")
.replace(/[^\w-]+/g, ""); // optional: hapus karakter non-alfanumerik
setValue("slug", slugified);
}
}, [titleValue, setValue]);
useEffect(() => {
async function initState() {
if (id) {
@ -323,7 +336,7 @@ export default function FormBlogUpdate() {
<Input
size="md"
type="text"
defaultValue={detail?.slug}
defaultValue={detail?.slug || field?.value}
onChange={field.onChange}
placeholder="Enter Slug"
/>
@ -363,7 +376,7 @@ export default function FormBlogUpdate() {
</div>
</Card>
<div className="w-full lg:w-4/12">
<Card className="h-[600px] sm:h-[850px] lg:h-[700px]">
<Card className="h-[600px] sm:h-[850px] lg:h-[700px] px-3 py-3">
<div className="px-3 py-3">
<Label htmlFor="fileInput">Gambar Utama</Label>
<input

View File

@ -1,6 +1,6 @@
"use client";
import React, { ChangeEvent, useEffect, useRef, useState } from "react";
import { useForm, Controller } from "react-hook-form";
import { useForm, Controller, useWatch } from "react-hook-form";
import { Input } from "@/components/ui/input";
import { Button } from "@/components/ui/button";
import { Label } from "@/components/ui/label";
@ -130,6 +130,19 @@ export default function FormBlog() {
setSelectedFiles((prevImages) => prevImages.filter((_, i) => i !== index));
};
const titleValue = useWatch({ control, name: "title" });
useEffect(() => {
if (titleValue) {
const slugified = titleValue
.toLowerCase()
.trim()
.replace(/\s+/g, "-")
.replace(/[^\w-]+/g, ""); // optional: hapus karakter non-alfanumerik
setValue("slug", slugified);
}
}, [titleValue, setValue]);
// useEffect(() => {
// async function initState() {
// getCategories();
@ -359,8 +372,8 @@ export default function FormBlog() {
</div>
</Card>
<div className="w-full lg:w-4/12">
<Card className=" h-[600px]">
<div className="px-3 py-3">
<Card className=" h-[600px] px-3 py-3">
<div className="px-3 py-3 flex flex-col">
<label htmlFor="fileInput">Gambar Utama</label>
<input id="fileInput" type="file" onChange={handleImageChange} />
</div>

View File

@ -20,10 +20,12 @@ import {
} from "@/components/ui/select";
import { Avatar, AvatarImage } from "@/components/ui/avatar";
import {
deleteEscalationDiscussion,
getEscalationDiscussion,
getTicketingDetail,
getTicketingInternalDetail,
getTicketingInternalDiscussion,
saveEscalationDiscussion,
saveTicketInternalReply,
} from "@/service/communication/communication";
import { Textarea } from "@/components/ui/textarea";
@ -33,6 +35,7 @@ import { loading } from "@/lib/swal";
import { id } from "date-fns/locale";
import { htmlToString } from "@/utils/globals";
import InfoLainnyaModal from "../ticketing/info-lainnya";
import { PlusIcon } from "lucide-react";
const taskSchema = z.object({
title: z.string().min(1, { message: "Judul diperlukan" }),
@ -62,25 +65,12 @@ export default function FormDetailEscalation() {
const [detail, setDetail] = useState<any>();
const [ticketReply, setTicketReply] = useState<replyDetail[]>([]);
const [replyVisible, setReplyVisible] = useState(false);
const [listDiscussion, setListDiscussion] = useState();
const [message, setMessage] = useState("");
const [activeReplyId, setActiveReplyId] = useState<number | null>(null);
const [selectedPriority, setSelectedPriority] = useState("");
const [openEmergencyModal, setOpenEmergencyModal] = useState(false);
const [replyMessage, setReplyMessage] = useState("");
const [replies, setReplies] = useState([
{
id: 1,
name: "Mabes Polri - Approver",
message: "test",
timestamp: "2024-12-20 00:56:10",
},
{
id: 2,
name: "Mabes Polri - Approver",
message: "balas",
timestamp: "2025-01-18 17:42:48",
},
]);
const [listDiscussion, setListDiscussion] = useState([]);
const [message, setMessage] = useState("");
const {
control,
@ -109,40 +99,75 @@ export default function FormDetailEscalation() {
}
const handleReply = () => {
setReplyVisible((prev) => !prev); // Toggle visibility
setReplyVisible((prev) => !prev);
};
// useEffect(() => {
// async function initState() {
// if (id != undefined) {
// loading();
// const responseGet = await getEscalationDiscussion(id);
// close();
// console.log("escal data", responseGet?.data);
// setListDiscussion(responseGet?.data?.data);
// }
// }
// initState();
// }, [id]);
const handleSendReply = () => {
if (replyMessage.trim() === "") return;
const newReply = {
id: replies.length + 1,
name: "Mabes Polri - Approver", // Sesuaikan dengan data dinamis jika ada
message: replyMessage,
timestamp: new Date().toISOString().slice(0, 19).replace("T", " "),
useEffect(() => {
const fetchDiscussion = async () => {
const response = await getEscalationDiscussion(id);
setListDiscussion(response?.data?.data || []);
};
setReplies([...replies, newReply]);
setReplyMessage("");
fetchDiscussion();
}, []);
const postData = async () => {
if (!message.trim()) return;
const payload = {
ticketId: id,
message,
parentId: null,
};
try {
await saveEscalationDiscussion(payload);
setMessage("");
const response = await getEscalationDiscussion(id);
setListDiscussion(response?.data?.data || []);
} catch (error) {
console.error("Gagal mengirim tanggapan:", error);
}
};
const postDataChild = async (parentId: any) => {
const textarea = document.getElementById(
`input-comment-${parentId}`
) as HTMLTextAreaElement | null;
const replyMessage = textarea?.value;
if (!replyMessage?.trim()) return;
const payload = {
ticketId: Number(id),
parentMessageId: parentId,
message: replyMessage,
};
try {
await saveEscalationDiscussion(payload);
if (textarea) textarea.value = "";
const response = await getEscalationDiscussion(id);
setListDiscussion(response?.data?.data || []);
} catch (error) {
console.error("Gagal mengirim balasan:", error);
}
};
const openEmergencyIssueDetail = () => {
setOpenEmergencyModal(true);
};
async function deleteDataSuggestion(dataId: any) {
const response = await deleteEscalationDiscussion(dataId);
console.log(response);
const responseGet = await getEscalationDiscussion(id);
setListDiscussion(responseGet?.data?.data);
}
return (
<div>
<div className="flex">
@ -273,44 +298,121 @@ export default function FormDetailEscalation() {
</div>
<div className="mx-3 my-3">
<h3 className="text-gray-700 font-medium">Tanggapan</h3>
<div className="space-y-4">
{replies.map((reply) => (
<div key={reply.id} className="border-b pb-2">
<p className="font-semibold text-gray-800">{reply.name}</p>
<p className="text-gray-600">{reply.message}</p>
<p className="text-sm text-gray-400">{reply.timestamp}</p>
<div className="space-y-4 ml-5 mt-5">
{listDiscussion.map((parent: any) => (
<div key={parent.id} className="border-b pb-4">
<div className="flex justify-between items-start">
<div>
<p className="font-semibold text-gray-800">
{parent.messageFrom?.fullname}
</p>
<p className="text-gray-600">{parent.message}</p>
<p className="text-sm text-gray-400">
{parent.createdAt}
</p>
</div>
<button
onClick={() => deleteDataSuggestion(parent.id)}
className="text-red-500 text-sm hover:underline ml-2"
>
Hapus
</button>
</div>
{activeReplyId !== parent.id && (
<button
onClick={() => setActiveReplyId(parent.id)}
className="text-blue-500 text-sm mt-2 hover:underline"
>
Balas
</button>
)}
{activeReplyId === parent.id && (
<div className="mt-2">
<textarea
id={`input-comment-${parent.id}`}
className="w-full h-20 border border-gray-300 rounded-md p-2"
placeholder="Tulis balasan di sini..."
/>
<div className="flex justify-end gap-2 mt-2">
<button
onClick={() => setActiveReplyId(null)}
className="px-4 py-1 text-sm bg-gray-200 text-gray-800 rounded-md"
>
Batal
</button>
<button
onClick={() => {
postDataChild(parent.id);
setActiveReplyId(null);
}}
className="px-4 py-1 text-sm bg-blue-600 text-white rounded-md"
>
Kirim
</button>
</div>
</div>
)}
{parent.children?.length > 0 && (
<div className="ml-4 mt-3 space-y-3 border-l-2 pl-4 border-gray-200">
{parent.children.map((child: any) => (
<div
key={child.id}
className="flex justify-between items-start"
>
<div>
<p className="font-semibold text-gray-800">
{child.messageFrom?.fullname}
</p>
<p className="text-gray-600">{child.message}</p>
<p className="text-sm text-gray-400">
{child.createdAt}
</p>
</div>
<button
onClick={() => deleteDataSuggestion(child.id)}
className="text-red-500 text-sm hover:underline ml-2"
>
Hapus
</button>
</div>
))}
</div>
)}
</div>
))}
</div>
</div>
<div className="mx-3">
<label
htmlFor="replyMessage"
className="block text-gray-700 font-medium mb-2"
>
Tulis Tanggapan Anda
</label>
<textarea
id="replyMessage"
className="w-full h-24 border border-gray-300 rounded-md p-2"
value={replyMessage}
onChange={(e) => setReplyMessage(e.target.value)}
placeholder="Tulis tanggapan anda di sini..."
/>
<div className="flex justify-end gap-3 mt-2 mb-3">
<button
onClick={() => setReplyMessage("")}
className="px-4 py-2 bg-gray-200 text-gray-800 rounded-md"
>
Batal
</button>
<button
onClick={handleSendReply}
className="px-4 py-2 bg-blue-600 text-white rounded-md"
>
Kirim Pesan
</button>
<div className="mt-6">
<label className="block text-gray-700 font-medium mb-2">
Tulis Tanggapan Anda
</label>
<textarea
value={message}
onChange={(e) => setMessage(e.target.value)}
className="w-full h-24 border border-gray-300 rounded-md p-2"
placeholder="Tulis tanggapan anda di sini..."
/>
<Button size="sm" variant={"outline"} color="primary">
<PlusIcon />
Lampiran
</Button>
<div className="flex justify-end gap-3 mt-2 mb-3">
<button
onClick={() => setMessage("")}
className="px-4 py-2 bg-gray-200 text-gray-800 rounded-md"
>
Batal
</button>
<button
onClick={postData}
className="px-4 py-2 bg-blue-600 text-white rounded-md"
>
Kirim Pesan
</button>
</div>
</div>
</div>
</div>

View File

@ -130,7 +130,7 @@ export default function FormDetailInternal() {
}
const handleReply = () => {
setReplyVisible((prev) => !prev); // Toggle visibility
setReplyVisible((prev) => !prev);
};
const handleSendReply = async () => {
@ -149,18 +149,9 @@ export default function FormDetailInternal() {
};
try {
const response = await saveTicketInternalReply(data);
await saveTicketInternalReply(data);
// Tambahkan balasan baru ke daftar balasan
const newReply: replyDetail = {
id: response?.data?.id,
message: replyMessage,
createdAt: response?.data?.createdAt,
messageFrom: response?.data?.messageFrom,
messageTo: response?.data?.messageTo,
};
setTicketReply((prevReplies) => [newReply, ...prevReplies]);
await getTicketReply();
MySwal.fire({
title: "Sukses",
@ -168,7 +159,6 @@ export default function FormDetailInternal() {
icon: "success",
});
// Reset input dan sembunyikan form balasan
setReplyMessage("");
setReplyVisible(false);
} catch (error) {

View File

@ -30,7 +30,7 @@ import dynamic from "next/dynamic";
const taskSchema = z.object({
title: z.string().min(1, { message: "Judul diperlukan" }),
naration: z.string().min(2, {
message: z.string().min(2, {
message: "Narasi Penugasan harus lebih dari 2 karakter.",
}),
});
@ -77,13 +77,12 @@ export default function FormInternal() {
);
const animatedComponent = makeAnimated();
const [platformTypeVisible, setPlatformTypeVisible] = useState(false);
const [selectedTarget, setSelectedTarget] = useState("");
const [selectedTarget, setSelectedTarget] = useState<number | null>(null);
// Opsi untuk dropdown
const priority = [
{ value: "low", label: "Low" },
{ value: "medium", label: "Medium" },
{ value: "high", label: "High" },
{ value: 1, label: "Low" },
{ value: 2, label: "Medium" },
{ value: 3, label: "High" },
];
const {
@ -142,7 +141,6 @@ export default function FormInternal() {
const rawUser = res?.data?.data?.content;
console.log("raw user", rawUser);
// Tentukan tipe array sebagai Option[]
const optionArr: Option[] = rawUser.map((option: any) => ({
id: option?.id,
label: option?.username + option?.fullname + option?.userLevel?.name,
@ -159,9 +157,9 @@ export default function FormInternal() {
const save = async (data: TaskSchema) => {
const requestData = {
title: data.title,
narration: data.naration,
message: data.message,
target: selectedTarget,
sendToId: selectedOption?.id, // This should work now without the error
sendToId: selectedOption?.id,
};
const response = await saveTicketingInternal(requestData);
@ -176,7 +174,7 @@ export default function FormInternal() {
confirmButtonColor: "#3085d6",
confirmButtonText: "OK",
}).then(() => {
router.push("/en/shared/communication");
router.push("/in/shared/communication");
});
};
@ -198,13 +196,15 @@ export default function FormInternal() {
return (
<Card>
<div className="px-6 py-6">
<p className="text-lg font-semibold mb-3">Form Penugasan</p>
<div className=" px-6 py-6">
<p className="text-lg font-semibold mb-3"></p>
<form onSubmit={handleSubmit(onSubmit)}>
<div className="gap-5 mb-5">
<div className="flex flex-col justify-center items-center gap-5 mb-5">
{/* Input Title */}
<div className="space-y-2">
<Label>Judul</Label>
<div className="w-6/12 space-y-2">
<Label>
Judul<span className="text-red-500">*</span>
</Label>
<Controller
control={control}
name="title"
@ -222,26 +222,28 @@ export default function FormInternal() {
<p className="text-red-400 text-sm">{errors.title.message}</p>
)}
</div>
<div className="w-full">
<div className="w-6/12">
<div className="mt-5">
<Label>Priority</Label>
<Label>
Priority <span className="text-red-500">*</span>
</Label>
<Select
id="target-select"
options={priority}
onChange={(selectedOption) =>
setSelectedTarget(selectedOption?.value || "")
setSelectedTarget(selectedOption?.value ?? null)
}
placeholder="Pilih"
styles={{
control: (base) => ({
...base,
minHeight: "40px", // Ukuran sesuai dengan size="md"
minHeight: "40px",
}),
}}
/>
</div>
</div>
<div className="w-full">
<div className="w-6/12">
<div className="mt-5">
<Label>Ditunjukan Untuk</Label>
<Select
@ -255,28 +257,27 @@ export default function FormInternal() {
/>
</div>
</div>
<div className="mt-5">
<div className="w-6/12 mt-5">
<Label>Narasi Penugasan</Label>
<Controller
control={control}
name="naration"
name="message"
render={({ field: { onChange, value } }) => (
<CustomEditor onChange={onChange} initialData={value} />
)}
/>
{errors.naration?.message && (
<p className="text-red-400 text-sm">
{errors.naration.message}
</p>
{errors.message?.message && (
<p className="text-red-400 text-sm">{errors.message.message}</p>
)}
</div>
</div>
{/* Submit Button */}
<div className="mt-4">
<Button type="submit" color="primary">
Submit
</Button>
<div className="w-6/12 flex justify-end gap-3 mt-5">
<Button type="button" color="primary" variant="outline">
Batal
</Button>
<Button type="submit" color="primary">
Submit
</Button>
</div>
</div>
</form>
</div>

View File

@ -162,27 +162,26 @@ export default function FormConvertSPIT() {
const [selectedWritingStyle, setSelectedWritingStyle] =
useState("Professional");
const imageSchema = z
.object({
contentTitle: z.string().min(1, { message: "Judul diperlukan" }),
contentDescription: z
.string()
.min(2, { message: "Narasi Penugasan harus lebih dari 2 karakter." }),
contentCreator: z.string().min(1, { message: "Creator diperlukan" }),
contentRewriteDescription: z.string().optional(),
})
.refine(
(data) => {
if (isContentRewriteClicked) {
return detail?.contentRewriteDescription?.trim().length > 0;
}
return true;
},
{
path: ["contentRewriteDescription"],
message: "File hasil rewrite wajib diisi",
}
);
const imageSchema = z.object({
contentTitle: z.string().min(1, { message: "Judul diperlukan" }),
contentDescription: z
.string()
.min(2, { message: "Narasi Penugasan harus lebih dari 2 karakter." }),
contentCreator: z.string().min(1, { message: "Creator diperlukan" }),
contentRewriteDescription: z.string().optional(),
});
// .refine(
// (data) => {
// if (isContentRewriteClicked) {
// return detail?.contentRewriteDescription?.trim().length > 0;
// }
// return true;
// },
// {
// path: ["contentRewriteDescription"],
// message: "File hasil rewrite wajib diisi",
// }
// );
const options: Option[] = [
{ id: "all", label: "SEMUA" },
@ -216,7 +215,7 @@ export default function FormConvertSPIT() {
contentTitle: detail?.contentTitle || "",
contentDescription: detail?.contentDescription || "",
contentCreator: detail?.contentCreator || "",
contentRewriteDescription: detail?.contentRewriteDescription || "",
// dll
},
});
@ -809,7 +808,11 @@ export default function FormConvertSPIT() {
) : (
<CustomEditor
onChange={onChange}
initialData={articleBody || value}
initialData={
articleBody ||
detail?.contentRewriteDescription ||
value
}
/>
)
}
@ -1030,7 +1033,7 @@ export default function FormConvertSPIT() {
<Input
size="md"
type="text"
value={detail?.contentCreator}
defaultValue={detail?.contentCreator}
onChange={field.onChange}
placeholder="Enter Title"
/>
@ -1100,7 +1103,7 @@ export default function FormConvertSPIT() {
</div>
<div className="mt-4">
<Button
type="submit"
type="button"
className="bg-red-500 hover:bg-red-700"
onClick={() => deleteSpitContent()}
>

View File

@ -487,7 +487,7 @@ export default function FormAudioTaDetail() {
</p>
)}
</div>
<div className="flex items-center">
{/* <div className="flex items-center">
<div className="py-3 w-full space-y-2">
<Label>{t("category")}</Label>
<Select
@ -509,7 +509,7 @@ export default function FormAudioTaDetail() {
</SelectContent>
</Select>
</div>
</div>
</div> */}
<div className="py-3 space-y-2">
<Label>{t("description")}</Label>
@ -569,8 +569,7 @@ export default function FormAudioTaDetail() {
</div>
</Card>
<div className="w-full lg:w-4/12">
<Card className="pb-3">
<div className="px-3 py-3">
{/* <div className="px-3 py-3">
<div className="space-y-2">
<Label>{t("creator")}</Label>
<Controller
@ -663,8 +662,8 @@ export default function FormAudioTaDetail() {
{formatDateToIndonesian(approval?.approvalDate)}
</p>
<ApprovalHistoryModal id={Number(id)} />
</div>
{/* {detail?.isPublish == false ? (
</div> */}
{/* {detail?.isPublish == false ? (
<div className="p-3">
<Button className="bg-blue-600">Publish</Button>
</div>
@ -672,218 +671,212 @@ export default function FormAudioTaDetail() {
""
)} */}
<Dialog open={modalOpen} onOpenChange={setModalOpen}>
<DialogContent size="md">
<DialogHeader>
<DialogTitle>{t("leave-comment")}</DialogTitle>
</DialogHeader>
{status == "2"
? files?.map((file, index) => (
<div
key={file.id}
className="flex flex-row gap-2 items-center"
<Dialog open={modalOpen} onOpenChange={setModalOpen}>
<DialogContent size="md">
<DialogHeader>
<DialogTitle>{t("leave-comment")}</DialogTitle>
</DialogHeader>
{status == "2"
? files?.map((file, index) => (
<div
key={file.id}
className="flex flex-row gap-2 items-center"
>
{/* <img src={file.url} className="w-[200px]" /> */}
<svg
xmlns="http://www.w3.org/2000/svg"
width="48"
height="48"
viewBox="0 0 20 20"
>
{/* <img src={file.url} className="w-[200px]" /> */}
<svg
xmlns="http://www.w3.org/2000/svg"
width="48"
height="48"
viewBox="0 0 20 20"
>
<path
fill="currentColor"
d="M14.702 2.226A1 1 0 0 1 16 3.18v6.027a5.5 5.5 0 0 0-1-.184V6.18L8 8.368V15.5a2.5 2.5 0 1 1-1-2V5.368a1 1 0 0 1 .702-.955zM8 7.32l7-2.187V3.18L8 5.368zM5.5 14a1.5 1.5 0 1 0 0 3a1.5 1.5 0 0 0 0-3m13.5.5a4.5 4.5 0 1 1-9 0a4.5 4.5 0 0 1 9 0m-2.265-.436l-2.994-1.65a.5.5 0 0 0-.741.438v3.3a.5.5 0 0 0 .741.438l2.994-1.65a.5.5 0 0 0 0-.876"
/>
</svg>{" "}
<div className="flex flex-col gap-2 w-full">
<div className="flex justify-between text-sm">
{file.fileName}
<a
onClick={() =>
handleDeleteFileApproval(file.id)
}
>
<Icon icon="humbleicons:times" color="red" />
</a>
</div>
{isUserMabesApprover && (
<div className="flex flex-row gap-2">
<div className="flex items-center space-x-2">
<Checkbox
id="terms"
value="all"
checked={filePlacements[index]?.includes(
"all"
)}
onCheckedChange={(e) =>
setupPlacement(index, "all", Boolean(e))
}
/>
<label
htmlFor="terms"
className="text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
>
{t("all")}
</label>
</div>
<div className="flex items-center space-x-2">
<Checkbox
id="terms"
checked={filePlacements[index]?.includes(
"mabes"
)}
onCheckedChange={(e) =>
setupPlacement(index, "mabes", Boolean(e))
}
/>
<label
htmlFor="terms"
className="text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
>
Nasional
</label>
</div>
<div className="flex items-center space-x-2">
<Checkbox
id="terms"
checked={filePlacements[index]?.includes(
"polda"
)}
onCheckedChange={(e) =>
setupPlacement(index, "polda", Boolean(e))
}
/>
<label
htmlFor="terms"
className="text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
>
Wilayah
</label>
</div>
<div className="flex items-center space-x-2">
<Checkbox
id="terms"
checked={filePlacements[index]?.includes(
"international"
)}
onCheckedChange={(e) =>
setupPlacement(
index,
"international",
Boolean(e)
)
}
/>
<label
htmlFor="terms"
className="text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
>
Internasional
</label>
</div>
</div>
)}
<path
fill="currentColor"
d="M14.702 2.226A1 1 0 0 1 16 3.18v6.027a5.5 5.5 0 0 0-1-.184V6.18L8 8.368V15.5a2.5 2.5 0 1 1-1-2V5.368a1 1 0 0 1 .702-.955zM8 7.32l7-2.187V3.18L8 5.368zM5.5 14a1.5 1.5 0 1 0 0 3a1.5 1.5 0 0 0 0-3m13.5.5a4.5 4.5 0 1 1-9 0a4.5 4.5 0 0 1 9 0m-2.265-.436l-2.994-1.65a.5.5 0 0 0-.741.438v3.3a.5.5 0 0 0 .741.438l2.994-1.65a.5.5 0 0 0 0-.876"
/>
</svg>{" "}
<div className="flex flex-col gap-2 w-full">
<div className="flex justify-between text-sm">
{file.fileName}
<a
onClick={() => handleDeleteFileApproval(file.id)}
>
<Icon icon="humbleicons:times" color="red" />
</a>
</div>
</div>
))
: ""}
<div className="flex flex-col gap-4">
<Textarea
placeholder="Type your message here."
value={description}
onChange={(e) => setDescription(e.target.value)}
/>
</div>
{status == "3" || status == "4" ? (
<div className="flex flex-row gap-2">
<Badge
color={
description === "Kualitas media kurang baik"
? "primary"
: "default"
}
className="cursor-pointer"
onClick={() =>
setDescription("Kualitas media kurang baik")
}
>
Kualitas media kurang baik
</Badge>
{isUserMabesApprover && (
<div className="flex flex-row gap-2">
<div className="flex items-center space-x-2">
<Checkbox
id="terms"
value="all"
checked={filePlacements[index]?.includes(
"all"
)}
onCheckedChange={(e) =>
setupPlacement(index, "all", Boolean(e))
}
/>
<label
htmlFor="terms"
className="text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
>
{t("all")}
</label>
</div>
<div className="flex items-center space-x-2">
<Checkbox
id="terms"
checked={filePlacements[index]?.includes(
"mabes"
)}
onCheckedChange={(e) =>
setupPlacement(index, "mabes", Boolean(e))
}
/>
<label
htmlFor="terms"
className="text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
>
Nasional
</label>
</div>
<div className="flex items-center space-x-2">
<Checkbox
id="terms"
checked={filePlacements[index]?.includes(
"polda"
)}
onCheckedChange={(e) =>
setupPlacement(index, "polda", Boolean(e))
}
/>
<label
htmlFor="terms"
className="text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
>
Wilayah
</label>
</div>
<Badge
color={
description === "Deskripsi kurang lengkap"
? "primary"
: "default"
}
className="cursor-pointer"
onClick={() =>
setDescription("Deskripsi kurang lengkap")
}
>
Deskripsi kurang lengkap
</Badge>
<Badge
color={
description === "Judul kurang tepat"
? "primary"
: "default"
}
className="cursor-pointer"
onClick={() => setDescription("Judul kurang tepat")}
>
Judul kurang tepat
</Badge>
</div>
) : (
<div className="flex flex-row gap-2">
<Badge
color={
description === "Konten sangat bagus"
? "primary"
: "default"
}
className="cursor-pointer"
onClick={() => setDescription("Konten sangat bagus")}
>
Konten sangat bagus
</Badge>
<Badge
color={
description === "Konten menarik"
? "primary"
: "default"
}
className="cursor-pointer"
onClick={() => setDescription("Konten menarik")}
>
Konten menarik
</Badge>
</div>
)}
<DialogFooter>
<Button
type="button"
color="primary"
onClick={() => submit()}
<div className="flex items-center space-x-2">
<Checkbox
id="terms"
checked={filePlacements[index]?.includes(
"international"
)}
onCheckedChange={(e) =>
setupPlacement(
index,
"international",
Boolean(e)
)
}
/>
<label
htmlFor="terms"
className="text-xs font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"
>
Internasional
</label>
</div>
</div>
)}
</div>
</div>
))
: ""}
<div className="flex flex-col gap-4">
<Textarea
placeholder="Type your message here."
value={description}
onChange={(e) => setDescription(e.target.value)}
/>
</div>
{status == "3" || status == "4" ? (
<div className="flex flex-row gap-2">
<Badge
color={
description === "Kualitas media kurang baik"
? "primary"
: "default"
}
className="cursor-pointer"
onClick={() =>
setDescription("Kualitas media kurang baik")
}
>
{t("submit")}
</Button>
<Button
type="button"
color="destructive"
onClick={() => {
setModalOpen(false);
}}
Kualitas media kurang baik
</Badge>
<Badge
color={
description === "Deskripsi kurang lengkap"
? "primary"
: "default"
}
className="cursor-pointer"
onClick={() => setDescription("Deskripsi kurang lengkap")}
>
{t("cancel")}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
</Card>
{Number(detail?.needApprovalFromLevel) == Number(userLevelId) ? (
Deskripsi kurang lengkap
</Badge>
<Badge
color={
description === "Judul kurang tepat"
? "primary"
: "default"
}
className="cursor-pointer"
onClick={() => setDescription("Judul kurang tepat")}
>
Judul kurang tepat
</Badge>
</div>
) : (
<div className="flex flex-row gap-2">
<Badge
color={
description === "Konten sangat bagus"
? "primary"
: "default"
}
className="cursor-pointer"
onClick={() => setDescription("Konten sangat bagus")}
>
Konten sangat bagus
</Badge>
<Badge
color={
description === "Konten menarik" ? "primary" : "default"
}
className="cursor-pointer"
onClick={() => setDescription("Konten menarik")}
>
Konten menarik
</Badge>
</div>
)}
<DialogFooter>
<Button
type="button"
color="primary"
onClick={() => submit()}
>
{t("submit")}
</Button>
<Button
type="button"
color="destructive"
onClick={() => {
setModalOpen(false);
}}
>
{t("cancel")}
</Button>
</DialogFooter>
</DialogContent>
</Dialog>
{/* {Number(detail?.needApprovalFromLevel) == Number(userLevelId) ? (
Number(detail?.uploadedById) == Number(userId) ? (
""
) : (
@ -915,7 +908,7 @@ export default function FormAudioTaDetail() {
)
) : (
""
)}
)} */}
</div>
</div>
) : (

View File

@ -459,7 +459,7 @@ export default function FormTeksTaDetail() {
</p>
)}
</div>
<div className="flex items-center">
{/* <div className="flex items-center">
<div className="py-3 w-full space-y-2">
<Label>{t("category")}</Label>
<Select
@ -481,7 +481,7 @@ export default function FormTeksTaDetail() {
</SelectContent>
</Select>
</div>
</div>
</div> */}
<div className="py-3 space-y-2">
<Label>{t("description")}</Label>
@ -584,7 +584,7 @@ export default function FormTeksTaDetail() {
</Card>
<div className="w-full lg:w-4/12">
<Card className="pb-3">
<div className="px-3 py-3">
{/* <div className="px-3 py-3">
<div className="space-y-2">
<Label>{t("creator")}</Label>
<Controller
@ -606,7 +606,7 @@ export default function FormTeksTaDetail() {
</p>
)}
</div>
</div>
</div> */}
{/* <div className="mt-3 px-3">
<Label>Pratinjau Gambar Utama</Label>
<Card className="mt-2">
@ -617,7 +617,7 @@ export default function FormTeksTaDetail() {
/>
</Card>
</div> */}
<div className="px-3 py-3">
{/* <div className="px-3 py-3">
<div className="space-y-2">
<Label>{t("tags")}</Label>
<div className="flex flex-wrap gap-2">
@ -633,8 +633,8 @@ export default function FormTeksTaDetail() {
))}
</div>
</div>
</div>
<div className="px-3 py-3">
</div> */}
{/* <div className="px-3 py-3">
<div className="flex flex-col gap-6 space-y-2">
<Label>{t("publish-target")}</Label>
<div className="flex gap-2 items-center">
@ -674,8 +674,8 @@ export default function FormTeksTaDetail() {
<SuggestionModal
id={Number(id)}
numberOfSuggestion={detail?.numberOfSuggestion}
/>
<div className="px-3 py-3 border mx-3">
/> */}
{/* <div className="px-3 py-3 border mx-3">
<p>{t("information")}:</p>
<p className="text-sm text-slate-400">{detail?.statusName}</p>
<p>Komentar</p>
@ -686,7 +686,7 @@ export default function FormTeksTaDetail() {
{formatDateToIndonesian(approval?.approvalDate)}
</p>
<ApprovalHistoryModal id={Number(id)} />
</div>
</div> */}
{/* {detail?.isPublish == false ? (
<div className="p-3">
<Button className="bg-blue-600">Publish</Button>

View File

@ -449,7 +449,7 @@ export default function FormVideoTaDetail() {
</p>
)}
</div>
<div className="flex items-center">
{/* <div className="flex items-center">
<div className="py-3 w-full space-y-2">
<Label>{t("category")}</Label>
<Select
@ -471,7 +471,7 @@ export default function FormVideoTaDetail() {
</SelectContent>
</Select>
</div>
</div>
</div> */}
<div className="py-3 space-y-2">
<Label>{t("description")}</Label>
@ -538,7 +538,7 @@ export default function FormVideoTaDetail() {
</Card>
<div className="w-full lg:w-4/12">
<Card className="pb-3">
<div className="px-3 py-3">
{/* <div className="px-3 py-3">
<div className="space-y-2">
<Label>{t("creator")}</Label>
<Controller
@ -640,7 +640,7 @@ export default function FormVideoTaDetail() {
{formatDateToIndonesian(approval?.approvalDate)}
</p>
<ApprovalHistoryModal id={Number(id)} />
</div>
</div> */}
{/* {detail?.isPublish == false ? (
<div className="p-3">
<Button className="bg-blue-600">Publish</Button>

View File

@ -156,3 +156,8 @@ export async function saveTicketsQuestion(data: any) {
const url = "ticketing/convert-question";
return httpPostInterceptor(url, data);
}
export async function deleteEscalationDiscussion(id: any) {
const url = `ticketing/escalation/discussion?id=${id}`;
return httpDeleteInterceptor(url);
}