223 lines
7.7 KiB
TypeScript
223 lines
7.7 KiB
TypeScript
"use client";
|
||
|
||
import { useState } from "react";
|
||
import { login } from "./actions";
|
||
import { Lock, Mail, AlertCircle, ArrowRight, Loader2 } from "lucide-react";
|
||
|
||
export default function LoginPage() {
|
||
const [error, setError] = useState<string | null>(null);
|
||
const [loading, setLoading] = useState(false);
|
||
|
||
async function handleSubmit(event: React.FormEvent<HTMLFormElement>) {
|
||
event.preventDefault();
|
||
setError(null);
|
||
setLoading(true);
|
||
|
||
const formData = new FormData(event.currentTarget);
|
||
const result = await login(formData);
|
||
|
||
if (result?.error) {
|
||
setError(result.error);
|
||
setLoading(false);
|
||
}
|
||
}
|
||
|
||
return (
|
||
<div
|
||
className="flex min-h-screen items-center justify-center p-4 relative overflow-hidden animated-gradient"
|
||
style={{ fontFamily: "Inter, var(--font-geist-sans), system-ui, sans-serif" }}
|
||
>
|
||
{/* Ambient glow blobs */}
|
||
<div
|
||
className="absolute top-1/4 left-1/4 w-96 h-96 rounded-full blur-3xl pointer-events-none"
|
||
style={{ background: "rgba(99, 102, 241, 0.08)" }}
|
||
/>
|
||
<div
|
||
className="absolute bottom-1/4 right-1/4 w-80 h-80 rounded-full blur-3xl pointer-events-none"
|
||
style={{ background: "rgba(139, 92, 246, 0.06)" }}
|
||
/>
|
||
|
||
{/* Card */}
|
||
<div
|
||
className="w-full max-w-sm relative z-10 rounded-2xl p-8"
|
||
style={{
|
||
background: "rgba(16, 16, 26, 0.85)",
|
||
border: "1px solid rgba(255,255,255,0.09)",
|
||
backdropFilter: "blur(24px)",
|
||
boxShadow:
|
||
"0 24px 64px rgba(0,0,0,0.5), 0 0 0 1px rgba(255,255,255,0.04) inset",
|
||
}}
|
||
>
|
||
{/* Logo / Header */}
|
||
<div className="text-center mb-8">
|
||
<div className="flex justify-center mb-5">
|
||
<div
|
||
className="w-12 h-12 rounded-2xl flex items-center justify-center relative"
|
||
style={{
|
||
background: "linear-gradient(135deg, #6366f1, #8b5cf6)",
|
||
boxShadow:
|
||
"0 0 32px rgba(99, 102, 241, 0.45), 0 0 0 1px rgba(255,255,255,0.12) inset",
|
||
}}
|
||
>
|
||
<span className="text-white font-black text-xl">A</span>
|
||
</div>
|
||
</div>
|
||
<h1
|
||
className="text-xl font-black tracking-wide mb-1"
|
||
style={{
|
||
background: "linear-gradient(135deg, #e4e4f0, #a78bfa)",
|
||
WebkitBackgroundClip: "text",
|
||
WebkitTextFillColor: "transparent",
|
||
backgroundClip: "text",
|
||
}}
|
||
>
|
||
AppAdmin
|
||
</h1>
|
||
<p className="text-xs font-medium" style={{ color: "rgba(255,255,255,0.3)" }}>
|
||
Yönetim paneline erişmek için giriş yapın
|
||
</p>
|
||
</div>
|
||
|
||
<form onSubmit={handleSubmit} className="space-y-4">
|
||
{/* Email */}
|
||
<div className="space-y-1.5">
|
||
<label
|
||
htmlFor="email"
|
||
className="block text-[11px] font-bold uppercase tracking-wider"
|
||
style={{ color: "rgba(255,255,255,0.35)" }}
|
||
>
|
||
E-posta
|
||
</label>
|
||
<div className="relative">
|
||
<Mail
|
||
size={14}
|
||
className="absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none"
|
||
style={{ color: "rgba(255,255,255,0.22)" }}
|
||
/>
|
||
<input
|
||
id="email"
|
||
name="email"
|
||
type="email"
|
||
autoComplete="email"
|
||
required
|
||
className="block w-full pl-9 pr-4 py-2.5 text-sm rounded-xl transition-all duration-200"
|
||
style={{
|
||
background: "rgba(255,255,255,0.05)",
|
||
border: "1px solid rgba(255,255,255,0.09)",
|
||
color: "rgba(255,255,255,0.85)",
|
||
outline: "none",
|
||
}}
|
||
placeholder="admin@admin.com"
|
||
onFocus={(e) => {
|
||
e.currentTarget.style.borderColor = "rgba(99, 102, 241, 0.5)";
|
||
e.currentTarget.style.background = "rgba(99, 102, 241, 0.06)";
|
||
}}
|
||
onBlur={(e) => {
|
||
e.currentTarget.style.borderColor = "rgba(255,255,255,0.09)";
|
||
e.currentTarget.style.background = "rgba(255,255,255,0.05)";
|
||
}}
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Password */}
|
||
<div className="space-y-1.5">
|
||
<label
|
||
htmlFor="password"
|
||
className="block text-[11px] font-bold uppercase tracking-wider"
|
||
style={{ color: "rgba(255,255,255,0.35)" }}
|
||
>
|
||
Şifre
|
||
</label>
|
||
<div className="relative">
|
||
<Lock
|
||
size={14}
|
||
className="absolute left-3 top-1/2 -translate-y-1/2 pointer-events-none"
|
||
style={{ color: "rgba(255,255,255,0.22)" }}
|
||
/>
|
||
<input
|
||
id="password"
|
||
name="password"
|
||
type="password"
|
||
autoComplete="current-password"
|
||
required
|
||
className="block w-full pl-9 pr-4 py-2.5 text-sm rounded-xl transition-all duration-200"
|
||
style={{
|
||
background: "rgba(255,255,255,0.05)",
|
||
border: "1px solid rgba(255,255,255,0.09)",
|
||
color: "rgba(255,255,255,0.85)",
|
||
outline: "none",
|
||
}}
|
||
placeholder="••••••••"
|
||
onFocus={(e) => {
|
||
e.currentTarget.style.borderColor = "rgba(99, 102, 241, 0.5)";
|
||
e.currentTarget.style.background = "rgba(99, 102, 241, 0.06)";
|
||
}}
|
||
onBlur={(e) => {
|
||
e.currentTarget.style.borderColor = "rgba(255,255,255,0.09)";
|
||
e.currentTarget.style.background = "rgba(255,255,255,0.05)";
|
||
}}
|
||
/>
|
||
</div>
|
||
</div>
|
||
|
||
{/* Error */}
|
||
{error && (
|
||
<div
|
||
className="flex items-center gap-2.5 p-3 rounded-xl text-xs font-medium"
|
||
style={{
|
||
background: "rgba(239, 68, 68, 0.08)",
|
||
border: "1px solid rgba(239, 68, 68, 0.2)",
|
||
color: "#f87171",
|
||
}}
|
||
>
|
||
<AlertCircle size={14} />
|
||
<span>{error}</span>
|
||
</div>
|
||
)}
|
||
|
||
{/* Submit */}
|
||
<button
|
||
type="submit"
|
||
disabled={loading}
|
||
className="relative w-full flex items-center justify-center gap-2 py-2.5 rounded-xl text-sm font-bold transition-all duration-200 mt-2 overflow-hidden group"
|
||
style={{
|
||
background: loading
|
||
? "rgba(99, 102, 241, 0.4)"
|
||
: "linear-gradient(135deg, #6366f1, #8b5cf6)",
|
||
color: "white",
|
||
boxShadow: loading
|
||
? "none"
|
||
: "0 0 24px rgba(99, 102, 241, 0.35)",
|
||
cursor: loading ? "not-allowed" : "pointer",
|
||
}}
|
||
>
|
||
{loading ? (
|
||
<>
|
||
<Loader2 size={15} className="animate-spin" />
|
||
<span>Giriş yapılıyor...</span>
|
||
</>
|
||
) : (
|
||
<>
|
||
<span>Giriş Yap</span>
|
||
<ArrowRight
|
||
size={15}
|
||
className="group-hover:translate-x-0.5 transition-transform duration-200"
|
||
/>
|
||
</>
|
||
)}
|
||
</button>
|
||
</form>
|
||
|
||
{/* Footer hint */}
|
||
<p
|
||
className="text-center text-[10px] mt-6"
|
||
style={{ color: "rgba(255,255,255,0.15)" }}
|
||
>
|
||
AppAdmin v1.0 · Yönetim Paneli
|
||
</p>
|
||
</div>
|
||
</div>
|
||
);
|
||
}
|