Phase2: Invoicecomputation/AdminpricingUI/Ainvoicemgnt
Some checks failed
Build and Push / build (push) Failing after 28s
Some checks failed
Build and Push / build (push) Failing after 28s
This commit is contained in:
55
src/app/[locale]/admin/billing/pricing/page.tsx
Normal file
55
src/app/[locale]/admin/billing/pricing/page.tsx
Normal file
@@ -0,0 +1,55 @@
|
||||
import { redirect } from "next/navigation";
|
||||
import { getTranslations } from "next-intl/server";
|
||||
import { getSessionUser } from "@/lib/session";
|
||||
import { getPlatformPricing, listSkillPricing } from "@/lib/db";
|
||||
import { PACKAGE_CATALOG } from "@/lib/packages";
|
||||
import { BackLink } from "@/components/ui/back-link";
|
||||
import { PricingEditor } from "@/components/admin/billing/pricing-editor";
|
||||
|
||||
/**
|
||||
* /admin/billing/pricing — edit platform-wide pricing config
|
||||
* (monthly fee, setup fee, Threema per-message, VAT rate for
|
||||
* CH/LI) and per-skill daily prices.
|
||||
*
|
||||
* Single-row platform_pricing semantics: one global pricing
|
||||
* config applies to every tenant. No per-tenant overrides in
|
||||
* v1.
|
||||
*/
|
||||
export default async function AdminBillingPricingPage() {
|
||||
const user = await getSessionUser();
|
||||
if (!user) redirect("/login");
|
||||
if (!user.isPlatform) redirect("/dashboard");
|
||||
const t = await getTranslations("adminBilling");
|
||||
|
||||
const [pricing, skillPricing] = await Promise.all([
|
||||
getPlatformPricing(),
|
||||
listSkillPricing(),
|
||||
]);
|
||||
|
||||
// Surface every package in the catalog so admin can price any of
|
||||
// them — UI defaults the picker to skill-kind entries but doesn't
|
||||
// hard-block other kinds (a future scenario where a non-skill
|
||||
// package gets a per-day price shouldn't need a code change).
|
||||
const catalog = Object.values(PACKAGE_CATALOG).map((p) => ({
|
||||
id: p.id,
|
||||
name: p.name,
|
||||
kind: p.kind,
|
||||
}));
|
||||
|
||||
return (
|
||||
<main className="max-w-4xl mx-auto px-6 py-8">
|
||||
<BackLink href="/admin/billing" label={t("backToBilling")} />
|
||||
<div className="mb-8 animate-in">
|
||||
<h1 className="font-display text-2xl font-semibold accent-rule">
|
||||
{t("pricingTitle")}
|
||||
</h1>
|
||||
<p className="text-sm text-text-secondary mt-3">{t("pricingPageDesc")}</p>
|
||||
</div>
|
||||
<PricingEditor
|
||||
initialPricing={pricing}
|
||||
initialSkillPricing={skillPricing}
|
||||
catalog={catalog}
|
||||
/>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user