Merge branch 'dev-anang' of https://gitlab.com/hanifsalafi/mediahub_redesign
This commit is contained in:
commit
d5be139635
|
|
@ -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>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,15 @@
|
|||
import FormAudioTaDetail from "@/components/form/content/task-ta/audio-detail-form";
|
||||
import SiteBreadcrumb from "@/components/site-breadcrumb";
|
||||
|
||||
const AudioDetailPage = async () => {
|
||||
return (
|
||||
<div>
|
||||
<SiteBreadcrumb />
|
||||
<div className="space-y-4">
|
||||
<FormAudioTaDetail />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default AudioDetailPage;
|
||||
|
|
@ -1,3 +1,4 @@
|
|||
import FormImageTaDetail from "@/components/form/content/task-ta/image-detail-form";
|
||||
import FormImageDetail from "@/components/form/content/task-ta/image-detail-form";
|
||||
import SiteBreadcrumb from "@/components/site-breadcrumb";
|
||||
|
||||
|
|
@ -6,7 +7,7 @@ const ImageDetailPage = async () => {
|
|||
<div>
|
||||
<SiteBreadcrumb />
|
||||
<div className="space-y-4">
|
||||
<FormImageDetail />
|
||||
<FormImageTaDetail />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,16 @@
|
|||
import FormTeksTaDetail from "@/components/form/content/task-ta/teks-detail-form";
|
||||
import FormTeksDetail from "@/components/form/content/task-ta/teks-detail-form";
|
||||
import SiteBreadcrumb from "@/components/site-breadcrumb";
|
||||
|
||||
const TeksDetailPage = async () => {
|
||||
return (
|
||||
<div>
|
||||
<SiteBreadcrumb />
|
||||
<div className="space-y-4">
|
||||
<FormTeksTaDetail />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default TeksDetailPage;
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
import FormVideoTaDetail from "@/components/form/content/task-ta/video-detail-form";
|
||||
import FormVideoDetail from "@/components/form/content/task-ta/video-detail-form";
|
||||
import SiteBreadcrumb from "@/components/site-breadcrumb";
|
||||
|
||||
const VideoDetailPage = async () => {
|
||||
return (
|
||||
<div>
|
||||
<SiteBreadcrumb />
|
||||
<div className="space-y-4">
|
||||
<FormVideoTaDetail />
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default VideoDetailPage;
|
||||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -103,20 +103,6 @@ export default function FormQuestionsDetail() {
|
|||
const [selectedOperatorEscalation, setSelectedOperatorEscalation] = useState<
|
||||
string[]
|
||||
>([]);
|
||||
// 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 {
|
||||
control,
|
||||
|
|
@ -156,12 +142,11 @@ export default function FormQuestionsDetail() {
|
|||
setDetail(detail);
|
||||
setDetailTickets(detail);
|
||||
|
||||
// Ambil escalationTeams seperti ":891:"
|
||||
if (detail?.escalationTeams) {
|
||||
const teamIds = detail.escalationTeams
|
||||
.split(":")
|
||||
.filter((id: string) => id); // hapus string kosong
|
||||
setSelectedOperatorEscalation(teamIds); // set ke state
|
||||
.filter((id: string) => id);
|
||||
setSelectedOperatorEscalation(teamIds);
|
||||
}
|
||||
|
||||
getTicketReply();
|
||||
|
|
@ -409,7 +394,7 @@ export default function FormQuestionsDetail() {
|
|||
|
||||
{/* Tag yang ditampilkan secara kolom */}
|
||||
{selectedOperator.length > 0 && (
|
||||
<div className="flex flex-col gap-2 mb-2">
|
||||
<div className="flex flex-row gap-2 mb-2">
|
||||
{selectedOperator.map((id) => {
|
||||
const label = operatorOpt.find(
|
||||
(op: any) => op.value === id
|
||||
|
|
@ -453,6 +438,7 @@ export default function FormQuestionsDetail() {
|
|||
className="flex items-center space-x-2 cursor-pointer px-2 py-1 hover:bg-gray-100 rounded"
|
||||
>
|
||||
<input
|
||||
disabled
|
||||
type="checkbox"
|
||||
checked={selectedOperator.includes(op.value)}
|
||||
onChange={(e) => {
|
||||
|
|
@ -495,7 +481,7 @@ export default function FormQuestionsDetail() {
|
|||
<Label>Eskalasi Untuk</Label>
|
||||
|
||||
{selectedOperatorEscalation.length > 0 && (
|
||||
<div className="flex flex-col gap-2 mb-2">
|
||||
<div className="flex flex-row gap-2 mb-2">
|
||||
{selectedOperatorEscalation.map((id) => {
|
||||
const operator = curatorOpt.find(
|
||||
(op: any) => op.value === id
|
||||
|
|
|
|||
|
|
@ -43,7 +43,7 @@ import {
|
|||
import { ChevronDownIcon } from "lucide-react";
|
||||
import { getOperatorUser } from "@/service/management-user/management-user";
|
||||
import makeAnimated from "react-select/animated";
|
||||
import Select from "react-select";
|
||||
import Select, { ActionMeta, MultiValue } from "react-select";
|
||||
|
||||
interface Option {
|
||||
id: string;
|
||||
|
|
@ -109,9 +109,7 @@ export default function FormQuestionsForward() {
|
|||
const [selectedOperator, setSelectedOperator] = useState<string[]>([]);
|
||||
const [options, setOptions] = useState<Option[]>([]);
|
||||
const animatedComponent = makeAnimated();
|
||||
const [selectedOption, setSelectedOption] = useState<Option | undefined>(
|
||||
undefined
|
||||
);
|
||||
const [selectedOption, setSelectedOption] = useState<Option[]>([]);
|
||||
const [replies, setReplies] = useState([
|
||||
{
|
||||
id: 1,
|
||||
|
|
@ -195,7 +193,7 @@ export default function FormQuestionsForward() {
|
|||
parentCommentId: detailTickets?.feedId,
|
||||
operatorTeam: selectedOperator.join(","),
|
||||
isEscalation: true,
|
||||
communicationTeam: selectedOption?.id,
|
||||
communicationTeam: selectedOption.map((item) => item.id).join(","),
|
||||
};
|
||||
|
||||
const response = await saveTicketsQuestion(payload);
|
||||
|
|
@ -206,7 +204,6 @@ export default function FormQuestionsForward() {
|
|||
icon: "success",
|
||||
});
|
||||
|
||||
// Refresh data jika perlu
|
||||
getTicketReply();
|
||||
} catch (error) {
|
||||
console.error("Gagal update:", error);
|
||||
|
|
@ -218,9 +215,11 @@ export default function FormQuestionsForward() {
|
|||
}
|
||||
};
|
||||
|
||||
const handleChange = (e: any) => {
|
||||
const selected = e;
|
||||
setSelectedOption(selected);
|
||||
const handleChange = (
|
||||
selected: MultiValue<Option>,
|
||||
_actionMeta: ActionMeta<Option>
|
||||
) => {
|
||||
setSelectedOption([...selected]);
|
||||
};
|
||||
|
||||
const formatOptionLabel = (option: Option) => (
|
||||
|
|
@ -353,9 +352,8 @@ export default function FormQuestionsForward() {
|
|||
<div className="mt-5 px-3 mb-3 flex flex-col gap-y-3">
|
||||
<Label>Operator</Label>
|
||||
|
||||
{/* Tag yang ditampilkan secara kolom */}
|
||||
{selectedOperator.length > 0 && (
|
||||
<div className="flex flex-col gap-2 mb-2">
|
||||
<div className="flex flex-row gap-2 mb-2">
|
||||
{selectedOperator.map((id) => {
|
||||
const label = operatorOpt.find(
|
||||
(op: any) => op.value === id
|
||||
|
|
@ -433,7 +431,7 @@ export default function FormQuestionsForward() {
|
|||
components={animatedComponent}
|
||||
onChange={handleChange}
|
||||
formatOptionLabel={formatOptionLabel}
|
||||
isMulti={false}
|
||||
isMulti={true}
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -125,7 +125,6 @@ export default function FormConvertSPIT() {
|
|||
const [selectedCategoryId, setSelectedCategoryId] = useState<number | null>(
|
||||
null
|
||||
);
|
||||
const [tags, setTags] = useState<any[]>([]);
|
||||
const [detail, setDetail] = useState<any>();
|
||||
const [refresh, setRefresh] = useState(false);
|
||||
const [selectedPublishers, setSelectedPublishers] = useState<number[]>([]);
|
||||
|
|
@ -159,30 +158,31 @@ export default function FormConvertSPIT() {
|
|||
const [filePlacements, setFilePlacements] = useState<string[][]>([]);
|
||||
const [isUserMabesApprover, setIsUserMabesApprover] = useState(false);
|
||||
const [files, setFiles] = useState<FileType[]>([]);
|
||||
const [tags, setTags] = useState<any[]>([]);
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
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 +216,7 @@ export default function FormConvertSPIT() {
|
|||
contentTitle: detail?.contentTitle || "",
|
||||
contentDescription: detail?.contentDescription || "",
|
||||
contentCreator: detail?.contentCreator || "",
|
||||
contentRewriteDescription: detail?.contentRewriteDescription || "",
|
||||
|
||||
// dll
|
||||
},
|
||||
});
|
||||
|
|
@ -368,6 +368,13 @@ export default function FormConvertSPIT() {
|
|||
setSelectedTarget(matchingCategory.name);
|
||||
}
|
||||
|
||||
if (details?.contentTag) {
|
||||
const initialTags = details.contentTag
|
||||
.split(",")
|
||||
.map((tag: string) => tag.trim());
|
||||
setTags(initialTags);
|
||||
}
|
||||
|
||||
// setSelectedTarget(details.categoryId); // Untuk dropdown
|
||||
}
|
||||
}
|
||||
|
|
@ -478,13 +485,14 @@ export default function FormConvertSPIT() {
|
|||
selectedFileType === "original"
|
||||
? data.contentDescription
|
||||
: data.contentRewriteDescription;
|
||||
const finalTags = tags.join(", ");
|
||||
|
||||
const requestData = {
|
||||
spitId: id,
|
||||
title: data.contentTitle,
|
||||
description,
|
||||
htmlDescription: description,
|
||||
tags: "siap",
|
||||
tags: finalTags,
|
||||
categoryId: selectedCategoryId,
|
||||
publishedFor: publishedFor.join(","),
|
||||
creator: data.contentCreator,
|
||||
|
|
@ -648,6 +656,19 @@ export default function FormConvertSPIT() {
|
|||
});
|
||||
}
|
||||
|
||||
const handleAddTag = (e: React.KeyboardEvent<HTMLInputElement>) => {
|
||||
if (e.key === "Enter" && inputRef.current?.value.trim()) {
|
||||
e.preventDefault();
|
||||
const newTag = inputRef.current.value.trim();
|
||||
|
||||
if (!tags.includes(newTag)) {
|
||||
setTags((prevTags) => [...prevTags, newTag]);
|
||||
}
|
||||
|
||||
inputRef.current.value = "";
|
||||
}
|
||||
};
|
||||
|
||||
return (
|
||||
<>
|
||||
<Form {...form}>
|
||||
|
|
@ -809,7 +830,11 @@ export default function FormConvertSPIT() {
|
|||
) : (
|
||||
<CustomEditor
|
||||
onChange={onChange}
|
||||
initialData={articleBody || value}
|
||||
initialData={
|
||||
articleBody ||
|
||||
detail?.contentRewriteDescription ||
|
||||
value
|
||||
}
|
||||
/>
|
||||
)
|
||||
}
|
||||
|
|
@ -1030,7 +1055,7 @@ export default function FormConvertSPIT() {
|
|||
<Input
|
||||
size="md"
|
||||
type="text"
|
||||
value={detail?.contentCreator}
|
||||
defaultValue={detail?.contentCreator}
|
||||
onChange={field.onChange}
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
|
|
@ -1051,17 +1076,22 @@ export default function FormConvertSPIT() {
|
|||
<div className="px-3 py-3">
|
||||
<div className="space-y-2">
|
||||
<Label>{t("tags")}</Label>
|
||||
<Input
|
||||
type="text"
|
||||
id="tags"
|
||||
placeholder="Add a tag and press Enter"
|
||||
onKeyDown={handleAddTag}
|
||||
ref={inputRef}
|
||||
/>
|
||||
<div className="flex flex-wrap gap-2">
|
||||
{detail?.contentTag
|
||||
?.split(",")
|
||||
.map((tag: any, index: any) => (
|
||||
<Badge
|
||||
key={index}
|
||||
className="border rounded-md px-2 py-2"
|
||||
>
|
||||
{tag.trim()}
|
||||
</Badge>
|
||||
))}
|
||||
{tags.map((tag, index) => (
|
||||
<Badge
|
||||
key={index}
|
||||
className="border rounded-md px-2 py-2"
|
||||
>
|
||||
{tag}
|
||||
</Badge>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -1100,7 +1130,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()}
|
||||
>
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ const ViewEditor = dynamic(
|
|||
{ ssr: false }
|
||||
);
|
||||
|
||||
export default function FormAudioDetail() {
|
||||
export default function FormAudioTaDetail() {
|
||||
const MySwal = withReactContent(Swal);
|
||||
const router = useRouter();
|
||||
const userId = getCookiesDecrypt("uie");
|
||||
|
|
@ -487,7 +487,7 @@ export default function FormAudioDetail() {
|
|||
</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 FormAudioDetail() {
|
|||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
<div className="py-3 space-y-2">
|
||||
<Label>{t("description")}</Label>
|
||||
|
|
@ -569,8 +569,7 @@ export default function FormAudioDetail() {
|
|||
</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 FormAudioDetail() {
|
|||
{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 FormAudioDetail() {
|
|||
""
|
||||
)} */}
|
||||
|
||||
<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 FormAudioDetail() {
|
|||
)
|
||||
) : (
|
||||
""
|
||||
)}
|
||||
)} */}
|
||||
</div>
|
||||
</div>
|
||||
) : (
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ const ViewEditor = dynamic(
|
|||
{ ssr: false }
|
||||
);
|
||||
|
||||
export default function FormImageDetail() {
|
||||
export default function FormImageTaDetail() {
|
||||
const MySwal = withReactContent(Swal);
|
||||
const router = useRouter();
|
||||
const userId = getCookiesDecrypt("uie");
|
||||
|
|
|
|||
|
|
@ -111,7 +111,7 @@ const ViewEditor = dynamic(
|
|||
{ ssr: false }
|
||||
);
|
||||
|
||||
export default function FormTeksDetail() {
|
||||
export default function FormTeksTaDetail() {
|
||||
const MySwal = withReactContent(Swal);
|
||||
const router = useRouter();
|
||||
const userId = getCookiesDecrypt("uie");
|
||||
|
|
@ -459,7 +459,7 @@ export default function FormTeksDetail() {
|
|||
</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 FormTeksDetail() {
|
|||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
<div className="py-3 space-y-2">
|
||||
<Label>{t("description")}</Label>
|
||||
|
|
@ -584,7 +584,7 @@ export default function FormTeksDetail() {
|
|||
</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 FormTeksDetail() {
|
|||
</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 FormTeksDetail() {
|
|||
/>
|
||||
</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 FormTeksDetail() {
|
|||
))}
|
||||
</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 FormTeksDetail() {
|
|||
<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 FormTeksDetail() {
|
|||
{formatDateToIndonesian(approval?.approvalDate)}
|
||||
</p>
|
||||
<ApprovalHistoryModal id={Number(id)} />
|
||||
</div>
|
||||
</div> */}
|
||||
{/* {detail?.isPublish == false ? (
|
||||
<div className="p-3">
|
||||
<Button className="bg-blue-600">Publish</Button>
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ const ViewEditor = dynamic(
|
|||
{ ssr: false }
|
||||
);
|
||||
|
||||
export default function FormVideoDetail() {
|
||||
export default function FormVideoTaDetail() {
|
||||
const MySwal = withReactContent(Swal);
|
||||
const router = useRouter();
|
||||
const userId = getCookiesDecrypt("uie");
|
||||
|
|
@ -449,7 +449,7 @@ export default function FormVideoDetail() {
|
|||
</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 FormVideoDetail() {
|
|||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
|
||||
<div className="py-3 space-y-2">
|
||||
<Label>{t("description")}</Label>
|
||||
|
|
@ -538,7 +538,7 @@ export default function FormVideoDetail() {
|
|||
</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 FormVideoDetail() {
|
|||
{formatDateToIndonesian(approval?.approvalDate)}
|
||||
</p>
|
||||
<ApprovalHistoryModal id={Number(id)} />
|
||||
</div>
|
||||
</div> */}
|
||||
{/* {detail?.isPublish == false ? (
|
||||
<div className="p-3">
|
||||
<Button className="bg-blue-600">Publish</Button>
|
||||
|
|
|
|||
|
|
@ -481,7 +481,7 @@ export default function FormVideo() {
|
|||
let id = Cookies.get("idCreate");
|
||||
|
||||
if (scheduleId !== undefined) {
|
||||
requestData.attachFromScheduleId = Number(scheduleId); // ✅ Tambahkan nilai ini
|
||||
requestData.attachFromScheduleId = Number(scheduleId);
|
||||
}
|
||||
|
||||
if (id == undefined) {
|
||||
|
|
@ -495,14 +495,14 @@ export default function FormVideo() {
|
|||
Cookies.set("idCreate", response?.data?.data, { expires: 1 });
|
||||
id = response?.data?.data;
|
||||
|
||||
// Upload Thumbnail
|
||||
const formMedia = new FormData();
|
||||
const thumbnail = files[0];
|
||||
formMedia.append("file", thumbnail);
|
||||
const responseThumbnail = await uploadThumbnail(id, formMedia);
|
||||
if (responseThumbnail?.error == true) {
|
||||
error(responseThumbnail?.message);
|
||||
return false;
|
||||
if (thumbnail) {
|
||||
const formMedia = new FormData();
|
||||
formMedia.append("file", thumbnail);
|
||||
const responseThumbnail = await uploadThumbnail(formMedia, id);
|
||||
if (responseThumbnail?.error) {
|
||||
error(responseThumbnail.message);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -526,6 +526,14 @@ export default function FormVideo() {
|
|||
// MySwal.fire("Sukses", "Data berhasil disimpan.", "success");
|
||||
};
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
if (preview) {
|
||||
URL.revokeObjectURL(preview);
|
||||
}
|
||||
};
|
||||
}, [preview]);
|
||||
|
||||
const onSubmit = (data: VideoSchema) => {
|
||||
MySwal.fire({
|
||||
title: "Simpan Data",
|
||||
|
|
@ -633,12 +641,10 @@ export default function FormVideo() {
|
|||
const handleImageChange = (e: React.ChangeEvent<HTMLInputElement>) => {
|
||||
const file = e.target.files?.[0];
|
||||
if (file) {
|
||||
setThumbnail(file);
|
||||
setThumbnail(file); // Simpan file asli tanpa dimodifikasi
|
||||
setPreview(URL.createObjectURL(file)); // Simpan preview string terpisah
|
||||
console.log("Selected Thumbnail:", file);
|
||||
}
|
||||
if (file) {
|
||||
setPreview(URL.createObjectURL(file));
|
||||
}
|
||||
};
|
||||
|
||||
const renderFilePreview = (file: FileWithPreview) => {
|
||||
|
|
@ -1075,10 +1081,10 @@ export default function FormVideo() {
|
|||
)}
|
||||
</div>
|
||||
</div>
|
||||
{/* <div className="px-3 py-3">
|
||||
<div className="px-3 py-3">
|
||||
<Label htmlFor="fileInput">Gambar Utama</Label>
|
||||
<Input id="fileInput" type="file" onChange={handleImageChange} />
|
||||
</div> */}
|
||||
</div>
|
||||
{preview && (
|
||||
<div className="mt-3 px-3">
|
||||
<img
|
||||
|
|
|
|||
|
|
@ -535,10 +535,10 @@ const LoginForm = () => {
|
|||
</div>
|
||||
|
||||
<Button
|
||||
type="button"
|
||||
type="submit"
|
||||
fullWidth
|
||||
onClick={handleEmailValidation}
|
||||
disabled={isPending}
|
||||
// onClick={handleEmailValidation}
|
||||
// disabled={isPending}
|
||||
>
|
||||
Selanjutnya
|
||||
</Button>
|
||||
|
|
|
|||
243
lib/menus.ts
243
lib/menus.ts
|
|
@ -38,7 +38,10 @@ export function getMenuList(pathname: string, t: any): Group[] {
|
|||
|
||||
let menusSelected = <any>[];
|
||||
|
||||
if ((Number(roleId) == 3 || Number(roleId) == 14) && Number(levelNumber) == 1) {
|
||||
if (
|
||||
(Number(roleId) == 3 || Number(roleId) == 14) &&
|
||||
Number(levelNumber) == 1
|
||||
) {
|
||||
menusSelected = [
|
||||
{
|
||||
groupLabel: t("apps"),
|
||||
|
|
@ -1531,13 +1534,236 @@ export function getMenuList(pathname: string, t: any): Group[] {
|
|||
icon: "heroicons:share",
|
||||
children: [],
|
||||
},
|
||||
// {
|
||||
// href: "/contributor/content/spit",
|
||||
// label: "spit",
|
||||
// active: pathname.includes("/content/spit"),
|
||||
// icon: "heroicons:credit-card",
|
||||
// children: [],
|
||||
// },
|
||||
// {
|
||||
// href: "/contributor/content/nulis-ai",
|
||||
// label: "nulis ai",
|
||||
// active: pathname.includes("/content/nulisai"),
|
||||
// icon: "heroicons:credit-card",
|
||||
// children: [],
|
||||
// },
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
groupLabel: "",
|
||||
id: "agenda-setting",
|
||||
menus: [
|
||||
{
|
||||
id: "agenda-setting",
|
||||
href: "/contributor/agenda-setting",
|
||||
label: t("agenda-setting"),
|
||||
active: pathname.includes("/agenda-setting"),
|
||||
icon: "iconoir:journal-page",
|
||||
submenus: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
groupLabel: "",
|
||||
id: "planning",
|
||||
menus: [
|
||||
{
|
||||
id: "planning",
|
||||
href: "/contributor/planning",
|
||||
label: t("planning"),
|
||||
active: pathname.includes("/planning"),
|
||||
icon: "pajamas:planning",
|
||||
submenus: [
|
||||
{
|
||||
href: "/contributor/content/spit",
|
||||
label: "spit",
|
||||
active: pathname.includes("/content/spit"),
|
||||
icon: "heroicons:credit-card",
|
||||
href: "/contributor/planning/mediahub",
|
||||
label: "mediaHub",
|
||||
active: pathname.includes("/planning/mediahub"),
|
||||
icon: "heroicons:arrow-trending-up",
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
href: "/contributor/planning/medsos-mediahub",
|
||||
label: "medsos mediahub",
|
||||
active: pathname.includes("/planning/medsos-mediahub"),
|
||||
icon: "heroicons:shopping-cart",
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
groupLabel: "",
|
||||
id: "task",
|
||||
menus: [
|
||||
{
|
||||
id: "task",
|
||||
href: "/contributor/task",
|
||||
label: t("task"),
|
||||
active: pathname.includes("/task"),
|
||||
icon: "fluent:clipboard-task-add-24-regular",
|
||||
submenus: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
groupLabel: "",
|
||||
id: "schedule",
|
||||
menus: [
|
||||
{
|
||||
id: "schedule",
|
||||
href: "/contributor/schedule",
|
||||
label: t("schedule"),
|
||||
active: pathname.includes("/schedule"),
|
||||
icon: "uil:schedule",
|
||||
submenus: [
|
||||
{
|
||||
href: "/contributor/schedule/press-conference",
|
||||
label: t("press-conference"),
|
||||
active: pathname.includes("/schedule/press-conference"),
|
||||
icon: "heroicons:arrow-trending-up",
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
href: "/contributor/schedule/event",
|
||||
label: t("event"),
|
||||
active: pathname.includes("/schedule/event"),
|
||||
icon: "heroicons:shopping-cart",
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
href: "/contributor/schedule/press-release",
|
||||
label: t("press-release"),
|
||||
active: pathname.includes("/schedule/press-release"),
|
||||
icon: "heroicons:shopping-cart",
|
||||
children: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
groupLabel: "",
|
||||
id: "blog",
|
||||
menus: [
|
||||
{
|
||||
id: "blog",
|
||||
href: "/contributor/blog",
|
||||
label: t("blog"),
|
||||
active: pathname.includes("/blog"),
|
||||
icon: "fluent:clipboard-text-32-regular",
|
||||
submenus: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
groupLabel: "",
|
||||
id: "curatedcontent",
|
||||
menus: [
|
||||
{
|
||||
id: "curatedcontent",
|
||||
href: "/shared/curated-content",
|
||||
label: t("curated-content"),
|
||||
active: pathname.includes("/curated-content"),
|
||||
icon: "pixelarticons:calendar-text",
|
||||
submenus: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
groupLabel: "",
|
||||
id: "communication",
|
||||
menus: [
|
||||
{
|
||||
id: "communication",
|
||||
href: "/shared/communication",
|
||||
label: t("communication"),
|
||||
active: pathname.includes("/communication"),
|
||||
icon: "token:chat",
|
||||
submenus: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
groupLabel: "",
|
||||
id: "contest",
|
||||
menus: [
|
||||
{
|
||||
id: "contest",
|
||||
href: "/shared/contest",
|
||||
label: t("contest"),
|
||||
active: pathname.includes("/contest"),
|
||||
icon: "ic:outline-emoji-events",
|
||||
submenus: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
} else if (Number(roleId) == 4 && Number(levelNumber) == 2) {
|
||||
menusSelected = [
|
||||
{
|
||||
groupLabel: t("apps"),
|
||||
id: "dashboard",
|
||||
menus: [
|
||||
{
|
||||
id: "dashboard",
|
||||
href: "/dashboard",
|
||||
label: t("dashboard"),
|
||||
active: pathname.includes("/dashboard"),
|
||||
icon: "material-symbols:dashboard",
|
||||
submenus: [],
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
groupLabel: "",
|
||||
id: "content",
|
||||
menus: [
|
||||
{
|
||||
id: "content",
|
||||
href: "/contributor/content/image",
|
||||
label: t("content"),
|
||||
active: pathname.includes("/content"),
|
||||
icon: "line-md:youtube",
|
||||
submenus: [
|
||||
{
|
||||
href: "/contributor/content/image",
|
||||
label: t("image"),
|
||||
active: pathname.includes("/content/image"),
|
||||
icon: "ic:outline-image",
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
href: "/contributor/content/video",
|
||||
label: t("video"),
|
||||
active: pathname.includes("/content/video"),
|
||||
icon: "line-md:youtube",
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
href: "/contributor/content/teks",
|
||||
label: t("text"),
|
||||
active: pathname.includes("/content/teks"),
|
||||
icon: "heroicons:document",
|
||||
children: [],
|
||||
},
|
||||
{
|
||||
href: "/contributor/content/audio",
|
||||
label: t("audio"),
|
||||
active: pathname.includes("/content/audio"),
|
||||
icon: "heroicons:share",
|
||||
children: [],
|
||||
},
|
||||
// {
|
||||
// href: "/contributor/content/spit",
|
||||
// label: "spit",
|
||||
// active: pathname.includes("/content/spit"),
|
||||
// icon: "heroicons:credit-card",
|
||||
// children: [],
|
||||
// },
|
||||
// {
|
||||
// href: "/contributor/content/nulis-ai",
|
||||
// label: "nulis ai",
|
||||
|
|
@ -1700,7 +1926,7 @@ export function getMenuList(pathname: string, t: any): Group[] {
|
|||
},
|
||||
];
|
||||
} else if (
|
||||
(Number(roleId) == 3 || Number(roleId) == 4 || Number(roleId) == 14 || Number(roleId) == 15) &&
|
||||
(Number(roleId) == 3 || Number(roleId) == 14 || Number(roleId) == 15) &&
|
||||
Number(levelNumber) == 2
|
||||
) {
|
||||
if (Number(userLevelId) != 761) {
|
||||
|
|
@ -2158,7 +2384,10 @@ export function getMenuList(pathname: string, t: any): Group[] {
|
|||
];
|
||||
}
|
||||
} else if (
|
||||
(Number(roleId) == 3 || Number(roleId) == 4 || Number(roleId) == 14 || Number(roleId) == 15) &&
|
||||
(Number(roleId) == 3 ||
|
||||
Number(roleId) == 4 ||
|
||||
Number(roleId) == 14 ||
|
||||
Number(roleId) == 15) &&
|
||||
Number(levelNumber) == 3
|
||||
) {
|
||||
if (Number(userParentLevelId) != 761) {
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -173,10 +173,10 @@ export async function createMedia(data: any) {
|
|||
|
||||
export async function uploadThumbnail(id: any, data: any) {
|
||||
const url = `media/upload?id=${id}&operation=thumbnail`;
|
||||
const headers = {
|
||||
"Content-Type": "multipart/form-data",
|
||||
};
|
||||
return httpPostInterceptor(url, data, headers);
|
||||
// const headers = {
|
||||
// "Content-Type": "multipart/form-data",
|
||||
// };
|
||||
return httpPostInterceptor(url, data);
|
||||
}
|
||||
|
||||
export async function detailSPIT(id: any) {
|
||||
|
|
@ -234,4 +234,4 @@ export async function postActivityLog(data: any) {
|
|||
"content-type": "application/json",
|
||||
};
|
||||
return httpPost(url, headers, data);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue