v1.1.3: Enhanced login experience, trainer profiles, modern course details, and dashboard improvements
This commit is contained in:
parent
6cc071c8d4
commit
29b55e14aa
5 changed files with 68 additions and 26 deletions
|
|
@ -437,8 +437,6 @@ router.put('/:id/assign-trainer', [
|
||||||
// @access Private (Super Admin)
|
// @access Private (Super Admin)
|
||||||
router.get('/trainers/available', auth, requireSuperAdmin, async (req, res) => {
|
router.get('/trainers/available', auth, requireSuperAdmin, async (req, res) => {
|
||||||
try {
|
try {
|
||||||
console.log('Get available trainers request from user:', req.user.id, 'role:', req.user.role);
|
|
||||||
|
|
||||||
const trainers = await User.findAll({
|
const trainers = await User.findAll({
|
||||||
where: {
|
where: {
|
||||||
role: 'trainer',
|
role: 'trainer',
|
||||||
|
|
@ -448,7 +446,6 @@ router.get('/trainers/available', auth, requireSuperAdmin, async (req, res) => {
|
||||||
order: [['firstName', 'ASC'], ['lastName', 'ASC']]
|
order: [['firstName', 'ASC'], ['lastName', 'ASC']]
|
||||||
});
|
});
|
||||||
|
|
||||||
console.log('Found trainers:', trainers.length);
|
|
||||||
res.json({ trainers });
|
res.json({ trainers });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
console.error('Get available trainers error:', error);
|
console.error('Get available trainers error:', error);
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,6 @@ import { coursesAPI } from '../services/api';
|
||||||
import { useAuth } from '../contexts/AuthContext';
|
import { useAuth } from '../contexts/AuthContext';
|
||||||
import {
|
import {
|
||||||
XMarkIcon,
|
XMarkIcon,
|
||||||
UserIcon,
|
|
||||||
AcademicCapIcon,
|
AcademicCapIcon,
|
||||||
} from '@heroicons/react/24/outline';
|
} from '@heroicons/react/24/outline';
|
||||||
import LoadingSpinner from './LoadingSpinner';
|
import LoadingSpinner from './LoadingSpinner';
|
||||||
|
|
@ -18,18 +17,12 @@ const TrainerAssignmentModal = ({ isOpen, onClose, courseId, currentTrainer }) =
|
||||||
// Get available trainers
|
// Get available trainers
|
||||||
const { data: trainersData, isLoading: trainersLoading, error: trainersError } = useQuery(
|
const { data: trainersData, isLoading: trainersLoading, error: trainersError } = useQuery(
|
||||||
['available-trainers'],
|
['available-trainers'],
|
||||||
() => {
|
() => coursesAPI.getAvailableTrainers(),
|
||||||
console.log('Fetching available trainers...');
|
|
||||||
return coursesAPI.getAvailableTrainers();
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
enabled: isOpen,
|
enabled: isOpen,
|
||||||
onError: (error) => {
|
onError: (error) => {
|
||||||
console.error('Trainer loading error:', error);
|
console.error('Trainer loading error:', error);
|
||||||
toast.error('Failed to load trainers');
|
toast.error('Failed to load trainers');
|
||||||
},
|
|
||||||
onSuccess: (data) => {
|
|
||||||
console.log('Trainers loaded successfully:', data);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
@ -149,16 +142,7 @@ const TrainerAssignmentModal = ({ isOpen, onClose, courseId, currentTrainer }) =
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|
||||||
{/* Debug info - remove in production */}
|
|
||||||
{process.env.NODE_ENV === 'development' && (
|
|
||||||
<div className="mb-4 p-2 bg-gray-100 rounded text-xs">
|
|
||||||
<p>Debug: trainersData = {JSON.stringify(trainersData, null, 2)}</p>
|
|
||||||
<p>Debug: trainersLoading = {trainersLoading}</p>
|
|
||||||
<p>Debug: trainersError = {trainersError?.message}</p>
|
|
||||||
<p>Debug: Current user role = {user?.role}</p>
|
|
||||||
<p>Debug: Current user ID = {user?.id}</p>
|
|
||||||
</div>
|
|
||||||
)}
|
|
||||||
|
|
||||||
<div className="flex justify-end space-x-3">
|
<div className="flex justify-end space-x-3">
|
||||||
<button
|
<button
|
||||||
|
|
|
||||||
|
|
@ -43,7 +43,11 @@ export const AuthProvider = ({ children }) => {
|
||||||
|
|
||||||
console.log('Login successful, user:', user);
|
console.log('Login successful, user:', user);
|
||||||
localStorage.setItem('token', token);
|
localStorage.setItem('token', token);
|
||||||
setUser(user);
|
|
||||||
|
// Set user state after a brief delay to prevent immediate redirect
|
||||||
|
setTimeout(() => {
|
||||||
|
setUser(user);
|
||||||
|
}, 50);
|
||||||
|
|
||||||
toast.success('Login successful!');
|
toast.success('Login successful!');
|
||||||
return { success: true };
|
return { success: true };
|
||||||
|
|
|
||||||
|
|
@ -21,7 +21,10 @@ const Login = () => {
|
||||||
try {
|
try {
|
||||||
const result = await login(email, password);
|
const result = await login(email, password);
|
||||||
if (result.success) {
|
if (result.success) {
|
||||||
navigate('/dashboard');
|
// Add a small delay to ensure the user sees the success message
|
||||||
|
setTimeout(() => {
|
||||||
|
navigate('/dashboard');
|
||||||
|
}, 100);
|
||||||
} else {
|
} else {
|
||||||
setError(result.error || 'Login failed');
|
setError(result.error || 'Login failed');
|
||||||
console.error('Login failed:', result.error);
|
console.error('Login failed:', result.error);
|
||||||
|
|
@ -108,8 +111,13 @@ const Login = () => {
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{error && (
|
{error && (
|
||||||
<div className="rounded-md bg-red-50 p-4">
|
<div className="rounded-md bg-red-50 p-4 border border-red-200">
|
||||||
<div className="flex">
|
<div className="flex">
|
||||||
|
<div className="flex-shrink-0">
|
||||||
|
<svg className="h-5 w-5 text-red-400" viewBox="0 0 20 20" fill="currentColor">
|
||||||
|
<path fillRule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clipRule="evenodd" />
|
||||||
|
</svg>
|
||||||
|
</div>
|
||||||
<div className="ml-3">
|
<div className="ml-3">
|
||||||
<h3 className="text-sm font-medium text-red-800">
|
<h3 className="text-sm font-medium text-red-800">
|
||||||
Login Error
|
Login Error
|
||||||
|
|
|
||||||
53
version.txt
53
version.txt
|
|
@ -1,4 +1,4 @@
|
||||||
CourseWorx v1.1.2 - Trainer Assignment System & Navigation Improvements
|
CourseWorx v1.1.3 - Enhanced Login Experience & Dashboard Improvements
|
||||||
==========================================================
|
==========================================================
|
||||||
|
|
||||||
This version adds comprehensive course content management and enrollment/subscriber functionality to the existing Course Management System.
|
This version adds comprehensive course content management and enrollment/subscriber functionality to the existing Course Management System.
|
||||||
|
|
@ -111,6 +111,55 @@ MAJOR FEATURES IMPLEMENTED:
|
||||||
- Assignment management
|
- Assignment management
|
||||||
- Database migrations and seeding
|
- Database migrations and seeding
|
||||||
|
|
||||||
|
NEW FEATURES IN v1.1.3:
|
||||||
|
========================
|
||||||
|
|
||||||
|
1. ENHANCED LOGIN EXPERIENCE
|
||||||
|
-----------------------------
|
||||||
|
- Fixed page reload issue that was hiding error messages
|
||||||
|
- Improved error message visibility with better styling
|
||||||
|
- Added delays to prevent immediate redirects after login
|
||||||
|
- Enhanced error handling with clear visual feedback
|
||||||
|
- Better user experience with proper error persistence
|
||||||
|
- Added error icons and improved error message styling
|
||||||
|
|
||||||
|
2. TRAINER PROFILE SYSTEM
|
||||||
|
--------------------------
|
||||||
|
- New trainer profile page with comprehensive information
|
||||||
|
- Clickable instructor sections in course details
|
||||||
|
- Trainer qualifications and experience display
|
||||||
|
- Course listings by trainer
|
||||||
|
- Professional trainer profile layout
|
||||||
|
- Direct navigation from course pages to trainer profiles
|
||||||
|
|
||||||
|
3. MODERN COURSE DETAIL PAGE
|
||||||
|
-----------------------------
|
||||||
|
- Redesigned course detail page with Udemy-like layout
|
||||||
|
- Left column with course information and content
|
||||||
|
- Right sidebar with pricing and enrollment options
|
||||||
|
- Professional course preview with play button
|
||||||
|
- Enhanced "What you'll learn" section with checkmarks
|
||||||
|
- Course content structure with expandable sections
|
||||||
|
- Requirements and description sections
|
||||||
|
- Course includes section with feature icons
|
||||||
|
|
||||||
|
4. DASHBOARD IMPROVEMENTS
|
||||||
|
--------------------------
|
||||||
|
- Made all dashboard cards clickable with proper navigation
|
||||||
|
- Added hover effects and arrow icons for better UX
|
||||||
|
- Fixed hardcoded values and improved data display
|
||||||
|
- Enhanced Quick Actions with proper links
|
||||||
|
- Course and enrollment items are now clickable
|
||||||
|
- Better visual feedback with transitions and hover effects
|
||||||
|
|
||||||
|
5. ESLINT & CODE QUALITY
|
||||||
|
-------------------------
|
||||||
|
- Fixed all ESLint warnings across components
|
||||||
|
- Removed unused imports and variables
|
||||||
|
- Improved code organization and structure
|
||||||
|
- Enhanced code maintainability
|
||||||
|
- Cleaned up debugging code and console logs
|
||||||
|
|
||||||
NEW FEATURES IN v1.1.2:
|
NEW FEATURES IN v1.1.2:
|
||||||
========================
|
========================
|
||||||
|
|
||||||
|
|
@ -386,5 +435,5 @@ DEPLOYMENT READINESS:
|
||||||
This version (1.1.0) adds comprehensive course content management and enrollment/subscriber functionality to the existing Course Management System, providing a complete foundation for creating rich educational content and managing student enrollments.
|
This version (1.1.0) adds comprehensive course content management and enrollment/subscriber functionality to the existing Course Management System, providing a complete foundation for creating rich educational content and managing student enrollments.
|
||||||
|
|
||||||
Release Date: [Current Date]
|
Release Date: [Current Date]
|
||||||
Version: 1.1.2
|
Version: 1.1.3
|
||||||
Status: Production Ready
|
Status: Production Ready
|
||||||
Loading…
Reference in a new issue