Files
ContentGen_FE/src/app/[locale]/(dashboard)/dashboard/pricing/page.tsx
Harun CAN 45a540c530
Some checks failed
UI Deploy (Next-Auth Support) 🎨 / build-and-deploy (push) Has been cancelled
main
2026-03-29 12:44:02 +03:00

252 lines
8.9 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters
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 { useState } from "react";
import { motion } from "framer-motion";
import {
Check,
X,
Zap,
Crown,
Rocket,
Sparkles,
ArrowRight,
} from "lucide-react";
import { cn } from "@/lib/utils";
const plans = [
{
id: "free",
name: "Free",
icon: Sparkles,
monthlyPrice: 0,
yearlyPrice: 0,
credits: 3,
description: "AI video üretimini keşfet",
color: "emerald",
gradient: "from-emerald-500/15 to-emerald-600/5",
borderActive: "border-emerald-500/30",
buttonClass: "btn-ghost",
buttonLabel: "Mevcut Plan",
features: [
{ label: "3 kredi / ay", included: true },
{ label: "720p video kalitesi", included: true },
{ label: "Max 30 saniye", included: true },
{ label: "5 proje limiti", included: true },
{ label: "Temel şablonlar", included: true },
{ label: "Öncelikli kuyruk", included: false },
{ label: "Marka kaldırma", included: false },
{ label: "API erişimi", included: false },
],
},
{
id: "pro",
name: "Pro",
icon: Zap,
monthlyPrice: 19,
yearlyPrice: 190,
credits: 50,
description: "İçerik üreticileri için güçlü araçlar",
color: "violet",
gradient: "from-violet-500/20 to-violet-600/8",
borderActive: "border-violet-500/40",
buttonClass: "btn-primary",
buttonLabel: "Pro'ya Yükselt",
recommended: true,
features: [
{ label: "50 kredi / ay", included: true },
{ label: "1080p video kalitesi", included: true },
{ label: "Max 120 saniye", included: true },
{ label: "50 proje limiti", included: true },
{ label: "Tüm şablonlar", included: true },
{ label: "Öncelikli kuyruk", included: true },
{ label: "Marka kaldırma", included: true },
{ label: "API erişimi", included: false },
],
},
{
id: "business",
name: "Business",
icon: Crown,
monthlyPrice: 49,
yearlyPrice: 490,
credits: -1,
description: "Ajanslar ve profesyonel ekipler",
color: "cyan",
gradient: "from-cyan-500/15 to-cyan-600/5",
borderActive: "border-cyan-500/30",
buttonClass: "btn-primary",
buttonLabel: "Business'a Yükselt",
features: [
{ label: "Sınırsız kredi", included: true },
{ label: "1080p video kalitesi", included: true },
{ label: "Max 180 saniye", included: true },
{ label: "Sınırsız proje", included: true },
{ label: "Tüm şablonlar + Özel", included: true },
{ label: "Öncelikli kuyruk", included: true },
{ label: "Marka kaldırma", included: true },
{ label: "API erişimi", included: true },
],
},
];
const fadeUp = {
hidden: { opacity: 0, y: 20 },
show: { opacity: 1, y: 0, transition: { duration: 0.6, ease: [0.16, 1, 0.3, 1] as const } },
};
export default function PricingPage() {
const [isYearly, setIsYearly] = useState(false);
return (
<div className="max-w-5xl mx-auto space-y-10 py-4">
{/* ── Başlık ── */}
<motion.div
variants={fadeUp}
initial="hidden"
animate="show"
className="text-center space-y-3"
>
<h1 className="font-[family-name:var(--font-display)] text-3xl md:text-4xl font-bold tracking-tight">
Planını Seç, Üretmeye Başla
</h1>
<p className="text-[var(--color-text-muted)] text-sm md:text-base max-w-md mx-auto">
Her plan ücretsiz deneme ile başlar. İstediğin zaman yükselt veya iptal et.
</p>
{/* Aylık / Yıllık Toggle */}
<div className="flex items-center justify-center gap-3 pt-2">
<span className={cn("text-sm", !isYearly ? "text-[var(--color-text-primary)]" : "text-[var(--color-text-muted)]")}>
Aylık
</span>
<button
onClick={() => setIsYearly(!isYearly)}
className={cn(
"relative w-14 h-7 rounded-full transition-colors",
isYearly ? "bg-violet-500" : "bg-[var(--color-bg-elevated)]"
)}
>
<motion.div
className="absolute top-0.5 w-6 h-6 rounded-full bg-white shadow-md"
animate={{ left: isYearly ? "calc(100% - 1.625rem)" : "0.125rem" }}
transition={{ type: "spring", stiffness: 500, damping: 30 }}
/>
</button>
<span className={cn("text-sm", isYearly ? "text-[var(--color-text-primary)]" : "text-[var(--color-text-muted)]")}>
Yıllık
</span>
{isYearly && (
<motion.span
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
className="badge badge-emerald text-[10px]"
>
%17 tasarruf
</motion.span>
)}
</div>
</motion.div>
{/* ── Plan Kartları ── */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-4 md:gap-5">
{plans.map((plan, i) => {
const Icon = plan.icon;
const price = isYearly ? plan.yearlyPrice : plan.monthlyPrice;
const period = isYearly ? "/yıl" : "/ay";
return (
<motion.div
key={plan.id}
initial={{ opacity: 0, y: 24 }}
animate={{ opacity: 1, y: 0 }}
transition={{ delay: i * 0.1, duration: 0.6, ease: [0.16, 1, 0.3, 1] }}
className={cn(
"relative card-surface p-6 flex flex-col bg-gradient-to-br",
plan.gradient,
plan.recommended && "glow-violet md:-translate-y-2"
)}
>
{plan.recommended && (
<div className="absolute -top-3 left-1/2 -translate-x-1/2">
<span className="badge bg-violet-500 text-white text-[10px] px-3 py-1 shadow-lg shadow-violet-500/30">
Önerilen
</span>
</div>
)}
{/* Header */}
<div className="flex items-center gap-3 mb-4">
<div className={cn(
"w-10 h-10 rounded-xl flex items-center justify-center",
plan.color === "violet" && "bg-violet-500/15 text-violet-400",
plan.color === "emerald" && "bg-emerald-500/15 text-emerald-400",
plan.color === "cyan" && "bg-cyan-500/15 text-cyan-400"
)}>
<Icon size={20} />
</div>
<div>
<h3 className="font-[family-name:var(--font-display)] text-lg font-bold">{plan.name}</h3>
<p className="text-[11px] text-[var(--color-text-muted)]">{plan.description}</p>
</div>
</div>
{/* Fiyat */}
<div className="mb-5">
<div className="flex items-baseline gap-1">
<span className="font-[family-name:var(--font-display)] text-4xl font-bold">
${price}
</span>
{price > 0 && (
<span className="text-sm text-[var(--color-text-muted)]">{period}</span>
)}
</div>
<p className="text-xs text-[var(--color-text-ghost)] mt-1">
{plan.credits === -1 ? "Sınırsız video üretimi" : `${plan.credits} kredi dahil`}
</p>
</div>
{/* Features */}
<ul className="space-y-2.5 flex-1 mb-6">
{plan.features.map((feat) => (
<li key={feat.label} className="flex items-center gap-2.5 text-sm">
{feat.included ? (
<Check size={14} className="text-emerald-400 shrink-0" />
) : (
<X size={14} className="text-[var(--color-text-ghost)] shrink-0" />
)}
<span className={cn(
feat.included ? "text-[var(--color-text-secondary)]" : "text-[var(--color-text-ghost)]"
)}>
{feat.label}
</span>
</li>
))}
</ul>
{/* CTA */}
<button className={cn("w-full py-3 rounded-xl font-semibold text-sm flex items-center justify-center gap-2", plan.buttonClass)}>
{plan.buttonLabel}
{price > 0 && <ArrowRight size={14} />}
</button>
</motion.div>
);
})}
</div>
{/* ── Trust ── */}
<motion.div
variants={fadeUp}
initial="hidden"
animate="show"
className="text-center space-y-2 pt-4"
>
<p className="text-xs text-[var(--color-text-ghost)]">
🔒 Güvenli ödeme İstediğin zaman iptal 7 gün para iade garantisi
</p>
<p className="text-[10px] text-[var(--color-text-ghost)]">
Stripe ile güvenli ödeme altyapısı
</p>
</motion.div>
</div>
);
}