Initiales CMS: Deutschsprachiges Blog-System mit Admin-Bereich

Vollständiges, schlankes PHP/SQLite-CMS für IT-, KI- und Gaming-Inhalte:

- Core: DB-Singleton, Auth mit Passwort-Hashing, Session-Cookies,
  CSRF-Schutz, Login-Rate-Limit, Bild-Upload mit serverseitiger Validierung
- Admin: Dashboard, Artikel/Seiten-Verwaltung mit Quill WYSIWYG-Editor,
  Kategorien, Navigation (Drag & Drop), Medienbibliothek, Profil
- Frontend: Responsive Dark-Theme, Artikel-Grid, Kategorie-Filter,
  Archiv, Paginierung, SEO-Meta-Tags
- Sicherheit: Prepared Statements, HTML-Sanitizer, .htaccess-Schutz
  für sensible Verzeichnisse, PHP-Ausführungsschutz im Upload-Ordner
- Installation: install.php erstellt DB-Schema und Admin-Account

https://claude.ai/code/session_01Xsg4j2t4S9goMuWVpF3ezG
This commit is contained in:
Claude
2026-04-05 20:59:52 +00:00
commit 3c97192386
45 changed files with 2839 additions and 0 deletions

27
assets/js/admin.js Normal file
View File

@@ -0,0 +1,27 @@
document.addEventListener('DOMContentLoaded', function () {
// Sidebar Toggle (Mobile)
var toggle = document.getElementById('sidebarToggle');
var sidebar = document.querySelector('.admin-sidebar');
if (toggle && sidebar) {
toggle.addEventListener('click', function () {
sidebar.classList.toggle('open');
});
// Sidebar schließen bei Klick außerhalb
document.addEventListener('click', function (e) {
if (sidebar.classList.contains('open') &&
!sidebar.contains(e.target) &&
e.target !== toggle) {
sidebar.classList.remove('open');
}
});
}
// Flash-Nachrichten automatisch ausblenden
document.querySelectorAll('.flash').forEach(function (el) {
setTimeout(function () {
el.style.transition = 'opacity 0.5s';
el.style.opacity = '0';
setTimeout(function () { el.remove(); }, 500);
}, 5000);
});
});

16
assets/js/main.js Normal file
View File

@@ -0,0 +1,16 @@
document.addEventListener('DOMContentLoaded', function () {
// Mobile Menü Toggle
var toggle = document.getElementById('menuToggle');
var nav = document.getElementById('siteNav');
if (toggle && nav) {
toggle.addEventListener('click', function () {
nav.classList.toggle('open');
});
}
// Lazy Loading für ältere Browser
if ('loading' in HTMLImageElement.prototype) return;
document.querySelectorAll('img[loading="lazy"]').forEach(function (img) {
img.src = img.src;
});
});