🚀 Complete Production Setup

 Features:
- Analytics Dashboard with real-time metrics
- Redis caching for performance optimization
- Import/Export functionality for projects
- Complete admin system with security
- Production-ready Docker setup

🔧 Technical:
- Removed Ghost CMS dependencies
- Added Redis container with caching
- Implemented API response caching
- Enhanced admin interface with analytics
- Optimized for dk0.dev domain

🛡️ Security:
- Admin authentication with Basic Auth
- Protected analytics endpoints
- Secure environment configuration

📊 Analytics:
- Performance metrics dashboard
- Project statistics visualization
- Real-time data with caching
- Umami integration for GDPR compliance

🎯 Production Ready:
- Multi-container Docker setup
- Health checks for all services
- Automatic restart policies
- Resource limits configured
- Ready for Nginx Proxy Manager
This commit is contained in:
Dennis Konkol
2025-09-05 21:35:54 +00:00
parent c736f860aa
commit 9835bb810d
19 changed files with 1386 additions and 45 deletions

View File

@@ -24,7 +24,8 @@ import {
FileText,
Settings,
Database,
BarChart3
BarChart3,
TrendingUp
} from 'lucide-react';
import Link from 'next/link';
import ReactMarkdown from 'react-markdown';
@@ -65,6 +66,8 @@ const apiService = {
}
};
import AdminDashboard from '@/components/AdminDashboard';
import ImportExport from '@/components/ImportExport';
import AnalyticsDashboard from '@/components/AnalyticsDashboard';
import { useToast } from '@/components/Toast';
interface Project {
@@ -136,6 +139,8 @@ const AdminPage = () => {
const [isPreview, setIsPreview] = useState(false);
const [isProjectsCollapsed, setIsProjectsCollapsed] = useState(false);
const [showTemplates, setShowTemplates] = useState(false);
const [showImportExport, setShowImportExport] = useState(false);
const [showAnalytics, setShowAnalytics] = useState(false);
const [formData, setFormData] = useState({
title: '',
description: '',
@@ -667,8 +672,8 @@ DELETE /api/users/:id
</p>
</motion.div>
{/* Projects Toggle Button - Always Visible */}
<div className="flex justify-center mb-6">
{/* Control Buttons */}
<div className="flex justify-center gap-4 mb-6">
<motion.button
onClick={() => setIsProjectsCollapsed(!isProjectsCollapsed)}
className="flex items-center space-x-2 px-6 py-3 bg-gradient-to-r from-gray-700 to-gray-800 hover:from-gray-600 hover:to-gray-700 rounded-xl text-white transition-all duration-200 hover:scale-105 border border-gray-600/50 shadow-lg"
@@ -688,8 +693,54 @@ DELETE /api/users/:id
</>
)}
</motion.button>
<motion.button
onClick={() => setShowImportExport(!showImportExport)}
className="flex items-center space-x-2 px-6 py-3 bg-gradient-to-r from-blue-600 to-blue-700 hover:from-blue-500 hover:to-blue-600 rounded-xl text-white transition-all duration-200 hover:scale-105 border border-blue-500/50 shadow-lg"
title="Import & Export Projects"
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
>
<FileText size={20} />
<span>Import/Export</span>
</motion.button>
<motion.button
onClick={() => setShowAnalytics(!showAnalytics)}
className="flex items-center space-x-2 px-6 py-3 bg-gradient-to-r from-green-600 to-green-700 hover:from-green-500 hover:to-green-600 rounded-xl text-white transition-all duration-200 hover:scale-105 border border-green-500/50 shadow-lg"
title="Analytics Dashboard"
whileHover={{ scale: 1.05 }}
whileTap={{ scale: 0.95 }}
>
<TrendingUp size={20} />
<span>Analytics</span>
</motion.button>
</div>
{/* Import/Export Section */}
{showImportExport && (
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
className="mb-8"
>
<ImportExport />
</motion.div>
)}
{/* Analytics Section */}
{showAnalytics && (
<motion.div
initial={{ opacity: 0, y: 20 }}
animate={{ opacity: 1, y: 0 }}
exit={{ opacity: 0, y: -20 }}
className="mb-8"
>
<AnalyticsDashboard />
</motion.div>
)}
<div className={`grid gap-8 ${isProjectsCollapsed ? 'grid-cols-1' : 'grid-cols-1 lg:grid-cols-3'}`}>
{/* Projects List */}
<div className={`${isProjectsCollapsed ? 'hidden' : 'lg:col-span-1'}`}>