import { Suspense } from "react"; import Image from "next/image"; import Link from "next/link"; import { ArrowRight, CheckCircle2, Coins, FileText, ListChecks, MessageCircleQuestion, RefreshCcw, ShieldCheck, } from "lucide-react"; import { getCurrentUser } from "@/lib/session"; import { URUNLER, DENEME_KREDISI, RAPOR_KREDI } from "@/lib/credits"; import { ACIK_SATIR } from "@/lib/rapor-maske"; import { VERI_YIL_SAYISI } from "@/lib/veri-kapsami"; import { Button } from "@/components/ui/button"; import { Parallax } from "@/components/parallax"; import { Skeleton } from "@/components/ui/skeleton"; import { SatinAlForm } from "./satin-al-form"; function tl(kurus: number) { return (kurus / 100).toLocaleString("tr-TR", { maximumFractionDigits: 0 }); } const OZELLIKLER = [ { icon: ListChecks, text: "Sıralamana özel, gerekçeli 24 tercihlik dengeli liste", }, { icon: ShieldCheck, text: `Her tercih için yerleşme riski ve trend analizi (son ${VERI_YIL_SAYISI} yıl)`, }, { icon: FileText, text: "Veliyle paylaşılabilir PDF rapor" }, { icon: RefreshCcw, text: "2 liste revizyon hakkı" }, { icon: MessageCircleQuestion, text: `${URUNLER.paket.credits} Yapay Zeka danışman sorusu (her mesaj 1 kredi)`, }, ] as const; // Paket + top-up kartları. Kartların gövdesi (başlık, fiyat, özellikler, // iyzico bandı) STATİK kabukta kalır; kullanıcıya bağlı olan yalnızca iki küçük // CTA alanıdır (PaketCta, TopupCta) ve her biri kendi Suspense sınırındadır. // // Neden bu kadar küçük parçalar: React Flight ~3,2 KB'ı aşan bir dinamik // parçanın devamını ayrı satırlara böler; PPR resume bunlara yeni segment // kimliği verirken kabukta geç tamamlanan sınırın (kök loading.tsx) kimliğiyle // çakışıyor (Next 16.2 / React 19.2) ve tarayıcıda HierarchyRequestError ile // sayfa boş kalıyordu. Dinamik parçayı bu sınırın altında tut: kartın gövdesini // yeniden bu async bileşenlerin içine TAŞIMA. export function PaketSatinAl() { return ( {/* Ana paket */}

Tercih Dönemi Paketi

{tl(URUNLER.paket.amountKurus)} TL

}>
iyzico ile Öde — Mastercard, Visa, American Express ve Troy ile güvenli ödeme

iyzico güvenli ödeme · Kart bilgilerin bize hiç ulaşmaz ·{" "} İade koşulları

{/* Top-up */}

Kredi bitti mi?

+{URUNLER.topup.credits} soru hakkı,{" "} {tl(URUNLER.topup.amountKurus)} TL.

}>
); } /** Ana paket kartının kullanıcıya bağlı CTA'sı — bilerek küçük (bkz. üstteki not). */ async function PaketCta() { const u = await getCurrentUser(); if (!u) { return (

Girişte {DENEME_KREDISI} deneme kredisi tanımlanır; liste{" "} {RAPOR_KREDI} kredi, ilk {ACIK_SATIR} satır açık. Paketi sonra alırsın.

); } if (u.hasPaket) { return (
Paketin aktif —{" "} {/* ?uret=1: rapor varsa /listem raporu gösterir (bayrak yok sayılır), yoksa bekleyen seçimlerle üretim başlar; seçim de yoksa boş durum sihirbaza yönlendirir. */} listeni oluştur
); } return ( ); } /** Top-up kartının kullanıcıya bağlı CTA'sı — bilerek küçük (bkz. üstteki not). */ async function TopupCta() { const u = await getCurrentUser(); // Top-up hasPaket vermez: paketsiz biri alırsa parasını verip yine maskeli // liste görür. Satın alma yalnızca paketliye açık; paketsize durum dürüstçe // açıklanır. if (u?.hasPaket) { return ( ); } if (u) { return (

Ek kredi, kilitli analizleri açmaz — o yüzden önce paket gerekir. Paket zaten {URUNLER.paket.credits} kredi içerir; bitince buradan yükleyebilirsin.

); } return ( ); }