"use client"; import React, { useState, useEffect, useMemo } from "react"; import { JournalPost, MoodType } from "@/components/types"; import { MOODS } from "@/components/mockData"; import { EditPostModal } from "@/components/EditPostModal"; import { NewPostModal } from "@/components/NewPostModal"; import { PostDetailModal } from "@/components/PostDetailModal"; import { Lock, User, KeyRound, LogOut, Plus, Edit3, Trash2, Eye, Search, RefreshCw, ShieldCheck, BarChart2, FileText, Heart, Tag, CheckCircle, AlertCircle } from "lucide-react"; export default function AdminPage() { // Auth state const [isAuthenticated, setIsAuthenticated] = useState(false); const [checkingAuth, setCheckingAuth] = useState(true); const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [loginError, setLoginError] = useState(""); const [isLoggingIn, setIsLoggingIn] = useState(false); // Data state const [posts, setPosts] = useState([]); const [loadingPosts, setLoadingPosts] = useState(false); const [searchQuery, setSearchQuery] = useState(""); const [selectedMoodFilter, setSelectedMoodFilter] = useState("all"); // Modal states const [editingPost, setEditingPost] = useState(null); const [isNewPostOpen, setIsNewPostOpen] = useState(false); const [detailPost, setDetailPost] = useState(null); const [deletingId, setDeletingId] = useState(null); // Check auth status on mount useEffect(() => { async function checkAuth() { try { const res = await fetch("/api/admin/check"); if (res.ok) { const data = await res.json(); setIsAuthenticated(data.authenticated); } } catch (err) { console.error("Auth check failed:", err); } finally { setCheckingAuth(false); } } checkAuth(); }, []); // Fetch posts if authenticated const fetchPosts = async () => { setLoadingPosts(true); try { const res = await fetch("/api/posts"); if (res.ok) { const data = await res.json(); setPosts(data); } } catch (err) { console.error("Error fetching posts:", err); } finally { setLoadingPosts(false); } }; useEffect(() => { if (isAuthenticated) { fetchPosts(); } }, [isAuthenticated]); // Handle Login const handleLogin = async (e: React.FormEvent) => { e.preventDefault(); setLoginError(""); setIsLoggingIn(true); try { const res = await fetch("/api/admin/login", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ username, password }), }); const data = await res.json(); if (res.ok) { setIsAuthenticated(true); setUsername(""); setPassword(""); } else { setLoginError(data.error || "Giriş başarısız oldu"); } } catch (err) { setLoginError("Sunucuya bağlanılamadı"); } finally { setIsLoggingIn(false); } }; // Handle Logout const handleLogout = async () => { try { await fetch("/api/admin/logout", { method: "POST" }); setIsAuthenticated(false); } catch (err) { console.error("Logout failed:", err); } }; // Handle Add Post const handleAddPost = async (newPost: JournalPost) => { try { const res = await fetch("/api/posts", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(newPost), }); if (res.ok) { fetchPosts(); } } catch (err) { console.error("Error adding post:", err); } }; // Handle Update Post const handleUpdatePost = async (updatedPost: JournalPost) => { try { const res = await fetch(`/api/posts/${updatedPost.id}`, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(updatedPost), }); if (res.ok) { setPosts((prev) => prev.map((p) => (p.id === updatedPost.id ? updatedPost : p)) ); } } catch (err) { console.error("Error updating post:", err); } }; // Handle Delete Post const handleDeletePost = async (id: string) => { try { const res = await fetch(`/api/posts/${id}`, { method: "DELETE", }); if (res.ok) { setPosts((prev) => prev.filter((p) => p.id !== id)); setDeletingId(null); } } catch (err) { console.error("Error deleting post:", err); } }; // Filtered posts for admin table const filteredPosts = useMemo(() => { return posts.filter((post) => { if (selectedMoodFilter !== "all" && post.mood !== selectedMoodFilter) { return false; } if (searchQuery.trim()) { const q = searchQuery.toLowerCase(); const matchesContent = post.content.toLowerCase().includes(q); const matchesTitle = post.title?.toLowerCase().includes(q); const matchesTags = post.tags.some((t) => t.toLowerCase().includes(q)); return matchesContent || matchesTitle || matchesTags; } return true; }); }, [posts, selectedMoodFilter, searchQuery]); // Total likes counter const totalLikes = useMemo(() => { return posts.reduce((sum, p) => sum + (p.likes || 0), 0); }, [posts]); if (checkingAuth) { return (
Admin Yetkisi Kontrol Ediliyor...
); } // --- LOGIN VIEW --- if (!isAuthenticated) { return (
{/* Top Washi Tape */}
{/* Header */}
M ADM

Yönetici Girişi

mstfyldz journal • Defter Yönetim Paneli

{/* Error Banner */} {loginError && (
{loginError}
)} {/* Login Form */}
setUsername(e.target.value)} placeholder="admin" className="w-full pl-9 pr-3 py-2 text-sm bg-white/80 border border-[#18181B]/15 rounded-lg focus:outline-none focus:ring-2 focus:ring-[#E11D48]/30 font-mono" />
setPassword(e.target.value)} placeholder="••••••••" className="w-full pl-9 pr-3 py-2 text-sm bg-white/80 border border-[#18181B]/15 rounded-lg focus:outline-none focus:ring-2 focus:ring-[#E11D48]/30 font-mono" />

Giriş bilgileri .env içindeki ADMIN_USERNAME ve ADMIN_PASSWORD değişkenlerinden okunur.

); } // --- AUTHENTICATED DASHBOARD VIEW --- return (
{/* Top Admin Telemetry Header */}
M
mstfyldz admin YETKİLENDİRİLDİ
Siteye Git
{/* Main Admin Dashboard Content */}
{/* Metric Cards Overview */}
TOPLAM KARALAMA
{posts.length}
TOPLAM BEĞENİ
{totalLikes}
VERİTABANI DURUMU
PostgreSQL (65.109...)
{/* Controls & Search Bar */}

Not & Karalama Yönetimi

PostgreSQL veritabanındaki tüm notları görüntüleyin, güncelleyin veya yeni içerik girin.

{/* Search & Mood Filter Inputs */}
setSearchQuery(e.target.value)} placeholder="Başlık, içerik veya etiketlerde ara..." className="w-full pl-8 pr-3 py-1.5 text-xs bg-white border border-[#18181B]/15 rounded-lg focus:outline-none focus:ring-2 focus:ring-[#E11D48]/30 font-serif" />
{/* Data Table */}
{filteredPosts.length > 0 ? ( filteredPosts.map((post) => ( {/* Format Badge */} {/* Date */} {/* Mood */} {/* Title / Content Preview */} {/* Likes */} {/* Tags */} {/* Actions */} )) ) : ( )}
Format / Tür Tarih Mood Başlık / İçerik Beğeni Etiketler İşlemler
{post.type} {post.date} {post.moodLabel}
{post.title || "(Başlıksız Not)"}
{post.content}
♥ {post.likes}
{post.tags.map((t) => ( #{t} ))}
{deletingId === post.id ? (
) : ( )}
Filtrelerle eşleşen not bulunamadı.
{/* Modals */} setEditingPost(null)} onUpdatePost={handleUpdatePost} /> setIsNewPostOpen(false)} onAddPost={handleAddPost} /> setDetailPost(null)} onTagClick={() => {}} />
); }