Files
ayristech_new/app/[lang]/admin/login/page.tsx
T
2026-05-30 18:23:21 +03:00

174 lines
7.1 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 * as React from "react";
import { useState } from "react";
import { useRouter } from "next/navigation";
import { motion, AnimatePresence } from "framer-motion";
import { adminLoginAction } from "@/app/actions";
import Link from "next/link";
const expo = [0.16, 1, 0.3, 1] as [number, number, number, number];
interface Props {
params: Promise<{ lang: string }>;
}
export default function AdminLoginPage({ params }: Props) {
const router = useRouter();
// Unpack params Promise natively using React 19 use() hook
const { lang } = React.use(params);
const [username, setUsername] = useState("");
const [password, setPassword] = useState("");
const [loading, setLoading] = useState(false);
const [error, setError] = useState<string | null>(null);
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
if (!username.trim() || !password.trim()) {
setError("Kullanıcı adı ve şifre zorunludur!");
return;
}
setLoading(true);
setError(null);
const res = await adminLoginAction({ username: username.trim(), password: password.trim() });
if (res.success) {
router.push(`/${lang}/admin`);
} else {
setError(res.error || "Giriş başarısız!");
setLoading(false);
}
};
return (
<div className="bg-[#F4F0E8] text-[#0A0A0A] font-body min-h-screen flex items-center justify-center p-6 relative overflow-hidden">
{/* Dynamic Background Pattern */}
<div
className="absolute inset-0 opacity-[0.03] pointer-events-none select-none"
style={{
backgroundImage: "radial-gradient(#000 1px, transparent 1px)",
backgroundSize: "20px 20px"
}}
/>
{/* Decorative Floating Block */}
<div className="absolute top-1/4 left-1/4 w-32 h-32 bg-[#FFE600] opacity-10 blur-2xl rounded-full pointer-events-none" />
<div className="absolute bottom-1/4 right-1/4 w-48 h-48 bg-[#FF4500] opacity-5 blur-3xl rounded-full pointer-events-none" />
<main className="relative z-10 w-full max-w-md">
{/* Back to Home Link */}
<div className="mb-6 flex justify-start">
<Link
href={`/${lang}`}
className="inline-flex items-center gap-2 font-mono text-[10px] tracking-[0.25em] uppercase text-[#A0998E] hover:text-[#0A0A0A] transition-colors"
>
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2.5" strokeLinecap="round" strokeLinejoin="round">
<line x1="19" y1="12" x2="5" y2="12" />
<polyline points="12 19 5 12 12 5" />
</svg>
ANA SAYFAYA DÖN
</Link>
</div>
<motion.div
initial={{ opacity: 0, y: 30 }}
animate={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8, ease: expo }}
className="bg-[#F4F0E8] border-2 border-[#0A0A0A] p-10 relative shadow-[8px_8px_0px_0px_#0A0A0A]"
>
{/* Accent Ribbon */}
<div className="absolute top-0 left-0 right-0 h-2 bg-[#FFE600]" />
{/* Logo Monogram */}
<div className="w-16 h-16 border-2 border-[#0A0A0A] bg-[#FFE600] text-[#0A0A0A] font-display font-black text-xl flex items-center justify-center select-none mx-auto mb-8 shadow-[4px_4px_0px_0px_#0A0A0A]">
AYR
</div>
<div className="text-center mb-8">
<h1 className="font-display font-black text-3xl uppercase tracking-tight text-[#0A0A0A] mb-2 leading-none">
YÖNETİCİ GİRİŞİ
</h1>
<p className="font-mono text-[9px] uppercase tracking-[0.2em] text-[#A0998E]">
AYRİS TECH YÖNETİM MERKEZİ
</p>
</div>
<form onSubmit={handleSubmit} className="space-y-6">
{/* Error Message */}
<AnimatePresence mode="wait">
{error && (
<motion.div
initial={{ opacity: 0, x: -10 }}
animate={{ opacity: 1, x: 0 }}
exit={{ opacity: 0, x: 10 }}
className="bg-[#FFF0F0] border border-[#FF4500] text-[#FF4500] p-4 font-mono text-[10px] tracking-wide uppercase flex items-center gap-3"
>
<div className="w-2.5 h-2.5 bg-[#FF4500] shrink-0 animate-ping" />
<span className="flex-grow">{error}</span>
</motion.div>
)}
</AnimatePresence>
{/* Username Input */}
<div className="space-y-2">
<label className="block font-mono text-[9px] uppercase tracking-[0.2em] text-[#6A6460]">
KULLANICI ADI
</label>
<input
type="text"
required
value={username}
onChange={(e) => setUsername(e.target.value)}
disabled={loading}
className="w-full font-mono text-xs bg-[#EDE8E0] border border-[#C8C2B8] hover:border-[#0A0A0A] focus:border-[#0A0A0A] focus:bg-[#EDE8E0] outline-none px-4 py-3.5 text-[#0A0A0A] transition-all"
placeholder="Örn: admin"
/>
</div>
{/* Password Input */}
<div className="space-y-2">
<label className="block font-mono text-[9px] uppercase tracking-[0.2em] text-[#6A6460]">
ŞİFRE
</label>
<input
type="password"
required
value={password}
onChange={(e) => setPassword(e.target.value)}
disabled={loading}
className="w-full font-mono text-xs bg-[#EDE8E0] border border-[#C8C2B8] hover:border-[#0A0A0A] focus:border-[#0A0A0A] focus:bg-[#EDE8E0] outline-none px-4 py-3.5 text-[#0A0A0A] transition-all"
placeholder="••••••••"
/>
</div>
{/* Submit Button */}
<button
type="submit"
disabled={loading}
className="w-full border-2 border-[#0A0A0A] bg-[#FFE600] hover:bg-[#FFE600] text-[#0A0A0A] py-4 font-display font-black text-xs tracking-[0.2em] uppercase transition-all shadow-[4px_4px_0px_0px_#0A0A0A] hover:shadow-[2px_2px_0px_0px_#0A0A0A] hover:translate-x-[2px] hover:translate-y-[2px] active:translate-x-[4px] active:translate-y-[4px] active:shadow-none cursor-pointer flex items-center justify-center gap-2"
>
{loading ? (
<>
<div className="w-3.5 h-3.5 border-2 border-[#0A0A0A] border-t-transparent rounded-full animate-spin shrink-0" />
BAĞLANIYOR...
</>
) : (
"SİSTEME GİRİŞ YAP"
)}
</button>
</form>
{/* Decorative Security Footer */}
<div className="mt-8 pt-6 border-t border-[#C8C2B8] flex justify-between items-center text-[#A0998E] font-mono text-[8px] tracking-widest uppercase">
<span>SECURE SHELL v2.4</span>
<span className="text-[#00CC77] font-bold"> ONLINE</span>
</div>
</motion.div>
</main>
</div>
);
}