feat(admin): implement activity logs frontend page (Phase 6-7)

Complete implementation of admin activity logs dashboard with real-time
streaming capabilities. Admin users can now monitor all system activity
through a comprehensive web interface.

Features:
- Stats dashboard with 4 key metrics (total logs, unique users, failures, 24h activity)
- Category breakdown visualization with color-coded badges
- Advanced filtering (date range, category, action type, username, success/failure)
- Paginated log table (50 entries per page) with sort by timestamp
- Real-time streaming toggle using Socket.IO
- Color-coded action badges (blue=auth, green=event, purple=match, red=admin, yellow=chat)
- Admin-only access with automatic redirect for non-admin users
- Responsive design for mobile and desktop

Frontend Changes:
- Created ActivityLogsPage.jsx (600+ lines) with complete UI implementation
- Added 3 admin API methods to api.js (getActivityLogs, getActivityLogActions, getActivityLogStats)
- Added /admin/activity-logs route to App.jsx
- Added admin navigation link to Navbar (desktop & mobile) with Shield icon
- Only visible to users with isAdmin flag

Implementation Details:
- Uses getSocket() from socket service for real-time updates
- Joins 'admin_activity_logs' Socket.IO room on streaming enable
- Receives 'activity_log_entry' events and prepends to table (first page only)
- Comprehensive error handling and loading states
- Empty states for no data
- Clean disconnect handling when streaming disabled

Testing:
- Build successful (no errors)
- Ready for manual testing and verification

Phase 8 (Testing) remains for manual verification of all features.
This commit is contained in:
Radosław Gierwiało
2025-12-02 23:17:19 +01:00
parent 08845704cf
commit 1051cc6754
5 changed files with 608 additions and 14 deletions

View File

@@ -1,6 +1,6 @@
import { Link, useNavigate } from 'react-router-dom';
import { useAuth } from '../../contexts/AuthContext';
import { Video, LogOut, User, History, Users, Menu, X, LayoutDashboard, Calendar } from 'lucide-react';
import { Video, LogOut, User, History, Users, Menu, X, LayoutDashboard, Calendar, Shield } from 'lucide-react';
import Avatar from '../common/Avatar';
import { useState, useEffect } from 'react';
import { matchesAPI } from '../../services/api';
@@ -122,6 +122,16 @@ const Navbar = ({ pageTitle = null }) => {
<span>Profile</span>
</Link>
{user?.isAdmin && (
<Link
to="/admin/activity-logs"
className="flex items-center space-x-1 px-3 py-2 rounded-md text-sm font-medium text-gray-700 hover:text-primary-600 hover:bg-gray-100"
>
<Shield className="w-4 h-4" />
<span>Admin</span>
</Link>
)}
<div className="flex items-center space-x-3">
<Avatar src={user?.avatar} username={user.username} size={32} />
<span className="text-sm font-medium text-gray-700">{user.username}</span>
@@ -201,6 +211,15 @@ const Navbar = ({ pageTitle = null }) => {
>
<User className="w-4 h-4" /> Profile
</Link>
{user?.isAdmin && (
<Link
to="/admin/activity-logs"
onClick={() => setMenuOpen(false)}
className="flex items-center gap-2 px-3 py-2 rounded-md text-sm font-medium text-gray-700 hover:bg-gray-100"
>
<Shield className="w-4 h-4" /> Admin
</Link>
)}
<button
onClick={() => {
setMenuOpen(false);