feat:update communication internal
This commit is contained in:
parent
a44b275f73
commit
ade8b1b296
|
|
@ -116,13 +116,10 @@ const columns: ColumnDef<any>[] = [
|
||||||
"menunggu review": "bg-orange-100 text-orange-600",
|
"menunggu review": "bg-orange-100 text-orange-600",
|
||||||
};
|
};
|
||||||
|
|
||||||
// Mengambil `statusName` dari data API
|
|
||||||
const status = row.getValue("statusName") as string;
|
const status = row.getValue("statusName") as string;
|
||||||
const statusName = status?.toLocaleLowerCase(); // Ubah ke huruf kecil
|
const statusName = status?.toLocaleLowerCase();
|
||||||
|
|
||||||
// Gunakan `statusName` untuk pencocokan
|
|
||||||
const statusStyles =
|
const statusStyles =
|
||||||
statusColors[statusName] || "bg-gray-100 text-gray-600";
|
statusColors[statusName] || "bg-red-200 text-red-600";
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Badge
|
<Badge
|
||||||
|
|
|
||||||
|
|
@ -25,6 +25,8 @@ import {
|
||||||
saveTicketInternalReply,
|
saveTicketInternalReply,
|
||||||
} from "@/service/communication/communication";
|
} from "@/service/communication/communication";
|
||||||
import { Icon } from "@iconify/react/dist/iconify.js";
|
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||||
|
import { list } from "postcss";
|
||||||
|
import { htmlToString } from "@/utils/globals";
|
||||||
|
|
||||||
const taskSchema = z.object({
|
const taskSchema = z.object({
|
||||||
title: z.string().min(1, { message: "Judul diperlukan" }),
|
title: z.string().min(1, { message: "Judul diperlukan" }),
|
||||||
|
|
@ -72,6 +74,19 @@ export type replyDetail = {
|
||||||
fullname: string;
|
fullname: string;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
export type internalDetail = {
|
||||||
|
id: number;
|
||||||
|
message: string;
|
||||||
|
createdAt: string;
|
||||||
|
createdBy: {
|
||||||
|
id: number;
|
||||||
|
fullname: string;
|
||||||
|
};
|
||||||
|
sendTo: {
|
||||||
|
id: number;
|
||||||
|
fullname: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
export default function FormDetailInternal() {
|
export default function FormDetailInternal() {
|
||||||
const MySwal = withReactContent(Swal);
|
const MySwal = withReactContent(Swal);
|
||||||
|
|
@ -79,6 +94,9 @@ export default function FormDetailInternal() {
|
||||||
|
|
||||||
const [detail, setDetail] = useState<taskDetail>();
|
const [detail, setDetail] = useState<taskDetail>();
|
||||||
const [ticketReply, setTicketReply] = useState<replyDetail[]>([]);
|
const [ticketReply, setTicketReply] = useState<replyDetail[]>([]);
|
||||||
|
const [ticketInternal, setTicketInternal] = useState<internalDetail | null>(
|
||||||
|
null
|
||||||
|
);
|
||||||
const [replyVisible, setReplyVisible] = useState(false);
|
const [replyVisible, setReplyVisible] = useState(false);
|
||||||
const [replyMessage, setReplyMessage] = useState("");
|
const [replyMessage, setReplyMessage] = useState("");
|
||||||
const [selectedPriority, setSelectedPriority] = useState("");
|
const [selectedPriority, setSelectedPriority] = useState("");
|
||||||
|
|
@ -96,6 +114,7 @@ export default function FormDetailInternal() {
|
||||||
async function initState() {
|
async function initState() {
|
||||||
if (id) {
|
if (id) {
|
||||||
const response = await getTicketingInternalDetail(id);
|
const response = await getTicketingInternalDetail(id);
|
||||||
|
setTicketInternal(response?.data?.data || null);
|
||||||
setDetail(response?.data?.data);
|
setDetail(response?.data?.data);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -203,6 +222,7 @@ export default function FormDetailInternal() {
|
||||||
<p className="p-4 bg-slate-300 rounded-t-xl text-lg font-semibold">
|
<p className="p-4 bg-slate-300 rounded-t-xl text-lg font-semibold">
|
||||||
Ticket #{detail?.referenceNumber}
|
Ticket #{detail?.referenceNumber}
|
||||||
</p>
|
</p>
|
||||||
|
|
||||||
{ticketReply?.map((list) => (
|
{ticketReply?.map((list) => (
|
||||||
<div key={list.id} className="flex flex-col">
|
<div key={list.id} className="flex flex-col">
|
||||||
<div className="flex flex-row gap-3 bg-sky-100 p-4 items-center">
|
<div className="flex flex-row gap-3 bg-sky-100 p-4 items-center">
|
||||||
|
|
@ -229,6 +249,38 @@ export default function FormDetailInternal() {
|
||||||
<p className="p-4 bg-white text-sm">{list.message}</p>
|
<p className="p-4 bg-white text-sm">{list.message}</p>
|
||||||
</div>
|
</div>
|
||||||
))}
|
))}
|
||||||
|
{ticketInternal && (
|
||||||
|
<div key={ticketInternal.id} className="flex flex-col">
|
||||||
|
<div className="flex flex-row gap-3 bg-sky-100 p-4 items-center">
|
||||||
|
<Icon icon="qlementine-icons:user-16" width={36} />
|
||||||
|
<div>
|
||||||
|
<p>
|
||||||
|
<span className="font-bold text-sm">
|
||||||
|
{ticketInternal?.createdBy?.fullname}
|
||||||
|
</span>{" "}
|
||||||
|
mengirimkan pesan untuk{" "}
|
||||||
|
<span className="font-bold text-sm">
|
||||||
|
{ticketInternal?.sendTo?.fullname}
|
||||||
|
</span>
|
||||||
|
</p>
|
||||||
|
<p className="text-xs">
|
||||||
|
{`${new Date(ticketInternal?.createdAt).getDate()}-${
|
||||||
|
new Date(ticketInternal?.createdAt).getMonth() + 1
|
||||||
|
}-${new Date(
|
||||||
|
ticketInternal?.createdAt
|
||||||
|
).getFullYear()} ${new Date(
|
||||||
|
ticketInternal?.createdAt
|
||||||
|
).getHours()}:${new Date(
|
||||||
|
ticketInternal?.createdAt
|
||||||
|
).getMinutes()}`}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<p className="p-4 bg-white text-sm">
|
||||||
|
{htmlToString(ticketInternal.message)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
{detail !== undefined && (
|
{detail !== undefined && (
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,7 @@ import { zodResolver } from "@hookform/resolvers/zod";
|
||||||
import * as z from "zod";
|
import * as z from "zod";
|
||||||
import Swal from "sweetalert2";
|
import Swal from "sweetalert2";
|
||||||
import withReactContent from "sweetalert2-react-content";
|
import withReactContent from "sweetalert2-react-content";
|
||||||
import { useParams, useRouter } from "next/navigation";
|
import { useParams } from "next/navigation";
|
||||||
import {
|
import {
|
||||||
Select,
|
Select,
|
||||||
SelectContent,
|
SelectContent,
|
||||||
|
|
@ -55,6 +55,7 @@ import { getCookiesDecrypt } from "@/lib/utils";
|
||||||
import { Icon } from "@iconify/react/dist/iconify.js";
|
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||||
import { error } from "@/lib/swal";
|
import { error } from "@/lib/swal";
|
||||||
import dynamic from "next/dynamic";
|
import dynamic from "next/dynamic";
|
||||||
|
import { useRouter } from "@/i18n/routing";
|
||||||
|
|
||||||
const imageSchema = z.object({
|
const imageSchema = z.object({
|
||||||
title: z.string().min(1, { message: "Judul diperlukan" }),
|
title: z.string().min(1, { message: "Judul diperlukan" }),
|
||||||
|
|
|
||||||
|
|
@ -167,10 +167,10 @@ export default function FormPressConference() {
|
||||||
)}
|
)}
|
||||||
</div>
|
</div>
|
||||||
<div className="flex flex-row items-center">
|
<div className="flex flex-row items-center">
|
||||||
<div className="mt-5">
|
<div className="mt-4 mb-3">
|
||||||
<Label>Live Streaming</Label>
|
<Label>Live Streaming</Label>
|
||||||
<div className="flex items-center gap-3">
|
<div className="flex items-center gap-3">
|
||||||
<p>Aktifkan fitur live streaming</p>
|
<Label>Aktifkan fitur live streaming</Label>
|
||||||
<Switch
|
<Switch
|
||||||
defaultChecked={isLiveStreamingEnabled}
|
defaultChecked={isLiveStreamingEnabled}
|
||||||
color="primary"
|
color="primary"
|
||||||
|
|
@ -184,7 +184,7 @@ export default function FormPressConference() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{isLiveStreamingEnabled && (
|
{isLiveStreamingEnabled && (
|
||||||
<div className="mt-1">
|
<div className="mb-2 mt-1">
|
||||||
<Controller
|
<Controller
|
||||||
control={control}
|
control={control}
|
||||||
name="title"
|
name="title"
|
||||||
|
|
@ -206,16 +206,17 @@ export default function FormPressConference() {
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
<div className="flex flex-col lg:flex-row mt-3 items-start lg:items-center justify-between">
|
<div className="flex flex-col lg:flex-row mb-4 mt-2 items-start lg:items-center justify-between">
|
||||||
<div className="flex flex-col ">
|
<div className="flex flex-col ">
|
||||||
<Label className="mr-3 mb-1">Tanggal</Label>
|
<Label className="mr-3 mb-1">Tanggal</Label>
|
||||||
<Popover>
|
<Popover>
|
||||||
<PopoverTrigger asChild>
|
<PopoverTrigger asChild>
|
||||||
<Button
|
<Button
|
||||||
|
size="md"
|
||||||
id="date"
|
id="date"
|
||||||
variant={"outline"}
|
variant={"outline"}
|
||||||
className={cn(
|
className={cn(
|
||||||
"w-[280px] lg:w-[300px] justify-start text-left font-normal",
|
"w-[280px] lg:w-[250px] justify-start text-left font-normal border border-slate-300",
|
||||||
!date && "text-muted-foreground"
|
!date && "text-muted-foreground"
|
||||||
)}
|
)}
|
||||||
>
|
>
|
||||||
|
|
@ -292,7 +293,7 @@ export default function FormPressConference() {
|
||||||
{errors.location?.message}
|
{errors.location?.message}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<p className="text-sm my-2 font-semibold">DI SAMPAIKAN OLEH</p>
|
<p className="text-sm mt-4 font-semibold">DI SAMPAIKAN OLEH</p>
|
||||||
<div className="flex flex-col ">
|
<div className="flex flex-col ">
|
||||||
<div className="mt-1">
|
<div className="mt-1">
|
||||||
<Label>Nama Pangkat</Label>
|
<Label>Nama Pangkat</Label>
|
||||||
|
|
|
||||||
|
|
@ -1119,6 +1119,7 @@ export default function FormTaskDetail() {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<Button
|
<Button
|
||||||
|
type="button"
|
||||||
size="icon"
|
size="icon"
|
||||||
color="destructive"
|
color="destructive"
|
||||||
variant="outline"
|
variant="outline"
|
||||||
|
|
@ -1249,7 +1250,7 @@ export default function FormTaskDetail() {
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{audioUploadedFiles?.length > 0 && (
|
{/* {audioUploadedFiles?.length > 0 && (
|
||||||
<AudioRecorder
|
<AudioRecorder
|
||||||
onRecordingComplete={addAudioElement}
|
onRecordingComplete={addAudioElement}
|
||||||
audioTrackConstraints={{
|
audioTrackConstraints={{
|
||||||
|
|
@ -1259,7 +1260,7 @@ export default function FormTaskDetail() {
|
||||||
downloadOnSavePress={true}
|
downloadOnSavePress={true}
|
||||||
downloadFileExtension="webm"
|
downloadFileExtension="webm"
|
||||||
/>
|
/>
|
||||||
)}
|
)} */}
|
||||||
</div>
|
</div>
|
||||||
{audioFile && (
|
{audioFile && (
|
||||||
<div className="flex flex-row justify-between items-center">
|
<div className="flex flex-row justify-between items-center">
|
||||||
|
|
@ -1277,6 +1278,7 @@ export default function FormTaskDetail() {
|
||||||
{isRecording && <p>Recording... {timer} seconds remaining</p>}{" "}
|
{isRecording && <p>Recording... {timer} seconds remaining</p>}{" "}
|
||||||
{/* Display remaining time */}
|
{/* Display remaining time */}
|
||||||
<div className="mt-4">
|
<div className="mt-4">
|
||||||
|
<Label>Link Url</Label>
|
||||||
{urlInputs.map((url: any, index: any) => (
|
{urlInputs.map((url: any, index: any) => (
|
||||||
<div
|
<div
|
||||||
key={url.id}
|
key={url.id}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue