This commit is contained in:
Sabda Yagra 2025-09-10 11:53:27 +07:00
parent 3d4860c7a5
commit 92f8a4b030
3 changed files with 122 additions and 71 deletions

View File

@ -169,7 +169,6 @@ export default function FormConvertSPIT() {
const t = useTranslations("Form"); const t = useTranslations("Form");
const { id } = useParams() as { id: string }; const { id } = useParams() as { id: string };
const [isAlreadySaved, setIsAlreadySaved] = useState(false); const [isAlreadySaved, setIsAlreadySaved] = useState(false);
const { const {
control, control,
handleSubmit, handleSubmit,

View File

@ -709,9 +709,9 @@ export default function FormDetailTicketing({ id }: Props) {
}; };
return ( return (
<section className="flex-1 flex flex-col bg-white"> <section className="flex flex-col h-full bg-white">
{/* Header */} {/* Header - tetap di atas */}
<div className="border-b px-4 py-3"> <div className="border-b px-4 py-3 shrink-0 bg-white sticky top-0 z-10">
<div className="flex items-center gap-3"> <div className="flex items-center gap-3">
<div className="text-sm font-medium"> <div className="text-sm font-medium">
{(detail?.title ?? "").split(" ").slice(0, 25).join(" ") + {(detail?.title ?? "").split(" ").slice(0, 25).join(" ") +
@ -723,10 +723,29 @@ export default function FormDetailTicketing({ id }: Props) {
</div> </div>
</div> </div>
{/* Chat Messages */} {/* Chat Messages - scrollable */}
<div className="flex-1 overflow-auto p-4 bg-gray-50 flex flex-col-reverse"> <div className="flex-1 overflow-y-auto p-4 space-y-3 bg-gray-50">
<div className="flex flex-col gap-3"> {!detail ? (
{ticketReply.map((m) => { <div className="h-full flex items-center justify-center text-muted-foreground">
<div className="text-center">
<div className="mb-4">
<svg
width="72"
height="72"
viewBox="0 0 24 24"
className="mx-auto opacity-60"
>
<path
fill="currentColor"
d="M12 3C7 3 3 6.6 3 11c0 1.9.8 3.6 2.2 5v3.1L8 17.9c1 .3 2 .5 4 .5 5 0 9-3.6 9-8.1S17 3 12 3z"
/>
</svg>
</div>
<div className="text-sm">Pilih issue untuk melihat detail</div>
</div>
</div>
) : (
ticketReply.map((m) => {
const isUser = m.user.fullname !== "Agent"; const isUser = m.user.fullname !== "Agent";
return ( return (
<div <div
@ -758,40 +777,63 @@ export default function FormDetailTicketing({ id }: Props) {
</div> </div>
</div> </div>
); );
})} })
</div> )}
<div ref={chatEndRef} />
</div> </div>
{/* Input Box */} {/* Input Box - tetap di bawah */}
<div className="border-t px-4 py-3 bg-white"> <div className="border-t px-4 py-3 bg-white shrink-0 sticky bottom-0 z-10">
<div className="flex flex-col gap-2 max-w-full mx-auto"> <div className="flex items-end gap-2">
{/* Translate button */}
<Button
variant="outline"
size="icon"
className="shrink-0"
onClick={handleTranslate}
>
<span>
<svg
xmlns="http://www.w3.org/2000/svg"
width="16"
height="16"
viewBox="0 0 16 16"
>
<g fill="currentColor">
<path d="M4.545 6.714L4.11 8H3l1.862-5h1.284L8 8H6.833l-.435-1.286zm1.634-.736L5.5 3.956h-.049l-.679 2.022z" />
<path d="M0 2a2 2 0 0 1 2-2h7a2 2 0 0 1 2 2v3h3a2 2 0 0 1 2 2v7a2 2 0 0 1-2 2H7a2 2 0 0 1-2-2v-3H2a2 2 0 0 1-2-2zm2-1a1 1 0 0 0-1 1v7a1 1 0 0 0 1 1h7a1 1 0 0 0 1-1V2a1 1 0 0 0-1-1zm7.138 9.995q.289.451.63.846c-.748.575-1.673 1.001-2.768 1.292c.178.217.451.635.555.867c1.125-.359 2.08-.844 2.886-1.494c.777.665 1.739 1.165 2.93 1.472c.133-.254.414-.673.629-.89c-1.125-.253-2.057-.694-2.82-1.284c.681-.747 1.222-1.651 1.621-2.757H14V8h-3v1.047h.765c-.318.844-.74 1.546-1.272 2.13a6 6 0 0 1-.415-.492a2 2 0 0 1-.94.31" />
</g>
</svg>
</span>
Translate
</Button>
{/* Textarea */}
<textarea <textarea
placeholder='Enter your reply or type "/" to insert a quick reply' placeholder="Tulis balasan..."
value={replyText} value={replyText}
onChange={(e) => setReplyText(e.target.value)} onChange={(e) => setReplyText(e.target.value)}
className="w-full border rounded-xl p-3 min-h-[64px] resize-none focus:outline-none focus:ring" className="flex-1 border rounded-xl p-3 resize-none min-h-[44px] max-h-[120px] focus:outline-none focus:ring"
rows={1}
/> />
<div className="flex items-center justify-between gap-3">
<Button variant="outline" size="sm" onClick={handleTranslate}> {/* Action buttons */}
Translate <div className="flex items-center gap-2 shrink-0">
<Button
variant="outline"
size="sm"
onClick={() => sendReply(true)}
disabled={!replyText.trim()}
>
Resolve
</Button>
<Button
size="sm"
onClick={() => sendReply(false)}
disabled={!replyText.trim()}
>
Kirim
</Button> </Button>
<div className="flex items-center gap-2">
<Button
variant="outline"
size="sm"
onClick={() => sendReply(true)}
disabled={!replyText.trim()}
>
Kirim & Resolve
</Button>
<Button
size="sm"
onClick={() => sendReply(false)}
disabled={!replyText.trim()}
>
Kirim
</Button>
</div>
</div> </div>
</div> </div>
</div> </div>

View File

@ -2642,6 +2642,8 @@ export function getMenuList(pathname: string, t: any): Group[] {
(Number(roleId) == 3 || Number(roleId) == 14 || Number(roleId) == 15) && (Number(roleId) == 3 || Number(roleId) == 14 || Number(roleId) == 15) &&
Number(levelNumber) == 3 Number(levelNumber) == 3
) { ) {
const hideForRole3 = Number(roleId) === 3;
if (Number(userParentLevelId) != 761) { if (Number(userParentLevelId) != 761) {
menusSelected = [ menusSelected = [
{ {
@ -2697,13 +2699,17 @@ export function getMenuList(pathname: string, t: any): Group[] {
icon: "heroicons:share", icon: "heroicons:share",
children: [], children: [],
}, },
{ ...(!hideForRole3
href: "/contributor/content/spit", ? [
label: "spit", {
active: pathname.includes("/content/spit"), href: "/contributor/content/spit",
icon: "heroicons:credit-card", label: "spit",
children: [], active: pathname.includes("/content/spit"),
}, icon: "heroicons:credit-card",
children: [],
},
]
: []),
// { // {
// href: "/contributor/content/nulis-ai", // href: "/contributor/content/nulis-ai",
// label: "nulis ai", // label: "nulis ai",
@ -2729,35 +2735,39 @@ export function getMenuList(pathname: string, t: any): Group[] {
}, },
], ],
}, },
{ ...(!hideForRole3
groupLabel: "", ? [
id: "planning", {
menus: [ groupLabel: "",
{ id: "planning",
id: "planning", menus: [
href: "/contributor/planning", {
label: t("planning"), id: "planning",
active: pathname.includes("/planning"), href: "/contributor/planning",
icon: "pajamas:planning", label: t("planning"),
submenus: [ active: pathname.includes("/planning"),
{ icon: "pajamas:planning",
href: "/contributor/planning/mediahub", submenus: [
label: "mediaHub", {
active: pathname.includes("/planning/mediahub"), href: "/contributor/planning/mediahub",
icon: "heroicons:arrow-trending-up", label: "mediaHub",
children: [], 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"), href: "/contributor/planning/medsos-mediahub",
icon: "heroicons:shopping-cart", label: "medsos mediahub",
children: [], active: pathname.includes("/planning/medsos-mediahub"),
}, icon: "heroicons:shopping-cart",
], children: [],
}, },
], ],
}, },
],
},
]
: []),
{ {
groupLabel: "", groupLabel: "",
id: "task", id: "task",