chore: initial project import
Some checks failed
CI - Production Readiness / Verify (push) Has been cancelled
Some checks failed
CI - Production Readiness / Verify (push) Has been cancelled
This commit is contained in:
84
app/settings/integrations/page.tsx
Normal file
84
app/settings/integrations/page.tsx
Normal file
@ -0,0 +1,84 @@
|
||||
import { ShellPage } from "@/components/page-templates";
|
||||
import { SectionCard } from "@/components/ui";
|
||||
import { headers } from "next/headers";
|
||||
import { getSession } from "@/lib/auth";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
export default async function IntegrationsSettingsPage() {
|
||||
const session = await getSession();
|
||||
if (!session) {
|
||||
redirect("/login");
|
||||
}
|
||||
|
||||
if (session.role === "agent") {
|
||||
redirect("/unauthorized");
|
||||
}
|
||||
|
||||
const tenantFilter = session.role === "super_admin" ? {} : { tenantId: session.tenantId };
|
||||
|
||||
const [channels, recentWebhook] = await Promise.all([
|
||||
prisma.channel.findMany({
|
||||
where: tenantFilter,
|
||||
orderBy: { createdAt: "desc" }
|
||||
}),
|
||||
prisma.webhookEvent.findMany({
|
||||
where: tenantFilter,
|
||||
orderBy: { createdAt: "desc" },
|
||||
take: 4
|
||||
})
|
||||
]);
|
||||
|
||||
const host = (await headers()).get("host");
|
||||
const webhookBase = host ? `${process.env.NODE_ENV === "production" ? "https" : "http"}://${host}` : "";
|
||||
|
||||
const connectedCount = channels.filter((channel) => channel.status === "CONNECTED").length;
|
||||
const failedCount = channels.filter((channel) => channel.status === "ERROR").length;
|
||||
|
||||
return (
|
||||
<ShellPage
|
||||
shell="admin"
|
||||
title="Webhook / Integration Settings"
|
||||
description="Status provider, webhook URL, dan reconnection action."
|
||||
>
|
||||
<div className="grid gap-6 xl:grid-cols-2">
|
||||
<SectionCard title="Provider config">
|
||||
<p className="text-sm text-on-surface-variant">
|
||||
Webhook URL: {webhookBase ? `${webhookBase}/api/webhooks/whatsapp` : "/api/webhooks/whatsapp"}
|
||||
</p>
|
||||
<p className="text-sm text-on-surface-variant">
|
||||
Connected: {connectedCount} • Error: {failedCount} • Total channels: {channels.length}
|
||||
</p>
|
||||
<ul className="mt-3 space-y-2">
|
||||
{channels.map((channel) => (
|
||||
<li key={channel.id} className="rounded-xl border border-line bg-surface-container p-3">
|
||||
<p className="font-medium text-ink">{channel.channelName}</p>
|
||||
<p className="text-sm text-on-surface-variant">Status: {channel.status}</p>
|
||||
<p className="text-sm text-outline">Provider: {channel.provider}</p>
|
||||
<p className="text-xs text-outline">
|
||||
WABA ID: {channel.wabaId ?? "N/A"} • Phone ID: {channel.phoneNumberId ?? "N/A"}
|
||||
</p>
|
||||
</li>
|
||||
))}
|
||||
{channels.length === 0 ? <p className="text-sm text-on-surface-variant">Tidak ada channel terhubung.</p> : null}
|
||||
</ul>
|
||||
</SectionCard>
|
||||
<SectionCard title="Health state">
|
||||
<ul className="space-y-2">
|
||||
{recentWebhook.map((event) => (
|
||||
<li key={event.id} className="rounded-xl border border-line bg-surface-container p-3">
|
||||
<p className="text-sm text-on-surface-variant">
|
||||
{event.eventType} • {event.processStatus}
|
||||
</p>
|
||||
<p className="text-xs text-outline">
|
||||
{event.createdAt.toLocaleString("id-ID", { dateStyle: "medium", timeStyle: "short" })}
|
||||
</p>
|
||||
</li>
|
||||
))}
|
||||
{recentWebhook.length === 0 ? <p className="text-sm text-on-surface-variant">Belum ada event webhook terbaru.</p> : null}
|
||||
</ul>
|
||||
</SectionCard>
|
||||
</div>
|
||||
</ShellPage>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user