Add Rybbit analytics script and enhance pricing section with new features
All checks were successful
Deploy / deploy (push) Successful in 14m22s
All checks were successful
Deploy / deploy (push) Successful in 14m22s
- Integrated Rybbit analytics script in layout.tsx for improved tracking. - Updated pricing section in page.tsx to include detailed package features and pricing information. - Refined button interactions and added icons for better user engagement. - Adjusted return URL handling in odeme/sonuc/page.tsx to preserve order information. - Enhanced satin-al-form.tsx to include visual indicators for payment redirection.
This commit is contained in:
@@ -1,4 +1,5 @@
|
||||
import type { Metadata, Viewport } from "next";
|
||||
import Script from "next/script";
|
||||
import { Cal_Sans, Geist_Mono, Bricolage_Grotesque } from "next/font/google";
|
||||
import localFont from "next/font/local";
|
||||
import { Toaster } from "@/components/ui/sonner";
|
||||
@@ -83,6 +84,12 @@ export default function RootLayout({
|
||||
// içerikle büyümeli, viewport tabanı body'deki min-h-dvh'den gelir.
|
||||
className={`${calSans.variable} ${clarityCity.variable} ${geistMono.variable} ${bricolage.variable} antialiased`}
|
||||
>
|
||||
{/* Rybbit analytics — beforeInteractive her zaman <head> içine defer olarak enjekte edilir */}
|
||||
<Script
|
||||
src="https://rybbit.kolaytercih.com/api/script.js"
|
||||
data-site-id="f2cb042c657e"
|
||||
strategy="beforeInteractive"
|
||||
/>
|
||||
<body className="min-h-dvh flex flex-col bg-slate-50">
|
||||
<HeaderGate>
|
||||
{/* Site geneli progressive blur — üst ve alt */}
|
||||
|
||||
@@ -21,7 +21,11 @@ export default async function OdemeSonucPage({
|
||||
searchParams: Promise<{ siparis?: string }>;
|
||||
}) {
|
||||
const { siparis } = await searchParams;
|
||||
const session = await verifySession("/paket");
|
||||
// Oturum düşmüşse geri dönüşte ?siparis= kaybolmasın (başarı/unblur deneyimi)
|
||||
const geriDonus = siparis
|
||||
? `/odeme/sonuc?siparis=${encodeURIComponent(siparis)}`
|
||||
: "/paket";
|
||||
const session = await verifySession(geriDonus);
|
||||
|
||||
const order = siparis
|
||||
? await appDb.query.orders.findFirst({
|
||||
|
||||
123
src/app/page.tsx
123
src/app/page.tsx
@@ -1,10 +1,14 @@
|
||||
import {
|
||||
ArrowRight,
|
||||
ArrowUpRight,
|
||||
BarChart3,
|
||||
CheckCircle2,
|
||||
Coins,
|
||||
Compass,
|
||||
FileText,
|
||||
ListChecks,
|
||||
MessageCircleQuestion,
|
||||
RefreshCcw,
|
||||
ShieldCheck,
|
||||
TrendingUp,
|
||||
Wallet,
|
||||
@@ -24,13 +28,14 @@ import {
|
||||
PixelField,
|
||||
SectionEyebrow,
|
||||
} from "@/components/pixel-decor";
|
||||
import { URUNLER } from "@/lib/credits";
|
||||
import { MAX_REVIZYON, URUNLER } from "@/lib/credits";
|
||||
import {
|
||||
Accordion,
|
||||
AccordionContent,
|
||||
AccordionItem,
|
||||
AccordionTrigger,
|
||||
} from "@/components/ui/accordion";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import {
|
||||
Card,
|
||||
CardDescription,
|
||||
@@ -160,10 +165,27 @@ const comparison = [
|
||||
feature: "Fiyat",
|
||||
robot: "Ücretsiz",
|
||||
danisman: "2.000–10.000 TL",
|
||||
tercihai: "İnsan danışmanın ~10'da 1'i",
|
||||
tercihai: `${PAKET_FIYATI} TL · tek seferlik`,
|
||||
},
|
||||
];
|
||||
|
||||
const paketOzellikleri = [
|
||||
{
|
||||
icon: ListChecks,
|
||||
text: "Sıralamana özel, gerekçeli 24 tercihlik dengeli liste",
|
||||
},
|
||||
{
|
||||
icon: ShieldCheck,
|
||||
text: "Her tercih için yerleşme olasılığı ve risk analizi (son 4 yıl)",
|
||||
},
|
||||
{ icon: FileText, text: "Veliyle paylaşılabilir PDF rapor" },
|
||||
{ icon: RefreshCcw, text: `${MAX_REVIZYON} liste revizyon hakkı` },
|
||||
{
|
||||
icon: MessageCircleQuestion,
|
||||
text: `${URUNLER.paket.credits} yapay zekâ danışman sorusu`,
|
||||
},
|
||||
] as const;
|
||||
|
||||
function ComparisonCell({ value }: { value: boolean | string }) {
|
||||
if (typeof value === "string") {
|
||||
return <span className="text-sm font-medium">{value}</span>;
|
||||
@@ -452,7 +474,102 @@ export default function Home() {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Karşılaştırma → SSS geçişi */}
|
||||
{/* Karşılaştırma → Fiyat geçişi */}
|
||||
<div aria-hidden className="mx-auto w-56">
|
||||
<Parallax strength={26}>
|
||||
<PixelDivider seed={29} />
|
||||
</Parallax>
|
||||
</div>
|
||||
|
||||
{/* Fiyat */}
|
||||
<section id="fiyat" className="scroll-mt-24 py-20 sm:py-24">
|
||||
<div className="mx-auto max-w-4xl px-4">
|
||||
<Parallax strength={16}>
|
||||
<Reveal className="flex flex-col items-center gap-4 text-center">
|
||||
<SectionEyebrow>Tek seferlik · Abonelik yok</SectionEyebrow>
|
||||
<h2 className="font-heading text-3xl font-bold sm:text-4xl">
|
||||
Ne kadar? Ne dahil?
|
||||
</h2>
|
||||
<p className="max-w-xl text-lg leading-relaxed text-slate-600">
|
||||
İnsan danışmanın 2.000–10.000 TL aldığı işi tek seferlik{" "}
|
||||
{PAKET_FIYATI} TL'ye alırsın. Abonelik yok, gizli ücret
|
||||
yok.
|
||||
</p>
|
||||
</Reveal>
|
||||
</Parallax>
|
||||
|
||||
<Parallax
|
||||
strength={7}
|
||||
className="mt-12 grid gap-6 sm:grid-cols-[1fr_auto]"
|
||||
>
|
||||
<Reveal
|
||||
delay={0.08}
|
||||
className="rounded-2xl border-2 border-orange-500 bg-white p-8 shadow-sm"
|
||||
>
|
||||
<div className="flex flex-wrap items-baseline justify-between gap-2">
|
||||
<h3 className="font-heading text-xl font-bold">
|
||||
{URUNLER.paket.label}
|
||||
</h3>
|
||||
<p className="font-heading text-3xl font-bold">
|
||||
{PAKET_FIYATI} TL
|
||||
</p>
|
||||
</div>
|
||||
<ul className="mt-6 space-y-3">
|
||||
{paketOzellikleri.map((o) => (
|
||||
<li
|
||||
key={o.text}
|
||||
className="flex items-start gap-3 text-sm text-slate-700"
|
||||
>
|
||||
<o.icon
|
||||
className="mt-0.5 size-4 shrink-0 text-emerald-600"
|
||||
aria-hidden
|
||||
/>
|
||||
{o.text}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<Button
|
||||
asChild
|
||||
className="mt-8 h-12 w-full cursor-pointer bg-orange-500 px-8 text-white transition-colors duration-200 hover:bg-orange-600"
|
||||
>
|
||||
<Link href="/paket">
|
||||
{PAKET_FIYATI} TL — Paketi incele
|
||||
<ArrowRight className="size-4" aria-hidden />
|
||||
</Link>
|
||||
</Button>
|
||||
<p className="mt-4 text-center text-xs text-slate-500">
|
||||
Temel program arama herkes için ücretsiz · iyzico güvenli ödeme
|
||||
</p>
|
||||
</Reveal>
|
||||
|
||||
<Reveal
|
||||
delay={0.16}
|
||||
className="flex h-fit flex-col rounded-2xl border border-slate-200/70 bg-white p-6 shadow-sm sm:w-56"
|
||||
>
|
||||
<div className="flex items-center gap-2">
|
||||
<Coins className="size-4 text-amber-500" aria-hidden />
|
||||
<h3 className="font-heading font-bold">Kredi bitti mi?</h3>
|
||||
</div>
|
||||
<p className="mt-2 flex-1 text-sm leading-relaxed text-slate-600">
|
||||
+{URUNLER.topup.credits} soru hakkı, {TOPUP_FIYATI} TL. Pakete
|
||||
ek olarak, istediğin zaman.
|
||||
</p>
|
||||
<Button
|
||||
asChild
|
||||
variant="outline"
|
||||
className="mt-4 h-11 w-full cursor-pointer"
|
||||
>
|
||||
<Link href="/paket">
|
||||
+{URUNLER.topup.credits} kredi — {TOPUP_FIYATI} TL
|
||||
<ArrowRight className="size-4" aria-hidden />
|
||||
</Link>
|
||||
</Button>
|
||||
</Reveal>
|
||||
</Parallax>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Fiyat → SSS geçişi */}
|
||||
<div aria-hidden className="mx-auto w-56">
|
||||
<Parallax strength={26}>
|
||||
<PixelDivider seed={31} />
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
import Link from "next/link";
|
||||
import type { Metadata } from "next";
|
||||
import {
|
||||
ArrowRight,
|
||||
CheckCircle2,
|
||||
Coins,
|
||||
FileText,
|
||||
@@ -122,6 +123,7 @@ export default async function PaketPage({
|
||||
/>
|
||||
)
|
||||
) : (
|
||||
<div className="space-y-2">
|
||||
<Button
|
||||
asChild
|
||||
className="h-12 w-full cursor-pointer bg-orange-500 px-8 text-white transition-colors duration-200 hover:bg-orange-600"
|
||||
@@ -129,9 +131,15 @@ export default async function PaketPage({
|
||||
<Link
|
||||
href={`/giris?callback=${encodeURIComponent("/paket")}`}
|
||||
>
|
||||
Giriş yap ve {DENEME_KREDISI} deneme kredisi kazan
|
||||
Giriş yap — sonra {tl(URUNLER.paket.amountKurus)} TL'ye
|
||||
al
|
||||
<ArrowRight className="size-4" aria-hidden />
|
||||
</Link>
|
||||
</Button>
|
||||
<p className="text-center text-xs text-slate-500">
|
||||
Girişte {DENEME_KREDISI} deneme kredisi de tanımlanır.
|
||||
</p>
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
<p className="mt-4 text-center text-xs text-slate-500">
|
||||
@@ -159,7 +167,7 @@ export default async function PaketPage({
|
||||
{u ? (
|
||||
<SatinAlForm
|
||||
urun="topup"
|
||||
label={`+${URUNLER.topup.credits} kredi al`}
|
||||
label={`+${URUNLER.topup.credits} kredi — ${tl(URUNLER.topup.amountKurus)} TL`}
|
||||
/>
|
||||
) : (
|
||||
<Button
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useActionState, useEffect } from "react";
|
||||
import { ArrowRight } from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { baslatOdeme, type OdemeBaslatDurum } from "./actions";
|
||||
@@ -36,7 +37,14 @@ export function SatinAlForm({
|
||||
}
|
||||
variant={vurgulu ? "default" : "outline"}
|
||||
>
|
||||
{pending ? "Ödeme sayfasına yönlendiriliyorsun…" : label}
|
||||
{pending ? (
|
||||
"Ödeme sayfasına yönlendiriliyorsun…"
|
||||
) : (
|
||||
<>
|
||||
{label}
|
||||
<ArrowRight className="size-4" aria-hidden />
|
||||
</>
|
||||
)}
|
||||
</Button>
|
||||
</form>
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user