last
This commit is contained in:
@@ -2,9 +2,9 @@
|
||||
<html lang="en">
|
||||
<head>
|
||||
<meta charset="UTF-8" />
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<link rel="icon" type="image/png" href="/logo.png" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>atakan-portal</title>
|
||||
<title>Atakan</title>
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
BIN
public/logo.png
Normal file
BIN
public/logo.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 20 KiB |
@@ -4,16 +4,10 @@ import { useNavigate } from 'react-router-dom';
|
||||
import {
|
||||
Terminal, Globe, Shield, Database,
|
||||
Github, Twitter, Linkedin, Mail, Lock, X, ChevronRight, ExternalLink,
|
||||
Coffee, Zap, Smartphone, Layers, Box, Server
|
||||
Coffee, Zap, Smartphone, Layers, Box, Server, Loader2 // Loader2 eklendi
|
||||
} from 'lucide-react';
|
||||
|
||||
// --- KULLANICI ADI VE ŞİFRE AYARLARI ---
|
||||
const AUTH_CONFIG = {
|
||||
username: "atakanzgn",
|
||||
password: "atakanc123"
|
||||
};
|
||||
|
||||
// --- YETENEKLER (Güncellendi) ---
|
||||
// --- YETENEKLER ---
|
||||
const skills = [
|
||||
{ name: "Java", icon: <Coffee size={20} />, desc: "Core & Enterprise" },
|
||||
{ name: "Spring Boot", icon: <Zap size={20} />, desc: "Microservices" },
|
||||
@@ -50,16 +44,49 @@ export default function Home() {
|
||||
const [isModalOpen, setIsModalOpen] = useState(false);
|
||||
const [username, setUsername] = useState("");
|
||||
const [password, setPassword] = useState("");
|
||||
|
||||
// Yeni State'ler
|
||||
const [error, setError] = useState("");
|
||||
const [isLoading, setIsLoading] = useState(false);
|
||||
|
||||
const navigate = useNavigate();
|
||||
|
||||
const handleLogin = (e) => {
|
||||
const API_URL = "https://api.atakanzgn.com.tr/login";
|
||||
|
||||
const handleLogin = async (e) => {
|
||||
e.preventDefault();
|
||||
if (username === AUTH_CONFIG.username && password === AUTH_CONFIG.password) {
|
||||
sessionStorage.setItem('isAuthenticated', 'true');
|
||||
navigate('/portal');
|
||||
} else {
|
||||
setError("Hatalı kullanıcı adı veya şifre!");
|
||||
setError("");
|
||||
setIsLoading(true);
|
||||
|
||||
try {
|
||||
const response = await fetch(API_URL, {
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'Content-Type': 'application/json',
|
||||
},
|
||||
body: JSON.stringify({
|
||||
username: username,
|
||||
password: password
|
||||
}),
|
||||
});
|
||||
|
||||
const data = await response.json();
|
||||
|
||||
if (response.ok) {
|
||||
// Başarılı giriş: Token'ı sakla
|
||||
// Backend'den { token: "..." } veya { accessToken: "..." } döndüğünü varsayıyoruz.
|
||||
sessionStorage.setItem('authToken', data.token || data.accessToken);
|
||||
sessionStorage.setItem('user', JSON.stringify(data.user)); // Opsiyonel: Kullanıcı bilgisini sakla
|
||||
navigate('/portal');
|
||||
} else {
|
||||
// Backend'den gelen hata mesajını göster
|
||||
setError(data.message || "Giriş başarısız. Bilgileri kontrol edin.");
|
||||
}
|
||||
} catch (err) {
|
||||
console.error("Login hatası:", err);
|
||||
setError("Sunucuya bağlanılamadı. Lütfen daha sonra tekrar deneyin.");
|
||||
} finally {
|
||||
setIsLoading(false);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -99,7 +126,6 @@ export default function Home() {
|
||||
{/* --- HERO BÖLÜMÜ --- */}
|
||||
<section className="relative pt-40 pb-20 px-6 flex flex-col items-center justify-center text-center min-h-screen">
|
||||
<div className="absolute inset-0 bg-[url('https://grainy-gradients.vercel.app/noise.svg')] opacity-20 brightness-100 pointer-events-none"></div>
|
||||
{/* Renkleri Java/Backend temasına uygun (Turuncu/Kırmızı) güncelledim */}
|
||||
<div className="absolute top-1/3 left-1/4 w-96 h-96 bg-orange-600/20 rounded-full blur-[100px] -z-10"></div>
|
||||
<div className="absolute bottom-1/4 right-1/4 w-96 h-96 bg-red-600/20 rounded-full blur-[100px] -z-10"></div>
|
||||
|
||||
@@ -124,7 +150,7 @@ export default function Home() {
|
||||
</motion.div>
|
||||
</section>
|
||||
|
||||
{/* --- HAKKIMDA (Güncellendi) --- */}
|
||||
{/* --- HAKKIMDA --- */}
|
||||
<section id="about" className="py-20 px-6 bg-slate-900/50">
|
||||
<div className="max-w-4xl mx-auto">
|
||||
<h2 className="text-3xl font-bold text-white mb-8 flex items-center gap-3">
|
||||
@@ -144,7 +170,7 @@ export default function Home() {
|
||||
</div>
|
||||
</section>
|
||||
|
||||
{/* --- YETENEKLER (Güncellendi) --- */}
|
||||
{/* --- YETENEKLER --- */}
|
||||
<section id="skills" className="py-20 px-6">
|
||||
<div className="max-w-6xl mx-auto">
|
||||
<h2 className="text-3xl font-bold text-white mb-12 text-center">Teknik Yetkinlikler</h2>
|
||||
@@ -240,25 +266,35 @@ export default function Home() {
|
||||
<label className="block text-xs font-medium text-slate-400 mb-1">Kullanıcı Adı</label>
|
||||
<input
|
||||
type="text"
|
||||
className="w-full bg-slate-800 border border-slate-700 rounded-lg p-2.5 text-white focus:outline-none focus:border-orange-500 transition-colors"
|
||||
className="w-full bg-slate-800 border border-slate-700 rounded-lg p-2.5 text-white focus:outline-none focus:border-orange-500 transition-colors disabled:opacity-50"
|
||||
value={username}
|
||||
onChange={(e) => setUsername(e.target.value)}
|
||||
disabled={isLoading}
|
||||
/>
|
||||
</div>
|
||||
<div>
|
||||
<label className="block text-xs font-medium text-slate-400 mb-1">Şifre</label>
|
||||
<input
|
||||
type="password"
|
||||
className="w-full bg-slate-800 border border-slate-700 rounded-lg p-2.5 text-white focus:outline-none focus:border-orange-500 transition-colors"
|
||||
className="w-full bg-slate-800 border border-slate-700 rounded-lg p-2.5 text-white focus:outline-none focus:border-orange-500 transition-colors disabled:opacity-50"
|
||||
value={password}
|
||||
onChange={(e) => setPassword(e.target.value)}
|
||||
disabled={isLoading}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{error && <p className="text-red-400 text-xs">{error}</p>}
|
||||
|
||||
<button type="submit" className="w-full bg-orange-600 hover:bg-orange-700 text-white font-medium py-2.5 rounded-lg transition-colors flex justify-center items-center gap-2">
|
||||
Giriş Yap <ChevronRight size={16} />
|
||||
<button
|
||||
type="submit"
|
||||
disabled={isLoading}
|
||||
className="w-full bg-orange-600 hover:bg-orange-700 disabled:bg-slate-700 disabled:cursor-not-allowed text-white font-medium py-2.5 rounded-lg transition-colors flex justify-center items-center gap-2"
|
||||
>
|
||||
{isLoading ? (
|
||||
<><Loader2 className="animate-spin" size={16} /> Giriş Yapılıyor...</>
|
||||
) : (
|
||||
<><span className='mr-1'>Giriş Yap</span> <ChevronRight size={16} /></>
|
||||
)}
|
||||
</button>
|
||||
</form>
|
||||
</motion.div>
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import React, { useEffect } from 'react';
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import { motion } from 'framer-motion';
|
||||
import { GitBranch, Video, Mail, Cloud, Puzzle, ArrowRight, ArrowLeft, LogOut } from 'lucide-react';
|
||||
import { Link, useNavigate } from 'react-router-dom';
|
||||
@@ -23,17 +23,31 @@ const cardVariants = {
|
||||
|
||||
export default function Portal() {
|
||||
const navigate = useNavigate();
|
||||
// Kullanıcı adını state'ten veya storage'dan alalım
|
||||
const [user, setUser] = useState({ name: "Atakan" });
|
||||
|
||||
// Sayfa yüklendiğinde güvenlik kontrolü yap
|
||||
useEffect(() => {
|
||||
const isAuth = sessionStorage.getItem('isAuthenticated');
|
||||
if (isAuth !== 'true') {
|
||||
navigate('/'); // Giriş yoksa ana sayfaya at
|
||||
// Backend'den aldığımız token'ı kontrol ediyoruz
|
||||
const token = sessionStorage.getItem('authToken');
|
||||
const userData = sessionStorage.getItem('user');
|
||||
|
||||
if (!token) {
|
||||
navigate('/'); // Token yoksa ana sayfaya at
|
||||
}
|
||||
|
||||
if (userData) {
|
||||
try {
|
||||
setUser(JSON.parse(userData));
|
||||
} catch (e) {
|
||||
// JSON parse hatası olursa varsayılan kalır
|
||||
}
|
||||
}
|
||||
}, [navigate]);
|
||||
|
||||
const handleLogout = () => {
|
||||
sessionStorage.removeItem('isAuthenticated');
|
||||
sessionStorage.removeItem('authToken');
|
||||
sessionStorage.removeItem('user');
|
||||
navigate('/');
|
||||
};
|
||||
|
||||
@@ -54,7 +68,8 @@ export default function Portal() {
|
||||
|
||||
<motion.div initial={{ opacity: 0, y: -20 }} animate={{ opacity: 1, y: 0 }} className="text-center mb-12">
|
||||
<h1 className="text-4xl md:text-5xl font-bold mb-2 text-white">Yönetim Portalı</h1>
|
||||
<p className="text-slate-400">Hoş geldin, Atakan. Servisler aktif.</p>
|
||||
{/* Kullanıcı adını dinamik gösterelim */}
|
||||
<p className="text-slate-400">Hoş geldin, {user.username || user.name || "Admin"}. Servisler aktif.</p>
|
||||
</motion.div>
|
||||
|
||||
<motion.div variants={containerVariants} initial="hidden" animate="visible" className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-5">
|
||||
|
||||
Reference in New Issue
Block a user