- 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>
131 lines
3.8 KiB
TypeScript
131 lines
3.8 KiB
TypeScript
"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>
|
||
);
|
||
}
|