/**
* Usage Stats Panel Component
*
* Platform usage statistics dashboard:
* - User stats (total, new, active)
* - Interview stats
* - Daily activity charts
* - Resume uploads
*/
import React, { useState, useEffect, useCallback } from 'react';
import {
BarChart3, RefreshCw, Users, FileText, MessageSquare,
TrendingUp, Calendar, Activity, Clock, ArrowUp, ArrowDown
} from 'lucide-react';
import { getToken } from '../../services/api';
const API_BASE = import.meta.env.VITE_API_URL || '';
// Stats card component
const StatsCard = ({ icon: Icon, title, value, change, changeType, subtitle }) => {
return (
{value.toLocaleString()}
{title}
{change !== undefined && (
{changeType === 'up' ? : }
{change}%
)}
{subtitle &&
{subtitle}}
);
};
// Simple bar chart component
const SimpleBarChart = ({ data, dataKey, labelKey, title }) => {
if (!data || data.length === 0) return null;
const maxValue = Math.max(...data.map(d => d[dataKey] || 0));
return (
{title}
{data.map((item, idx) => (
0 ? (item[dataKey] / maxValue) * 100 : 0}%`
}}
>
{item[dataKey]}
{new Date(item[labelKey]).toLocaleDateString('en-US', {
month: 'short',
day: 'numeric'
})}
))}
);
};
function UsageStatsPanel() {
const [stats, setStats] = useState(null);
const [loading, setLoading] = useState(true);
const [error, setError] = useState(null);
const [days, setDays] = useState(7);
// Fetch stats
const fetchStats = useCallback(async () => {
setLoading(true);
setError(null);
try {
const token = getToken();
const response = await fetch(`${API_BASE}/api/admin/usage-stats?days=${days}`, {
headers: {
'Authorization': `Bearer ${token}`,
'Content-Type': 'application/json'
}
});
if (!response.ok) throw new Error('Failed to fetch usage stats');
const data = await response.json();
if (data.success) {
setStats(data.stats);
}
} catch (err) {
setError(err.message);
} finally {
setLoading(false);
}
}, [days]);
// Initial fetch
useEffect(() => {
fetchStats();
}, [fetchStats]);
if (loading) {
return (
Loading usage statistics...
);
}
if (error) {
return (
);
}
const { users, interviews, resumes, daily } = stats || {};
return (
{/* Header */}
Usage Statistics
{/* Main Stats Cards */}
{/* Charts Section */}
{/* Daily Breakdown Table */}
{daily && daily.length > 0 && (
Daily Breakdown
| Date |
Interviews |
Signups |
API Requests |
{daily.map((day, idx) => (
| {new Date(day.date).toLocaleDateString()} |
{day.interviews} |
{day.signups} |
{day.api_requests} |
))}
)}
);
}
export default UsageStatsPanel;