Fix header layout and add debugging for dashboard statistics - Removed 'CourseWorx' text from header - Fixed logo path to use /images/cx-logo.png - Moved navigation items next to Home icon - Added debugging to API calls and dashboard - Added console logging to backend stats endpoints
This commit is contained in:
parent
b198ba5676
commit
7c28c49e75
4 changed files with 82 additions and 31 deletions
|
|
@ -458,6 +458,8 @@ router.get('/trainers/available', auth, requireSuperAdmin, async (req, res) => {
|
||||||
// @access Private
|
// @access Private
|
||||||
router.get('/stats/overview', auth, async (req, res) => {
|
router.get('/stats/overview', auth, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
|
console.log('Course stats endpoint called by user:', req.user.id, req.user.role);
|
||||||
|
|
||||||
const whereClause = {};
|
const whereClause = {};
|
||||||
if (req.user.role === 'trainer') {
|
if (req.user.role === 'trainer') {
|
||||||
whereClause.trainerId = req.user.id;
|
whereClause.trainerId = req.user.id;
|
||||||
|
|
@ -471,6 +473,8 @@ router.get('/stats/overview', auth, async (req, res) => {
|
||||||
where: { ...whereClause, isFeatured: true }
|
where: { ...whereClause, isFeatured: true }
|
||||||
});
|
});
|
||||||
|
|
||||||
|
console.log('Course stats calculated:', { totalCourses, publishedCourses, featuredCourses, whereClause });
|
||||||
|
|
||||||
// For trainers, provide specific stats
|
// For trainers, provide specific stats
|
||||||
let myCourses = 0;
|
let myCourses = 0;
|
||||||
let myPublishedCourses = 0;
|
let myPublishedCourses = 0;
|
||||||
|
|
|
||||||
|
|
@ -219,11 +219,15 @@ router.delete('/:id', auth, requireSuperAdmin, async (req, res) => {
|
||||||
// @access Private (Super Admin)
|
// @access Private (Super Admin)
|
||||||
router.get('/stats/overview', auth, requireSuperAdmin, async (req, res) => {
|
router.get('/stats/overview', auth, requireSuperAdmin, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
|
console.log('User stats endpoint called by user:', req.user.id, req.user.role);
|
||||||
|
|
||||||
const totalUsers = await User.count();
|
const totalUsers = await User.count();
|
||||||
const activeUsers = await User.count({ where: { isActive: true } });
|
const activeUsers = await User.count({ where: { isActive: true } });
|
||||||
const trainers = await User.count({ where: { role: 'trainer' } });
|
const trainers = await User.count({ where: { role: 'trainer' } });
|
||||||
const trainees = await User.count({ where: { role: 'trainee' } });
|
const trainees = await User.count({ where: { role: 'trainee' } });
|
||||||
|
|
||||||
|
console.log('User stats calculated:', { totalUsers, activeUsers, trainers, trainees });
|
||||||
|
|
||||||
res.json({
|
res.json({
|
||||||
stats: {
|
stats: {
|
||||||
totalUsers,
|
totalUsers,
|
||||||
|
|
|
||||||
|
|
@ -55,12 +55,14 @@ const Layout = () => {
|
||||||
<div className="min-h-screen bg-gray-50">
|
<div className="min-h-screen bg-gray-50">
|
||||||
{/* Header */}
|
{/* Header */}
|
||||||
<div className="sticky top-0 z-40 flex h-16 shrink-0 items-center gap-x-4 border-b border-gray-200 bg-white px-4 shadow-sm sm:gap-x-6 sm:px-6 lg:px-8">
|
<div className="sticky top-0 z-40 flex h-16 shrink-0 items-center gap-x-4 border-b border-gray-200 bg-white px-4 shadow-sm sm:gap-x-6 sm:px-6 lg:px-8">
|
||||||
{/* Logo and Home Icon */}
|
{/* Logo and Navigation */}
|
||||||
<div className="flex items-center space-x-4">
|
<div className="flex items-center space-x-6">
|
||||||
<div className="flex items-center space-x-2">
|
<div className="flex items-center space-x-2">
|
||||||
<img src="/courseworx-logo.png" alt="CourseWorx" className="h-8 w-auto" />
|
<img src="/images/cx-logo.png" alt="CourseWorx" className="h-8 w-auto" />
|
||||||
<h1 className="text-xl font-bold text-gray-900">CourseWorx</h1>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Navigation Items */}
|
||||||
|
<div className="flex items-center space-x-4">
|
||||||
<button
|
<button
|
||||||
onClick={() => navigate('/dashboard')}
|
onClick={() => navigate('/dashboard')}
|
||||||
className="flex items-center space-x-1 text-gray-600 hover:text-gray-900 transition-colors"
|
className="flex items-center space-x-1 text-gray-600 hover:text-gray-900 transition-colors"
|
||||||
|
|
@ -68,10 +70,7 @@ const Layout = () => {
|
||||||
<HomeIcon className="h-5 w-5" />
|
<HomeIcon className="h-5 w-5" />
|
||||||
<span className="hidden sm:inline text-sm font-medium">Home</span>
|
<span className="hidden sm:inline text-sm font-medium">Home</span>
|
||||||
</button>
|
</button>
|
||||||
</div>
|
|
||||||
|
|
||||||
{/* Navigation Items */}
|
|
||||||
<div className="flex flex-1 items-center justify-center space-x-8">
|
|
||||||
{navigation.map((item) => (
|
{navigation.map((item) => (
|
||||||
<a
|
<a
|
||||||
key={item.name}
|
key={item.name}
|
||||||
|
|
@ -87,9 +86,10 @@ const Layout = () => {
|
||||||
</a>
|
</a>
|
||||||
))}
|
))}
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
{/* User dropdown menu */}
|
{/* User dropdown menu */}
|
||||||
<div className="flex items-center gap-x-4 lg:gap-x-6">
|
<div className="flex flex-1 items-center justify-end gap-x-4 lg:gap-x-6">
|
||||||
<div className="hidden lg:block lg:h-6 lg:w-px lg:bg-gray-200" />
|
<div className="hidden lg:block lg:h-6 lg:w-px lg:bg-gray-200" />
|
||||||
|
|
||||||
<div className="relative user-menu">
|
<div className="relative user-menu">
|
||||||
|
|
|
||||||
|
|
@ -84,13 +84,40 @@ const Dashboard = () => {
|
||||||
const { data: userStats, isLoading: userStatsLoading } = useQuery(
|
const { data: userStats, isLoading: userStatsLoading } = useQuery(
|
||||||
['users', 'stats'],
|
['users', 'stats'],
|
||||||
() => usersAPI.getStats(),
|
() => usersAPI.getStats(),
|
||||||
{ enabled: isSuperAdmin }
|
{
|
||||||
|
enabled: isSuperAdmin,
|
||||||
|
onSuccess: (data) => {
|
||||||
|
console.log('User stats response:', data);
|
||||||
|
console.log('User stats data structure:', {
|
||||||
|
totalUsers: data?.stats?.totalUsers,
|
||||||
|
trainers: data?.stats?.trainers,
|
||||||
|
trainees: data?.stats?.trainees
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
console.error('User stats error:', error);
|
||||||
|
console.error('User stats error response:', error.response);
|
||||||
|
}
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
const { data: courseStats, isLoading: courseStatsLoading } = useQuery(
|
const { data: courseStats, isLoading: courseStatsLoading } = useQuery(
|
||||||
['courses', 'stats'],
|
['courses', 'stats'],
|
||||||
() => coursesAPI.getStats(),
|
() => coursesAPI.getStats(),
|
||||||
{ enabled: isSuperAdmin || isTrainer }
|
{
|
||||||
|
enabled: isSuperAdmin || isTrainer,
|
||||||
|
onSuccess: (data) => {
|
||||||
|
console.log('Course stats response:', data);
|
||||||
|
console.log('Course stats data structure:', {
|
||||||
|
totalCourses: data?.stats?.totalCourses,
|
||||||
|
publishedCourses: data?.stats?.publishedCourses
|
||||||
|
});
|
||||||
|
},
|
||||||
|
onError: (error) => {
|
||||||
|
console.error('Course stats error:', error);
|
||||||
|
console.error('Course stats error response:', error.response);
|
||||||
|
}
|
||||||
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
// New queries for real counts
|
// New queries for real counts
|
||||||
|
|
@ -120,6 +147,19 @@ const Dashboard = () => {
|
||||||
return <LoadingSpinner size="lg" className="mt-8" />;
|
return <LoadingSpinner size="lg" className="mt-8" />;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Debug section to show raw API responses
|
||||||
|
const debugSection = (
|
||||||
|
<div className="mb-6 p-4 bg-yellow-50 border border-yellow-200 rounded-lg">
|
||||||
|
<h3 className="text-lg font-medium text-yellow-800 mb-2">Debug Information</h3>
|
||||||
|
<div className="text-sm text-yellow-700">
|
||||||
|
<p><strong>User Stats:</strong> {JSON.stringify(userStats)}</p>
|
||||||
|
<p><strong>Course Stats:</strong> {JSON.stringify(courseStats)}</p>
|
||||||
|
<p><strong>User Role:</strong> {user?.role}</p>
|
||||||
|
<p><strong>Is Super Admin:</strong> {isSuperAdmin ? 'Yes' : 'No'}</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
|
||||||
const renderSuperAdminDashboard = () => (
|
const renderSuperAdminDashboard = () => (
|
||||||
<div className="space-y-6">
|
<div className="space-y-6">
|
||||||
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
|
||||||
|
|
@ -397,6 +437,9 @@ const Dashboard = () => {
|
||||||
<p className="text-gray-600">Welcome back, {user?.firstName}! Here's what's happening.</p>
|
<p className="text-gray-600">Welcome back, {user?.firstName}! Here's what's happening.</p>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{/* Debug section */}
|
||||||
|
{debugSection}
|
||||||
|
|
||||||
{isSuperAdmin && renderSuperAdminDashboard()}
|
{isSuperAdmin && renderSuperAdminDashboard()}
|
||||||
{isTrainer && renderTrainerDashboard()}
|
{isTrainer && renderTrainerDashboard()}
|
||||||
{isTrainee && renderTraineeDashboard()}
|
{isTrainee && renderTraineeDashboard()}
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue