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:
Mahmoud M. Abdalla 2025-07-31 02:51:24 +03:00
parent b198ba5676
commit 7c28c49e75
4 changed files with 82 additions and 31 deletions

View file

@ -458,6 +458,8 @@ router.get('/trainers/available', auth, requireSuperAdmin, async (req, res) => {
// @access Private
router.get('/stats/overview', auth, async (req, res) => {
try {
console.log('Course stats endpoint called by user:', req.user.id, req.user.role);
const whereClause = {};
if (req.user.role === 'trainer') {
whereClause.trainerId = req.user.id;
@ -471,6 +473,8 @@ router.get('/stats/overview', auth, async (req, res) => {
where: { ...whereClause, isFeatured: true }
});
console.log('Course stats calculated:', { totalCourses, publishedCourses, featuredCourses, whereClause });
// For trainers, provide specific stats
let myCourses = 0;
let myPublishedCourses = 0;

View file

@ -219,11 +219,15 @@ router.delete('/:id', auth, requireSuperAdmin, async (req, res) => {
// @access Private (Super Admin)
router.get('/stats/overview', auth, requireSuperAdmin, async (req, res) => {
try {
console.log('User stats endpoint called by user:', req.user.id, req.user.role);
const totalUsers = await User.count();
const activeUsers = await User.count({ where: { isActive: true } });
const trainers = await User.count({ where: { role: 'trainer' } });
const trainees = await User.count({ where: { role: 'trainee' } });
console.log('User stats calculated:', { totalUsers, activeUsers, trainers, trainees });
res.json({
stats: {
totalUsers,

View file

@ -55,41 +55,41 @@ const Layout = () => {
<div className="min-h-screen bg-gray-50">
{/* 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">
{/* Logo and Home Icon */}
<div className="flex items-center space-x-4">
{/* Logo and Navigation */}
<div className="flex items-center space-x-6">
<div className="flex items-center space-x-2">
<img src="/courseworx-logo.png" alt="CourseWorx" className="h-8 w-auto" />
<h1 className="text-xl font-bold text-gray-900">CourseWorx</h1>
<img src="/images/cx-logo.png" alt="CourseWorx" className="h-8 w-auto" />
</div>
<button
onClick={() => navigate('/dashboard')}
className="flex items-center space-x-1 text-gray-600 hover:text-gray-900 transition-colors"
>
<HomeIcon className="h-5 w-5" />
<span className="hidden sm:inline text-sm font-medium">Home</span>
</button>
</div>
{/* Navigation Items */}
<div className="flex flex-1 items-center justify-center space-x-8">
{navigation.map((item) => (
<a
key={item.name}
href={item.href}
className={`flex items-center space-x-1 px-3 py-2 text-sm font-medium rounded-md transition-colors ${
isActive(item.href)
? 'bg-primary-100 text-primary-900'
: 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'
}`}
{/* Navigation Items */}
<div className="flex items-center space-x-4">
<button
onClick={() => navigate('/dashboard')}
className="flex items-center space-x-1 text-gray-600 hover:text-gray-900 transition-colors"
>
<item.icon className="h-5 w-5" />
<span className="hidden sm:inline">{item.name}</span>
</a>
))}
<HomeIcon className="h-5 w-5" />
<span className="hidden sm:inline text-sm font-medium">Home</span>
</button>
{navigation.map((item) => (
<a
key={item.name}
href={item.href}
className={`flex items-center space-x-1 px-3 py-2 text-sm font-medium rounded-md transition-colors ${
isActive(item.href)
? 'bg-primary-100 text-primary-900'
: 'text-gray-600 hover:bg-gray-50 hover:text-gray-900'
}`}
>
<item.icon className="h-5 w-5" />
<span className="hidden sm:inline">{item.name}</span>
</a>
))}
</div>
</div>
{/* 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="relative user-menu">

View file

@ -84,13 +84,40 @@ const Dashboard = () => {
const { data: userStats, isLoading: userStatsLoading } = useQuery(
['users', 'stats'],
() => 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(
['courses', 'stats'],
() => 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
@ -120,6 +147,19 @@ const Dashboard = () => {
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 = () => (
<div className="space-y-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>
</div>
{/* Debug section */}
{debugSection}
{isSuperAdmin && renderSuperAdminDashboard()}
{isTrainer && renderTrainerDashboard()}
{isTrainee && renderTraineeDashboard()}