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:
93
app/super-admin/tenants/[tenantId]/edit/page.tsx
Normal file
93
app/super-admin/tenants/[tenantId]/edit/page.tsx
Normal file
@ -0,0 +1,93 @@
|
||||
import { redirect } from "next/navigation";
|
||||
|
||||
import { ShellPage } from "@/components/page-templates";
|
||||
import { Button, SectionCard } from "@/components/ui";
|
||||
import { updateTenant } from "@/lib/admin-crud";
|
||||
import { getSession } from "@/lib/auth";
|
||||
import { prisma } from "@/lib/prisma";
|
||||
|
||||
function formatTenantLabel(tenant: { status: string }) {
|
||||
return tenant.status;
|
||||
}
|
||||
|
||||
export default async function EditTenantPage({
|
||||
params,
|
||||
searchParams
|
||||
}: {
|
||||
params: Promise<{ tenantId: string }>;
|
||||
searchParams?: Promise<{ error?: string }>;
|
||||
}) {
|
||||
const session = await getSession();
|
||||
if (!session || session.role !== "super_admin") {
|
||||
redirect("/unauthorized");
|
||||
}
|
||||
|
||||
const { tenantId } = await params;
|
||||
const [tenant, plans, query] = await Promise.all([
|
||||
prisma.tenant.findUnique({
|
||||
where: { id: tenantId },
|
||||
include: { plan: true }
|
||||
}),
|
||||
prisma.subscriptionPlan.findMany({ orderBy: { priceMonthly: "asc" } }),
|
||||
searchParams ?? Promise.resolve({ error: undefined })
|
||||
]);
|
||||
|
||||
if (!tenant) {
|
||||
redirect("/super-admin/tenants?error=tenant_not_found");
|
||||
}
|
||||
|
||||
const error = query.error;
|
||||
const infoMessage =
|
||||
error === "missing_fields"
|
||||
? "Semua field wajib diisi."
|
||||
: error === "slug_exists"
|
||||
? "Slug sudah dipakai tenant lain."
|
||||
: error === "invalid_plan"
|
||||
? "Plan tidak valid."
|
||||
: null;
|
||||
|
||||
return (
|
||||
<ShellPage shell="super-admin" title="Edit Tenant" description="Update tenant profile dan subscription metadata.">
|
||||
<SectionCard title="Tenant form">
|
||||
<form action={updateTenant} className="grid gap-4 md:max-w-3xl">
|
||||
<input type="hidden" name="tenantId" value={tenant.id} />
|
||||
{infoMessage ? (
|
||||
<p className="rounded-xl border border-warning/30 bg-warning/10 p-3 text-sm text-warning">{infoMessage}</p>
|
||||
) : null}
|
||||
<input
|
||||
name="name"
|
||||
className="rounded-xl border border-line px-4 py-3"
|
||||
defaultValue={tenant.name}
|
||||
placeholder="Company name"
|
||||
required
|
||||
/>
|
||||
<input
|
||||
name="companyName"
|
||||
className="rounded-xl border border-line px-4 py-3"
|
||||
defaultValue={tenant.companyName}
|
||||
placeholder="Company legal name"
|
||||
required
|
||||
/>
|
||||
<input name="slug" className="rounded-xl border border-line px-4 py-3" defaultValue={tenant.slug} placeholder="Tenant slug" required />
|
||||
<select name="status" required className="rounded-xl border border-line px-4 py-3" defaultValue={formatTenantLabel(tenant)}>
|
||||
<option value="ACTIVE">Active</option>
|
||||
<option value="TRIAL">Trial</option>
|
||||
<option value="SUSPENDED">Suspended</option>
|
||||
<option value="INACTIVE">Inactive</option>
|
||||
</select>
|
||||
<select name="planId" required className="rounded-xl border border-line px-4 py-3" defaultValue={tenant.planId}>
|
||||
{plans.map((plan) => (
|
||||
<option key={plan.id} value={plan.id}>
|
||||
{plan.name} ({plan.code})
|
||||
</option>
|
||||
))}
|
||||
</select>
|
||||
<input name="timezone" className="rounded-xl border border-line px-4 py-3" placeholder="Timezone" defaultValue={tenant.timezone} required />
|
||||
<div>
|
||||
<Button type="submit">Save changes</Button>
|
||||
</div>
|
||||
</form>
|
||||
</SectionCard>
|
||||
</ShellPage>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user