diff --git a/package-lock.json b/package-lock.json index 0843507..8cefc8c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -34,6 +34,7 @@ "@radix-ui/react-toggle": "^1.1.2", "@radix-ui/react-toggle-group": "^1.1.2", "@radix-ui/react-tooltip": "^1.1.8", + "@reduxjs/toolkit": "^2.9.0", "@tailwindcss/postcss": "^4.1.12", "class-variance-authority": "^0.7.1", "clsx": "*", @@ -48,6 +49,7 @@ "react-day-picker": "^8.10.1", "react-dom": "^18.3.1", "react-hook-form": "^7.55.0", + "react-redux": "^9.2.0", "react-resizable-panels": "^2.1.7", "react-router-dom": "^7.8.2", "recharts": "^2.15.2", @@ -1891,6 +1893,32 @@ "integrity": "sha512-HPwpGIzkl28mWyZqG52jiqDJ12waP11Pa1lGoiyUkIEuMLBP0oeK/C89esbXrxsky5we7dfd8U58nm0SgAWpVw==", "license": "MIT" }, + "node_modules/@reduxjs/toolkit": { + "version": "2.9.0", + "resolved": "https://registry.npmjs.org/@reduxjs/toolkit/-/toolkit-2.9.0.tgz", + "integrity": "sha512-fSfQlSRu9Z5yBkvsNhYF2rPS8cGXn/TZVrlwN1948QyZ8xMZ0JvP50S2acZNaf+o63u6aEeMjipFyksjIcWrog==", + "license": "MIT", + "dependencies": { + "@standard-schema/spec": "^1.0.0", + "@standard-schema/utils": "^0.3.0", + "immer": "^10.0.3", + "redux": "^5.0.1", + "redux-thunk": "^3.1.0", + "reselect": "^5.1.0" + }, + "peerDependencies": { + "react": "^16.9.0 || ^17.0.0 || ^18 || ^19", + "react-redux": "^7.2.1 || ^8.1.3 || ^9.0.0" + }, + "peerDependenciesMeta": { + "react": { + "optional": true + }, + "react-redux": { + "optional": true + } + } + }, "node_modules/@rolldown/pluginutils": { "version": "1.0.0-beta.27", "resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz", @@ -2178,6 +2206,18 @@ "win32" ] }, + "node_modules/@standard-schema/spec": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@standard-schema/spec/-/spec-1.0.0.tgz", + "integrity": "sha512-m2bOd0f2RT9k8QJx1JN85cZYyH1RqFBdlwtkSlf4tBDYLCiiZnv1fIIwacK6cqwXavOydf0NPToMQgpKq+dVlA==", + "license": "MIT" + }, + "node_modules/@standard-schema/utils": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@standard-schema/utils/-/utils-0.3.0.tgz", + "integrity": "sha512-e7Mew686owMaPJVNNLs55PUvgz371nKgwsc4vxE49zsODpJEnxgxRo2y/OKrqueavXgZNMDVj3DdHFlaSAeU8g==", + "license": "MIT" + }, "node_modules/@swc/core": { "version": "1.13.5", "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.13.5.tgz", @@ -2765,6 +2805,12 @@ "@types/react": "^19.0.0" } }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.6", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz", + "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==", + "license": "MIT" + }, "node_modules/@vitejs/plugin-react-swc": { "version": "3.11.0", "resolved": "https://registry.npmjs.org/@vitejs/plugin-react-swc/-/plugin-react-swc-3.11.0.tgz", @@ -3167,6 +3213,16 @@ "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", "license": "ISC" }, + "node_modules/immer": { + "version": "10.1.3", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.1.3.tgz", + "integrity": "sha512-tmjF/k8QDKydUlm3mZU+tjM6zeq9/fFpPqH9SzWmBnVVKsPBg/V66qsMwb3/Bo90cgUN+ghdVBess+hPsxUyRw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/input-otp": { "version": "1.4.2", "resolved": "https://registry.npmjs.org/input-otp/-/input-otp-1.4.2.tgz", @@ -3691,6 +3747,29 @@ "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==", "license": "MIT" }, + "node_modules/react-redux": { + "version": "9.2.0", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz", + "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==", + "license": "MIT", + "dependencies": { + "@types/use-sync-external-store": "^0.0.6", + "use-sync-external-store": "^1.4.0" + }, + "peerDependencies": { + "@types/react": "^18.2.25 || ^19", + "react": "^18.0 || ^19", + "redux": "^5.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, "node_modules/react-remove-scroll": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/react-remove-scroll/-/react-remove-scroll-2.7.1.tgz", @@ -3871,6 +3950,27 @@ "decimal.js-light": "^2.4.1" } }, + "node_modules/redux": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz", + "integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==", + "license": "MIT" + }, + "node_modules/redux-thunk": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/redux-thunk/-/redux-thunk-3.1.0.tgz", + "integrity": "sha512-NW2r5T6ksUKXCabzhL9z+h206HQw/NJkcLm1GPImRQ8IzfXwRGqjVhKJGauHirT0DAuyy6hjdnMZaRoAcy0Klw==", + "license": "MIT", + "peerDependencies": { + "redux": "^5.0.0" + } + }, + "node_modules/reselect": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz", + "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==", + "license": "MIT" + }, "node_modules/rollup": { "version": "4.49.0", "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.49.0.tgz", diff --git a/package.json b/package.json index 24082b8..717df5f 100644 --- a/package.json +++ b/package.json @@ -29,6 +29,7 @@ "@radix-ui/react-toggle": "^1.1.2", "@radix-ui/react-toggle-group": "^1.1.2", "@radix-ui/react-tooltip": "^1.1.8", + "@reduxjs/toolkit": "^2.9.0", "@tailwindcss/postcss": "^4.1.12", "class-variance-authority": "^0.7.1", "clsx": "*", @@ -43,6 +44,7 @@ "react-day-picker": "^8.10.1", "react-dom": "^18.3.1", "react-hook-form": "^7.55.0", + "react-redux": "^9.2.0", "react-resizable-panels": "^2.1.7", "react-router-dom": "^7.8.2", "recharts": "^2.15.2", diff --git a/src/Redux/Store.tsx b/src/Redux/Store.tsx new file mode 100644 index 0000000..a985924 --- /dev/null +++ b/src/Redux/Store.tsx @@ -0,0 +1,11 @@ +import {configureStore} from '@reduxjs/toolkit'; +import { demoApi } from './services/demo.service'; + +export const store = configureStore({ + reducer: { + [demoApi.reducerPath]: demoApi.reducer}, + middleware: (getDefaultMiddleware) => + getDefaultMiddleware().concat(demoApi.middleware), +}); +export type RootState = ReturnType; +export type AppDispatch = typeof store.dispatch; \ No newline at end of file diff --git a/src/Redux/services/demo.service.ts b/src/Redux/services/demo.service.ts new file mode 100644 index 0000000..1c9c23b --- /dev/null +++ b/src/Redux/services/demo.service.ts @@ -0,0 +1,16 @@ +// import { createApi } from '@reduxjs/toolkit/query' +import { fetchBaseQuery, createApi } from '@reduxjs/toolkit/query/react' + + +export const demoApi = createApi({ + reducerPath: 'demoApi', + baseQuery: fetchBaseQuery({ baseUrl: "https://jsonplaceholder.typicode.com" }), + endpoints: (builder) => ({ + // GET example + getPosts: builder.query({ + query: () => "/posts", + }), + }), +}) + +export const { useGetPostsQuery } = demoApi; \ No newline at end of file diff --git a/src/components/HeroSection.tsx b/src/components/HeroSection.tsx new file mode 100644 index 0000000..881d134 --- /dev/null +++ b/src/components/HeroSection.tsx @@ -0,0 +1,186 @@ +import React from 'react'; +import { Button } from './ui/button'; +import { ArrowRight, ChevronLeft, ChevronRight } from 'lucide-react'; +import { ImageWithFallback } from './figma/ImageWithFallback'; +// import heroBannerImage from 'figma:asset/1bb9c22c86c0892d4716564b7135835f04869298.png'; +const heroBannerImage = 'https://images.unsplash.com/photo-1504384308090-c894fdcc538d?ixlib=rb-4.0.3&ixid=M3wxMjA3fDB8MHxwaG90by1wYWdlfHx8fGVufDB8fHx8fA%3D%3D&auto=format&fit=crop&w=1470&q=80'; + +interface HeroSectionProps { + showAnnouncementBar?: boolean; + announcementText?: string; + announcementCTA?: string; + title?: string; + subtitle?: string; + ctaText?: string; + onAnnouncementClick?: () => void; + onCTAClick?: () => void; + showFeatures?: boolean; +} + +export function HeroSection({ + showAnnouncementBar = true, + announcementText = "Join Our Upcoming Leadership Webinars - Transform Your Leadership Journey", + announcementCTA = "Enroll Now", + title = "Empowering Future-Ready Leaders", + subtitle = "Build confidence, agility, and clarity for today's complex challenges.", + ctaText = "Build Your Leadership Pipeline", + onAnnouncementClick, + onCTAClick, + showFeatures = true +}: HeroSectionProps) { + + const handleAnnouncementClick = () => { + if (onAnnouncementClick) { + onAnnouncementClick(); + } else { + window.location.href = '/webinars?view=individual'; + } + }; + + const handleCTAClick = () => { + if (onCTAClick) { + onCTAClick(); + } else { + window.location.href = '/dashboard?view=individual'; + } + }; + + return ( +
+ {/* Top Announcement Bar */} + {showAnnouncementBar && ( +
+
+
+ + {announcementText} + + +
+
+
+ )} + + {/* Main Hero Section */} +
+ {/* Background Image */} +
+ + {/* Overlay for better text readability */} +
+
+ + {/* Hero Content */} +
+
+
+ {/* Main Heading */} +

+ {title} +

+ + {/* Subtext */} +

+ {subtitle} +

+ + {/* CTA Button */} +
+ +
+
+
+
+ + {/* Bottom Feature Navigation */} + {showFeatures && ( +
+
+
+ {/* Feature 01 */} +
+
+
01
+
+
+
+

Leadership Is Learning. We Teach It Right.

+

+ Master proven methodologies and frameworks that transform managers into exceptional leaders. +

+
+
+ + {/* Feature 02 */} +
+
+
02
+
+
+
+

Turn Managers Into Impactful Leaders

+

+ Develop strategic thinking, emotional intelligence, and decision-making capabilities. +

+
+
+ + {/* Feature 03 */} +
+
+
03
+
+
+
+

Struggling with Managerial Gaps?

+

+ Bridge the gap between individual contribution and effective team leadership. +

+
+
+
+
+ + {/* Navigation Controls */} +
+ + +
+
+ )} +
+
+ ); +} \ No newline at end of file diff --git a/src/components/Navigation.tsx b/src/components/Navigation.tsx new file mode 100644 index 0000000..f47a6cb --- /dev/null +++ b/src/components/Navigation.tsx @@ -0,0 +1,712 @@ +import React, { useState, useEffect } from 'react'; +import { Button } from './ui/button'; +import { Input } from './ui/input'; +import { Avatar, AvatarFallback, AvatarImage } from './ui/avatar'; +import { Badge } from './ui/badge'; +import { + DropdownMenu, + DropdownMenuContent, + DropdownMenuItem, + DropdownMenuTrigger, + DropdownMenuSeparator, + DropdownMenuLabel, +} from './ui/dropdown-menu'; +import { + Sheet, + SheetContent, + SheetHeader, + SheetTitle, + SheetTrigger, +} from './ui/sheet'; +import { Collapsible, CollapsibleContent, CollapsibleTrigger } from './ui/collapsible'; +// import { navigate } from './Router'; +import { useAuth } from './AuthContext'; +// import klcLogo from 'figma:asset/209958db0c439ec78be82ab4f3e335a6aed5de89.png'; +// import exampleImage from 'figma:asset/6cae567b6bf6a44cb03b767e4308c4c705340d08.png'; +const klcLogo = 'https://res.cloudinary.com/dt3k2apqd/image/upload/v1697045531/Kautilya_Leadership_Centre_Logo_hor_uxh0v4.png'; +const exampleImage = 'https://images.unsplash.com/photo-1508214751196-bcfd4ca60f91?w=150&h=150&fit=crop&crop=face'; +import { + Menu, + ChevronDown, + ChevronRight, + ShoppingCart, + Search, + Building2, + User, + Settings, + LogOut, + LayoutDashboard, + Users, + Target, + Award, + Lightbulb, + GraduationCap, + BookOpen, + Video, + FileText, + Eye, + Heart, + MapPin, + Calendar, + Play, + Home, + Check, + ArrowRight +} from 'lucide-react'; +import { useNavigate } from 'react-router-dom'; +const navigate = useNavigate(); +interface NavigationProps { + currentPage?: string; +} + +export function Navigation({ currentPage }: NavigationProps) { + const [isScrolled, setIsScrolled] = useState(false); + const [activeDropdown, setActiveDropdown] = useState(null); + const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false); + const [expandedMobileSection, setExpandedMobileSection] = useState(null); + + const { user, login, signOut, isAuthenticated } = useAuth(); + + // Determine user type from URL or user data + const getQueryParam = (param: string) => { + const urlParams = new URLSearchParams(window.location.search); + return urlParams.get(param); + }; + + const isIndividualUser = getQueryParam('view') === 'individual' || + (!getQueryParam('view') && currentPage?.includes('/dashboard')) || + (!getQueryParam('view') && currentPage?.includes('/library')) || + (!getQueryParam('view') && currentPage?.includes('/course')) || + (!getQueryParam('view') && currentPage?.includes('/settings')) || + (!getQueryParam('view') && currentPage?.includes('/surveys')) || + (!getQueryParam('view') && currentPage?.includes('/webinars')) || + (!getQueryParam('view') && currentPage?.includes('/leaderboard')); + + const isCorporateUser = getQueryParam('view') === 'corporate'; + + useEffect(() => { + const handleScroll = () => { + setIsScrolled(window.scrollY > 10); + }; + + window.addEventListener('scroll', handleScroll); + return () => window.removeEventListener('scroll', handleScroll); + }, []); + + useEffect(() => { + const handleClickOutside = (event: MouseEvent) => { + const target = event.target as Element; + if (!target.closest('[data-dropdown]')) { + setActiveDropdown(null); + } + }; + + document.addEventListener('click', handleClickOutside); + return () => document.removeEventListener('click', handleClickOutside); + }, []); + + const handleDropdownToggle = (dropdown: string) => { + setActiveDropdown(activeDropdown === dropdown ? null : dropdown); + }; + + const handleMobileToggle = (section: string) => { + setExpandedMobileSection(expandedMobileSection === section ? null : section); + }; + + const handleLogin = () => { + navigate('/auth'); // Route to login selection page + setIsMobileMenuOpen(false); + }; + + const handleSignup = () => { + navigate('/signup'); + setIsMobileMenuOpen(false); + }; + + const handleLogout = () => { + signOut(); + navigate('/'); + setActiveDropdown(null); + setIsMobileMenuOpen(false); + }; + + const handleAccountSignIn = (accountType: 'individual' | 'corporate') => { + // Navigate to appropriate sign-in page for the account type + if (accountType === 'individual') { + navigate('/login'); + } else { + navigate('/corporate/login'); + } + setActiveDropdown(null); + setIsMobileMenuOpen(false); + }; + + const navigationItems = [ + { + title: 'About Us', + href: '/about-us/our-vision', + items: [ + { title: 'Our Vision', href: '/about-us/our-vision', icon: Eye }, + { title: 'Our Team', href: '/about-us/our-team', icon: Users }, + { title: 'Our Impact', href: '/about-us/our-impact', icon: Target }, + { title: 'Our Expertise', href: '/about-us/our-expertise', icon: Award } + ] + }, + { + title: 'Programmes', + href: '/programmes', + items: [ + { title: 'Programme Catalogue', href: '/programmes', icon: BookOpen }, + { title: 'Executive Leadership', href: '/programmes/executive-leadership', icon: Award }, + { title: 'Team Leadership', href: '/programmes/team-leadership', icon: Users }, + { title: 'Innovation Leadership', href: '/programmes/innovation-leadership', icon: Lightbulb }, + { title: 'Leadership Online', href: '/programmes/leadership-online', icon: Play } + ] + }, + { + title: 'Services', + href: '/services/leadership-development', + items: [ + { title: 'Leadership Development', href: '/services/leadership-development', icon: Target }, + { title: 'Management Development', href: '/services/management-development', icon: Users }, + { title: 'Executive Coaching', href: '/services/executive-coaching', icon: Award }, + { title: 'Culture & Competence', href: '/services/culture-competence', icon: Heart }, + { title: 'Consulting', href: '/services/consulting', icon: Lightbulb }, + { title: 'Learning Facility', href: '/services/learning-facility', icon: MapPin } + ] + }, + { + title: 'Learning', + href: '/learning/articles', + items: [ + { title: 'Articles', href: '/learning/articles', icon: FileText }, + { title: 'Blog', href: '/learning/blog', icon: BookOpen }, + { title: 'Resources', href: '/learning/resources', icon: BookOpen }, + { title: 'Webinars', href: '/individual-webinars', icon: Video } + ] + } + ]; + + const learnerMenuItems = [ + { + title: 'Dashboard', + href: isIndividualUser ? '/dashboard?view=individual' : '/dashboard?view=corporate', + icon: LayoutDashboard, + description: isIndividualUser ? 'Your learning overview' : 'Team management hub' + }, + { + title: 'Library', + href: isIndividualUser ? '/library?view=individual' : '/library?view=corporate', + icon: BookOpen, + description: isIndividualUser ? 'Browse courses' : 'Assigned courses' + }, + { + title: 'Course Timeline', + href: isIndividualUser ? '/course?view=individual' : '/course?view=corporate', + icon: Calendar, + description: isIndividualUser ? 'Your learning path' : 'Team progress' + }, + { + title: 'Surveys & Assessments', + href: isIndividualUser ? '/surveys?view=individual' : '/surveys?view=corporate', + icon: FileText, + description: isIndividualUser ? 'Complete assessments' : 'Team evaluations' + }, + { + title: 'Live Webinars', + href: isIndividualUser ? '/webinars?view=individual' : '/webinars?view=corporate', + icon: Video, + description: isIndividualUser ? 'Join sessions' : 'Corporate events' + }, + { + title: 'Leaderboard', + href: isIndividualUser ? '/leaderboard?view=individual' : '/leaderboard?view=corporate', + icon: Award, + description: isIndividualUser ? 'Your achievements' : 'Team rankings' + }, + { + title: 'Settings', + href: isIndividualUser ? '/settings?view=individual' : '/settings?view=corporate', + icon: Settings, + description: isIndividualUser ? 'Account preferences' : 'Admin settings' + } + ]; + + // Mock data for demonstration - replace with actual user data + const currentUser = { + name: 'Priya Sharma', + email: 'priya.sharma@example.com', + avatar: "https://images.unsplash.com/photo-1494790108755-2616b612b786?w=150&h=150&fit=crop&crop=face", + organization: 'TechCorp Inc.', + role: 'Marketing Team Member' + }; + + const availableAccounts = [ + { + type: 'individual', + isActive: isIndividualUser, + title: 'Personal Learning', + subtitle: 'Access your individual learning portal', + icon: User, + user: currentUser + }, + { + type: 'corporate', + isActive: isCorporateUser, + title: 'Corporate Learning', + subtitle: 'Enterprise team development portal', + icon: Building2, + user: currentUser, + organization: 'TechCorp Inc.' + } + ]; + + return ( + + ); +} \ No newline at end of file diff --git a/src/components/learner/LibraryStats.tsx b/src/components/learner/LibraryStats.tsx new file mode 100644 index 0000000..b85b27d --- /dev/null +++ b/src/components/learner/LibraryStats.tsx @@ -0,0 +1,595 @@ +import React, { useState, useEffect } from 'react'; +import { Card, CardContent, CardHeader, CardTitle } from '../ui/card'; +// import { Progress } from '../ui/progress'; +import { Badge } from '../ui/badge'; +import { Button } from '../ui/button'; +import { + BookOpen, + Clock, + Trophy, + Target, + TrendingUp, + Award, + CheckCircle, + Calendar, + Users, + Star, + Play, + Bookmark, + Search, + Zap, + ArrowRight, + BarChart3, + Brain, + Sparkles, + Flame, + ChevronRight, + Gauge, + Activity, + ChevronLeft, + ChevronDown, + MoreHorizontal +} from 'lucide-react'; +import { + BarChart, + Bar, + XAxis, + YAxis, + CartesianGrid, + ResponsiveContainer, + Tooltip, + PieChart, + Pie, + Cell, + Legend +} from 'recharts'; +import { Course } from '../../pages/learner/data/libraryData'; + +interface LibraryStatsProps { + courses: Course[]; + userType: 'individual' | 'corporate'; +} + + + +export function LibraryStats({ courses, userType }: LibraryStatsProps) { + const [isVisible, setIsVisible] = useState(false); + const [selectedTimeRange, setSelectedTimeRange] = useState('December'); + + // Calculate statistics + const stats = { + totalCourses: courses.length, + completedCourses: courses.filter(c => c.status === 'completed').length, + inProgressCourses: courses.filter(c => c.status === 'in-progress').length, + bookmarkedCourses: courses.filter(c => c.status === 'bookmarked').length, + assignedCourses: userType === 'corporate' ? courses.filter(c => c.organizationAssigned).length : 0, + overdueCourses: userType === 'corporate' ? courses.filter(c => c.status === 'not-started').length : undefined, + completionRate: courses.length > 0 ? (courses.filter(c => c.status === 'completed').length / courses.length) * 100 : 0, + averageRating: courses.length > 0 ? courses.reduce((sum, c) => sum + c.rating, 0) / courses.length : 0, + totalHours: courses.reduce((sum, c) => sum + parseFloat(c.duration.replace(/[^\d.]/g, '')), 0), + certificatesEarned: courses.filter(c => c.status === 'completed').length + }; + + useEffect(() => { + const timer = setTimeout(() => setIsVisible(true), 100); + return () => clearTimeout(timer); + }, []); + + // Performance chart data (bar chart showing progress over time) + const performanceData = [ + { name: 'Jan', value: 1, color: '#04045B' }, + { name: 'Feb', value: 2, color: '#04045B' }, + { name: 'Mar', value: 4, color: '#04045B' }, + { name: 'Apr', value: 6, color: '#04045B' }, + { name: 'May', value: 7, color: '#04045B' }, + { name: 'Jun', value: 8, color: '#04045B' } + ]; + + + + // Time learning data (stacked bar chart) + const timeLearningData = [ + { date: 'Apr 18', performance: 2, consistency: 1, unknown: 0.5 }, + { date: 'Apr 19', performance: 3, consistency: 2, unknown: 1 }, + { date: 'Apr 20', performance: 1.5, consistency: 2.5, unknown: 0.5 }, + { date: 'Apr 21', performance: 4, consistency: 1, unknown: 1 }, + { date: 'Apr 22', performance: 2, consistency: 3, unknown: 0.5 }, + { date: 'Apr 23', performance: 3.5, consistency: 1.5, unknown: 1 }, + { date: 'Apr 24', performance: 2.5, consistency: 2, unknown: 1.5 } + ]; + + // Course list with progress + const courseList = [ + { name: 'Introduction to Strategic Leadership', lessons: '24/30 Lessons', progress: 80, color: '#04045B' }, + { name: 'English for Effective Communication', lessons: '18/25 Lessons', progress: 72, color: '#10B981' }, + { name: 'Introduction to Team Management', lessons: '14/20 Lessons', progress: 70, color: '#F8C301' }, + { name: 'Introduction to Digital Leadership', lessons: '8/15 Lessons', progress: 53, color: '#6366F1' } + ]; + + // Daily activity timeline + const dailyActivities = [ + { time: '07:00', course: 'Introduction to Strategic Leadership', type: 'Google Meeting', color: '#F8C301', instructor: 'A' }, + { time: '08:00', course: '', type: '', color: '', instructor: '' }, + { time: '09:00', course: 'English for Effective Communication', type: 'Google Meeting', color: '#3B82F6', instructor: 'E' }, + { time: '10:00', course: '', type: '', color: '', instructor: '' }, + { time: '11:00', course: '', type: '', color: '', instructor: '' }, + { time: '12:00', course: 'Introduction to Digital Leadership', type: 'Google Meeting', color: '#6366F1', instructor: 'I' }, + { time: '01:00', course: '', type: '', color: '', instructor: '' } + ]; + + // Month navigation functionality + const months = [ + 'January', 'February', 'March', 'April', 'May', 'June', + 'July', 'August', 'September', 'October', 'November', 'December' + ]; + + const navigateMonth = (direction: 'prev' | 'next') => { + const currentIndex = months.findIndex(month => month === selectedTimeRange); + let newIndex; + + if (direction === 'prev') { + newIndex = currentIndex <= 0 ? months.length - 1 : currentIndex - 1; + } else { + newIndex = currentIndex >= months.length - 1 ? 0 : currentIndex + 1; + } + + setSelectedTimeRange(months[newIndex]); + }; + + const handleWheel = (e: React.WheelEvent) => { + e.preventDefault(); + + // Throttle wheel events to prevent rapid scrolling + const now = Date.now(); + const lastWheelTime = (e.currentTarget as any)._lastWheelTime || 0; + + if (now - lastWheelTime < 200) return; // 200ms throttle + + (e.currentTarget as any)._lastWheelTime = now; + + if (e.deltaY > 0) { + navigateMonth('next'); + } else { + navigateMonth('prev'); + } + }; + + return ( +
+ {/* Dashboard Grid Layout - Matching Reference Image */} +
+ + {/* Top Row */} + + {/* Simplified Performance Chart */} +
+ + +
+ + Performance + + +
+
+ {stats.completedCourses} Course Completed +
+
+ + + + + + + + + + + + + + [`${value} courses`, 'Completed']} + labelStyle={{ color: '#111827', fontWeight: 600, marginBottom: '4px' }} + /> + + + +
+
+ + {/* Simplified Time Learning Chart */} +
+ + +
+
+ + Time spend on learning + +
+ 4 Course Completed +
+
+
+
+ + + {selectedTimeRange} + + +
+
+
+
+ + +
+ + + + + + + + + + + + + + + + +
+ + {/* Enhanced Legend */} +
+
+
+ Performance +
+
+
+ Consistency +
+
+
+ Other +
+
+
+
+
+ + {/* Bottom Row */} + + {/* Enhanced Your Courses (7 columns) */} +
+ + +
+
+ + Your Courses + +
+ {courseList.length} Course{courseList.length !== 1 ? 's' : ''} • {courseList.filter(c => c.progress === 100).length} Completed +
+
+ +
+
+ + +
+ {courseList.map((course, index) => { + const isCompleted = course.progress === 100; + const isInProgress = course.progress > 0 && course.progress < 100; + const isNotStarted = course.progress === 0; + + return ( +
window.location.href = '/course?view=individual'} + > + {/* Enhanced Course Avatar */} +
+
+ {course.name.charAt(0)} +
+ {/* Status Indicator */} + {isCompleted && ( +
+ +
+ )} + {isInProgress && ( +
+ )} +
+ + {/* Course Information */} +
+
+

+ {course.name} +

+
+ + {course.progress}% + + {isCompleted && ( + + Complete + + )} +
+
+ +
+ + {course.lessons} + + + • {isCompleted ? 'Completed' : isInProgress ? 'In Progress' : 'Not Started'} + + {isInProgress && ( + + • Continue Learning + + )} +
+ + {/* Enhanced Progress Bar */} +
+
+
+ {/* Progress bar shine effect */} +
+
+
+ + {/* Action Button */} +
+ {isCompleted ? ( + + ) : isInProgress ? ( + + ) : ( + + )} +
+
+
+ + {/* Hover Arrow */} +
+ +
+
+ ); + })} + + {/* Quick Action Footer */} +
+
+
+
+
+ Completed +
+
+
+ In Progress +
+
+
+ Not Started +
+
+ +
+
+
+
+
+
+ + {/* Daily Activity (5 columns) */} +
+ + +
+
+ + Daily activity + +
+ Today Apr 24 +
+
+
+
+ + +
+ {dailyActivities.map((activity, index) => ( +
+
+ {activity.time} +
+
+ {activity.course && ( +
+ )} +
+
+ {activity.course ? ( +
+
+
+ {activity.course} +
+
+ {activity.type} +
+
+
+ {activity.instructor} +
+
+ ) : ( +
+ )} +
+
+ ))} +
+
+
+
+
+
+ ); +} \ No newline at end of file diff --git a/src/main.tsx b/src/main.tsx index d96f8d8..2185878 100644 --- a/src/main.tsx +++ b/src/main.tsx @@ -1,7 +1,12 @@ +import { createRoot } from "react-dom/client"; +import { BrowserRouter } from "react-router-dom"; +import App from "./App.tsx"; +import "./styles/globals.css"; +import { Provider } from "react-redux"; +import { store } from "./Redux/Store.tsx"; - import { createRoot } from "react-dom/client"; - import App from "./App.tsx"; - import "./index.css"; - - createRoot(document.getElementById("root")!).render(); - \ No newline at end of file +createRoot(document.getElementById("root")!).render( + + + +); diff --git a/src/pages/CorporateLeaderboard.tsx b/src/pages/CorporateLeaderboard.tsx new file mode 100644 index 0000000..ec86c25 --- /dev/null +++ b/src/pages/CorporateLeaderboard.tsx @@ -0,0 +1,794 @@ +import React, { useState, useEffect } from 'react'; +import { LearnerLayout } from '../components/learner/LearnerLayout'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../components/ui/card'; +import { Button } from '../components/ui/button'; +import { Input } from '../components/ui/input'; +import { Badge } from '../components/ui/badge'; +import { Avatar, AvatarFallback, AvatarImage } from '../components/ui/avatar'; +import { Tabs, TabsContent, TabsList, TabsTrigger } from '../components/ui/tabs'; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../components/ui/select'; +import { Progress } from '../components/ui/progress'; +import { Separator } from '../components/ui/separator'; +import { motion } from 'motion/react'; +import { + ArrowLeft, + Trophy, + Medal, + Award, + Target, + TrendingUp, + Users, + Download, + Filter, + Search, + Crown, + Star, + Gift, + Zap, + ChevronRight, + Calendar, + Clock, + BookOpen, + CheckCircle, + BarChart3, + PieChart, + ArrowUp, + ArrowDown, + Minus, + Settings, + Flag, + Sparkles +} from 'lucide-react'; +import { useNavigate } from 'react-router-dom'; + const navigate = useNavigate(); + +// Mock data for leaderboard +const mockLeaderboard = [ + { + id: 1, + rank: 1, + name: "Alexandra Chen", + title: "Senior Director", + department: "Operations", + avatar: "https://images.unsplash.com/photo-1494790108755-2616b612b786?w=150&h=150&fit=crop&crop=face", + totalPoints: 2847, + monthlyPoints: 485, + coursesCompleted: 12, + streakDays: 28, + level: "Expert", + progress: 85, + trend: "up", + badges: ["Leadership Excellence", "Team Builder", "Innovation Champion"], + lastActive: "2 hours ago", + completionRate: 94 + }, + { + id: 2, + rank: 2, + name: "Michael Rodriguez", + title: "VP Engineering", + department: "Technology", + avatar: "https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=150&h=150&fit=crop&crop=face", + totalPoints: 2756, + monthlyPoints: 423, + coursesCompleted: 11, + streakDays: 22, + level: "Expert", + progress: 76, + trend: "up", + badges: ["Tech Leader", "Mentor", "Strategic Thinker"], + lastActive: "4 hours ago", + completionRate: 89 + }, + { + id: 3, + rank: 3, + name: "Sarah Johnson", + title: "Director of Sales", + department: "Sales", + avatar: "https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=150&h=150&fit=crop&crop=face", + totalPoints: 2634, + monthlyPoints: 398, + coursesCompleted: 10, + streakDays: 19, + level: "Advanced", + progress: 68, + trend: "up", + badges: ["Sales Champion", "Customer Focus", "Results Driver"], + lastActive: "1 hour ago", + completionRate: 91 + }, + { + id: 4, + rank: 4, + name: "David Kim", + title: "Marketing Manager", + department: "Marketing", + avatar: "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=150&h=150&fit=crop&crop=face", + totalPoints: 2521, + monthlyPoints: 367, + coursesCompleted: 9, + streakDays: 15, + level: "Advanced", + progress: 52, + trend: "stable", + badges: ["Creative Leader", "Brand Builder", "Analytics Pro"], + lastActive: "6 hours ago", + completionRate: 87 + }, + { + id: 5, + rank: 5, + name: "Emily Watson", + title: "HR Director", + department: "Human Resources", + avatar: "https://images.unsplash.com/photo-1573496359142-b8d87734a5a2?w=150&h=150&fit=crop&crop=face", + totalPoints: 2398, + monthlyPoints: 334, + coursesCompleted: 8, + streakDays: 12, + level: "Advanced", + progress: 45, + trend: "down", + badges: ["People Leader", "Culture Champion", "Diversity Advocate"], + lastActive: "3 hours ago", + completionRate: 92 + }, + { + id: 6, + rank: 6, + name: "James Thompson", + title: "Finance Manager", + department: "Finance", + avatar: "https://images.unsplash.com/photo-1556157382-97eda2d62296?w=150&h=150&fit=crop&crop=face", + totalPoints: 2267, + monthlyPoints: 298, + coursesCompleted: 7, + streakDays: 8, + level: "Intermediate", + progress: 34, + trend: "up", + badges: ["Financial Acumen", "Risk Manager", "Process Optimizer"], + lastActive: "5 hours ago", + completionRate: 85 + } +]; + +// Animated number counter component +const AnimatedNumber = ({ value, duration = 1000 }: { value: number; duration?: number }) => { + const [displayValue, setDisplayValue] = useState(0); + + useEffect(() => { + let startTime: number; + let animationFrame: number; + + const animate = (timestamp: number) => { + if (!startTime) startTime = timestamp; + const progress = Math.min((timestamp - startTime) / duration, 1); + + // Easing function for smooth animation + const easeOut = 1 - Math.pow(1 - progress, 3); + setDisplayValue(Math.floor(value * easeOut)); + + if (progress < 1) { + animationFrame = requestAnimationFrame(animate); + } + }; + + animationFrame = requestAnimationFrame(animate); + + return () => { + if (animationFrame) { + cancelAnimationFrame(animationFrame); + } + }; + }, [value, duration]); + + return {displayValue.toLocaleString()}; +}; + +export function CorporateLeaderboard() { + const [searchQuery, setSearchQuery] = useState(''); + const [selectedDepartment, setSelectedDepartment] = useState('all'); + const [selectedLevel, setSelectedLevel] = useState('all'); + const [sortBy, setSortBy] = useState('rank'); + const [timeFilter, setTimeFilter] = useState('month'); + + // Mock corporate user data matching dashboard pattern + const user = { + name: "Sarah Johnson", + email: "sarah.johnson@company.com", + avatar: "https://images.unsplash.com/photo-1494790108755-2616b612b786?w=150&h=150&fit=crop&crop=face", + organization: "TCS", + orgLogo: "https://images.unsplash.com/photo-1560179707-f14e90ef3623?w=32&h=32&fit=crop", + role: "Senior Manager", + cohort: "Leadership 2024" + }; + + const getRankIcon = (rank: number) => { + switch (rank) { + case 1: + return ; + case 2: + return ; + case 3: + return ; + default: + return ; + } + }; + + const getTrendIcon = (trend: string) => { + switch (trend) { + case 'up': + return ; + case 'down': + return ; + default: + return ; + } + }; + + // Filter leaderboard data + const filteredLeaderboard = mockLeaderboard.filter(user => { + const matchesSearch = user.name.toLowerCase().includes(searchQuery.toLowerCase()) || + user.department.toLowerCase().includes(searchQuery.toLowerCase()) || + user.title.toLowerCase().includes(searchQuery.toLowerCase()); + + const matchesDepartment = selectedDepartment === 'all' || user.department === selectedDepartment; + const matchesLevel = selectedLevel === 'all' || user.level === selectedLevel; + + return matchesSearch && matchesDepartment && matchesLevel; + }); + + // Get unique departments and levels for filters + const departments = Array.from(new Set(mockLeaderboard.map(user => user.department))); + const levels = Array.from(new Set(mockLeaderboard.map(user => user.level))); + + return ( + +
+ {/* KPI Cards - Matching Dashboard Design with Brand Colors */} +
+ + +
+ +
+

128

+

Active Learners

+
+
+ + + +
+ +
+

1,247

+

Courses Completed

+
+
+ + + +
+ +
+

89%

+

Avg Completion

+
+
+ + + +
+ +
+

+23%

+

This Month

+
+
+
+ + {/* Time Period Filter - Enhanced Design */} + + +
+
+

Performance Tracking

+

View leaderboard data across different time periods

+
+ +
+ + + +
+
+
+
+ + {/* Top Performers - Enhanced with KLC Branding */} + + + +
+
+ +
+
+ Top Performers This Month + + Celebrating our highest achievers and their outstanding dedication + +
+
+
+ +
+ {filteredLeaderboard.slice(0, 3).map((user, index) => { + const isFirst = index === 0; + const isSecond = index === 1; + const isThird = index === 2; + + return ( + + + {/* Subtle Metallic Shimmer Effect for Top 3 */} +
+ + {/* Rank Ribbon with KLC Colors */} + + #{user.rank} + + + {/* Winner Crown for First Place */} + {isFirst && ( + + + + )} + + + {/* Rank Icon */} + +
+ {getRankIcon(user.rank)} +
+
+ + {/* User Avatar with Enhanced Styling */} + + + + + {user.name.split(' ').map(n => n[0]).join('')} + + + {/* Trend Indicator */} + + {getTrendIcon(user.trend)} + + + + {/* User Information */} + +

{user.name}

+

{user.title}

+

{user.department}

+
+ + {/* Performance Stats */} + +
+

+ +

+

Points

+
+
+

+ +

+

Courses

+
+
+

+ +

+

Day Streak

+
+
+ + {/* Level Progress */} + +
+ Level Progress + + {user.level} + +
+ +

{user.progress}% to next level

+
+ + {/* Achievement Badges */} + +

Recent Achievements

+
+ {user.badges.slice(0, 3).map((badge, badgeIndex) => ( + + + {badge} + + + ))} +
+
+ + {/* Monthly Performance Indicator */} + +
+ + + + this month + +
+
+
+ + + ); + })} +
+ +
+
+ + {/* Search and Filters - Matching Dashboard Design */} + + +
+ {/* Search Bar */} +
+ + setSearchQuery(e.target.value)} + className="pl-10 text-base h-11" + /> +
+ + {/* Filters Row */} +
+ + + + + + + +
+
+
+
+ + {/* Full Leaderboard Table - Enhanced Design */} + + +
+
+
+ +
+
+ Complete Leaderboard +

+ View all team members and their performance metrics +

+
+
+ + {filteredLeaderboard.length} {filteredLeaderboard.length === 1 ? 'learner' : 'learners'} + +
+
+ + +
+ {filteredLeaderboard.map((user, index) => ( + +
+ {/* Rank */} +
+
+ {user.rank <= 3 ? getRankIcon(user.rank) : ( + #{user.rank} + )} +
+
+ + {/* Avatar and User Info */} +
+ + + + {user.name.split(' ').map(n => n[0]).join('')} + + + +
+
+

+ {user.name} +

+ {getTrendIcon(user.trend)} +
+
+ {user.title} + + {user.department} + + + {user.level} + +
+
+
+ + {/* Performance Stats */} +
+
+

{user.totalPoints.toLocaleString()}

+

Points

+
+
+

{user.coursesCompleted}

+

Courses

+
+
+

{user.streakDays}

+

Streak

+
+
+

{user.completionRate}%

+

Complete

+
+
+ + {/* Action */} + +
+ + {/* Mobile Stats */} +
+
+

{user.totalPoints.toLocaleString()}

+

Points

+
+
+

{user.coursesCompleted}

+

Courses

+
+
+

{user.streakDays}

+

Streak

+
+
+

{user.completionRate}%

+

Complete

+
+
+
+ ))} +
+
+
+
+ + ); +} \ No newline at end of file diff --git a/src/pages/Surveys.tsx b/src/pages/Surveys.tsx new file mode 100644 index 0000000..452f34e --- /dev/null +++ b/src/pages/Surveys.tsx @@ -0,0 +1,954 @@ +import React, { useState, useEffect, useRef } from 'react'; +import { LearnerLayout } from '../components/learner/LearnerLayout'; +import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../components/ui/card'; +import { Button } from '../components/ui/button'; +import { Input } from '../components/ui/input'; +import { Label } from '../components/ui/label'; +import { Textarea } from '../components/ui/textarea'; +import { RadioGroup, RadioGroupItem } from '../components/ui/radio-group'; +import { Checkbox } from '../components/ui/checkbox'; +import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../components/ui/select'; +import { Tabs, TabsContent, TabsList, TabsTrigger } from '../components/ui/tabs'; +import { Badge } from '../components/ui/badge'; +import { Progress } from '../components/ui/progress'; +import { Alert, AlertDescription } from '../components/ui/alert'; +import { Separator } from '../components/ui/separator'; +import { + FileText, + Clock, + Users, + ChevronRight, + Star, + TrendingUp, + BarChart3, + MessageSquare, + AlertCircle, + CheckCircle, + Calendar, + Target, + Zap, + ThumbsUp, + ThumbsDown, + Send, + Eye, + Award, + Lightbulb, + ArrowUp, + ArrowDown, + MapPin, + Globe, + ExternalLink +} from 'lucide-react'; +import { LineChart, Line, XAxis, YAxis, CartesianGrid, Tooltip, ResponsiveContainer, PieChart, Pie, Cell } from 'recharts'; +// import exampleImage from 'figma:asset/c501c3d3f3a828828d4cb2dadb9558b43986718f.png'; +import { useNavigate } from 'react-router-dom'; + const exampleImage = 'https://via.placeholder.com/600x400?text=Example+Image'; + +interface SurveyProps { + userType: 'individual' | 'corporate'; +} + +interface Survey { + id: string; + title: string; + description: string; + category: string; + type: 'self-assessment' | 'feedback' | 'evaluation'; + duration: string; + questions: number; + status: 'available' | 'in-progress' | 'completed' | 'pending'; + dueDate?: string; + completedDate?: string; + score?: number; + feedback?: string; + participants?: number; + responses?: number; + certificateEarned?: boolean; +} + +interface LearningInsights { + averageScore: number; + totalSurveys: number; + completedSurveys: number; + strengths: string[]; + developmentAreas: string[]; + nextRecommendations: string[]; + progressTrend: 'improving' | 'stable' | 'needs-attention'; +} + +// Mock data for academic dashboard +const dashboardData = { + satisfactionScore: { + current: 78, + previous: 74, + trend: 5.4, + data: [ + { date: 'Week 2', score: 70, previousScore: 68 }, + { date: 'Week 4', score: 75, previousScore: 72 }, + { date: 'Week 6', score: 78, previousScore: 74 }, + { date: 'Week 8', score: 82, previousScore: 77 }, + { date: 'Week 10', score: 80, previousScore: 76 }, + { date: 'Week 12', score: 78, previousScore: 74 } + ] + }, + netPromoterScore: { + current: 82, + previous: 78, + trend: 5.1, + promoters: 85, + passives: 12, + detractors: 8, + data: [ + { date: 'Week 2', promoters: 78, passives: 15, detractors: 12 }, + { date: 'Week 4', promoters: 80, passives: 14, detractors: 10 }, + { date: 'Week 6', promoters: 82, passives: 13, detractors: 9 }, + { date: 'Week 8', promoters: 85, passives: 12, detractors: 8 }, + { date: 'Week 10', promoters: 87, passives: 11, detractors: 7 }, + { date: 'Week 12', promoters: 85, passives: 12, detractors: 8 } + ] + }, + responsesFeedback: [ + { + id: 1, + user: 'Jennifer Schmidt', + avatar: 'https://images.unsplash.com/photo-1494790108755-2616b612b786?w=40&h=40&fit=crop&crop=face', + feedback: 'The midterm exam format was fair and comprehensive. The case study questions really tested our understanding.', + timeAgo: '2 days ago', + rating: 5 + }, + { + id: 2, + user: 'Michael Kim', + avatar: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=40&h=40&fit=crop&crop=face', + feedback: 'Appreciate the detailed feedback on my leadership assessment. The rubric was clearly explained.', + timeAgo: '1 week ago', + rating: 4 + }, + { + id: 3, + user: 'Maria Rodriguez', + avatar: 'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=40&h=40&fit=crop&crop=face', + feedback: 'The group project evaluation process was transparent. Would like more peer review opportunities.', + timeAgo: '1 week ago', + rating: 4 + }, + { + id: 4, + user: 'David Thompson', + avatar: 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=40&h=40&fit=crop&crop=face', + feedback: 'Research paper guidelines were comprehensive. The academic writing workshop really helped prepare us.', + timeAgo: '2 weeks ago', + rating: 5 + } + ], + learnersByLocation: [ + { country: 'United States', count: 145, flag: '🇺🇸', activity: 'Taking Assessment', coords: { x: 25, y: 35 }, status: 'active' }, + { country: 'United Kingdom', count: 98, flag: '🇬🇧', activity: 'Reviewing Results', coords: { x: 48, y: 28 }, status: 'active' }, + { country: 'Germany', count: 87, flag: '🇩🇪', activity: 'Course Progress', coords: { x: 52, y: 30 }, status: 'studying' }, + { country: 'Singapore', count: 76, flag: '🇸🇬', activity: 'Live Session', coords: { x: 75, y: 52 }, status: 'online' }, + { country: 'Australia', count: 65, flag: '🇦🇺', activity: 'Assignment Due', coords: { x: 82, y: 72 }, status: 'pending' }, + { country: 'Canada', count: 54, flag: '🇨🇦', activity: 'Group Project', coords: { x: 22, y: 25 }, status: 'collaboration' }, + { country: 'India', count: 43, flag: '🇮🇳', activity: 'Webinar Prep', coords: { x: 68, y: 45 }, status: 'preparing' }, + { country: 'Japan', count: 38, flag: '🇯🇵', activity: 'Peer Review', coords: { x: 82, y: 40 }, status: 'reviewing' } + ] +}; + +// Mock data for academic assessments and insights +const mockData = { + insights: { + averageScore: 81, + totalSurveys: 8, + completedSurveys: 5, + strengths: [ + 'Theoretical Understanding', + 'Case Study Analysis', + 'Academic Writing', + 'Critical Thinking' + ], + developmentAreas: [ + 'Quantitative Analysis', + 'Research Methodology', + 'Group Presentation Skills' + ], + nextRecommendations: [ + 'Focus on statistical analysis methods for your final research paper', + 'Attend the academic writing workshop to improve citation and structure', + 'Review leadership frameworks for the comprehensive final examination' + ], + progressTrend: 'improving' as const + }, + availableSurveys: [ + { + id: 'exam-1', + title: 'Midterm Examination', + description: 'Comprehensive examination covering weeks 1-7 course material including leadership theories and frameworks', + category: 'Formal Assessment', + type: 'evaluation' as const, + duration: '120 min', + questions: 60, + status: 'available' as const, + dueDate: '2024-03-15' + }, + { + id: 'assignment-2', + title: 'Research Paper Draft Submission', + description: 'Submit first draft of your 3000-word research paper on organizational leadership challenges', + category: 'Research Assignment', + type: 'self-assessment' as const, + duration: '2-3 weeks', + questions: 1, + status: 'in-progress' as const, + dueDate: '2024-03-22' + }, + { + id: 'quiz-3', + title: 'Weekly Quiz: Communication Theory', + description: 'Assessment on communication models and leadership communication strategies from Week 8', + category: 'Weekly Assessment', + type: 'evaluation' as const, + duration: '30 min', + questions: 25, + status: 'pending' as const, + dueDate: '2024-03-18' + } + ], + completedSurveys: [ + { + id: 'completed-1', + title: 'Leadership Theory Examination', + description: 'Comprehensive assessment of foundational leadership theories and their practical applications', + category: 'Course Examination', + type: 'evaluation' as const, + duration: '90 min', + questions: 45, + status: 'completed' as const, + completedDate: '2024-02-20', + score: 87, + feedback: 'Excellent grasp of theoretical concepts. Strong application to case studies. Consider exploring modern leadership paradigms.', + participants: 32, + responses: 32, + certificateEarned: false + }, + { + id: 'completed-2', + title: 'Group Project Evaluation', + description: 'Collaborative assessment of team leadership dynamics and strategic planning exercise', + category: 'Group Assignment', + type: 'evaluation' as const, + duration: '3 weeks', + questions: 5, + status: 'completed' as const, + completedDate: '2024-02-28', + score: 83, + feedback: 'Strong collaborative approach and well-structured presentation. Peer evaluations were consistently positive.', + participants: 6, + responses: 6, + certificateEarned: false + } + ] +}; + +// Survey Card Component (Enhanced) +function SurveyCard({ + survey, + userType, + onStart, + onContinue, + onView +}: { + survey: Survey; + userType: 'individual' | 'corporate'; + onStart: (id: string) => void; + onContinue: (id: string) => void; + onView: (id: string) => void; +}) { + const getStatusInfo = (status: string) => { + switch (status) { + case 'available': + return { + label: 'AVAILABLE', + className: 'inline-flex items-center px-2 py-1 text-[12px] bg-primary/10 text-primary rounded-md border border-primary/20' + }; + case 'in-progress': + return { + label: 'IN PROGRESS', + className: 'inline-flex items-center px-2 py-1 text-[12px] bg-orange-100 text-orange-700 rounded-md border border-orange-200' + }; + case 'pending': + return { + label: 'PENDING', + className: 'inline-flex items-center px-2 py-1 text-[12px] bg-yellow-100 text-yellow-700 rounded-md border border-yellow-200' + }; + default: + return null; + } + }; + + const getActionButton = () => { + switch (survey.status) { + case 'available': + return ( + + ); + case 'in-progress': + return ( + + ); + case 'pending': + return ( + + ); + default: + return null; + } + }; + + const statusInfo = getStatusInfo(survey.status); + + return ( + + +
+
+ {statusInfo && ( + + {statusInfo.label} + + )} + + {survey.type.replace('-', ' ').toUpperCase()} + +
+
+ {survey.title} + + {survey.description} + +
+
+
+ + +
+
+
+ + {survey.duration} +
+
+ + {survey.questions} questions +
+
+ + {survey.category} +
+ {survey.dueDate && ( +
+ + Due {new Date(survey.dueDate).toLocaleDateString()} +
+ )} +
+
+ +
+ {getActionButton()} +
+
+
+ ); +} + +export function Surveys({ userType = 'individual' }: SurveyProps) { + const [activeTab, setActiveTab] = useState<'available' | 'completed'>('available'); + const navigate = useNavigate(); + + // Mock user data for LearnerLayout - matching Library page pattern + const user = { + name: "Priya Sharma", + email: userType === 'corporate' ? "priya.sharma@company.com" : "priya.sharma@example.com", + avatar: "https://images.unsplash.com/photo-1494790108755-2616b612b786?w=150&h=150&fit=crop&crop=face", + ...(userType === 'corporate' && { + organization: "TCS", + orgLogo: "https://images.unsplash.com/photo-1560179707-f14e90ef3623?w=32&h=32&fit=crop", + role: "Senior Manager", + cohort: "Leadership 2024" + }) + }; + + const handleStartSurvey = (surveyId: string) => { + console.log('Starting survey:', surveyId); + // Implementation for starting survey + }; + + const handleContinueSurvey = (surveyId: string) => { + console.log('Continuing survey:', surveyId); + // Implementation for continuing survey + }; + + const handleViewResults = (surveyId: string) => { + console.log('Viewing results for survey:', surveyId); + // Implementation for viewing survey results + }; + + return ( + + {/* Enhanced Page Header */} +
+
+
+
+

+ Course Assessments & Examinations +
+

+
+

+ {userType === 'corporate' + ? 'Complete course examinations, assignments, and academic assessments for your leadership development program' + : 'Complete course examinations, assignments, and academic assessments for your leadership studies' + } +

+
+
+
+ + {/* Main Content with Dashboard Layout */} +
+
+ {/* Dashboard Layout - 2x2 Grid */} +
+ {/* Satisfaction Score Chart - Top Left */} + + +
+ + Course Performance Average + +
+ Last 30 days +
+
+
+ +
+
+ + {dashboardData.satisfactionScore.current}% + +
+ + + {Math.abs(dashboardData.satisfactionScore.trend)}% + +
+
+

+ Previous semester average +

+
+ +
+ + + + + + + + + + +
+
+
+ + {/* Net Promoter Score Chart - Top Right */} + + +
+ + Academic Progress Tracking + +
+
+
+ Excellent (A) +
+
+
+ Good (B) +
+
+
+ Needs Improvement +
+
+
+
+ +
+
+ + {dashboardData.netPromoterScore.current} + +
+ + + {dashboardData.netPromoterScore.trend}% + +
+
+

+ Current semester +

+
+ +
+ + + + + + + + + + + +
+
+
+ + {/* Responses from Users - Bottom Left */} + + +
+ + Academic Feedback & Reviews + + +
+
+ +
+ {dashboardData.responsesFeedback.map((response) => ( +
+ {response.user} +
+
+ {response.user} +
+ {Array.from({ length: response.rating }).map((_, i) => ( + + ))} +
+
+

+ {response.feedback} +

+ {response.timeAgo} +
+
+ ))} +
+
+
+ + {/* Global Learning Activity Heatmap - Bottom Right */} + + +
+ + Global Learning Activity + + +
+
+ + {/* Interactive World Map Heatmap */} +
+
+ {/* World map background */} +
+ + {/* Simplified world continents */} + + + + + + +
+ + {/* Activity points on map */} + {dashboardData.learnersByLocation.map((location, index) => { + const getStatusColor = (status: string) => { + switch (status) { + case 'active': return 'bg-green-500'; + case 'studying': return 'bg-blue-500'; + case 'online': return 'bg-purple-500'; + case 'pending': return 'bg-orange-500'; + case 'collaboration': return 'bg-yellow-500'; + case 'preparing': return 'bg-indigo-500'; + case 'reviewing': return 'bg-pink-500'; + default: return 'bg-gray-500'; + } + }; + + const getActivitySize = (count: number) => { + if (count > 100) return 'w-4 h-4'; + if (count > 50) return 'w-3 h-3'; + return 'w-2 h-2'; + }; + + return ( +
+ {/* Pulse ring */} +
+ + {/* Hover tooltip */} +
+
{location.country}
+
{location.count} students
+
{location.activity}
+
+
+
+ ); + })} +
+
+ + {/* Activity Legend */} +
+

Live Activity Status

+
+
+
+ Taking Assessment +
+
+
+ Course Progress +
+
+
+ Live Session +
+
+
+ Assignment Due +
+
+
+ + {/* Top Countries List */} +
+

Top Active Regions

+ {dashboardData.learnersByLocation.slice(0, 4).map((country, index) => ( +
+
+ {country.flag} +
+ {country.country} + {country.activity} +
+
+
+
{country.count}
+
+ {country.status} +
+
+
+ ))} +
+
+
+
+ + {/* Enhanced Survey Tabs */} + + {/* Enhanced Segmented Control */} +
+
+ {[ + { + value: 'available', + label: `Available Surveys (${mockData.availableSurveys.filter(s => ['available', 'in-progress', 'pending'].includes(s.status)).length})`, + icon: FileText + }, + { + value: 'completed', + label: `Completed (${mockData.completedSurveys.length})`, + icon: CheckCircle + } + ].map((tab) => { + const Icon = tab.icon; + return ( + + ); + })} +
+
+ + {/* Available Surveys */} + + {mockData.availableSurveys.filter(s => ['available', 'in-progress', 'pending'].includes(s.status)).length === 0 ? ( + + + +

No Available Surveys

+

+ All surveys have been completed. Check back later for new assessments. +

+
+
+ ) : ( +
+ {mockData.availableSurveys + .filter(s => ['available', 'in-progress', 'pending'].includes(s.status)) + .map((survey) => ( + + ))} +
+ )} +
+ + {/* Completed Surveys */} + + {mockData.completedSurveys.length === 0 ? ( + + + +

No Completed Surveys

+

+ Complete your first survey to see results and insights here. +

+
+
+ ) : ( +
+ {mockData.completedSurveys.map((survey) => ( + + +
+
+
+ + COMPLETED + + + {survey.type.replace('-', ' ').toUpperCase()} + +
+ {survey.certificateEarned && ( + + )} +
+
+ {survey.title} + + {survey.description} + +
+
+
+ + +
+
+
+
{survey.score}%
+
Score
+
+
+
{survey.questions}
+
Questions
+
+
+ +
+
+ + Completed on {survey.completedDate ? new Date(survey.completedDate).toLocaleDateString() : 'N/A'} +
+
+ + {survey.participants} participants +
+
+ + {survey.category} +
+
+ + {survey.feedback && ( +
+

"{survey.feedback}"

+
+ )} +
+ + +
+
+ ))} +
+ )} +
+
+
+
+
+ ); +} \ No newline at end of file diff --git a/src/pages/learner/AchievementBadges.tsx b/src/pages/learner/AchievementBadges.tsx new file mode 100644 index 0000000..1328513 --- /dev/null +++ b/src/pages/learner/AchievementBadges.tsx @@ -0,0 +1,150 @@ +import React from "react"; +import { Card, CardHeader, CardTitle, CardContent } from "../../components/ui/card"; +import { Trophy } from "lucide-react"; +import { ImageWithFallback } from "../../components/figma/ImageWithFallback"; + +const platinumTrophy = 'https://via.placeholder.com/150?text=Platinum+Trophy'; +const goldTrophy = 'https://via.placeholder.com/150?text=Gold+Trophy'; +const silverTrophy = 'https://via.placeholder.com/150?text=Silver+Trophy'; +const bronzeTrophy = 'https://via.placeholder.com/150?text=Bronze+Trophy'; + +// Achievement Badges component +export function AchievementBadges() { + const badges = [ + { + id: 'bronze', + title: 'Bronze Trophy', + description: 'Complete 3 foundational leadership courses and score 80%+ in all assessments', + exp: 20, + unlocked: true, + bgColor: 'from-orange-50 to-orange-100', + borderColor: 'border-orange-200', + trophyImage: bronzeTrophy + }, + { + id: 'silver', + title: 'Silver Trophy', + description: 'Master 5 advanced leadership modules and lead a successful team project', + exp: 40, + unlocked: true, + bgColor: 'from-gray-50 to-gray-100', + borderColor: 'border-gray-300', + trophyImage: silverTrophy + }, + { + id: 'gold', + title: 'Gold Trophy', + description: 'Achieve executive leadership certification and mentor 3 junior leaders', + exp: 60, + unlocked: true, + bgColor: 'from-yellow-50 to-yellow-100', + borderColor: 'border-yellow-300', + trophyImage: goldTrophy + }, + { + id: 'platinum', + title: 'Platinum Trophy', + description: 'Complete all specialization tracks and become a certified KLC ambassador', + exp: 100, + unlocked: false, + bgColor: 'from-gray-50 to-gray-100', + borderColor: 'border-gray-200', + trophyImage: platinumTrophy + } + ]; + + const unlockedCount = badges.filter(badge => badge.unlocked).length; + const totalCount = badges.length; + + return ( + + +
+
+
+ +
+ + Achievement Badges + +
+
+ + + {unlockedCount}/{totalCount} + +
+
+ +

+ Unlock trophies by completing challenges and competitions +

+ +
+
+
+
+
+
+ + +
+ {badges.map((badge) => ( +
+
+
+ +{badge.exp} EXP +
+
+ +
+
+
+ +
+
+
+ +
+

+ {badge.title} +

+

+ {badge.description} +

+
+ +
+
+ {badge.unlocked ? 'UNLOCKED' : 'LOCKED'} +
+
+
+ ))} +
+
+
+ ); +} diff --git a/src/pages/learner/ActivityRecommendations.tsx b/src/pages/learner/ActivityRecommendations.tsx new file mode 100644 index 0000000..d25f5e5 --- /dev/null +++ b/src/pages/learner/ActivityRecommendations.tsx @@ -0,0 +1,139 @@ +import React from "react"; +import { useNavigate } from "react-router-dom"; +import { Clock, Users } from "lucide-react"; + +import { Card, CardContent } from "../../components/ui/card"; +import { Button } from "../../components/ui/button"; +import { Badge } from "../../components/ui/badge"; +import { ImageWithFallback } from "../../components/figma/ImageWithFallback"; + +// Based on your recent activity recommendations component - redesigned to match provided image +export function ActivityRecommendations({ userType = 'individual' }: { userType?: 'individual' | 'corporate' }) { + const recommendations = [ + { + id: 1, + title: "Emotional Intelligence Mastery", + description: "Develop self-awareness and interpersonal skills to become a more effective leader.", + duration: "5 hours", + difficulty: "Intermediate", + badgeText: "Intermediate", + badgeColor: "bg-yellow-100 text-yellow-800", + thumbnail: "https://images.unsplash.com/photo-1552664730-d307ca884978?w=400&h=240&fit=crop", + recentLearners: 248 + }, + { + id: 2, + title: "Strategic Thinking Framework", + description: "Learn to analyze complex business scenarios and make data-driven decisions.", + duration: "4 hours", + difficulty: "Advanced", + badgeText: "Advanced", + badgeColor: "bg-red-100 text-red-800", + thumbnail: "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=400&h=240&fit=crop", + recentLearners: 189 + }, + { + id: 3, + title: "Team Leadership Excellence", + description: "Master the art of motivating and guiding high-performance teams.", + duration: "8 hours", + difficulty: "Intermediate", + badgeText: "Intermediate", + badgeColor: "bg-yellow-100 text-yellow-800", + thumbnail: "https://images.unsplash.com/photo-1600880292203-757bb62b4baf?w=400&h=240&fit=crop", + recentLearners: 156 + }, + { + id: 4, + title: "Change Management Strategies", + description: "Navigate organizational transformation with confidence and clarity.", + duration: "3 hours", + difficulty: "Beginner", + badgeText: "Beginner", + badgeColor: "bg-green-100 text-green-800", + thumbnail: "https://images.unsplash.com/photo-1542744173-8e7e53415bb0?w=400&h=240&fit=crop", + recentLearners: 134 + } + ]; +const navigate = useNavigate(); + return ( +
+
+
+

+ Based on your recent activity, here are your recommendations +

+

+ Personalized course suggestions to accelerate your leadership journey +

+
+ +
+ +
+ {recommendations.map((course) => ( + + {/* Course Thumbnail */} +
+ +
+ + {course.badgeText} + +
+
+ + + {/* Course Title */} +

+ {course.title} +

+ + {/* Course Description */} +

+ {course.description} +

+ + {/* Duration and Recent Learners (Balanced) */} +
+ {/* Duration */} +
+ + {course.duration} +
+ + {/* Recent Learners */} +
+ + {course.recentLearners} +
+
+ + {/* Enroll Button */} + +
+
+ + ))} +
+
+ ); +} \ No newline at end of file diff --git a/src/pages/learner/ConnectionStatus.tsx b/src/pages/learner/ConnectionStatus.tsx new file mode 100644 index 0000000..e27027c --- /dev/null +++ b/src/pages/learner/ConnectionStatus.tsx @@ -0,0 +1,56 @@ +import React, { useEffect, useState } from "react"; +import { WifiOff, Wifi, RefreshCw } from "lucide-react"; +import { Alert, AlertDescription } from "../../components/ui/alert"; +import { Button } from "../../components/ui/button"; + + +// Connection status component + export function ConnectionStatus() { + const [isOnline, setIsOnline] = useState(navigator.onLine); + const [isLoading, setIsLoading] = useState(false); + + useEffect(() => { + const handleOnline = () => setIsOnline(true); + const handleOffline = () => setIsOnline(false); + + window.addEventListener('online', handleOnline); + window.addEventListener('offline', handleOffline); + + return () => { + window.removeEventListener('online', handleOnline); + window.removeEventListener('offline', handleOffline); + }; + }, []); + + const handleRetry = async () => { + setIsLoading(true); + await new Promise(resolve => setTimeout(resolve, 1000)); + setIsLoading(false); + window.location.reload(); + }; + + if (isOnline) return null; + + return ( + + + + You're currently offline. Some features may not be available. + + + + ); +} diff --git a/src/pages/learner/CurrentLearningProgress.tsx b/src/pages/learner/CurrentLearningProgress.tsx new file mode 100644 index 0000000..f2143cc --- /dev/null +++ b/src/pages/learner/CurrentLearningProgress.tsx @@ -0,0 +1,206 @@ +import React from "react"; +import { useNavigate } from "react-router-dom"; +import { Play, FastForward, CheckCircle, ChevronRight, BookOpen } from "lucide-react"; +import { Card, CardContent, CardHeader, CardTitle } from "../../components/ui/card"; +import CurrentLearningHeaderIcon from "../../imports/CurrentLearningHeaderIcon-4285-106"; +import { Badge } from "../../components/ui/badge"; +import { Button } from "../../components/ui/button"; + +export function CurrentLearningProgress({ userType = 'individual' }: { userType?: 'individual' | 'corporate' }) { + const currentCourse = { + title: "Strategic Leadership Excellence Program", + rating: 4.9, + provider: "Dr. Rajesh Sharma, KLC", + dueDate: "Aug 30, 2025", + totalModules: 8, + currentModule: { + title: "Building High-Performance Teams", + number: 6, + progress: 65, + lessonsRemaining: 3 + }, + nextModule: { + title: "Leadership Communication Mastery", + number: 7 + } + }; + + // Sample module data to match the image layout + const moduleList = [ + { title: "Leadership Fundamentals", duration: "1h 15m", completed: true }, + { title: "Emotional Intelligence for Leaders", duration: "1h 30m", completed: true }, + { title: "Strategic Decision Making", duration: "1h", completed: true }, + { title: "Conflict Resolution & Negotiation", duration: "50m", completed: true }, + { title: "Change Management Principles", duration: "40m", completed: true }, + { title: "Building High-Performance Teams", duration: "1h 20m", completed: false, current: true }, + { title: "Leadership Communication Mastery", duration: "1h 45m", completed: false, upcoming: true }, + { title: "Innovation & Strategic Thinking", duration: "2h", completed: false } + ]; + + const completedModules = moduleList.filter(module => module.completed).length; + const totalModules = moduleList.length; + const overallProgress = Math.round((completedModules / totalModules) * 100); + const navigate = useNavigate(); + + return ( + + +
+
+
+
+ +
+
+ + Current Learning Progress + +
+
+
+ + + {/* Course Header */} +
+
+

+ {currentCourse.title} +

+

+ with {currentCourse.provider} +

+
+
+ + In Progress + +

2h 30m remaining

+
+
+ + {/* Overall Progress */} +
+
+ Overall Progress + Modules +
+
+ {overallProgress}% + {completedModules}/{totalModules} +
+
+ Started + Completed +
+ + {/* Progress Bar */} +
+
+
+
+ + {/* Current and Up Next Modules */} +
+ {/* Current Module */} +
+
+
+ +
+ Current +
+

+ {currentCourse.currentModule.title} +

+ +
+ + {/* Up Next Module */} +
+
+
+ +
+ Up Next +
+

+ {currentCourse.nextModule.title} +

+ +
+
+ + {/* Course Modules List */} +
+
+

Course Modules

+ +
+ +
+ {moduleList.slice(0, 5).map((module, index) => ( +
+
+
+ {module.completed ? ( + + ) : ( +
+ )} +
+ + {module.title} + +
+
+ {module.duration} + +
+
+ ))} +
+
+ + {/* Action Buttons */} +
+ + + +
+
+
+ ); +} \ No newline at end of file diff --git a/src/pages/learner/Dashboard.tsx b/src/pages/learner/Dashboard.tsx new file mode 100644 index 0000000..ce4037b --- /dev/null +++ b/src/pages/learner/Dashboard.tsx @@ -0,0 +1,72 @@ +import { LearnerLayout } from '../../components/learner/LearnerLayout'; +import { RecentActivity } from './RecentActivity'; +import { WelcomeMessage } from './WelcomeMessage'; +import { CurrentLearningProgress } from './CurrentLearningProgress'; +import { ConnectionStatus } from './ConnectionStatus'; +import { WeeklyProgressTracker } from './WeeklyProgressTracker'; +import { AchievementBadges } from './AchievementBadges'; +import { GlobalLeaderboard } from './GlobalLeaderboard'; +import { ActivityRecommendations } from './ActivityRecommendations'; +import { RecentlyViewed } from './RecentlyViewed'; +import { WhatOthersLearning } from './WhatOthersLearning'; + + + +interface DashboardProps { + userType?: 'individual' | 'corporate'; +} + +// Main Dashboard component +export default function Dashboard({ userType = 'individual' }: DashboardProps) { + const user = { name: 'Alex', email: 'alex@example.com' }; + + return ( + +
+ + + {/* Welcome Section */} +
+ +

+ Continue your leadership development journey with our personalized recommendations and track your progress +

+
+ + {/* Weekly Progress Tracker */} + + + {/* Current Learning Progress */} + + + {/* Achievement Badges */} + + + {/* Global Leaderboard (left, prominent) and Recent Activity (right) Grid */} +
+
+ +
+
+ +
+
+ + {/* Based on your activity recommendations - NO TOP PADDING */} +
+ +
+ + {/* Recently Viewed section - NO TOP PADDING */} +
+ +
+ + {/* What are others learning section - NO TOP PADDING */} +
+ +
+
+
+ ); +} \ No newline at end of file diff --git a/src/pages/learner/GlobalLeaderboard.tsx b/src/pages/learner/GlobalLeaderboard.tsx new file mode 100644 index 0000000..e324573 --- /dev/null +++ b/src/pages/learner/GlobalLeaderboard.tsx @@ -0,0 +1,163 @@ +import React from "react"; +import { useNavigate } from "react-router-dom"; +import { Trophy } from "lucide-react"; + +import { Card, CardHeader, CardTitle, CardContent } from "../../components/ui/card"; +import { Button } from "../../components/ui/button"; +import { ScrollArea } from "../../components/ui/scroll-area"; +import { Avatar, AvatarImage, AvatarFallback } from "../../components/ui/avatar"; + +// Global Leaderboard component - increased height to match Recent Activity +export function GlobalLeaderboard() { + const leaderboardData = [ + { + rank: 1, + name: "Sarah Chen", + points: 2450, + avatar: "https://images.unsplash.com/photo-1494790108755-2616b612b5c8?w=80&h=80&fit=crop&crop=face", + badge: "gold", + change: "+15" + }, + { + rank: 2, + name: "Marcus Johnson", + points: 2380, + avatar: "https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=80&h=80&fit=crop&crop=face", + badge: "silver", + change: "+8" + }, + { + rank: 3, + name: "Emily Rodriguez", + points: 2320, + avatar: "https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=80&h=80&fit=crop&crop=face", + badge: "bronze", + change: "+12" + }, + { + rank: 4, + name: "David Kim", + points: 2180, + avatar: "https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=80&h=80&fit=crop&crop=face", + badge: "regular", + change: "+5" + }, + { + rank: 5, + name: "Lisa Thompson", + points: 2140, + avatar: "https://images.unsplash.com/photo-1517841905240-472988babdf9?w=80&h=80&fit=crop&crop=face", + badge: "regular", + change: "+20" + }, + { + rank: 6, + name: "Alex Patel", + points: 2090, + avatar: "https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=80&h=80&fit=crop&crop=face", + badge: "regular", + change: "+3" + }, + { + rank: 7, + name: "Your Position", + points: 1950, + avatar: "https://images.unsplash.com/photo-1535713875002-d1d0cf377fde?w=80&h=80&fit=crop&crop=face", + badge: "user", + change: "+18", + isCurrentUser: true + }, + { + rank: 8, + name: "Jennifer Lee", + points: 1890, + avatar: "https://images.unsplash.com/photo-1534528741775-53994a69daeb?w=80&h=80&fit=crop&crop=face", + badge: "regular", + change: "+7" + } + ]; + + const getBadgeColor = (badge: string) => { + switch (badge) { + case 'gold': return 'bg-gradient-to-r from-yellow-400 to-yellow-500 text-white'; + case 'silver': return 'bg-gradient-to-r from-gray-300 to-gray-400 text-gray-800'; + case 'bronze': return 'bg-gradient-to-r from-orange-400 to-orange-500 text-white'; + case 'user': return 'bg-gradient-to-r from-brand-navy to-brand-navy/90 text-white'; + default: return 'bg-gray-100 text-gray-600'; + } + }; + const navigate = useNavigate(); + + return ( + + +
+
+
+ +
+ + Global Leaderboard + +
+ +
+

+ Top learners this month +

+
+ + + +
+ {leaderboardData.map((user) => ( +
+ {/* Rank */} +
+ {user.rank} +
+ + {/* Avatar */} + + + {user.name.split(' ').map(n => n[0]).join('')} + + + {/* User Info */} +
+

+ {user.name} +

+

+ {user.points.toLocaleString()} points +

+
+ + {/* Change */} +
+ {user.change} +
+
+ ))} +
+
+
+
+ ); +} \ No newline at end of file diff --git a/src/pages/learner/RecentActivity.tsx b/src/pages/learner/RecentActivity.tsx new file mode 100644 index 0000000..7fd6c7b --- /dev/null +++ b/src/pages/learner/RecentActivity.tsx @@ -0,0 +1,167 @@ +import { + CheckCircle, + Video, + FileText, + Award, + PlayCircle, + MessageSquare, + BookOpen, + Users, + Activity +} from "lucide-react"; + +import { useNavigate } from "react-router-dom"; +import { Card, CardContent, CardHeader, CardTitle } from "../../components/ui/card"; +import { Button } from "../../components/ui/button"; +import { ScrollArea } from "../../components/ui/scroll-area"; +// import { Card, CardHeader, CardTitle, CardContent } from "@/components/ui/card"; +// import { Button } from "@/components/ui/button"; +// import { ScrollArea } from "@/components/ui/scroll-area"; + +// Recent Activity component - increased height to match Global Leaderboard +export function RecentActivity() { + const activities = [ + { + id: 1, + type: 'course_completed', + title: 'Completed "Strategic Decision Making"', + description: 'Module 3 of 4 • Leadership Fundamentals', + timestamp: '2 hours ago', + icon: CheckCircle, + iconColor: 'text-green-600', + iconBg: 'bg-green-100' + }, + { + id: 2, + type: 'webinar_joined', + title: 'Attended Live Webinar', + description: 'Digital Transformation for Leaders', + timestamp: '5 hours ago', + icon: Video, + iconColor: 'text-blue-600', + iconBg: 'bg-blue-100' + }, + { + id: 3, + type: 'assessment_completed', + title: 'Assessment Completed', + description: 'Leadership Style Assessment • Score: 92%', + timestamp: '1 day ago', + icon: FileText, + iconColor: 'text-purple-600', + iconBg: 'bg-purple-100' + }, + { + id: 4, + type: 'certificate_earned', + title: 'Certificate Earned', + description: 'Leadership Foundation Certification', + timestamp: '2 days ago', + icon: Award, + iconColor: 'text-brand-gold', + iconBg: 'bg-yellow-100' + }, + { + id: 5, + type: 'course_started', + title: 'Started New Course', + description: 'Innovation Leadership Track', + timestamp: '3 days ago', + icon: PlayCircle, + iconColor: 'text-green-600', + iconBg: 'bg-green-100' + }, + { + id: 6, + type: 'discussion_posted', + title: 'Discussion Contribution', + description: 'Team Management Best Practices', + timestamp: '4 days ago', + icon: MessageSquare, + iconColor: 'text-orange-600', + iconBg: 'bg-orange-100' + }, + { + id: 7, + type: 'resource_downloaded', + title: 'Resource Downloaded', + description: 'Leadership Skills Handbook PDF', + timestamp: '5 days ago', + icon: BookOpen, + iconColor: 'text-gray-600', + iconBg: 'bg-gray-100' + }, + { + id: 8, + type: 'peer_connection', + title: 'New Connection', + description: 'Connected with 3 peer learners', + timestamp: '1 week ago', + icon: Users, + iconColor: 'text-brand-navy', + iconBg: 'bg-blue-100' + } + ]; + const navigate = useNavigate(); + return ( + + +
+
+
+ +
+ + Recent Activity + +
+ +
+

+ Your recent learning activities +

+
+ + + +
+ {activities.map((activity) => { + const Icon = activity.icon; + return ( +
+ {/* Activity Icon */} +
+ +
+ + {/* Activity Content */} +
+

+ {activity.title} +

+

+ {activity.description} +

+

+ {activity.timestamp} +

+
+
+ ); + })} +
+
+
+
+ ); +} \ No newline at end of file diff --git a/src/pages/learner/RecentlyViewed.tsx b/src/pages/learner/RecentlyViewed.tsx new file mode 100644 index 0000000..94ca2f0 --- /dev/null +++ b/src/pages/learner/RecentlyViewed.tsx @@ -0,0 +1,155 @@ +import React from "react"; +import { useNavigate } from "react-router-dom"; +import { Box, Clock, Users } from "lucide-react"; + +import { Card, CardContent } from "../../components/ui/card"; +import { Button } from "../../components/ui/button"; +import { Badge } from "../../components/ui/badge"; +import { ImageWithFallback } from "../../components/figma/ImageWithFallback"; + +// Recently Viewed component - redesigned to match course card layout +export function RecentlyViewed({ userType = 'individual' }: { userType?: 'individual' | 'corporate' }) { + const recentItems = [ + { + id: 1, + title: "Strategic Decision Making", + description: "Master critical thinking and decision-making frameworks for effective leadership.", + type: "Course", + progress: 75, + lastAccessed: "2 hours ago", + thumbnail: "https://images.unsplash.com/photo-1664575602276-acd073f104c1?w=400&h=240&fit=crop", + duration: "4.2 hours", + badgeText: "In Progress", + badgeColor: "bg-blue-100 text-blue-800", + recentLearners: 312 + }, + { + id: 2, + title: "Digital Transformation for Leaders", + description: "Navigate the digital landscape and lead technological change in organizations.", + type: "Webinar", + progress: 100, + lastAccessed: "5 hours ago", + thumbnail: "https://images.unsplash.com/photo-1551434678-e076c223a692?w=400&h=240&fit=crop", + duration: "1.5 hours", + badgeText: "Completed", + badgeColor: "bg-green-100 text-green-800", + recentLearners: 189 + }, + { + id: 3, + title: "Leadership Style Assessment", + description: "Discover your leadership style and develop targeted improvement strategies.", + type: "Assessment", + progress: 100, + lastAccessed: "1 day ago", + thumbnail: "https://images.unsplash.com/photo-1450101499163-c8848c66ca85?w=400&h=240&fit=crop", + duration: "30 minutes", + badgeText: "Completed", + badgeColor: "bg-green-100 text-green-800", + recentLearners: 276 + }, + { + id: 4, + title: "Team Management Fundamentals", + description: "Build essential skills for managing and developing high-performing teams.", + type: "Course", + progress: 45, + lastAccessed: "2 days ago", + thumbnail: "https://images.unsplash.com/photo-1522202176988-66273c2fd55f?w=400&h=240&fit=crop", + duration: "6.1 hours", + badgeText: "In Progress", + badgeColor: "bg-blue-100 text-blue-800", + recentLearners: 198 + } + ]; + + const navigate = useNavigate(); + + return ( +
+
+
+

+ Recently Viewed +

+

+ Continue where you left off or revisit completed content +

+
+ +
+ +
+ {recentItems.map((item) => ( + + {/* Course Thumbnail */} +
+ +
+ + {item.badgeText} + +
+ {/* Progress overlay for in-progress items */} + {item.progress > 0 && item.progress < 100 && ( +
+ Progress: {item.progress}% +
+ )} +
+ + {/* Make content take full space and push button down */} + +
+ {/* Course Title */} +

+ {item.title} +

+ + {/* Course Description */} +

+ {item.description} +

+ + {/* Duration and Recent Learners */} +
+
+ + {item.duration} +
+
+ + {item.recentLearners} +
+
+
+ + {/* Action Button fixed at bottom */} + +
+
+ + ))} +
+
+ ); +} diff --git a/src/pages/learner/WeeklyProgressModal.tsx b/src/pages/learner/WeeklyProgressModal.tsx new file mode 100644 index 0000000..b1042c6 --- /dev/null +++ b/src/pages/learner/WeeklyProgressModal.tsx @@ -0,0 +1,121 @@ +import React, { useState } from "react"; +import { + Dialog, + DialogContent, + DialogDescription, + DialogHeader, + DialogTitle, +} from "../../components/ui/dialog"; +import { Checkbox } from "../../components/ui/checkbox"; +import { Button } from "../../components/ui/button"; + +// Weekly Progress Goal Setting Modal component +export function WeeklyProgressModal({ + isOpen, + onClose, + weeklyGoal, + setWeeklyGoal, + completedDays, + setCompletedDays, +}: { + isOpen?: boolean; + onClose?: () => void; + weeklyGoal?: number; + setWeeklyGoal?: (goal: number) => void; + completedDays?: number[]; + setCompletedDays?: (days: number[]) => void; +}) { + const [selectedDays, setSelectedDays] = useState(completedDays ?? []); + + const daysOfWeek = [ + { label: "Monday", index: 0 }, + { label: "Tuesday", index: 1 }, + { label: "Wednesday", index: 2 }, + { label: "Thursday", index: 3 }, + { label: "Friday", index: 4 }, + { label: "Saturday", index: 5 }, + { label: "Sunday", index: 6 }, + ]; + + const toggleDay = (dayIndex: number) => { + setSelectedDays((prev) => + prev.includes(dayIndex) + ? prev.filter((d) => d !== dayIndex) + : [...prev, dayIndex] + ); + }; + + const handleSave = () => { + setCompletedDays?.(selectedDays); + setWeeklyGoal?.(selectedDays.length); + onClose?.(); + }; + + const handleCancel = () => { + setSelectedDays(completedDays ?? []); + onClose?.(); + }; + + return ( + + + + + Set your weekly learning goal + + + Consistency is key to success! Choose your learning days so we can + estimate your course completion dates and schedule assignment + deadlines, helping you stay on track. + + + +
+
+

+ Choose your learning days +

+

+ The days you select will apply to all your courses on KLC +

+ +
+ {daysOfWeek.map((day) => ( +
+ toggleDay(day.index)} + className="h-5 w-5" + /> + +
+ ))} +
+
+
+ +
+ + +
+
+
+ ); +} diff --git a/src/pages/learner/WeeklyProgressTracker.tsx b/src/pages/learner/WeeklyProgressTracker.tsx new file mode 100644 index 0000000..af2f64a --- /dev/null +++ b/src/pages/learner/WeeklyProgressTracker.tsx @@ -0,0 +1,133 @@ +import React, { useState } from "react"; +import { BookOpen, Clock } from "lucide-react"; +import { + Card, + CardContent, + CardHeader, + CardTitle, +} from "../../components/ui/card"; +import { Button } from "../../components/ui/button"; +import { WeeklyProgressModal } from "./WeeklyProgressModal"; + +// Weekly Progress component based on the provided design + export function WeeklyProgressTracker() { + const [weeklyGoal, setWeeklyGoal] = useState("Learn 1 day a week on KLC"); + const [completedDays, setCompletedDays] = useState([0, 1, 2]); + const [isModalOpen, setIsModalOpen] = useState(false); + + const kpiData = [ + { + id: 'courses', + value: 8, + label: "Courses Completed", + change: "+2 this month", + icon: BookOpen, + iconBg: "bg-gradient-to-br from-emerald-500 to-emerald-600" + }, + { + id: 'hours', + value: 47, + label: "Learning Hours", + change: "+8 this week", + icon: Clock, + iconBg: "bg-gradient-to-br from-blue-500 to-blue-600" + } + ]; + + const daysOfWeek = [ + { label: 'M', full: 'Monday', index: 0 }, + { label: 'T', full: 'Tuesday', index: 1 }, + { label: 'W', full: 'Wednesday', index: 2 }, + { label: 'T', full: 'Thursday', index: 3 }, + { label: 'F', full: 'Friday', index: 4 }, + { label: 'S', full: 'Saturday', index: 5 }, + { label: 'S', full: 'Sunday', index: 6 } + ]; + + return ( + <> +
+ {kpiData.map((data) => { + const Icon = data.icon; + return ( + + +
+
+
+ {data.label} +
+
+ +
+
+ +
+ {data.value}{data.id === 'hours' ? 'h' : ''} +
+
+ +
+ {data.change} +
+
+
+ ); + })} + + + +
+ + Weekly Learning Goal + + +
+
+ + +
+

+ {weeklyGoal} +

+ +
+ {daysOfWeek.map((day) => ( +
+
+ {day.label} +
+
+ ))} +
+
+ +

+ {completedDays.length} days completed +

+
+
+
+ + setIsModalOpen(false)} + weeklyGoal={1} + setWeeklyGoal={() => {}} + completedDays={completedDays} + setCompletedDays={setCompletedDays} + /> + + ); +} \ No newline at end of file diff --git a/src/pages/learner/WelcomeMessage.tsx b/src/pages/learner/WelcomeMessage.tsx new file mode 100644 index 0000000..9d0ee1e --- /dev/null +++ b/src/pages/learner/WelcomeMessage.tsx @@ -0,0 +1,36 @@ +import React, { useState, useEffect } from "react"; + +// Welcome Message component with simple visible emoji + export function WelcomeMessage({ user }: { user: any }) { + const [showEmoji, setShowEmoji] = useState(true); + const emojiChar = '👋'; + + useEffect(() => { + const timer = setTimeout(() => { + setShowEmoji(false); + }, 5000); + + return () => clearTimeout(timer); + }, []); + + return ( +
+ + Welcome back, Priya Sharma! + + {showEmoji && ( + + {emojiChar} + + )} +
+ ); +} \ No newline at end of file diff --git a/src/pages/learner/WhatOthersLearning.tsx b/src/pages/learner/WhatOthersLearning.tsx new file mode 100644 index 0000000..f977736 --- /dev/null +++ b/src/pages/learner/WhatOthersLearning.tsx @@ -0,0 +1,141 @@ +import React from "react"; +import { useNavigate } from "react-router-dom"; +import { Clock, Users } from "lucide-react"; + +import { Card, CardContent } from "../../components/ui/card"; +import { Button } from "../../components/ui/button"; +import { Badge } from "../../components/ui/badge"; +import { ImageWithFallback } from "../../components/figma/ImageWithFallback"; + +// What are others learning component - redesigned to match course card layout +export function WhatOthersLearning({ userType = 'individual' }: { userType?: 'individual' | 'corporate' }) { + const trendingContent = [ + { + id: 1, + title: "AI in Leadership Decision Making", + description: "Explore how artificial intelligence is reshaping leadership strategies and decision-making processes.", + trend: "Hot", + enrollments: 2340, + duration: "5.2 hours", + badgeColor: "bg-red-100 text-red-800", + thumbnail: "https://images.unsplash.com/photo-1485827404703-89b55fcc595e?w=400&h=240&fit=crop", + recentLearners: 423 + }, + { + id: 2, + title: "Remote Team Management", + description: "Master the art of leading distributed teams effectively in the modern workplace.", + trend: "Trending", + enrollments: 1890, + duration: "3 sessions", + badgeColor: "bg-orange-100 text-orange-800", + thumbnail: "https://images.unsplash.com/photo-1556761175-b413da4baf72?w=400&h=240&fit=crop", + recentLearners: 267 + }, + { + id: 3, + title: "Sustainable Leadership Practices", + description: "Build leadership approaches that create lasting organizational change and impact.", + trend: "Rising", + enrollments: 1560, + duration: "1 day", + badgeColor: "bg-green-100 text-green-800", + thumbnail: "https://images.unsplash.com/photo-1542744094-3a31f272c490?w=400&h=240&fit=crop", + recentLearners: 198 + }, + { + id: 4, + title: "Data-Driven Leadership", + description: "Learn to make strategic decisions using data analytics and business insights.", + trend: "Popular", + enrollments: 2100, + duration: "4.8 hours", + badgeColor: "bg-blue-100 text-blue-800", + thumbnail: "https://images.unsplash.com/photo-1551288049-bebda4e38f71?w=400&h=240&fit=crop", + recentLearners: 356 + } + ]; + + const navigate = useNavigate(); + + return ( +
+
+
+

+ What are others learning +

+

+ Trending courses and popular content among your peers +

+
+ +
+ +
+ {trendingContent.map((content) => ( + + {/* Course Thumbnail */} +
+ +
+ + {content.trend} + +
+
+ + {/* Make content flex column so button sticks to bottom */} + +
+ {/* Course Title */} +

+ {content.title} +

+ + {/* Course Description */} +

+ {content.description} +

+ + {/* Duration and Recent Learners */} +
+
+ + {content.duration} +
+
+ + {content.recentLearners} +
+
+
+ + {/* Enroll Button at bottom */} + +
+
+ + ))} +
+
+ ); +} \ No newline at end of file