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:
@@ -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);
|
||||
|
||||
@@ -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">
|
||||
|
||||
Reference in New Issue
Block a user