TorbatYar/frontend/app/pricing/page.tsx
2026-07-28 20:39:10 +03:30

82 lines
3.4 KiB
TypeScript
Raw Permalink Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"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>
);
}