worked on the files arrranging

This commit is contained in:
2025-09-09 15:16:05 +05:30
parent b21b7a87c5
commit 31a068ae4e
59 changed files with 1291 additions and 1237 deletions

76
package-lock.json generated
View File

@@ -51,7 +51,8 @@
"react-hook-form": "^7.55.0",
"react-redux": "^9.2.0",
"react-resizable-panels": "^2.1.7",
"react-router-dom": "^7.8.2",
"react-router": "^6.30.1",
"react-router-dom": "^6.30.1",
"recharts": "^2.15.2",
"sonner": "^2.0.3",
"tailwind-merge": "*",
@@ -1919,6 +1920,15 @@
}
}
},
"node_modules/@remix-run/router": {
"version": "1.23.0",
"resolved": "https://registry.npmjs.org/@remix-run/router/-/router-1.23.0.tgz",
"integrity": "sha512-O3rHJzAQKamUz1fvE0Qaw0xSFqsA/yafi2iqeE0pvdFtCO1viYx8QL6f3Ln/aCCTLxs68SLf0KPM9eSeM8yBnA==",
"license": "MIT",
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/@rolldown/pluginutils": {
"version": "1.0.0-beta.27",
"resolved": "https://registry.npmjs.org/@rolldown/pluginutils/-/pluginutils-1.0.0-beta.27.tgz",
@@ -2789,7 +2799,7 @@
"version": "19.1.12",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.12.tgz",
"integrity": "sha512-cMoR+FoAf/Jyq6+Df2/Z41jISvGZZ2eTlnsaJRptmZ76Caldwy1odD4xTr/gNV9VLj0AWgg/nmkevIyUfIIq5w==",
"devOptional": true,
"dev": true,
"license": "MIT",
"dependencies": {
"csstype": "^3.0.2"
@@ -2799,7 +2809,7 @@
"version": "19.1.9",
"resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.9.tgz",
"integrity": "sha512-qXRuZaOsAdXKFyOhRBg6Lqqc0yay13vN7KrIg4L7N4aaHN68ma9OK3NE1BoDFgFOTfM7zg+3/8+2n8rLUH3OKQ==",
"devOptional": true,
"dev": true,
"license": "MIT",
"peerDependencies": {
"@types/react": "^19.0.0"
@@ -2883,15 +2893,6 @@
"react-dom": "^18 || ^19 || ^19.0.0-rc"
}
},
"node_modules/cookie": {
"version": "1.0.2",
"resolved": "https://registry.npmjs.org/cookie/-/cookie-1.0.2.tgz",
"integrity": "sha512-9Kr/j4O16ISv8zBBhJoi4bXOYNTkFLOqSL3UDB0njXxCXNezjeyVrJyGOWtgfs/q2km1gwBcfH8q1yEGoMYunA==",
"license": "MIT",
"engines": {
"node": ">=18"
}
},
"node_modules/csstype": {
"version": "3.1.3",
"resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
@@ -3019,17 +3020,6 @@
"node": ">=12"
}
},
"node_modules/date-fns": {
"version": "3.6.0",
"resolved": "https://registry.npmjs.org/date-fns/-/date-fns-3.6.0.tgz",
"integrity": "sha512-fRHTG8g/Gif+kSh50gaGEdToemgfj74aRX3swtiouboip5JDLAyDE9F11nHMIcvOaXeOC6D7SpNhi7uFyB7Uww==",
"license": "MIT",
"peer": true,
"funding": {
"type": "github",
"url": "https://github.com/sponsors/kossnocorp"
}
},
"node_modules/decimal.js-light": {
"version": "2.5.1",
"resolved": "https://registry.npmjs.org/decimal.js-light/-/decimal.js-light-2.5.1.tgz",
@@ -3828,41 +3818,35 @@
}
},
"node_modules/react-router": {
"version": "7.8.2",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-7.8.2.tgz",
"integrity": "sha512-7M2fR1JbIZ/jFWqelpvSZx+7vd7UlBTfdZqf6OSdF9g6+sfdqJDAWcak6ervbHph200ePlu+7G8LdoiC3ReyAQ==",
"version": "6.30.1",
"resolved": "https://registry.npmjs.org/react-router/-/react-router-6.30.1.tgz",
"integrity": "sha512-X1m21aEmxGXqENEPG3T6u0Th7g0aS4ZmoNynhbs+Cn+q+QGTLt+d5IQ2bHAXKzKcxGJjxACpVbnYQSCRcfxHlQ==",
"license": "MIT",
"dependencies": {
"cookie": "^1.0.1",
"set-cookie-parser": "^2.6.0"
"@remix-run/router": "1.23.0"
},
"engines": {
"node": ">=20.0.0"
"node": ">=14.0.0"
},
"peerDependencies": {
"react": ">=18",
"react-dom": ">=18"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
}
"react": ">=16.8"
}
},
"node_modules/react-router-dom": {
"version": "7.8.2",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-7.8.2.tgz",
"integrity": "sha512-Z4VM5mKDipal2jQ385H6UBhiiEDlnJPx6jyWsTYoZQdl5TrjxEV2a9yl3Fi60NBJxYzOTGTTHXPi0pdizvTwow==",
"version": "6.30.1",
"resolved": "https://registry.npmjs.org/react-router-dom/-/react-router-dom-6.30.1.tgz",
"integrity": "sha512-llKsgOkZdbPU1Eg3zK8lCn+sjD9wMRZZPuzmdWWX5SUs8OFkN5HnFVC0u5KMeMaC9aoancFI/KoLuKPqN+hxHw==",
"license": "MIT",
"dependencies": {
"react-router": "7.8.2"
"@remix-run/router": "1.23.0",
"react-router": "6.30.1"
},
"engines": {
"node": ">=20.0.0"
"node": ">=14.0.0"
},
"peerDependencies": {
"react": ">=18",
"react-dom": ">=18"
"react": ">=16.8",
"react-dom": ">=16.8"
}
},
"node_modules/react-smooth": {
@@ -4020,12 +4004,6 @@
"loose-envify": "^1.1.0"
}
},
"node_modules/set-cookie-parser": {
"version": "2.7.1",
"resolved": "https://registry.npmjs.org/set-cookie-parser/-/set-cookie-parser-2.7.1.tgz",
"integrity": "sha512-IOc8uWeOZgnb3ptbCURJWNjWUPcO3ZnTTdzsurqERrP6nPyv+paC55vJM0LpOlT2ne+Ix+9+CRG1MNLlyZ4GjQ==",
"license": "MIT"
},
"node_modules/sonner": {
"version": "2.0.7",
"resolved": "https://registry.npmjs.org/sonner/-/sonner-2.0.7.tgz",

View File

@@ -46,7 +46,8 @@
"react-hook-form": "^7.55.0",
"react-redux": "^9.2.0",
"react-resizable-panels": "^2.1.7",
"react-router-dom": "^7.8.2",
"react-router": "^6.30.1",
"react-router-dom": "^6.30.1",
"recharts": "^2.15.2",
"sonner": "^2.0.3",
"tailwind-merge": "*",

View File

@@ -1,34 +1,8 @@
import { Routes, Route } from "react-router-dom";
// import AppLayout from "./components/AppLayout";
// Pages
import IndividualWebinars from "./pages/IndividualWebinars";
import Leaderboard from "./pages/Leaderboard";
import HomePage from "./pages/HomePage";
import Dashboard from "./pages/learner/Dashboard";
import { Library } from "./pages/learner/Library";
import { CourseTimeline } from "./pages/learner/CourseTimeline";
import { Settings } from "./pages/Settings";
import { Surveys } from "./pages/Surveys";
import React from "react";
import { Router } from "./components/Router";
export default function App() {
return (
<>
<Routes>
{/* Main */}
<Route path="/" element={<Dashboard />} />
<Route path="/dashboard" element={<Dashboard />} />
<Route path="/library" element={<Library />} />
<Route path="/course" element={<CourseTimeline />} />
<Route path="/settings" element={<Settings userType="individual" />} />
<Route path="/surveys" element={<Surveys userType="individual" />} />
<Route path="/webinars" element={<IndividualWebinars />} />
<Route path="/individual-webinars" element={<IndividualWebinars />} />
<Route path="/leaderboard" element={<Leaderboard />} />
{/* Fallback */}
<Route path="*" element={<HomePage />} />
</Routes>
</>
<Router />
);
}

View File

@@ -0,0 +1,14 @@
import React from "react";
import { Outlet } from "react-router-dom";
export default function AppLayout() {
return (
<div className="min-h-screen">
<main>
<Outlet />
</main>
</div>
);
}

View File

@@ -20,11 +20,11 @@ import {
} from './ui/sheet';
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from './ui/collapsible';
// import { navigate } from './Router';
import { useAuth } from './AuthContext';
// 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';
const exampleImage = 'https://images.unsplash.com/photo-1508214751196-bcfd4ca60f91?w=150&h=150&fit=crop&crop=face';
import {
Menu,
ChevronDown,
@@ -54,12 +54,13 @@ import {
ArrowRight
} from 'lucide-react';
import { useNavigate } from 'react-router-dom';
const navigate = useNavigate();
import { useAuth } from './AuthContext';
interface NavigationProps {
currentPage?: string;
}
export function Navigation({ currentPage }: NavigationProps) {
const navigate = useNavigate();
const [isScrolled, setIsScrolled] = useState(false);
const [activeDropdown, setActiveDropdown] = useState<string | null>(null);
const [isMobileMenuOpen, setIsMobileMenuOpen] = useState(false);
@@ -73,14 +74,14 @@ export function Navigation({ currentPage }: NavigationProps) {
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 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';
@@ -262,451 +263,447 @@ export function Navigation({ currentPage }: NavigationProps) {
];
return (
<nav className={`fixed top-0 left-0 right-0 z-50 transition-all duration-300 ${
isScrolled ? 'bg-white/95 backdrop-blur-md shadow-sm' : 'bg-white'
}`}>
<div className="w-full px-4 lg:px-8">
<div className="flex items-center justify-between h-[70px]">
{/* Logo */}
<div className="flex-shrink-0">
<button
onClick={() => navigate('/')}
className="flex items-center space-x-2 focus:outline-none focus:ring-2 focus:ring-primary rounded-lg p-1 hover:bg-gray-50 transition-colors"
aria-label="Go to KLC homepage"
>
<img
src={klcLogo}
alt="Kautilya Leadership Centre"
className="h-12 w-auto object-contain"
/>
</button>
</div>
// <nav className={`fixed top-0 left-0 right-0 z-50 transition-all duration-300 ${isScrolled ? 'bg-white/95 backdrop-blur-md shadow-sm' : 'bg-white'
// }`}>
// <div className="w-full px-4 lg:px-8">
// <div className="flex items-center justify-between h-[70px]">
// {/* Logo */}
// <div className="flex-shrink-0">
// <button
// onClick={() => navigate('/')}
// className="flex items-center space-x-2 focus:outline-none focus:ring-2 focus:ring-primary rounded-lg p-1 hover:bg-gray-50 transition-colors"
// aria-label="Go to KLC homepage"
// >
// <img
// src={klcLogo}
// alt="Kautilya Leadership Centre"
// className="h-12 w-auto object-contain"
// />
// </button>
// </div>
{/* Desktop Navigation */}
<div className="hidden lg:flex items-center space-x-8">
{navigationItems.map((item) => (
<div key={item.title} className="relative" data-dropdown>
<button
onClick={() => handleDropdownToggle(item.title)}
className="flex items-center space-x-1 text-[16px] text-foreground hover:text-primary transition-colors py-2 px-3 rounded-lg hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-primary"
aria-expanded={activeDropdown === item.title}
aria-haspopup="true"
>
<span>{item.title}</span>
<ChevronDown className={`h-4 w-4 transition-transform ${
activeDropdown === item.title ? 'rotate-180' : ''
}`} />
</button>
// {/* Desktop Navigation */}
// <div className="hidden lg:flex items-center space-x-8">
// {navigationItems.map((item) => (
// <div key={item.title} className="relative" data-dropdown>
// <button
// onClick={() => handleDropdownToggle(item.title)}
// className="flex items-center space-x-1 text-[16px] text-foreground hover:text-primary transition-colors py-2 px-3 rounded-lg hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-primary"
// aria-expanded={activeDropdown === item.title}
// aria-haspopup="true"
// >
// <span>{item.title}</span>
// <ChevronDown className={`h-4 w-4 transition-transform ${activeDropdown === item.title ? 'rotate-180' : ''
// }`} />
// </button>
{activeDropdown === item.title && (
<div className="absolute top-full left-0 mt-2 w-64 bg-white rounded-lg shadow-lg border border-gray-200 py-2 z-50">
{item.items.map((subItem) => {
const IconComponent = subItem.icon;
return (
<button
key={subItem.title}
onClick={() => {
navigate(subItem.href);
setActiveDropdown(null);
}}
className="w-full flex items-center space-x-3 px-4 py-3 text-[16px] text-gray-700 hover:bg-gray-50 hover:text-primary transition-colors text-left focus:outline-none focus:ring-2 focus:ring-primary"
>
<IconComponent className="h-4 w-4 flex-shrink-0" />
<span>{subItem.title}</span>
</button>
);
})}
</div>
)}
</div>
))}
// {activeDropdown === item.title && (
// <div className="absolute top-full left-0 mt-2 w-64 bg-white rounded-lg shadow-lg border border-gray-200 py-2 z-50">
// {item.items.map((subItem) => {
// const IconComponent = subItem.icon;
// return (
// <button
// key={subItem.title}
// onClick={() => {
// navigate(subItem.href);
// setActiveDropdown(null);
// }}
// className="w-full flex items-center space-x-3 px-4 py-3 text-[16px] text-gray-700 hover:bg-gray-50 hover:text-primary transition-colors text-left focus:outline-none focus:ring-2 focus:ring-primary"
// >
// <IconComponent className="h-4 w-4 flex-shrink-0" />
// <span>{subItem.title}</span>
// </button>
// );
// })}
// </div>
// )}
// </div>
// ))}
<button
onClick={() => navigate('/contact')}
className="text-[16px] text-foreground hover:text-primary transition-colors py-2 px-3 rounded-lg hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-primary"
>
Contact
</button>
</div>
// <button
// onClick={() => navigate('/contact')}
// className="text-[16px] text-foreground hover:text-primary transition-colors py-2 px-3 rounded-lg hover:bg-gray-50 focus:outline-none focus:ring-2 focus:ring-primary"
// >
// Contact
// </button>
// </div>
{/* Right Section - Desktop */}
<div className="hidden lg:flex items-center space-x-4">
{!isAuthenticated ? (
<>
<Button
variant="ghost"
onClick={handleLogin}
className="text-[16px] min-h-[44px]"
>
Sign In
</Button>
<Button
onClick={handleSignup}
className="text-[16px] min-h-[44px] bg-primary hover:bg-primary/90 text-primary-foreground"
>
Get Started
</Button>
</>
) : (
<div className="flex items-center space-x-4">
{/* Redesigned User Profile Dropdown */}
<DropdownMenu>
<DropdownMenuTrigger asChild>
<Button
variant="ghost"
className="flex items-center gap-3 h-auto p-2 hover:bg-gray-50 transition-all duration-200 rounded-lg min-h-[44px]"
aria-label="Open user menu"
>
<Avatar className="h-8 w-8">
<AvatarImage
src={currentUser.avatar}
alt={currentUser.name}
/>
<AvatarFallback className="bg-primary/10 text-primary text-sm">
{currentUser.name.split(' ').map(n => n[0]).join('')}
</AvatarFallback>
</Avatar>
<div className="flex flex-col items-start min-w-0">
<span className="text-[16px] font-medium text-gray-900 truncate">
{currentUser.name}
</span>
<span className="text-[14px] text-gray-600 truncate">
{isIndividualUser ? 'Individual Account' : 'Corporate Account'}
</span>
</div>
<ChevronDown className="h-4 w-4 text-gray-500 flex-shrink-0" />
</Button>
</DropdownMenuTrigger>
<DropdownMenuContent className="w-80 p-0" align="end" forceMount>
{/* Header Section */}
<div className="p-4 border-b border-gray-100 bg-gray-50">
<div className="flex items-center gap-3">
<Avatar className="h-12 w-12">
<AvatarImage
src={currentUser.avatar}
alt={currentUser.name}
/>
<AvatarFallback className="bg-primary/10 text-primary text-lg">
{currentUser.name.split(' ').map(n => n[0]).join('')}
</AvatarFallback>
</Avatar>
<div className="flex-1 min-w-0">
<div className="flex items-center gap-2">
<p className="text-[16px] font-semibold text-gray-900 truncate">
{currentUser.name}
</p>
<ChevronDown className="h-4 w-4 text-gray-400 flex-shrink-0" />
</div>
<p className="text-[14px] text-gray-600 truncate">
{isIndividualUser ? 'Individual Account' : 'Corporate Account'}
</p>
</div>
</div>
</div>
// {/* Right Section - Desktop */}
// <div className="hidden lg:flex items-center space-x-4">
// {!isAuthenticated ? (
// <>
// <Button
// variant="ghost"
// onClick={handleLogin}
// className="text-[16px] min-h-[44px]"
// >
// Sign In
// </Button>
// <Button
// onClick={handleSignup}
// className="text-[16px] min-h-[44px] bg-primary hover:bg-primary/90 text-primary-foreground"
// >
// Get Started
// </Button>
// </>
// ) : (
// <div className="flex items-center space-x-4">
// {/* Redesigned User Profile Dropdown */}
// <DropdownMenu>
// <DropdownMenuTrigger asChild>
// <Button
// variant="ghost"
// className="flex items-center gap-3 h-auto p-2 hover:bg-gray-50 transition-all duration-200 rounded-lg min-h-[44px]"
// aria-label="Open user menu"
// >
// <Avatar className="h-8 w-8">
// <AvatarImage
// src={currentUser.avatar}
// alt={currentUser.name}
// />
// <AvatarFallback className="bg-primary/10 text-primary text-sm">
// {currentUser.name.split(' ').map(n => n[0]).join('')}
// </AvatarFallback>
// </Avatar>
// <div className="flex flex-col items-start min-w-0">
// <span className="text-[16px] font-medium text-gray-900 truncate">
// {currentUser.name}
// </span>
// <span className="text-[14px] text-gray-600 truncate">
// {isIndividualUser ? 'Individual Account' : 'Corporate Account'}
// </span>
// </div>
// <ChevronDown className="h-4 w-4 text-gray-500 flex-shrink-0" />
// </Button>
// </DropdownMenuTrigger>
// <DropdownMenuContent className="w-80 p-0" align="end" forceMount>
// {/* Header Section */}
// <div className="p-4 border-b border-gray-100 bg-gray-50">
// <div className="flex items-center gap-3">
// <Avatar className="h-12 w-12">
// <AvatarImage
// src={currentUser.avatar}
// alt={currentUser.name}
// />
// <AvatarFallback className="bg-primary/10 text-primary text-lg">
// {currentUser.name.split(' ').map(n => n[0]).join('')}
// </AvatarFallback>
// </Avatar>
// <div className="flex-1 min-w-0">
// <div className="flex items-center gap-2">
// <p className="text-[16px] font-semibold text-gray-900 truncate">
// {currentUser.name}
// </p>
// <ChevronDown className="h-4 w-4 text-gray-400 flex-shrink-0" />
// </div>
// <p className="text-[14px] text-gray-600 truncate">
// {isIndividualUser ? 'Individual Account' : 'Corporate Account'}
// </p>
// </div>
// </div>
// </div>
{/* Account Switching Section */}
<div className="p-4 border-b border-gray-100">
<h4 className="text-[14px] font-medium text-gray-900 mb-3">Switch Account</h4>
<div className="space-y-2">
{availableAccounts.map((account) => {
const IconComponent = account.icon;
return (
<div
key={account.type}
className={`flex items-center gap-3 p-3 rounded-lg border transition-all duration-200 ${
account.isActive
? 'bg-green-50 border-green-200'
: 'bg-gray-50 border-gray-200 hover:bg-gray-100 cursor-pointer'
}`}
onClick={() => !account.isActive && handleAccountSignIn(account.type as 'individual' | 'corporate')}
>
<div className="relative">
{account.type === 'individual' ? (
<Avatar className="h-8 w-8">
<AvatarImage
src={currentUser.avatar}
alt={currentUser.name}
/>
<AvatarFallback className="bg-blue-100 text-blue-700 text-sm">
<User className="h-4 w-4" />
</AvatarFallback>
</Avatar>
) : (
<div className="h-8 w-8 bg-purple-100 rounded-full flex items-center justify-center">
<Building2 className="h-4 w-4 text-purple-700" />
</div>
)}
{account.isActive && (
<div className="absolute -top-1 -right-1 w-4 h-4 bg-green-500 rounded-full flex items-center justify-center">
<Check className="h-2.5 w-2.5 text-white" />
</div>
)}
</div>
<div className="flex-1 min-w-0">
<p className="text-[14px] font-medium text-gray-900 truncate">
{account.title}
</p>
<p className="text-[14px] text-gray-600 truncate">
{account.subtitle}
</p>
</div>
{!account.isActive && (
<ArrowRight className="h-4 w-4 text-gray-400 flex-shrink-0" />
)}
</div>
);
})}
</div>
</div>
// {/* Account Switching Section */}
// <div className="p-4 border-b border-gray-100">
// <h4 className="text-[14px] font-medium text-gray-900 mb-3">Switch Account</h4>
// <div className="space-y-2">
// {availableAccounts.map((account) => {
// const IconComponent = account.icon;
// return (
// <div
// key={account.type}
// className={`flex items-center gap-3 p-3 rounded-lg border transition-all duration-200 ${account.isActive
// ? 'bg-green-50 border-green-200'
// : 'bg-gray-50 border-gray-200 hover:bg-gray-100 cursor-pointer'
// }`}
// onClick={() => !account.isActive && handleAccountSignIn(account.type as 'individual' | 'corporate')}
// >
// <div className="relative">
// {account.type === 'individual' ? (
// <Avatar className="h-8 w-8">
// <AvatarImage
// src={currentUser.avatar}
// alt={currentUser.name}
// />
// <AvatarFallback className="bg-blue-100 text-blue-700 text-sm">
// <User className="h-4 w-4" />
// </AvatarFallback>
// </Avatar>
// ) : (
// <div className="h-8 w-8 bg-purple-100 rounded-full flex items-center justify-center">
// <Building2 className="h-4 w-4 text-purple-700" />
// </div>
// )}
// {account.isActive && (
// <div className="absolute -top-1 -right-1 w-4 h-4 bg-green-500 rounded-full flex items-center justify-center">
// <Check className="h-2.5 w-2.5 text-white" />
// </div>
// )}
// </div>
// <div className="flex-1 min-w-0">
// <p className="text-[14px] font-medium text-gray-900 truncate">
// {account.title}
// </p>
// <p className="text-[14px] text-gray-600 truncate">
// {account.subtitle}
// </p>
// </div>
// {!account.isActive && (
// <ArrowRight className="h-4 w-4 text-gray-400 flex-shrink-0" />
// )}
// </div>
// );
// })}
// </div>
// </div>
<DropdownMenuSeparator />
// <DropdownMenuSeparator />
{/* Settings and Logout */}
<div className="p-2">
<DropdownMenuItem
className="flex items-center gap-3 px-3 py-2 cursor-pointer rounded-md hover:bg-gray-50 focus:bg-gray-50 min-h-[44px]"
onClick={() => navigate(learnerMenuItems[learnerMenuItems.length - 1].href)}
>
<Settings className="h-5 w-5 text-gray-500" />
<span className="text-[16px] font-medium text-gray-900">Settings</span>
</DropdownMenuItem>
<DropdownMenuItem
className="flex items-center gap-3 px-3 py-2 cursor-pointer rounded-md text-red-600 hover:bg-red-50 focus:bg-red-50 min-h-[44px]"
onClick={handleLogout}
>
<LogOut className="h-5 w-5" />
<span className="text-[16px] font-medium">Sign Out</span>
</DropdownMenuItem>
</div>
</DropdownMenuContent>
</DropdownMenu>
</div>
)}
</div>
// {/* Settings and Logout */}
// <div className="p-2">
// <DropdownMenuItem
// className="flex items-center gap-3 px-3 py-2 cursor-pointer rounded-md hover:bg-gray-50 focus:bg-gray-50 min-h-[44px]"
// onClick={() => navigate(learnerMenuItems[learnerMenuItems.length - 1].href)}
// >
// <Settings className="h-5 w-5 text-gray-500" />
// <span className="text-[16px] font-medium text-gray-900">Settings</span>
// </DropdownMenuItem>
{/* Mobile Menu Button */}
<div className="lg:hidden">
<Sheet open={isMobileMenuOpen} onOpenChange={setIsMobileMenuOpen}>
<SheetTrigger asChild>
<Button
variant="ghost"
size="icon"
className="h-10 w-10"
aria-label="Open mobile menu"
>
<Menu className="h-6 w-6" />
</Button>
</SheetTrigger>
<SheetContent side="right" className="w-full sm:w-96 p-0">
<SheetHeader className="p-6 border-b border-gray-200">
<SheetTitle className="text-left flex items-center gap-3">
<img
src={klcLogo}
alt="KLC"
className="h-8 w-auto object-contain"
/>
<span className="text-lg font-semibold">Menu</span>
</SheetTitle>
</SheetHeader>
// <DropdownMenuItem
// className="flex items-center gap-3 px-3 py-2 cursor-pointer rounded-md text-red-600 hover:bg-red-50 focus:bg-red-50 min-h-[44px]"
// onClick={handleLogout}
// >
// <LogOut className="h-5 w-5" />
// <span className="text-[16px] font-medium">Sign Out</span>
// </DropdownMenuItem>
// </div>
// </DropdownMenuContent>
// </DropdownMenu>
// </div>
// )}
// </div>
<div className="flex flex-col h-full">
{/* User Section for Mobile */}
{isAuthenticated && (
<div className="p-4 border-b border-gray-200">
<div className="flex items-center gap-3 mb-4">
<Avatar className="h-12 w-12">
<AvatarImage
src={currentUser.avatar}
alt={currentUser.name}
/>
<AvatarFallback className="bg-primary/10 text-primary">
{currentUser.name.split(' ').map(n => n[0]).join('')}
</AvatarFallback>
</Avatar>
<div className="flex-1 min-w-0">
<p className="text-[16px] font-semibold text-gray-900 truncate">
{currentUser.name}
</p>
<p className="text-[14px] text-gray-600 truncate">
{isIndividualUser ? 'Individual Account' : 'Corporate Account'}
</p>
</div>
</div>
// {/* Mobile Menu Button */}
// <div className="lg:hidden">
// <Sheet open={isMobileMenuOpen} onOpenChange={setIsMobileMenuOpen}>
// <SheetTrigger asChild>
// <Button
// variant="ghost"
// size="icon"
// className="h-10 w-10"
// aria-label="Open mobile menu"
// >
// <Menu className="h-6 w-6" />
// </Button>
// </SheetTrigger>
// <SheetContent side="right" className="w-full sm:w-96 p-0">
// <SheetHeader className="p-6 border-b border-gray-200">
// <SheetTitle className="text-left flex items-center gap-3">
// <img
// src={klcLogo}
// alt="KLC"
// className="h-8 w-auto object-contain"
// />
// <span className="text-lg font-semibold">Menu</span>
// </SheetTitle>
// </SheetHeader>
{/* Mobile Account Switching */}
<div className="space-y-3">
<h4 className="text-[14px] font-medium text-gray-900">Switch Account</h4>
<div className="space-y-2">
{availableAccounts.map((account) => (
<button
key={account.type}
onClick={() => !account.isActive && handleAccountSignIn(account.type as 'individual' | 'corporate')}
disabled={account.isActive}
className={`w-full flex items-center gap-3 p-3 rounded-lg border text-left transition-all duration-200 ${
account.isActive
? 'bg-green-50 border-green-200'
: 'bg-gray-50 border-gray-200 hover:bg-gray-100'
}`}
>
<div className="relative">
{account.type === 'individual' ? (
<Avatar className="h-8 w-8">
<AvatarImage
src={currentUser.avatar}
alt={currentUser.name}
/>
<AvatarFallback className="bg-blue-100 text-blue-700 text-sm">
<User className="h-4 w-4" />
</AvatarFallback>
</Avatar>
) : (
<div className="h-8 w-8 bg-purple-100 rounded-full flex items-center justify-center">
<Building2 className="h-4 w-4 text-purple-700" />
</div>
)}
{account.isActive && (
<div className="absolute -top-1 -right-1 w-4 h-4 bg-green-500 rounded-full flex items-center justify-center">
<Check className="h-2.5 w-2.5 text-white" />
</div>
)}
</div>
<div className="flex-1 min-w-0">
<p className="text-[14px] font-medium text-gray-900 truncate">
{account.title}
</p>
<p className="text-[14px] text-gray-600 truncate">
{account.subtitle}
</p>
</div>
{!account.isActive && (
<ArrowRight className="h-4 w-4 text-gray-400 flex-shrink-0" />
)}
</button>
))}
</div>
</div>
</div>
)}
// <div className="flex flex-col h-full">
// {/* User Section for Mobile */}
// {isAuthenticated && (
// <div className="p-4 border-b border-gray-200">
// <div className="flex items-center gap-3 mb-4">
// <Avatar className="h-12 w-12">
// <AvatarImage
// src={currentUser.avatar}
// alt={currentUser.name}
// />
// <AvatarFallback className="bg-primary/10 text-primary">
// {currentUser.name.split(' ').map(n => n[0]).join('')}
// </AvatarFallback>
// </Avatar>
// <div className="flex-1 min-w-0">
// <p className="text-[16px] font-semibold text-gray-900 truncate">
// {currentUser.name}
// </p>
// <p className="text-[14px] text-gray-600 truncate">
// {isIndividualUser ? 'Individual Account' : 'Corporate Account'}
// </p>
// </div>
// </div>
{/* Navigation Items */}
<div className="flex-1 overflow-y-auto py-4">
{/* Learner Portal Items (if authenticated) */}
{isAuthenticated && (isIndividualUser || isCorporateUser) && (
<div className="px-4 mb-6">
<h3 className="text-[14px] font-medium text-gray-900 mb-3">
{isIndividualUser ? 'Personal Learning' : 'Corporate Learning'}
</h3>
<div className="space-y-1">
{learnerMenuItems.map((item) => {
const IconComponent = item.icon;
return (
<button
key={item.title}
onClick={() => {
navigate(item.href);
setIsMobileMenuOpen(false);
}}
className="w-full flex items-center gap-3 px-3 py-2 text-left text-[16px] text-gray-700 hover:bg-gray-50 hover:text-primary rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-primary min-h-[44px]"
>
<IconComponent className="h-5 w-5 flex-shrink-0" />
<div className="flex-1 min-w-0">
<div className="font-medium">{item.title}</div>
<div className="text-[14px] text-gray-500 truncate">{item.description}</div>
</div>
</button>
);
})}
</div>
</div>
)}
// {/* Mobile Account Switching */}
// <div className="space-y-3">
// <h4 className="text-[14px] font-medium text-gray-900">Switch Account</h4>
// <div className="space-y-2">
// {availableAccounts.map((account) => (
// <button
// key={account.type}
// onClick={() => !account.isActive && handleAccountSignIn(account.type as 'individual' | 'corporate')}
// disabled={account.isActive}
// className={`w-full flex items-center gap-3 p-3 rounded-lg border text-left transition-all duration-200 ${account.isActive
// ? 'bg-green-50 border-green-200'
// : 'bg-gray-50 border-gray-200 hover:bg-gray-100'
// }`}
// >
// <div className="relative">
// {account.type === 'individual' ? (
// <Avatar className="h-8 w-8">
// <AvatarImage
// src={currentUser.avatar}
// alt={currentUser.name}
// />
// <AvatarFallback className="bg-blue-100 text-blue-700 text-sm">
// <User className="h-4 w-4" />
// </AvatarFallback>
// </Avatar>
// ) : (
// <div className="h-8 w-8 bg-purple-100 rounded-full flex items-center justify-center">
// <Building2 className="h-4 w-4 text-purple-700" />
// </div>
// )}
// {account.isActive && (
// <div className="absolute -top-1 -right-1 w-4 h-4 bg-green-500 rounded-full flex items-center justify-center">
// <Check className="h-2.5 w-2.5 text-white" />
// </div>
// )}
// </div>
// <div className="flex-1 min-w-0">
// <p className="text-[14px] font-medium text-gray-900 truncate">
// {account.title}
// </p>
// <p className="text-[14px] text-gray-600 truncate">
// {account.subtitle}
// </p>
// </div>
// {!account.isActive && (
// <ArrowRight className="h-4 w-4 text-gray-400 flex-shrink-0" />
// )}
// </button>
// ))}
// </div>
// </div>
// </div>
// )}
{/* Public Navigation Items */}
<div className="px-4">
{navigationItems.map((item) => (
<Collapsible key={item.title}>
<CollapsibleTrigger
onClick={() => handleMobileToggle(item.title)}
className="w-full flex items-center justify-between p-3 text-[16px] text-gray-900 hover:bg-gray-50 rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-primary min-h-[44px]"
>
<span className="font-medium">{item.title}</span>
<ChevronRight className={`h-4 w-4 transition-transform ${
expandedMobileSection === item.title ? 'rotate-90' : ''
}`} />
</CollapsibleTrigger>
<CollapsibleContent className="px-4 pb-2">
<div className="space-y-1">
{item.items.map((subItem) => {
const IconComponent = subItem.icon;
return (
<button
key={subItem.title}
onClick={() => {
navigate(subItem.href);
setIsMobileMenuOpen(false);
}}
className="w-full flex items-center gap-3 px-3 py-2 text-left text-[16px] text-gray-600 hover:bg-gray-50 hover:text-primary rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-primary min-h-[44px]"
>
<IconComponent className="h-4 w-4 flex-shrink-0" />
<span>{subItem.title}</span>
</button>
);
})}
</div>
</CollapsibleContent>
</Collapsible>
))}
<button
onClick={() => {
navigate('/contact');
setIsMobileMenuOpen(false);
}}
className="w-full flex items-center p-3 text-[16px] text-gray-900 hover:bg-gray-50 rounded-lg transition-colors text-left focus:outline-none focus:ring-2 focus:ring-primary min-h-[44px]"
>
<span className="font-medium">Contact</span>
</button>
</div>
</div>
// {/* Navigation Items */}
// <div className="flex-1 overflow-y-auto py-4">
// {/* Learner Portal Items (if authenticated) */}
// {isAuthenticated && (isIndividualUser || isCorporateUser) && (
// <div className="px-4 mb-6">
// <h3 className="text-[14px] font-medium text-gray-900 mb-3">
// {isIndividualUser ? 'Personal Learning' : 'Corporate Learning'}
// </h3>
// <div className="space-y-1">
// {learnerMenuItems.map((item) => {
// const IconComponent = item.icon;
// return (
// <button
// key={item.title}
// onClick={() => {
// navigate(item.href);
// setIsMobileMenuOpen(false);
// }}
// className="w-full flex items-center gap-3 px-3 py-2 text-left text-[16px] text-gray-700 hover:bg-gray-50 hover:text-primary rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-primary min-h-[44px]"
// >
// <IconComponent className="h-5 w-5 flex-shrink-0" />
// <div className="flex-1 min-w-0">
// <div className="font-medium">{item.title}</div>
// <div className="text-[14px] text-gray-500 truncate">{item.description}</div>
// </div>
// </button>
// );
// })}
// </div>
// </div>
// )}
{/* Mobile Authentication Actions */}
{!isAuthenticated && (
<div className="p-4 border-t border-gray-200 space-y-2">
<Button
onClick={handleLogin}
variant="outline"
className="w-full text-[16px] min-h-[44px]"
>
Sign In
</Button>
<Button
onClick={handleSignup}
className="w-full text-[16px] min-h-[44px] bg-primary hover:bg-primary/90 text-primary-foreground"
>
Get Started
</Button>
</div>
)}
// {/* Public Navigation Items */}
// <div className="px-4">
// {navigationItems.map((item) => (
// <Collapsible key={item.title}>
// <CollapsibleTrigger
// onClick={() => handleMobileToggle(item.title)}
// className="w-full flex items-center justify-between p-3 text-[16px] text-gray-900 hover:bg-gray-50 rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-primary min-h-[44px]"
// >
// <span className="font-medium">{item.title}</span>
// <ChevronRight className={`h-4 w-4 transition-transform ${expandedMobileSection === item.title ? 'rotate-90' : ''
// }`} />
// </CollapsibleTrigger>
// <CollapsibleContent className="px-4 pb-2">
// <div className="space-y-1">
// {item.items.map((subItem) => {
// const IconComponent = subItem.icon;
// return (
// <button
// key={subItem.title}
// onClick={() => {
// navigate(subItem.href);
// setIsMobileMenuOpen(false);
// }}
// className="w-full flex items-center gap-3 px-3 py-2 text-left text-[16px] text-gray-600 hover:bg-gray-50 hover:text-primary rounded-lg transition-colors focus:outline-none focus:ring-2 focus:ring-primary min-h-[44px]"
// >
// <IconComponent className="h-4 w-4 flex-shrink-0" />
// <span>{subItem.title}</span>
// </button>
// );
// })}
// </div>
// </CollapsibleContent>
// </Collapsible>
// ))}
{/* Mobile Logout */}
{isAuthenticated && (
<div className="p-4 border-t border-gray-200">
<Button
onClick={handleLogout}
variant="outline"
className="w-full text-[16px] min-h-[44px] text-red-600 border-red-200 hover:bg-red-50"
>
<LogOut className="h-4 w-4 mr-2" />
Sign Out
</Button>
</div>
)}
</div>
</SheetContent>
</Sheet>
</div>
</div>
</div>
</nav>
// <button
// onClick={() => {
// navigate('/contact');
// setIsMobileMenuOpen(false);
// }}
// className="w-full flex items-center p-3 text-[16px] text-gray-900 hover:bg-gray-50 rounded-lg transition-colors text-left focus:outline-none focus:ring-2 focus:ring-primary min-h-[44px]"
// >
// <span className="font-medium">Contact</span>
// </button>
// </div>
// </div>
// {/* Mobile Authentication Actions */}
// {!isAuthenticated && (
// <div className="p-4 border-t border-gray-200 space-y-2">
// <Button
// onClick={handleLogin}
// variant="outline"
// className="w-full text-[16px] min-h-[44px]"
// >
// Sign In
// </Button>
// <Button
// onClick={handleSignup}
// className="w-full text-[16px] min-h-[44px] bg-primary hover:bg-primary/90 text-primary-foreground"
// >
// Get Started
// </Button>
// </div>
// )}
// {/* Mobile Logout */}
// {isAuthenticated && (
// <div className="p-4 border-t border-gray-200">
// <Button
// onClick={handleLogout}
// variant="outline"
// className="w-full text-[16px] min-h-[44px] text-red-600 border-red-200 hover:bg-red-50"
// >
// <LogOut className="h-4 w-4 mr-2" />
// Sign Out
// </Button>
// </div>
// )}
// </div>
// </SheetContent>
// </Sheet>
// </div>
// </div>
// </div>
// </nav>
<></>
);
}

View File

@@ -1,4 +1,6 @@
import React from "react";
import { Routes, Route, Navigate, useSearchParams } from "react-router-dom";
import AppLayout from "./AppLayout";
// Import all page components
import { HomePage } from "../pages/HomePage";
@@ -83,136 +85,138 @@ export function Router() {
return (
<div className="min-h-screen">
<Routes>
{/* Main */}
<Route path="/" element={<HomePage />} />
<Route path="/" element={<AppLayout />}>
{/* Main */}
<Route index element={<HomePage />} />
{/* Auth */}
<Route path="/auth" element={<LoginSelection />} />
<Route path="/login-selection" element={<LoginSelection />} />
<Route path="/login" element={<Login />} />
<Route path="/signup" element={<Signup />} />
<Route path="/corporate/auth" element={<CorporateAuth />} />
<Route path="/corporate/login" element={<CorporateLogin />} />
<Route path="/corporate/signup" element={<CorporateSignup />} />
<Route path="/forgot-password" element={<ForgotPassword />} />
<Route path="/email-verification" element={<EmailVerification />} />
{/* Auth */}
<Route path="auth" element={<LoginSelection />} />
<Route path="login-selection" element={<LoginSelection />} />
<Route path="login" element={<Login />} />
<Route path="signup" element={<Signup />} />
<Route path="corporate/auth" element={<CorporateAuth />} />
<Route path="corporate/login" element={<CorporateLogin />} />
<Route path="corporate/signup" element={<CorporateSignup />} />
<Route path="forgot-password" element={<ForgotPassword />} />
<Route path="email-verification" element={<EmailVerification />} />
{/* Learner Portal */}
<Route path="/dashboard" element={<DashboardRoute />} />
<Route path="/library" element={<Library />} />
<Route path="/course" element={<CourseTimeline />} />
<Route path="/settings" element={<Settings />} />
<Route path="/surveys" element={<Surveys userType="individual" />} />
<Route path="/webinars" element={<WebinarsRoute />} />
<Route path="/leaderboard" element={<LeaderboardRoute />} />
{/* Learner Portal */}
<Route path="dashboard" element={<DashboardRoute />} />
<Route path="library" element={<Library />} />
<Route path="course" element={<CourseTimeline />} />
<Route path="settings" element={<Settings />} />
<Route path="surveys" element={<Surveys userType="individual" />} />
<Route path="webinars" element={<WebinarsRoute />} />
<Route path="leaderboard" element={<LeaderboardRoute />} />
{/* Other Pages */}
<Route path="/individual-webinars" element={<IndividualWebinars />} />
<Route path="/contact" element={<Contact />} />
<Route path="/about-klc" element={<AboutKLC />} />
<Route path="/about-us/our-vision" element={<OurVision />} />
<Route path="/about-us/our-team" element={<OurTeam />} />
<Route path="/about-us/our-impact" element={<OurImpact />} />
<Route path="/about-us/our-expertise" element={<OurExpertise />} />
{/* Other Pages */}
<Route path="individual-webinars" element={<IndividualWebinars />} />
<Route path="contact" element={<Contact />} />
<Route path="about-klc" element={<AboutKLC />} />
<Route path="about-us/our-vision" element={<OurVision />} />
<Route path="about-us/our-team" element={<OurTeam />} />
<Route path="about-us/our-impact" element={<OurImpact />} />
<Route path="about-us/our-expertise" element={<OurExpertise />} />
{/* Programmes */}
<Route path="/programmes" element={<ProgrammeCatalogue />} />
<Route path="/programmes/detail" element={<ProgrammeDetail />} />
<Route
path="/programmes/executive-leadership"
element={<ExecutiveLeadership />}
/>
<Route path="/programmes/team-leadership" element={<TeamLeadership />} />
<Route
path="/programmes/innovation-leadership"
element={<InnovationLeadership />}
/>
<Route
path="/programmes/leadership-online"
element={<LeadershipOnline />}
/>
{/* Programmes */}
<Route path="programmes" element={<ProgrammeCatalogue />} />
<Route path="programmes/detail" element={<ProgrammeDetail />} />
<Route
path="programmes/executive-leadership"
element={<ExecutiveLeadership />}
/>
<Route path="programmes/team-leadership" element={<TeamLeadership />} />
<Route
path="programmes/innovation-leadership"
element={<InnovationLeadership />}
/>
<Route
path="programmes/leadership-online"
element={<LeadershipOnline />}
/>
{/* Services */}
<Route
path="/services/leadership-development"
element={<LeadershipDevelopment />}
/>
<Route
path="/services/management-development"
element={<ManagementDevelopment />}
/>
<Route
path="/services/executive-coaching"
element={<ExecutiveCoaching />}
/>
<Route
path="/services/culture-competence"
element={<CultureCompetence />}
/>
<Route path="/services/consulting" element={<Consulting />} />
<Route path="/services/learning-facility" element={<LearningFacility />} />
{/* Services */}
<Route
path="services/leadership-development"
element={<LeadershipDevelopment />}
/>
<Route
path="services/management-development"
element={<ManagementDevelopment />}
/>
<Route
path="services/executive-coaching"
element={<ExecutiveCoaching />}
/>
<Route
path="services/culture-competence"
element={<CultureCompetence />}
/>
<Route path="services/consulting" element={<Consulting />} />
<Route path="services/learning-facility" element={<LearningFacility />} />
{/* Learning */}
<Route path="/learning/articles" element={<Articles />} />
<Route path="/learning/blog" element={<BlogListing />} />
<Route path="/learning/blog/detail" element={<BlogDetail />} />
<Route path="/learning/resources" element={<Resources />} />
{/* Learning */}
<Route path="learning/articles" element={<Articles />} />
<Route path="learning/blog" element={<BlogListing />} />
<Route path="learning/blog/detail" element={<BlogDetail />} />
<Route path="learning/resources" element={<Resources />} />
{/* Webinars */}
<Route path="/webinars/listing" element={<WebinarListing />} />
<Route path="/webinars/detail" element={<WebinarDetail />} />
{/* Webinars */}
<Route path="webinars/listing" element={<WebinarListing />} />
<Route path="webinars/detail" element={<WebinarDetail />} />
{/* Facilities */}
<Route path="/facilities/detail" element={<FacilityDetail />} />
<Route path="/facilities/booking" element={<FacilityBooking />} />
<Route path="/facilities/tour" element={<FacilityTour />} />
{/* Facilities */}
<Route path="facilities/detail" element={<FacilityDetail />} />
<Route path="facilities/booking" element={<FacilityBooking />} />
<Route path="facilities/tour" element={<FacilityTour />} />
{/* E-commerce */}
<Route path="/cart" element={<Cart />} />
<Route path="/checkout" element={<Checkout />} />
<Route path="/order-confirmation" element={<OrderConfirmation />} />
<Route path="/order-failed" element={<OrderFailed />} />
{/* E-commerce */}
<Route path="cart" element={<Cart />} />
<Route path="checkout" element={<Checkout />} />
<Route path="order-confirmation" element={<OrderConfirmation />} />
<Route path="order-failed" element={<OrderFailed />} />
{/* Extra Features */}
<Route path="/my-cohort" element={<MyCohort />} />
{/* Extra Features */}
<Route path="my-cohort" element={<MyCohort />} />
{/* Legal */}
<Route path="/faq" element={<FAQ />} />
<Route path="/privacy" element={<Privacy />} />
<Route path="/terms" element={<Terms />} />
{/* Legal */}
<Route path="faq" element={<FAQ />} />
<Route path="privacy" element={<Privacy />} />
<Route path="terms" element={<Terms />} />
{/* Legacy Redirects */}
<Route
path="/corporate/dashboard"
element={<Navigate to="/dashboard?view=corporate" replace />}
/>
<Route
path="/corporate/library"
element={<Navigate to="/library?view=corporate" replace />}
/>
<Route
path="/corporate/course"
element={<Navigate to="/course?view=corporate" replace />}
/>
<Route
path="/corporate/settings"
element={<Navigate to="/settings?view=corporate" replace />}
/>
<Route
path="/corporate/surveys"
element={<Navigate to="/surveys?view=corporate" replace />}
/>
<Route
path="/corporate/webinars"
element={<Navigate to="/webinars?view=corporate" replace />}
/>
<Route
path="/corporate/leaderboard"
element={<Navigate to="/leaderboard?view=corporate" replace />}
/>
{/* Legacy Redirects */}
<Route
path="corporate/dashboard"
element={<Navigate to="/dashboard?view=corporate" replace />}
/>
<Route
path="corporate/library"
element={<Navigate to="/library?view=corporate" replace />}
/>
<Route
path="corporate/course"
element={<Navigate to="/course?view=corporate" replace />}
/>
<Route
path="corporate/settings"
element={<Navigate to="/settings?view=corporate" replace />}
/>
<Route
path="corporate/surveys"
element={<Navigate to="/surveys?view=corporate" replace />}
/>
<Route
path="corporate/webinars"
element={<Navigate to="/webinars?view=corporate" replace />}
/>
<Route
path="corporate/leaderboard"
element={<Navigate to="/leaderboard?view=corporate" replace />}
/>
{/* Catch-all */}
<Route path="*" element={<NotFound />} />
{/* Catch-all under layout */}
<Route path="*" element={<NotFound />} />
</Route>
</Routes>
</div>
);

View File

@@ -5,7 +5,8 @@ import { Badge } from '../ui/badge';
import { Sheet, SheetContent, SheetTrigger } from '../ui/sheet';
import { ScrollArea } from '../ui/scroll-area';
import { Separator } from '../ui/separator';
import logo from "../../assets/klc-logo.png"
// import logo from "../../assets/klc-logo.png"
const logo = new URL("../../assets/klc-logo.png", import.meta.url).href
import {
Menu,
Search,
@@ -261,7 +262,7 @@ export function LearnerLayout({ children, currentPage, userType = 'individual',
</div>
{/* Navigation */}
<ScrollArea className="flex-1 px-4 py-6">
<div className="flex-1 px-4 py-6" >
<nav className="space-y-2">
{navigationItems.map((item) => {
const Icon = item.icon;
@@ -286,14 +287,14 @@ export function LearnerLayout({ children, currentPage, userType = 'individual',
</nav>
</ScrollArea>
</div>
</div>
</div >
);
return (
<div className="min-h-screen bg-background">
<div className="min-h-screen " style={{ backgroundColor: "green" }}>
{/* Mobile Header */}
<header className="lg:hidden border-b border-border bg-card/95 backdrop-blur supports-[backdrop-filter]:bg-card/60">
<header className="lg:hidden fixed top-0 left-0 right-0 z-50 border-b border-border bg-card/95 backdrop-blur supports-[backdrop-filter]:bg-card/60">
<div className="flex items-center justify-between p-4">
<Sheet open={sidebarOpen} onOpenChange={setSidebarOpen}>
<SheetTrigger asChild>
@@ -359,9 +360,9 @@ export function LearnerLayout({ children, currentPage, userType = 'individual',
</div>
{/* Main Content Area - Optimized for wider content */}
<div className="flex-1 lg:ml-0">
<div className="flex-1 lg:ml-0" style={{ backgroundColor: "green" }}>
{/* Desktop Header */}
<header className="hidden lg:block border-b border-border bg-card/95 backdrop-blur supports-[backdrop-filter]:bg-card/60">
<header className="hidden lg:block fixed top-0 left-60 right-0 z-40 border-b border-border bg-card/95 backdrop-blur supports-[backdrop-filter]:bg-card/60">
<div className="flex items-center justify-end px-4 py-4">
{/* <div className="flex-1 max-w-sm">
<div className="relative">
@@ -431,8 +432,8 @@ export function LearnerLayout({ children, currentPage, userType = 'individual',
</AvatarFallback>
</Avatar>
<div className="hidden xl:block">
<p className="text-lg font-medium">{user?.name || 'Priya Sharma'}</p>
<p className="text-sm text-muted-foreground">{user?.email || 'priya.sharma@example.com'}</p>
<p className="text-lg font-medium">{user?.name || 'Parth Patel'}</p>
<p className="text-sm text-muted-foreground">{user?.email || 'parthPatel@example.com'}</p>
</div>
<ChevronDown className="h-4 w-4 text-muted-foreground" />
</div>
@@ -440,15 +441,15 @@ export function LearnerLayout({ children, currentPage, userType = 'individual',
</div>
</header>
{/* Page Content - Remove default padding, let pages control their own spacing */}
{/* Page Content - Scrollable area under fixed headers */}
<main
className="flex-1 min-h-screen bg-background"
className="flex-1 h-screen bg-background overflow-hidden"
role="main"
id="main-content"
tabIndex={-1}
>
{/* Content wrapper with consistent spacing and accessibility */}
<div className="w-full min-h-full">
<div className="w-full h-full overflow-y-auto pt-[56px] lg:pt-[64px]">
{/* Skip to main content anchor for screen readers */}
<a
href="#learner-content"
@@ -460,7 +461,7 @@ export function LearnerLayout({ children, currentPage, userType = 'individual',
{/* Main learner content area */}
<div
id="learner-content"
className="w-full"
className="w-full h-full"
role="region"
aria-label="Learner portal content"
>
@@ -528,7 +529,7 @@ export function LearnerLayout({ children, currentPage, userType = 'individual',
{/* Progress indicator for course content */}
<div
id="learner-progress-indicator"
className="fixed top-[70px] left-0 right-0 h-1 bg-gray-200 opacity-0 transition-opacity duration-200 z-40"
className="fixed top-[56px] lg:top-[64px] left-0 right-0 h-1 bg-gray-200 opacity-0 transition-opacity duration-200 z-40"
role="progressbar"
aria-label="Page loading progress"
aria-hidden="true"

View File

@@ -1,14 +1,18 @@
import React from "react";
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 { AuthProvider } from "./components/AuthContext.tsx";
createRoot(document.getElementById("root")!).render(
<Provider store={store}>
<BrowserRouter>
<App />
</BrowserRouter>
<AuthProvider>
<BrowserRouter>
<App />
</BrowserRouter>
</AuthProvider>
</Provider>
);

View File

@@ -1,7 +1,9 @@
import React, { useEffect } from 'react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function AboutKLC() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -1,7 +1,9 @@
import React, { useEffect } from 'react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function Articles() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -1,7 +1,9 @@
import React, { useEffect } from 'react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function BlogDetail() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -1,7 +1,9 @@
import React, { useEffect } from 'react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function BlogListing() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -1,7 +1,9 @@
import React, { useEffect } from 'react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function Cart() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -1,7 +1,9 @@
import React, { useEffect } from 'react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function Checkout() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -3,7 +3,7 @@ import { Button } from '../components/ui/button';
import { Input } from '../components/ui/input';
import { Card, CardContent, CardHeader, CardTitle } from '../components/ui/card';
import { ArrowLeft, Mail, Phone, MapPin, Clock, Send } from 'lucide-react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function Contact() {
const [formData, setFormData] = useState({
@@ -13,11 +13,12 @@ export function Contact() {
message: ''
});
const [isLoading, setIsLoading] = useState(false);
const navigate = useNavigate();
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setIsLoading(true);
try {
// Simulate form submission
await new Promise(resolve => setTimeout(resolve, 1000));
@@ -65,7 +66,7 @@ export function Contact() {
<div className="container mx-auto px-4 lg:px-8 -mt-8">
<div className="max-w-6xl mx-auto">
<div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
{/* Contact Form */}
<div className="lg:col-span-2">
<Card className="bg-white shadow-xl border-0">
@@ -77,7 +78,7 @@ export function Contact() {
We'd love to hear from you. Fill out the form below and we'll get back to you as soon as possible.
</p>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className="space-y-6">
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">

View File

@@ -2,9 +2,11 @@ import React from 'react';
import { Button } from '../components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '../components/ui/card';
import { ArrowLeft, Building2, Users, Shield, BarChart3 } from 'lucide-react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function CorporateAuth() {
const navigate = useNavigate();
const handleBackNavigation = () => {
navigate('/auth');
};
@@ -59,7 +61,7 @@ export function CorporateAuth() {
Sign in to your corporate learning account or request access from your administrator
</p>
</CardHeader>
<CardContent className="space-y-8">
{/* Features Overview */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">

View File

@@ -40,7 +40,7 @@ import {
Sparkles
} from 'lucide-react';
import { useNavigate } from 'react-router-dom';
const navigate = useNavigate();
// const navigate = useNavigate();
// Mock data for leaderboard
const mockLeaderboard = [
@@ -165,7 +165,7 @@ const AnimatedNumber = ({ value, duration = 1000 }: { value: number; duration?:
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));
@@ -232,12 +232,12 @@ export function CorporateLeaderboard() {
// 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());
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;
});
@@ -299,7 +299,7 @@ export function CorporateLeaderboard() {
<h2 className="text-xl font-semibold mb-1 text-foreground">Performance Tracking</h2>
<p className="text-base text-muted-foreground">View leaderboard data across different time periods</p>
</div>
<div className="flex gap-2">
<Button
variant={timeFilter === 'week' ? 'default' : 'outline'}
@@ -353,64 +353,61 @@ export function CorporateLeaderboard() {
const isFirst = index === 0;
const isSecond = index === 1;
const isThird = index === 2;
return (
<motion.div
key={user.id}
initial={{ opacity: 0, y: 30, scale: 0.95 }}
animate={{ opacity: 1, y: 0, scale: 1 }}
transition={{
transition={{
duration: 0.6,
delay: index * 0.15,
ease: "easeOut"
}}
whileHover={{
whileHover={{
scale: 1.02,
y: -5,
transition: { duration: 0.2 }
}}
className="w-full"
>
<Card
className={`relative overflow-hidden transition-all duration-300 hover:shadow-xl cursor-pointer group ${
isFirst ? 'border-2 border-[#F8C301] bg-gradient-to-br from-[#F8C301]/5 to-[#F8C301]/10' :
isSecond ? 'border-2 border-primary bg-gradient-to-br from-primary/5 to-primary/10' :
'border-2 border-[#26231A] bg-gradient-to-br from-[#26231A]/5 to-[#26231A]/10'
} ${isFirst ? 'lg:scale-105 lg:-translate-y-2' : ''}`}
<Card
className={`relative overflow-hidden transition-all duration-300 hover:shadow-xl cursor-pointer group ${isFirst ? 'border-2 border-[#F8C301] bg-gradient-to-br from-[#F8C301]/5 to-[#F8C301]/10' :
isSecond ? 'border-2 border-primary bg-gradient-to-br from-primary/5 to-primary/10' :
'border-2 border-[#26231A] bg-gradient-to-br from-[#26231A]/5 to-[#26231A]/10'
} ${isFirst ? 'lg:scale-105 lg:-translate-y-2' : ''}`}
>
{/* Subtle Metallic Shimmer Effect for Top 3 */}
<div
className={`absolute inset-0 opacity-0 group-hover:opacity-60 transition-opacity duration-1000 pointer-events-none shimmer-effect ${
isFirst ? 'shimmer-gold' : isSecond ? 'shimmer-silver' : 'shimmer-bronze'
}`}
<div
className={`absolute inset-0 opacity-0 group-hover:opacity-60 transition-opacity duration-1000 pointer-events-none shimmer-effect ${isFirst ? 'shimmer-gold' : isSecond ? 'shimmer-silver' : 'shimmer-bronze'
}`}
/>
{/* Rank Ribbon with KLC Colors */}
<motion.div
className={`absolute top-0 right-0 px-3 py-1 rounded-bl-lg text-white text-sm font-medium ${
isFirst ? 'bg-[#F8C301] text-[#26231A]' :
isSecond ? 'bg-primary text-white' :
'bg-[#26231A] text-white'
}`}
<motion.div
className={`absolute top-0 right-0 px-3 py-1 rounded-bl-lg text-white text-sm font-medium ${isFirst ? 'bg-[#F8C301] text-[#26231A]' :
isSecond ? 'bg-primary text-white' :
'bg-[#26231A] text-white'
}`}
initial={{ x: 20, opacity: 0 }}
animate={{ x: 0, opacity: 1 }}
transition={{ delay: index * 0.15 + 0.3 }}
>
#{user.rank}
</motion.div>
{/* Winner Crown for First Place */}
{isFirst && (
<motion.div
<motion.div
className="absolute top-4 left-4"
initial={{ rotate: -10, scale: 0 }}
animate={{
rotate: 0,
animate={{
rotate: 0,
scale: 1,
y: [0, -2, 0],
rotateZ: [0, 2, -2, 0]
}}
transition={{
transition={{
delay: 0.5,
type: "spring",
stiffness: 200,
@@ -433,29 +430,28 @@ export function CorporateLeaderboard() {
<CardContent className="p-8 text-center">
{/* Rank Icon */}
<motion.div
<motion.div
className="flex justify-center mb-6"
initial={{ scale: 0, rotate: -180 }}
animate={{ scale: 1, rotate: 0 }}
transition={{
transition={{
delay: index * 0.15 + 0.2,
type: "spring",
stiffness: 150
}}
>
<div className={`p-4 rounded-full ${
isFirst ? 'bg-[#F8C301]/10' : isSecond ? 'bg-primary/10' : 'bg-[#26231A]/10'
}`}>
<div className={`p-4 rounded-full ${isFirst ? 'bg-[#F8C301]/10' : isSecond ? 'bg-primary/10' : 'bg-[#26231A]/10'
}`}>
{getRankIcon(user.rank)}
</div>
</motion.div>
{/* User Avatar with Enhanced Styling */}
<motion.div
<motion.div
className="relative mb-6"
initial={{ scale: 0 }}
animate={{ scale: 1 }}
transition={{
transition={{
delay: index * 0.15 + 0.4,
type: "spring",
stiffness: 200
@@ -469,7 +465,7 @@ export function CorporateLeaderboard() {
</AvatarFallback>
</Avatar>
{/* Trend Indicator */}
<motion.div
<motion.div
className="absolute -bottom-2 -right-2 p-1 bg-white rounded-full shadow-md"
initial={{ scale: 0 }}
animate={{
@@ -489,7 +485,7 @@ export function CorporateLeaderboard() {
</motion.div>
{/* User Information */}
<motion.div
<motion.div
className="mb-6"
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
@@ -501,7 +497,7 @@ export function CorporateLeaderboard() {
</motion.div>
{/* Performance Stats */}
<motion.div
<motion.div
className="grid grid-cols-3 gap-4 mb-6 p-4 bg-white/50 rounded-lg backdrop-blur-sm"
initial={{ opacity: 0, scale: 0.9 }}
animate={{ opacity: 1, scale: 1 }}
@@ -528,7 +524,7 @@ export function CorporateLeaderboard() {
</motion.div>
{/* Level Progress */}
<motion.div
<motion.div
className="mb-6"
initial={{ opacity: 0, x: -20 }}
animate={{ opacity: 1, x: 0 }}
@@ -545,7 +541,7 @@ export function CorporateLeaderboard() {
</motion.div>
{/* Achievement Badges */}
<motion.div
<motion.div
className="space-y-3"
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
@@ -558,18 +554,17 @@ export function CorporateLeaderboard() {
key={badge}
initial={{ opacity: 0, scale: 0.8 }}
animate={{ opacity: 1, scale: 1 }}
transition={{
transition={{
delay: index * 0.15 + 1 + (badgeIndex * 0.1)
}}
whileHover={{ scale: 1.05 }}
>
<Badge
variant="outline"
className={`text-sm px-3 py-1 ${
badgeIndex === 0 ? 'border-[#F8C301]/30 bg-[#F8C301]/5 text-[#26231A]' :
badgeIndex === 1 ? 'border-primary/30 bg-primary/5 text-primary' :
'border-success/30 bg-success/5 text-success'
}`}
<Badge
variant="outline"
className={`text-sm px-3 py-1 ${badgeIndex === 0 ? 'border-[#F8C301]/30 bg-[#F8C301]/5 text-[#26231A]' :
badgeIndex === 1 ? 'border-primary/30 bg-primary/5 text-primary' :
'border-success/30 bg-success/5 text-success'
}`}
>
{badge}
</Badge>
@@ -579,7 +574,7 @@ export function CorporateLeaderboard() {
</motion.div>
{/* Monthly Performance Indicator */}
<motion.div
<motion.div
className="mt-6 pt-4 border-t border-border/50"
initial={{ opacity: 0, y: 10 }}
animate={{ opacity: 1, y: 0 }}
@@ -655,8 +650,8 @@ export function CorporateLeaderboard() {
</SelectContent>
</Select>
<Button
variant="outline"
<Button
variant="outline"
className="text-base h-11"
onClick={() => {
setSearchQuery('');
@@ -720,7 +715,7 @@ export function CorporateLeaderboard() {
{user.name.split(' ').map(n => n[0]).join('')}
</AvatarFallback>
</Avatar>
<div className="flex-1 min-w-0">
<div className="flex items-center gap-2">
<p className="text-base font-medium text-foreground group-hover:text-primary transition-colors truncate">

View File

@@ -2,7 +2,6 @@ import React, { useState, useEffect } from 'react';
import { Navigation } from '../components/Navigation';
import { Footer } from '../components/Footer';
import { AIChatbot } from '../components/AIChatbot';
const navigate = useNavigate();
import { Button } from '../components/ui/button';
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from '../components/ui/card';
import { Input } from '../components/ui/input';
@@ -33,6 +32,7 @@ import {
Target,
Star
} from 'lucide-react';
import { useNavigate } from 'react-router';
interface SignInFormData {
workEmail: string;
@@ -147,9 +147,10 @@ export default function CorporateLearnerLogin() {
const [showEmailVerification, setShowEmailVerification] = useState(false);
const [maskedEmail, setMaskedEmail] = useState('');
const [resendCooldown, setResendCooldown] = useState(0);
const navigate = useNavigate();
useEffect(() => {
document.title = isSignUp
document.title = isSignUp
? 'Join Your Learning Journey - Corporate Learner | KLC'
: 'Welcome Back, Learner - Corporate Access | KLC';
}, [isSignUp]);
@@ -171,10 +172,10 @@ export default function CorporateLearnerLogin() {
};
const score = Object.values(criteria).filter(Boolean).length;
let label = 'Very Weak';
let color = 'bg-destructive';
if (score >= 4) {
label = 'Strong';
color = 'bg-success';
@@ -273,11 +274,11 @@ export default function CorporateLearnerLogin() {
const handleSignUpInputChange = (field: keyof SignUpFormData, value: string) => {
setSignUpData(prev => ({ ...prev, [field]: value }));
if (errors[field]) {
setErrors(prev => ({ ...prev, [field]: '' }));
}
if (field === 'password') {
setPasswordStrength(calculatePasswordStrength(value));
}
@@ -308,19 +309,19 @@ export default function CorporateLearnerLogin() {
try {
await new Promise(resolve => setTimeout(resolve, 1500));
if (signInData.workEmail === 'suspended@company.com') {
setAccountSuspended(true);
setIsSubmitting(false);
return;
}
if (signInData.workEmail === 'mfa@company.com' && signInData.password === 'learner123' && !requiresMFA) {
setRequiresMFA(true);
setIsSubmitting(false);
return;
}
if (signInData.workEmail === 'learner@company.com' && signInData.password === 'learner123') {
const redirectUrl = sessionStorage.getItem('loginRedirect') || '/corporate/dashboard';
sessionStorage.removeItem('loginRedirect');
@@ -372,7 +373,7 @@ export default function CorporateLearnerLogin() {
return (
<div className="min-h-screen bg-background">
<Navigation currentPage="/signin/corporate-learner" />
<main className="pt-40 pb-16">
<div className="container mx-auto px-4 lg:px-8">
<div className="max-w-2xl mx-auto text-center">
@@ -381,17 +382,17 @@ export default function CorporateLearnerLogin() {
<div className="w-16 h-16 bg-secondary/10 rounded-full flex items-center justify-center mx-auto mb-6">
<GraduationCap className="w-8 h-8 text-secondary" />
</div>
<h1 className="text-2xl mb-4">Check Your Inbox</h1>
<p className="text-base text-muted-foreground mb-6">
We've sent a verification email to <strong>{maskedEmail}</strong>
</p>
<p className="text-base text-muted-foreground mb-8">
Click the verification link to activate your learner account and start your development journey.
Click the verification link to activate your learner account and start your development journey.
The link will expire in 30 minutes.
</p>
<div className="space-y-4">
<Button
onClick={handleResendEmail}
@@ -402,7 +403,7 @@ export default function CorporateLearnerLogin() {
<RefreshCw className="w-4 h-4 mr-2" />
{resendCooldown > 0 ? `Resend in ${resendCooldown}s` : 'Resend Email'}
</Button>
<p className="text-sm text-muted-foreground">
Need help getting started? Contact your HR team or email us at{' '}
<a href="mailto:learners@klc.edu.in" className="text-primary hover:underline">
@@ -410,7 +411,7 @@ export default function CorporateLearnerLogin() {
</a>
</p>
</div>
<div className="mt-8 p-4 bg-muted/50 rounded-lg">
<p className="text-sm text-muted-foreground mb-2">Demo Mode:</p>
<Button
@@ -436,7 +437,7 @@ export default function CorporateLearnerLogin() {
return (
<div className="min-h-screen bg-background">
<Navigation currentPage="/signin/corporate-learner" />
<main className="pt-40 pb-16">
<div className="container mx-auto px-4 lg:px-8">
<div className="max-w-6xl mx-auto">
@@ -452,7 +453,7 @@ export default function CorporateLearnerLogin() {
{isSignUp ? 'Start Your Learning Journey' : 'Welcome Back to Your Learning'}
</h1>
<p className="text-base text-muted-foreground leading-relaxed">
{isSignUp
{isSignUp
? 'Join your organization\'s learning community and unlock your potential with personalized development programs, skill certifications, and peer collaboration.'
: 'Continue your professional development journey with access to your learning dashboard, progress tracking, and new skill-building opportunities.'
}
@@ -481,7 +482,7 @@ export default function CorporateLearnerLogin() {
<h3 className="text-lg font-semibold text-foreground mb-2">Learning Excellence</h3>
<p className="text-base text-muted-foreground">Join thousands of successful learners</p>
</div>
<div className="grid grid-cols-2 gap-6">
{learnerStats.map((stat) => {
const Icon = stat.icon;
@@ -511,15 +512,15 @@ export default function CorporateLearnerLogin() {
{isSignUp ? 'Join Your Learning Community' : 'Welcome Back, Learner'}
</CardTitle>
<CardDescription className="text-base min-h-[44px] flex items-center justify-center">
{isSignUp
{isSignUp
? 'Get started with your personalized learning journey'
: requiresMFA
? 'Enter the verification code sent to your device'
: requiresMFA
? 'Enter the verification code sent to your device'
: 'Access your learning dashboard and continue growing'
}
</CardDescription>
</CardHeader>
<CardContent>
<form onSubmit={isSignUp ? handleSignUpSubmit : handleSignInSubmit} className="space-y-6">
{accountSuspended && (
@@ -617,7 +618,7 @@ export default function CorporateLearnerLogin() {
id="workEmail"
type="email"
value={isSignUp ? signUpData.workEmail : signInData.workEmail}
onChange={(e) => isSignUp
onChange={(e) => isSignUp
? handleSignUpInputChange('workEmail', e.target.value)
: handleSignInInputChange('workEmail', e.target.value)
}
@@ -644,7 +645,7 @@ export default function CorporateLearnerLogin() {
id="password"
type={showPassword ? "text" : "password"}
value={isSignUp ? signUpData.password : signInData.password}
onChange={(e) => isSignUp
onChange={(e) => isSignUp
? handleSignUpInputChange('password', e.target.value)
: handleSignInInputChange('password', e.target.value)
}
@@ -677,16 +678,15 @@ export default function CorporateLearnerLogin() {
<div className="space-y-2">
<div className="flex items-center justify-between">
<span className="text-sm text-muted-foreground">Password strength:</span>
<span className={`text-sm font-medium ${
passwordStrength.score >= 4 ? 'text-success' :
passwordStrength.score >= 3 ? 'text-secondary' :
passwordStrength.score >= 2 ? 'text-orange-500' : 'text-destructive'
}`}>
<span className={`text-sm font-medium ${passwordStrength.score >= 4 ? 'text-success' :
passwordStrength.score >= 3 ? 'text-secondary' :
passwordStrength.score >= 2 ? 'text-orange-500' : 'text-destructive'
}`}>
{passwordStrength.label}
</span>
</div>
<Progress
value={(passwordStrength.score / 5) * 100}
<Progress
value={(passwordStrength.score / 5) * 100}
className="h-2"
/>
<div className="grid grid-cols-2 gap-2 text-xs">
@@ -695,9 +695,9 @@ export default function CorporateLearnerLogin() {
{met ? <Check className="w-3 h-3" /> : <X className="w-3 h-3" />}
<span>
{key === 'length' ? '8+ chars' :
key === 'lowercase' ? 'lowercase' :
key === 'uppercase' ? 'uppercase' :
key === 'number' ? 'number' : 'symbol'}
key === 'lowercase' ? 'lowercase' :
key === 'uppercase' ? 'uppercase' :
key === 'number' ? 'number' : 'symbol'}
</span>
</div>
))}

View File

@@ -3,8 +3,8 @@ import { Button } from '../components/ui/button';
import { Input } from '../components/ui/input';
import { Card, CardContent, CardHeader, CardTitle } from '../components/ui/card';
import { ArrowLeft, Eye, EyeOff, Mail, Lock, Building2 } from 'lucide-react';
const navigate = useNavigate();
import { useAuth } from '../components/AuthContext';
import { useNavigate } from 'react-router';
export function CorporateLogin() {
const [email, setEmail] = useState('');
@@ -12,11 +12,12 @@ export function CorporateLogin() {
const [showPassword, setShowPassword] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const { login } = useAuth();
const navigate = useNavigate();
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setIsLoading(true);
try {
// Simulate corporate login and go directly to corporate dashboard
await login(email || 'corporate@klc.edu', password || 'demo');
@@ -88,7 +89,7 @@ export function CorporateLogin() {
Sign in to your corporate learning account
</p>
</CardHeader>
<CardContent>
{/* Quick Access Button */}
<div className="mb-6">

View File

@@ -3,7 +3,7 @@ import { Button } from '../components/ui/button';
import { Input } from '../components/ui/input';
import { Card, CardContent, CardHeader, CardTitle } from '../components/ui/card';
import { ArrowLeft, Mail, User, Building2, Phone, Users } from 'lucide-react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function CorporateSignup() {
const [formData, setFormData] = useState({
@@ -17,11 +17,12 @@ export function CorporateSignup() {
message: ''
});
const [isLoading, setIsLoading] = useState(false);
const navigate = useNavigate();
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setIsLoading(true);
try {
// Simulate request submission
await new Promise(resolve => setTimeout(resolve, 1000));
@@ -79,7 +80,7 @@ export function CorporateSignup() {
Fill out this form and our enterprise team will contact you within 24 hours
</p>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className="space-y-6">
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">

View File

@@ -47,10 +47,8 @@ import {
MoreHorizontal,
Search
} from 'lucide-react';
// const navigate = useNavigate();
import { ImageWithFallback } from '../components/figma/ImageWithFallback';
import { useNavigate } from 'react-router-dom';
const navigate = useNavigate();
// Mock data for webinars
const mockWebinars = [
{
@@ -185,7 +183,7 @@ const mockWebinars = [
// Enhanced badge components with KLC brand colors
function RequiredBadge() {
return (
<Badge
<Badge
variant="outline"
className="text-sm font-medium px-3 py-1.5 h-auto flex items-center bg-destructive/5 text-destructive border-destructive/30 hover:bg-destructive/10 transition-colors"
>
@@ -197,7 +195,7 @@ function RequiredBadge() {
function CategoryBadge({ children }: { children: React.ReactNode }) {
return (
<Badge
<Badge
variant="outline"
className="text-sm font-medium px-2 py-1 bg-primary/5 text-primary border-primary/30"
>
@@ -209,7 +207,7 @@ function CategoryBadge({ children }: { children: React.ReactNode }) {
function TagBadge({ children }: { children: React.ReactNode }) {
return (
<Badge
<Badge
variant="outline"
className="text-sm px-2 py-1 bg-muted/50 text-muted-foreground border-border"
>
@@ -234,9 +232,8 @@ function LevelBadge({ level }: { level: string }) {
return 'bg-muted/50 text-muted-foreground border-border';
}
};
return (
<Badge
<Badge
variant="outline"
className={`text-sm font-medium px-2 py-1 ${getLevelStyle(level)}`}
>
@@ -250,21 +247,22 @@ function truncateText(text: string, maxLength: number): { truncated: string; nee
if (text.length <= maxLength) {
return { truncated: text, needsTruncation: false };
}
// Find the last space before maxLength to avoid cutting words
let truncatedText = text.substring(0, maxLength);
const lastSpaceIndex = truncatedText.lastIndexOf(' ');
if (lastSpaceIndex > maxLength * 0.8) { // Only use word boundary if it's not too far back
truncatedText = text.substring(0, lastSpaceIndex);
}
return { truncated: truncatedText, needsTruncation: true };
}
// Enhanced WebinarCard component with KLC branding and consistent design
function WebinarCard({ webinar }: { webinar: typeof mockWebinars[0] }) {
const [isDescriptionExpanded, setIsDescriptionExpanded] = useState(false);
const navigate = useNavigate();
const handleJoinWebinar = () => {
navigate(`/webinar-detail?id=${webinar.id}&view=corporate`);
@@ -289,10 +287,10 @@ function WebinarCard({ webinar }: { webinar: typeof mockWebinars[0] }) {
alt={webinar.title}
className="w-full h-full object-cover group-hover:scale-105 transition-transform duration-200"
/>
{/* Brand Gradient Overlay */}
<div className="absolute inset-0 bg-gradient-to-br from-[#04045B]/80 via-[#04045B]/60 to-transparent" />
{/* Geometric Brand Elements */}
<div className="absolute inset-0">
<div className="absolute top-0 right-0 w-24 h-24 bg-[#F8C301]/20 transform rotate-45 translate-x-8 -translate-y-8" />
@@ -301,7 +299,7 @@ function WebinarCard({ webinar }: { webinar: typeof mockWebinars[0] }) {
{/* Play Button with KLC Brand Colors */}
<div className="absolute inset-0 flex items-center justify-center">
<button
<button
onClick={handleJoinWebinar}
className="w-16 h-16 bg-white rounded-full flex items-center justify-center shadow-lg hover:scale-105 transition-transform duration-200 group border-2 border-primary/20"
aria-label="Watch webinar"
@@ -317,7 +315,7 @@ function WebinarCard({ webinar }: { webinar: typeof mockWebinars[0] }) {
{/* Category Badge */}
<div className="absolute top-3 right-3">
<Badge
<Badge
variant="outline"
className="bg-white/90 backdrop-blur-sm border-white/30 text-[#26231A] text-sm font-medium"
>
@@ -404,7 +402,7 @@ function WebinarCard({ webinar }: { webinar: typeof mockWebinars[0] }) {
<span>{webinar.duration}min</span>
</div>
</div>
<div className="flex items-center justify-between">
<div className="flex items-center gap-2 text-base text-muted-foreground">
<Users className="h-4 w-4" />
@@ -433,7 +431,7 @@ function WebinarCard({ webinar }: { webinar: typeof mockWebinars[0] }) {
{/* CTA Button - Auto-positioned at bottom */}
<div className="mt-auto">
<Button
<Button
onClick={handleJoinWebinar}
className="w-full text-base font-medium h-11 group"
>
@@ -447,6 +445,7 @@ function WebinarCard({ webinar }: { webinar: typeof mockWebinars[0] }) {
}
export function CorporateWebinars() {
const navigate = useNavigate();
const [searchQuery, setSearchQuery] = useState('');
const [selectedCategory, setSelectedCategory] = useState('all');
const [selectedStatus, setSelectedStatus] = useState('all');
@@ -465,12 +464,12 @@ export function CorporateWebinars() {
// Filter webinars based on search and filters
const filteredWebinars = mockWebinars.filter(webinar => {
const matchesSearch = webinar.title.toLowerCase().includes(searchQuery.toLowerCase()) ||
webinar.presenter.toLowerCase().includes(searchQuery.toLowerCase()) ||
webinar.description.toLowerCase().includes(searchQuery.toLowerCase());
webinar.presenter.toLowerCase().includes(searchQuery.toLowerCase()) ||
webinar.description.toLowerCase().includes(searchQuery.toLowerCase());
const matchesCategory = selectedCategory === 'all' || webinar.category === selectedCategory;
const matchesStatus = selectedStatus === 'all' || webinar.status === selectedStatus;
return matchesSearch && matchesCategory && matchesStatus;
});
@@ -539,8 +538,8 @@ export function CorporateWebinars() {
{/* Filters */}
<div className="grid grid-cols-1 md:grid-cols-3 gap-4">
<select
value={selectedCategory}
<select
value={selectedCategory}
onChange={(e) => setSelectedCategory(e.target.value)}
className="px-3 py-2 border border-border rounded-md text-base min-h-[44px] bg-background"
>
@@ -552,8 +551,8 @@ export function CorporateWebinars() {
<option value="Sustainability">Sustainability</option>
</select>
<select
value={selectedStatus}
<select
value={selectedStatus}
onChange={(e) => setSelectedStatus(e.target.value)}
className="px-3 py-2 border border-border rounded-md text-base min-h-[44px] bg-background"
>
@@ -563,8 +562,8 @@ export function CorporateWebinars() {
<option value="completed">Completed</option>
</select>
<Button
variant="outline"
<Button
variant="outline"
className="text-base min-h-[44px]"
onClick={() => {
setSearchQuery('');
@@ -587,7 +586,7 @@ export function CorporateWebinars() {
{filteredWebinars.length} {filteredWebinars.length === 1 ? 'webinar' : 'webinars'}
</Badge>
</div>
{filteredWebinars.length > 0 ? (
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
{filteredWebinars.map((webinar) => (
@@ -604,7 +603,7 @@ export function CorporateWebinars() {
<p className="text-base text-muted-foreground mb-6">
Try adjusting your search terms or filters to find webinars.
</p>
<Button
<Button
variant="outline"
onClick={() => {
setSearchQuery('');
@@ -631,12 +630,12 @@ export function CorporateWebinars() {
Quick overview of your upcoming webinar commitments
</p>
</CardHeader>
<CardContent className="flex-1">
<div className="space-y-4">
{mockWebinars.slice(0, 3).map((webinar) => (
<div
key={webinar.id}
<div
key={webinar.id}
className="group cursor-pointer p-4 rounded-lg border border-border hover:border-primary/30 hover:bg-muted/30 transition-all duration-200"
onClick={() => navigate(`/webinar-detail?id=${webinar.id}&view=corporate`)}
>
@@ -667,9 +666,9 @@ export function CorporateWebinars() {
</div>
))}
</div>
<div className="mt-6">
<Button
<Button
variant="outline"
onClick={() => navigate('/webinars?view=corporate')}
className="w-full text-base h-11"

View File

@@ -2,13 +2,14 @@ import React from 'react';
import { Button } from '../components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '../components/ui/card';
import { Mail, CheckCircle, RefreshCw } from 'lucide-react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function EmailVerification() {
const handleResendEmail = () => {
// Simulate resending verification email
console.log('Resending verification email...');
};
const navigate = useNavigate();
return (
<div className="min-h-screen bg-gradient-to-br from-gray-50 to-white flex items-center justify-center px-4">
@@ -24,7 +25,7 @@ export function EmailVerification() {
We've sent a verification link to your email address
</p>
</CardHeader>
<CardContent className="space-y-6">
<div className="bg-blue-50 rounded-lg p-4">
<div className="flex items-start gap-3">
@@ -44,7 +45,7 @@ export function EmailVerification() {
<p className="text-[16px] text-gray-600 text-center">
Don't see the email? Check your spam folder or request a new one.
</p>
<Button
onClick={handleResendEmail}
variant="outline"

View File

@@ -1,7 +1,9 @@
import React, { useEffect } from 'react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function ExecutiveLeadership() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -3,9 +3,11 @@ import { Button } from '../components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '../components/ui/card';
import { Collapsible, CollapsibleContent, CollapsibleTrigger } from '../components/ui/collapsible';
import { ArrowLeft, ChevronDown, HelpCircle, Mail, Phone } from 'lucide-react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function FAQ() {
const navigate = useNavigate();
const handleBackNavigation = () => {
navigate('/');
};
@@ -99,7 +101,7 @@ export function FAQ() {
</div>
</div>
</CardHeader>
<CardContent>
<div className="space-y-4">
{faqData.map((faq, index) => (

View File

@@ -1,7 +1,9 @@
import React, { useEffect } from 'react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function FacilityBooking() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -1,7 +1,9 @@
import React, { useEffect } from 'react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function FacilityDetail() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -1,7 +1,9 @@
import React, { useEffect } from 'react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function FacilityTour() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -3,17 +3,18 @@ import { Button } from '../components/ui/button';
import { Input } from '../components/ui/input';
import { Card, CardContent, CardHeader, CardTitle } from '../components/ui/card';
import { ArrowLeft, Mail, CheckCircle } from 'lucide-react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function ForgotPassword() {
const [email, setEmail] = useState('');
const [isSubmitted, setIsSubmitted] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const navigate = useNavigate();
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setIsLoading(true);
try {
// Simulate password reset request
await new Promise(resolve => setTimeout(resolve, 1000));
@@ -44,13 +45,13 @@ export function ForgotPassword() {
We've sent password reset instructions to {email}
</p>
</CardHeader>
<CardContent className="space-y-6">
<div className="text-center space-y-4">
<p className="text-[16px] text-gray-600">
Click the link in the email to reset your password. If you don't see it, check your spam folder.
</p>
<Button
onClick={() => navigate('/auth')}
className="w-full text-[16px] min-h-[48px] bg-primary hover:bg-primary/90"
@@ -103,7 +104,7 @@ export function ForgotPassword() {
We'll help you get back into your account
</p>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className="space-y-6">
<div>

View File

@@ -1,7 +1,9 @@
import React, { useEffect } from 'react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function InnovationLeadership() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -10,9 +10,9 @@ import { Skeleton } from '../components/ui/skeleton';
import { Tabs, TabsContent, TabsList, TabsTrigger } from '../components/ui/tabs';
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '../components/ui/select';
import { ImageWithFallback } from '../components/figma/ImageWithFallback';
import {
import {
ArrowLeft,
Trophy,
Trophy,
Crown,
Medal,
Star,
@@ -248,7 +248,7 @@ function AchievementBadge({ achievement, size = 'sm' }: { achievement: Achieveme
};
return (
<div
<div
className={`${sizeClasses[size]} ${rarityColors[achievement.rarity]} rounded-full border-2 flex items-center justify-center relative group cursor-pointer`}
title={`${achievement.name}: ${achievement.description}`}
>
@@ -270,9 +270,8 @@ function RankChangeIndicator({ currentRank, previousRank }: { currentRank: numbe
if (change === 0) return null;
return (
<div className={`flex items-center gap-1 text-sm font-medium ${
change > 0 ? 'text-success' : 'text-destructive'
}`}>
<div className={`flex items-center gap-1 text-sm font-medium ${change > 0 ? 'text-success' : 'text-destructive'
}`}>
{change > 0 ? (
<ChevronUp className="h-4 w-4" />
) : (
@@ -303,14 +302,14 @@ function PersonalStatsOverview({ stats, achievements }: { stats: LearningStats;
out of {stats.totalParticipants.toLocaleString()} learners
</div>
</div>
<div className="space-y-2">
<div className="flex justify-between text-base">
<span>Next milestone</span>
<span className="font-semibold">#{stats.nextMilestone.rank}</span>
</div>
<Progress
value={((stats.xpThisMonth / (stats.xpThisMonth + stats.nextMilestone.xpRequired)) * 100)}
<Progress
value={((stats.xpThisMonth / (stats.xpThisMonth + stats.nextMilestone.xpRequired)) * 100)}
className="h-3"
/>
<div className="text-sm text-muted-foreground">
@@ -338,14 +337,14 @@ function PersonalStatsOverview({ stats, achievements }: { stats: LearningStats;
</div>
<div className="text-sm text-muted-foreground">XP Earned</div>
</div>
<div className="space-y-2">
<div className="flex justify-between text-base">
<span className="text-muted-foreground">Target</span>
<span className="font-semibold">500 XP</span>
</div>
<Progress
value={(stats.xpThisWeek / 500) * 100}
<Progress
value={(stats.xpThisWeek / 500) * 100}
className="h-3"
/>
<div className="text-sm text-muted-foreground text-center">
@@ -370,12 +369,12 @@ function PersonalStatsOverview({ stats, achievements }: { stats: LearningStats;
<span className="text-base text-muted-foreground">XP Earned</span>
<span className="text-2xl font-bold text-primary">{stats.xpThisMonth}</span>
</div>
<div className="flex justify-between items-center">
<span className="text-base text-muted-foreground">Courses</span>
<span className="text-2xl font-bold text-success">{stats.coursesThisMonth}</span>
</div>
<div className="text-center">
<div className="text-sm text-muted-foreground">Monthly Goal</div>
<div className="text-lg font-semibold">5 Courses</div>
@@ -401,12 +400,12 @@ function PersonalStatsOverview({ stats, achievements }: { stats: LearningStats;
<span className="text-2xl font-bold text-orange-600">{stats.currentStreak}</span>
</div>
</div>
<div className="flex justify-between items-center">
<span className="text-base text-muted-foreground">Best Streak</span>
<span className="text-lg font-bold">{stats.longestStreak} days</span>
</div>
<div>
<div className="text-base text-muted-foreground mb-2">Achievements</div>
<div className="flex gap-2 flex-wrap justify-center">
@@ -423,11 +422,11 @@ function PersonalStatsOverview({ stats, achievements }: { stats: LearningStats;
}
// Main leaderboard table component
function LeaderboardTable({
data,
function LeaderboardTable({
data,
isLoading,
currentUserRank
}: {
currentUserRank
}: {
data: LeaderboardEntry[];
isLoading: boolean;
currentUserRank: number;
@@ -472,7 +471,7 @@ function LeaderboardTable({
const formatLastActive = (date: Date) => {
const now = new Date();
const diffInMinutes = Math.floor((now.getTime() - date.getTime()) / (1000 * 60));
if (diffInMinutes < 60) {
return `${diffInMinutes}m ago`;
} else if (diffInMinutes < 1440) {
@@ -513,13 +512,12 @@ function LeaderboardTable({
{topPerformers.map((entry, index) => (
<div
key={entry.id}
className={`flex items-center gap-4 p-4 rounded-xl border transition-all duration-200 hover:shadow-md ${
entry.rank <= 3
? 'bg-gradient-to-r from-yellow-50 to-orange-50 border-yellow-200'
className={`flex items-center gap-4 p-4 rounded-xl border transition-all duration-200 hover:shadow-md ${entry.rank <= 3
? 'bg-gradient-to-r from-yellow-50 to-orange-50 border-yellow-200'
: entry.isCurrentUser
? 'bg-gradient-to-r from-primary/5 to-primary/10 border-primary/20 ring-2 ring-primary/20'
: 'bg-muted/30 border-border hover:bg-muted/50'
}`}
? 'bg-gradient-to-r from-primary/5 to-primary/10 border-primary/20 ring-2 ring-primary/20'
: 'bg-muted/30 border-border hover:bg-muted/50'
}`}
>
{/* Rank */}
<div className="flex items-center gap-2">
@@ -535,7 +533,7 @@ function LeaderboardTable({
{entry.name.split(' ').map(n => n[0]).join('')}
</AvatarFallback>
</Avatar>
<div className="flex-1">
<div className="flex items-center gap-2">
<h3 className="text-lg font-semibold">{entry.name}</h3>
@@ -544,7 +542,7 @@ function LeaderboardTable({
)}
<div className="text-sm text-muted-foreground">Level {entry.level}</div>
</div>
<div className="flex items-center gap-4 text-sm text-muted-foreground">
<span className="flex items-center gap-1">
<BookOpen className="h-3 w-3" />
@@ -590,7 +588,7 @@ function LeaderboardTable({
<span className="px-4 text-sm text-muted-foreground">Your Position</span>
<Separator className="flex-1" />
</div>
<div className="flex items-center gap-4 p-4 rounded-xl border bg-gradient-to-r from-primary/5 to-primary/10 border-primary/20 ring-2 ring-primary/20">
<div className="flex items-center gap-2">
<span className="text-lg font-bold text-muted-foreground">#{currentUser!.rank}</span>
@@ -602,14 +600,14 @@ function LeaderboardTable({
<AvatarImage src={currentUser!.avatar} />
<AvatarFallback className="text-base">You</AvatarFallback>
</Avatar>
<div className="flex-1">
<div className="flex items-center gap-2">
<h3 className="text-lg font-semibold">{currentUser!.name}</h3>
<Badge className="bg-primary text-primary-foreground text-sm">You</Badge>
<div className="text-sm text-muted-foreground">Level {currentUser!.level}</div>
</div>
<div className="flex items-center gap-4 text-sm text-muted-foreground">
<span className="flex items-center gap-1">
<BookOpen className="h-3 w-3" />
@@ -652,7 +650,7 @@ export function Leaderboard() {
const [activeTab, setActiveTab] = useState('global');
const [filterPeriod, setFilterPeriod] = useState('all-time');
const [filterCategory, setFilterCategory] = useState('all');
const navigate = useNavigate();
const navigate = useNavigate();
// Mock user data for LearnerLayout - matching Library page pattern
@@ -686,101 +684,100 @@ export function Leaderboard() {
<div className="w-full max-w-none px-2 sm:px-4 lg:px-6 pb-8">
<div className="space-y-8">
{/* Personal Stats Overview - Updated to 4 columns */}
<PersonalStatsOverview
stats={mockCurrentUserStats}
achievements={mockAchievements}
/>
{/* Personal Stats Overview - Updated to 4 columns */}
<PersonalStatsOverview
stats={mockCurrentUserStats}
achievements={mockAchievements}
/>
{/* Filters and Tabs */}
<Card>
<CardContent className="p-6">
<div className="flex flex-col lg:flex-row gap-4 items-start lg:items-center justify-between">
{/* Custom Segmented Control */}
<div className="w-full lg:w-auto bg-yellow-50/80 rounded-full p-1.5">
<div className="flex items-center space-x-1">
{[
{ value: 'global', label: 'Global' },
{ value: 'regional', label: 'Regional' },
{ value: 'friends', label: 'Friends' }
].map((tab) => (
<button
key={tab.value}
onClick={() => setActiveTab(tab.value)}
className={`flex-1 px-4 py-2.5 text-base font-medium rounded-full transition-all duration-300 ease-in-out focus:outline-none focus:ring-0 active:outline-none ${
activeTab === tab.value
? 'bg-white text-gray-900 shadow-sm'
: 'text-gray-700 hover:text-gray-900 hover:bg-white/60'
}`}
>
{tab.label}
</button>
))}
{/* Filters and Tabs */}
<Card>
<CardContent className="p-6">
<div className="flex flex-col lg:flex-row gap-4 items-start lg:items-center justify-between">
{/* Custom Segmented Control */}
<div className="w-full lg:w-auto bg-yellow-50/80 rounded-full p-1.5">
<div className="flex items-center space-x-1">
{[
{ value: 'global', label: 'Global' },
{ value: 'regional', label: 'Regional' },
{ value: 'friends', label: 'Friends' }
].map((tab) => (
<button
key={tab.value}
onClick={() => setActiveTab(tab.value)}
className={`flex-1 px-4 py-2.5 text-base font-medium rounded-full transition-all duration-300 ease-in-out focus:outline-none focus:ring-0 active:outline-none ${activeTab === tab.value
? 'bg-white text-gray-900 shadow-sm'
: 'text-gray-700 hover:text-gray-900 hover:bg-white/60'
}`}
>
{tab.label}
</button>
))}
</div>
</div>
<div className="flex flex-col sm:flex-row gap-3 w-full lg:w-auto">
<Select value={filterPeriod} onValueChange={setFilterPeriod}>
<SelectTrigger className="w-full sm:w-40 text-base min-h-[44px]">
<SelectValue placeholder="Time Period" />
</SelectTrigger>
<SelectContent>
<SelectItem value="all-time" className="text-base">All Time</SelectItem>
<SelectItem value="this-month" className="text-base">This Month</SelectItem>
<SelectItem value="this-week" className="text-base">This Week</SelectItem>
</SelectContent>
</Select>
<Select value={filterCategory} onValueChange={setFilterCategory}>
<SelectTrigger className="w-full sm:w-40 text-base min-h-[44px]">
<SelectValue placeholder="Category" />
</SelectTrigger>
<SelectContent>
<SelectItem value="all" className="text-base">All Categories</SelectItem>
<SelectItem value="leadership" className="text-base">Leadership</SelectItem>
<SelectItem value="management" className="text-base">Management</SelectItem>
<SelectItem value="innovation" className="text-base">Innovation</SelectItem>
</SelectContent>
</Select>
</div>
</div>
</CardContent>
</Card>
<div className="flex flex-col sm:flex-row gap-3 w-full lg:w-auto">
<Select value={filterPeriod} onValueChange={setFilterPeriod}>
<SelectTrigger className="w-full sm:w-40 text-base min-h-[44px]">
<SelectValue placeholder="Time Period" />
</SelectTrigger>
<SelectContent>
<SelectItem value="all-time" className="text-base">All Time</SelectItem>
<SelectItem value="this-month" className="text-base">This Month</SelectItem>
<SelectItem value="this-week" className="text-base">This Week</SelectItem>
</SelectContent>
</Select>
{/* Tab Content */}
<Tabs value={activeTab} className="space-y-6">
<TabsContent value="global" className="space-y-6">
<LeaderboardTable
data={mockLeaderboardData}
isLoading={isLoading}
currentUserRank={mockCurrentUserStats.currentRank}
/>
</TabsContent>
<Select value={filterCategory} onValueChange={setFilterCategory}>
<SelectTrigger className="w-full sm:w-40 text-base min-h-[44px]">
<SelectValue placeholder="Category" />
</SelectTrigger>
<SelectContent>
<SelectItem value="all" className="text-base">All Categories</SelectItem>
<SelectItem value="leadership" className="text-base">Leadership</SelectItem>
<SelectItem value="management" className="text-base">Management</SelectItem>
<SelectItem value="innovation" className="text-base">Innovation</SelectItem>
</SelectContent>
</Select>
</div>
</div>
</CardContent>
</Card>
<TabsContent value="regional" className="space-y-6">
<LeaderboardTable
data={mockLeaderboardData.filter(entry => entry.region === 'North America')}
isLoading={isLoading}
currentUserRank={mockCurrentUserStats.currentRank}
/>
</TabsContent>
{/* Tab Content */}
<Tabs value={activeTab} className="space-y-6">
<TabsContent value="global" className="space-y-6">
<LeaderboardTable
data={mockLeaderboardData}
isLoading={isLoading}
currentUserRank={mockCurrentUserStats.currentRank}
/>
</TabsContent>
<TabsContent value="regional" className="space-y-6">
<LeaderboardTable
data={mockLeaderboardData.filter(entry => entry.region === 'North America')}
isLoading={isLoading}
currentUserRank={mockCurrentUserStats.currentRank}
/>
</TabsContent>
<TabsContent value="friends" className="space-y-6">
<Card>
<CardContent className="p-8 text-center">
<Users className="h-16 w-16 text-muted-foreground mx-auto mb-4" />
<h3 className="text-xl font-semibold mb-2">Connect with Friends</h3>
<p className="text-base text-muted-foreground mb-6">
Add friends to see how you compare with your learning buddies
</p>
<Button className="text-base min-h-[44px]">
<Users className="h-4 w-4 mr-2" />
Find Friends
</Button>
</CardContent>
</Card>
</TabsContent>
</Tabs>
<TabsContent value="friends" className="space-y-6">
<Card>
<CardContent className="p-8 text-center">
<Users className="h-16 w-16 text-muted-foreground mx-auto mb-4" />
<h3 className="text-xl font-semibold mb-2">Connect with Friends</h3>
<p className="text-base text-muted-foreground mb-6">
Add friends to see how you compare with your learning buddies
</p>
<Button className="text-base min-h-[44px]">
<Users className="h-4 w-4 mr-2" />
Find Friends
</Button>
</CardContent>
</Card>
</TabsContent>
</Tabs>
</div>
</div>
</LearnerLayout>

View File

@@ -1,7 +1,9 @@
import React, { useEffect } from 'react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function LeadershipOnline() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -3,7 +3,6 @@ import { Button } from '../components/ui/button';
import { Input } from '../components/ui/input';
import { Card, CardContent, CardHeader, CardTitle } from '../components/ui/card';
import { ArrowLeft, Eye, EyeOff, Mail, Lock } from 'lucide-react';
const navigate = useNavigate();
import { useAuth } from '../components/AuthContext';
import { useNavigate } from 'react-router-dom';
@@ -13,11 +12,12 @@ export function Login() {
const [showPassword, setShowPassword] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const { login } = useAuth();
const navigate = useNavigate();
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setIsLoading(true);
try {
// Simulate login and go directly to individual dashboard
await login(email || 'demo@klc.edu', password || 'demo');
@@ -86,7 +86,7 @@ export function Login() {
Sign in to your individual learning account
</p>
</CardHeader>
<CardContent>
{/* Quick Access Button */}
<div className="mb-6">

View File

@@ -6,9 +6,9 @@ import { ArrowLeft, Building2, User, ArrowRight, CheckCircle, Users, Target, Boo
// const navigate = useNavigate();
import { useAuth } from '../components/AuthContext';
import { useNavigate } from 'react-router-dom';
const navigate = useNavigate();
export function LoginSelection() {
const { login } = useAuth();
const navigate = useNavigate();
const handleBackNavigation = () => {
navigate('/');
@@ -63,7 +63,7 @@ export function LoginSelection() {
<div className="container mx-auto px-4 lg:px-8 -mt-8">
<div className="max-w-6xl mx-auto">
<div className="grid grid-cols-1 lg:grid-cols-2 gap-8">
{/* Individual Learner Card */}
<Card className="relative overflow-hidden hover:shadow-xl transition-all duration-300 border-2 hover:border-blue-200 bg-white">
<div className="absolute top-0 right-0 w-32 h-32 bg-gradient-to-br from-blue-500/10 to-transparent rounded-bl-full"></div>
@@ -83,7 +83,7 @@ export function LoginSelection() {
Access your personalized learning journey with expert-led courses, assessments, and progress tracking tailored to your professional goals.
</p>
</CardHeader>
<CardContent className="space-y-6">
{/* Features List */}
<div className="space-y-4">
@@ -134,7 +134,7 @@ export function LoginSelection() {
</div>
</div>
<Button
<Button
onClick={handleIndividualLogin}
className="w-full text-[16px] min-h-[48px] bg-blue-600 hover:bg-blue-700 text-white group"
>
@@ -145,7 +145,7 @@ export function LoginSelection() {
<div className="text-center">
<p className="text-[14px] text-gray-500">
Want to explore first?{' '}
<button
<button
onClick={() => navigate('/login')}
className="text-blue-600 hover:text-blue-700 font-medium hover:underline"
>
@@ -175,7 +175,7 @@ export function LoginSelection() {
Access your organization's learning programs with team collaboration, assigned courses, and comprehensive progress tracking for enterprise development.
</p>
</CardHeader>
<CardContent className="space-y-6">
{/* Features List */}
<div className="space-y-4">
@@ -226,7 +226,7 @@ export function LoginSelection() {
</div>
</div>
<Button
<Button
onClick={handleCorporateLogin}
className="w-full text-[16px] min-h-[48px] bg-purple-600 hover:bg-purple-700 text-white group"
>
@@ -237,7 +237,7 @@ export function LoginSelection() {
<div className="text-center">
<p className="text-[14px] text-gray-500">
Want to explore first?{' '}
<button
<button
onClick={() => navigate('/corporate/login')}
className="text-purple-600 hover:text-purple-700 font-medium hover:underline"
>
@@ -258,7 +258,7 @@ export function LoginSelection() {
<p className="text-[16px] text-gray-600 leading-relaxed mb-6 max-w-2xl mx-auto">
Click the buttons above to instantly access either dashboard. No credentials required - designed for easy testing and exploration of the KLC learning platform.
</p>
<div className="grid grid-cols-1 md:grid-cols-3 gap-6 mb-8">
<div className="text-center">
<div className="w-12 h-12 bg-[#F8C301] rounded-full flex items-center justify-center mx-auto mb-3">
@@ -284,15 +284,15 @@ export function LoginSelection() {
</div>
<div className="flex flex-col sm:flex-row gap-4 justify-center">
<Button
variant="outline"
<Button
variant="outline"
onClick={() => navigate('/contact')}
className="text-[16px] min-h-[44px] border-[#04045B] text-[#04045B] hover:bg-[#04045B]/10"
>
Contact Support
</Button>
<Button
variant="outline"
<Button
variant="outline"
onClick={() => navigate('/individual-webinars')}
className="text-[16px] min-h-[44px] border-[#04045B] text-[#04045B] hover:bg-[#04045B]/10"
>
@@ -313,7 +313,7 @@ export function LoginSelection() {
Experience world-class leadership development with proven results
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-4 gap-8">
<div className="text-center">
<p className="text-[32px] font-bold text-[#F8C301] mb-2">27,000+</p>

View File

@@ -1,7 +1,10 @@
import React, { useEffect } from 'react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function MyCohort() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -2,9 +2,11 @@ import React from 'react';
import { Button } from '../components/ui/button';
import { Card, CardContent } from '../components/ui/card';
import { ArrowLeft, Home, Search, HelpCircle } from 'lucide-react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function NotFound() {
const navigate = useNavigate();
const handleGoHome = () => {
navigate('/');
};
@@ -20,11 +22,11 @@ export function NotFound() {
<div className="w-32 h-32 bg-gradient-to-br from-[#04045B]/10 to-[#F8C301]/20 rounded-full flex items-center justify-center mx-auto mb-8 border-2 border-[#04045B]/20">
<span className="text-[48px] font-bold text-[#04045B]">404</span>
</div>
<h1 className="text-[36px] font-bold text-[#04045B] mb-4">
Page Not Found
</h1>
<p className="text-[16px] text-gray-600 mb-8 leading-relaxed">
Sorry, we couldn't find the page you're looking for. The page may have been moved, deleted, or you may have entered an incorrect URL.
</p>
@@ -37,7 +39,7 @@ export function NotFound() {
<Home className="w-4 w-4 mr-2" />
Return to Home
</Button>
<Button
variant="outline"
onClick={handleGoBack}
@@ -62,7 +64,7 @@ export function NotFound() {
<Search className="h-4 w-4 text-gray-500 flex-shrink-0" />
<span className="text-[16px] text-gray-700">Professional Webinars</span>
</button>
<button
onClick={() => navigate('/contact')}
className="flex items-center gap-3 p-3 text-left rounded-lg hover:bg-gray-50 transition-colors"
@@ -70,7 +72,7 @@ export function NotFound() {
<HelpCircle className="h-4 w-4 text-gray-500 flex-shrink-0" />
<span className="text-[16px] text-gray-700">Contact Support</span>
</button>
<button
onClick={() => navigate('/auth')}
className="flex items-center gap-3 p-3 text-left rounded-lg hover:bg-gray-50 transition-colors"

View File

@@ -1,7 +1,9 @@
import React, { useEffect } from 'react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function OrderConfirmation() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -1,7 +1,9 @@
import React, { useEffect } from 'react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function OrderFailed() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -1,7 +1,9 @@
import React, { useEffect } from 'react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function OurExpertise() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -1,7 +1,9 @@
import React, { useEffect } from 'react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function OurImpact() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -1,7 +1,9 @@
import React, { useEffect } from 'react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function OurTeam() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -1,7 +1,9 @@
import React, { useEffect } from 'react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function OurVision() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -2,9 +2,11 @@ import React from 'react';
import { Button } from '../components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '../components/ui/card';
import { ArrowLeft, Shield, Eye, Lock, FileText } from 'lucide-react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function Privacy() {
const navigate = useNavigate();
const handleBackNavigation = () => {
navigate('/');
};
@@ -55,15 +57,15 @@ export function Privacy() {
</div>
</div>
</CardHeader>
<CardContent className="prose prose-gray max-w-none">
<div className="space-y-8">
{/* Introduction */}
<section>
<h2 className="text-[24px] font-semibold text-gray-900 mb-4">Introduction</h2>
<p className="text-[16px] text-gray-600 leading-relaxed mb-4">
At Kautilya Leadership Centre (KLC), we are committed to protecting your privacy and personal information.
This Privacy Policy explains how we collect, use, disclose, and safeguard your information when you use our
At Kautilya Leadership Centre (KLC), we are committed to protecting your privacy and personal information.
This Privacy Policy explains how we collect, use, disclose, and safeguard your information when you use our
learning platform and services.
</p>
</section>
@@ -74,7 +76,7 @@ export function Privacy() {
<Eye className="h-5 w-5 text-primary" />
<h2 className="text-[24px] font-semibold text-gray-900">Information We Collect</h2>
</div>
<div className="space-y-4">
<div>
<h3 className="text-[18px] font-semibold text-gray-900 mb-2">Personal Information</h3>
@@ -110,7 +112,7 @@ export function Privacy() {
<FileText className="h-5 w-5 text-primary" />
<h2 className="text-[24px] font-semibold text-gray-900">How We Use Your Information</h2>
</div>
<ul className="list-disc pl-6 space-y-2 text-[16px] text-gray-600">
<li>Provide and improve our learning services</li>
<li>Personalize your learning experience</li>
@@ -141,9 +143,9 @@ export function Privacy() {
<Lock className="h-5 w-5 text-primary" />
<h2 className="text-[24px] font-semibold text-gray-900">Data Security</h2>
</div>
<p className="text-[16px] text-gray-600 leading-relaxed mb-4">
We implement appropriate technical and organizational security measures to protect your personal information
We implement appropriate technical and organizational security measures to protect your personal information
against unauthorized access, alteration, disclosure, or destruction. These measures include:
</p>
<ul className="list-disc pl-6 space-y-2 text-[16px] text-gray-600">
@@ -186,8 +188,8 @@ export function Privacy() {
<section>
<h2 className="text-[24px] font-semibold text-gray-900 mb-4">Policy Updates</h2>
<p className="text-[16px] text-gray-600 leading-relaxed">
We may update this Privacy Policy from time to time. We will notify you of any changes by posting the new
Privacy Policy on this page and updating the "Last updated" date. We encourage you to review this Privacy
We may update this Privacy Policy from time to time. We will notify you of any changes by posting the new
Privacy Policy on this page and updating the "Last updated" date. We encourage you to review this Privacy
Policy periodically for any changes.
</p>
</section>

View File

@@ -1,7 +1,9 @@
import React, { useEffect } from 'react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function ProgrammeCatalogue() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -1,7 +1,9 @@
import React, { useEffect } from 'react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function ProgrammeDetail() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -1,7 +1,9 @@
import React, { useEffect } from 'react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function Resources() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -3,7 +3,7 @@ import { Button } from '../components/ui/button';
import { Input } from '../components/ui/input';
import { Card, CardContent, CardHeader, CardTitle } from '../components/ui/card';
import { ArrowLeft, Eye, EyeOff, Mail, Lock, User } from 'lucide-react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function Signup() {
const [formData, setFormData] = useState({
@@ -13,14 +13,16 @@ export function Signup() {
password: '',
confirmPassword: ''
});
const [showPassword, setShowPassword] = useState(false);
const [showConfirmPassword, setShowConfirmPassword] = useState(false);
const [isLoading, setIsLoading] = useState(false);
const navigate = useNavigate();
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setIsLoading(true);
try {
// Simulate signup
await new Promise(resolve => setTimeout(resolve, 1000));
@@ -75,7 +77,7 @@ export function Signup() {
Create your individual learning account
</p>
</CardHeader>
<CardContent>
<form onSubmit={handleSubmit} className="space-y-6">
<div className="space-y-4">

View File

@@ -1,7 +1,9 @@
import React, { useEffect } from 'react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function TeamLeadership() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -2,9 +2,11 @@ import React from 'react';
import { Button } from '../components/ui/button';
import { Card, CardContent, CardHeader, CardTitle } from '../components/ui/card';
import { ArrowLeft, FileText, Scale, AlertCircle } from 'lucide-react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function Terms() {
const navigate = useNavigate();
const handleBackNavigation = () => {
navigate('/');
};
@@ -55,15 +57,15 @@ export function Terms() {
</div>
</div>
</CardHeader>
<CardContent className="prose prose-gray max-w-none">
<div className="space-y-8">
{/* Introduction */}
<section>
<h2 className="text-[24px] font-semibold text-gray-900 mb-4">Agreement to Terms</h2>
<p className="text-[16px] text-gray-600 leading-relaxed mb-4">
By accessing and using the Kautilya Leadership Centre (KLC) learning platform, you agree to be bound by these
Terms of Service and all applicable laws and regulations. If you do not agree with any of these terms, you are
By accessing and using the Kautilya Leadership Centre (KLC) learning platform, you agree to be bound by these
Terms of Service and all applicable laws and regulations. If you do not agree with any of these terms, you are
prohibited from using or accessing this site.
</p>
</section>
@@ -74,9 +76,9 @@ export function Terms() {
<FileText className="h-5 w-5 text-primary" />
<h2 className="text-[24px] font-semibold text-gray-900">Use License</h2>
</div>
<p className="text-[16px] text-gray-600 leading-relaxed mb-4">
Permission is granted to temporarily access the materials on KLC's learning platform for personal,
Permission is granted to temporarily access the materials on KLC's learning platform for personal,
non-commercial transitory viewing only. This is the grant of a license, not a transfer of title, and under this license you may not:
</p>
<ul className="list-disc pl-6 space-y-2 text-[16px] text-gray-600 mb-4">
@@ -123,7 +125,7 @@ export function Terms() {
<section>
<h2 className="text-[24px] font-semibold text-gray-900 mb-4">Course Content and Certificates</h2>
<p className="text-[16px] text-gray-600 leading-relaxed mb-4">
Our courses and learning materials are for educational purposes. Course completion certificates are issued
Our courses and learning materials are for educational purposes. Course completion certificates are issued
upon successful completion of requirements. These certificates:
</p>
<ul className="list-disc pl-6 space-y-2 text-[16px] text-gray-600">
@@ -152,8 +154,8 @@ export function Terms() {
<section>
<h2 className="text-[24px] font-semibold text-gray-900 mb-4">Intellectual Property</h2>
<p className="text-[16px] text-gray-600 leading-relaxed">
All content, materials, and intellectual property on the KLC platform remain the exclusive property of
Kautilya Leadership Centre or its licensors. You may not reproduce, distribute, or create derivative works
All content, materials, and intellectual property on the KLC platform remain the exclusive property of
Kautilya Leadership Centre or its licensors. You may not reproduce, distribute, or create derivative works
without written permission.
</p>
</section>
@@ -164,10 +166,10 @@ export function Terms() {
<AlertCircle className="h-5 w-5 text-amber-500 flex-shrink-0 mt-1" />
<h2 className="text-[24px] font-semibold text-gray-900">Disclaimer</h2>
</div>
<p className="text-[16px] text-gray-600 leading-relaxed">
The materials on KLC's platform are provided on an 'as is' basis. KLC makes no warranties, expressed or implied,
and hereby disclaims all other warranties including, without limitation, implied warranties or conditions of
The materials on KLC's platform are provided on an 'as is' basis. KLC makes no warranties, expressed or implied,
and hereby disclaims all other warranties including, without limitation, implied warranties or conditions of
merchantability, fitness for a particular purpose, or non-infringement of intellectual property.
</p>
</section>
@@ -176,8 +178,8 @@ export function Terms() {
<section>
<h2 className="text-[24px] font-semibold text-gray-900 mb-4">Limitation of Liability</h2>
<p className="text-[16px] text-gray-600 leading-relaxed">
In no event shall KLC or its suppliers be liable for any damages (including, without limitation, damages for
loss of data or profit, or due to business interruption) arising out of the use or inability to use the materials
In no event shall KLC or its suppliers be liable for any damages (including, without limitation, damages for
loss of data or profit, or due to business interruption) arising out of the use or inability to use the materials
on KLC's platform, even if KLC or an authorized representative has been notified of the possibility of such damage.
</p>
</section>

View File

@@ -1,7 +1,9 @@
import React, { useEffect } from 'react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function WebinarDetail() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -1,7 +1,9 @@
import React, { useEffect } from 'react';
const navigate = useNavigate();
import { useNavigate } from 'react-router';
export function WebinarListing() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -9,10 +9,10 @@ import { Separator } from '../../components/ui/separator';
import { Skeleton } from '../../components/ui/skeleton';
import { Alert, AlertDescription } from '../../components/ui/alert';
import { PieChart, Pie, Cell, ResponsiveContainer, Legend, Tooltip } from 'recharts';
import {
BookOpen,
Clock,
Trophy,
import {
BookOpen,
Clock,
Trophy,
Calendar,
TrendingUp,
Play,
@@ -47,10 +47,10 @@ import {
MapPin
} from 'lucide-react';
import { ImageWithFallback } from '../../components/figma/ImageWithFallback';
import globalMapImage from 'figma:asset/1b56e6afe31d5744d2e7a38d3e2f8c3ce78a90af.png';
// import globalMapImage from 'figma:asset/1b56e6afe31d5744d2e7a38d3e2f8c3ce78a90af.png';
import { useNavigate } from 'react-router-dom';
const navigate = useNavigate();
// Loading skeleton component for corporate dashboard
const globalMapImage = 'https://images.unsplash.com/photo-1526778548025-fa2f459cd5c1?w=1600&auto=format&fit=crop&q=60'
function CorporateDashboardSkeleton() {
return (
<div className="space-y-8">
@@ -148,7 +148,7 @@ function ConnectionStatus() {
<WifiOff className="h-5 w-5 text-destructive" />
<AlertDescription className="flex items-center justify-between text-base">
<span>You're currently offline. Some features may not be available.</span>
<Button
<Button
onClick={handleRetry}
disabled={isLoading}
size="sm"
@@ -170,36 +170,36 @@ function ConnectionStatus() {
// Corporate KPI Cards component
function CorporateKPICards() {
const kpiData = [
{
id: 'team-members',
value: 24,
label: "Team Members",
change: "+3 this quarter",
icon: Users,
{
id: 'team-members',
value: 24,
label: "Team Members",
change: "+3 this quarter",
icon: Users,
bgGradient: "bg-gradient-to-br from-brand-navy/70 to-brand-navy/80"
},
{
id: 'completion-rate',
value: 87,
label: "Completion Rate",
change: "+12% this month",
icon: CheckCircle,
{
id: 'completion-rate',
value: 87,
label: "Completion Rate",
change: "+12% this month",
icon: CheckCircle,
bgGradient: "bg-gradient-to-br from-success to-emerald-500"
},
{
id: 'team-ranking',
value: 3,
label: "Division Ranking",
change: "↑2 positions",
icon: Trophy,
{
id: 'team-ranking',
value: 3,
label: "Division Ranking",
change: "↑2 positions",
icon: Trophy,
bgGradient: "bg-gradient-to-br from-brand-gold to-amber-500"
},
{
id: 'upcoming-deadlines',
value: 8,
label: "Upcoming Deadlines",
change: "Next: Today",
icon: Calendar,
{
id: 'upcoming-deadlines',
value: 8,
label: "Upcoming Deadlines",
change: "Next: Today",
icon: Calendar,
bgGradient: "bg-gradient-to-br from-brand-charcoal to-gray-800"
}
];
@@ -240,65 +240,65 @@ function CorporateKPICards() {
// Team Performance Overview component
function TeamPerformanceOverview() {
const teamGoals = [
{
id: '1',
title: 'Q4 Leadership Development',
description: 'Complete advanced leadership track',
progress: 18,
total: 24,
icon: Crown,
{
id: '1',
title: 'Q4 Leadership Development',
description: 'Complete advanced leadership track',
progress: 18,
total: 24,
icon: Crown,
bgGradient: 'bg-gradient-to-br from-brand-gold to-amber-500'
},
{
id: '2',
title: 'Strategic Planning Mastery',
description: 'Team strategic thinking certification',
progress: 15,
total: 20,
icon: Brain,
{
id: '2',
title: 'Strategic Planning Mastery',
description: 'Team strategic thinking certification',
progress: 15,
total: 20,
icon: Brain,
bgGradient: 'bg-gradient-to-br from-brand-charcoal to-gray-800'
},
{
id: '3',
title: 'Innovation Workshop Series',
description: 'Complete innovation methodology training',
progress: 12,
total: 12,
icon: Lightbulb,
{
id: '3',
title: 'Innovation Workshop Series',
description: 'Complete innovation methodology training',
progress: 12,
total: 12,
icon: Lightbulb,
bgGradient: 'bg-gradient-to-br from-success to-emerald-500'
},
{
id: '4',
title: 'Cross-Department Collaboration',
description: 'Inter-team project completion',
progress: 8,
total: 16,
icon: Network,
{
id: '4',
title: 'Cross-Department Collaboration',
description: 'Inter-team project completion',
progress: 8,
total: 16,
icon: Network,
bgGradient: 'bg-gradient-to-br from-brand-navy/70 to-brand-navy/80'
},
{
id: '5',
title: 'Digital Transformation Skills',
description: 'Master digital leadership competencies',
progress: 6,
total: 18,
icon: Zap,
{
id: '5',
title: 'Digital Transformation Skills',
description: 'Master digital leadership competencies',
progress: 6,
total: 18,
icon: Zap,
bgGradient: 'bg-gradient-to-br from-purple-500 to-indigo-600'
},
{
id: '6',
title: 'Performance Management Excellence',
description: 'Advanced coaching and feedback techniques',
progress: 14,
total: 22,
icon: Star,
{
id: '6',
title: 'Performance Management Excellence',
description: 'Advanced coaching and feedback techniques',
progress: 14,
total: 22,
icon: Star,
bgGradient: 'bg-gradient-to-br from-orange-400 to-pink-500'
}
];
const overallProgress = Math.round(
(teamGoals.reduce((acc, goal) => acc + goal.progress, 0) /
teamGoals.reduce((acc, goal) => acc + goal.total, 0)) * 100
(teamGoals.reduce((acc, goal) => acc + goal.progress, 0) /
teamGoals.reduce((acc, goal) => acc + goal.total, 0)) * 100
);
return (
@@ -316,7 +316,7 @@ function TeamPerformanceOverview() {
</Badge>
</CardTitle>
</CardHeader>
<CardContent className="flex-1 flex flex-col">
{/* Overall Progress */}
<div className="space-y-2 mb-6">
@@ -334,13 +334,12 @@ function TeamPerformanceOverview() {
const Icon = goal.icon;
const progressPercentage = Math.round((goal.progress / goal.total) * 100);
const isCompleted = goal.progress >= goal.total;
return (
<div
<div
key={goal.id}
className={`p-3 rounded-lg border transition-all duration-200 flex flex-col ${
isCompleted ? 'bg-success/5 border-success/20' : 'bg-muted/30 hover:bg-muted/50'
}`}
className={`p-3 rounded-lg border transition-all duration-200 flex flex-col ${isCompleted ? 'bg-success/5 border-success/20' : 'bg-muted/30 hover:bg-muted/50'
}`}
>
<div className="flex items-start gap-3 flex-1">
<div className={`w-10 h-10 rounded-full flex-shrink-0 flex items-center justify-center shadow-md border border-white/20 ${isCompleted ? 'bg-gradient-to-br from-success to-emerald-500' : goal.bgGradient}`}>
@@ -381,6 +380,7 @@ function TeamPerformanceOverview() {
// Corporate Analytics component
function CorporateAnalytics() {
const navigate = useNavigate();
const analyticsData = [
{ name: 'Completed', value: 68, color: '#21A36A' },
{ name: 'In Progress', value: 25, color: '#F8C301' },
@@ -419,8 +419,8 @@ function CorporateAnalytics() {
</div>
Team Analytics
</div>
<Button
variant="ghost"
<Button
variant="ghost"
size="sm"
onClick={() => navigate('/library?view=corporate')}
className="text-base h-auto p-0 text-primary hover:text-primary/80"
@@ -429,7 +429,7 @@ function CorporateAnalytics() {
</Button>
</CardTitle>
</CardHeader>
<CardContent className="flex-1 flex flex-col">
{/* Top Statistics - 2x2 Grid */}
<div className="grid grid-cols-2 gap-4 text-center mb-6">
@@ -489,7 +489,7 @@ function CorporateAnalytics() {
<Tooltip content={<CustomTooltip />} />
</PieChart>
</ResponsiveContainer>
{/* Center Text */}
<div className="absolute inset-0 flex flex-col items-center justify-center">
<div className="text-4xl font-bold text-primary">
@@ -504,7 +504,7 @@ function CorporateAnalytics() {
{/* Bottom Button */}
<div className="mt-6">
<Button
<Button
variant="outline"
onClick={() => navigate('/library?view=corporate')}
className="w-full text-base h-11"
@@ -520,6 +520,7 @@ function CorporateAnalytics() {
// Corporate Assigned Training component
function AssignedTraining() {
const navigate = useNavigate();
const assignments = [
{
id: '1',
@@ -619,8 +620,8 @@ function AssignedTraining() {
</div>
Assigned Training
</div>
<Button
variant="ghost"
<Button
variant="ghost"
size="sm"
onClick={() => navigate('/library?view=corporate')}
className="text-base h-10"
@@ -629,16 +630,15 @@ function AssignedTraining() {
</Button>
</CardTitle>
</CardHeader>
<CardContent className="flex-1">
{/* Assignments Grid */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-4 h-full">
{assignments.map((assignment) => (
<div
key={assignment.id}
className={`group cursor-pointer bg-white rounded-lg border transition-all duration-200 flex flex-col h-full overflow-hidden ${
assignment.status === 'urgent' ? 'border-destructive/30 bg-destructive/5' : 'border-border hover:shadow-md'
}`}
<div
key={assignment.id}
className={`group cursor-pointer bg-white rounded-lg border transition-all duration-200 flex flex-col h-full overflow-hidden ${assignment.status === 'urgent' ? 'border-destructive/30 bg-destructive/5' : 'border-border hover:shadow-md'
}`}
onClick={() => navigate(`/library?view=corporate&courseId=${assignment.id}&tab=overview`)}
>
{/* Course Image */}
@@ -650,23 +650,21 @@ function AssignedTraining() {
/>
{/* Category Badge Overlay */}
<div className="absolute top-3 left-3">
<Badge
<Badge
variant="outline"
className={`text-sm font-normal border px-2 py-0.5 bg-white/90 backdrop-blur-sm ${
assignment.categoryColor === 'bg-destructive' ? 'border-destructive/30 text-destructive' :
className={`text-sm font-normal border px-2 py-0.5 bg-white/90 backdrop-blur-sm ${assignment.categoryColor === 'bg-destructive' ? 'border-destructive/30 text-destructive' :
assignment.categoryColor === 'bg-primary' ? 'border-primary/30 text-primary' :
assignment.categoryColor === 'bg-success' ? 'border-success/30 text-success' :
'border-[#26231A]/30 text-[#26231A]'
}`}
assignment.categoryColor === 'bg-success' ? 'border-success/30 text-success' :
'border-[#26231A]/30 text-[#26231A]'
}`}
>
{assignment.category}
</Badge>
</div>
{/* Deadline Badge Overlay */}
<div className="absolute top-3 right-3">
<div className={`text-sm font-medium px-2 py-1 rounded bg-white/90 backdrop-blur-sm ${
assignment.status === 'urgent' ? 'text-destructive' : 'text-muted-foreground'
}`}>
<div className={`text-sm font-medium px-2 py-1 rounded bg-white/90 backdrop-blur-sm ${assignment.status === 'urgent' ? 'text-destructive' : 'text-muted-foreground'
}`}>
Due: {assignment.deadline}
</div>
</div>
@@ -701,7 +699,7 @@ function AssignedTraining() {
<span className="font-medium">{new Date(assignment.dueDate).toLocaleDateString()}</span>
</div>
</div>
{/* Assignment Metadata and Action - Auto-positioned at bottom */}
<div className="mt-auto space-y-3">
<div className="flex items-center justify-between pt-3 border-t border-border">
@@ -709,16 +707,16 @@ function AssignedTraining() {
<Clock className="h-4 w-4" />
<span>{assignment.duration}</span>
</div>
<Badge
<Badge
variant={assignment.status === 'urgent' ? 'destructive' : 'outline'}
className="text-base"
>
{assignment.status === 'urgent' ? 'Urgent' : 'Assigned'}
</Badge>
</div>
{/* Action Button */}
<Button
<Button
size="sm"
variant={assignment.status === 'urgent' ? 'destructive' : 'default'}
className="w-full text-base h-10"
@@ -742,6 +740,7 @@ function AssignedTraining() {
// Team Leaderboard component
function TeamLeaderboard() {
const navigate = useNavigate();
const teamData = [
{ id: '1', name: 'Sarah Johnson (You)', avatar: 'https://images.unsplash.com/photo-1494790108755-2616b612b786?w=100&h=100&fit=crop', points: 2156, rank: 1, completed: 12, isCurrentUser: true },
{ id: '2', name: 'Alex Chen', avatar: 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=100&h=100&fit=crop', points: 2089, rank: 2, completed: 11 },
@@ -761,8 +760,8 @@ function TeamLeaderboard() {
</div>
<span className="bg-gradient-to-r from-gray-800 to-gray-600 bg-clip-text text-transparent">Team Leaderboard</span>
</div>
<Button
variant="outline"
<Button
variant="outline"
size="sm"
onClick={() => navigate('/leaderboard?view=corporate')}
className="text-base h-10 border-2 border-brand-navy/15 text-brand-navy/80 hover:bg-brand-navy/3 font-semibold"
@@ -773,22 +772,20 @@ function TeamLeaderboard() {
</CardHeader>
<CardContent className="space-y-4 p-6">
{teamData.map((entry) => (
<div
key={entry.id}
className={`flex items-center justify-between p-4 rounded-xl transition-all duration-200 hover:shadow-lg ${
entry.isCurrentUser
? 'bg-gradient-to-r from-brand-navy/10 to-brand-navy/5 border-2 border-brand-navy/20 shadow-md'
: 'hover:bg-gradient-to-r hover:from-gray-50 hover:to-white bg-white/50 border border-gray-200/50'
}`}
<div
key={entry.id}
className={`flex items-center justify-between p-4 rounded-xl transition-all duration-200 hover:shadow-lg ${entry.isCurrentUser
? 'bg-gradient-to-r from-brand-navy/10 to-brand-navy/5 border-2 border-brand-navy/20 shadow-md'
: 'hover:bg-gradient-to-r hover:from-gray-50 hover:to-white bg-white/50 border border-gray-200/50'
}`}
>
<div className="flex items-center gap-4 flex-1 min-w-0">
<div className={`flex items-center justify-center w-10 h-10 rounded-xl text-base font-bold flex-shrink-0 shadow-md ${
entry.rank === 1 ? 'bg-gradient-to-br from-brand-gold to-amber-500 text-white' :
<div className={`flex items-center justify-center w-10 h-10 rounded-xl text-base font-bold flex-shrink-0 shadow-md ${entry.rank === 1 ? 'bg-gradient-to-br from-brand-gold to-amber-500 text-white' :
entry.rank === 2 ? 'bg-gradient-to-br from-gray-400 to-gray-500 text-white' :
entry.rank === 3 ? 'bg-gradient-to-br from-amber-600 to-amber-700 text-white' :
entry.isCurrentUser ? 'bg-gradient-to-br from-brand-navy to-brand-navy/80 text-white' :
'bg-gradient-to-br from-gray-200 to-gray-300 text-gray-600'
}`}>
entry.rank === 3 ? 'bg-gradient-to-br from-amber-600 to-amber-700 text-white' :
entry.isCurrentUser ? 'bg-gradient-to-br from-brand-navy to-brand-navy/80 text-white' :
'bg-gradient-to-br from-gray-200 to-gray-300 text-gray-600'
}`}>
{entry.rank}
</div>
<Avatar className="w-10 h-10 flex-shrink-0 shadow-md border-2 border-white">
@@ -811,10 +808,9 @@ function TeamLeaderboard() {
</div>
</div>
</div>
<Badge variant={entry.isCurrentUser ? "default" : "outline"} className={`text-base px-3 py-1 font-semibold ${
entry.isCurrentUser ? 'bg-gradient-to-r from-brand-navy to-brand-navy/80 text-white shadow-md' : 'border-gray-300 text-gray-600'
}`}>
<Badge variant={entry.isCurrentUser ? "default" : "outline"} className={`text-base px-3 py-1 font-semibold ${entry.isCurrentUser ? 'bg-gradient-to-r from-brand-navy to-brand-navy/80 text-white shadow-md' : 'border-gray-300 text-gray-600'
}`}>
#{entry.rank}
</Badge>
</div>
@@ -898,7 +894,7 @@ function RecentActivity() {
{activities.map((activity) => {
const Icon = activity.icon;
return (
<div
<div
key={activity.id}
className={`group flex items-start gap-4 p-4 rounded-xl border-0 bg-gradient-to-r ${activity.bgColor} hover:shadow-lg transition-all duration-300 cursor-pointer hover:-translate-y-0.5`}
>
@@ -928,73 +924,73 @@ function RecentActivity() {
// Global Learner Map component - Full width heatmap
function GlobalLearnerMap() {
const learnersByCountry = [
{
country: 'Romania',
learners: 55760,
percentage: 21.2,
{
country: 'Romania',
learners: 55760,
percentage: 21.2,
color: '#04045B',
flag: '🇷🇴'
},
{
country: 'Australia',
learners: 60374,
percentage: 22.9,
{
country: 'Australia',
learners: 60374,
percentage: 22.9,
color: '#04045B',
flag: '🇦🇺'
},
{
country: 'Russia',
learners: 37556,
percentage: 17,
{
country: 'Russia',
learners: 37556,
percentage: 17,
color: '#04045B',
flag: '🇷🇺'
},
{
country: 'Ireland',
learners: 32123,
percentage: 14,
{
country: 'Ireland',
learners: 32123,
percentage: 14,
color: '#F8C301',
flag: '🇮🇪'
},
{
country: 'Ukraine',
learners: 30589,
percentage: 13,
{
country: 'Ukraine',
learners: 30589,
percentage: 13,
color: '#F8C301',
flag: '🇺🇦'
},
{
country: 'USA',
learners: 24544,
percentage: 12.8,
{
country: 'USA',
learners: 24544,
percentage: 12.8,
color: '#26231A',
flag: '🇺🇸'
},
{
country: 'Germany',
learners: 23787,
percentage: 12.8,
{
country: 'Germany',
learners: 23787,
percentage: 12.8,
color: '#26231A',
flag: '🇩🇪'
},
{
country: 'Argentina',
learners: 18245,
percentage: 8.9,
{
country: 'Argentina',
learners: 18245,
percentage: 8.9,
color: '#6B7280',
flag: '🇦🇷'
},
{
country: 'Spain',
learners: 12374,
percentage: 3.7,
{
country: 'Spain',
learners: 12374,
percentage: 3.7,
color: '#6B7280',
flag: '🇪🇸'
},
{
country: 'Brazil',
learners: 12374,
percentage: 3.7,
{
country: 'Brazil',
learners: 12374,
percentage: 3.7,
color: '#6B7280',
flag: '🇧🇷'
}
@@ -1019,8 +1015,8 @@ function GlobalLearnerMap() {
</p>
</div>
</div>
<Button
variant="outline"
<Button
variant="outline"
className="text-base h-11 px-6 border-brand-navy/20 text-brand-navy hover:bg-brand-navy/5"
>
<MapPin className="h-4 w-4 mr-2" />
@@ -1031,7 +1027,7 @@ function GlobalLearnerMap() {
<CardContent className="p-8">
<div className="grid grid-cols-1 lg:grid-cols-5 gap-8 items-center">
{/* Left Column - Country Statistics */}
<div className="lg:col-span-2 space-y-1">
<div className="mb-6">
@@ -1043,10 +1039,10 @@ function GlobalLearnerMap() {
Distribution of learners by country
</p>
</div>
<div className="space-y-3 max-h-96 overflow-y-auto scrollbar-minimal">
{learnersByCountry.map((country, index) => (
<div
<div
key={country.country}
className="flex items-center justify-between py-3 px-4 rounded-lg hover:bg-gray-50/80 transition-colors duration-200 group cursor-pointer"
style={{
@@ -1056,7 +1052,7 @@ function GlobalLearnerMap() {
<div className="flex items-center gap-3 flex-1">
<div className="flex items-center gap-3 min-w-0 flex-1">
<span className="text-xl flex-shrink-0">{country.flag}</span>
<div
<div
className="w-4 h-4 rounded-full flex-shrink-0 shadow-sm border border-white/50"
style={{ backgroundColor: country.color }}
></div>
@@ -1065,7 +1061,7 @@ function GlobalLearnerMap() {
</span>
</div>
</div>
<div className="flex items-center gap-4 flex-shrink-0">
<div className="text-right">
<div className="text-base font-semibold text-foreground">
@@ -1076,9 +1072,9 @@ function GlobalLearnerMap() {
</div>
</div>
<div className="w-16 bg-gray-200 rounded-full h-2">
<div
<div
className="h-2 rounded-full transition-all duration-500 shadow-sm"
style={{
style={{
width: `${Math.min(country.percentage * 4, 100)}%`,
backgroundColor: country.color
}}
@@ -1122,114 +1118,114 @@ function GlobalLearnerMap() {
alt="Global learner distribution map"
className="w-full h-auto opacity-90 drop-shadow-lg"
/>
{/* Overlay heatmap dots for major countries */}
<div className="absolute inset-0">
{/* Romania - Eastern Europe */}
<div
<div
className="absolute w-3 h-3 rounded-full shadow-lg animate-pulse"
style={{
style={{
backgroundColor: '#04045B',
top: '25%',
top: '25%',
left: '55%',
boxShadow: '0 0 20px rgba(4, 4, 91, 0.6)'
}}
></div>
{/* Australia - Oceania */}
<div
<div
className="absolute w-4 h-4 rounded-full shadow-lg animate-pulse"
style={{
style={{
backgroundColor: '#04045B',
top: '75%',
top: '75%',
right: '15%',
boxShadow: '0 0 25px rgba(4, 4, 91, 0.6)'
}}
></div>
{/* Russia - Northern Asia */}
<div
<div
className="absolute w-3 h-3 rounded-full shadow-lg animate-pulse"
style={{
style={{
backgroundColor: '#04045B',
top: '20%',
top: '20%',
left: '70%',
boxShadow: '0 0 20px rgba(4, 4, 91, 0.6)'
}}
></div>
{/* Ireland - Western Europe */}
<div
<div
className="absolute w-3 h-3 rounded-full shadow-lg animate-pulse"
style={{
style={{
backgroundColor: '#F8C301',
top: '28%',
top: '28%',
left: '45%',
boxShadow: '0 0 20px rgba(248, 195, 1, 0.6)'
}}
></div>
{/* Ukraine - Eastern Europe */}
<div
<div
className="absolute w-3 h-3 rounded-full shadow-lg animate-pulse"
style={{
style={{
backgroundColor: '#F8C301',
top: '30%',
top: '30%',
left: '58%',
boxShadow: '0 0 20px rgba(248, 195, 1, 0.6)'
}}
></div>
{/* USA - North America */}
<div
<div
className="absolute w-3 h-3 rounded-full shadow-lg animate-pulse"
style={{
style={{
backgroundColor: '#26231A',
top: '35%',
top: '35%',
left: '25%',
boxShadow: '0 0 20px rgba(38, 35, 26, 0.6)'
}}
></div>
{/* Germany - Central Europe */}
<div
<div
className="absolute w-3 h-3 rounded-full shadow-lg animate-pulse"
style={{
style={{
backgroundColor: '#26231A',
top: '32%',
top: '32%',
left: '50%',
boxShadow: '0 0 20px rgba(38, 35, 26, 0.6)'
}}
></div>
{/* Argentina - South America */}
<div
<div
className="absolute w-2 h-2 rounded-full shadow-lg animate-pulse"
style={{
style={{
backgroundColor: '#6B7280',
top: '80%',
top: '80%',
left: '30%',
boxShadow: '0 0 15px rgba(107, 114, 128, 0.6)'
}}
></div>
{/* Spain - Western Europe */}
<div
<div
className="absolute w-2 h-2 rounded-full shadow-lg animate-pulse"
style={{
style={{
backgroundColor: '#6B7280',
top: '38%',
top: '38%',
left: '46%',
boxShadow: '0 0 15px rgba(107, 114, 128, 0.6)'
}}
></div>
{/* Brazil - South America */}
<div
<div
className="absolute w-2 h-2 rounded-full shadow-lg animate-pulse"
style={{
style={{
backgroundColor: '#6B7280',
top: '70%',
top: '70%',
left: '33%',
boxShadow: '0 0 15px rgba(107, 114, 128, 0.6)'
}}
@@ -1320,7 +1316,7 @@ export function CorporateDashboard() {
<TeamPerformanceOverview />
<CorporateAnalytics />
</div>
{/* Right Column - Assigned Training */}
<div className="lg:col-span-3">
<AssignedTraining />

View File

@@ -53,8 +53,8 @@ function LibrarySkeleton() {
export function Library({ userType = 'individual' }: LibraryProps) {
const [isLoading, setIsLoading] = useState(true);
const [courses] = useState<Course[]>(getCoursesData(userType));
const navigate = useNavigate();
const navigate = useNavigate();
// Filter states
const [searchQuery, setSearchQuery] = useState('');
const [selectedCategory, setSelectedCategory] = useState('All Categories');
@@ -89,9 +89,9 @@ export function Library({ userType = 'individual' }: LibraryProps) {
const filteredCourses = courses.filter(course => {
// Search filter
if (searchQuery && !course.title.toLowerCase().includes(searchQuery.toLowerCase()) &&
!course.description.toLowerCase().includes(searchQuery.toLowerCase()) &&
!course.instructor.name.toLowerCase().includes(searchQuery.toLowerCase()) &&
!course.tags.some(tag => tag.toLowerCase().includes(searchQuery.toLowerCase()))) {
!course.description.toLowerCase().includes(searchQuery.toLowerCase()) &&
!course.instructor.name.toLowerCase().includes(searchQuery.toLowerCase()) &&
!course.tags.some(tag => tag.toLowerCase().includes(searchQuery.toLowerCase()))) {
return false;
}
@@ -192,7 +192,7 @@ export function Library({ userType = 'individual' }: LibraryProps) {
Leadership Development Library
</h1>
<p className="text-[16px] font-medium leading-[20px] text-[#6B7280]">
{userType === 'corporate'
{userType === 'corporate'
? 'Access your assigned courses and explore additional leadership development opportunities'
: 'Discover and enroll in courses designed to advance your leadership journey'
}
@@ -251,11 +251,10 @@ export function Library({ userType = 'individual' }: LibraryProps) {
<button
key={tab.value}
onClick={() => setActiveTab(tab.value)}
className={`flex-1 px-4 py-2.5 text-[16px] font-semibold rounded-full transition-all duration-300 ease-in-out focus:outline-none focus:ring-0 active:outline-none ${
activeTab === tab.value
className={`flex-1 px-4 py-2.5 text-[16px] font-semibold rounded-full transition-all duration-300 ease-in-out focus:outline-none focus:ring-0 active:outline-none ${activeTab === tab.value
? 'bg-white text-[#111827] shadow-lg backdrop-blur-sm border border-white/50'
: 'text-[#6B7280] hover:text-[#111827] hover:bg-white/60 hover:shadow-md'
}`}
}`}
>
{tab.label}
</button>
@@ -278,7 +277,7 @@ export function Library({ userType = 'individual' }: LibraryProps) {
: 'No courses are available in this category.'}
</p>
{(searchQuery || selectedCategory !== 'All Categories' || selectedLevel !== 'All Levels') && (
<Button
<Button
variant="outline"
onClick={() => {
setSearchQuery('');
@@ -300,11 +299,11 @@ export function Library({ userType = 'individual' }: LibraryProps) {
<CardHeader className="pb-6 bg-gradient-to-r from-white to-gray-50/50 border-b border-[#E5E7EB]/50">
<CardTitle className="text-[20px] font-bold flex items-center justify-between">
<span className="bg-gradient-to-r from-gray-800 to-gray-600 bg-clip-text text-transparent">
{activeTab === 'all' ? 'All Leadership Courses' :
activeTab === 'in-progress' ? 'In Progress' :
activeTab === 'completed' ? 'Completed Courses' :
activeTab === 'bookmarked' ? 'Bookmarked Courses' :
'Assigned Courses'}
{activeTab === 'all' ? 'All Leadership Courses' :
activeTab === 'in-progress' ? 'In Progress' :
activeTab === 'completed' ? 'Completed Courses' :
activeTab === 'bookmarked' ? 'Bookmarked Courses' :
'Assigned Courses'}
<span className="text-[#6B7280] ml-2 text-[16px] font-medium">({filteredCourses.length})</span>
</span>
</CardTitle>

View File

@@ -1,8 +1,9 @@
import React, { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
// import { navigate } from '../../components/Router';
const navigate = useNavigate();
export function Consulting() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -1,9 +1,10 @@
import React, { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
// import { navigate } from '../../components/Router';
const navigate = useNavigate();
export function CultureCompetence() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -1,9 +1,10 @@
import React, { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
// import { navigate } from '../../components/Router';
const navigate = useNavigate();
export function ExecutiveCoaching() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -1,8 +1,9 @@
import React, { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
// import { navigate } from '../../components/Router';
const navigate = useNavigate();
export function LeadershipDevelopment() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -1,9 +1,10 @@
import React, { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
// import { navigate } from '../../components/Router';
const navigate = useNavigate();
export function LearningFacility() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

View File

@@ -1,9 +1,10 @@
import React, { useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
// import { navigate } from '../../components/Router';
const navigate = useNavigate();
export function ManagementDevelopment() {
const navigate = useNavigate();
useEffect(() => {
// This is a deprecated page, redirect to home
navigate('/');

21
src/types/images.d.ts vendored Normal file
View File

@@ -0,0 +1,21 @@
declare module '*.png' {
const src: string;
export default src;
}
declare module '*.jpg' {
const src: string;
export default src;
}
declare module '*.jpeg' {
const src: string;
export default src;
}
declare module '*.svg' {
const src: string;
export default src;
}