Merge pull request 'add dummy assign profiler and added course and programme' (#24) from priyanshu-dev into main
All checks were successful
Build-Check / Build and Test PR (pull_request) Successful in 32s
Sonar Check / SonarQube Scan (pull_request) Successful in 57s

Reviewed-on: #24
This commit is contained in:
2026-04-23 14:24:35 +00:00
8 changed files with 539 additions and 3991 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,5 +1,7 @@
import { import {
BarChart3, BarChart3,
BookOpen,
FolderOpen,
Home, Home,
MessageSquare, MessageSquare,
Users Users
@@ -12,6 +14,8 @@ import { useAuth } from '../../context/AuthContext';
const menuItems = [ const menuItems = [
{ id: 'dashboard', label: 'Dashboard', icon: Home, path: '/hr/dashboard' }, { id: 'dashboard', label: 'Dashboard', icon: Home, path: '/hr/dashboard' },
{ id: 'learners', label: 'Learners', icon: Users, path: '/hr/learners' }, { id: 'learners', label: 'Learners', icon: Users, path: '/hr/learners' },
{ id: 'courses', label: 'Courses', icon: BookOpen, path: '/hr/courses' },
{ id: 'programmes', label: 'Programmes', icon: FolderOpen, path: '/hr/programmes' },
{ id: 'reports', label: 'Reports', icon: BarChart3, path: '/hr/reports' }, { id: 'reports', label: 'Reports', icon: BarChart3, path: '/hr/reports' },
{ id: 'discussions', label: 'Discussion Forums', icon: MessageSquare, path: '/hr/discussions' } { id: 'discussions', label: 'Discussion Forums', icon: MessageSquare, path: '/hr/discussions' }
]; ];

View File

@@ -0,0 +1,93 @@
import React from 'react';
import { Calendar, Clock, Lock } from 'lucide-react';
import { Card, CardContent, CardHeader, CardTitle } from '../../components/ui/card';
import { Button } from '../../components/ui/button';
import { Progress } from '../../components/ui/progress';
import { useGetAssignedHrCoursesQuery } from '../../redux/services/learnersApi';
const CoursesPage: React.FC = () => {
const { data, isLoading, isError } = useGetAssignedHrCoursesQuery({
limit: 10,
start: 0,
});
const courseCards = data?.data.course_items ?? [];
const totalCourses = data?.data.pagination.total ?? 0;
return (
<div className="space-y-4">
<h1 className="text-3xl font-bold tracking-tight">My Courses</h1>
<Card className="border border-indigo-100 bg-gradient-to-br from-indigo-50 via-white to-cyan-50">
<CardHeader className="pb-3">
<CardTitle className="text-2xl text-indigo-900">Assigned Courses</CardTitle>
<p className="text-sm text-muted-foreground">{totalCourses} courses assigned by your organization.</p>
</CardHeader>
<CardContent>
{isLoading && <p className="text-sm text-muted-foreground">Loading courses...</p>}
{isError && <p className="text-sm text-red-600">Failed to load courses. Please try again.</p>}
{!isLoading && !isError && courseCards.length === 0 && (
<p className="text-sm text-muted-foreground">No courses found.</p>
)}
<div className="grid grid-cols-1 gap-4 lg:grid-cols-2">
{courseCards.map((course) => (
<Card key={course.id} className="h-full border border-indigo-100 bg-white/95">
<CardContent className="flex h-full flex-col space-y-3 p-4">
<div className="flex items-start gap-3">
<img
src={course.thumbnail_url}
alt={course.course_name}
className="h-20 w-20 shrink-0 rounded-lg object-cover"
/>
<div className="min-w-0">
<h3 className="text-xl font-semibold leading-tight text-indigo-950">{course.course_name}</h3>
<p className="line-clamp-2 text-sm text-muted-foreground">{course.course_description}</p>
</div>
</div>
<div className="flex flex-wrap items-center gap-3 text-sm text-muted-foreground">
<span className="flex items-center gap-1">
<Clock className="h-4 w-4" />
Duration: {course.total_duration}h
</span>
<span className="flex items-center gap-1">
<Calendar className="h-4 w-4" />
Learners: {course.total_learners}
</span>
<span className="flex items-center gap-1">
<Calendar className="h-4 w-4" />
Status: {course.status}
</span>
</div>
<div className="space-y-1">
<div className="flex items-center justify-between text-sm">
<span className="font-medium">Progress</span>
<span className="font-medium">{course.avg_progress}%</span>
</div>
<Progress value={course.avg_progress} className="h-2 bg-slate-200" />
</div>
<div className="mt-auto pt-1">
{course.status === 'new' ? (
<Button className="w-full bg-slate-200 text-slate-700 hover:bg-slate-300">
<Lock className="mr-2 h-4 w-4" />
Not Started
</Button>
) : (
<Button className="w-full bg-[#061a72] text-white hover:bg-[#051458]" style={{backgroundColor: '#061a72', color: 'white'}}>View Course</Button>
)}
</div>
</CardContent>
</Card>
))}
</div>
</CardContent>
</Card>
</div>
);
};
export default CoursesPage;

View File

@@ -192,9 +192,9 @@ const DiscussionsPage: React.FC = () => {
<div className="mt-0.5 flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-muted text-xs font-semibold text-muted-foreground"> <div className="mt-0.5 flex h-8 w-8 shrink-0 items-center justify-center rounded-full bg-muted text-xs font-semibold text-muted-foreground">
L L
</div> </div>
<div className="min-w-0 flex-1 border-l-[3px] border-[#0a2f6f] pl-3"> <div className="min-w-0 flex-1 pl-3">
<div className="flex items-center gap-2"> <div className="flex items-center gap-2">
<h3 className="truncate text-3xl font-semibold leading-tight">{thread.title}</h3> <h3 className="truncate text-xl font-semibold leading-tight">{thread.title}</h3>
</div> </div>
<p className="mt-1 line-clamp-1 text-sm text-muted-foreground">{thread.content}</p> <p className="mt-1 line-clamp-1 text-sm text-muted-foreground">{thread.content}</p>
<div className="mt-3 flex flex-wrap items-center gap-4 text-sm text-muted-foreground"> <div className="mt-3 flex flex-wrap items-center gap-4 text-sm text-muted-foreground">

View File

@@ -11,6 +11,12 @@ import { Progress } from '../../components/ui/progress';
import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from '../../components/ui/sheet'; import { Sheet, SheetContent, SheetDescription, SheetHeader, SheetTitle } from '../../components/ui/sheet';
import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '../../components/ui/dialog'; import { Dialog, DialogContent, DialogDescription, DialogHeader, DialogTitle } from '../../components/ui/dialog';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '../../components/ui/tabs'; import { Tabs, TabsContent, TabsList, TabsTrigger } from '../../components/ui/tabs';
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuTrigger,
} from '../../components/ui/dropdown-menu';
import { import {
Search, Search,
Plus, Plus,
@@ -87,6 +93,7 @@ const LearnersPage: React.FC = () => {
const [showImportModal, setShowImportModal] = useState(false); const [showImportModal, setShowImportModal] = useState(false);
const [showAssignModal, setShowAssignModal] = useState(false); const [showAssignModal, setShowAssignModal] = useState(false);
const [showAssignCourseModal, setShowAssignCourseModal] = useState(false); const [showAssignCourseModal, setShowAssignCourseModal] = useState(false);
const [showAssignProfilerModal, setShowAssignProfilerModal] = useState(false);
const [showEditDrawer, setShowEditDrawer] = useState(false); const [showEditDrawer, setShowEditDrawer] = useState(false);
const [selectedProgrammeId, setSelectedProgrammeId] = useState(''); const [selectedProgrammeId, setSelectedProgrammeId] = useState('');
const [selectedCourseId, setSelectedCourseId] = useState(''); const [selectedCourseId, setSelectedCourseId] = useState('');
@@ -94,6 +101,11 @@ const LearnersPage: React.FC = () => {
const [courseEndDate, setCourseEndDate] = useState(''); const [courseEndDate, setCourseEndDate] = useState('');
const [assignError, setAssignError] = useState(''); const [assignError, setAssignError] = useState('');
const [assignCourseError, setAssignCourseError] = useState(''); const [assignCourseError, setAssignCourseError] = useState('');
const [assignProfilerError, setAssignProfilerError] = useState('');
const [selectedProfilerId, setSelectedProfilerId] = useState('');
const [profilerStartDate, setProfilerStartDate] = useState('');
const [profilerEndDate, setProfilerEndDate] = useState('');
const [isAssigningProfiler, setIsAssigningProfiler] = useState(false);
const [editingEmployee, setEditingEmployee] = useState<Employee | null>(null); const [editingEmployee, setEditingEmployee] = useState<Employee | null>(null);
const [editForm, setEditForm] = useState({ const [editForm, setEditForm] = useState({
firstName: '', firstName: '',
@@ -132,6 +144,11 @@ const LearnersPage: React.FC = () => {
{ code: '+61', label: 'AU +61' }, { code: '+61', label: 'AU +61' },
{ code: '+86', label: 'CN +86' }, { code: '+86', label: 'CN +86' },
]; ];
const profilerOptions = [
{ id: 'profiler-1', name: 'Leadership Profiler' },
{ id: 'profiler-2', name: 'Behavioral Profiler' },
{ id: 'profiler-3', name: 'Skills Profiler' },
];
useEffect(() => { useEffect(() => {
const timer = setTimeout(() => { const timer = setTimeout(() => {
@@ -787,6 +804,74 @@ const LearnersPage: React.FC = () => {
} }
}; };
const handleAssignProfiler = async () => {
setAssignProfilerError('');
if (selectedEmployees.length === 0) {
setAssignProfilerError('Please select at least one learner.');
return;
}
if (!selectedProfilerId) {
setAssignProfilerError('Please select a profiler.');
return;
}
if (!profilerStartDate || !profilerEndDate) {
setAssignProfilerError('Please select start date and end date.');
return;
}
if (new Date(profilerEndDate) < new Date(profilerStartDate)) {
setAssignProfilerError('End date cannot be before start date.');
return;
}
try {
setIsAssigningProfiler(true);
await new Promise((resolve) => setTimeout(resolve, 600));
const profilerName =
profilerOptions.find((option) => option.id === selectedProfilerId)?.name ?? 'selected profiler';
showToast(
'Profiler assigned',
`${selectedEmployees.length} learner${selectedEmployees.length !== 1 ? 's' : ''} assigned to ${profilerName}.`,
'success'
);
setShowAssignProfilerModal(false);
setSelectedProfilerId('');
setProfilerStartDate('');
setProfilerEndDate('');
setSelectedEmployees([]);
} catch {
setAssignProfilerError('Failed to assign profiler.');
showToast('Assign failed', 'Failed to assign profiler.', 'error');
} finally {
setIsAssigningProfiler(false);
}
};
const handleOpenAssignAction = (employeeId: string, action: 'programme' | 'course' | 'profiler') => {
setSelectedEmployees([employeeId]);
if (action === 'programme') {
setAssignError('');
setSelectedProgrammeId('');
setProgrammeStartDate('');
setProgrammeEndDate('');
setShowAssignModal(true);
return;
}
if (action === 'course') {
setAssignCourseError('');
setSelectedCourseId('');
setCourseStartDate('');
setCourseEndDate('');
setShowAssignCourseModal(true);
return;
}
setAssignProfilerError('');
setSelectedProfilerId('');
setProfilerStartDate('');
setProfilerEndDate('');
setShowAssignProfilerModal(true);
};
const getStatusColor = (status: string) => { const getStatusColor = (status: string) => {
switch (status) { switch (status) {
case 'Active': return 'default'; case 'Active': return 'default';
@@ -964,18 +1049,11 @@ const LearnersPage: React.FC = () => {
<Button <Button
variant="outline" variant="outline"
size="sm" size="sm"
onClick={() => setShowAssignProfilerModal(true)}
className="min-tap-44" className="min-tap-44"
> >
<Mail className="h-4 w-4 mr-2" /> <Award className="h-4 w-4 mr-2" />
Send Email Assign to Profiler
</Button>
<Button
variant="outline"
size="sm"
className="min-tap-44 text-red-600"
>
<XCircle className="h-4 w-4 mr-2" />
Deactivate
</Button> </Button>
</div> </div>
</div> </div>
@@ -1083,6 +1161,8 @@ const LearnersPage: React.FC = () => {
> >
<Edit className="h-4 w-4" /> <Edit className="h-4 w-4" />
</Button> </Button>
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button <Button
variant="ghost" variant="ghost"
size="sm" size="sm"
@@ -1091,6 +1171,28 @@ const LearnersPage: React.FC = () => {
> >
<MoreHorizontal className="h-4 w-4" /> <MoreHorizontal className="h-4 w-4" />
</Button> </Button>
</DropdownMenuTrigger>
<DropdownMenuContent align="end">
<DropdownMenuItem
onClick={() => handleOpenAssignAction(employee.id, 'programme')}
>
<UserPlus className="h-4 w-4 mr-2" />
Assign to Programme
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => handleOpenAssignAction(employee.id, 'course')}
>
<BookOpen className="h-4 w-4 mr-2" />
Assign to Course
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => handleOpenAssignAction(employee.id, 'profiler')}
>
<Award className="h-4 w-4 mr-2" />
Assign to Profiler
</DropdownMenuItem>
</DropdownMenuContent>
</DropdownMenu>
</div> </div>
</TableCell> </TableCell>
</TableRow> </TableRow>
@@ -1609,6 +1711,86 @@ const LearnersPage: React.FC = () => {
</DialogContent> </DialogContent>
</Dialog> </Dialog>
{/* Assign Profiler Modal (Bulk) */}
<Dialog open={showAssignProfilerModal} onOpenChange={setShowAssignProfilerModal}>
<DialogContent className="sm:max-w-[500px]">
<DialogHeader>
<DialogTitle>Assign to Profiler</DialogTitle>
<DialogDescription>
Assign {selectedEmployees.length} selected learner{selectedEmployees.length !== 1 ? 's' : ''} to a profiler.
</DialogDescription>
</DialogHeader>
<div className="space-y-4">
{assignProfilerError && (
<div className="flex items-center gap-2 rounded-md border border-red-200 bg-red-50 p-3 text-sm text-red-700">
<AlertCircle className="h-4 w-4" />
{assignProfilerError}
</div>
)}
<div>
<label className="block text-sm font-medium mb-2">
Select Profiler
</label>
<Select value={selectedProfilerId} onValueChange={setSelectedProfilerId}>
<SelectTrigger>
<SelectValue placeholder="Choose profiler" />
</SelectTrigger>
<SelectContent>
{profilerOptions.map((profiler) => (
<SelectItem key={profiler.id} value={profiler.id}>
{profiler.name}
</SelectItem>
))}
</SelectContent>
</Select>
</div>
<div className="grid grid-cols-1 gap-4 sm:grid-cols-2">
<div>
<label className="block text-sm font-medium mb-2">Start Date *</label>
<Input
type="date"
value={profilerStartDate}
onChange={(e) => setProfilerStartDate(e.target.value)}
required
/>
</div>
<div>
<label className="block text-sm font-medium mb-2">End Date *</label>
<Input
type="date"
value={profilerEndDate}
onChange={(e) => setProfilerEndDate(e.target.value)}
required
/>
</div>
</div>
<div className="flex gap-2 pt-4">
<Button
className="flex-1"
onClick={handleAssignProfiler}
disabled={isAssigningProfiler}
>
{isAssigningProfiler ? 'Assigning...' : 'Assign'}
</Button>
<Button
variant="outline"
onClick={() => {
setShowAssignProfilerModal(false);
setAssignProfilerError('');
setSelectedProfilerId('');
setProfilerStartDate('');
setProfilerEndDate('');
}}
className="flex-1"
disabled={isAssigningProfiler}
>
Cancel
</Button>
</div>
</div>
</DialogContent>
</Dialog>
{/* Edit Drawer */} {/* Edit Drawer */}
<Sheet open={showEditDrawer} onOpenChange={setShowEditDrawer}> <Sheet open={showEditDrawer} onOpenChange={setShowEditDrawer}>
<SheetContent className="w-[800px] sm:w-[900px] px-4 overflow-y-auto"> <SheetContent className="w-[800px] sm:w-[900px] px-4 overflow-y-auto">

View File

@@ -0,0 +1,133 @@
import React, { useState } from 'react';
import { BookOpen, Calendar, ChevronRight, FolderOpen, Info, Presentation, Users } from 'lucide-react';
import { Card, CardContent, CardHeader, CardTitle } from '../../components/ui/card';
import { Button } from '../../components/ui/button';
import { Progress } from '../../components/ui/progress';
import { useGetAssignedHrProgrammesQuery } from '../../redux/services/learnersApi';
const ProgrammesPage: React.FC = () => {
const { data, isLoading, isError } = useGetAssignedHrProgrammesQuery({
limit: 10,
start: 0,
});
const [openProgrammeId, setOpenProgrammeId] = useState<string | null>(null);
const programmeItems = data?.data.programme_items ?? [];
const formatDate = (date: string) =>
new Date(date).toLocaleDateString('en-GB', {
day: '2-digit',
month: 'short',
year: 'numeric',
});
return (
<div className="space-y-4">
<h1 className="text-3xl font-bold tracking-tight">My Programs</h1>
{isLoading && <p className="text-sm text-muted-foreground">Loading programmes...</p>}
{isError && <p className="text-sm text-red-600">Failed to load programmes. Please try again.</p>}
{!isLoading && !isError && programmeItems.length === 0 && (
<p className="text-sm text-muted-foreground">No programmes found.</p>
)}
<div className="space-y-4">
{programmeItems.map((programme) => {
const isOpen = openProgrammeId === programme.id;
return (
<Card
key={programme.id}
className="gap-0 overflow-hidden border border-violet-100 bg-gradient-to-br from-violet-50 via-white to-fuchsia-50"
>
<CardHeader
className={`cursor-pointer !pt-4 !pb-4 transition-colors duration-200 ${isOpen ? 'border-b border-violet-100' : 'border-b border-transparent'}`}
onClick={() => setOpenProgrammeId((prev) => (prev === programme.id ? null : programme.id))}
>
<div className="flex items-start justify-between gap-3">
<div className="flex items-start gap-2">
<ChevronRight
className={`mt-1 h-5 w-5 text-violet-800 transition-transform ${isOpen ? 'rotate-90' : 'rotate-0'}`}
/>
<div className="space-y-2">
<CardTitle className="text-xl font-semibold leading-tight text-violet-950">{programme.programme_title}</CardTitle>
<div className="flex flex-wrap items-center gap-4 text-sm text-muted-foreground">
<span>{programme.progress ?? 0}% Complete</span>
<span className="flex items-center gap-1">
<Calendar className="h-4 w-4" />
Ends: {formatDate(programme.end_date)}
</span>
<span className="flex items-center gap-1">
<BookOpen className="h-4 w-4" />
{programme.courses} Courses
</span>
<span className="flex items-center gap-1">
<Presentation className="h-4 w-4" />
{programme.webinars} Webinars
</span>
<span className="flex items-center gap-1">
<FolderOpen className="h-4 w-4" />
{programme.resources} Resources
</span>
<span className="flex items-center gap-1">
<Users className="h-4 w-4" />
{programme.classes} Classes
</span>
</div>
</div>
</div>
<Button variant="outline" className="shrink-0 border-violet-300 text-violet-800">
<Info className="mr-2 h-4 w-4" />
Programme Info
</Button>
</div>
</CardHeader>
<div
className={`grid transition-all duration-300 ease-in-out ${isOpen ? 'grid-rows-[1fr] opacity-100' : 'pointer-events-none grid-rows-[0fr] opacity-0'}`}
>
<div className="overflow-hidden">
<CardContent className="space-y-5 pt-4">
<div className="space-y-2 border-b border-violet-100 pb-4">
<h3 className="text-lg font-semibold leading-tight text-foreground">Programme Summary</h3>
<div className="flex flex-wrap items-center gap-4 text-sm text-muted-foreground">
<span className="flex items-center gap-1">
<BookOpen className="h-4 w-4 text-[#061a72]" />
{programme.courses} Courses
</span>
<span className="flex items-center gap-1">
<FolderOpen className="h-4 w-4 text-[#061a72]" />
{programme.resources} Resources
</span>
<span className="flex items-center gap-1">
<Presentation className="h-4 w-4 text-[#061a72]" />
{programme.webinars} Webinars
</span>
<span className="flex items-center gap-1">
<Users className="h-4 w-4 text-[#061a72]" />
{programme.classes} Classes
</span>
</div>
</div>
<div className="space-y-1">
<div className="flex items-center justify-between text-sm">
<span className="font-medium">Progress</span>
<span className="font-medium">{programme.progress ?? 0}%</span>
</div>
<Progress value={programme.progress ?? 0} className="h-2 bg-slate-200" />
</div>
</CardContent>
</div>
</div>
</Card>
);
})}
</div>
</div>
);
};
export default ProgrammesPage;

View File

@@ -288,6 +288,74 @@ interface UpdateLearnerResponse {
correlation_id: string; correlation_id: string;
} }
export interface AssignedHrCoursesQueryParams {
limit: number;
start: number;
search_query?: string;
status?: 'inprogress' | 'completed' | 'new';
}
export interface AssignedHrCourseItem {
id: string;
course_name: string;
course_description: string;
thumbnail_url: string;
total_duration: number;
total_learners: number;
avg_progress: number;
status: 'inprogress' | 'completed' | 'new';
}
interface AssignedHrCoursesResponse {
success: boolean;
status: number;
message: string;
data: {
course_items: AssignedHrCourseItem[];
pagination: {
total: number;
limit: number;
start: number;
has_next: boolean;
};
};
errors: unknown;
correlation_id: string;
}
export interface AssignedHrProgrammesQueryParams {
limit: number;
start: number;
}
export interface AssignedHrProgrammeItem {
id: string;
programme_title: string;
end_date: string;
courses: number;
webinars: number;
resources: number;
classes: number;
progress: number | null;
}
interface AssignedHrProgrammesResponse {
success: boolean;
status: number;
message: string;
data: {
programme_items: AssignedHrProgrammeItem[];
pagination: {
total: number;
limit: number;
start: number;
has_next: boolean;
};
};
errors: unknown;
correlation_id: string;
}
const API_BASE_URL = import.meta.env.VITE_API_URL; const API_BASE_URL = import.meta.env.VITE_API_URL;
export const learnersApi = createApi({ export const learnersApi = createApi({
@@ -440,6 +508,31 @@ export const learnersApi = createApi({
}), }),
invalidatesTags: ['Learners'], invalidatesTags: ['Learners'],
}), }),
getAssignedHrCourses: builder.query<AssignedHrCoursesResponse, AssignedHrCoursesQueryParams>({
query: (params) => ({
url: '/hr/organization/assigned-courses/hr',
method: 'GET',
params: {
limit: params.limit,
start: params.start,
search_query: params.search_query || undefined,
status: params.status || undefined,
},
}),
}),
getAssignedHrProgrammes: builder.query<
AssignedHrProgrammesResponse,
AssignedHrProgrammesQueryParams
>({
query: (params) => ({
url: '/hr/organization/assigned-programmes/hr',
method: 'GET',
params: {
limit: params.limit,
start: params.start,
},
}),
}),
}), }),
}); });
@@ -457,4 +550,6 @@ export const {
useGetAssignedCoursesForOrganizationQuery, useGetAssignedCoursesForOrganizationQuery,
useGetLearnerCoursesQuery, useGetLearnerCoursesQuery,
useUpdateLearnerMutation, useUpdateLearnerMutation,
useGetAssignedHrCoursesQuery,
useGetAssignedHrProgrammesQuery,
} = learnersApi; } = learnersApi;

View File

@@ -9,6 +9,8 @@ import ReportsPage from '../pages/ReportsPage/ReportsPage';
import DiscussionsPage from '../pages/DiscussionsPage/DiscussionsPage'; import DiscussionsPage from '../pages/DiscussionsPage/DiscussionsPage';
import ProgrammeViewPage from '../pages/ProgrammeViewPage/ProgrammeViewPage'; import ProgrammeViewPage from '../pages/ProgrammeViewPage/ProgrammeViewPage';
import CourseViewPage from '../pages/CourseViewPage/CourseViewPage'; import CourseViewPage from '../pages/CourseViewPage/CourseViewPage';
import CoursesPage from '../pages/Courses/CoursesPage';
import ProgrammesPage from '../pages/Programmes/ProgrammesPage';
export const router = createBrowserRouter([ export const router = createBrowserRouter([
{ {
@@ -46,6 +48,14 @@ export const router = createBrowserRouter([
path: 'reports', path: 'reports',
element: <ReportsPage />, element: <ReportsPage />,
}, },
{
path: 'courses',
element: <CoursesPage />,
},
{
path: 'programmes',
element: <ProgrammesPage />,
},
{ {
path: 'discussions', path: 'discussions',
element: <DiscussionsPage />, element: <DiscussionsPage />,