82 lines
3.4 KiB
TypeScript
82 lines
3.4 KiB
TypeScript
"use client";
|
||
|
||
import { useEffect, useState } from "react";
|
||
import Link from "next/link";
|
||
import { Button, Container, SectionTitle } from "@/components/ui";
|
||
import { loadCommercialBundles, loadCommercialPricing } from "@/modules/commercial/adapters";
|
||
import type { AdapterResult, CommercialBundle, CommercialPricingItem } from "@/modules/commercial/types";
|
||
import { BundleCard, CommercialEmptyState } from "@/modules/commercial/components";
|
||
|
||
export default function PricingPage() {
|
||
const [pricing, setPricing] = useState<AdapterResult<CommercialPricingItem[]> | null>(null);
|
||
const [bundles, setBundles] = useState<AdapterResult<CommercialBundle[]> | null>(null);
|
||
|
||
useEffect(() => {
|
||
void Promise.all([loadCommercialPricing(), loadCommercialBundles()]).then(([p, b]) => {
|
||
setPricing(p);
|
||
setBundles(b);
|
||
});
|
||
}, []);
|
||
|
||
return (
|
||
<Container className="py-12">
|
||
<div className="mb-8 flex flex-wrap items-end justify-between gap-4">
|
||
<div>
|
||
<h1 className="text-3xl font-extrabold text-secondary dark:text-gray-100">قیمتگذاری</h1>
|
||
<p className="mt-2 max-w-xl text-sm text-gray-600 dark:text-gray-400">
|
||
تمام مبالغ و مدلها از کاتالوگ تجاری runtime — بدون قیمت ثابت در frontend.
|
||
</p>
|
||
</div>
|
||
<Link href="/discover">
|
||
<Button>شروع Trial</Button>
|
||
</Link>
|
||
</div>
|
||
|
||
<section>
|
||
<SectionTitle title="کاتالوگ قیمت" />
|
||
{pricing?.availability === "ready" && pricing.data.length ? (
|
||
<ul className="mt-4 grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
||
{pricing.data.map((item) => (
|
||
<li
|
||
key={item.pricing_item_code}
|
||
className="rounded-2xl border border-gray-100 bg-white p-5 dark:border-gray-800 dark:bg-gray-900"
|
||
>
|
||
<p className="text-lg font-bold text-secondary dark:text-gray-100">
|
||
{item.display_name}
|
||
</p>
|
||
<p className="mt-2 text-sm text-gray-600">
|
||
{item.pricing_model || "—"} ·{" "}
|
||
{item.amount_minor != null
|
||
? `${item.amount_minor} ${item.currency || ""}`
|
||
: "مبلغ از بکاند"}
|
||
</p>
|
||
{item.trial_days != null ? (
|
||
<p className="mt-2 text-xs text-primary">Trial {item.trial_days} روز</p>
|
||
) : null}
|
||
{item.tax_class_code ? (
|
||
<p className="mt-1 text-[10px] text-gray-400">مالیات: {item.tax_class_code}</p>
|
||
) : null}
|
||
</li>
|
||
))}
|
||
</ul>
|
||
) : (
|
||
<CommercialEmptyState title="قیمتگذاری خالی است" description={pricing?.message} />
|
||
)}
|
||
</section>
|
||
|
||
<section className="mt-12">
|
||
<SectionTitle title="باندلها" subtitle="قیمت داخل باندل نیست — فقط pricing_refs" />
|
||
{bundles?.availability === "ready" && bundles.data.length ? (
|
||
<div className="mt-4 grid gap-4">
|
||
{bundles.data.map((b) => (
|
||
<BundleCard key={b.bundle_code} bundle={b} />
|
||
))}
|
||
</div>
|
||
) : (
|
||
<CommercialEmptyState title="باندلی نیست" description={bundles?.message} />
|
||
)}
|
||
</section>
|
||
</Container>
|
||
);
|
||
}
|