feat: add architecture, api routes and components

This commit is contained in:
Atakan Doğan Özban
2026-07-06 02:27:06 +02:00
parent 91dbfa7d77
commit 2fe32edc3a
31 changed files with 2796 additions and 148 deletions
+80
View File
@@ -0,0 +1,80 @@
"use client";
import Link from "next/link";
import { useEffect } from "react";
import { useRouter } from "next/navigation";
export default function AdminLayout({
children,
}: {
children: React.ReactNode;
}) {
const router = useRouter();
const handleLogout = async () => {
try {
await fetch("/api/auth/logout", { method: "POST" });
router.push("/login");
router.refresh();
} catch (e) {
console.error("Logout failed", e);
}
};
const closeAdminSidebar = () => {
if (typeof window !== 'undefined' && typeof document !== 'undefined') {
const offcanvasEl = document.getElementById('adminSidebar');
if (offcanvasEl && (window as any).bootstrap) {
try {
const bsOffcanvas = (window as any).bootstrap.Offcanvas.getInstance(offcanvasEl) || new (window as any).bootstrap.Offcanvas(offcanvasEl);
if (bsOffcanvas) {
bsOffcanvas.hide();
}
} catch (e) {
console.error('Error closing admin offcanvas:', e);
offcanvasEl.classList.remove('show', 'showing');
}
}
}
};
return (
<div className="d-flex h-100" style={{ minHeight: "100vh" }}>
{/* Mobile Header with Toggle Button */}
<div className="d-md-none bg-dark text-white p-3 d-flex justify-content-between align-items-center w-100 position-fixed top-0 z-3" style={{ height: "60px" }}>
<span className="fs-5">Admin Panel</span>
<button className="btn btn-outline-light" type="button" data-bs-toggle="offcanvas" data-bs-target="#adminSidebar" aria-controls="adminSidebar">
</button>
</div>
{/* Sidebar (Offcanvas on mobile, visible on desktop) */}
<div className="offcanvas-md offcanvas-start bg-dark text-white border-end border-secondary d-flex flex-column flex-shrink-0 p-3" tabIndex={-1} id="adminSidebar" style={{ width: "280px" }}>
<div className="offcanvas-header d-md-none border-bottom border-secondary mb-3 p-0 pb-3">
<h5 className="offcanvas-title">Admin Panel</h5>
<button type="button" className="btn-close btn-close-white" onClick={closeAdminSidebar} aria-label="Close"></button>
</div>
<Link href="/admin" className="d-flex align-items-center mb-3 mb-md-0 me-md-auto text-white text-decoration-none d-none d-md-flex">
<span className="fs-4">Admin Panel</span>
</Link>
<hr className="d-none d-md-block" />
<ul className="nav nav-pills flex-column mb-auto">
<li>
<Link href="/" className="nav-link text-white" onClick={closeAdminSidebar}>
Go to Site
</Link>
</li>
<li>
<button onClick={handleLogout} className="nav-link text-white text-start w-100 bg-transparent border-0">
Log out
</button>
</li>
</ul>
</div>
{/* Main Content Area */}
<div className="w-100 overflow-auto bg-dark text-white pt-5 pt-md-0" data-bs-theme="dark">
<div className="container mt-4 p-4">{children}</div>
</div>
</div>
);
}