"use client"; import { motion, AnimatePresence } from "framer-motion"; import { useState, useEffect } from "react"; import Link from "next/link"; import Header from "@/components/Header"; import type { Locale } from "@/i18n-config"; import { blogPosts, BlogPost } from "@/data/blog"; import { saveProject, deleteProject, saveBlogPost, deleteBlogPost, adminLogoutAction, savePartner, deletePartner } from "@/app/actions"; const expo = [0.16, 1, 0.3, 1] as [number, number, number, number]; interface ToastMsg { text: string; type: "success" | "info" | "alert"; } interface ProjectData { id?: number; num: string; slug: string; title: string; tag: string; desc: string; spec: string; year: string; client: string; duration: string; tech: string[]; challenge: string; solution: string; results: string[]; image: string; gallery?: string[]; website?: string; } interface PartnerData { id?: number; name: string; tag: string; mono: string; year: string; desc: string; } export default function AdminClient({ lang, dict, initialProjects = [], initialBlogPosts = [], initialPartners = [], }: { lang: Locale; dict: any; initialProjects?: ProjectData[]; initialBlogPosts?: BlogPost[]; initialPartners?: PartnerData[]; }) { const [activeTab, setActiveTab] = useState<"projeler" | "blog" | "partnerler" | "ayarlar">("projeler"); // Toast state const [toast, setToast] = useState(null); const showToast = (text: string, type: "success" | "info" | "alert" = "success") => { setToast({ text, type }); }; useEffect(() => { if (toast) { const t = setTimeout(() => setToast(null), 3000); return () => clearTimeout(t); } }, [toast]); // Project CRUD State const [projects, setProjects] = useState(initialProjects); const [searchQuery, setSearchQuery] = useState(""); const [editingProject, setEditingProject] = useState(null); const [isAddingNew, setIsAddingNew] = useState(false); // Edit / New Project Form State const [formTitle, setFormTitle] = useState(""); const [formTag, setFormTag] = useState(""); const [formDesc, setFormDesc] = useState(""); const [formSpec, setFormSpec] = useState(""); const [formYear, setFormYear] = useState(""); const [formClient, setFormClient] = useState(""); const [formDuration, setFormDuration] = useState(""); const [formTechString, setFormTechString] = useState(""); const [formChallenge, setFormChallenge] = useState(""); const [formSolution, setFormSolution] = useState(""); const [formResults, setFormResults] = useState([]); const [newResultItem, setNewResultItem] = useState(""); const [formImage, setFormImage] = useState(""); const [formGallery, setFormGallery] = useState([]); const [newGalleryItem, setNewGalleryItem] = useState(""); const [formWebsite, setFormWebsite] = useState(""); // Blog CRUD State const [posts, setPosts] = useState(initialBlogPosts); const [blogSearchQuery, setBlogSearchQuery] = useState(""); const [editingPost, setEditingPost] = useState(null); const [isAddingNewPost, setIsAddingNewPost] = useState(false); // Partner CRUD State const [partners, setPartners] = useState(initialPartners); const [partnerSearchQuery, setPartnerSearchQuery] = useState(""); const [editingPartner, setEditingPartner] = useState(null); const [isAddingNewPartner, setIsAddingNewPartner] = useState(false); // Edit / New Partner Form State const [formPartnerName, setFormPartnerName] = useState(""); const [formPartnerTag, setFormPartnerTag] = useState(""); const [formPartnerMono, setFormPartnerMono] = useState(""); const [formPartnerYear, setFormPartnerYear] = useState(""); const [formPartnerDesc, setFormPartnerDesc] = useState(""); // Blog Modal Form Sub-tabs ("genel" | "tr" | "en") const [blogFormSubTab, setBlogFormSubTab] = useState<"genel" | "tr" | "en">("genel"); const [formBlogSlug, setFormBlogSlug] = useState(""); const [formBlogDate, setFormBlogDate] = useState(""); const [formBlogAuthor, setFormBlogAuthor] = useState(""); const [formBlogAuthorRole, setFormBlogAuthorRole] = useState(""); const [formBlogImage, setFormBlogImage] = useState(""); const [formBlogTrTitle, setFormBlogTrTitle] = useState(""); const [formBlogTrExcerpt, setFormBlogTrExcerpt] = useState(""); const [formBlogTrReadingTime, setFormBlogTrReadingTime] = useState(""); const [formBlogTrCategory, setFormBlogTrCategory] = useState(""); const [formBlogTrTags, setFormBlogTrTags] = useState(""); const [formBlogTrContent, setFormBlogTrContent] = useState(""); const [formBlogEnTitle, setFormBlogEnTitle] = useState(""); const [formBlogEnExcerpt, setFormBlogEnExcerpt] = useState(""); const [formBlogEnReadingTime, setFormBlogEnReadingTime] = useState(""); const [formBlogEnCategory, setFormBlogEnCategory] = useState(""); const [formBlogEnTags, setFormBlogEnTags] = useState(""); const [formBlogEnContent, setFormBlogEnContent] = useState(""); // Site Settings Form State const [brandName, setBrandName] = useState(dict.nav.brandName || "Ayris"); const [brandSub, setBrandSub] = useState(dict.nav.brandSub || "Tech"); const [heroBadge, setHeroBadge] = useState(dict.hero.badge || "Ayris Tech — Mühendislik Zirvesi"); const [heroTitle1, setHeroTitle1] = useState(dict.hero.titleLine1 || "Geleceği"); const [heroTitle2, setHeroTitle2] = useState(dict.hero.titleLine2 || "İnşa Ediyoruz"); const [heroDesc, setHeroDesc] = useState(dict.hero.desc || ""); const [telemetryEmail, setTelemetryEmail] = useState("info@ayristech.com"); const [telemetryHub, setTelemetryHub] = useState(dict.contact.infoBaseText || "İstanbul, Türkiye"); // Open modal for project editing const handleStartEdit = (p: ProjectData) => { setEditingProject(p); setIsAddingNew(false); setFormTitle(p.title); setFormTag(p.tag); setFormDesc(p.desc); setFormSpec(p.spec); setFormYear(p.year); setFormClient(p.client); setFormDuration(p.duration); setFormTechString(p.tech.join(", ")); setFormChallenge(p.challenge); setFormSolution(p.solution); setFormResults([...p.results]); setNewResultItem(""); setFormImage(p.image || ""); setFormGallery(p.gallery ? [...p.gallery] : []); setNewGalleryItem(""); setFormWebsite(p.website || ""); }; // Open modal for project adding const handleStartAdd = () => { setEditingProject(null); setIsAddingNew(true); setFormTitle(""); setFormTag(""); setFormDesc(""); setFormSpec(""); setFormYear("2026"); setFormClient(""); setFormDuration(""); setFormTechString(""); setFormChallenge(""); setFormSolution(""); setFormResults([]); setNewResultItem(""); setFormImage(""); setFormGallery([]); setNewGalleryItem(""); setFormWebsite(""); }; // Save project const handleSaveProject = async (e: React.FormEvent) => { e.preventDefault(); if (!formTitle.trim()) { showToast("Proje başlığı boş bırakılamaz!", "alert"); return; } const techArray = formTechString.split(",").map(t => t.trim()).filter(Boolean); const slugValue = formTitle.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, ""); const nextNum = isAddingNew ? (projects.length > 0 ? String(Math.max(...projects.map(p => parseInt(p.num, 10))) + 1).padStart(2, '0') : "01") : editingProject!.num; const projectDataToSave = { id: editingProject?.id, num: nextNum, slug: slugValue, title: formTitle, tag: formTag || "Web · Yapay Zekâ", desc: formDesc, spec: formSpec, year: formYear, client: formClient, duration: formDuration, tech: techArray, challenge: formChallenge, solution: formSolution, results: formResults.length > 0 ? formResults : ["Proje başarıyla tamamlandı"], image: formImage, gallery: formGallery, website: formWebsite, }; const res = await saveProject(projectDataToSave); if (res.success && res.project) { if (isAddingNew) { setProjects([...projects, { ...projectDataToSave, id: res.project.id }]); showToast(`[ YENİ PROJE YARATILDI // ${formTitle.toUpperCase()} ]`, "success"); setIsAddingNew(false); } else { const updatedList = projects.map(p => { if (p.id === editingProject?.id) { return { ...p, ...projectDataToSave, }; } return p; }); setProjects(updatedList); showToast(`[ PROJE BAŞARIYLA DÜZENLENDİ // ${formTitle.toUpperCase()} ]`, "success"); setEditingProject(null); } } else { showToast(`Hata: ${res.error}`, "alert"); } }; // Delete project const handleDeleteProject = async (id: number, title: string) => { if (confirm(`"${title}" projesini silmek istediğinize emin misiniz?`)) { const res = await deleteProject(id); if (res.success) { setProjects(projects.filter(p => p.id !== id)); showToast(`[ PROJE SİLİNDİ // ${title.toUpperCase()} ]`, "alert"); } else { showToast(`Hata: ${res.error}`, "alert"); } } }; // Add list result item const handleAddResultItem = () => { if (newResultItem.trim()) { setFormResults([...formResults, newResultItem.trim()]); setNewResultItem(""); } }; // Remove list result item const handleRemoveResultItem = (idx: number) => { setFormResults(formResults.filter((_, i) => i !== idx)); }; // Add gallery item const handleAddGalleryItem = () => { if (newGalleryItem.trim()) { setFormGallery([...formGallery, newGalleryItem.trim()]); setNewGalleryItem(""); } }; // Remove gallery item const handleRemoveGalleryItem = (idx: number) => { setFormGallery(formGallery.filter((_, i) => i !== idx)); }; // ── BLOG HANDLERS ── // Open modal for blog editing const handleStartEditPost = (post: BlogPost) => { setEditingPost(post); setIsAddingNewPost(false); setBlogFormSubTab("genel"); setFormBlogSlug(post.slug); setFormBlogDate(post.date); setFormBlogAuthor(post.author); setFormBlogAuthorRole(post.authorRole); setFormBlogImage(post.image); setFormBlogTrTitle(post.tr.title); setFormBlogTrExcerpt(post.tr.excerpt); setFormBlogTrReadingTime(post.tr.readingTime); setFormBlogTrCategory(post.tr.category); setFormBlogTrTags(post.tr.tags.join(", ")); setFormBlogTrContent(post.tr.content); setFormBlogEnTitle(post.en.title); setFormBlogEnExcerpt(post.en.excerpt); setFormBlogEnReadingTime(post.en.readingTime); setFormBlogEnCategory(post.en.category); setFormBlogEnTags(post.en.tags.join(", ")); setFormBlogEnContent(post.en.content); }; // Open modal for blog adding const handleStartAddPost = () => { setEditingPost(null); setIsAddingNewPost(true); setBlogFormSubTab("genel"); setFormBlogSlug(""); setFormBlogDate(new Date().toISOString().split('T')[0]); setFormBlogAuthor("Mustafa Yıldız"); setFormBlogAuthorRole("Founder & Architect"); setFormBlogImage(""); setFormBlogTrTitle(""); setFormBlogTrExcerpt(""); setFormBlogTrReadingTime("5 dk okuma"); setFormBlogTrCategory("Teknoloji"); setFormBlogTrTags("AI, Web"); setFormBlogTrContent(""); setFormBlogEnTitle(""); setFormBlogEnExcerpt(""); setFormBlogEnReadingTime("5 min read"); setFormBlogEnCategory("Technology"); setFormBlogEnTags("AI, Web"); setFormBlogEnContent(""); }; // Save Blog Post const handleSavePost = async (e: React.FormEvent) => { e.preventDefault(); if (!formBlogTrTitle.trim()) { showToast("Türkçe blog başlığı zorunludur!", "alert"); return; } const calculatedSlug = formBlogSlug.trim() || formBlogTrTitle.toLowerCase().replace(/[^a-z0-9]+/g, "-").replace(/(^-|-$)/g, ""); const blogPostDataToSave = { id: editingPost?.id, slug: calculatedSlug, date: formBlogDate || new Date().toISOString().split('T')[0], author: formBlogAuthor || "Ayris Council", authorRole: formBlogAuthorRole || "Chief Engineer", image: formBlogImage || "https://images.unsplash.com/photo-1504384308090-c894fdcc538d?auto=format&fit=crop&w=1200&q=80", trTitle: formBlogTrTitle, trExcerpt: formBlogTrExcerpt, trReadingTime: formBlogTrReadingTime || "5 dk okuma", trCategory: formBlogTrCategory || "Teknoloji", trTags: formBlogTrTags.split(",").map(t => t.trim()).filter(Boolean), trContent: formBlogTrContent || "## Yeni Teknik Blok Başlığı\nİçerik buraya gelecektir.", enTitle: formBlogEnTitle || formBlogTrTitle, enExcerpt: formBlogEnExcerpt || formBlogTrExcerpt, enReadingTime: formBlogEnReadingTime || "5 min read", enCategory: formBlogEnCategory || "Technology", enTags: formBlogEnTags.split(",").map(t => t.trim()).filter(Boolean), enContent: formBlogEnContent || "## New Technical Article\nContent goes here.", }; const res = await saveBlogPost(blogPostDataToSave); if (res.success && res.post) { const mappedPost: BlogPost = { id: res.post.id, slug: res.post.slug, date: res.post.date, author: res.post.author, authorRole: res.post.authorRole, image: res.post.image, tr: { title: res.post.trTitle, excerpt: res.post.trExcerpt, readingTime: res.post.trReadingTime, category: res.post.trCategory, tags: res.post.trTags, content: res.post.trContent, }, en: { title: res.post.enTitle, excerpt: res.post.enExcerpt, readingTime: res.post.enReadingTime, category: res.post.enCategory, tags: res.post.enTags, content: res.post.enContent, } }; if (isAddingNewPost) { setPosts([...posts, mappedPost]); showToast(`[ BLOG YAZISI EKLEDİ // ${mappedPost.tr.title.toUpperCase()} ]`, "success"); setIsAddingNewPost(false); } else { setPosts(posts.map(p => p.id === editingPost?.id ? mappedPost : p)); showToast(`[ BLOG YAZISI GÜNCELLEDİ // ${mappedPost.tr.title.toUpperCase()} ]`, "success"); setEditingPost(null); } } else { showToast(`Hata: ${res.error}`, "alert"); } }; // Delete Blog Post const handleDeletePost = async (id: number, title: string) => { if (confirm(`"${title}" blog yazısını silmek istediğinize emin misiniz?`)) { const res = await deleteBlogPost(id); if (res.success) { setPosts(posts.filter(p => p.id !== id)); showToast(`[ BLOG YAZISI SİLİNDİ // ${title.toUpperCase()} ]`, "alert"); } else { showToast(`Hata: ${res.error}`, "alert"); } } }; // ── PARTNER CRUD ACTIONS ── const handleStartEditPartner = (p: PartnerData) => { setEditingPartner(p); setIsAddingNewPartner(false); setFormPartnerName(p.name); setFormPartnerTag(p.tag); setFormPartnerMono(p.mono); setFormPartnerYear(p.year); setFormPartnerDesc(p.desc); }; const handleStartAddPartner = () => { setEditingPartner(null); setIsAddingNewPartner(true); setFormPartnerName(""); setFormPartnerTag(""); setFormPartnerMono(""); setFormPartnerYear("2026"); setFormPartnerDesc(""); }; const handleSavePartner = async (e: React.FormEvent) => { e.preventDefault(); if (!formPartnerName.trim() || !formPartnerMono.trim()) { showToast("Partner ismi ve monogramı zorunludur!", "alert"); return; } const partnerDataToSave = { id: editingPartner?.id, name: formPartnerName.trim(), tag: formPartnerTag.trim() || "Web3", mono: formPartnerMono.trim().toUpperCase(), year: formPartnerYear.trim() || "2026", desc: formPartnerDesc.trim(), }; const res = await savePartner(partnerDataToSave); if (res.success && res.partner) { if (isAddingNewPartner) { setPartners([...partners, { ...partnerDataToSave, id: res.partner.id }]); showToast(`[ YENİ PARTNER YARATILDI // ${formPartnerName.toUpperCase()} ]`, "success"); setIsAddingNewPartner(false); } else { const updatedList = partners.map(p => { if (p.id === editingPartner?.id) { return { ...p, ...partnerDataToSave, }; } return p; }); setPartners(updatedList); showToast(`[ PARTNER BAŞARIYLA DÜZENLENDİ // ${formPartnerName.toUpperCase()} ]`, "success"); setEditingPartner(null); } } else { showToast(`Hata: ${res.error}`, "alert"); } }; const handleDeletePartner = async (id: number, name: string) => { if (confirm(`"${name}" iş ortağını silmek istediğinize emin misiniz?`)) { const res = await deletePartner(id); if (res.success) { setPartners(partners.filter(p => p.id !== id)); showToast(`[ PARTNER SİLİNDİ // ${name.toUpperCase()} ]`, "alert"); } else { showToast(`Hata: ${res.error}`, "alert"); } } }; // Save Settings Form const handleSaveSettings = (e: React.FormEvent) => { e.preventDefault(); showToast("[ SİTE AYARLARI BAŞARIYLA KAYDEDİLDİ VE YENİLENDİ ]", "success"); }; // Logout Handler const handleLogout = async () => { if (confirm("Sistemden çıkış yapmak istediğinize emin misiniz?")) { const res = await adminLogoutAction(); if (res.success) { window.location.href = `/${lang}/admin/login`; } else { showToast("Çıkış yapılırken bir hata oluştu!", "alert"); } } }; // Filters const filteredProjects = projects.filter(p => p.title.toLowerCase().includes(searchQuery.toLowerCase()) || p.tag.toLowerCase().includes(searchQuery.toLowerCase()) ); const filteredPosts = posts.filter(post => post.tr.title.toLowerCase().includes(blogSearchQuery.toLowerCase()) || post.author.toLowerCase().includes(blogSearchQuery.toLowerCase()) || post.tr.category.toLowerCase().includes(blogSearchQuery.toLowerCase()) ); const filteredPartners = partners.filter(p => p.name.toLowerCase().includes(partnerSearchQuery.toLowerCase()) || p.tag.toLowerCase().includes(partnerSearchQuery.toLowerCase()) || p.mono.toLowerCase().includes(partnerSearchQuery.toLowerCase()) ); return (
{/* LEFT NAV PANEL - Brutalist Sidebar */} {/* RIGHT MAIN PANEL - Dashboard workspace */}
{/* TAB 1: PROJELER */} {activeTab === "projeler" && (
setSearchQuery(e.target.value)} className="w-full font-mono text-[11px] bg-[#F4F0E8] border border-[#C8C2B8] focus:border-[#0A0A0A] outline-none px-4 py-3 placeholder-[#A0998E] text-[#0A0A0A] transition-colors" />
{filteredProjects.map((p) => (
PROJE // 0{p.num} {p.tag}

{p.title}

{p.tech.map((t) => ( {t} ))}
))} {filteredProjects.length === 0 && (

[ HİÇBİR PROJE BULUNAMADI ]

)}
)} {/* TAB 2: BLOG YAZILARI YÖNETİMİ */} {activeTab === "blog" && (
setBlogSearchQuery(e.target.value)} className="w-full font-mono text-[11px] bg-[#F4F0E8] border border-[#C8C2B8] focus:border-[#0A0A0A] outline-none px-4 py-3 placeholder-[#A0998E] text-[#0A0A0A] transition-colors" />
{filteredPosts.map((post) => (
SLUG: {post.slug} {post.tr.category}

{post.tr.title}

Yazar: {post.author} ({post.authorRole}) • Tarih: {post.date}

))} {filteredPosts.length === 0 && (

[ HİÇBİR BLOG YAZISI BULUNAMADI ]

)}
)} {/* TAB 2.5: PARTNERLER YÖNETİMİ */} {activeTab === "partnerler" && (
setPartnerSearchQuery(e.target.value)} className="w-full font-mono text-[11px] bg-[#F4F0E8] border border-[#C8C2B8] focus:border-[#0A0A0A] outline-none px-4 py-3 placeholder-[#A0998E] text-[#0A0A0A] transition-colors" />
{filteredPartners.map((p) => (
MONOGRAM: {p.mono} {p.tag} YIL: {p.year}

{p.name}

{p.desc}

))} {filteredPartners.length === 0 && (

[ HİÇBİR PARTNER BULUNAMADI ]

)}
)} {/* TAB 3: SITE AYARLARI */} {activeTab === "ayarlar" && (

⚙️ SİTE GENEL YAPILANDIRMASI

Görsel kimlik, başlıklar ve iletişim kanallarının yönetimi.

setBrandName(e.target.value)} className="w-full font-mono text-[12px] bg-[#EDE8E0] border border-[#C8C2B8] focus:border-[#0A0A0A] outline-none px-4 py-3 text-[#0A0A0A]" />
setBrandSub(e.target.value)} className="w-full font-mono text-[12px] bg-[#EDE8E0] border border-[#C8C2B8] focus:border-[#0A0A0A] outline-none px-4 py-3 text-[#0A0A0A]" />
setHeroBadge(e.target.value)} className="w-full font-mono text-[12px] bg-[#EDE8E0] border border-[#C8C2B8] focus:border-[#0A0A0A] outline-none px-4 py-3 text-[#0A0A0A]" />
setHeroTitle1(e.target.value)} className="w-full font-mono text-[12px] bg-[#EDE8E0] border border-[#C8C2B8] focus:border-[#0A0A0A] outline-none px-4 py-3 text-[#0A0A0A]" />
setHeroTitle2(e.target.value)} className="w-full font-mono text-[12px] bg-[#EDE8E0] border border-[#C8C2B8] focus:border-[#0A0A0A] outline-none px-4 py-3 text-[#0A0A0A]" />