chore: initial project import
Some checks failed
CI - Production Readiness / Verify (push) Has been cancelled

This commit is contained in:
Wira Basalamah
2026-04-21 09:29:29 +07:00
commit adde003fba
222 changed files with 37657 additions and 0 deletions

View File

@ -0,0 +1,25 @@
import Link from "next/link";
import { ShellPage } from "@/components/page-templates";
import { TablePlaceholder } from "@/components/placeholders";
import { getAgentMentionedConversations } from "@/lib/inbox-ops";
export default async function AgentMentionedPage() {
const rows = await getAgentMentionedConversations();
return (
<ShellPage shell="agent" title="Mentioned Conversations" description="Conversation yang melibatkan agent secara khusus.">
<TablePlaceholder
title="Mentioned"
columns={["Conversation", "Mentioned by", "Time"]}
rows={rows.map((item) => [
<Link key={`${item.id}-conv`} className="text-primary underline" href={`/agent/inbox?conversationId=${item.id}`}>
{item.contactName}
</Link>,
item.mentionedBy,
item.time
])}
/>
</ShellPage>
);
}

48
app/agent/inbox/page.tsx Normal file
View File

@ -0,0 +1,48 @@
import { InboxPlaceholder } from "@/components/placeholders";
import { ShellPage } from "@/components/page-templates";
import {
addConversationNote,
assignConversation,
getInboxWorkspace,
replyToConversation,
setConversationTags,
updateConversationStatus
} from "@/lib/inbox-ops";
const allowedFilters = ["all", "open", "pending", "resolved", "unassigned"] as const;
export default async function AgentInboxPage({
searchParams
}: {
searchParams: Promise<{ conversationId?: string; filter?: string }>;
}) {
const params = await searchParams;
const filter =
params?.filter && allowedFilters.includes(params.filter as (typeof allowedFilters)[number])
? (params.filter as (typeof allowedFilters)[number])
: "all";
const data = await getInboxWorkspace({
scope: "agent",
conversationId: params?.conversationId,
filter
});
return (
<ShellPage shell="agent" title="My Inbox" description="Assigned conversations, notes, tags, dan reply composer versi agent.">
<InboxPlaceholder
conversations={data.conversations}
selectedConversation={data.selectedConversation}
defaultPath={data.defaultPath}
role={data.role}
filter={data.filter}
canSelfAssign={data.canSelfAssign}
assignConversation={assignConversation}
updateConversationStatus={updateConversationStatus}
replyToConversation={replyToConversation}
addConversationNote={addConversationNote}
setConversationTags={setConversationTags}
/>
</ShellPage>
);
}

View File

@ -0,0 +1,17 @@
import { ShellPage } from "@/components/page-templates";
import { TablePlaceholder } from "@/components/placeholders";
import { getAgentResolvedHistory } from "@/lib/inbox-ops";
export default async function AgentResolvedPage() {
const rows = await getAgentResolvedHistory();
return (
<ShellPage shell="agent" title="Resolved History" description="Riwayat conversation yang sudah selesai ditangani.">
<TablePlaceholder
title="Resolved"
columns={["Conversation", "Resolved at", "Last action"]}
rows={rows.map((item) => [item.contactName, item.resolvedAt, item.lastAction])}
/>
</ShellPage>
);
}

View File

@ -0,0 +1,31 @@
import { ShellPage } from "@/components/page-templates";
import { TablePlaceholder } from "@/components/placeholders";
import { assignConversation, getInboxWorkspace } from "@/lib/inbox-ops";
export default async function AgentUnassignedPage() {
const data = await getInboxWorkspace({ scope: "agent", filter: "unassigned" });
return (
<ShellPage shell="agent" title="Unassigned Queue" description="Queue yang bisa diambil agent jika diizinkan.">
<TablePlaceholder
title="Queue"
columns={["Contact", "Last message", "Waiting time", "Action"]}
rows={data.conversations.map((item) => [
<>
<p>{item.name}</p>
<p className="text-xs text-outline">{item.phone}</p>
</>,
item.snippet,
item.time,
<form key={item.id} action={assignConversation} className="inline">
<input type="hidden" name="conversationId" value={item.id} />
<input type="hidden" name="nextPath" value="/agent/inbox/unassigned" />
<button className="rounded-full bg-surface-container-low px-3 py-2 text-xs" type="submit">
Take assignment
</button>
</form>
])}
/>
</ShellPage>
);
}