Files
kolaytercih/src/app/giris/giris-form.tsx
bilalgursen cee6200237 feat: kimlik doğrulama, ödeme, kredi ve AI rapor sihirbazı ekle
- better-auth ile giriş/oturum yönetimi (src/lib/auth, giris sayfası)
- iyzico ödeme entegrasyonu ve paket satın alma akışı
- kredi sistemi ve uygulama veritabanı şeması (drizzle)
- AI destekli rapor üretimi ve tercih sihirbazı
- rapor yazdırma sayfası ve site header/kullanıcı menüsü

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-07-22 02:13:39 +03:00

131 lines
3.8 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 { Loader2, Mail } from "lucide-react";
import { toast } from "sonner";
import { authClient } from "@/lib/auth-client";
import { Button } from "@/components/ui/button";
import { Input } from "@/components/ui/input";
function GoogleIcon() {
return (
<svg viewBox="0 0 24 24" className="size-4" aria-hidden>
<path
fill="#4285F4"
d="M22.56 12.25c0-.78-.07-1.53-.2-2.25H12v4.26h5.92a5.06 5.06 0 0 1-2.2 3.32v2.77h3.57c2.08-1.92 3.27-4.74 3.27-8.1Z"
/>
<path
fill="#34A853"
d="M12 23c2.97 0 5.46-.98 7.28-2.66l-3.57-2.77c-.98.66-2.23 1.06-3.71 1.06-2.86 0-5.29-1.93-6.16-4.53H2.18v2.84A11 11 0 0 0 12 23Z"
/>
<path
fill="#FBBC05"
d="M5.84 14.1a6.6 6.6 0 0 1 0-4.2V7.06H2.18a11 11 0 0 0 0 9.88l3.66-2.84Z"
/>
<path
fill="#EA4335"
d="M12 5.38c1.62 0 3.06.56 4.21 1.64l3.15-3.15A11 11 0 0 0 2.18 7.06L5.84 9.9C6.71 7.31 9.14 5.38 12 5.38Z"
/>
</svg>
);
}
export function GirisForm({ callbackURL }: { callbackURL: string }) {
const [email, setEmail] = useState("");
const [busy, setBusy] = useState<"google" | "email" | null>(null);
const [sent, setSent] = useState(false);
async function googleIleGiris() {
setBusy("google");
const { error } = await authClient.signIn.social({
provider: "google",
callbackURL,
});
if (error) {
toast.error("Google ile giriş başarısız. Tekrar dener misin?");
setBusy(null);
}
}
async function linkGonder(e: React.FormEvent) {
e.preventDefault();
if (!/^\S+@\S+\.\S+$/.test(email)) {
toast.error("Geçerli bir e-posta adresi gir.");
return;
}
setBusy("email");
const { error } = await authClient.signIn.magicLink({
email,
callbackURL,
});
setBusy(null);
if (error) {
toast.error("Bağlantı gönderilemedi. Tekrar dener misin?");
return;
}
setSent(true);
}
if (sent) {
return (
<div className="mt-6 rounded-xl border border-emerald-200 bg-emerald-50 p-4 text-sm text-emerald-800">
<p className="font-semibold">Bağlantı gönderildi 📬</p>
<p className="mt-1">
<span className="font-medium">{email}</span> adresine bir giriş
bağlantısı gönderdik. Gelen kutunu (ve spam klasörünü) kontrol et
bağlantı 5 dakika geçerli.
</p>
</div>
);
}
return (
<div className="mt-6 space-y-4">
<Button
variant="outline"
className="h-11 w-full cursor-pointer"
onClick={googleIleGiris}
disabled={busy !== null}
>
{busy === "google" ? (
<Loader2 className="size-4 animate-spin" aria-hidden />
) : (
<GoogleIcon />
)}
Google ile devam et
</Button>
<div className="flex items-center gap-3 text-xs text-slate-400">
<div className="h-px flex-1 bg-slate-200" />
veya
<div className="h-px flex-1 bg-slate-200" />
</div>
<form onSubmit={linkGonder} className="space-y-3">
<Input
type="email"
inputMode="email"
autoComplete="email"
placeholder="E-posta adresin"
value={email}
onChange={(e) => setEmail(e.target.value)}
disabled={busy !== null}
className="h-11"
/>
<Button
type="submit"
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
</Button>
</form>
</div>
);
}