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,119 @@
import Link from "next/link";
import { redirect } from "next/navigation";
import { ShellPage } from "@/components/page-templates";
import { Button, SectionCard } from "@/components/ui";
import { getSession } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
function formatDate(date: Date | null | undefined) {
if (!date) {
return "-";
}
return new Intl.DateTimeFormat("id-ID", {
day: "2-digit",
month: "short",
year: "numeric",
hour: "2-digit",
minute: "2-digit"
}).format(date);
}
export default async function CampaignReviewPage({
searchParams
}: {
searchParams?: Promise<{ campaignId?: string; error?: string }>;
}) {
const session = await getSession();
if (!session) {
redirect("/login");
}
const query = await (searchParams ?? Promise.resolve<{ campaignId?: string; error?: string }>({}));
const campaignId = query.campaignId;
const campaign = campaignId
? await prisma.broadcastCampaign.findFirst({
where: {
id: campaignId,
tenantId: session.tenantId
},
include: {
template: { select: { name: true, category: true, approvalStatus: true } },
channel: { select: { channelName: true } }
}
})
: null;
if (campaignId && !campaign) {
redirect("/campaigns/review?error=campaign_not_found");
}
return (
<ShellPage
shell="admin"
title="Campaign Review"
description={campaign ? "Review draft campaign sebelum di-queue untuk pengiriman." : "Belum ada campaign yang dipilih untuk review."}
>
<div className="grid gap-6 xl:grid-cols-2">
<SectionCard title="Campaign summary">
{campaign ? (
<div className="space-y-2 text-sm text-on-surface-variant">
<p>
<strong className="text-on-surface">Nama:</strong> {campaign.name}
</p>
<p>
<strong className="text-on-surface">Template:</strong> {campaign.template.name} ({campaign.template.category}) {" "}
{campaign.template.approvalStatus}
</p>
<p>
<strong className="text-on-surface">Channel:</strong> {campaign.channel.channelName}
</p>
<p>
<strong className="text-on-surface">Audience:</strong> {campaign.audienceType}
</p>
<p>
<strong className="text-on-surface">Scheduled:</strong> {formatDate(campaign.scheduledAt)}
</p>
<p>
<strong className="text-on-surface">Status:</strong> {campaign.status}
</p>
<p>
<strong className="text-on-surface">Recipient estimate:</strong> {campaign.totalRecipients}
</p>
<p className="mt-2">Estimasi sukses: {(campaign.totalRecipients * 0.82).toFixed(0)} kontak</p>
</div>
) : (
<p className="text-sm text-on-surface-variant">Pilih campaign dari halaman campaign list untuk menampilkan detail review.</p>
)}
</SectionCard>
<SectionCard title="Review checks">
{campaign ? (
<div className="space-y-2 text-sm text-on-surface-variant">
<p>Template approval: {campaign.template.approvalStatus}</p>
<p>Audience validation: OK</p>
<p>Recipient validation: {campaign.totalRecipients > 0 ? "PASS" : "No recipients"}</p>
<p>Channel availability: Available</p>
</div>
) : (
<p className="text-sm text-on-surface-variant">Tidak ada pemeriksaan yang berjalan karena campaign belum dipilih.</p>
)}
</SectionCard>
</div>
<div className="flex gap-3">
{campaign ? (
<Button href={`/campaigns/${campaign.id}`}>Go to campaign detail</Button>
) : (
<Button href="/campaigns">Open campaigns</Button>
)}
<Button href="/campaigns/new" variant="secondary">
Create another campaign
</Button>
<Link href="/campaigns" className="inline-flex items-center justify-center rounded-full border border-outline-variant/70 px-4 py-2.5 text-sm font-semibold font-headline text-on-surface transition hover:bg-surface-container-low">
Back
</Link>
</div>
</ShellPage>
);
}