Refactor code structure for improved readability and maintainability
All checks were successful
Deploy / deploy (push) Successful in 10m26s
All checks were successful
Deploy / deploy (push) Successful in 10m26s
This commit is contained in:
@@ -1,7 +1,7 @@
|
||||
"use client";
|
||||
|
||||
import { useState } from "react";
|
||||
import { Loader2, Mail } from "lucide-react";
|
||||
import { Mail } from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
import { authClient } from "@/lib/auth-client";
|
||||
import { Button } from "@/components/ui/button";
|
||||
@@ -126,12 +126,8 @@ export function GirisForm({ callbackURL }: { callbackURL: string }) {
|
||||
onClick={googleIleGiris}
|
||||
disabled={busy !== null}
|
||||
>
|
||||
{busy === "google" ? (
|
||||
<Loader2 className="size-4 animate-spin" aria-hidden />
|
||||
) : (
|
||||
<GoogleIcon />
|
||||
)}
|
||||
Google ile devam et
|
||||
<GoogleIcon />
|
||||
{busy === "google" ? "Yönlendiriliyorsun…" : "Google ile devam et"}
|
||||
</Button>
|
||||
|
||||
<div className="flex items-center gap-3 text-xs text-slate-400">
|
||||
@@ -156,12 +152,8 @@ export function GirisForm({ callbackURL }: { callbackURL: string }) {
|
||||
className="h-11 w-full cursor-pointer bg-orange-500 text-white transition-colors duration-200 hover:bg-orange-600"
|
||||
disabled={busy !== null}
|
||||
>
|
||||
{busy === "email" ? (
|
||||
<Loader2 className="size-4 animate-spin" aria-hidden />
|
||||
) : (
|
||||
<Mail className="size-4" aria-hidden />
|
||||
)}
|
||||
Giriş bağlantısı gönder
|
||||
<Mail className="size-4" aria-hidden />
|
||||
{busy === "email" ? "Gönderiliyor…" : "Giriş bağlantısı gönder"}
|
||||
</Button>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import type { Metadata } from "next";
|
||||
import Link from "next/link";
|
||||
import { Parallax } from "@/components/parallax";
|
||||
import { ScrollFlow } from "@/components/scroll-flow";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Gizlilik ve KVKK — KolayTercih",
|
||||
@@ -8,59 +10,70 @@ export const metadata: Metadata = {
|
||||
// NOT: MVP taslağıdır; yayına almadan önce hukuki gözden geçirme gerekir.
|
||||
export default function GizlilikPage() {
|
||||
return (
|
||||
<main className="mx-auto w-full max-w-2xl px-4 py-16">
|
||||
<h1 className="font-heading text-3xl font-bold">
|
||||
Gizlilik ve Kişisel Verilerin Korunması
|
||||
</h1>
|
||||
<p className="mt-2 text-sm text-slate-500">Son güncelleme: 26 Temmuz 2026</p>
|
||||
<ScrollFlow>
|
||||
<main className="mx-auto w-full max-w-2xl px-4 py-16">
|
||||
<Parallax fromStart strength={10}>
|
||||
<h1 className="font-heading text-3xl font-bold">
|
||||
Gizlilik ve Kişisel Verilerin Korunması
|
||||
</h1>
|
||||
<p className="mt-2 text-sm text-slate-500">
|
||||
Son güncelleme: 26 Temmuz 2026
|
||||
</p>
|
||||
</Parallax>
|
||||
|
||||
<div className="mt-8 space-y-6 text-sm leading-7 text-slate-700">
|
||||
<section>
|
||||
<h2 className="font-heading text-lg font-bold text-slate-900">
|
||||
Hangi verileri işliyoruz?
|
||||
</h2>
|
||||
<p className="mt-2">
|
||||
KolayTercih; e-posta adresini (hesap oluşturma ve giriş için), YKS
|
||||
başarı sıralamanı ve sihirbazda yaptığın seçimleri (tercih listeni
|
||||
üretmek için), danışman sohbetine yazdığın mesajları (sorularını
|
||||
yanıtlamak için) ve ödeme yaptığında sipariş kayıtlarını işler.
|
||||
Kart bilgilerin bize hiç ulaşmaz; ödeme iyzico altyapısında
|
||||
gerçekleşir.
|
||||
</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2 className="font-heading text-lg font-bold text-slate-900">
|
||||
Ne için kullanıyoruz?
|
||||
</h2>
|
||||
<p className="mt-2">
|
||||
Verilerin yalnızca tercih önerileri üretmek, hesabını ve kredi
|
||||
bakiyeni yönetmek ve sana hizmetle ilgili e-posta (giriş bağlantısı,
|
||||
ödeme bilgilendirmesi) göndermek için kullanılır. Verilerini
|
||||
üçüncü taraflara satmayız, reklam amacıyla paylaşmayız.
|
||||
</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2 className="font-heading text-lg font-bold text-slate-900">
|
||||
Saklama ve silme
|
||||
</h2>
|
||||
<p className="mt-2">
|
||||
Hesabını sildirmek veya verilerinin bir kopyasını istemek için{" "}
|
||||
<Link href="/iletisim" className="text-primary underline">
|
||||
iletişim sayfasındaki
|
||||
</Link>{" "}
|
||||
adresten bize yazabilirsin; talepler 30 gün içinde sonuçlandırılır.
|
||||
</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2 className="font-heading text-lg font-bold text-slate-900">
|
||||
Çerezler
|
||||
</h2>
|
||||
<p className="mt-2">
|
||||
Yalnızca oturumunu açık tutmak için zorunlu çerezler kullanılır;
|
||||
reklam veya izleme çerezi kullanılmaz.
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
<Parallax
|
||||
fromStart
|
||||
strength={4}
|
||||
className="mt-8 space-y-6 text-sm leading-7 text-slate-700"
|
||||
>
|
||||
<section>
|
||||
<h2 className="font-heading text-lg font-bold text-slate-900">
|
||||
Hangi verileri işliyoruz?
|
||||
</h2>
|
||||
<p className="mt-2">
|
||||
KolayTercih; e-posta adresini (hesap oluşturma ve giriş için), YKS
|
||||
başarı sıralamanı ve sihirbazda yaptığın seçimleri (tercih listeni
|
||||
üretmek için), danışman sohbetine yazdığın mesajları (sorularını
|
||||
yanıtlamak için) ve ödeme yaptığında sipariş kayıtlarını işler.
|
||||
Kart bilgilerin bize hiç ulaşmaz; ödeme iyzico altyapısında
|
||||
gerçekleşir.
|
||||
</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2 className="font-heading text-lg font-bold text-slate-900">
|
||||
Ne için kullanıyoruz?
|
||||
</h2>
|
||||
<p className="mt-2">
|
||||
Verilerin yalnızca tercih önerileri üretmek, hesabını ve kredi
|
||||
bakiyeni yönetmek ve sana hizmetle ilgili e-posta (giriş
|
||||
bağlantısı, ödeme bilgilendirmesi) göndermek için kullanılır.
|
||||
Verilerini üçüncü taraflara satmayız, reklam amacıyla paylaşmayız.
|
||||
</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2 className="font-heading text-lg font-bold text-slate-900">
|
||||
Saklama ve silme
|
||||
</h2>
|
||||
<p className="mt-2">
|
||||
Hesabını sildirmek veya verilerinin bir kopyasını istemek için{" "}
|
||||
<Link href="/iletisim" className="text-primary underline">
|
||||
iletişim sayfasındaki
|
||||
</Link>{" "}
|
||||
adresten bize yazabilirsin; talepler 30 gün içinde
|
||||
sonuçlandırılır.
|
||||
</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2 className="font-heading text-lg font-bold text-slate-900">
|
||||
Çerezler
|
||||
</h2>
|
||||
<p className="mt-2">
|
||||
Yalnızca oturumunu açık tutmak için zorunlu çerezler kullanılır;
|
||||
reklam veya izleme çerezi kullanılmaz.
|
||||
</p>
|
||||
</section>
|
||||
</Parallax>
|
||||
</main>
|
||||
</ScrollFlow>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -7,9 +7,10 @@
|
||||
@theme inline {
|
||||
--color-background: var(--background);
|
||||
--color-foreground: var(--foreground);
|
||||
--font-sans: var(--font-work-sans);
|
||||
--font-sans: var(--font-clarity-city);
|
||||
--font-mono: var(--font-geist-mono);
|
||||
--font-heading: var(--font-outfit);
|
||||
--font-heading: var(--font-cal-sans);
|
||||
--font-bricolage: var(--font-bricolage-grotesque);
|
||||
--color-sidebar-ring: var(--sidebar-ring);
|
||||
--color-sidebar-border: var(--sidebar-border);
|
||||
--color-sidebar-accent-foreground: var(--sidebar-accent-foreground);
|
||||
@@ -168,7 +169,22 @@
|
||||
body {
|
||||
@apply bg-background text-foreground;
|
||||
}
|
||||
/* Chrome autofill'in soluk mavi dolgusu inputun kendi arka planını
|
||||
ezmesin; dolgu metne kırpılır, renkler temadan gelir. */
|
||||
input:-webkit-autofill,
|
||||
input:-webkit-autofill:hover,
|
||||
input:-webkit-autofill:focus {
|
||||
-webkit-background-clip: text;
|
||||
-webkit-text-fill-color: var(--foreground);
|
||||
caret-color: var(--foreground);
|
||||
}
|
||||
html {
|
||||
@apply font-sans;
|
||||
scroll-behavior: smooth;
|
||||
}
|
||||
@media (prefers-reduced-motion: reduce) {
|
||||
html {
|
||||
scroll-behavior: auto;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,7 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Mail } from "lucide-react";
|
||||
import { Parallax } from "@/components/parallax";
|
||||
import { ScrollFlow } from "@/components/scroll-flow";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "İletişim — KolayTercih",
|
||||
@@ -7,24 +9,28 @@ export const metadata: Metadata = {
|
||||
|
||||
export default function IletisimPage() {
|
||||
return (
|
||||
<main className="mx-auto w-full max-w-2xl px-4 py-16">
|
||||
<h1 className="font-heading text-3xl font-bold">İletişim</h1>
|
||||
<p className="mt-4 text-sm leading-7 text-slate-700">
|
||||
Ödeme, iade, hesap silme ya da başka bir konuda yardıma mı ihtiyacın
|
||||
var? Tercih döneminde mesajlara aynı gün dönmeye çalışıyoruz.
|
||||
</p>
|
||||
<a
|
||||
href="mailto:destek@kolaytercih.com"
|
||||
className="mt-6 inline-flex items-center gap-2 rounded-xl border border-slate-200 bg-white px-4 py-3 text-sm font-semibold text-slate-900 shadow-xs transition-colors hover:border-slate-300 hover:bg-slate-50"
|
||||
>
|
||||
<Mail className="size-4 text-primary" aria-hidden />
|
||||
destek@kolaytercih.com
|
||||
</a>
|
||||
<p className="mt-6 text-xs text-slate-500">
|
||||
Ödemenle ilgili yazıyorsan e-postana sipariş tarihini ve kullandığın
|
||||
hesap adresini eklersen daha hızlı yardımcı olabiliriz. Kart bilgini
|
||||
asla e-postayla paylaşma.
|
||||
</p>
|
||||
</main>
|
||||
<ScrollFlow>
|
||||
<main className="mx-auto w-full max-w-2xl px-4 py-16">
|
||||
<Parallax fromStart strength={10}>
|
||||
<h1 className="font-heading text-3xl font-bold">İletişim</h1>
|
||||
</Parallax>
|
||||
<p className="mt-4 text-sm leading-7 text-slate-700">
|
||||
Ödeme, iade, hesap silme ya da başka bir konuda yardıma mı ihtiyacın
|
||||
var? Tercih döneminde mesajlara aynı gün dönmeye çalışıyoruz.
|
||||
</p>
|
||||
<a
|
||||
href="mailto:destek@kolaytercih.com"
|
||||
className="mt-6 inline-flex items-center gap-2 rounded-xl border border-slate-200 bg-white px-4 py-3 text-sm font-semibold text-slate-900 shadow-xs transition-colors hover:border-slate-300 hover:bg-slate-50"
|
||||
>
|
||||
<Mail className="size-4 text-primary" aria-hidden />
|
||||
destek@kolaytercih.com
|
||||
</a>
|
||||
<p className="mt-6 text-xs text-slate-500">
|
||||
Ödemenle ilgili yazıyorsan e-postana sipariş tarihini ve kullandığın
|
||||
hesap adresini eklersen daha hızlı yardımcı olabiliriz. Kart bilgini
|
||||
asla e-postayla paylaşma.
|
||||
</p>
|
||||
</main>
|
||||
</ScrollFlow>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
import type { Metadata } from "next";
|
||||
import Link from "next/link";
|
||||
import { Parallax } from "@/components/parallax";
|
||||
import { ScrollFlow } from "@/components/scroll-flow";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "Kullanım ve Satış Koşulları — KolayTercih",
|
||||
@@ -8,67 +10,77 @@ export const metadata: Metadata = {
|
||||
// NOT: MVP taslağıdır; yayına almadan önce hukuki gözden geçirme gerekir.
|
||||
export default function KosullarPage() {
|
||||
return (
|
||||
<main className="mx-auto w-full max-w-2xl px-4 py-16">
|
||||
<h1 className="font-heading text-3xl font-bold">
|
||||
Kullanım ve Satış Koşulları
|
||||
</h1>
|
||||
<p className="mt-2 text-sm text-slate-500">Son güncelleme: 26 Temmuz 2026</p>
|
||||
<ScrollFlow>
|
||||
<main className="mx-auto w-full max-w-2xl px-4 py-16">
|
||||
<Parallax fromStart strength={10}>
|
||||
<h1 className="font-heading text-3xl font-bold">
|
||||
Kullanım ve Satış Koşulları
|
||||
</h1>
|
||||
<p className="mt-2 text-sm text-slate-500">
|
||||
Son güncelleme: 26 Temmuz 2026
|
||||
</p>
|
||||
</Parallax>
|
||||
|
||||
<div className="mt-8 space-y-6 text-sm leading-7 text-slate-700">
|
||||
<section>
|
||||
<h2 className="font-heading text-lg font-bold text-slate-900">
|
||||
Hizmetin kapsamı
|
||||
</h2>
|
||||
<p className="mt-2">
|
||||
KolayTercih, resmî YÖK Atlas verilerine dayanan bir karar destek
|
||||
aracıdır. Öneriler bilgilendirme amaçlıdır; KolayTercih yerleşme
|
||||
garantisi vermez ve ÖSYM ya da YÖK ile bağlantılı değildir. Tercih
|
||||
listenin son hali ve başvuru sorumluluğu sana aittir.
|
||||
</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2 className="font-heading text-lg font-bold text-slate-900">
|
||||
Ücretlendirme
|
||||
</h2>
|
||||
<p className="mt-2">
|
||||
Temel program arama ücretsizdir. Tercih Dönemi Paketi tek seferlik
|
||||
bir satın almadır; abonelik değildir, otomatik yenilenmez. Paket
|
||||
içeriği ve güncel fiyat{" "}
|
||||
<Link href="/paket" className="text-primary underline">
|
||||
paket sayfasında
|
||||
</Link>{" "}
|
||||
yazar.
|
||||
</p>
|
||||
</section>
|
||||
<section id="iade" className="scroll-mt-24">
|
||||
<h2 className="font-heading text-lg font-bold text-slate-900">
|
||||
İade ve cayma
|
||||
</h2>
|
||||
<p className="mt-2">
|
||||
Paket, satın alır almaz ifasına başlanan dijital bir içeriktir.
|
||||
Buna rağmen kişisel listen henüz üretilmemişse (paket hiç
|
||||
kullanılmamışsa) satın almadan itibaren 14 gün içinde koşulsuz
|
||||
iade talep edebilirsin. Teknik bir sorun nedeniyle hizmeti
|
||||
alamadıysan, kullanımdan bağımsız olarak ücretin iade edilir.
|
||||
İade talepleri için{" "}
|
||||
<Link href="/iletisim" className="text-primary underline">
|
||||
bize yaz
|
||||
</Link>
|
||||
; talepler 14 gün içinde sonuçlandırılır ve iade, ödeme yaptığın
|
||||
karta yapılır.
|
||||
</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2 className="font-heading text-lg font-bold text-slate-900">
|
||||
Hesap ve adil kullanım
|
||||
</h2>
|
||||
<p className="mt-2">
|
||||
Krediler hesabına tanımlıdır, kişiseldir ve üçüncü kişilere
|
||||
devredilemez. Hizmeti kötüye kullanan (otomatik istek, içerik
|
||||
kazıma vb.) hesaplar kapatılabilir.
|
||||
</p>
|
||||
</section>
|
||||
</div>
|
||||
</main>
|
||||
<Parallax
|
||||
fromStart
|
||||
strength={4}
|
||||
className="mt-8 space-y-6 text-sm leading-7 text-slate-700"
|
||||
>
|
||||
<section>
|
||||
<h2 className="font-heading text-lg font-bold text-slate-900">
|
||||
Hizmetin kapsamı
|
||||
</h2>
|
||||
<p className="mt-2">
|
||||
KolayTercih, resmî YÖK Atlas verilerine dayanan bir karar destek
|
||||
aracıdır. Öneriler bilgilendirme amaçlıdır; KolayTercih yerleşme
|
||||
garantisi vermez ve ÖSYM ya da YÖK ile bağlantılı değildir. Tercih
|
||||
listenin son hali ve başvuru sorumluluğu sana aittir.
|
||||
</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2 className="font-heading text-lg font-bold text-slate-900">
|
||||
Ücretlendirme
|
||||
</h2>
|
||||
<p className="mt-2">
|
||||
Temel program arama ücretsizdir. Tercih Dönemi Paketi tek seferlik
|
||||
bir satın almadır; abonelik değildir, otomatik yenilenmez. Paket
|
||||
içeriği ve güncel fiyat{" "}
|
||||
<Link href="/paket" className="text-primary underline">
|
||||
paket sayfasında
|
||||
</Link>{" "}
|
||||
yazar.
|
||||
</p>
|
||||
</section>
|
||||
<section id="iade" className="scroll-mt-24">
|
||||
<h2 className="font-heading text-lg font-bold text-slate-900">
|
||||
İade ve cayma
|
||||
</h2>
|
||||
<p className="mt-2">
|
||||
Paket, satın alır almaz ifasına başlanan dijital bir içeriktir.
|
||||
Buna rağmen kişisel listen henüz üretilmemişse (paket hiç
|
||||
kullanılmamışsa) satın almadan itibaren 14 gün içinde koşulsuz
|
||||
iade talep edebilirsin. Teknik bir sorun nedeniyle hizmeti
|
||||
alamadıysan, kullanımdan bağımsız olarak ücretin iade edilir. İade
|
||||
talepleri için{" "}
|
||||
<Link href="/iletisim" className="text-primary underline">
|
||||
bize yaz
|
||||
</Link>
|
||||
; talepler 14 gün içinde sonuçlandırılır ve iade, ödeme yaptığın
|
||||
karta yapılır.
|
||||
</p>
|
||||
</section>
|
||||
<section>
|
||||
<h2 className="font-heading text-lg font-bold text-slate-900">
|
||||
Hesap ve adil kullanım
|
||||
</h2>
|
||||
<p className="mt-2">
|
||||
Krediler hesabına tanımlıdır, kişiseldir ve üçüncü kişilere
|
||||
devredilemez. Hizmeti kötüye kullanan (otomatik istek, içerik
|
||||
kazıma vb.) hesaplar kapatılabilir.
|
||||
</p>
|
||||
</section>
|
||||
</Parallax>
|
||||
</main>
|
||||
</ScrollFlow>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { Metadata } from "next";
|
||||
import { Outfit, Work_Sans, Geist_Mono } from "next/font/google";
|
||||
import { Cal_Sans, Geist_Mono, Bricolage_Grotesque } from "next/font/google";
|
||||
import localFont from "next/font/local";
|
||||
import { Toaster } from "@/components/ui/sonner";
|
||||
import { SiteHeader } from "@/components/site-header";
|
||||
import { ListeCekmecesi } from "@/components/manuel-liste/liste-cekmecesi";
|
||||
@@ -8,14 +9,21 @@ import { ProgressiveBlur } from "@/components/ui/skiper-ui/skiper41";
|
||||
import { DevPanel } from "@/components/dev/dev-panel";
|
||||
import "./globals.css";
|
||||
|
||||
const outfit = Outfit({
|
||||
variable: "--font-outfit",
|
||||
const calSans = Cal_Sans({
|
||||
variable: "--font-cal-sans",
|
||||
weight: "400",
|
||||
subsets: ["latin", "latin-ext"],
|
||||
});
|
||||
|
||||
const workSans = Work_Sans({
|
||||
variable: "--font-work-sans",
|
||||
subsets: ["latin", "latin-ext"],
|
||||
const clarityCity = localFont({
|
||||
variable: "--font-clarity-city",
|
||||
src: [
|
||||
{ path: "../fonts/ClarityCity-Regular.woff2", weight: "400" },
|
||||
{ path: "../fonts/ClarityCity-Medium.woff2", weight: "500" },
|
||||
{ path: "../fonts/ClarityCity-SemiBold.woff2", weight: "600" },
|
||||
{ path: "../fonts/ClarityCity-Bold.woff2", weight: "700" },
|
||||
{ path: "../fonts/ClarityCity-ExtraBold.woff2", weight: "800" },
|
||||
],
|
||||
});
|
||||
|
||||
const geistMono = Geist_Mono({
|
||||
@@ -23,6 +31,12 @@ const geistMono = Geist_Mono({
|
||||
subsets: ["latin"],
|
||||
});
|
||||
|
||||
const bricolage = Bricolage_Grotesque({
|
||||
variable: "--font-bricolage-grotesque",
|
||||
subsets: ["latin", "latin-ext"],
|
||||
axes: ["opsz"],
|
||||
});
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: "KolayTercih — Tercih Danışmanı",
|
||||
description:
|
||||
@@ -37,7 +51,7 @@ export default function RootLayout({
|
||||
return (
|
||||
<html
|
||||
lang="tr"
|
||||
className={`${outfit.variable} ${workSans.variable} ${geistMono.variable} h-full antialiased`}
|
||||
className={`${calSans.variable} ${clarityCity.variable} ${geistMono.variable} ${bricolage.variable} h-full antialiased`}
|
||||
>
|
||||
<body className="min-h-full flex flex-col bg-slate-50">
|
||||
{/* Site geneli progressive blur — üst ve alt */}
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
import { useState } from "react";
|
||||
import { useRouter } from "next/navigation";
|
||||
import { Loader2, RefreshCcw } from "lucide-react";
|
||||
import { RefreshCcw } from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { listeRevize } from "@/app/sonuc/actions";
|
||||
@@ -80,11 +80,7 @@ export function RevizyonKutusu({ kalanHak }: { kalanHak: number }) {
|
||||
onClick={revizeEt}
|
||||
className="cursor-pointer"
|
||||
>
|
||||
{pending ? (
|
||||
<Loader2 className="size-4 animate-spin" aria-hidden />
|
||||
) : (
|
||||
<RefreshCcw className="size-4" aria-hidden />
|
||||
)}
|
||||
<RefreshCcw className="size-4" aria-hidden />
|
||||
{pending ? "Yeniden kuruluyor…" : "Revize et (3 kredi)"}
|
||||
</Button>
|
||||
<span className="text-xs text-slate-500">
|
||||
|
||||
@@ -21,6 +21,7 @@ import {
|
||||
import { PromptSuggestion } from "@/components/ui/prompt-suggestion";
|
||||
import { ScrollButton } from "@/components/ui/scroll-button";
|
||||
import { DotsLoader } from "@/components/ui/loader";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
|
||||
interface Mesaj {
|
||||
id: string;
|
||||
@@ -174,7 +175,15 @@ export function SohbetClient({
|
||||
))}
|
||||
</div>
|
||||
) : (
|
||||
<DotsLoader />
|
||||
<div className="flex max-w-lg flex-wrap justify-center gap-2">
|
||||
{[112, 148, 96, 132].map((w, i) => (
|
||||
<Skeleton
|
||||
key={i}
|
||||
className="h-7 rounded-full"
|
||||
style={{ width: w }}
|
||||
/>
|
||||
))}
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
) : (
|
||||
@@ -195,8 +204,10 @@ export function SohbetClient({
|
||||
{m.content}
|
||||
</MessageContent>
|
||||
) : (
|
||||
<div className="rounded-lg bg-slate-100 px-4 py-3">
|
||||
<DotsLoader size="sm" />
|
||||
<div className="w-full max-w-[85%] space-y-2 rounded-lg bg-slate-100 px-4 py-3">
|
||||
<Skeleton className="h-3.5 w-full bg-slate-200" />
|
||||
<Skeleton className="h-3.5 w-4/5 bg-slate-200" />
|
||||
<Skeleton className="h-3.5 w-3/5 bg-slate-200" />
|
||||
</div>
|
||||
)}
|
||||
</Message>
|
||||
|
||||
@@ -1,13 +1,30 @@
|
||||
import { Loader2 } from "lucide-react";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
|
||||
// Kendi loading dosyası olmayan tüm rotalar için genel sayfa iskeleti:
|
||||
// spinner yerine başlık, metin ve kart bloklarının yer tutucuları —
|
||||
// içerik gelince zıplama olmaz.
|
||||
export default function Loading() {
|
||||
return (
|
||||
<main
|
||||
aria-live="polite"
|
||||
className="flex min-h-[60vh] flex-col items-center justify-center gap-3"
|
||||
>
|
||||
<Loader2 className="size-8 animate-spin text-primary" aria-hidden />
|
||||
<p className="text-sm text-slate-500">Yükleniyor…</p>
|
||||
<main aria-live="polite" className="mx-auto w-full max-w-6xl px-4 py-12">
|
||||
{/* Rozet + başlık + alt metin */}
|
||||
<Skeleton className="h-6 w-44 rounded-full" />
|
||||
<Skeleton className="mt-5 h-10 w-3/4 max-w-2xl" />
|
||||
<Skeleton className="mt-3 h-10 w-1/2 max-w-md" />
|
||||
<Skeleton className="mt-5 h-5 w-2/3 max-w-lg" />
|
||||
<Skeleton className="mt-2 h-5 w-1/2 max-w-sm" />
|
||||
|
||||
{/* Form / aksiyon şeridi */}
|
||||
<div className="mt-8 flex max-w-xl flex-col gap-3 sm:flex-row">
|
||||
<Skeleton className="h-12 flex-1 rounded-lg" />
|
||||
<Skeleton className="h-12 w-full rounded-lg sm:w-44" />
|
||||
</div>
|
||||
|
||||
{/* Kart bloklar */}
|
||||
<div className="mt-14 grid gap-4 sm:grid-cols-2 lg:grid-cols-3">
|
||||
{Array.from({ length: 3 }).map((_, i) => (
|
||||
<Skeleton key={i} className="h-40 w-full rounded-2xl" />
|
||||
))}
|
||||
</div>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
645
src/app/page.tsx
645
src/app/page.tsx
@@ -12,6 +12,16 @@ import {
|
||||
import Image from "next/image";
|
||||
import Link from "next/link";
|
||||
import { HeroForm } from "@/components/hero-form";
|
||||
import { Parallax } from "@/components/parallax";
|
||||
import { ScrollFlow } from "@/components/scroll-flow";
|
||||
import { Reveal } from "@/components/landing/reveal";
|
||||
import { TurkeyPixelMap } from "@/components/turkey-pixel-map";
|
||||
import {
|
||||
PixelCorner,
|
||||
PixelDivider,
|
||||
PixelField,
|
||||
SectionEyebrow,
|
||||
} from "@/components/pixel-decor";
|
||||
import { URUNLER } from "@/lib/credits";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Button } from "@/components/ui/button";
|
||||
@@ -156,261 +166,412 @@ function ComparisonCell({ value }: { value: boolean | string }) {
|
||||
|
||||
export default function Home() {
|
||||
return (
|
||||
<div className="flex min-h-screen flex-col bg-slate-50 text-slate-900">
|
||||
<main className="flex-1">
|
||||
{/* Hero */}
|
||||
<section className="mx-auto flex max-w-6xl flex-col items-center px-4 pb-20 pt-16 text-center sm:pt-24">
|
||||
<Badge
|
||||
variant="secondary"
|
||||
className="mb-6 bg-primary/10 text-primary"
|
||||
>
|
||||
2026 YKS tercih dönemi açık
|
||||
</Badge>
|
||||
<h1 className="max-w-3xl font-heading text-4xl font-bold tracking-tight sm:text-6xl">
|
||||
Dört yıllık geleceğini{" "}
|
||||
<span className="text-primary">48 saatlik panikle</span> seçme
|
||||
</h1>
|
||||
<p className="mt-6 max-w-2xl text-lg leading-relaxed text-slate-600">
|
||||
<div className="bg-slate-50 text-slate-900">
|
||||
<ScrollFlow className="flex min-h-screen flex-col">
|
||||
<main className="flex-1">
|
||||
{/* Hero */}
|
||||
<section className="relative isolate overflow-hidden">
|
||||
<div
|
||||
aria-hidden
|
||||
// SVG altta 9 hücrelik serpinti payı taşıdığı için silüet merkezi
|
||||
// yüksekliğin %37,1'inde; -1/2 yerine bu oranla hizalanır
|
||||
className="pointer-events-none absolute left-1/2 top-[43%] -z-10 hidden -translate-x-1/2 -translate-y-[37.14%] sm:block"
|
||||
>
|
||||
{/* Arka katman: harita scroll'un gerisinde kalır, derinlik verir */}
|
||||
<Parallax fromStart strength={-52}>
|
||||
{/* Harita hiçbir boyutta taşmaz: her zaman ekran genişliği
|
||||
eksi kenar payı kadar; sayfa küçüldükçe onunla birlikte
|
||||
küçülür. Çok geniş ekranda 1665px tavanına oturur;
|
||||
mobilde tümüyle gizli. */}
|
||||
<TurkeyPixelMap className="w-[min(1665px,100vw_-_2.5rem)] max-w-none text-primary" />
|
||||
</Parallax>
|
||||
</div>
|
||||
<div
|
||||
aria-hidden
|
||||
className="pointer-events-none absolute inset-0 -z-10 bg-[radial-gradient(ellipse_58%_52%_at_50%_42%,rgba(248,250,252,0.9)_25%,rgba(248,250,252,0)_75%)]"
|
||||
/>
|
||||
<Parallax
|
||||
fromStart
|
||||
strength={14}
|
||||
className="mx-auto flex min-h-[calc(100svh-5.5rem)] max-w-6xl flex-col items-center justify-center px-4 pb-44 pt-4 text-center"
|
||||
>
|
||||
<Badge
|
||||
variant="secondary"
|
||||
className="mb-6 bg-primary/10 text-primary"
|
||||
>
|
||||
2026 YKS tercih dönemi açık
|
||||
</Badge>
|
||||
<h1 className="max-w-3xl font-heading text-4xl font-bold tracking-[0.015em] sm:text-6xl">
|
||||
Dört yıllık geleceğini <br className="hidden sm:block" />
|
||||
<span className="font-bricolage italic tracking-tighter font-bold text-primary">
|
||||
48 saatlik panikle
|
||||
</span>{" "}
|
||||
seçme
|
||||
</h1>
|
||||
{/* <p className="mt-6 max-w-2xl text-lg leading-relaxed text-slate-600">
|
||||
KolayTercih, gerçek YÖK Atlas verisiyle çalışan yapay zekâ tercih
|
||||
danışmanın. İnsan danışmanın binlerce lira aldığı işi — dengeli
|
||||
liste, risk analizi, soru-cevap — onda bir fiyatına yapar.
|
||||
</p>
|
||||
<div
|
||||
id="hero-form"
|
||||
className="mt-10 flex w-full scroll-mt-28 justify-center"
|
||||
>
|
||||
<HeroForm />
|
||||
</div>
|
||||
<p className="mt-4 text-sm text-slate-500">
|
||||
Temel arama her zaman ücretsiz · Kredi kartı gerekmez · Tam analiz
|
||||
paketi tek seferlik {PAKET_FIYATI} TL
|
||||
</p>
|
||||
<div className="mt-3 inline-flex items-center gap-2.5 rounded-lg border border-slate-200 bg-white px-3 py-2 text-left text-xs text-slate-700 shadow-xs">
|
||||
<Image
|
||||
src="/yok-logo.svg"
|
||||
alt="Yükseköğretim Kurulu"
|
||||
width={68}
|
||||
height={33}
|
||||
className="h-7 w-auto shrink-0"
|
||||
/>
|
||||
<span className="h-5 w-px shrink-0 bg-slate-200" aria-hidden />
|
||||
<span>
|
||||
<strong className="font-semibold text-slate-900">
|
||||
YÖK Atlas'ın gerçek verileriyle
|
||||
</strong>{" "}
|
||||
güvenilir sonuçlar
|
||||
</span>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Problem */}
|
||||
<section className="border-y border-slate-200 bg-white py-20">
|
||||
<div className="mx-auto max-w-6xl px-4">
|
||||
<h2 className="text-center font-heading text-3xl font-bold sm:text-4xl">
|
||||
Tercih dönemi neden bu kadar stresli?
|
||||
</h2>
|
||||
<div className="mt-12 grid gap-6 md:grid-cols-3">
|
||||
{problems.map((p) => (
|
||||
<Card key={p.title} className="border-slate-200">
|
||||
<CardHeader>
|
||||
<div className="mb-2 flex size-11 items-center justify-center rounded-xl bg-primary/10">
|
||||
<p.icon className="size-5 text-primary" aria-hidden />
|
||||
</div>
|
||||
<CardTitle className="font-heading text-xl">
|
||||
{p.title}
|
||||
</CardTitle>
|
||||
<CardDescription className="text-base leading-relaxed">
|
||||
{p.description}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
</Card>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* How it works */}
|
||||
<section id="nasil-calisir" className="scroll-mt-24 py-20">
|
||||
<div className="mx-auto max-w-6xl px-4">
|
||||
<h2 className="text-center font-heading text-3xl font-bold sm:text-4xl">
|
||||
Üç adımda listen hazır
|
||||
</h2>
|
||||
<div className="mt-12 grid gap-6 md:grid-cols-3">
|
||||
{steps.map((s) => (
|
||||
<div
|
||||
key={s.step}
|
||||
className="relative rounded-2xl border border-slate-200 bg-white p-8"
|
||||
>
|
||||
<span className="absolute -top-4 left-8 flex size-8 items-center justify-center rounded-full bg-orange-500 font-heading text-sm font-bold text-white">
|
||||
{s.step}
|
||||
</span>
|
||||
<s.icon className="size-6 text-primary" aria-hidden />
|
||||
<h3 className="mt-4 font-heading text-xl font-semibold">
|
||||
{s.title}
|
||||
</h3>
|
||||
<p className="mt-2 leading-relaxed text-slate-600">
|
||||
{s.description}
|
||||
</p>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
|
||||
{/* Veriye dayalı güven + garanti vaadine karşı dürüst konumlandırma */}
|
||||
<div className="mx-auto mt-12 w-full max-w-3xl overflow-hidden rounded-2xl border border-slate-200 bg-white shadow-sm">
|
||||
<dl className="grid grid-cols-1 divide-y divide-slate-200 sm:grid-cols-3 sm:divide-x sm:divide-y-0">
|
||||
{[
|
||||
{ value: "23.000+", label: "Taranan lisans programı" },
|
||||
{ value: "4 yıl", label: "Taban sıralaması trend verisi" },
|
||||
{ value: "%100", label: "Resmî YÖK Atlas kaynağı" },
|
||||
].map((stat) => (
|
||||
<div key={stat.label} className="p-6 text-center">
|
||||
<dt className="text-sm text-slate-500">{stat.label}</dt>
|
||||
<dd className="mt-1 font-heading text-3xl font-bold text-primary">
|
||||
{stat.value}
|
||||
</dd>
|
||||
</div>
|
||||
))}
|
||||
</dl>
|
||||
|
||||
<div className="flex gap-4 border-t border-slate-200 bg-primary/5 p-6 text-left sm:items-center sm:p-7">
|
||||
<div className="flex size-11 shrink-0 items-center justify-center rounded-xl bg-primary text-white shadow-sm">
|
||||
<ShieldCheck className="size-5" aria-hidden />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-xs font-semibold uppercase tracking-wider text-primary">
|
||||
Dürüstlük notu
|
||||
</p>
|
||||
<p className="mt-1 font-heading text-lg font-bold text-slate-900 sm:text-xl">
|
||||
Yerleşme garantisi vermiyoruz — çünkü kimse veremez.
|
||||
</p>
|
||||
<p className="mt-1.5 text-sm leading-6 text-slate-600">
|
||||
Taban sıralamaları her yıl değişir. Biz sonuç vaadi satmak
|
||||
yerine riski satır satır gösterir, daha güvenli bir liste
|
||||
kurmana yardımcı oluruz.
|
||||
</p>
|
||||
</div>
|
||||
</p> */}
|
||||
<div
|
||||
id="hero-form"
|
||||
className="mt-6 flex w-full scroll-mt-28 justify-center"
|
||||
>
|
||||
<HeroForm />
|
||||
</div>
|
||||
<p className="mt-4 text-sm text-slate-500">
|
||||
Temel arama her zaman ücretsiz · Kredi kartı gerekmez · Tam
|
||||
analiz paketi tek seferlik {PAKET_FIYATI} TL
|
||||
</p>
|
||||
<div className="mt-3 inline-flex items-center gap-2.5 rounded-lg border border-slate-200 bg-white px-3 py-2 text-left text-xs text-slate-700 shadow-xs">
|
||||
<Image
|
||||
src="/yok-logo.svg"
|
||||
alt="Yükseköğretim Kurulu"
|
||||
width={68}
|
||||
height={33}
|
||||
className="h-7 w-auto shrink-0"
|
||||
/>
|
||||
<span className="h-5 w-px shrink-0 bg-slate-200" aria-hidden />
|
||||
<span>
|
||||
<strong className="font-semibold text-slate-900">
|
||||
YÖK Atlas'ın gerçek verileriyle
|
||||
</strong>{" "}
|
||||
güvenilir sonuçlar
|
||||
</span>
|
||||
</div>
|
||||
</Parallax>
|
||||
</section>
|
||||
|
||||
{/* Hero → Problem geçişi: border yerine piksel ayraç */}
|
||||
<div aria-hidden className="mx-auto w-56">
|
||||
<Parallax strength={26}>
|
||||
<PixelDivider seed={11} />
|
||||
</Parallax>
|
||||
</div>
|
||||
|
||||
{/* Problem */}
|
||||
<section className="py-20 sm:py-24">
|
||||
<div className="mx-auto max-w-6xl px-4">
|
||||
{/* Başlık gövdeden hafif hızlı akar — katman derinliği */}
|
||||
<Parallax strength={16}>
|
||||
<Reveal className="flex flex-col items-center gap-4 text-center">
|
||||
<SectionEyebrow>Sorun</SectionEyebrow>
|
||||
<h2 className="font-heading text-3xl font-bold sm:text-4xl">
|
||||
Tercih dönemi neden bu kadar stresli?
|
||||
</h2>
|
||||
<p className="max-w-xl text-lg leading-relaxed text-slate-600">
|
||||
Her yıl iki milyondan fazla aday aynı üç duvara çarpıyor.
|
||||
</p>
|
||||
</Reveal>
|
||||
</Parallax>
|
||||
<Parallax
|
||||
strength={7}
|
||||
className="mt-12 grid gap-6 md:grid-cols-3"
|
||||
>
|
||||
{problems.map((p, i) => (
|
||||
<Reveal key={p.title} delay={i * 0.08}>
|
||||
<Card className="relative h-full overflow-hidden border-slate-200/70 shadow-sm transition-all duration-300 hover:-translate-y-1 hover:border-primary/30 hover:shadow-lg hover:shadow-primary/5">
|
||||
<PixelCorner className="absolute right-4 top-4" />
|
||||
<CardHeader>
|
||||
<div className="mb-2 flex size-11 items-center justify-center rounded-xl bg-primary/10">
|
||||
<p.icon className="size-5 text-primary" aria-hidden />
|
||||
</div>
|
||||
<CardTitle className="font-heading text-xl">
|
||||
{p.title}
|
||||
</CardTitle>
|
||||
<CardDescription className="text-base leading-relaxed">
|
||||
{p.description}
|
||||
</CardDescription>
|
||||
</CardHeader>
|
||||
</Card>
|
||||
</Reveal>
|
||||
))}
|
||||
</Parallax>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
{/* Comparison */}
|
||||
<section
|
||||
id="karsilastirma"
|
||||
className="scroll-mt-24 border-y border-slate-200 bg-white py-20"
|
||||
>
|
||||
<div className="mx-auto max-w-4xl px-4">
|
||||
<h2 className="text-center font-heading text-3xl font-bold sm:text-4xl">
|
||||
Robot mu, danışman mı, KolayTercih mi?
|
||||
</h2>
|
||||
<div className="mt-12 overflow-x-auto rounded-2xl border border-slate-200 bg-white">
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow className="bg-slate-50">
|
||||
<TableHead className="w-[40%]">Özellik</TableHead>
|
||||
<TableHead className="text-center">
|
||||
Ücretsiz robotlar
|
||||
</TableHead>
|
||||
<TableHead className="text-center">
|
||||
İnsan danışman
|
||||
</TableHead>
|
||||
<TableHead className="text-center font-heading font-bold text-primary">
|
||||
KolayTercih
|
||||
</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{comparison.map((row) => (
|
||||
<TableRow key={row.feature}>
|
||||
<TableCell className="font-medium">
|
||||
{row.feature}
|
||||
</TableCell>
|
||||
<TableCell className="text-center">
|
||||
<ComparisonCell value={row.robot} />
|
||||
</TableCell>
|
||||
<TableCell className="text-center">
|
||||
<ComparisonCell value={row.danisman} />
|
||||
</TableCell>
|
||||
<TableCell className="bg-primary/5 text-center">
|
||||
<ComparisonCell value={row.tercihai} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
{/* Problem → Nasıl çalışır geçişi */}
|
||||
<div aria-hidden className="mx-auto w-56">
|
||||
<Parallax strength={26}>
|
||||
<PixelDivider seed={17} />
|
||||
</Parallax>
|
||||
</div>
|
||||
|
||||
{/* How it works */}
|
||||
<section id="nasil-calisir" className="scroll-mt-24 py-20 sm:py-24">
|
||||
<div className="mx-auto max-w-6xl px-4">
|
||||
<Parallax strength={16}>
|
||||
<Reveal className="flex flex-col items-center gap-4 text-center">
|
||||
<SectionEyebrow>Nasıl çalışır?</SectionEyebrow>
|
||||
<h2 className="font-heading text-3xl font-bold sm:text-4xl">
|
||||
Üç adımda listen hazır
|
||||
</h2>
|
||||
<p className="max-w-xl text-lg leading-relaxed text-slate-600">
|
||||
Sıralamandan dengeli 24'lük listeye giden yol üç adım
|
||||
sürer.
|
||||
</p>
|
||||
</Reveal>
|
||||
</Parallax>
|
||||
<Parallax
|
||||
strength={7}
|
||||
className="mt-12 grid gap-6 md:grid-cols-3"
|
||||
>
|
||||
{steps.map((s, i) => (
|
||||
<Reveal key={s.step} delay={i * 0.08} className="h-full">
|
||||
<div className="relative h-full rounded-2xl border border-slate-200/70 bg-white p-8 shadow-sm transition-all duration-300 hover:-translate-y-1 hover:border-primary/30 hover:shadow-lg hover:shadow-primary/5">
|
||||
<span className="absolute -top-4 left-8 flex size-8 items-center justify-center rounded-full bg-orange-500 font-heading text-sm font-bold text-white">
|
||||
{s.step}
|
||||
</span>
|
||||
<PixelCorner className="absolute right-4 top-4" />
|
||||
<s.icon className="size-6 text-primary" aria-hidden />
|
||||
<h3 className="mt-4 font-heading text-xl font-semibold">
|
||||
{s.title}
|
||||
</h3>
|
||||
<p className="mt-2 leading-relaxed text-slate-600">
|
||||
{s.description}
|
||||
</p>
|
||||
</div>
|
||||
</Reveal>
|
||||
))}
|
||||
</Parallax>
|
||||
|
||||
{/* Veriye dayalı güven + garanti vaadine karşı dürüst konumlandırma */}
|
||||
<Parallax
|
||||
strength={10}
|
||||
className="mx-auto mt-12 w-full max-w-3xl"
|
||||
>
|
||||
<Reveal
|
||||
delay={0.1}
|
||||
className="overflow-hidden rounded-2xl border border-slate-200/70 bg-white shadow-sm"
|
||||
>
|
||||
<dl className="grid grid-cols-1 divide-y divide-slate-200 sm:grid-cols-3 sm:divide-x sm:divide-y-0">
|
||||
{[
|
||||
{ value: "23.000+", label: "Taranan lisans programı" },
|
||||
{
|
||||
value: "4 yıl",
|
||||
label: "Taban sıralaması trend verisi",
|
||||
},
|
||||
{ value: "%100", label: "Resmî YÖK Atlas kaynağı" },
|
||||
].map((stat) => (
|
||||
<div key={stat.label} className="p-6 text-center">
|
||||
<dt className="text-sm text-slate-500">{stat.label}</dt>
|
||||
<dd className="mt-1 font-heading text-3xl font-bold text-primary">
|
||||
{stat.value}
|
||||
</dd>
|
||||
</div>
|
||||
))}
|
||||
</dl>
|
||||
|
||||
<div className="flex gap-4 border-t border-slate-200 bg-primary/5 p-6 text-left sm:items-center sm:p-7">
|
||||
<div className="flex size-11 shrink-0 items-center justify-center rounded-xl bg-primary text-white shadow-sm">
|
||||
<ShieldCheck className="size-5" aria-hidden />
|
||||
</div>
|
||||
<div>
|
||||
<p className="text-xs font-semibold uppercase tracking-wider text-primary">
|
||||
Dürüstlük notu
|
||||
</p>
|
||||
<p className="mt-1 font-heading text-lg font-bold text-slate-900 sm:text-xl">
|
||||
Yerleşme garantisi vermiyoruz — çünkü kimse veremez.
|
||||
</p>
|
||||
<p className="mt-1.5 text-sm leading-6 text-slate-600">
|
||||
Taban sıralamaları her yıl değişir. Biz sonuç vaadi
|
||||
satmak yerine riski satır satır gösterir, daha güvenli
|
||||
bir liste kurmana yardımcı oluruz.
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</Reveal>
|
||||
</Parallax>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</section>
|
||||
|
||||
{/* FAQ */}
|
||||
<section id="sss" className="scroll-mt-24 py-20">
|
||||
<div className="mx-auto max-w-3xl px-4">
|
||||
<h2 className="text-center font-heading text-3xl font-bold sm:text-4xl">
|
||||
Sık sorulan sorular
|
||||
</h2>
|
||||
<Accordion type="single" collapsible className="mt-10">
|
||||
{faqs.map((faq) => (
|
||||
<AccordionItem key={faq.question} value={faq.question}>
|
||||
<AccordionTrigger className="cursor-pointer text-left font-heading text-base font-semibold">
|
||||
{faq.question}
|
||||
</AccordionTrigger>
|
||||
<AccordionContent className="text-base leading-relaxed text-slate-600">
|
||||
{faq.answer}
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
))}
|
||||
</Accordion>
|
||||
{/* Nasıl çalışır → Karşılaştırma geçişi */}
|
||||
<div aria-hidden className="mx-auto w-56">
|
||||
<Parallax strength={26}>
|
||||
<PixelDivider seed={23} />
|
||||
</Parallax>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Final CTA */}
|
||||
<section className="bg-primary py-20 text-white">
|
||||
<div className="mx-auto flex max-w-3xl flex-col items-center px-4 text-center">
|
||||
<MessageCircleQuestion className="size-10 opacity-80" aria-hidden />
|
||||
<h2 className="mt-6 font-heading text-3xl font-bold sm:text-4xl">
|
||||
Tercih listen, pişmanlık listesi olmasın
|
||||
</h2>
|
||||
<p className="mt-4 max-w-xl text-lg leading-relaxed text-white/90">
|
||||
Sıralamanı gir, yapay zekâ danışmanın veriyle konuşsun. Tercih
|
||||
dönemi bitmeden yerini al.
|
||||
{/* Comparison */}
|
||||
<section id="karsilastirma" 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>Karşılaştır</SectionEyebrow>
|
||||
<h2 className="font-heading text-3xl font-bold sm:text-4xl">
|
||||
Robot mu, danışman mı, KolayTercih mi?
|
||||
</h2>
|
||||
<p className="max-w-xl text-lg leading-relaxed text-slate-600">
|
||||
Aynı işi kim, neyle, kaça yapıyor — yan yana bak.
|
||||
</p>
|
||||
</Reveal>
|
||||
</Parallax>
|
||||
<Parallax strength={7} className="mt-12">
|
||||
<Reveal
|
||||
delay={0.08}
|
||||
className="overflow-x-auto rounded-2xl border border-slate-200/70 bg-white shadow-sm"
|
||||
>
|
||||
<Table>
|
||||
<TableHeader>
|
||||
<TableRow className="bg-slate-50">
|
||||
<TableHead className="w-[40%]">Özellik</TableHead>
|
||||
<TableHead className="text-center">
|
||||
Ücretsiz robotlar
|
||||
</TableHead>
|
||||
<TableHead className="text-center">
|
||||
İnsan danışman
|
||||
</TableHead>
|
||||
<TableHead className="text-center font-heading font-bold text-primary">
|
||||
KolayTercih
|
||||
</TableHead>
|
||||
</TableRow>
|
||||
</TableHeader>
|
||||
<TableBody>
|
||||
{comparison.map((row) => (
|
||||
<TableRow key={row.feature}>
|
||||
<TableCell className="font-medium">
|
||||
{row.feature}
|
||||
</TableCell>
|
||||
<TableCell className="text-center">
|
||||
<ComparisonCell value={row.robot} />
|
||||
</TableCell>
|
||||
<TableCell className="text-center">
|
||||
<ComparisonCell value={row.danisman} />
|
||||
</TableCell>
|
||||
<TableCell className="bg-primary/5 text-center">
|
||||
<ComparisonCell value={row.tercihai} />
|
||||
</TableCell>
|
||||
</TableRow>
|
||||
))}
|
||||
</TableBody>
|
||||
</Table>
|
||||
</Reveal>
|
||||
</Parallax>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Karşılaştırma → SSS geçişi */}
|
||||
<div aria-hidden className="mx-auto w-56">
|
||||
<Parallax strength={26}>
|
||||
<PixelDivider seed={31} />
|
||||
</Parallax>
|
||||
</div>
|
||||
|
||||
{/* FAQ */}
|
||||
<section id="sss" className="scroll-mt-24 py-20 sm:py-24">
|
||||
<div className="mx-auto max-w-3xl px-4">
|
||||
<Parallax strength={16}>
|
||||
<Reveal className="flex flex-col items-center gap-4 text-center">
|
||||
<SectionEyebrow>SSS</SectionEyebrow>
|
||||
<h2 className="font-heading text-3xl font-bold sm:text-4xl">
|
||||
Sık sorulan sorular
|
||||
</h2>
|
||||
</Reveal>
|
||||
</Parallax>
|
||||
<Parallax strength={7}>
|
||||
<Reveal delay={0.08}>
|
||||
<Accordion
|
||||
type="single"
|
||||
collapsible
|
||||
className="mt-10 rounded-2xl border border-slate-200/70 bg-white px-6 shadow-sm"
|
||||
>
|
||||
{faqs.map((faq) => (
|
||||
<AccordionItem
|
||||
key={faq.question}
|
||||
value={faq.question}
|
||||
className="last:border-b-0"
|
||||
>
|
||||
<AccordionTrigger className="cursor-pointer text-left font-heading text-base font-semibold">
|
||||
{faq.question}
|
||||
</AccordionTrigger>
|
||||
<AccordionContent className="text-base leading-relaxed text-slate-600">
|
||||
{faq.answer}
|
||||
</AccordionContent>
|
||||
</AccordionItem>
|
||||
))}
|
||||
</Accordion>
|
||||
</Reveal>
|
||||
</Parallax>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* Final CTA — tam genişlik bant yerine yüzen, köşeleri yumuşak panel */}
|
||||
<section className="px-4 pb-24 pt-6 sm:px-6">
|
||||
<Parallax strength={12} className="mx-auto max-w-6xl">
|
||||
<Reveal>
|
||||
<div className="relative isolate overflow-hidden rounded-3xl bg-primary px-4 py-20 text-white shadow-xl shadow-primary/20 sm:py-24">
|
||||
{/* Hero'nun piksel dokusu koyu zeminde: ortası boş, kenarlara doğru yoğun */}
|
||||
{/* Piksel zemin panel içinde geride kalır; taşma payı için dikeyde büyütülür */}
|
||||
<div
|
||||
aria-hidden
|
||||
className="pointer-events-none absolute inset-x-0 -inset-y-10 -z-10 text-white"
|
||||
>
|
||||
<Parallax strength={-22} className="h-full">
|
||||
<PixelField seed={8} />
|
||||
</Parallax>
|
||||
</div>
|
||||
<div className="mx-auto flex max-w-3xl flex-col items-center text-center">
|
||||
<MessageCircleQuestion
|
||||
className="size-10 opacity-80"
|
||||
aria-hidden
|
||||
/>
|
||||
<h2 className="mt-6 font-heading text-3xl font-bold sm:text-4xl">
|
||||
Tercih listen, pişmanlık listesi olmasın
|
||||
</h2>
|
||||
<p className="mt-4 max-w-xl text-lg leading-relaxed text-white/90">
|
||||
Sıralamanı gir, yapay zekâ danışmanın veriyle konuşsun.
|
||||
Tercih dönemi bitmeden yerini al.
|
||||
</p>
|
||||
<Button
|
||||
asChild
|
||||
size="lg"
|
||||
className="mt-8 h-12 cursor-pointer bg-orange-500 px-8 text-white transition-colors duration-200 hover:bg-orange-600"
|
||||
>
|
||||
<a href="#hero-form">Ücretsiz dene</a>
|
||||
</Button>
|
||||
</div>
|
||||
</div>
|
||||
</Reveal>
|
||||
</Parallax>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer className="pb-32 pt-4">
|
||||
<div className="mx-auto max-w-6xl px-4 text-center text-sm leading-relaxed text-slate-500">
|
||||
<p>
|
||||
© 2026 KolayTercih. Veriler resmî YÖK Atlas kaynağından derlenir;
|
||||
KolayTercih, ÖSYM veya YÖK ile bağlantılı değildir.
|
||||
</p>
|
||||
<Button
|
||||
asChild
|
||||
size="lg"
|
||||
className="mt-8 h-12 cursor-pointer bg-orange-500 px-8 text-white transition-colors duration-200 hover:bg-orange-600"
|
||||
<p className="mt-2">
|
||||
KolayTercih bir karar destek aracıdır, yerleşme garantisi vermez.
|
||||
Tercih listenizin son hali ve başvuru sorumluluğu size aittir.
|
||||
</p>
|
||||
<nav
|
||||
aria-label="Yasal sayfalar"
|
||||
className="mt-4 flex items-center justify-center gap-4"
|
||||
>
|
||||
<a href="#hero-form">Ücretsiz dene</a>
|
||||
</Button>
|
||||
<Link
|
||||
href="/gizlilik"
|
||||
className="hover:text-slate-700 hover:underline"
|
||||
>
|
||||
Gizlilik & KVKK
|
||||
</Link>
|
||||
<Link
|
||||
href="/kosullar"
|
||||
className="hover:text-slate-700 hover:underline"
|
||||
>
|
||||
Kullanım & iade koşulları
|
||||
</Link>
|
||||
<Link
|
||||
href="/iletisim"
|
||||
className="hover:text-slate-700 hover:underline"
|
||||
>
|
||||
İletişim
|
||||
</Link>
|
||||
</nav>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
|
||||
<footer className="border-t border-slate-200 bg-white pb-32 pt-10">
|
||||
<div className="mx-auto max-w-6xl px-4 text-center text-sm leading-relaxed text-slate-500">
|
||||
<p>
|
||||
© 2026 KolayTercih. Veriler resmî YÖK Atlas kaynağından derlenir;
|
||||
KolayTercih, ÖSYM veya YÖK ile bağlantılı değildir.
|
||||
</p>
|
||||
<p className="mt-2">
|
||||
KolayTercih bir karar destek aracıdır, yerleşme garantisi vermez.
|
||||
Tercih listenizin son hali ve başvuru sorumluluğu size aittir.
|
||||
</p>
|
||||
<nav
|
||||
aria-label="Yasal sayfalar"
|
||||
className="mt-4 flex items-center justify-center gap-4"
|
||||
>
|
||||
<Link href="/gizlilik" className="hover:text-slate-700 hover:underline">
|
||||
Gizlilik & KVKK
|
||||
</Link>
|
||||
<Link href="/kosullar" className="hover:text-slate-700 hover:underline">
|
||||
Kullanım & iade koşulları
|
||||
</Link>
|
||||
<Link href="/iletisim" className="hover:text-slate-700 hover:underline">
|
||||
İletişim
|
||||
</Link>
|
||||
</nav>
|
||||
</div>
|
||||
</footer>
|
||||
</footer>
|
||||
</ScrollFlow>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -13,6 +13,8 @@ import { getCurrentUser } from "@/lib/session";
|
||||
import { URUNLER, DENEME_KREDISI } from "@/lib/credits";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Badge } from "@/components/ui/badge";
|
||||
import { Parallax } from "@/components/parallax";
|
||||
import { ScrollFlow } from "@/components/scroll-flow";
|
||||
import { SatinAlForm } from "./satin-al-form";
|
||||
|
||||
export const metadata: Metadata = {
|
||||
@@ -51,134 +53,143 @@ export default async function PaketPage({
|
||||
const odemeHatasi = hata === "token" || hata === "siparis";
|
||||
|
||||
return (
|
||||
<div className="flex min-h-screen flex-col bg-slate-50 text-slate-900">
|
||||
<main className="mx-auto w-full max-w-3xl flex-1 px-4 py-16">
|
||||
{odemeHatasi ? (
|
||||
<div
|
||||
role="alert"
|
||||
className="mb-8 rounded-2xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-800"
|
||||
<div className="bg-slate-50 text-slate-900">
|
||||
<ScrollFlow className="flex min-h-screen flex-col">
|
||||
<main className="mx-auto w-full max-w-3xl flex-1 px-4 py-16">
|
||||
{odemeHatasi ? (
|
||||
<div
|
||||
role="alert"
|
||||
className="mb-8 rounded-2xl border border-amber-200 bg-amber-50 px-4 py-3 text-sm text-amber-800"
|
||||
>
|
||||
Ödemen doğrulanamadı. Kartından çekim yapıldıysa kredilerin birkaç
|
||||
dakika içinde otomatik tanımlanır; tanımlanmazsa aşağıdan tekrar
|
||||
deneyebilirsin — çekim yapılmadıysa hiçbir ücret ödemedin.
|
||||
</div>
|
||||
) : null}
|
||||
<Parallax fromStart strength={12} className="text-center">
|
||||
<Badge variant="secondary" className="bg-primary/10 text-primary">
|
||||
Tek seferlik ödeme · Abonelik yok
|
||||
</Badge>
|
||||
<h1 className="mt-4 font-heading text-3xl font-bold sm:text-4xl">
|
||||
İnsan danışmanın işini,{" "}
|
||||
<span className="text-primary">onda bir fiyatına</span>
|
||||
</h1>
|
||||
<p className="mx-auto mt-3 max-w-xl text-slate-600">
|
||||
Tercih danışmanları bu dönemde 2.000–10.000 TL alıyor. KolayTercih
|
||||
aynı işi gerçek YÖK Atlas verisiyle, dakikalar içinde yapar.
|
||||
</p>
|
||||
</Parallax>
|
||||
|
||||
<Parallax
|
||||
strength={6}
|
||||
className="mt-10 grid gap-6 sm:grid-cols-[1fr_auto]"
|
||||
>
|
||||
Ödemen doğrulanamadı. Kartından çekim yapıldıysa kredilerin birkaç
|
||||
dakika içinde otomatik tanımlanır; tanımlanmazsa aşağıdan tekrar
|
||||
deneyebilirsin — çekim yapılmadıysa hiçbir ücret ödemedin.
|
||||
</div>
|
||||
) : null}
|
||||
<div className="text-center">
|
||||
<Badge variant="secondary" className="bg-primary/10 text-primary">
|
||||
Tek seferlik ödeme · Abonelik yok
|
||||
</Badge>
|
||||
<h1 className="mt-4 font-heading text-3xl font-bold sm:text-4xl">
|
||||
İnsan danışmanın işini,{" "}
|
||||
<span className="text-primary">onda bir fiyatına</span>
|
||||
</h1>
|
||||
<p className="mx-auto mt-3 max-w-xl text-slate-600">
|
||||
Tercih danışmanları bu dönemde 2.000–10.000 TL alıyor. KolayTercih
|
||||
aynı işi gerçek YÖK Atlas verisiyle, dakikalar içinde yapar.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="mt-10 grid gap-6 sm:grid-cols-[1fr_auto]">
|
||||
{/* Ana paket */}
|
||||
<section className="rounded-2xl border-2 border-orange-500 bg-white p-8 shadow-sm">
|
||||
<div className="flex items-baseline justify-between">
|
||||
<h2 className="font-heading text-xl font-bold">
|
||||
Tercih Dönemi Paketi
|
||||
</h2>
|
||||
<p className="font-heading text-3xl font-bold">
|
||||
{tl(URUNLER.paket.amountKurus)} TL
|
||||
</p>
|
||||
</div>
|
||||
<ul className="mt-6 space-y-3">
|
||||
{OZELLIKLER.map((o) => (
|
||||
<li key={o.text} className="flex items-start gap-3 text-sm">
|
||||
<o.icon
|
||||
className="mt-0.5 size-4 shrink-0 text-emerald-600"
|
||||
aria-hidden
|
||||
/>
|
||||
{o.text}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<div className="mt-8">
|
||||
{u ? (
|
||||
u.hasPaket ? (
|
||||
<div className="flex items-center gap-2 rounded-xl border border-emerald-200 bg-emerald-50 px-4 py-3 text-sm font-medium text-emerald-800">
|
||||
<CheckCircle2 className="size-4" aria-hidden />
|
||||
Paketin aktif —{" "}
|
||||
<Link href="/" className="underline">
|
||||
listeni oluştur
|
||||
</Link>
|
||||
</div>
|
||||
{/* Ana paket */}
|
||||
<section className="rounded-2xl border-2 border-orange-500 bg-white p-8 shadow-sm">
|
||||
<div className="flex items-baseline justify-between">
|
||||
<h2 className="font-heading text-xl font-bold">
|
||||
Tercih Dönemi Paketi
|
||||
</h2>
|
||||
<p className="font-heading text-3xl font-bold">
|
||||
{tl(URUNLER.paket.amountKurus)} TL
|
||||
</p>
|
||||
</div>
|
||||
<ul className="mt-6 space-y-3">
|
||||
{OZELLIKLER.map((o) => (
|
||||
<li key={o.text} className="flex items-start gap-3 text-sm">
|
||||
<o.icon
|
||||
className="mt-0.5 size-4 shrink-0 text-emerald-600"
|
||||
aria-hidden
|
||||
/>
|
||||
{o.text}
|
||||
</li>
|
||||
))}
|
||||
</ul>
|
||||
<div className="mt-8">
|
||||
{u ? (
|
||||
u.hasPaket ? (
|
||||
<div className="flex items-center gap-2 rounded-xl border border-emerald-200 bg-emerald-50 px-4 py-3 text-sm font-medium text-emerald-800">
|
||||
<CheckCircle2 className="size-4" aria-hidden />
|
||||
Paketin aktif —{" "}
|
||||
<Link href="/" className="underline">
|
||||
listeni oluştur
|
||||
</Link>
|
||||
</div>
|
||||
) : (
|
||||
<SatinAlForm
|
||||
urun="paket"
|
||||
label={`${tl(URUNLER.paket.amountKurus)} TL — Paketi al`}
|
||||
vurgulu
|
||||
/>
|
||||
)
|
||||
) : (
|
||||
<Button
|
||||
asChild
|
||||
className="h-12 w-full cursor-pointer bg-orange-500 px-8 text-white transition-colors duration-200 hover:bg-orange-600"
|
||||
>
|
||||
<Link
|
||||
href={`/giris?callback=${encodeURIComponent("/paket")}`}
|
||||
>
|
||||
Giriş yap ve {DENEME_KREDISI} deneme kredisi kazan
|
||||
</Link>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
<p className="mt-4 text-center text-xs text-slate-500">
|
||||
iyzico güvenli ödeme · Kart bilgilerin bize hiç ulaşmaz ·{" "}
|
||||
<Link
|
||||
href="/kosullar#iade"
|
||||
className="underline hover:text-slate-700"
|
||||
>
|
||||
İade koşulları
|
||||
</Link>
|
||||
</p>
|
||||
</section>
|
||||
|
||||
{/* Top-up */}
|
||||
<section className="flex h-fit flex-col rounded-2xl border border-slate-200 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 />
|
||||
<h2 className="font-heading font-bold">Kredi bitti mi?</h2>
|
||||
</div>
|
||||
<p className="mt-2 flex-1 text-sm text-slate-600">
|
||||
+{URUNLER.topup.credits} soru hakkı,{" "}
|
||||
{tl(URUNLER.topup.amountKurus)} TL.
|
||||
</p>
|
||||
<div className="mt-4">
|
||||
{u ? (
|
||||
<SatinAlForm
|
||||
urun="paket"
|
||||
label={`${tl(URUNLER.paket.amountKurus)} TL — Paketi al`}
|
||||
vurgulu
|
||||
urun="topup"
|
||||
label={`+${URUNLER.topup.credits} kredi al`}
|
||||
/>
|
||||
)
|
||||
) : (
|
||||
<Button
|
||||
asChild
|
||||
className="h-12 w-full cursor-pointer bg-orange-500 px-8 text-white transition-colors duration-200 hover:bg-orange-600"
|
||||
>
|
||||
<Link href={`/giris?callback=${encodeURIComponent("/paket")}`}>
|
||||
Giriş yap ve {DENEME_KREDISI} deneme kredisi kazan
|
||||
</Link>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
<p className="mt-4 text-center text-xs text-slate-500">
|
||||
iyzico güvenli ödeme · Kart bilgilerin bize hiç ulaşmaz ·{" "}
|
||||
<Link
|
||||
href="/kosullar#iade"
|
||||
className="underline hover:text-slate-700"
|
||||
>
|
||||
İade koşulları
|
||||
</Link>
|
||||
</p>
|
||||
</section>
|
||||
) : (
|
||||
<Button
|
||||
asChild
|
||||
variant="outline"
|
||||
className="h-11 w-full cursor-pointer"
|
||||
>
|
||||
<Link
|
||||
href={`/giris?callback=${encodeURIComponent("/paket")}`}
|
||||
>
|
||||
Önce giriş yap
|
||||
</Link>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
</Parallax>
|
||||
|
||||
{/* Top-up */}
|
||||
<section className="flex h-fit flex-col rounded-2xl border border-slate-200 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 />
|
||||
<h2 className="font-heading font-bold">Kredi bitti mi?</h2>
|
||||
</div>
|
||||
<p className="mt-2 flex-1 text-sm text-slate-600">
|
||||
+{URUNLER.topup.credits} soru hakkı,{" "}
|
||||
{tl(URUNLER.topup.amountKurus)} TL.
|
||||
</p>
|
||||
<div className="mt-4">
|
||||
{u ? (
|
||||
<SatinAlForm
|
||||
urun="topup"
|
||||
label={`+${URUNLER.topup.credits} kredi al`}
|
||||
/>
|
||||
) : (
|
||||
<Button
|
||||
asChild
|
||||
variant="outline"
|
||||
className="h-11 w-full cursor-pointer"
|
||||
>
|
||||
<Link href={`/giris?callback=${encodeURIComponent("/paket")}`}>
|
||||
Önce giriş yap
|
||||
</Link>
|
||||
</Button>
|
||||
)}
|
||||
</div>
|
||||
</section>
|
||||
</div>
|
||||
|
||||
<p className="mt-10 text-center text-xs leading-relaxed text-slate-500">
|
||||
KolayTercih bir karar destek aracıdır; öneriler resmî YÖK Atlas verisine
|
||||
dayanır ancak yerleşme garantisi verilmez. Tercih listesinin nihai
|
||||
sorumluluğu adaya aittir. Sorun mu var?{" "}
|
||||
<Link href="/iletisim" className="underline hover:text-slate-700">
|
||||
Bize yaz
|
||||
</Link>
|
||||
.
|
||||
</p>
|
||||
</main>
|
||||
<p className="mt-10 text-center text-xs leading-relaxed text-slate-500">
|
||||
KolayTercih bir karar destek aracıdır; öneriler resmî YÖK Atlas
|
||||
verisine dayanır ancak yerleşme garantisi verilmez. Tercih
|
||||
listesinin nihai sorumluluğu adaya aittir. Sorun mu var?{" "}
|
||||
<Link href="/iletisim" className="underline hover:text-slate-700">
|
||||
Bize yaz
|
||||
</Link>
|
||||
.
|
||||
</p>
|
||||
</main>
|
||||
</ScrollFlow>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
"use client";
|
||||
|
||||
import { useActionState, useEffect } from "react";
|
||||
import { Loader2 } from "lucide-react";
|
||||
import { toast } from "sonner";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { baslatOdeme, type OdemeBaslatDurum } from "./actions";
|
||||
@@ -37,9 +36,6 @@ export function SatinAlForm({
|
||||
}
|
||||
variant={vurgulu ? "default" : "outline"}
|
||||
>
|
||||
{pending ? (
|
||||
<Loader2 className="size-4 animate-spin" aria-hidden />
|
||||
) : null}
|
||||
{pending ? "Ödeme sayfasına yönlendiriliyorsun…" : label}
|
||||
</Button>
|
||||
</form>
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
|
||||
import { useMemo, useEffect, useRef, useState } from "react";
|
||||
import Link from "next/link";
|
||||
import { FileText, Loader2, Lock, RefreshCcw } from "lucide-react";
|
||||
import { FileText, Lock, RefreshCcw } from "lucide-react";
|
||||
import { Button } from "@/components/ui/button";
|
||||
import { Skeleton } from "@/components/ui/skeleton";
|
||||
import { SohbetPopup } from "./sohbet-popup";
|
||||
import { RaporListesi } from "@/components/rapor-listesi";
|
||||
import { TercihHaritasi, type HaritaPin } from "@/components/tercih-haritasi";
|
||||
@@ -305,16 +306,28 @@ function UretimGovdesi() {
|
||||
ref={govdeRef}
|
||||
tabIndex={-1}
|
||||
aria-live="polite"
|
||||
className="mt-16 flex flex-col items-center justify-center gap-4 rounded-2xl border border-slate-200 bg-white py-16 text-center outline-none"
|
||||
className="mt-16 rounded-2xl border border-slate-200 bg-white p-6 outline-none sm:p-8"
|
||||
>
|
||||
<Loader2 className="size-10 animate-spin text-primary" aria-hidden />
|
||||
<p className="font-heading text-lg font-bold">Listen hazırlanıyor</p>
|
||||
<p className="max-w-sm text-sm text-slate-500">
|
||||
{URETIM_MESAJLARI[mesajIdx]}
|
||||
</p>
|
||||
<p className="text-xs text-slate-400">
|
||||
Bu işlem yarım dakika kadar sürebilir, sayfayı kapatma.
|
||||
</p>
|
||||
<div className="flex flex-col items-center gap-1.5 text-center">
|
||||
<p className="font-heading text-lg font-bold">Listen hazırlanıyor</p>
|
||||
<p className="max-w-sm text-sm text-slate-500">
|
||||
{URETIM_MESAJLARI[mesajIdx]}
|
||||
</p>
|
||||
<p className="text-xs text-slate-400">
|
||||
Bu işlem yarım dakika kadar sürebilir, sayfayı kapatma.
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Gelmekte olan tercih listesinin iskeleti */}
|
||||
<div className="mt-8 flex flex-col gap-2">
|
||||
<div className="flex items-center justify-between">
|
||||
<Skeleton className="h-6 w-44" />
|
||||
<Skeleton className="h-6 w-24 rounded-full" />
|
||||
</div>
|
||||
{Array.from({ length: 6 }).map((_, i) => (
|
||||
<Skeleton key={i} className="h-14 w-full rounded-xl" />
|
||||
))}
|
||||
</div>
|
||||
</section>
|
||||
);
|
||||
}
|
||||
@@ -370,11 +383,7 @@ function RevizyonKutusu({
|
||||
}}
|
||||
className="cursor-pointer"
|
||||
>
|
||||
{pending ? (
|
||||
<Loader2 className="size-4 animate-spin" aria-hidden />
|
||||
) : (
|
||||
<RefreshCcw className="size-4" aria-hidden />
|
||||
)}
|
||||
<RefreshCcw className="size-4" aria-hidden />
|
||||
{pending ? "Yeniden kuruluyor…" : "Revize et (3 kredi)"}
|
||||
</Button>
|
||||
<span className="text-xs text-slate-500">
|
||||
|
||||
Reference in New Issue
Block a user