feat: merge rama
This commit is contained in:
commit
aa48619491
|
|
@ -0,0 +1,95 @@
|
|||
"use client";
|
||||
import SiteBreadcrumb from "@/components/site-breadcrumb";
|
||||
import { Progress } from "@/components/ui/progress";
|
||||
import { getUserFeedbacks } from "@/service/master/faq";
|
||||
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||
import { stringify } from "querystring";
|
||||
import { useEffect, useState } from "react";
|
||||
|
||||
export default function UserFeedback() {
|
||||
const [listData, setListData] = useState<any>([]);
|
||||
|
||||
useEffect(() => {
|
||||
initState();
|
||||
}, []);
|
||||
async function initState() {
|
||||
const response = await getUserFeedbacks();
|
||||
console.log("ssss", response?.data?.data);
|
||||
setListData(response?.data?.data);
|
||||
}
|
||||
|
||||
const renderStar = (count: number) => {
|
||||
const mapped = [1, 2, 3, 4, 5];
|
||||
return (
|
||||
<div className="flex flex-row gap-3 items-center">
|
||||
{mapped?.map((row) =>
|
||||
row < count + 1 ? (
|
||||
<Icon key={row} icon="emojione:star" width={33} />
|
||||
) : (
|
||||
<Icon key={row} icon="emojione-monotone:star" width={33} />
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
return (
|
||||
<div>
|
||||
<SiteBreadcrumb />
|
||||
<div className="flex flex-col gap-2 bg-white p-4">
|
||||
<p className="text-lg">Hasil Feedback</p>
|
||||
<div className="grid grid-cols-2 gap-5">
|
||||
{listData?.map(
|
||||
(list: any) =>
|
||||
list?.avgScore !== "NaN" && (
|
||||
<div
|
||||
key={list?.id}
|
||||
className="flex flex-col gap-2 bg-gray-100 rounded-md p-5"
|
||||
>
|
||||
<div className="flex flex-row gap-3 items-center">
|
||||
<p className="text-3xl">{parseInt(list?.avgScore)}</p>
|
||||
{renderStar(parseInt(list?.avgScore))}
|
||||
</div>
|
||||
<p className="font-semibold">{list?.question}</p>
|
||||
<div className="flex flex-row gap-3 items-center">
|
||||
<p className="w-[120px]">Penilaian 5</p>
|
||||
<Progress
|
||||
value={parseInt(list?.score5)}
|
||||
className="w-[70%]"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-row gap-3 items-center">
|
||||
<p className="w-[120px]">Penilaian 4</p>
|
||||
<Progress
|
||||
value={parseInt(list?.score4)}
|
||||
className="w-[70%]"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-row gap-3 items-center">
|
||||
<p className="w-[120px]">Penilaian 3</p>
|
||||
<Progress
|
||||
value={parseInt(list?.score3)}
|
||||
className="w-[70%]"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-row gap-3 items-center">
|
||||
<p className="w-[120px]">Penilaian 2</p>
|
||||
<Progress
|
||||
value={parseInt(list?.score2)}
|
||||
className="w-[70%]"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex flex-row gap-3 items-center">
|
||||
<p className="w-[120px]">Penilaian 1</p>
|
||||
<Progress
|
||||
value={parseInt(list?.score1)}
|
||||
className="w-[70%]"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
@ -69,7 +69,10 @@ export default function CollaborationPage() {
|
|||
loading();
|
||||
const response = await deleteCollabDiscussion(dataId);
|
||||
console.log(response);
|
||||
|
||||
toast({
|
||||
title: "Sukses hapus",
|
||||
});
|
||||
setReplyValue("");
|
||||
close();
|
||||
initState();
|
||||
}
|
||||
|
|
@ -79,7 +82,7 @@ export default function CollaborationPage() {
|
|||
loading();
|
||||
const data = {
|
||||
ticketId: id,
|
||||
replyValue,
|
||||
message: replyValue,
|
||||
parentId: null,
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -100,14 +100,6 @@ const columns: ColumnDef<any>[] = [
|
|||
View
|
||||
</DropdownMenuItem>
|
||||
</Link>
|
||||
<DropdownMenuItem className="p-2 border-b text-default-700 group focus:bg-default focus:text-primary-foreground rounded-none">
|
||||
<SquarePen className="w-4 h-4 me-1.5" />
|
||||
Edit
|
||||
</DropdownMenuItem>
|
||||
<DropdownMenuItem className="p-2 border-b text-destructive bg-destructive/30 focus:bg-destructive focus:text-destructive-foreground rounded-none">
|
||||
<Trash2 className="w-4 h-4 me-1.5" />
|
||||
Delete
|
||||
</DropdownMenuItem>
|
||||
</DropdownMenuContent>
|
||||
</DropdownMenu>
|
||||
);
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ import {
|
|||
saveTicketInternalReply,
|
||||
} from "@/service/communication/communication";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||
import { Link } from "@/i18n/routing";
|
||||
|
||||
const taskSchema = z.object({
|
||||
title: z.string().min(1, { message: "Judul diperlukan" }),
|
||||
|
|
@ -34,33 +36,6 @@ const taskSchema = z.object({
|
|||
}),
|
||||
});
|
||||
|
||||
export type escalationDetail = {
|
||||
id: number;
|
||||
title: string;
|
||||
createdAt: string;
|
||||
commentFromUserName: string;
|
||||
message: string;
|
||||
createdBy: {
|
||||
id: number;
|
||||
fullname: string;
|
||||
};
|
||||
sendTo: {
|
||||
id: number;
|
||||
fullname: string;
|
||||
};
|
||||
status: {
|
||||
id: number;
|
||||
name: string;
|
||||
};
|
||||
priority: {
|
||||
id: number;
|
||||
name: string;
|
||||
};
|
||||
description: string;
|
||||
narration: string;
|
||||
is_active: string;
|
||||
};
|
||||
|
||||
export type replyDetail = {
|
||||
id: number;
|
||||
message: string;
|
||||
|
|
@ -79,7 +54,7 @@ export default function FormDetailEscalation() {
|
|||
const MySwal = withReactContent(Swal);
|
||||
const { id } = useParams() as { id: string };
|
||||
|
||||
const [detail, setDetail] = useState<escalationDetail>();
|
||||
const [detail, setDetail] = useState<any>();
|
||||
const [ticketReply, setTicketReply] = useState<replyDetail[]>([]);
|
||||
const [replyVisible, setReplyVisible] = useState(false);
|
||||
const [replyMessage, setReplyMessage] = useState("");
|
||||
|
|
@ -165,121 +140,134 @@ export default function FormDetailEscalation() {
|
|||
};
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<div className="px-6 py-6">
|
||||
<div className="flex">
|
||||
<div className="flex flex-col mt-6 w-full mb-3">
|
||||
{detail !== undefined && (
|
||||
<div key={detail?.id} className="bg-slate-300 rounded-md">
|
||||
<p className="px-3 py-3 bg-slate-300 rounded-md text-lg font-semibold">
|
||||
Ticket #{detail.id}
|
||||
</p>
|
||||
<div className="flex flex-row gap-3 mt-3 bg-blue-300 py-2 px-2">
|
||||
<Avatar>
|
||||
<AvatarImage
|
||||
src={"/images/avatar/avatar-3.png"}
|
||||
alt={`mabes`}
|
||||
/>
|
||||
</Avatar>
|
||||
<div>
|
||||
<p>
|
||||
<span className="font-bold">
|
||||
{detail?.commentFromUserName}
|
||||
</span>{" "}
|
||||
mengirimkan pesan untuk{" "}
|
||||
<span className="font-bold">{detail?.message}</span>
|
||||
</p>
|
||||
<p>{detail?.createdAt}</p>
|
||||
</div>
|
||||
<div>
|
||||
<div className="flex">
|
||||
<div className="flex flex-col mt-6 w-full mb-3">
|
||||
{detail !== undefined && (
|
||||
<div key={detail?.id} className="bg-slate-300 rounded-md">
|
||||
<p className="p-5 bg-slate-300 rounded-md text-lg font-semibold">
|
||||
Ticket #{detail.id}
|
||||
</p>
|
||||
<div className="flex flex-row gap-3 bg-sky-100 p-5 items-center">
|
||||
<Icon icon="qlementine-icons:user-16" width={36} />
|
||||
|
||||
<div>
|
||||
<p>
|
||||
<span className="font-bold">
|
||||
{detail?.commentFromUserName}
|
||||
</span>
|
||||
{` `}
|
||||
mengirimkan pesan untuk{` `}
|
||||
<Link
|
||||
href={
|
||||
detail?.feed
|
||||
? detail?.feed?.permalink_url == undefined
|
||||
? detail?.feedUrl
|
||||
: detail?.feed?.permalink_url
|
||||
: ""
|
||||
}
|
||||
target="_blank"
|
||||
className="font-bold"
|
||||
>
|
||||
{detail?.message}
|
||||
</Link>
|
||||
</p>
|
||||
<p className="text-xs">
|
||||
{`${new Date(detail?.createdAt).getDate()}-${
|
||||
new Date(detail?.createdAt).getMonth() + 1
|
||||
}-${new Date(detail?.createdAt).getFullYear()} ${new Date(
|
||||
detail?.createdAt
|
||||
).getHours()}:${new Date(detail?.createdAt).getMinutes()}`}
|
||||
</p>
|
||||
</div>
|
||||
<p className="pl-3 bg-white">{detail.message}</p>
|
||||
</div>
|
||||
)}
|
||||
<p className="p-5 bg-white">{detail.message}</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{detail !== undefined && (
|
||||
<div className="gap-5 mb-5 w-full border mt-3 rounded-md bg-white">
|
||||
<div className="space-y-2 px-3 mt-3">
|
||||
<Label>Judul</Label>
|
||||
<Controller
|
||||
control={control}
|
||||
name="title"
|
||||
render={({ field }) => (
|
||||
<Input
|
||||
size="md"
|
||||
type="text"
|
||||
value={detail?.title}
|
||||
onChange={field.onChange}
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{/* {errors.title?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.title.message}
|
||||
</p>
|
||||
)} */}
|
||||
</div>
|
||||
<div className="mt-5 px-3">
|
||||
<Label>Prioritas</Label>
|
||||
<Select
|
||||
onValueChange={setSelectedPriority}
|
||||
value={detail?.priority?.name}
|
||||
>
|
||||
<SelectTrigger size="md" className="w-3/12">
|
||||
<SelectValue placeholder="Pilih" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="Low">Low</SelectItem>
|
||||
<SelectItem value="Medium">Medium</SelectItem>
|
||||
<SelectItem value="High">High</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="space-y-2 px-3 mt-3">
|
||||
<Label>Description</Label>
|
||||
<Controller
|
||||
control={control}
|
||||
name="title"
|
||||
render={({ field }) => (
|
||||
<Textarea
|
||||
value={detail?.description}
|
||||
onChange={field.onChange}
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{/* {errors.title?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.title.message}
|
||||
</p>
|
||||
)} */}
|
||||
</div>
|
||||
<div className="mt-4 px-3 mb-3">
|
||||
<Label htmlFor="replyMessage">Tulis Pesan</Label>
|
||||
<textarea
|
||||
id="replyMessage"
|
||||
className="w-full h-24 border rounded-md p-2"
|
||||
value={replyMessage}
|
||||
onChange={(e) => setReplyMessage(e.target.value)}
|
||||
placeholder="Tulis pesan di sini..."
|
||||
/>
|
||||
<div className="flex justify-end gap-3 mt-2">
|
||||
<Button
|
||||
onClick={() => setReplyVisible(false)}
|
||||
color="default"
|
||||
variant="outline"
|
||||
>
|
||||
Batal
|
||||
</Button>
|
||||
<Button onClick={handleSendReply} color="primary">
|
||||
Kirim
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
{detail !== undefined && (
|
||||
<div className="gap-5 mb-5 w-full border mt-3 rounded-md">
|
||||
<div className="space-y-2 px-3 mt-3">
|
||||
<Label>Judul</Label>
|
||||
<Controller
|
||||
control={control}
|
||||
name="title"
|
||||
render={({ field }) => (
|
||||
<Input
|
||||
size="md"
|
||||
type="text"
|
||||
value={detail?.title}
|
||||
onChange={field.onChange}
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{/* {errors.title?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.title.message}
|
||||
</p>
|
||||
)} */}
|
||||
</div>
|
||||
<div className="mt-5 px-3">
|
||||
<Label>Prioritas</Label>
|
||||
<Select
|
||||
onValueChange={setSelectedPriority}
|
||||
value={detail?.priority?.name}
|
||||
>
|
||||
<SelectTrigger size="md" className="w-3/12">
|
||||
<SelectValue placeholder="Pilih" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="Low">Low</SelectItem>
|
||||
<SelectItem value="Medium">Medium</SelectItem>
|
||||
<SelectItem value="High">High</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="space-y-2 px-3 mt-3">
|
||||
<Label>Description</Label>
|
||||
<Controller
|
||||
control={control}
|
||||
name="title"
|
||||
render={({ field }) => (
|
||||
<Textarea
|
||||
value={detail?.description}
|
||||
onChange={field.onChange}
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{/* {errors.title?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.title.message}
|
||||
</p>
|
||||
)} */}
|
||||
</div>
|
||||
<div className="mt-4 px-3 mb-3">
|
||||
<Label htmlFor="replyMessage">Tulis Pesan</Label>
|
||||
<textarea
|
||||
id="replyMessage"
|
||||
className="w-full h-24 border rounded-md p-2"
|
||||
value={replyMessage}
|
||||
onChange={(e) => setReplyMessage(e.target.value)}
|
||||
placeholder="Tulis pesan di sini..."
|
||||
/>
|
||||
<div className="flex justify-end gap-3 mt-2">
|
||||
<Button
|
||||
onClick={() => setReplyVisible(false)}
|
||||
color="default"
|
||||
variant="outline"
|
||||
>
|
||||
Batal
|
||||
</Button>
|
||||
<Button onClick={handleSendReply} color="primary">
|
||||
Kirim
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@ import {
|
|||
getTicketingInternalDiscussion,
|
||||
saveTicketInternalReply,
|
||||
} from "@/service/communication/communication";
|
||||
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||
|
||||
const taskSchema = z.object({
|
||||
title: z.string().min(1, { message: "Judul diperlukan" }),
|
||||
|
|
@ -36,6 +37,7 @@ export type taskDetail = {
|
|||
id: number;
|
||||
title: string;
|
||||
createdAt: string;
|
||||
referenceNumber: string | number;
|
||||
createdBy: {
|
||||
id: number;
|
||||
fullname: string;
|
||||
|
|
@ -161,132 +163,132 @@ export default function FormDetailInternal() {
|
|||
};
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<div className="px-6 py-6">
|
||||
<div className="mt-4 flex flex-row items-center gap-3">
|
||||
<Button onClick={handleReply} color="default" variant={"outline"}>
|
||||
Balas
|
||||
</Button>
|
||||
<div className="py-5">
|
||||
<div className="mt-4 flex flex-row items-center gap-3">
|
||||
<Button onClick={handleReply} color="default" variant={"outline"}>
|
||||
Balas
|
||||
</Button>
|
||||
|
||||
<Button color="default" variant={"outline"}>
|
||||
Hapus
|
||||
</Button>
|
||||
</div>
|
||||
<Button color="default" variant={"outline"}>
|
||||
Hapus
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{replyVisible && (
|
||||
<div className="mt-4">
|
||||
<Label htmlFor="replyMessage">Tulis Pesan</Label>
|
||||
<textarea
|
||||
id="replyMessage"
|
||||
className="w-full h-24 border rounded-md p-2"
|
||||
value={replyMessage}
|
||||
onChange={(e) => setReplyMessage(e.target.value)}
|
||||
placeholder="Tulis pesan di sini..."
|
||||
/>
|
||||
<div className="flex justify-end gap-3 mt-2">
|
||||
<Button
|
||||
onClick={() => setReplyVisible(false)}
|
||||
color="default"
|
||||
variant="outline"
|
||||
>
|
||||
Batal
|
||||
</Button>
|
||||
<Button onClick={handleSendReply} color="primary">
|
||||
Kirim
|
||||
</Button>
|
||||
<div className="flex flex-row gap-5 mt-5">
|
||||
<div className="flex flex-col w-[70%]">
|
||||
{replyVisible && (
|
||||
<div className="">
|
||||
<textarea
|
||||
id="replyMessage"
|
||||
className="w-full h-24 border rounded-md p-2"
|
||||
value={replyMessage}
|
||||
onChange={(e) => setReplyMessage(e.target.value)}
|
||||
placeholder="Tulis pesan di sini..."
|
||||
/>
|
||||
<div className="flex justify-end gap-3 my-2">
|
||||
<Button
|
||||
onClick={() => setReplyVisible(false)}
|
||||
color="default"
|
||||
variant="outline"
|
||||
>
|
||||
Batal
|
||||
</Button>
|
||||
<Button onClick={handleSendReply} color="primary">
|
||||
Kirim
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex flex-row justify-between ">
|
||||
<div className="flex flex-col mt-6 w-7/12">
|
||||
)}
|
||||
<div className="border rounded-t-xl">
|
||||
<p className="p-4 bg-slate-300 rounded-t-xl text-lg font-semibold">
|
||||
Ticket #{detail?.referenceNumber}
|
||||
</p>
|
||||
{ticketReply?.map((list) => (
|
||||
<div key={list.id} className="bg-slate-300 rounded-md border">
|
||||
<p className="px-3 pt-3 bg-slate-300 rounded-md text-lg font-semibold">
|
||||
Ticket #{list.id}
|
||||
</p>
|
||||
<div className="flex flex-row gap-3 mt-3 bg-blue-300 py-2 px-2">
|
||||
<Avatar>
|
||||
<AvatarImage
|
||||
src={"/images/avatar/avatar-3.png"}
|
||||
alt={`mabes`}
|
||||
/>
|
||||
</Avatar>
|
||||
<div key={list.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">
|
||||
<span className="font-bold text-sm">
|
||||
{list?.messageFrom?.fullname}
|
||||
</span>{" "}
|
||||
mengirimkan pesan untuk{" "}
|
||||
<span className="font-bold">
|
||||
<span className="font-bold text-sm">
|
||||
{list?.messageTo?.fullname}
|
||||
</span>
|
||||
</p>
|
||||
<p>{list?.createdAt}</p>
|
||||
<p className="text-xs">
|
||||
{`${new Date(list?.createdAt).getDate()}-${
|
||||
new Date(list?.createdAt).getMonth() + 1
|
||||
}-${new Date(list?.createdAt).getFullYear()} ${new Date(
|
||||
list?.createdAt
|
||||
).getHours()}:${new Date(list?.createdAt).getMinutes()}`}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
<p className="pl-3 bg-white py-2">{list.message}</p>
|
||||
<p className="p-4 bg-white text-sm">{list.message}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{detail !== undefined && (
|
||||
<div className="gap-5 mb-5 w-3/12 border mt-3 rounded-md">
|
||||
<Label className="ml-3 mt-3">Properties</Label>
|
||||
<div className="space-y-2 px-3">
|
||||
<Label>Judul</Label>
|
||||
<Controller
|
||||
control={control}
|
||||
name="title"
|
||||
render={({ field }) => (
|
||||
<Input
|
||||
size="md"
|
||||
type="text"
|
||||
value={detail?.title}
|
||||
onChange={field.onChange}
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{/* {errors.title?.message && (
|
||||
</div>
|
||||
{detail !== undefined && (
|
||||
<div className="gap-5 mb-5 w-[30%] border bg-white rounded-md">
|
||||
<p className="mx-3 mt-3">Properties</p>
|
||||
<div className="space-y-2 px-3">
|
||||
<Label>Judul</Label>
|
||||
<Controller
|
||||
control={control}
|
||||
name="title"
|
||||
render={({ field }) => (
|
||||
<Input
|
||||
size="md"
|
||||
type="text"
|
||||
value={detail?.title}
|
||||
onChange={field.onChange}
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{/* {errors.title?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.title.message}
|
||||
</p>
|
||||
)} */}
|
||||
</div>
|
||||
<div className="mt-5 px-3">
|
||||
<Label>Prioritas</Label>
|
||||
<Select
|
||||
onValueChange={setSelectedPriority}
|
||||
value={detail?.priority?.name}
|
||||
>
|
||||
<SelectTrigger size="md">
|
||||
<SelectValue placeholder="Pilih" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="Low">Low</SelectItem>
|
||||
<SelectItem value="Medium">Medium</SelectItem>
|
||||
<SelectItem value="High">High</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="mt-5 px-3 mb-3">
|
||||
<Label>Status</Label>
|
||||
<Select
|
||||
onValueChange={setSelectedStatus}
|
||||
value={detail?.status?.name}
|
||||
>
|
||||
<SelectTrigger size="md">
|
||||
<SelectValue placeholder="Pilih" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="Open">Open</SelectItem>
|
||||
<SelectItem value="Close">Close</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<div className="mt-5 px-3">
|
||||
<Label>Prioritas</Label>
|
||||
<Select
|
||||
onValueChange={setSelectedPriority}
|
||||
value={detail?.priority?.name}
|
||||
>
|
||||
<SelectTrigger size="md">
|
||||
<SelectValue placeholder="Pilih" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="Low">Low</SelectItem>
|
||||
<SelectItem value="Medium">Medium</SelectItem>
|
||||
<SelectItem value="High">High</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="mt-5 px-3 mb-3">
|
||||
<Label>Status</Label>
|
||||
<Select
|
||||
onValueChange={setSelectedStatus}
|
||||
value={detail?.status?.name}
|
||||
>
|
||||
<SelectTrigger size="md">
|
||||
<SelectValue placeholder="Pilih" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="Open">Open</SelectItem>
|
||||
<SelectItem value="Close">Close</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,6 +26,8 @@ import {
|
|||
saveTicketInternalReply,
|
||||
} from "@/service/communication/communication";
|
||||
import { Textarea } from "@/components/ui/textarea";
|
||||
import { htmlToString } from "@/utils/globals";
|
||||
import { Icon } from "@iconify/react/dist/iconify.js";
|
||||
|
||||
const taskSchema = z.object({
|
||||
// description: z.string().min(2, {
|
||||
|
|
@ -33,30 +35,6 @@ const taskSchema = z.object({
|
|||
// }),
|
||||
});
|
||||
|
||||
export type taskDetail = {
|
||||
id: number;
|
||||
title: string;
|
||||
createdAt: string;
|
||||
createdBy: {
|
||||
id: number;
|
||||
fullname: string;
|
||||
};
|
||||
sendTo: {
|
||||
id: number;
|
||||
fullname: string;
|
||||
};
|
||||
status: {
|
||||
id: number;
|
||||
name: string;
|
||||
};
|
||||
priority: {
|
||||
id: number;
|
||||
name: string;
|
||||
};
|
||||
description: string;
|
||||
is_active: string;
|
||||
};
|
||||
|
||||
export type replyDetail = {
|
||||
id: number;
|
||||
message: string;
|
||||
|
|
@ -76,13 +54,14 @@ export default function FormEditInternal() {
|
|||
const { id } = useParams() as { id: string };
|
||||
const router = useRouter();
|
||||
|
||||
const [detail, setDetail] = useState<taskDetail>();
|
||||
const [detail, setDetail] = useState<any>();
|
||||
const [ticketReply, setTicketReply] = useState<replyDetail[]>([]);
|
||||
const [replyVisible, setReplyVisible] = useState(false);
|
||||
const [replyMessage, setReplyMessage] = useState("");
|
||||
const [selectedPriority, setSelectedPriority] = useState("");
|
||||
const [selectedStatus, setSelectedStatus] = useState("");
|
||||
const [selectedTarget, setSelectedTarget] = useState("");
|
||||
const [description, setDescription] = useState("");
|
||||
type TaskSchema = z.infer<typeof taskSchema>;
|
||||
|
||||
const {
|
||||
|
|
@ -98,6 +77,10 @@ export default function FormEditInternal() {
|
|||
if (id) {
|
||||
const response = await getTicketingInternalDetail(id);
|
||||
setDetail(response?.data?.data);
|
||||
setSelectedPriority(response?.data?.data?.priority?.name);
|
||||
console.log("sadad", response?.data?.data);
|
||||
setSelectedStatus(response?.data?.data?.status?.name);
|
||||
setDescription(htmlToString(response?.data?.data?.message));
|
||||
}
|
||||
}
|
||||
initState();
|
||||
|
|
@ -206,56 +189,51 @@ export default function FormEditInternal() {
|
|||
};
|
||||
|
||||
return (
|
||||
<Card>
|
||||
<div className="px-6 py-6">
|
||||
<div className="mt-4 flex flex-row items-center gap-3">
|
||||
<Button onClick={handleReply} color="default" variant={"outline"}>
|
||||
Balas
|
||||
</Button>
|
||||
<div className="py-5">
|
||||
<div className="mt-4 flex flex-row items-center gap-3">
|
||||
<Button onClick={handleReply} color="default" variant={"outline"}>
|
||||
Balas
|
||||
</Button>
|
||||
|
||||
<Button color="default" variant={"outline"}>
|
||||
Hapus
|
||||
</Button>
|
||||
</div>
|
||||
<Button color="default" variant={"outline"}>
|
||||
Hapus
|
||||
</Button>
|
||||
</div>
|
||||
|
||||
{replyVisible && (
|
||||
<div className="mt-4">
|
||||
<Label htmlFor="replyMessage">Tulis Pesan</Label>
|
||||
<textarea
|
||||
id="replyMessage"
|
||||
className="w-full h-24 border rounded-md p-2"
|
||||
value={replyMessage}
|
||||
onChange={(e) => setReplyMessage(e.target.value)}
|
||||
placeholder="Tulis pesan di sini..."
|
||||
/>
|
||||
<div className="flex justify-end gap-3 mt-2">
|
||||
<Button
|
||||
onClick={() => setReplyVisible(false)}
|
||||
color="default"
|
||||
variant="outline"
|
||||
>
|
||||
Batal
|
||||
</Button>
|
||||
<Button onClick={handleSendReply} color="primary">
|
||||
Kirim
|
||||
</Button>
|
||||
<div className="flex flex-row gap-5 mt-5">
|
||||
<div className="flex flex-col w-[70%]">
|
||||
{replyVisible && (
|
||||
<div>
|
||||
<textarea
|
||||
id="replyMessage"
|
||||
className="w-full h-24 border rounded-md p-2"
|
||||
value={replyMessage}
|
||||
onChange={(e) => setReplyMessage(e.target.value)}
|
||||
placeholder="Tulis pesan di sini..."
|
||||
/>
|
||||
<div className="flex justify-end gap-3 mt-2">
|
||||
<Button
|
||||
onClick={() => setReplyVisible(false)}
|
||||
color="default"
|
||||
variant="outline"
|
||||
>
|
||||
Batal
|
||||
</Button>
|
||||
<Button onClick={handleSendReply} color="primary">
|
||||
Kirim
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)}
|
||||
<div className="flex flex-row justify-between ">
|
||||
<div className="flex flex-col mt-6 w-7/12">
|
||||
)}
|
||||
<div className="border rounded-t-xl">
|
||||
<p className="p-4 bg-slate-300 rounded-t-xl text-lg font-semibold">
|
||||
Ticket #{detail?.referenceNumber}
|
||||
</p>
|
||||
{ticketReply?.map((list) => (
|
||||
<div key={list.id} className="bg-slate-300 rounded-md border">
|
||||
<p className="px-3 pt-3 bg-slate-300 rounded-md text-lg font-semibold">
|
||||
Ticket #{list.id}
|
||||
</p>
|
||||
<div className="flex flex-row gap-3 mt-3 bg-blue-300 py-2 px-2">
|
||||
<Avatar>
|
||||
<AvatarImage
|
||||
src={"/images/avatar/avatar-3.png"}
|
||||
alt={`mabes`}
|
||||
/>
|
||||
</Avatar>
|
||||
<div key={list.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">
|
||||
|
|
@ -266,98 +244,96 @@ export default function FormEditInternal() {
|
|||
{list?.messageTo?.fullname}
|
||||
</span>
|
||||
</p>
|
||||
<p>{list?.createdAt}</p>
|
||||
<p className="text-xs">{`${new Date(
|
||||
list?.createdAt
|
||||
).getDate()}-${
|
||||
new Date(list?.createdAt).getMonth() + 1
|
||||
}-${new Date(list?.createdAt).getFullYear()} ${new Date(
|
||||
list?.createdAt
|
||||
).getHours()}:${new Date(
|
||||
list?.createdAt
|
||||
).getMinutes()}`}</p>
|
||||
</div>
|
||||
</div>
|
||||
<p className="pl-3 bg-white py-2">{list.message}</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
{detail !== undefined && (
|
||||
<form onSubmit={handleSubmit(onSubmit)}>
|
||||
<div className="gap-5 mb-5 w-full border mt-3 rounded-md">
|
||||
<Label className="ml-3 mt-3">Properties</Label>
|
||||
<div className="space-y-2 px-3">
|
||||
<Label>Judul</Label>
|
||||
<Controller
|
||||
control={control}
|
||||
name="title"
|
||||
render={({ field }) => (
|
||||
<Input
|
||||
size="md"
|
||||
type="text"
|
||||
value={detail?.title}
|
||||
onChange={field.onChange}
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{/* {errors.title?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.title.message}
|
||||
</p>
|
||||
)} */}
|
||||
</div>
|
||||
<div className="mt-5 px-3">
|
||||
<Label>Prioritas</Label>
|
||||
<Select
|
||||
onValueChange={setSelectedPriority}
|
||||
value={detail?.priority?.name}
|
||||
>
|
||||
<SelectTrigger size="md">
|
||||
<SelectValue placeholder="Pilih" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="Low">Low</SelectItem>
|
||||
<SelectItem value="Medium">Medium</SelectItem>
|
||||
<SelectItem value="High">High</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="mt-5 px-3 mb-3">
|
||||
<Label>Status</Label>
|
||||
<Select
|
||||
onValueChange={setSelectedStatus}
|
||||
value={detail?.status?.name}
|
||||
>
|
||||
<SelectTrigger size="md">
|
||||
<SelectValue placeholder="Pilih" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="1">Open</SelectItem>
|
||||
<SelectItem value="2">Close</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="space-y-2 px-3">
|
||||
<Label>Description</Label>
|
||||
<Controller
|
||||
control={control}
|
||||
name="description"
|
||||
render={({ field }) => (
|
||||
<Textarea
|
||||
value={detail?.description}
|
||||
onChange={field.onChange}
|
||||
placeholder="Enter description"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{/* {errors.title?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.title.message}
|
||||
</p>
|
||||
)} */}
|
||||
</div>
|
||||
<div className="flex justify-end mt-3 mr-3">
|
||||
<Button type="submit" color="primary">
|
||||
Update
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
)}
|
||||
</div>
|
||||
{detail !== undefined && (
|
||||
<form onSubmit={handleSubmit(onSubmit)} className="w-[30%]">
|
||||
<div className="gap-5 mb-5 border bg-white rounded-xl">
|
||||
<p className="mx-3 mt-3">Properties</p>
|
||||
<div className="space-y-2 px-3">
|
||||
<Label>Judul</Label>
|
||||
<Controller
|
||||
control={control}
|
||||
name="title"
|
||||
render={({ field }) => (
|
||||
<Input
|
||||
size="md"
|
||||
type="text"
|
||||
value={detail?.title}
|
||||
onChange={field.onChange}
|
||||
placeholder="Enter Title"
|
||||
/>
|
||||
)}
|
||||
/>
|
||||
{/* {errors.title?.message && (
|
||||
<p className="text-red-400 text-sm">
|
||||
{errors.title.message}
|
||||
</p>
|
||||
)} */}
|
||||
</div>
|
||||
<div className="mt-5 px-3">
|
||||
<Label>Prioritas</Label>
|
||||
<Select
|
||||
onValueChange={setSelectedPriority}
|
||||
value={selectedPriority}
|
||||
>
|
||||
<SelectTrigger size="md">
|
||||
<SelectValue placeholder="Pilih" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="Low">Low</SelectItem>
|
||||
<SelectItem value="Medium">Medium</SelectItem>
|
||||
<SelectItem value="High">High</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="mt-5 px-3 mb-3">
|
||||
<Label>Status</Label>
|
||||
<Select
|
||||
onValueChange={setSelectedStatus}
|
||||
value={selectedStatus}
|
||||
>
|
||||
<SelectTrigger size="md">
|
||||
<SelectValue placeholder="Pilih" />
|
||||
</SelectTrigger>
|
||||
<SelectContent>
|
||||
<SelectItem value="Open">Open</SelectItem>
|
||||
<SelectItem value="Close">Close</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
</div>
|
||||
<div className="space-y-2 px-3">
|
||||
<Label>Description</Label>
|
||||
|
||||
<Textarea
|
||||
value={description}
|
||||
onChange={(e) => setDescription(e.target.value)}
|
||||
placeholder="Enter description"
|
||||
/>
|
||||
</div>
|
||||
<div className="flex justify-end mt-3 mr-3">
|
||||
<Button type="submit" color="primary">
|
||||
Update
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
)}
|
||||
</div>
|
||||
</Card>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,11 @@
|
|||
import {
|
||||
httpGetInterceptor,
|
||||
} from "../http-config/http-interceptor-service";
|
||||
import { httpGetInterceptor } from "../http-config/http-interceptor-service";
|
||||
|
||||
export async function getFaqList() {
|
||||
const url = `master/faq/list`;
|
||||
return httpGetInterceptor(url);
|
||||
}
|
||||
}
|
||||
|
||||
export async function getUserFeedbacks() {
|
||||
const url = "feedback/list-all";
|
||||
return httpGetInterceptor(url);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,16 +1 @@
|
|||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../typescript/bin/tsc" "$@"
|
||||
else
|
||||
exec node "$basedir/../typescript/bin/tsc" "$@"
|
||||
fi
|
||||
../typescript/bin/tsc
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\typescript\bin\tsc" %*
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../typescript/bin/tsc" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../typescript/bin/tsc" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../typescript/bin/tsc" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../typescript/bin/tsc" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
|
|
@ -1,16 +1 @@
|
|||
#!/bin/sh
|
||||
basedir=$(dirname "$(echo "$0" | sed -e 's,\\,/,g')")
|
||||
|
||||
case `uname` in
|
||||
*CYGWIN*|*MINGW*|*MSYS*)
|
||||
if command -v cygpath > /dev/null 2>&1; then
|
||||
basedir=`cygpath -w "$basedir"`
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ -x "$basedir/node" ]; then
|
||||
exec "$basedir/node" "$basedir/../typescript/bin/tsserver" "$@"
|
||||
else
|
||||
exec node "$basedir/../typescript/bin/tsserver" "$@"
|
||||
fi
|
||||
../typescript/bin/tsserver
|
||||
|
|
@ -1,17 +0,0 @@
|
|||
@ECHO off
|
||||
GOTO start
|
||||
:find_dp0
|
||||
SET dp0=%~dp0
|
||||
EXIT /b
|
||||
:start
|
||||
SETLOCAL
|
||||
CALL :find_dp0
|
||||
|
||||
IF EXIST "%dp0%\node.exe" (
|
||||
SET "_prog=%dp0%\node.exe"
|
||||
) ELSE (
|
||||
SET "_prog=node"
|
||||
SET PATHEXT=%PATHEXT:;.JS;=;%
|
||||
)
|
||||
|
||||
endLocal & goto #_undefined_# 2>NUL || title %COMSPEC% & "%_prog%" "%dp0%\..\typescript\bin\tsserver" %*
|
||||
|
|
@ -1,28 +0,0 @@
|
|||
#!/usr/bin/env pwsh
|
||||
$basedir=Split-Path $MyInvocation.MyCommand.Definition -Parent
|
||||
|
||||
$exe=""
|
||||
if ($PSVersionTable.PSVersion -lt "6.0" -or $IsWindows) {
|
||||
# Fix case when both the Windows and Linux builds of Node
|
||||
# are installed in the same directory
|
||||
$exe=".exe"
|
||||
}
|
||||
$ret=0
|
||||
if (Test-Path "$basedir/node$exe") {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "$basedir/node$exe" "$basedir/../typescript/bin/tsserver" $args
|
||||
} else {
|
||||
& "$basedir/node$exe" "$basedir/../typescript/bin/tsserver" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
} else {
|
||||
# Support pipeline input
|
||||
if ($MyInvocation.ExpectingInput) {
|
||||
$input | & "node$exe" "$basedir/../typescript/bin/tsserver" $args
|
||||
} else {
|
||||
& "node$exe" "$basedir/../typescript/bin/tsserver" $args
|
||||
}
|
||||
$ret=$LASTEXITCODE
|
||||
}
|
||||
exit $ret
|
||||
Loading…
Reference in New Issue