'use client';
import React, { useState, useEffect, useCallback } from 'react';
import { motion, AnimatePresence } from 'framer-motion';
import {
Mail,
Settings,
TrendingUp,
Plus,
Shield,
Users,
Activity,
Database,
Home,
LogOut,
Menu,
X
} from 'lucide-react';
import Link from 'next/link';
import dynamic from 'next/dynamic';
const EmailManager = dynamic(
() => import('./EmailManager').then((m) => m.EmailManager),
{ ssr: false, loading: () =>
Loading emails…
}
);
const AnalyticsDashboard = dynamic(
() => import('./AnalyticsDashboard').then((m) => m.default),
{ ssr: false, loading: () => Loading analytics…
}
);
const ImportExport = dynamic(
() => import('./ImportExport').then((m) => m.default),
{ ssr: false, loading: () => Loading tools…
}
);
const ProjectManager = dynamic(
() => import('./ProjectManager').then((m) => m.ProjectManager),
{ ssr: false, loading: () => Loading projects…
}
);
const ContentManager = dynamic(
() => import('./ContentManager').then((m) => m.default),
{ ssr: false, loading: () => Loading content…
}
);
interface Project {
id: string;
title: string;
description: string;
content?: string;
category: string;
difficulty?: string;
tags?: string[];
featured: boolean;
published: boolean;
github?: string;
live?: string;
image?: string;
createdAt: string;
updatedAt: string;
analytics?: {
views: number;
likes: number;
shares: number;
};
performance?: {
lighthouse: number;
};
}
interface ModernAdminDashboardProps {
isAuthenticated?: boolean;
}
const ModernAdminDashboard: React.FC = ({ isAuthenticated = true }) => {
const [activeTab, setActiveTab] = useState<'overview' | 'projects' | 'emails' | 'analytics' | 'content' | 'settings'>('overview');
const [projects, setProjects] = useState([]);
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const [isLoading, setIsLoading] = useState(false);
const [mobileMenuOpen, setMobileMenuOpen] = useState(false);
const [analytics, setAnalytics] = useState | null>(null);
const [emails, setEmails] = useState[]>([]);
const [systemStats, setSystemStats] = useState | null>(null);
const loadProjects = useCallback(async () => {
try {
setIsLoading(true);
const sessionToken = sessionStorage.getItem('admin_session_token');
const response = await fetch('/api/projects', {
headers: {
'x-admin-request': 'true',
'x-session-token': sessionToken || ''
}
});
if (!response.ok) {
console.warn('Failed to load projects:', response.status);
setProjects([]);
return;
}
const data = await response.json();
setProjects(data.projects || []);
} catch {
setProjects([]);
} finally {
setIsLoading(false);
}
}, []);
const loadAnalytics = useCallback(async () => {
try {
const sessionToken = sessionStorage.getItem('admin_session_token');
const response = await fetch('/api/analytics/dashboard', {
headers: {
'x-admin-request': 'true',
'x-session-token': sessionToken || ''
}
});
if (response.ok) {
const data = await response.json();
setAnalytics(data);
}
} catch (error) {
console.error('Error loading analytics:', error);
}
}, []);
const loadEmails = useCallback(async () => {
try {
const sessionToken = sessionStorage.getItem('admin_session_token');
const response = await fetch('/api/contacts', {
headers: {
'x-admin-request': 'true',
'x-session-token': sessionToken || ''
}
});
if (response.ok) {
const data = await response.json();
setEmails(data.contacts || []);
}
} catch (error) {
console.error('Error loading emails:', error);
}
}, []);
const loadSystemStats = useCallback(async () => {
try {
const sessionToken = sessionStorage.getItem('admin_session_token');
const response = await fetch('/api/health', {
headers: {
'x-admin-request': 'true',
'x-session-token': sessionToken || ''
}
});
if (response.ok) {
const data = await response.json();
setSystemStats(data);
}
} catch (error) {
console.error('Error loading system stats:', error);
}
}, []);
const loadAllData = useCallback(async () => {
await Promise.all([
loadProjects(),
loadAnalytics(),
loadEmails(),
loadSystemStats()
]);
}, [loadProjects, loadAnalytics, loadEmails, loadSystemStats]);
// Real stats from API data
const stats = {
totalProjects: projects.length,
publishedProjects: projects.filter(p => p.published).length,
totalViews: ((analytics?.overview as Record)?.totalViews as number) || (analytics?.totalViews as number) || projects.reduce((sum, p) => sum + (p.analytics?.views || 0), 0),
unreadEmails: emails.filter(e => !(e.read as boolean)).length,
avgPerformance: (() => {
// Only show real performance data, not defaults
const projectsWithPerf = projects.filter(p => {
const perf = p.performance as Record || {};
return (perf.lighthouse as number || 0) > 0;
});
if (projectsWithPerf.length === 0) return 0;
return Math.round(projectsWithPerf.reduce((sum, p) => {
const perf = p.performance as Record || {};
return sum + (perf.lighthouse as number || 0);
}, 0) / projectsWithPerf.length);
})(),
systemHealth: (systemStats?.status as string) || 'unknown',
totalUsers: ((analytics?.metrics as Record)?.totalUsers as number) || (analytics?.totalUsers as number) || 0,
bounceRate: ((analytics?.metrics as Record)?.bounceRate as number) || (analytics?.bounceRate as number) || 0,
avgSessionDuration: ((analytics?.metrics as Record)?.avgSessionDuration as number) || (analytics?.avgSessionDuration as number) || 0
};
useEffect(() => {
// Prioritize the data needed for the initial dashboard render
void (async () => {
await Promise.all([loadProjects(), loadSystemStats()]);
const idle = (cb: () => void) => {
if (typeof window !== 'undefined' && 'requestIdleCallback' in window) {
(window as unknown as { requestIdleCallback: (fn: () => void) => void }).requestIdleCallback(cb);
} else {
setTimeout(cb, 300);
}
};
idle(() => {
void loadAnalytics();
void loadEmails();
});
})();
}, [loadProjects, loadSystemStats, loadAnalytics, loadEmails]);
const navigation = [
{ id: 'overview', label: 'Dashboard', icon: Home, color: 'blue', description: 'Overview & Statistics' },
{ id: 'projects', label: 'Projects', icon: Database, color: 'green', description: 'Manage Projects' },
{ id: 'emails', label: 'Emails', icon: Mail, color: 'purple', description: 'Email Management' },
{ id: 'analytics', label: 'Analytics', icon: Activity, color: 'orange', description: 'Site Analytics' },
{ id: 'content', label: 'Content', icon: Shield, color: 'teal', description: 'Texts, pages & localization' },
{ id: 'settings', label: 'Settings', icon: Settings, color: 'gray', description: 'System Settings' }
];
return (
{/* Animated Background - same as main site */}
{/* Admin Navbar - Horizontal Navigation */}
{/* Left side - Logo and Admin Panel */}
{/* Center - Desktop Navigation */}
{navigation.map((item) => (
setActiveTab(item.id as 'overview' | 'projects' | 'emails' | 'analytics' | 'content' | 'settings')}
className={`flex items-center space-x-2 px-4 py-2 rounded-lg transition-all duration-200 ${
activeTab === item.id
? 'bg-stone-100 text-stone-900 font-medium shadow-sm border border-stone-200'
: 'text-stone-500 hover:text-stone-800 hover:bg-stone-50'
}`}
>
{item.label}
))}
{/* Right side - User info and Logout */}
Welcome, Dennis
{
try {
await fetch('/api/auth/logout', { method: 'POST' });
sessionStorage.removeItem('admin_authenticated');
sessionStorage.removeItem('admin_session_token');
window.location.href = '/manage';
} catch (error) {
console.error('Logout failed:', error);
// Force logout anyway
sessionStorage.removeItem('admin_authenticated');
sessionStorage.removeItem('admin_session_token');
window.location.href = '/manage';
}
}}
className="flex items-center space-x-2 px-3 py-2 rounded-lg hover:bg-red-50 text-stone-500 hover:text-red-600 transition-all duration-200 border border-transparent hover:border-red-100"
>
Logout
{/* Mobile menu button */}
setMobileMenuOpen(!mobileMenuOpen)}
className="md:hidden flex items-center justify-center p-2 rounded-lg text-stone-600 hover:bg-stone-100 transition-colors"
>
{mobileMenuOpen ? : }
{/* Mobile Navigation Menu */}
{mobileMenuOpen && (
{navigation.map((item) => (
{
setActiveTab(item.id as 'overview' | 'projects' | 'emails' | 'analytics' | 'content' | 'settings');
setMobileMenuOpen(false);
}}
className={`w-full flex items-center space-x-3 px-4 py-3 rounded-lg transition-all duration-200 ${
activeTab === item.id
? 'bg-stone-100 text-stone-900 shadow-sm border border-stone-200'
: 'text-stone-500 hover:text-stone-800 hover:bg-stone-50'
}`}
>
{item.label}
{item.description}
))}
)}
{/* Main Content - Full Width Horizontal Layout */}
{/* Content */}
{activeTab === 'overview' && (
Admin Dashboard
Manage your portfolio and monitor performance
{/* Stats Grid - Mobile: 2x3, Desktop: 6x1 horizontal */}
setActiveTab('projects')}
>
{stats.totalProjects}
{stats.publishedProjects} published
✅ REAL DATA: Total projects in your portfolio from the database. Shows published vs unpublished count.
setActiveTab('analytics')}
>
{stats.totalViews.toLocaleString()}
{stats.totalUsers} users
✅ REAL DATA: Total page views from PageView table (last 30 days). Each visit is tracked with IP, user agent, and timestamp. Users = unique IP addresses.
setActiveTab('emails')}
>
{emails.length}
{stats.unreadEmails} unread
setActiveTab('analytics')}
>
{stats.avgPerformance || 'N/A'}
Lighthouse Score
{stats.avgPerformance > 0
? "✅ REAL DATA: Average Lighthouse score (0-100) calculated from real Web Vitals (LCP, FCP, CLS, FID, TTFB) collected from actual page visits. Only averages projects with real performance data."
: "No performance data yet. Scores appear after visitors load pages and Web Vitals are tracked."}
setActiveTab('analytics')}
>
{stats.bounceRate}%
Exit rate
✅ REAL DATA: Percentage of sessions with only 1 pageview (calculated from PageView records grouped by IP). Lower is better. Shows how many visitors leave after viewing just one page.
setActiveTab('settings')}
>
{/* Recent Activity & Quick Actions - Mobile: vertical, Desktop: horizontal */}
{/* Recent Activity */}
Recent Activity
loadAllData()}
className="text-stone-500 hover:text-stone-800 text-sm font-medium px-3 py-1 bg-stone-100 rounded-lg transition-colors border border-stone-200"
>
Refresh
{/* Mobile: vertical stack, Desktop: horizontal columns */}
Projects
{projects.slice(0, 3).map((project) => (
setActiveTab('projects')}>
{project.title}
{project.published ? 'Published' : 'Draft'} • {project.analytics?.views || 0} views
{project.published ? 'Live' : 'Draft'}
{project.featured && (
Featured
)}
))}
Messages
{emails.slice(0, 3).map((email, index) => (
setActiveTab('emails')}>
From {email.name as string}
{(email.subject as string) || 'No subject'}
{!(email.read as boolean) && (
)}
))}
{/* Quick Actions */}
Quick Actions
window.location.href = '/editor'}
className="w-full flex items-center space-x-3 p-3 bg-stone-50 border border-stone-100 rounded-lg hover:shadow-sm hover:bg-white transition-all duration-200 text-left group"
>
Ghost Editor
Professional writing tool
setActiveTab('analytics')}
className="w-full flex items-center space-x-3 p-3 bg-stone-50 border border-stone-100 rounded-lg hover:shadow-sm hover:bg-white transition-all duration-200 text-left group"
>
Reset Analytics
Clear analytics data
setActiveTab('emails')}
className="w-full flex items-center space-x-3 p-3 bg-stone-50 border border-stone-100 rounded-lg hover:shadow-sm hover:bg-white transition-all duration-200 text-left group"
>
View Messages
{stats.unreadEmails} unread messages
setActiveTab('analytics')}
className="w-full flex items-center space-x-3 p-3 bg-stone-50 border border-stone-100 rounded-lg hover:shadow-sm hover:bg-white transition-all duration-200 text-left group"
>
Analytics
View detailed statistics
setActiveTab('settings')}
className="w-full flex items-center space-x-3 p-3 bg-stone-50 border border-stone-100 rounded-lg hover:shadow-sm hover:bg-white transition-all duration-200 text-left group"
>
Settings
System configuration
)}
{activeTab === 'projects' && (
Project Management
Manage your portfolio projects
)}
{activeTab === 'emails' && (
)}
{activeTab === 'analytics' && (
)}
{activeTab === 'content' && (
)}
{activeTab === 'settings' && (
System Settings
Manage system configuration and preferences
Import / Export
Backup and restore your portfolio data
)}
);
};
export default ModernAdminDashboard;