Add Social Overview card to Trinity Console dashboard

- Shows cross-platform totals (posts, views, likes, comments)
- Breaks down by platform with icons
- Clickable link to full Social Analytics page

Chronicler #76
This commit is contained in:
Claude
2026-04-10 22:23:21 +00:00
parent 74f7876955
commit 918fb99b87
2 changed files with 88 additions and 1 deletions

View File

@@ -15,12 +15,47 @@ const isAdmin = (req, res, next) => {
router.get('/', isAdmin, async (req, res) => {
try {
const mappings = getRoleMappings();
// Fetch social stats across all platforms
const socialStats = await db.query(`
SELECT
platform,
COUNT(*) as post_count,
COALESCE(SUM(views), 0) as total_views,
COALESCE(SUM(likes), 0) as total_likes,
COALESCE(SUM(comments), 0) as total_comments
FROM social_posts
GROUP BY platform
`);
// Aggregate totals
const socialTotals = {
posts: 0,
views: 0,
likes: 0,
comments: 0,
platforms: {}
};
for (const row of socialStats.rows) {
socialTotals.posts += parseInt(row.post_count);
socialTotals.views += parseInt(row.total_views);
socialTotals.likes += parseInt(row.total_likes);
socialTotals.comments += parseInt(row.total_comments);
socialTotals.platforms[row.platform] = {
posts: parseInt(row.post_count),
views: parseInt(row.total_views),
likes: parseInt(row.total_likes)
};
}
res.render('admin/dashboard', {
title: 'Dashboard',
adminUser: req.user,
csrfToken: req.csrfToken(),
mappings: mappings,
currentPath: '/dashboard'
currentPath: '/dashboard',
socialTotals
});
} catch (error) {
console.error('Admin dashboard error:', error);

View File

@@ -55,6 +55,58 @@
</div>
</div>
<!-- Social Overview Card -->
<% if (socialTotals && socialTotals.posts > 0) { %>
<a href="/admin/social" class="block bg-gradient-to-r from-pink-500/10 via-purple-500/10 to-blue-500/10 rounded-lg border border-purple-500/30 p-6 mb-6 hover:border-purple-400/50 transition group">
<div class="flex items-center justify-between mb-4">
<div class="flex items-center gap-2">
<span class="text-2xl">📊</span>
<h3 class="text-lg font-semibold text-purple-400 group-hover:text-purple-300 transition">Social Overview</h3>
</div>
<span class="text-xs text-gray-500">Click for details →</span>
</div>
<div class="grid grid-cols-2 md:grid-cols-4 gap-4">
<div class="text-center">
<div class="text-2xl font-bold text-gray-200"><%= socialTotals.posts %></div>
<div class="text-xs text-gray-500">Total Posts</div>
</div>
<div class="text-center">
<div class="text-2xl font-bold text-cyan-400"><%= socialTotals.views.toLocaleString() %></div>
<div class="text-xs text-gray-500">Total Views</div>
</div>
<div class="text-center">
<div class="text-2xl font-bold text-pink-400"><%= socialTotals.likes.toLocaleString() %></div>
<div class="text-xs text-gray-500">Total Likes</div>
</div>
<div class="text-center">
<div class="text-2xl font-bold text-green-400"><%= socialTotals.comments %></div>
<div class="text-xs text-gray-500">Comments</div>
</div>
</div>
<% if (Object.keys(socialTotals.platforms).length > 0) { %>
<div class="flex gap-4 mt-4 pt-4 border-t border-gray-700/50">
<% for (const [platform, stats] of Object.entries(socialTotals.platforms)) { %>
<div class="flex items-center gap-2 text-sm">
<% if (platform === 'tiktok') { %>
<span class="text-pink-400">🎵</span>
<% } else if (platform === 'bluesky') { %>
<span class="text-blue-400">🦋</span>
<% } else if (platform === 'instagram') { %>
<span class="text-purple-400">📷</span>
<% } else if (platform === 'facebook') { %>
<span class="text-blue-600">📘</span>
<% } else if (platform === 'x') { %>
<span class="text-gray-400">𝕏</span>
<% } %>
<span class="text-gray-400 capitalize"><%= platform %></span>
<span class="text-gray-500">(<%= stats.views.toLocaleString() %> views)</span>
</div>
<% } %>
</div>
<% } %>
</a>
<% } %>
<div class="bg-white dark:bg-darkcard rounded-lg shadow-sm border border-gray-200 dark:border-gray-700 p-6">
<h3 class="text-lg font-semibold mb-4">🔥❄️ Welcome to Trinity Console</h3>
<p class="text-gray-600 dark:text-gray-400">