"use client"; import React, { useState, useEffect } from "react"; import { Lock, LogOut, Plus, Edit, Trash2, ExternalLink, Sparkles, Terminal, Gamepad2, FlaskConical, Search, CheckCircle, AlertCircle, Database, ArrowLeft, X, RefreshCw, } from "lucide-react"; interface ProjectItem { id: string; title: string; category: "software" | "games" | "lab"; categoryLabel: string; tagline: string; status: string; statusType: "active" | "alpha" | "prototype" | "upcoming"; releaseTarget: string; description: string; longDescription: string; features: string[]; stack: string[]; accentGradient: string; borderGlow: string; iconName: string; orderIndex?: number; } export default function AdminPage() { const [isAuthenticated, setIsAuthenticated] = useState(null); const [username, setUsername] = useState(""); const [password, setPassword] = useState(""); const [loginError, setLoginError] = useState(""); const [loginLoading, setLoginLoading] = useState(false); // Dashboard state const [projects, setProjects] = useState([]); const [loadingProjects, setLoadingProjects] = useState(false); const [searchQuery, setSearchQuery] = useState(""); const [selectedCategory, setSelectedCategory] = useState("all"); // Modal state const [isModalOpen, setIsModalOpen] = useState(false); const [editingProject, setEditingProject] = useState(null); const [formError, setFormError] = useState(""); const [formSubmitting, setFormSubmitting] = useState(false); const [toastMessage, setToastMessage] = useState(null); // Form Fields const [formId, setFormId] = useState(""); const [formTitle, setFormTitle] = useState(""); const [formCategory, setFormCategory] = useState<"software" | "games" | "lab">("software"); const [formCategoryLabel, setFormCategoryLabel] = useState(""); const [formTagline, setFormTagline] = useState(""); const [formStatus, setFormStatus] = useState("In Active Dev"); const [formStatusType, setFormStatusType] = useState<"active" | "alpha" | "prototype" | "upcoming">("active"); const [formReleaseTarget, setFormReleaseTarget] = useState("2027"); const [formDescription, setFormDescription] = useState(""); const [formLongDescription, setFormLongDescription] = useState(""); const [formFeatures, setFormFeatures] = useState(""); const [formStack, setFormStack] = useState(""); const [formIconName, setFormIconName] = useState("Terminal"); const [formAccentGradient, setFormAccentGradient] = useState("from-cyan-500/20 via-blue-600/10 to-transparent"); // Check initial authentication useEffect(() => { checkAuthStatus(); }, []); const checkAuthStatus = async () => { try { const res = await fetch("/api/auth/me"); const data = await res.json(); setIsAuthenticated(data.authenticated === true); if (data.authenticated) { fetchProjects(); } } catch { setIsAuthenticated(false); } }; const fetchProjects = async () => { setLoadingProjects(true); try { const res = await fetch("/api/projects"); const data = await res.json(); if (data.success && Array.isArray(data.data)) { setProjects(data.data); } } catch { showToast("Error loading projects from database", true); } finally { setLoadingProjects(false); } }; const showToast = (msg: string, isError = false) => { setToastMessage(msg); setTimeout(() => { setToastMessage(null); }, 4000); }; const handleLogin = async (e: React.FormEvent) => { e.preventDefault(); setLoginError(""); setLoginLoading(true); try { const res = await fetch("/api/auth/login", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ username, password }), }); const data = await res.json(); if (res.ok && data.success) { setIsAuthenticated(true); fetchProjects(); } else { setLoginError(data.error || "Authentication failed. Check credentials."); } } catch { setLoginError("Network connection error to database."); } finally { setLoginLoading(false); } }; const handleLogout = async () => { await fetch("/api/auth/logout", { method: "POST" }); setIsAuthenticated(false); setUsername(""); setPassword(""); }; const openCreateModal = () => { setEditingProject(null); setFormId(""); setFormTitle(""); setFormCategory("software"); setFormCategoryLabel("Creative Tool"); setFormTagline(""); setFormStatus("In Active Dev"); setFormStatusType("active"); setFormReleaseTarget("2027"); setFormDescription(""); setFormLongDescription(""); setFormFeatures(""); setFormStack("Rust, WebGPU, TypeScript"); setFormIconName("Terminal"); setFormAccentGradient("from-cyan-500/20 via-blue-600/10 to-transparent"); setFormError(""); setIsModalOpen(true); }; const openEditModal = (p: ProjectItem) => { setEditingProject(p); setFormId(p.id); setFormTitle(p.title); setFormCategory(p.category); setFormCategoryLabel(p.categoryLabel); setFormTagline(p.tagline); setFormStatus(p.status); setFormStatusType(p.statusType); setFormReleaseTarget(p.releaseTarget); setFormDescription(p.description); setFormLongDescription(p.longDescription); setFormFeatures(p.features ? p.features.join("\n") : ""); setFormStack(p.stack ? p.stack.join(", ") : ""); setFormIconName(p.iconName || "Terminal"); setFormAccentGradient(p.accentGradient || "from-cyan-500/20 via-blue-600/10 to-transparent"); setFormError(""); setIsModalOpen(true); }; const handleDelete = async (id: string, title: string) => { if (!confirm(`Are you sure you want to delete "${title}" from the database?`)) { return; } try { const res = await fetch(`/api/projects/${id}`, { method: "DELETE" }); if (res.ok) { setProjects((prev) => prev.filter((p) => p.id !== id)); showToast(`Project "${title}" deleted from database.`); } else { const data = await res.json(); showToast(data.error || "Failed to delete", true); } } catch { showToast("Error deleting project", true); } }; const handleSaveProject = async (e: React.FormEvent) => { e.preventDefault(); setFormError(""); setFormSubmitting(true); try { const featuresArray = formFeatures .split("\n") .map((s) => s.trim()) .filter((s) => s.length > 0); const stackArray = formStack .split(",") .map((s) => s.trim()) .filter((s) => s.length > 0); const payload = { id: formId || formTitle.toLowerCase().replace(/[^a-z0-9]+/g, "-"), title: formTitle, category: formCategory, categoryLabel: formCategoryLabel, tagline: formTagline, status: formStatus, statusType: formStatusType, releaseTarget: formReleaseTarget, description: formDescription, longDescription: formLongDescription, features: featuresArray, stack: stackArray, iconName: formIconName, accentGradient: formAccentGradient, borderGlow: `hover:border-${formCategory === "games" ? "cyan" : formCategory === "lab" ? "emerald" : "purple"}-400/50`, }; if (editingProject) { // Update existing const res = await fetch(`/api/projects/${editingProject.id}`, { method: "PUT", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload), }); if (res.ok) { showToast(`Project "${formTitle}" updated successfully!`); setIsModalOpen(false); fetchProjects(); } else { const data = await res.json(); setFormError(data.error || "Failed to update project"); } } else { // Create new const res = await fetch("/api/projects", { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify(payload), }); if (res.ok) { showToast(`New project "${formTitle}" deployed to database!`); setIsModalOpen(false); fetchProjects(); } else { const data = await res.json(); setFormError(data.error || "Failed to create project"); } } } catch { setFormError("Network error while saving project."); } finally { setFormSubmitting(false); } }; // Filter projects by category and search const filteredProjects = projects.filter((p) => { const matchesCategory = selectedCategory === "all" || p.category === selectedCategory; const matchesSearch = p.title.toLowerCase().includes(searchQuery.toLowerCase()) || p.tagline.toLowerCase().includes(searchQuery.toLowerCase()) || p.categoryLabel.toLowerCase().includes(searchQuery.toLowerCase()); return matchesCategory && matchesSearch; }); // Loading screen during session check if (isAuthenticated === null) { return (
CHECKING SECURE COCKPIT CREDENTIALS...
); } // LOGIN SCREEN if (!isAuthenticated) { return (
{/* Background ambient lighting */}
{/* Header */}

AGHATIS STUDIO

ADMIN COMMAND CONSOLE // AUTHENTICATION

{loginError && (
{loginError}
)}
setUsername(e.target.value)} placeholder="Enter username" required className="w-full px-4 py-2.5 rounded-xl bg-black/40 border border-white/15 text-white font-mono text-xs focus:outline-none focus:border-cyan-400 transition-colors" />
setPassword(e.target.value)} placeholder="••••••••••••" required className="w-full px-4 py-2.5 rounded-xl bg-black/40 border border-white/15 text-white font-mono text-xs focus:outline-none focus:border-cyan-400 transition-colors" />
); } // AUTHENTICATED DASHBOARD return (
{/* Toast Alert */} {toastMessage && (
{toastMessage}
)} {/* Top Navbar Header */}
AS
AGHATIS STUDIO ADMIN COCKPIT
MySQL 103.155.224.244 • aghatis_studio_db
{/* Main Container */}
{/* Metric Cards Row */}
Total Fleet Projects
{projects.length}
Active in Database
Software Tools
{projects.filter((p) => p.category === "software").length}
Native Workstations & Pipelines
Original Games
{projects.filter((p) => p.category === "games").length}
Atmospheric Titles
Lab R&D Prototypes
{projects.filter((p) => p.category === "lab").length}
Procedural & Audio Experiments
{/* Action Controls & Filtering Bar */}
{/* Category Filter Pills */}
{[ { id: "all", label: "All Projects" }, { id: "software", label: "Software" }, { id: "games", label: "Games" }, { id: "lab", label: "Lab R&D" }, ].map((cat) => ( ))}
{/* Search Input & Add Button */}
setSearchQuery(e.target.value)} placeholder="Search projects..." className="w-full pl-9 pr-3 py-1.5 rounded-xl bg-white/5 border border-white/10 text-xs font-mono text-white placeholder-slate-500 focus:outline-none focus:border-cyan-400" />
{/* Project Grid */}
{filteredProjects.map((p) => (
{p.categoryLabel} {p.status}

{p.title}

ID: {p.id} • Target: {p.releaseTarget}

{p.tagline}

{/* Stack Badges */}
{p.stack?.slice(0, 3).map((item) => ( {item} ))} {p.stack?.length > 3 && ( +{p.stack.length - 3} more )}
{/* Action Buttons */}
{p.features?.length || 0} Features
))} {filteredProjects.length === 0 && (
NO PROJECTS FOUND IN THIS SECTOR
)}
{/* CREATE / EDIT MODAL */} {isModalOpen && (
{/* Modal Header */}

{editingProject ? `Edit Project: ${editingProject.title}` : "Deploy New Original Project"}

Data will be committed directly to MySQL database

{formError && (
{formError}
)}
setFormId(e.target.value)} placeholder="e.g. aetheria" disabled={!!editingProject} required className="w-full px-3 py-2 rounded-xl bg-white/5 border border-white/15 text-xs font-mono text-white focus:outline-none focus:border-cyan-400 disabled:opacity-50" />
setFormTitle(e.target.value)} placeholder="e.g. Aetheria: Chrono Drift" required className="w-full px-3 py-2 rounded-xl bg-white/5 border border-white/15 text-xs font-mono text-white focus:outline-none focus:border-cyan-400" />
setFormCategoryLabel(e.target.value)} placeholder="e.g. Tactical Flight RPG" required className="w-full px-3 py-2 rounded-xl bg-white/5 border border-white/15 text-xs font-mono text-white focus:outline-none focus:border-cyan-400" />
setFormStatus(e.target.value)} placeholder="e.g. In Active Dev" required className="w-full px-3 py-2 rounded-xl bg-white/5 border border-white/15 text-xs font-mono text-white focus:outline-none focus:border-cyan-400" />
setFormReleaseTarget(e.target.value)} placeholder="e.g. Alpha 2027" required className="w-full px-3 py-2 rounded-xl bg-white/5 border border-white/15 text-xs font-mono text-white focus:outline-none focus:border-cyan-400" />
setFormTagline(e.target.value)} placeholder="Atmospheric spaceflight RPG driven by Newtonian physics & relativistic time mechanics." required className="w-full px-3 py-2 rounded-xl bg-white/5 border border-white/15 text-xs font-mono text-white focus:outline-none focus:border-cyan-400" />