File: /var/www/indoadvisory_new/web/webapp/views/admin/dashboard.ejs
<%- contentFor('additionalCSS') %>
<style>
.admin-card {
background: white;
border-radius: 12px;
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
transition: all 0.3s ease;
}
.admin-card:hover {
box-shadow: 0 8px 25px rgba(0, 0, 0, 0.12);
transform: translateY(-2px);
}
.stat-card {
background: linear-gradient(135deg, var(--bg-start), var(--bg-end));
border-radius: 16px;
padding: 24px;
color: white;
position: relative;
overflow: hidden;
}
.stat-card::before {
content: '';
position: absolute;
top: -50%;
right: -50%;
width: 100%;
height: 100%;
background: rgba(255, 255, 255, 0.1);
border-radius: 50%;
}
.stat-number {
font-size: 2.5rem;
font-weight: 800;
line-height: 1;
}
.activity-item {
padding: 12px 0;
border-bottom: 1px solid #f1f5f9;
transition: background-color 0.2s ease;
}
.activity-item:hover {
background-color: #f8fafc;
border-radius: 8px;
padding: 12px;
margin: 0 -12px;
}
.activity-item:last-child {
border-bottom: none;
}
</style>
<%- contentFor('body') %>
<div class="min-h-screen bg-gray-50">
<!-- Admin Header -->
<div class="bg-white shadow-sm border-b">
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8">
<div class="flex justify-between items-center py-6">
<div>
<h1 class="text-3xl font-bold text-gray-900">
<%= __('admin_dashboard') %>
</h1>
<p class="text-gray-600 mt-1">
Welcome back, <%= user.name %>
</p>
</div>
<div class="flex items-center space-x-4">
<div class="text-right text-sm text-gray-500">
<div>Last login: <%= user.last_login ? new Date(user.last_login).toLocaleString() : 'First time' %></div>
<div>Role: <span class="font-medium text-mckinsey-blue"><%= user.role %></span></div>
</div>
<div class="flex space-x-2">
<a href="/"
target="_blank"
class="px-4 py-2 bg-gray-100 text-gray-700 rounded-lg hover:bg-gray-200 transition-colors">
<i class="fas fa-external-link-alt mr-2"></i>
View Site
</a>
<form method="POST" action="/auth/logout" class="inline">
<input type="hidden" name="_csrf" value="<%= csrfToken %>">
<button type="submit"
class="px-4 py-2 bg-red-100 text-red-700 rounded-lg hover:bg-red-200 transition-colors">
<i class="fas fa-sign-out-alt mr-2"></i>
<%= __('nav_logout') %>
</button>
</form>
</div>
</div>
</div>
</div>
</div>
<!-- Dashboard Content -->
<div class="max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 py-8">
<!-- Statistics Overview -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 mb-8">
<!-- Team Members -->
<div class="stat-card" style="--bg-start: #3B82F6; --bg-end: #1D4ED8;">
<div class="flex items-center justify-between">
<div>
<p class="text-blue-100 text-sm font-medium">Team Members</p>
<p class="stat-number"><%= stats.totalTeamMembers || 0 %></p>
</div>
<div class="text-4xl text-blue-200">
<i class="fas fa-users"></i>
</div>
</div>
</div>
<!-- Clients -->
<div class="stat-card" style="--bg-start: #10B981; --bg-end: #059669;">
<div class="flex items-center justify-between">
<div>
<p class="text-emerald-100 text-sm font-medium">Portfolio Clients</p>
<p class="stat-number"><%= stats.totalClients || 0 %></p>
</div>
<div class="text-4xl text-emerald-200">
<i class="fas fa-building"></i>
</div>
</div>
</div>
<!-- Articles -->
<div class="stat-card" style="--bg-start: #8B5CF6; --bg-end: #7C3AED;">
<div class="flex items-center justify-between">
<div>
<p class="text-violet-100 text-sm font-medium">Published Articles</p>
<p class="stat-number"><%= stats.totalArticles || 0 %></p>
</div>
<div class="text-4xl text-violet-200">
<i class="fas fa-newspaper"></i>
</div>
</div>
</div>
<!-- Inquiries -->
<div class="stat-card" style="--bg-start: #F59E0B; --bg-end: #D97706;">
<div class="flex items-center justify-between">
<div>
<p class="text-amber-100 text-sm font-medium">New Inquiries</p>
<p class="stat-number"><%= stats.newInquiries || 0 %></p>
</div>
<div class="text-4xl text-amber-200">
<i class="fas fa-envelope"></i>
</div>
</div>
</div>
</div>
<!-- Quick Actions -->
<div class="grid grid-cols-1 lg:grid-cols-3 gap-6 mb-8">
<div class="admin-card p-6">
<h3 class="text-lg font-semibold text-gray-900 mb-4">
<i class="fas fa-plus-circle text-mckinsey-blue mr-2"></i>
Quick Actions
</h3>
<div class="space-y-3">
<a href="/admin/clients/new"
class="block w-full text-left px-4 py-3 bg-blue-50 text-blue-700 rounded-lg hover:bg-blue-100 transition-colors">
<i class="fas fa-plus mr-2"></i>
Add New Client
</a>
<a href="/admin/team/new"
class="block w-full text-left px-4 py-3 bg-green-50 text-green-700 rounded-lg hover:bg-green-100 transition-colors">
<i class="fas fa-user-plus mr-2"></i>
Add Team Member
</a>
<a href="/admin/articles/new"
class="block w-full text-left px-4 py-3 bg-purple-50 text-purple-700 rounded-lg hover:bg-purple-100 transition-colors">
<i class="fas fa-edit mr-2"></i>
Write Article
</a>
</div>
</div>
<!-- Recent Activities -->
<div class="admin-card p-6">
<h3 class="text-lg font-semibold text-gray-900 mb-4">
<i class="fas fa-history text-mckinsey-blue mr-2"></i>
Recent Activities
</h3>
<div class="space-y-2">
<% if (stats.recentActivities && stats.recentActivities.length > 0) { %>
<% stats.recentActivities.slice(0, 5).forEach(function(activity) { %>
<div class="activity-item">
<div class="flex items-start">
<div class="flex-shrink-0 mt-1">
<% if (activity.action.includes('login')) { %>
<i class="fas fa-sign-in-alt text-green-500"></i>
<% } else if (activity.action.includes('created')) { %>
<i class="fas fa-plus text-blue-500"></i>
<% } else if (activity.action.includes('updated')) { %>
<i class="fas fa-edit text-yellow-500"></i>
<% } else if (activity.action.includes('deleted')) { %>
<i class="fas fa-trash text-red-500"></i>
<% } else { %>
<i class="fas fa-circle text-gray-400"></i>
<% } %>
</div>
<div class="ml-3 flex-1">
<p class="text-sm text-gray-900">
<span class="font-medium"><%= activity.user_name || 'System' %></span>
<%= activity.action.replace(/_/g, ' ') %>
<% if (activity.resource_type) { %>
<span class="text-gray-600"><%= activity.resource_type %></span>
<% } %>
</p>
<p class="text-xs text-gray-500">
<%= new Date(activity.created_at).toLocaleString() %>
</p>
</div>
</div>
</div>
<% }); %>
<% } else { %>
<p class="text-gray-500 text-sm">No recent activities</p>
<% } %>
</div>
<div class="mt-4 pt-4 border-t">
<a href="/admin/security"
class="text-sm text-mckinsey-blue hover:text-mckinsey-navy">
View all activities →
</a>
</div>
</div>
<!-- Recent Inquiries -->
<div class="admin-card p-6">
<h3 class="text-lg font-semibold text-gray-900 mb-4">
<i class="fas fa-envelope-open-text text-mckinsey-blue mr-2"></i>
Recent Inquiries
</h3>
<div class="space-y-3">
<% if (stats.recentInquiries && stats.recentInquiries.length > 0) { %>
<% stats.recentInquiries.forEach(function(inquiry) { %>
<div class="activity-item">
<div class="flex items-start justify-between">
<div class="flex-1">
<p class="text-sm font-medium text-gray-900">
<%= inquiry.name %>
</p>
<p class="text-sm text-gray-600 line-clamp-1">
<%= inquiry.subject %>
</p>
<p class="text-xs text-gray-500 mt-1">
<%= new Date(inquiry.created_at).toLocaleString() %>
</p>
</div>
<span class="inline-flex items-center px-2.5 py-0.5 rounded-full text-xs font-medium <%= inquiry.status === 'new' ? 'bg-red-100 text-red-800' : inquiry.status === 'in_progress' ? 'bg-yellow-100 text-yellow-800' : 'bg-green-100 text-green-800' %>">
<%= inquiry.status.replace('_', ' ') %>
</span>
</div>
</div>
<% }); %>
<% } else { %>
<p class="text-gray-500 text-sm">No recent inquiries</p>
<% } %>
</div>
<div class="mt-4 pt-4 border-t">
<a href="/admin/inquiries"
class="text-sm text-mckinsey-blue hover:text-mckinsey-navy">
View all inquiries →
</a>
</div>
</div>
</div>
<!-- Management Sections -->
<div class="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
<!-- Content Management -->
<div class="admin-card p-6">
<div class="flex items-center mb-4">
<div class="w-12 h-12 bg-blue-100 rounded-lg flex items-center justify-center mr-4">
<i class="fas fa-edit text-blue-600 text-xl"></i>
</div>
<h3 class="text-lg font-semibold text-gray-900">
<%= __('admin_content') %>
</h3>
</div>
<p class="text-gray-600 text-sm mb-4">
Manage website content, company information, and site settings.
</p>
<div class="space-y-2">
<a href="/admin/content"
class="block text-sm text-mckinsey-blue hover:text-mckinsey-navy">
• Company Settings
</a>
<a href="/admin/articles"
class="block text-sm text-mckinsey-blue hover:text-mckinsey-navy">
• Articles & Insights
</a>
</div>
</div>
<!-- Team Management -->
<div class="admin-card p-6">
<div class="flex items-center mb-4">
<div class="w-12 h-12 bg-green-100 rounded-lg flex items-center justify-center mr-4">
<i class="fas fa-users text-green-600 text-xl"></i>
</div>
<h3 class="text-lg font-semibold text-gray-900">
<%= __('admin_team') %>
</h3>
</div>
<p class="text-gray-600 text-sm mb-4">
Add and manage team members, their profiles, and display order.
</p>
<div class="space-y-2">
<a href="/admin/team"
class="block text-sm text-mckinsey-blue hover:text-mckinsey-navy">
• Team Members (<%= stats.totalTeamMembers || 0 %>)
</a>
<a href="/admin/team/new"
class="block text-sm text-mckinsey-blue hover:text-mckinsey-navy">
• Add New Member
</a>
</div>
</div>
<!-- Client Management -->
<div class="admin-card p-6">
<div class="flex items-center mb-4">
<div class="w-12 h-12 bg-purple-100 rounded-lg flex items-center justify-center mr-4">
<i class="fas fa-building text-purple-600 text-xl"></i>
</div>
<h3 class="text-lg font-semibold text-gray-900">
<%= __('admin_clients') %>
</h3>
</div>
<p class="text-gray-600 text-sm mb-4">
Manage portfolio companies, projects, and client showcase.
</p>
<div class="space-y-2">
<a href="/admin/clients"
class="block text-sm text-mckinsey-blue hover:text-mckinsey-navy">
• Portfolio Clients (<%= stats.totalClients || 0 %>)
</a>
<a href="/admin/clients/new"
class="block text-sm text-mckinsey-blue hover:text-mckinsey-navy">
• Add New Client
</a>
</div>
</div>
<!-- Security & Users -->
<div class="admin-card p-6">
<div class="flex items-center mb-4">
<div class="w-12 h-12 bg-red-100 rounded-lg flex items-center justify-center mr-4">
<i class="fas fa-shield-alt text-red-600 text-xl"></i>
</div>
<h3 class="text-lg font-semibold text-gray-900">
<%= __('admin_security') %>
</h3>
</div>
<p class="text-gray-600 text-sm mb-4">
Monitor system security, audit logs, and user management.
</p>
<div class="space-y-2">
<a href="/admin/security"
class="block text-sm text-mckinsey-blue hover:text-mckinsey-navy">
• Audit Logs (<%= stats.dailyActivities || 0 %> today)
</a>
<a href="/admin/users"
class="block text-sm text-mckinsey-blue hover:text-mckinsey-navy">
• User Management
</a>
</div>
</div>
<!-- Inquiries -->
<div class="admin-card p-6">
<div class="flex items-center mb-4">
<div class="w-12 h-12 bg-yellow-100 rounded-lg flex items-center justify-center mr-4">
<i class="fas fa-envelope text-yellow-600 text-xl"></i>
</div>
<h3 class="text-lg font-semibold text-gray-900">
<%= __('admin_inquiries') %>
</h3>
</div>
<p class="text-gray-600 text-sm mb-4">
Review and respond to customer inquiries and contact form submissions.
</p>
<div class="space-y-2">
<a href="/admin/inquiries?status=new"
class="block text-sm text-mckinsey-blue hover:text-mckinsey-navy">
• New Inquiries (<%= stats.newInquiries || 0 %>)
</a>
<a href="/admin/inquiries"
class="block text-sm text-mckinsey-blue hover:text-mckinsey-navy">
• All Inquiries
</a>
</div>
</div>
<!-- System Status -->
<div class="admin-card p-6">
<div class="flex items-center mb-4">
<div class="w-12 h-12 bg-gray-100 rounded-lg flex items-center justify-center mr-4">
<i class="fas fa-server text-gray-600 text-xl"></i>
</div>
<h3 class="text-lg font-semibold text-gray-900">
System Status
</h3>
</div>
<p class="text-gray-600 text-sm mb-4">
Monitor system health and performance metrics.
</p>
<div class="space-y-2">
<div class="flex justify-between items-center">
<span class="text-sm text-gray-600">Database</span>
<span class="text-sm text-green-600">
<i class="fas fa-check-circle mr-1"></i>
Healthy
</span>
</div>
<div class="flex justify-between items-center">
<span class="text-sm text-gray-600">Server</span>
<span class="text-sm text-green-600">
<i class="fas fa-check-circle mr-1"></i>
Online
</span>
</div>
<div class="flex justify-between items-center">
<span class="text-sm text-gray-600">Uptime</span>
<span class="text-sm text-blue-600">
<i class="fas fa-clock mr-1"></i>
99.9%
</span>
</div>
</div>
</div>
</div>
</div>
</div>
<%- contentFor('additionalJS') %>
<script>
document.addEventListener('DOMContentLoaded', function() {
// Auto-refresh dashboard data every 5 minutes
setInterval(function() {
// Refresh activity feed
fetch('/admin/activities/recent')
.then(response => response.json())
.then(data => {
if (data.success) {
console.log('Dashboard data refreshed');
}
})
.catch(error => console.error('Failed to refresh dashboard:', error));
}, 300000); // 5 minutes
// Add click animations to cards
document.querySelectorAll('.admin-card').forEach(card => {
card.addEventListener('click', function(e) {
// Only animate if clicking the card directly, not links inside
if (e.target === this || e.target.closest('a') === null) {
this.style.transform = 'scale(0.98)';
setTimeout(() => {
this.style.transform = '';
}, 150);
}
});
});
// Animate stat numbers on load
document.querySelectorAll('.stat-number').forEach(element => {
const finalValue = parseInt(element.textContent);
let currentValue = 0;
const increment = finalValue / 50; // 50 steps
const timer = setInterval(() => {
currentValue += increment;
if (currentValue >= finalValue) {
element.textContent = finalValue;
clearInterval(timer);
} else {
element.textContent = Math.floor(currentValue);
}
}, 30);
});
});
</script>
<%
// Set admin layout variables
locals.pageTitle = __('admin_dashboard');
locals.activePage = 'dashboard';
%>