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,73 @@
import { ShellPage } from "@/components/page-templates";
import { Button, SectionCard } from "@/components/ui";
import { getSession } from "@/lib/auth";
import { prisma } from "@/lib/prisma";
import { redirect } from "next/navigation";
export default async function ExportContactsPage() {
const session = await getSession();
if (!session) {
redirect("/login");
}
if (session.role === "agent") {
redirect("/unauthorized");
}
const [segments, tags, count, lastUpdated] = await Promise.all([
prisma.contactSegment.findMany({
where: { tenantId: session.tenantId },
orderBy: { name: "asc" },
select: { id: true, name: true, _count: { select: { members: true } } }
}),
prisma.tag.findMany({ where: { tenantId: session.tenantId }, select: { name: true }, orderBy: { name: "asc" } }),
prisma.contact.count({ where: { tenantId: session.tenantId } }),
prisma.contact.findFirst({
where: { tenantId: session.tenantId },
orderBy: { updatedAt: "desc" },
select: { updatedAt: true }
})
]);
const fields = ["fullName", "phoneNumber", "email", "countryCode", "optInStatus", "createdAt", "updatedAt"];
return (
<ShellPage shell="admin" title="Export Contacts" description="Atur field dan filter sebelum export.">
<SectionCard title="Export options">
<div className="grid gap-4 md:max-w-xl">
<p className="rounded-xl border border-line bg-surface-container p-3 text-sm text-on-surface-variant">
Total kontak: {count} Last updated: {lastUpdated?.updatedAt ? new Intl.DateTimeFormat("id-ID").format(lastUpdated.updatedAt) : "-"}
</p>
<input className="rounded-xl border border-line px-4 py-3" placeholder="Filter tags / segments" />
<select className="rounded-xl border border-line px-4 py-3" defaultValue="">
<option value="">Select segment (optional)</option>
{segments.map((segment) => (
<option key={segment.id} value={segment.id}>
{segment.name} ({segment._count.members})
</option>
))}
</select>
<label className="text-sm text-on-surface-variant">
<span>Fields to export</span>
<select className="mt-2 w-full rounded-xl border border-line px-4 py-3">
{fields.map((field) => (
<option key={field} value={field}>
{field}
</option>
))}
</select>
</label>
<p className="text-sm text-on-surface-variant">Available tags: {tags.length ? tags.map((tag) => tag.name).join(", ") : "-"}</p>
<div>
<Button href="/contacts">Export</Button>
</div>
<div>
{segments.length === 0 ? (
<p className="text-xs text-warning">Tambahkan segment untuk filtering export yang lebih presisi.</p>
) : null}
</div>
</div>
</SectionCard>
</ShellPage>
);
}