110 lines
4.8 KiB
TypeScript
110 lines
4.8 KiB
TypeScript
"use client";
|
|
|
|
import { useState } from "react";
|
|
import { useTranslation } from "@/i18n/navigation";
|
|
import { Link } from "@/i18n/navigation";
|
|
import Footer from "@/app/components/Footer";
|
|
|
|
const PLANS = [
|
|
{ id: "free", key: "free", price: 0, priceYear: 0, features: ["browse"], highlight: false },
|
|
{ id: "basic", key: "basic", price: 39, priceYear: 390, features: ["browse", "noAds", "advancedFilter", "unlimitedSwipe", "priorityEvent"], highlight: true },
|
|
{ id: "pro", key: "pro", price: 149, priceYear: 1490, features: ["browse", "noAds", "advancedFilter", "unlimitedSwipe", "priorityEvent", "crmRoster", "oneOnOne", "gigAccess", "dashboard"], highlight: false },
|
|
] as const;
|
|
|
|
export default function PricingPage() {
|
|
const { t } = useTranslation("pricing");
|
|
const [yearly, setYearly] = useState(false);
|
|
|
|
return (
|
|
<div className="min-h-screen bg-[#fafafa] dark:bg-gray-950">
|
|
<div className="max-w-6xl mx-auto px-4 sm:px-6 py-12 sm:py-16">
|
|
<div className="text-center mb-12">
|
|
<h1 className="text-2xl sm:text-3xl md:text-4xl font-bold text-gray-900 dark:text-gray-100">
|
|
{t("title")}
|
|
</h1>
|
|
<p className="mt-2 text-gray-500 dark:text-gray-400">
|
|
{t("subtitle")}
|
|
</p>
|
|
<div className="mt-6 flex items-center justify-center gap-3">
|
|
<span className={`text-sm font-medium ${!yearly ? "text-gray-900 dark:text-gray-100" : "text-gray-500 dark:text-gray-400"}`}>
|
|
{t("monthly")}
|
|
</span>
|
|
<button
|
|
type="button"
|
|
onClick={() => setYearly(!yearly)}
|
|
className={`relative w-12 h-6 rounded-full transition-colors ${yearly ? "bg-[#ff4d4f]" : "bg-gray-200 dark:bg-gray-700"}`}
|
|
>
|
|
<span className={`absolute top-1 w-4 h-4 rounded-full bg-white shadow transition-transform ${yearly ? "left-7" : "left-1"}`} />
|
|
</button>
|
|
<span className={`text-sm font-medium ${yearly ? "text-gray-900 dark:text-gray-100" : "text-gray-500 dark:text-gray-400"}`}>
|
|
{t("yearly")}
|
|
</span>
|
|
</div>
|
|
</div>
|
|
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 lg:gap-8">
|
|
{PLANS.map((plan) => {
|
|
const displayPrice = yearly ? plan.priceYear : plan.price;
|
|
const priceKey = yearly ? "perYear" : "perMonth";
|
|
return (
|
|
<div
|
|
key={plan.id}
|
|
className={`rounded-2xl border p-6 sm:p-8 flex flex-col ${
|
|
plan.highlight
|
|
? "border-[#ff4d4f] bg-white dark:bg-gray-900 shadow-xl dark:shadow-none ring-2 ring-[#ff4d4f]/20"
|
|
: "border-gray-200 dark:border-gray-700 bg-white dark:bg-gray-900"
|
|
}`}
|
|
>
|
|
<h2 className="text-xl font-bold text-gray-900 dark:text-gray-100">
|
|
{t(plan.key)}
|
|
</h2>
|
|
<div className="mt-4 flex items-baseline gap-1">
|
|
<span className="text-3xl sm:text-4xl font-bold text-gray-900 dark:text-gray-100">
|
|
{displayPrice === 0 ? "¥0" : `¥${displayPrice.toLocaleString()}`}
|
|
</span>
|
|
{displayPrice > 0 && (
|
|
<span className="text-gray-500 dark:text-gray-400">
|
|
{t(priceKey)}
|
|
</span>
|
|
)}
|
|
</div>
|
|
{yearly && plan.priceYear > 0 && (
|
|
<p className="mt-1 text-xs text-green-600 dark:text-green-400">
|
|
省 ¥{(plan.price * 12 - plan.priceYear).toLocaleString()}
|
|
</p>
|
|
)}
|
|
<ul className="mt-6 space-y-3 flex-1">
|
|
{plan.features.map((f) => (
|
|
<li
|
|
key={f}
|
|
className="flex items-center gap-2 text-sm text-gray-600 dark:text-gray-300"
|
|
>
|
|
<span className="text-green-500">✓</span>
|
|
{t(`features.${f}`)}
|
|
</li>
|
|
))}
|
|
</ul>
|
|
<Link
|
|
href="/join"
|
|
className={`mt-6 w-full py-3 rounded-lg text-center font-medium transition-colors ${
|
|
plan.highlight
|
|
? "bg-[#ff4d4f] text-white hover:bg-[#ff3333]"
|
|
: "bg-gray-100 dark:bg-gray-800 text-gray-900 dark:text-gray-100 hover:bg-gray-200 dark:hover:bg-gray-700"
|
|
}`}
|
|
>
|
|
{plan.id === "free" ? t("getStarted") : t("upgrade")}
|
|
</Link>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
|
|
<p className="mt-8 text-center text-sm text-gray-500 dark:text-gray-400">
|
|
{t("features.experienceCamp")}
|
|
</p>
|
|
</div>
|
|
<Footer />
|
|
</div>
|
|
);
|
|
}
|