128 lines
4.9 KiB
TypeScript
128 lines
4.9 KiB
TypeScript
import Link from "next/link";
|
||
import { redirect } from "next/navigation";
|
||
import { getSession } from "@/lib/session";
|
||
import { PixelCorner } from "@/components/pixel-decor";
|
||
import { Skeleton } from "@/components/ui/skeleton";
|
||
import { GirisForm } from "./giris-form";
|
||
import { GirisBaslik } from "./giris-baslik";
|
||
|
||
export async function GirisKarti({
|
||
callback,
|
||
hata,
|
||
}: {
|
||
callback?: string;
|
||
hata?: string;
|
||
}) {
|
||
// Yalnız site içi yol: "//evil.com" ve "/\\evil.com" protokol-göreli adres
|
||
// sayılır, açık yönlendirmeye izin verme (dogrula-karti.tsx ile aynı kalkan).
|
||
const callbackURL =
|
||
callback && /^\/(?![/\\])/.test(callback) ? callback : "/";
|
||
// Magic link doğrulaması başarısız olunca errorCallbackURL buraya düşürür
|
||
// (bkz. giris-form.tsx ve /giris/dogrula) — ham INVALID_TOKEN yerine
|
||
// dostça bir mesaj gösterip yeni bağlantı istemeye yönlendiriyoruz.
|
||
const baglantiHatasi = hata === "gecersiz-baglanti";
|
||
|
||
const session = await getSession();
|
||
if (session) redirect(callbackURL);
|
||
|
||
// Sihirbaz funnel'ı: seçimler yapıldı, listeye giriş kaldı. /listem?uret=1
|
||
// callback'i de aynı vaadi taşır (girişten dönüşte üretim orada başlar).
|
||
const funnel =
|
||
callbackURL.startsWith("/sonuc") || callbackURL.startsWith("/listem?uret=1");
|
||
|
||
return (
|
||
<>
|
||
<div className="relative">
|
||
<div className="relative rounded-2xl border border-slate-200 bg-white p-8 shadow-sm">
|
||
{baglantiHatasi && (
|
||
<div
|
||
role="alert"
|
||
className="mb-5 rounded-xl border border-red-200 bg-red-50 p-4 text-sm text-red-800"
|
||
>
|
||
<p className="font-semibold">
|
||
Giriş bağlantısı geçersiz ya da süresi dolmuş
|
||
</p>
|
||
<p className="mt-1">
|
||
Bağlantılar 15 dakika geçerli ve tek kullanımlık. Aşağıdan
|
||
yeni bir bağlantı isteyebilirsin.
|
||
</p>
|
||
</div>
|
||
)}
|
||
<GirisBaslik funnel={funnel} />
|
||
<p className="mt-2 text-sm text-slate-600">
|
||
{funnel ? (
|
||
<>
|
||
Seçimlerin hazır — giriş yap,{" "}
|
||
<span className="font-semibold">5 deneme kredinle</span> listen
|
||
hemen üretilsin.
|
||
</>
|
||
) : (
|
||
<>
|
||
Kayıt olduğunda{" "}
|
||
<span className="font-semibold">5 deneme kredisi</span>{" "}
|
||
hesabına tanımlanır — Yapay Zeka danışmana ücretsiz soru sorabilirsin.
|
||
</>
|
||
)}
|
||
</p>
|
||
<GirisForm callbackURL={callbackURL} />
|
||
</div>
|
||
<div
|
||
aria-hidden
|
||
className="pointer-events-none absolute inset-0 z-10 text-primary"
|
||
>
|
||
<PixelCorner className="absolute -right-4 -top-4 size-9 [&_rect]:[fill-opacity:0.65]" />
|
||
<PixelCorner className="absolute -bottom-4 -right-4 size-9 rotate-90 [&_rect]:[fill-opacity:0.65]" />
|
||
<PixelCorner className="absolute -bottom-4 -left-4 size-9 rotate-180 [&_rect]:[fill-opacity:0.65]" />
|
||
<PixelCorner className="absolute -left-4 -top-4 size-9 -rotate-90 [&_rect]:[fill-opacity:0.65]" />
|
||
</div>
|
||
</div>
|
||
<p className="mt-6 text-center text-xs leading-relaxed text-slate-500">
|
||
Giriş yaparak verilerinin tercih önerileri üretmek amacıyla{" "}
|
||
<Link href="/gizlilik" className="underline hover:text-slate-700">
|
||
gizlilik metnindeki
|
||
</Link>{" "}
|
||
gibi işlenmesini ve{" "}
|
||
<Link href="/kosullar" className="underline hover:text-slate-700">
|
||
kullanım koşullarını
|
||
</Link>{" "}
|
||
kabul etmiş olursun. KolayTercih yerleşme garantisi vermez.
|
||
</p>
|
||
</>
|
||
);
|
||
}
|
||
|
||
// Kart, başlık, Google butonu, ayraç, e-posta alanı ve gönder butonu aynı
|
||
// yerde belirir — içerik gelince zıplama olmaz.
|
||
export function GirisKartiSkeleton() {
|
||
return (
|
||
<>
|
||
<div className="rounded-2xl border border-slate-200 bg-white p-8 shadow-sm">
|
||
{/* Başlık + alt metin */}
|
||
<Skeleton className="h-8 w-40" />
|
||
<Skeleton className="mt-3 h-4 w-full" />
|
||
<Skeleton className="mt-1.5 h-4 w-2/3" />
|
||
|
||
{/* Google ile devam et */}
|
||
<Skeleton className="mt-6 h-11 w-full rounded-lg" />
|
||
|
||
{/* "veya" ayracı */}
|
||
<div className="mt-4 flex items-center gap-3">
|
||
<Skeleton className="h-px flex-1" />
|
||
<Skeleton className="h-3 w-8" />
|
||
<Skeleton className="h-px flex-1" />
|
||
</div>
|
||
|
||
{/* E-posta alanı + gönder butonu */}
|
||
<Skeleton className="mt-4 h-11 w-full rounded-lg" />
|
||
<Skeleton className="mt-3 h-11 w-full rounded-lg" />
|
||
</div>
|
||
|
||
{/* Kart altındaki yasal metin */}
|
||
<div className="mt-6 flex flex-col items-center gap-1.5">
|
||
<Skeleton className="h-3 w-3/4" />
|
||
<Skeleton className="h-3 w-1/2" />
|
||
</div>
|
||
</>
|
||
);
|
||
}
|