Files
KLC-Hr-Dashboard-Frontend/src/pages/Programmes/ProgrammesPage.tsx
priyanshuvish bd36b3c9d1
All checks were successful
Build-Check / Build and Test PR (pull_request) Successful in 35s
Sonar Check / SonarQube Scan (pull_request) Successful in 58s
add dummy assign profiler and added course and programme
2026-04-23 19:53:27 +05:30

134 lines
6.2 KiB
TypeScript

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;