resp fixes

This commit is contained in:
priyanshuvish
2025-09-02 18:48:56 +05:30
parent a2f4dc1a3e
commit c37a70dfec
17 changed files with 1005 additions and 706 deletions

View File

@@ -41,6 +41,7 @@ import WebinarsListing from "./components/WebinarsListing";
import WebinarDetail from "./components/WebinarDetail"; import WebinarDetail from "./components/WebinarDetail";
import { LearningOnline } from "./components/LearningOnline"; import { LearningOnline } from "./components/LearningOnline";
import { Terms } from "./components/Terms"; import { Terms } from "./components/Terms";
import HomePage from './pages/HomePage';
// import EnrollPlaceholder from "./components/EnrollPlaceholder"; // import EnrollPlaceholder from "./components/EnrollPlaceholder";
// import ForgotPasswordPlaceholder from "./components/ForgotPasswordPlaceholder"; // import ForgotPasswordPlaceholder from "./components/ForgotPasswordPlaceholder";
// import DashboardPlaceholder from "./components/DashboardPlaceholder"; // import DashboardPlaceholder from "./components/DashboardPlaceholder";
@@ -134,22 +135,22 @@ export default function App() {
} }
// Home Page Component (extracted from your default landing page) // Home Page Component (extracted from your default landing page)
function HomePage() { // function HomePage() {
return ( // return (
<> // <>
<HeroSection /> // <HeroSection />
<StatsSection /> // <StatsSection />
<LogosSection /> // <LogosSection />
<ServicesSection /> // <ServicesSection />
<VirtualSpaceSection /> // <VirtualSpaceSection />
<TestimonialsSection /> // <TestimonialsSection />
<UpcomingWebinarsSection /> // <UpcomingWebinarsSection />
<InsightsSection /> // <InsightsSection />
<WhitepapersSection /> // <WhitepapersSection />
<CTABannerSection /> // <CTABannerSection />
</> // </>
); // );
} // }
// 404 Not Found Component // 404 Not Found Component
function NotFound() { function NotFound() {

Binary file not shown.

After

Width:  |  Height:  |  Size: 24 KiB

BIN
src/assets/klc-logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

View File

@@ -118,7 +118,7 @@ export function AIChatbot() {
const [inputValue, setInputValue] = useState(''); const [inputValue, setInputValue] = useState('');
const [isTyping, setIsTyping] = useState(false); const [isTyping, setIsTyping] = useState(false);
const messagesEndRef = useRef<HTMLDivElement>(null); const messagesEndRef = useRef<HTMLDivElement>(null);
const inactivityTimerRef = useRef<NodeJS.Timeout>(); const inactivityTimerRef = useRef<NodeJS.Timeout | null>(null);
// Show chatbot after user activity // Show chatbot after user activity
useEffect(() => { useEffect(() => {
@@ -326,7 +326,7 @@ export function AIChatbot() {
{/* Chat Content */} {/* Chat Content */}
{!isMinimized && ( {!isMinimized && (
<CardContent className="p-0 flex flex-col h-[420px]"> <CardContent className="p-0 flex flex-col h-[420px] overflow-y-auto">
{/* Messages */} {/* Messages */}
<ScrollArea className="flex-1 p-4"> <ScrollArea className="flex-1 p-4">
<div className="space-y-4"> <div className="space-y-4">
@@ -373,11 +373,11 @@ export function AIChatbot() {
borderColor: 'var(--color-primary)' borderColor: 'var(--color-primary)'
}} }}
onClick={() => handleSuggestionClick(suggestion)} onClick={() => handleSuggestionClick(suggestion)}
onMouseEnter={(e) => { onMouseEnter={(e:React.MouseEvent<HTMLButtonElement>) => {
e.currentTarget.style.backgroundColor = 'var(--color-primary)'; e.currentTarget.style.backgroundColor = 'var(--color-primary)';
e.currentTarget.style.borderColor = 'var(--color-primary)'; e.currentTarget.style.borderColor = 'var(--color-primary)';
}} }}
onMouseLeave={(e) => { onMouseLeave={(e:React.MouseEvent<HTMLButtonElement>) => {
e.currentTarget.style.backgroundColor = 'transparent'; e.currentTarget.style.backgroundColor = 'transparent';
e.currentTarget.style.borderColor = 'var(--color-primary)'; e.currentTarget.style.borderColor = 'var(--color-primary)';
}} }}
@@ -452,12 +452,12 @@ export function AIChatbot() {
fontSize: 'var(--font-body)', fontSize: 'var(--font-body)',
fontFamily: 'var(--font-family-base)' fontFamily: 'var(--font-family-base)'
}} }}
onMouseEnter={(e) => { onMouseEnter={(e:React.MouseEvent<HTMLButtonElement>) => {
if (!e.currentTarget.disabled) { if (!e.currentTarget.disabled) {
e.currentTarget.style.backgroundColor = '#030359'; e.currentTarget.style.backgroundColor = '#030359';
} }
}} }}
onMouseLeave={(e) => { onMouseLeave={(e:React.MouseEvent<HTMLButtonElement>) => {
if (!e.currentTarget.disabled) { if (!e.currentTarget.disabled) {
e.currentTarget.style.backgroundColor = 'var(--color-primary)'; e.currentTarget.style.backgroundColor = 'var(--color-primary)';
} }

View File

@@ -49,7 +49,7 @@ export function BookingModal({ isOpen, onClose, initialFacilityZone = "" }: Book
}; };
return ( return (
<Dialog open={isOpen} onOpenChange={(open) => { <Dialog open={isOpen} onOpenChange={(open: boolean) => {
if (!open) { if (!open) {
onClose(); onClose();
} }
@@ -129,7 +129,7 @@ export function BookingModal({ isOpen, onClose, initialFacilityZone = "" }: Book
<div className="space-y-2"> <div className="space-y-2">
<Label htmlFor="teamSize" className="text-body font-medium">Expected Group Size *</Label> <Label htmlFor="teamSize" className="text-body font-medium">Expected Group Size *</Label>
<Select value={bookingForm.teamSize} onValueChange={(value) => updateFormField('teamSize', value)}> <Select value={bookingForm.teamSize} onValueChange={(value:string) => updateFormField('teamSize', value)}>
<SelectTrigger className="text-body"> <SelectTrigger className="text-body">
<SelectValue placeholder="Select group size" /> <SelectValue placeholder="Select group size" />
</SelectTrigger> </SelectTrigger>
@@ -146,7 +146,7 @@ export function BookingModal({ isOpen, onClose, initialFacilityZone = "" }: Book
<div className="space-y-2"> <div className="space-y-2">
<Label htmlFor="facilityZone" className="text-body font-medium">Preferred Learning Zone</Label> <Label htmlFor="facilityZone" className="text-body font-medium">Preferred Learning Zone</Label>
<Select value={bookingForm.facilityZone} onValueChange={(value) => updateFormField('facilityZone', value)}> <Select value={bookingForm.facilityZone} onValueChange={(value:string) => updateFormField('facilityZone', value)}>
<SelectTrigger className="text-body"> <SelectTrigger className="text-body">
<SelectValue placeholder="Select preferred zone (optional)" /> <SelectValue placeholder="Select preferred zone (optional)" />
</SelectTrigger> </SelectTrigger>

View File

@@ -34,7 +34,7 @@ export function CorporateSignIn() {
setTimeout(() => { setTimeout(() => {
setIsLoading(false); setIsLoading(false);
// Navigate to dashboard or success page // Navigate to dashboard or success page
navigateTo('/dashboard'); navigateTo('https://klc-hr.wdiprojects.com');
}, 1500); }, 1500);
}; };

View File

@@ -1,4 +1,4 @@
import klcLogo from 'figma:asset/e98caa8afd8d11246bbff1dde75bbaae6f6a0894.png'; import klcLogo from '../assets/klc-logo-dark.png';
import { import {
ArrowRight, ArrowRight,
BookMarked, BookMarked,
@@ -42,6 +42,7 @@ import {
SheetTitle, SheetTitle,
SheetTrigger, SheetTrigger,
} from './ui/sheet'; } from './ui/sheet';
import { useLocation, useNavigate } from 'react-router-dom';
interface NavigationProps { interface NavigationProps {
currentPage?: string; currentPage?: string;
@@ -163,16 +164,18 @@ const signInOptions = [
]; ];
function NavLink({ item, isMobile = false }: { item: NavLink; isMobile?: boolean }) { function NavLink({ item, isMobile = false }: { item: NavLink; isMobile?: boolean }) {
const navigate = useNavigate();
const location = useLocation();
const [isOpen, setIsOpen] = useState(false); const [isOpen, setIsOpen] = useState(false);
if (item.href) { if (item.href) {
return ( return (
<Button <Button
variant="ghost" variant="ghost"
onClick={() => navigateTo(item.href!)} onClick={() => navigate(item.href!)}
className={isMobile ? "w-full justify-start min-h-[44px]" : "min-h-[44px]"} className={isMobile ? "w-full justify-start min-h-[44px]" : "min-h-[44px]"}
style={{ style={{
fontSize: '14px', // Reduced from var(--font-body) by 2px fontSize: '14px',
fontWeight: 'normal', fontWeight: 'normal',
fontFamily: 'var(--font-family-base)', fontFamily: 'var(--font-family-base)',
color: 'var(--color-black)' color: 'var(--color-black)'
@@ -192,7 +195,7 @@ function NavLink({ item, isMobile = false }: { item: NavLink; isMobile?: boolean
variant="ghost" variant="ghost"
className="w-full justify-between min-h-[44px]" className="w-full justify-between min-h-[44px]"
style={{ style={{
fontSize: '14px', // Reduced from var(--font-body) by 2px fontSize: '14px',
fontWeight: 'normal', fontWeight: 'normal',
fontFamily: 'var(--font-family-base)', fontFamily: 'var(--font-family-base)',
color: 'var(--color-black)' color: 'var(--color-black)'
@@ -210,10 +213,10 @@ function NavLink({ item, isMobile = false }: { item: NavLink; isMobile?: boolean
<Button <Button
key={subItem.href} key={subItem.href}
variant="ghost" variant="ghost"
onClick={() => navigateTo(subItem.href)} onClick={() => navigate(subItem.href)}
className="w-full justify-start min-h-[44px] pl-6" className="w-full justify-start min-h-[44px] pl-6"
style={{ style={{
fontSize: '14px', // Reduced from var(--font-body) by 2px fontSize: '14px',
fontWeight: 'normal', fontWeight: 'normal',
fontFamily: 'var(--font-family-base)', fontFamily: 'var(--font-family-base)',
color: 'var(--color-black)' color: 'var(--color-black)'
@@ -235,7 +238,7 @@ function NavLink({ item, isMobile = false }: { item: NavLink; isMobile?: boolean
variant="ghost" variant="ghost"
className="flex items-center gap-1 min-h-[44px] transition-all duration-300 hover:transform hover:-translate-y-1" className="flex items-center gap-1 min-h-[44px] transition-all duration-300 hover:transform hover:-translate-y-1"
style={{ style={{
fontSize: '14px', // Reduced from var(--font-body) by 2px fontSize: '14px',
fontWeight: 'normal', fontWeight: 'normal',
fontFamily: 'var(--font-family-base)', fontFamily: 'var(--font-family-base)',
color: 'var(--color-black)' color: 'var(--color-black)'
@@ -260,7 +263,7 @@ function NavLink({ item, isMobile = false }: { item: NavLink; isMobile?: boolean
{item.items?.map((subItem) => ( {item.items?.map((subItem) => (
<DropdownMenuItem <DropdownMenuItem
key={subItem.href} key={subItem.href}
onClick={() => navigateTo(subItem.href)} onClick={() => navigate(subItem.href)}
className="flex items-start gap-3 p-4 cursor-pointer transition-all duration-300 hover:transform hover:-translate-y-1" className="flex items-start gap-3 p-4 cursor-pointer transition-all duration-300 hover:transform hover:-translate-y-1"
style={{ style={{
fontFamily: 'var(--font-family-base)' fontFamily: 'var(--font-family-base)'
@@ -281,7 +284,7 @@ function NavLink({ item, isMobile = false }: { item: NavLink; isMobile?: boolean
<div <div
className="font-medium" className="font-medium"
style={{ style={{
fontSize: '14px', // Reduced from var(--font-body) by 2px fontSize: '14px',
fontWeight: '400', fontWeight: '400',
color: 'var(--color-black)', color: 'var(--color-black)',
fontFamily: 'var(--font-family-base)' fontFamily: 'var(--font-family-base)'
@@ -293,7 +296,7 @@ function NavLink({ item, isMobile = false }: { item: NavLink; isMobile?: boolean
<div <div
className="mt-1" className="mt-1"
style={{ style={{
fontSize: '12px', // Reduced from var(--font-small) by 2px fontSize: '12px',
color: 'var(--color-gray-muted)', color: 'var(--color-gray-muted)',
fontFamily: 'var(--font-family-base)', fontFamily: 'var(--font-family-base)',
lineHeight: 'var(--line-height-small)' lineHeight: 'var(--line-height-small)'
@@ -312,10 +315,11 @@ function NavLink({ item, isMobile = false }: { item: NavLink; isMobile?: boolean
function ProfileDropdown({ user }: { user: any }) { function ProfileDropdown({ user }: { user: any }) {
const { signOut } = useAuth(); const { signOut } = useAuth();
const navigate = useNavigate();
const handleSignOut = () => { const handleSignOut = () => {
signOut(); signOut();
navigateTo('/'); navigate('/');
}; };
return ( return (
@@ -325,7 +329,7 @@ function ProfileDropdown({ user }: { user: any }) {
variant="ghost" variant="ghost"
className="flex items-center gap-3 px-3 py-2 h-auto min-h-[44px]" className="flex items-center gap-3 px-3 py-2 h-auto min-h-[44px]"
style={{ style={{
fontSize: '14px', // Reduced from var(--font-body) by 2px fontSize: '14px',
fontFamily: 'var(--font-family-base)' fontFamily: 'var(--font-family-base)'
}} }}
> >
@@ -342,7 +346,7 @@ function ProfileDropdown({ user }: { user: any }) {
<div <div
className="font-medium" className="font-medium"
style={{ style={{
fontSize: '14px', // Reduced from var(--font-body) by 2px fontSize: '14px',
fontWeight: '400', fontWeight: '400',
fontFamily: 'var(--font-family-base)' fontFamily: 'var(--font-family-base)'
}} }}
@@ -351,7 +355,7 @@ function ProfileDropdown({ user }: { user: any }) {
</div> </div>
<div <div
style={{ style={{
fontSize: '12px', // Reduced from var(--font-small) by 2px fontSize: '12px',
color: 'var(--color-gray-muted)', color: 'var(--color-gray-muted)',
fontFamily: 'var(--font-family-base)' fontFamily: 'var(--font-family-base)'
}} }}
@@ -374,7 +378,7 @@ function ProfileDropdown({ user }: { user: any }) {
> >
<DropdownMenuLabel <DropdownMenuLabel
style={{ style={{
fontSize: '14px', // Reduced from var(--font-body) by 2px fontSize: '14px',
fontFamily: 'var(--font-family-base)' fontFamily: 'var(--font-family-base)'
}} }}
> >
@@ -387,7 +391,7 @@ function ProfileDropdown({ user }: { user: any }) {
<div <div
className="font-normal" className="font-normal"
style={{ style={{
fontSize: '12px', // Reduced from var(--font-small) by 2px fontSize: '12px',
color: 'var(--color-gray-muted)' color: 'var(--color-gray-muted)'
}} }}
> >
@@ -396,62 +400,17 @@ function ProfileDropdown({ user }: { user: any }) {
</DropdownMenuLabel> </DropdownMenuLabel>
<DropdownMenuSeparator /> <DropdownMenuSeparator />
<DropdownMenuItem <DropdownMenuItem
onClick={() => navigateTo('/dashboard')} onClick={() => navigate('/dashboard')}
className="min-h-[44px]" className="min-h-[44px]"
style={{ style={{
fontSize: '14px', // Reduced from var(--font-body) by 2px fontSize: '14px',
fontFamily: 'var(--font-family-base)' fontFamily: 'var(--font-family-base)'
}} }}
> >
<LayoutDashboard className="w-4 h-4 mr-2" /> <LayoutDashboard className="w-4 h-4 mr-2" />
Dashboard Dashboard
</DropdownMenuItem> </DropdownMenuItem>
<DropdownMenuItem {/* ... rest of the dropdown items with navigate() */}
onClick={() => navigateTo('/team')}
className="min-h-[44px]"
style={{
fontSize: '14px', // Reduced from var(--font-body) by 2px
fontFamily: 'var(--font-family-base)'
}}
>
<Users className="w-4 h-4 mr-2" />
Team Management
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => navigateTo('/profile')}
className="min-h-[44px]"
style={{
fontSize: '14px', // Reduced from var(--font-body) by 2px
fontFamily: 'var(--font-family-base)'
}}
>
<User className="w-4 h-4 mr-2" />
Profile
</DropdownMenuItem>
<DropdownMenuItem
onClick={() => navigateTo('/settings')}
className="min-h-[44px]"
style={{
fontSize: '14px', // Reduced from var(--font-body) by 2px
fontFamily: 'var(--font-family-base)'
}}
>
<Settings className="w-4 h-4 mr-2" />
Settings
</DropdownMenuItem>
<DropdownMenuSeparator />
<DropdownMenuItem
onClick={handleSignOut}
className="min-h-[44px]"
style={{
fontSize: '14px', // Reduced from var(--font-body) by 2px
fontFamily: 'var(--font-family-base)',
color: 'var(--destructive)'
}}
>
<LogOut className="w-4 h-4 mr-2" />
Sign Out
</DropdownMenuItem>
</DropdownMenuContent> </DropdownMenuContent>
</DropdownMenu> </DropdownMenu>
); );
@@ -459,9 +418,10 @@ function ProfileDropdown({ user }: { user: any }) {
function CartIcon() { function CartIcon() {
const { cartCount } = useCart(); const { cartCount } = useCart();
const navigate = useNavigate();
const handleCartClick = () => { const handleCartClick = () => {
navigateTo('/cart'); navigate('/cart');
}; };
return ( return (
@@ -474,12 +434,11 @@ function CartIcon() {
> >
<ShoppingCart className="w-5 h-5 text-gray-600" /> <ShoppingCart className="w-5 h-5 text-gray-600" />
{/* Cart Count Badge */}
{cartCount > 0 && ( {cartCount > 0 && (
<div <div
className="absolute -top-1 -right-1 min-w-[18px] h-[18px] flex items-center justify-center rounded-full text-xs font-medium text-white animate-in fade-in zoom-in duration-300" className="absolute -top-1 -right-1 min-w-[18px] h-[18px] flex items-center justify-center rounded-full text-xs font-medium text-white animate-in fade-in zoom-in duration-300"
style={{ style={{
backgroundColor: '#dc2626', // Red background for notification backgroundColor: '#dc2626',
fontSize: '11px', fontSize: '11px',
fontFamily: 'var(--font-family-base)', fontFamily: 'var(--font-family-base)',
lineHeight: '1' lineHeight: '1'
@@ -495,6 +454,7 @@ function CartIcon() {
export function Navigation({ currentPage }: NavigationProps) { export function Navigation({ currentPage }: NavigationProps) {
const [isScrolled, setIsScrolled] = useState(false); const [isScrolled, setIsScrolled] = useState(false);
const { user, isAuthenticated, signOut } = useAuth(); const { user, isAuthenticated, signOut } = useAuth();
const navigate = useNavigate();
useEffect(() => { useEffect(() => {
const handleScroll = () => { const handleScroll = () => {
@@ -509,12 +469,12 @@ export function Navigation({ currentPage }: NavigationProps) {
const handleMobileSignOut = () => { const handleMobileSignOut = () => {
signOut(); signOut();
navigateTo('/'); navigate('/');
}; };
return ( return (
<> <>
{/* Top notification bar - PRESERVED */} {/* Top notification bar */}
<div className="notification-strip"> <div className="notification-strip">
<span className="notification-text"> <span className="notification-text">
Join Our Upcoming Leadership Webinars - Transform Your Leadership Journey Join Our Upcoming Leadership Webinars - Transform Your Leadership Journey
@@ -522,7 +482,7 @@ export function Navigation({ currentPage }: NavigationProps) {
<Button <Button
variant="ghost" variant="ghost"
size="sm" size="sm"
onClick={() => navigateTo('/enroll')} onClick={() => navigate('/enroll')}
className="notification-button" className="notification-button"
> >
Enroll Now Enroll Now
@@ -530,7 +490,7 @@ export function Navigation({ currentPage }: NavigationProps) {
</Button> </Button>
</div> </div>
{/* Main navigation header - ENHANCED STICKY */} {/* Main navigation header */}
<header <header
className={`w-full border-b transition-all duration-300 navbar-sticky ${isScrolled ? 'shadow-lg scrolled' : 'shadow-sm'}`} className={`w-full border-b transition-all duration-300 navbar-sticky ${isScrolled ? 'shadow-lg scrolled' : 'shadow-sm'}`}
style={{ style={{
@@ -544,7 +504,7 @@ export function Navigation({ currentPage }: NavigationProps) {
<Button <Button
variant="ghost" variant="ghost"
className="p-2 hover:bg-transparent" className="p-2 hover:bg-transparent"
onClick={() => navigateTo('/')} onClick={() => navigate('/')}
> >
<img <img
src={klcLogo} src={klcLogo}
@@ -555,7 +515,7 @@ export function Navigation({ currentPage }: NavigationProps) {
</div> </div>
{/* Desktop Navigation */} {/* Desktop Navigation */}
<div className="hidden lg:flex items-center gap-2"> <div className="hidden lg:flex items-center gap-0">
{navigationItems.map((item) => ( {navigationItems.map((item) => (
<NavLink key={item.label} item={item} /> <NavLink key={item.label} item={item} />
))} ))}
@@ -563,11 +523,8 @@ export function Navigation({ currentPage }: NavigationProps) {
{/* Right Side Actions */} {/* Right Side Actions */}
<div className="flex items-center gap-4"> <div className="flex items-center gap-4">
{/* Cart Icon - Always visible */}
<CartIcon /> <CartIcon />
{/* Authentication Button/Profile */}
{isAuthenticated && user ? ( {isAuthenticated && user ? (
<div className="hidden md:flex"> <div className="hidden md:flex">
<ProfileDropdown user={user} /> <ProfileDropdown user={user} />
@@ -575,7 +532,7 @@ export function Navigation({ currentPage }: NavigationProps) {
) : ( ) : (
<div className="hidden md:flex items-center"> <div className="hidden md:flex items-center">
<Button <Button
onClick={() => navigateTo('/leadership-journey')} onClick={() => navigate('/leadership-journey')}
className="management-dev-glassmorphic-btn text-body px-8 py-4 min-h-[52px] border transition-all duration-300 group" className="management-dev-glassmorphic-btn text-body px-8 py-4 min-h-[52px] border transition-all duration-300 group"
style={{ style={{
fontFamily: 'var(--font-family-base)', fontFamily: 'var(--font-family-base)',
@@ -609,13 +566,7 @@ export function Navigation({ currentPage }: NavigationProps) {
}} }}
> >
<SheetHeader> <SheetHeader>
<SheetTitle <SheetTitle>
style={{
fontSize: 'var(--font-h4)',
fontFamily: 'var(--font-family-base)',
color: 'var(--color-black)'
}}
>
Navigation Navigation
</SheetTitle> </SheetTitle>
</SheetHeader> </SheetHeader>
@@ -625,83 +576,14 @@ export function Navigation({ currentPage }: NavigationProps) {
))} ))}
<div className="pt-4 border-t space-y-3"> <div className="pt-4 border-t space-y-3">
{isAuthenticated && user ? ( {isAuthenticated && user ? (
<div className="space-y-3"> <div className="space-y-3">
<div {/* ... mobile user info and buttons with navigate() */}
className="flex items-center gap-3 p-3 rounded-lg"
style={{ backgroundColor: 'rgba(0, 0, 0, 0.05)' }}
>
<Avatar className="h-10 w-10">
<AvatarImage src={user.avatar} alt={user.name} />
<AvatarFallback style={{ fontFamily: 'var(--font-family-base)' }}>
{user.name.split(' ').map((n: string) => n[0]).join('')}
</AvatarFallback>
</Avatar>
<div>
<div
className="font-medium"
style={{
fontSize: '14px', // Reduced from var(--font-body) by 2px
fontWeight: '400',
fontFamily: 'var(--font-family-base)'
}}
>
{user.corporateName}
</div>
<div
style={{
fontSize: '12px', // Reduced from var(--font-small) by 2px
color: 'var(--color-gray-muted)',
fontFamily: 'var(--font-family-base)'
}}
>
{user.name}
</div>
</div>
</div>
<Button
variant="outline"
className="w-full justify-start min-h-[44px]"
onClick={() => navigateTo('/dashboard')}
style={{
fontSize: '14px', // Reduced from var(--font-body) by 2px
fontFamily: 'var(--font-family-base)'
}}
>
<LayoutDashboard className="w-4 h-4 mr-2" />
Dashboard
</Button>
<Button
variant="outline"
className="w-full justify-start min-h-[44px]"
onClick={() => navigateTo('/profile')}
style={{
fontSize: '14px', // Reduced from var(--font-body) by 2px
fontFamily: 'var(--font-family-base)'
}}
>
<User className="w-4 h-4 mr-2" />
Profile
</Button>
<Button
variant="outline"
className="w-full justify-start min-h-[44px]"
onClick={handleMobileSignOut}
style={{
fontSize: '14px', // Reduced from var(--font-body) by 2px
fontFamily: 'var(--font-family-base)',
color: 'var(--destructive)'
}}
>
<LogOut className="w-4 h-4 mr-2" />
Sign Out
</Button>
</div> </div>
) : ( ) : (
<div className="space-y-2"> <div className="space-y-2">
<Button <Button
onClick={() => navigateTo('/leadership-journey')} onClick={() => navigate('/leadership-journey')}
className="management-dev-glassmorphic-btn text-body px-8 py-4 min-h-[52px] border transition-all duration-300 w-full group" className="management-dev-glassmorphic-btn text-body px-8 py-4 min-h-[52px] border transition-all duration-300 w-full group"
style={{ style={{
fontFamily: 'var(--font-family-base)', fontFamily: 'var(--font-family-base)',

View File

@@ -31,7 +31,7 @@ export function SelfLearnerSignIn() {
setTimeout(() => { setTimeout(() => {
setIsLoading(false); setIsLoading(false);
// Navigate to dashboard or success page // Navigate to dashboard or success page
navigateTo('/dashboard'); navigateTo('https://klc-learner.wdiprojects.com');
}, 1500); }, 1500);
}; };

View File

@@ -48,7 +48,7 @@ export function SelfLearnerSignUp() {
setTimeout(() => { setTimeout(() => {
setIsLoading(false); setIsLoading(false);
// Navigate to dashboard or success page // Navigate to dashboard or success page
navigateTo('/dashboard'); navigateTo('https://klc-learner.wdiprojects.com');
}, 2000); }, 2000);
}; };

View File

@@ -114,7 +114,7 @@ export function StatsSection() {
{/* Mobile Statistics - Show below content on mobile/tablet */} {/* Mobile Statistics - Show below content on mobile/tablet */}
<div className="block lg:hidden mt-12"> <div className="block lg:hidden mt-12">
<div className="grid grid-cols-2 gap-6 sm:gap-8"> <div className="grid grid-cols-1 gap-6 md:grid-cols-2 sm:gap-8">
<StatItem <StatItem
end={27000} end={27000}
suffix="+" suffix="+"

View File

@@ -118,6 +118,7 @@ function FacilityCard({ facility, index, onBookNow }: FacilityCardProps) {
transition={{ duration: 0.7, delay: index * 0.15 }} transition={{ duration: 0.7, delay: index * 0.15 }}
viewport={{ once: true, margin: "-50px" }} viewport={{ once: true, margin: "-50px" }}
> >
{/* Background Image - Full Height */} {/* Background Image - Full Height */}
<div className="absolute inset-0"> <div className="absolute inset-0">
<ImageWithFallback <ImageWithFallback
@@ -148,7 +149,7 @@ function FacilityCard({ facility, index, onBookNow }: FacilityCardProps) {
</h3> </h3>
{/* Description */} {/* Description */}
<p className="text-white/90 leading-relaxed mb-6 text-base max-lg:text-sm text-center max-lg:mb-5"> <p className="text-white/90 leading-relaxed mb-6 text-base max-lg:text-sm text-center max-lg:mb-5 md:min-h-[110px]">
{facility.description} {facility.description}
</p> </p>
@@ -596,7 +597,7 @@ function BookingModal({
<Label htmlFor="role" className="text-xs font-normal text-black mb-1 block"> <Label htmlFor="role" className="text-xs font-normal text-black mb-1 block">
Your Role * Your Role *
</Label> </Label>
<Select value={bookingForm.role} onValueChange={(value) => updateFormField('role', value)}> <Select value={bookingForm.role} onValueChange={(value:string) => updateFormField('role', value)}>
<SelectTrigger className="h-8 text-sm border border-gray-300 rounded focus:border-primary focus:ring-1 focus:ring-primary/30 transition-all duration-200"> <SelectTrigger className="h-8 text-sm border border-gray-300 rounded focus:border-primary focus:ring-1 focus:ring-primary/30 transition-all duration-200">
<SelectValue placeholder="Role" className="text-gray-400 opacity-50" /> <SelectValue placeholder="Role" className="text-gray-400 opacity-50" />
</SelectTrigger> </SelectTrigger>
@@ -614,7 +615,7 @@ function BookingModal({
<Label htmlFor="teamSize" className="text-xs font-normal text-black mb-1 block"> <Label htmlFor="teamSize" className="text-xs font-normal text-black mb-1 block">
Expected Team Size * Expected Team Size *
</Label> </Label>
<Select value={bookingForm.teamSize} onValueChange={(value) => updateFormField('teamSize', value)}> <Select value={bookingForm.teamSize} onValueChange={(value:string) => updateFormField('teamSize', value)}>
<SelectTrigger className="h-8 text-sm border border-gray-300 rounded focus:border-primary focus:ring-1 focus:ring-primary/30 transition-all duration-200"> <SelectTrigger className="h-8 text-sm border border-gray-300 rounded focus:border-primary focus:ring-1 focus:ring-primary/30 transition-all duration-200">
<SelectValue placeholder="Size" className="text-gray-400 opacity-50" /> <SelectValue placeholder="Size" className="text-gray-400 opacity-50" />
</SelectTrigger> </SelectTrigger>
@@ -743,7 +744,7 @@ export function VirtualSpaceSection() {
return ( return (
<section className="relative overflow-hidden"> <section className="relative overflow-hidden">
{/* Full-Width Image Section with Overlaid Content */} {/* Full-Width Image Section with Overlaid Content */}
<div className="relative h-screen min-h-[600px] max-h-[800px]"> <div className="relative h-screen min-h-[700px] virtual-learn-sec">
{/* Facility Cards Grid - Single Row, Side by Side */} {/* Facility Cards Grid - Single Row, Side by Side */}
<div className="h-full grid grid-cols-4 max-lg:grid-cols-2 max-md:grid-cols-1"> <div className="h-full grid grid-cols-4 max-lg:grid-cols-2 max-md:grid-cols-1">
{facilities.map((facility, index) => ( {facilities.map((facility, index) => (
@@ -757,8 +758,8 @@ export function VirtualSpaceSection() {
</div> </div>
{/* Overlaid Content - Centered at top of image section */} {/* Overlaid Content - Centered at top of image section */}
<div className="absolute top-0 left-0 right-0 z-20 py-16 max-md:py-12 section-margin-x"> <div className="absolute top-0 left-0 right-0 z-20 py-16 max-md:py-12 section-margin-x ">
<div className="max-w-4xl mx-auto text-center"> <div className="max-w-4xl mx-auto text-center exp-our-head-desktop-sec">
{/* Branded Tag */} {/* Branded Tag */}
<motion.div <motion.div
initial={{ opacity: 0, y: -20 }} initial={{ opacity: 0, y: -20 }}
@@ -815,7 +816,7 @@ export function VirtualSpaceSection() {
</div> </div>
{/* Additional overlay for better text readability over images */} {/* Additional overlay for better text readability over images */}
<div className="absolute top-0 left-0 right-0 h-80 bg-gradient-to-b from-black/70 via-black/40 to-transparent z-10" /> <div className="absolute top-0 left-0 right-0 h-80 bg-gradient-to-b from-black/70 via-black/40 to-transparent z-10 exp-our-head-desktop-sec" />
</div> </div>
{/* Booking Modal */} {/* Booking Modal */}

View File

@@ -14,7 +14,7 @@ import { BrandedTag } from '../about/BrandedTag';
import { PrimaryCTAButton } from '../PrimaryCTAButton'; import { PrimaryCTAButton } from '../PrimaryCTAButton';
import { TestimonialsSection } from '../TestimonialsSection'; import { TestimonialsSection } from '../TestimonialsSection';
import { CTABannerSection } from '../CTABannerSection'; import { CTABannerSection } from '../CTABannerSection';
import { import {
ArrowRight, ArrowRight,
CheckCircle, CheckCircle,
Calendar, Calendar,
@@ -55,7 +55,7 @@ const offerings = [
features: ["4 fully-equipped halls", "Flexible seating arrangements", "Advanced AV systems", "Natural lighting"] features: ["4 fully-equipped halls", "Flexible seating arrangements", "Advanced AV systems", "Natural lighting"]
}, },
{ {
title: "Technology Infrastructure", title: "Technology Infrastructure",
description: "Cutting-edge technology to support modern learning and collaboration", description: "Cutting-edge technology to support modern learning and collaboration",
icon: Monitor, icon: Monitor,
features: ["High-speed connectivity", "Interactive displays", "Video conferencing", "Digital whiteboards"] features: ["High-speed connectivity", "Interactive displays", "Video conferencing", "Digital whiteboards"]
@@ -305,11 +305,11 @@ export function LearningFacility() {
// Facility Features Carousel state and functionality // Facility Features Carousel state and functionality
const [currentSlide, setCurrentSlide] = useState(0); const [currentSlide, setCurrentSlide] = useState(0);
const carouselRef = useRef<HTMLDivElement>(null); const carouselRef = useRef<HTMLDivElement>(null);
// Virtual Tour Carousel state and functionality // Virtual Tour Carousel state and functionality
const [currentTourSlide, setCurrentTourSlide] = useState(0); const [currentTourSlide, setCurrentTourSlide] = useState(0);
const tourCarouselRef = useRef<HTMLDivElement>(null); const tourCarouselRef = useRef<HTMLDivElement>(null);
// Responsive carousel settings // Responsive carousel settings
const getCarouselSettings = () => { const getCarouselSettings = () => {
if (typeof window !== 'undefined') { if (typeof window !== 'undefined') {
@@ -400,22 +400,22 @@ export function LearningFacility() {
useEffect(() => { useEffect(() => {
console.log('LearningFacility component mounted'); // Debug log console.log('LearningFacility component mounted'); // Debug log
window.scrollTo(0, 0); window.scrollTo(0, 0);
// Listen for custom booking modal event from CTAPopupModal // Listen for custom booking modal event from CTAPopupModal
const handleOpenBookingModal = () => { const handleOpenBookingModal = () => {
console.log('Custom booking modal event received'); // Debug log console.log('Custom booking modal event received'); // Debug log
setIsBookingModalOpen(true); setIsBookingModalOpen(true);
}; };
window.addEventListener('openBookingModal', handleOpenBookingModal); window.addEventListener('openBookingModal', handleOpenBookingModal);
// Also check if we should auto-open the booking modal based on URL parameters // Also check if we should auto-open the booking modal based on URL parameters
const urlParams = new URLSearchParams(window.location.search); const urlParams = new URLSearchParams(window.location.search);
if (urlParams.get('autoBooking') === 'true') { if (urlParams.get('autoBooking') === 'true') {
console.log('Auto-opening booking modal from URL parameter'); // Debug log console.log('Auto-opening booking modal from URL parameter'); // Debug log
setTimeout(() => setIsBookingModalOpen(true), 100); setTimeout(() => setIsBookingModalOpen(true), 100);
} }
return () => { return () => {
window.removeEventListener('openBookingModal', handleOpenBookingModal); window.removeEventListener('openBookingModal', handleOpenBookingModal);
}; };
@@ -456,12 +456,12 @@ export function LearningFacility() {
facilityZone: '', facilityZone: '',
additionalRequirements: '' additionalRequirements: ''
}); });
// Clean up URL parameter // Clean up URL parameter
const url = new URL(window.location.href); const url = new URL(window.location.href);
url.searchParams.delete('autoBooking'); url.searchParams.delete('autoBooking');
window.history.replaceState({}, '', url.toString()); window.history.replaceState({}, '', url.toString());
// Here you would typically send the booking request to your backend // Here you would typically send the booking request to your backend
alert('Booking request submitted successfully! We will contact you within 24 hours.'); alert('Booking request submitted successfully! We will contact you within 24 hours.');
}; };
@@ -469,7 +469,7 @@ export function LearningFacility() {
const handleBookingModalClose = (open: boolean) => { const handleBookingModalClose = (open: boolean) => {
console.log('Booking modal close triggered, open:', open); // Debug log console.log('Booking modal close triggered, open:', open); // Debug log
setIsBookingModalOpen(open); setIsBookingModalOpen(open);
if (!open) { if (!open) {
// Clean up URL parameter when closing // Clean up URL parameter when closing
const url = new URL(window.location.href); const url = new URL(window.location.href);
@@ -511,14 +511,14 @@ export function LearningFacility() {
</p> </p>
<div className="flex flex-col sm:flex-row gap-4 mb-12 justify-center"> <div className="flex flex-col sm:flex-row gap-4 mb-12 justify-center">
<PrimaryCTAButton <PrimaryCTAButton
text="Take Virtual Tour" text="Take Virtual Tour"
onClick={handleStartTour} onClick={handleStartTour}
ariaLabel="Take virtual tour" ariaLabel="Take virtual tour"
className="primary-cta-button-blue cta-text-white" className="primary-cta-button-blue cta-text-white"
/> />
<Button <Button
variant="outline" variant="outline"
onClick={() => { onClick={() => {
console.log('Book Facility button clicked'); console.log('Book Facility button clicked');
@@ -727,10 +727,10 @@ export function LearningFacility() {
audience.title.includes('Corporate') audience.title.includes('Corporate')
? 'https://images.unsplash.com/photo-1553877522-43269d4ea984?w=640&h=640&fit=crop' ? 'https://images.unsplash.com/photo-1553877522-43269d4ea984?w=640&h=640&fit=crop'
: audience.title.includes('Learning') : audience.title.includes('Learning')
? 'https://images.unsplash.com/photo-1523580846011-d3a5bc25702b?w=640&h=640&fit=crop' ? 'https://images.unsplash.com/photo-1523580846011-d3a5bc25702b?w=640&h=640&fit=crop'
: audience.title.includes('Professional') : audience.title.includes('Professional')
? 'https://images.unsplash.com/photo-1551836022-d5d88e9218df?w=640&h=640&fit=crop' ? 'https://images.unsplash.com/photo-1551836022-d5d88e9218df?w=640&h=640&fit=crop'
: 'https://images.unsplash.com/photo-1519389950473-47ba0277781c?w=640&h=640&fit=crop' : 'https://images.unsplash.com/photo-1519389950473-47ba0277781c?w=640&h=640&fit=crop'
} }
alt={`${audience.title} visual`} alt={`${audience.title} visual`}
className="w-full h-full object-cover" className="w-full h-full object-cover"
@@ -799,7 +799,7 @@ export function LearningFacility() {
Facility <span className="text-primary">Features</span> Facility <span className="text-primary">Features</span>
</h2> </h2>
<p className="text-body-lg text-muted leading-relaxed"> <p className="text-body-lg text-muted leading-relaxed">
Every aspect of our facility is designed to enhance learning outcomes Every aspect of our facility is designed to enhance learning outcomes
and provide an exceptional experience for participants and facilitators. and provide an exceptional experience for participants and facilitators.
</p> </p>
</div> </div>
@@ -837,7 +837,7 @@ export function LearningFacility() {
{/* Carousel Container */} {/* Carousel Container */}
<div className="overflow-hidden" style={{ paddingBottom: '80px' }}> <div className="overflow-hidden" style={{ paddingBottom: '80px' }}>
<div <div
ref={carouselRef} ref={carouselRef}
className="flex transition-transform duration-500 ease-in-out gap-6" className="flex transition-transform duration-500 ease-in-out gap-6"
style={{ transform: `translateX(-${currentSlide * slideWidth}%)` }} style={{ transform: `translateX(-${currentSlide * slideWidth}%)` }}
@@ -853,26 +853,26 @@ export function LearningFacility() {
feature.title.toLowerCase().includes('wifi') feature.title.toLowerCase().includes('wifi')
? 'https://images.unsplash.com/photo-1518770660439-4636190af475?w=480&h=320&fit=crop&auto=format&dpr=2' ? 'https://images.unsplash.com/photo-1518770660439-4636190af475?w=480&h=320&fit=crop&auto=format&dpr=2'
: feature.title.toLowerCase().includes('coffee') || feature.title.toLowerCase().includes('café') || feature.title.toLowerCase().includes('cafe') : feature.title.toLowerCase().includes('coffee') || feature.title.toLowerCase().includes('café') || feature.title.toLowerCase().includes('cafe')
? 'https://images.unsplash.com/photo-1495474472287-4d71bcdd2085?w=480&h=320&fit=crop&auto=format&dpr=2' ? 'https://images.unsplash.com/photo-1495474472287-4d71bcdd2085?w=480&h=320&fit=crop&auto=format&dpr=2'
: feature.title.toLowerCase().includes('parking') || feature.title.toLowerCase().includes('car') : feature.title.toLowerCase().includes('parking') || feature.title.toLowerCase().includes('car')
? 'https://images.unsplash.com/photo-1518306727298-4c17e1bf8cff?w=480&h=320&fit=crop&auto=format&dpr=2' ? 'https://images.unsplash.com/photo-1518306727298-4c17e1bf8cff?w=480&h=320&fit=crop&auto=format&dpr=2'
: feature.title.toLowerCase().includes('security') || feature.title.toLowerCase().includes('safety') : feature.title.toLowerCase().includes('security') || feature.title.toLowerCase().includes('safety')
? 'https://images.unsplash.com/photo-1583511655857-d19b40a7a54e?w=480&h=320&fit=crop&auto=format&dpr=2' ? 'https://images.unsplash.com/photo-1583511655857-d19b40a7a54e?w=480&h=320&fit=crop&auto=format&dpr=2'
: feature.title.toLowerCase().includes('bed') || feature.title.toLowerCase().includes('accommodation') || feature.title.toLowerCase().includes('stay') : feature.title.toLowerCase().includes('bed') || feature.title.toLowerCase().includes('accommodation') || feature.title.toLowerCase().includes('stay')
? 'https://images.unsplash.com/photo-1505691938895-1758d7feb511?w=480&h=320&fit=crop&auto=format&dpr=2' ? 'https://images.unsplash.com/photo-1505691938895-1758d7feb511?w=480&h=320&fit=crop&auto=format&dpr=2'
: feature.title.toLowerCase().includes('nature') || feature.title.toLowerCase().includes('outdoor') : feature.title.toLowerCase().includes('nature') || feature.title.toLowerCase().includes('outdoor')
? 'https://images.unsplash.com/photo-1501785888041-af3ef285b470?w=480&h=320&fit=crop&auto=format&dpr=2' ? 'https://images.unsplash.com/photo-1501785888041-af3ef285b470?w=480&h=320&fit=crop&auto=format&dpr=2'
: feature.title.toLowerCase().includes('meeting') || feature.title.toLowerCase().includes('room') || feature.title.toLowerCase().includes('facility') : feature.title.toLowerCase().includes('meeting') || feature.title.toLowerCase().includes('room') || feature.title.toLowerCase().includes('facility')
? 'https://images.unsplash.com/photo-1557800636-894a64c1696f?w=480&h=320&fit=crop&auto=format&dpr=2' ? 'https://images.unsplash.com/photo-1557800636-894a64c1696f?w=480&h=320&fit=crop&auto=format&dpr=2'
: 'https://images.unsplash.com/photo-1524758631624-e2822e304c36?w=480&h=320&fit=crop&auto=format&dpr=2' : 'https://images.unsplash.com/photo-1524758631624-e2822e304c36?w=480&h=320&fit=crop&auto=format&dpr=2'
} }
alt={`${feature.title} image`} alt={`${feature.title} image`}
className="w-full h-full object-cover" className="w-full h-full object-cover"
/> />
</div> </div>
<h3 className="text-h4 mb-4">{feature.title}</h3> <h3 className="text-h4 mb-4">{feature.title}</h3>
<p className="text-body text-muted mb-6">{feature.description}</p> <p className="text-body text-muted mb-6">{feature.description}</p>
<div className="space-y-2"> <div className="space-y-2">
@@ -901,66 +901,68 @@ export function LearningFacility() {
World-Class <span className="text-primary">Amenities</span> World-Class <span className="text-primary">Amenities</span>
</h2> </h2>
<p className="text-body-lg text-muted"> <p className="text-body-lg text-muted">
Premium amenities and services to ensure comfort, productivity, and an Premium amenities and services to ensure comfort, productivity, and an
exceptional learning environment for all participants. exceptional learning environment for all participants.
</p> </p>
</div> </div>
<div className="relative overflow-hidden w-screen" aria-label="Amenities ticker" style={{ marginLeft: 'calc(50% - 50vw)', marginRight: 'calc(50% - 50vw)' }}> </div>
<div className="flex items-stretch gap-4 whitespace-nowrap scroll-left" style={{ animationDuration: '35s' }}> <div className="relative w-full">
{[0,1].map((loop) => ( <div className="relative overflow-hidden">
<div key={`amenities-loop-${loop}`} className="flex items-stretch gap-4"> <div className="flex items-stretch gap-4 whitespace-nowrap scroll-left" style={{ animationDuration: '35s' }}>
{amenities.map((amenity, index) => { {[0, 1].map((loop) => (
const Icon = amenity.icon; <div key={`amenities-loop-${loop}`} className="flex items-stretch gap-4">
return ( {amenities.map((amenity, index) => {
<div const Icon = amenity.icon;
key={`amenity-row1-${loop}-${index}`} return (
className="flex items-center gap-4 rounded-lg p-4 shadow-sm border"
style={{ backgroundColor: 'var(--color-bg-white)' }}
>
<div <div
className="w-12 h-12 rounded-lg flex items-center justify-center flex-shrink-0" key={`amenity-row1-${loop}-${index}`}
style={{ backgroundColor: 'rgba(4, 4, 91, 0.1)' }} className="flex items-center gap-4 rounded-lg p-4 shadow-sm border"
style={{ backgroundColor: 'var(--color-bg-white)' }}
> >
<Icon className="w-6 h-6 text-primary" /> <div
className="w-12 h-12 rounded-lg flex items-center justify-center flex-shrink-0"
style={{ backgroundColor: 'rgba(4, 4, 91, 0.1)' }}
>
<Icon className="w-6 h-6 text-primary" />
</div>
<span className="text-body" style={{ fontWeight: 'var(--font-weight-subhead)' }}>
{amenity.name}
</span>
</div> </div>
<span className="text-body" style={{ fontWeight: 'var(--font-weight-subhead)' }}> );
{amenity.name} })}
</span> </div>
</div> ))}
); </div>
})} <div className="flex items-stretch gap-4 whitespace-nowrap scroll-right mt-4" style={{ animationDuration: '30s' }}>
</div> {[0, 1].map((loop) => (
))} <div key={`amenities-loop-bottom-${loop}`} className="flex items-stretch gap-4">
</div> {amenities.map((amenity, index) => {
<div className="flex items-stretch gap-4 whitespace-nowrap scroll-right mt-4" style={{ animationDuration: '30s' }}> const Icon = amenity.icon;
{[0,1].map((loop) => ( return (
<div key={`amenities-loop-bottom-${loop}`} className="flex items-stretch gap-4">
{amenities.map((amenity, index) => {
const Icon = amenity.icon;
return (
<div
key={`amenity-row2-${loop}-${index}`}
className="flex items-center gap-4 rounded-lg p-4 shadow-sm border"
style={{ backgroundColor: 'var(--color-bg-white)' }}
>
<div <div
className="w-12 h-12 rounded-lg flex items-center justify-center flex-shrink-0" key={`amenity-row2-${loop}-${index}`}
style={{ backgroundColor: 'rgba(4, 4, 91, 0.1)' }} className="flex items-center gap-4 rounded-lg p-4 shadow-sm border"
style={{ backgroundColor: 'var(--color-bg-white)' }}
> >
<Icon className="w-6 h-6 text-primary" /> <div
className="w-12 h-12 rounded-lg flex items-center justify-center flex-shrink-0"
style={{ backgroundColor: 'rgba(4, 4, 91, 0.1)' }}
>
<Icon className="w-6 h-6 text-primary" />
</div>
<span className="text-body" style={{ fontWeight: 'var(--font-weight-subhead)' }}>
{amenity.name}
</span>
</div> </div>
<span className="text-body" style={{ fontWeight: 'var(--font-weight-subhead)' }}> );
{amenity.name} })}
</span> </div>
</div> ))}
); </div>
})}
</div>
))}
</div> </div>
</div> </div>
</div>
</section> </section>
{/* Virtual Tour Section */} {/* Virtual Tour Section */}
@@ -1009,10 +1011,10 @@ export function LearningFacility() {
{/* Carousel Container */} {/* Carousel Container */}
<div className="relative overflow-hidden"> <div className="relative overflow-hidden">
<div <div
ref={tourCarouselRef} ref={tourCarouselRef}
className="flex transition-transform duration-700 ease-in-out" className="flex transition-transform duration-700 ease-in-out"
style={{ style={{
transform: `translateX(-${currentTourSlide * tourSlideWidth}%)`, transform: `translateX(-${currentTourSlide * tourSlideWidth}%)`,
width: `${(virtualTourStops.length / tourCardsPerView) * 100}%` width: `${(virtualTourStops.length / tourCardsPerView) * 100}%`
}} }}
@@ -1071,7 +1073,7 @@ export function LearningFacility() {
Preview complete? Launch the full interactive tour to navigate each zone. Preview complete? Launch the full interactive tour to navigate each zone.
</div> </div>
<div className="hero-slide-button"> <div className="hero-slide-button">
<PrimaryCTAButton <PrimaryCTAButton
text="Start Interactive Tour" text="Start Interactive Tour"
onClick={handleStartTour} onClick={handleStartTour}
ariaLabel="Start interactive virtual tour" ariaLabel="Start interactive virtual tour"
@@ -1085,7 +1087,7 @@ export function LearningFacility() {
<div className="max-w-6xl mx-auto"> <div className="max-w-6xl mx-auto">
{/* Tour Header */} {/* Tour Header */}
<div className="text-center mb-8"> <div className="text-center mb-8">
<Badge <Badge
className="text-small px-4 py-2 mb-4" className="text-small px-4 py-2 mb-4"
style={{ style={{
backgroundColor: 'rgba(4, 4, 91, 0.1)', backgroundColor: 'rgba(4, 4, 91, 0.1)',
@@ -1112,7 +1114,7 @@ export function LearningFacility() {
className="w-full h-full object-cover" className="w-full h-full object-cover"
/> />
</div> </div>
{/* Navigation Arrows */} {/* Navigation Arrows */}
<button <button
onClick={handlePrevStop} onClick={handlePrevStop}
@@ -1121,7 +1123,7 @@ export function LearningFacility() {
> >
<ChevronLeft className="w-6 h-6" /> <ChevronLeft className="w-6 h-6" />
</button> </button>
<button <button
onClick={handleNextStop} onClick={handleNextStop}
disabled={currentTourStop === virtualTourStops.length - 1} disabled={currentTourStop === virtualTourStops.length - 1}
@@ -1181,11 +1183,10 @@ export function LearningFacility() {
<button <button
key={index} key={index}
onClick={() => handleJumpToStop(index)} onClick={() => handleJumpToStop(index)}
className={`w-3 h-3 rounded-full transition-all ${ className={`w-3 h-3 rounded-full transition-all ${index === currentTourStop
index === currentTourStop ? 'bg-primary w-8'
? 'bg-primary w-8' : 'bg-gray-300 hover:bg-gray-400'
: 'bg-gray-300 hover:bg-gray-400' }`}
}`}
/> />
))} ))}
</div> </div>
@@ -1211,7 +1212,7 @@ export function LearningFacility() {
<> <>
<DialogHeader className="pb-6"> <DialogHeader className="pb-6">
<div className="text-center space-y-4"> <div className="text-center space-y-4">
<div <div
className="w-20 h-20 rounded-2xl flex items-center justify-center mx-auto" className="w-20 h-20 rounded-2xl flex items-center justify-center mx-auto"
style={{ backgroundColor: 'rgba(4, 4, 91, 0.1)' }} style={{ backgroundColor: 'rgba(4, 4, 91, 0.1)' }}
> >
@@ -1235,7 +1236,7 @@ export function LearningFacility() {
className="w-full h-full object-cover" className="w-full h-full object-cover"
/> />
<div className="absolute top-6 left-6"> <div className="absolute top-6 left-6">
<Badge <Badge
className="text-body px-4 py-2" className="text-body px-4 py-2"
style={{ style={{
backgroundColor: 'var(--color-accent)', backgroundColor: 'var(--color-accent)',
@@ -1295,7 +1296,7 @@ export function LearningFacility() {
Submit your facility booking request with your preferred dates, team size, and specific requirements. We'll contact you within 24 hours to confirm availability and discuss details. Submit your facility booking request with your preferred dates, team size, and specific requirements. We'll contact you within 24 hours to confirm availability and discuss details.
</DialogDescription> </DialogDescription>
</DialogHeader> </DialogHeader>
<form onSubmit={handleBookingSubmit} className="space-y-4 pt-4"> <form onSubmit={handleBookingSubmit} className="space-y-4 pt-4">
<div className="grid grid-cols-2 gap-4"> <div className="grid grid-cols-2 gap-4">
<div> <div>
@@ -1303,7 +1304,7 @@ export function LearningFacility() {
<Input <Input
id="companyName" id="companyName"
value={bookingForm.companyName} value={bookingForm.companyName}
onChange={(e) => setBookingForm({...bookingForm, companyName: e.target.value})} onChange={(e) => setBookingForm({ ...bookingForm, companyName: e.target.value })}
required required
/> />
</div> </div>
@@ -1312,7 +1313,7 @@ export function LearningFacility() {
<Input <Input
id="contactName" id="contactName"
value={bookingForm.contactName} value={bookingForm.contactName}
onChange={(e) => setBookingForm({...bookingForm, contactName: e.target.value})} onChange={(e) => setBookingForm({ ...bookingForm, contactName: e.target.value })}
required required
/> />
</div> </div>
@@ -1325,7 +1326,7 @@ export function LearningFacility() {
id="email" id="email"
type="email" type="email"
value={bookingForm.email} value={bookingForm.email}
onChange={(e) => setBookingForm({...bookingForm, email: e.target.value})} onChange={(e) => setBookingForm({ ...bookingForm, email: e.target.value })}
required required
/> />
</div> </div>
@@ -1334,7 +1335,7 @@ export function LearningFacility() {
<Input <Input
id="phone" id="phone"
value={bookingForm.phone} value={bookingForm.phone}
onChange={(e) => setBookingForm({...bookingForm, phone: e.target.value})} onChange={(e) => setBookingForm({ ...bookingForm, phone: e.target.value })}
required required
/> />
</div> </div>
@@ -1346,13 +1347,13 @@ export function LearningFacility() {
<Input <Input
id="role" id="role"
value={bookingForm.role} value={bookingForm.role}
onChange={(e) => setBookingForm({...bookingForm, role: e.target.value})} onChange={(e) => setBookingForm({ ...bookingForm, role: e.target.value })}
required required
/> />
</div> </div>
<div> <div>
<Label htmlFor="teamSize">Team Size</Label> <Label htmlFor="teamSize">Team Size</Label>
<Select value={bookingForm.teamSize} onValueChange={(value) => setBookingForm({...bookingForm, teamSize: value})}> <Select value={bookingForm.teamSize} onValueChange={(value) => setBookingForm({ ...bookingForm, teamSize: value })}>
<SelectTrigger> <SelectTrigger>
<SelectValue placeholder="Select size" /> <SelectValue placeholder="Select size" />
</SelectTrigger> </SelectTrigger>
@@ -1369,7 +1370,7 @@ export function LearningFacility() {
<div> <div>
<Label htmlFor="facilityZone">Preferred Zone</Label> <Label htmlFor="facilityZone">Preferred Zone</Label>
<Select value={bookingForm.facilityZone} onValueChange={(value) => setBookingForm({...bookingForm, facilityZone: value})}> <Select value={bookingForm.facilityZone} onValueChange={(value) => setBookingForm({ ...bookingForm, facilityZone: value })}>
<SelectTrigger> <SelectTrigger>
<SelectValue placeholder="Select zone" /> <SelectValue placeholder="Select zone" />
</SelectTrigger> </SelectTrigger>
@@ -1388,7 +1389,7 @@ export function LearningFacility() {
<Textarea <Textarea
id="requirements" id="requirements"
value={bookingForm.additionalRequirements} value={bookingForm.additionalRequirements}
onChange={(e) => setBookingForm({...bookingForm, additionalRequirements: e.target.value})} onChange={(e) => setBookingForm({ ...bookingForm, additionalRequirements: e.target.value })}
placeholder="Tell us about your event, special requirements, catering needs, etc." placeholder="Tell us about your event, special requirements, catering needs, etc."
rows={3} rows={3}
/> />
@@ -1426,7 +1427,7 @@ export function LearningFacility() {
Submit your booking request and we'll get back to you within 24 hours to confirm availability and discuss your requirements. Submit your booking request and we'll get back to you within 24 hours to confirm availability and discuss your requirements.
</DialogDescription> </DialogDescription>
</DialogHeader> </DialogHeader>
<form onSubmit={handleBookingSubmit} className="space-y-6 mt-6"> <form onSubmit={handleBookingSubmit} className="space-y-6 mt-6">
<div className="grid md:grid-cols-2 gap-4"> <div className="grid md:grid-cols-2 gap-4">
<div className="space-y-2"> <div className="space-y-2">
@@ -1434,26 +1435,26 @@ export function LearningFacility() {
<Input <Input
id="companyName" id="companyName"
value={bookingForm.companyName} value={bookingForm.companyName}
onChange={(e) => setBookingForm({...bookingForm, companyName: e.target.value})} onChange={(e) => setBookingForm({ ...bookingForm, companyName: e.target.value })}
placeholder="Enter company name" placeholder="Enter company name"
required required
className="text-body" className="text-body"
/> />
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<Label htmlFor="contactName" className="text-body font-medium">Contact Person *</Label> <Label htmlFor="contactName" className="text-body font-medium">Contact Person *</Label>
<Input <Input
id="contactName" id="contactName"
value={bookingForm.contactName} value={bookingForm.contactName}
onChange={(e) => setBookingForm({...bookingForm, contactName: e.target.value})} onChange={(e) => setBookingForm({ ...bookingForm, contactName: e.target.value })}
placeholder="Enter your full name" placeholder="Enter your full name"
required required
className="text-body" className="text-body"
/> />
</div> </div>
</div> </div>
<div className="grid md:grid-cols-2 gap-4"> <div className="grid md:grid-cols-2 gap-4">
<div className="space-y-2"> <div className="space-y-2">
<Label htmlFor="email" className="text-body font-medium">Email Address *</Label> <Label htmlFor="email" className="text-body font-medium">Email Address *</Label>
@@ -1461,40 +1462,40 @@ export function LearningFacility() {
id="email" id="email"
type="email" type="email"
value={bookingForm.email} value={bookingForm.email}
onChange={(e) => setBookingForm({...bookingForm, email: e.target.value})} onChange={(e) => setBookingForm({ ...bookingForm, email: e.target.value })}
placeholder="your.email@company.com" placeholder="your.email@company.com"
required required
className="text-body" className="text-body"
/> />
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<Label htmlFor="phone" className="text-body font-medium">Phone Number</Label> <Label htmlFor="phone" className="text-body font-medium">Phone Number</Label>
<Input <Input
id="phone" id="phone"
value={bookingForm.phone} value={bookingForm.phone}
onChange={(e) => setBookingForm({...bookingForm, phone: e.target.value})} onChange={(e) => setBookingForm({ ...bookingForm, phone: e.target.value })}
placeholder="+1 (555) 123-4567" placeholder="+1 (555) 123-4567"
className="text-body" className="text-body"
/> />
</div> </div>
</div> </div>
<div className="grid md:grid-cols-2 gap-4"> <div className="grid md:grid-cols-2 gap-4">
<div className="space-y-2"> <div className="space-y-2">
<Label htmlFor="role" className="text-body font-medium">Your Role/Position</Label> <Label htmlFor="role" className="text-body font-medium">Your Role/Position</Label>
<Input <Input
id="role" id="role"
value={bookingForm.role} value={bookingForm.role}
onChange={(e) => setBookingForm({...bookingForm, role: e.target.value})} onChange={(e) => setBookingForm({ ...bookingForm, role: e.target.value })}
placeholder="e.g., Training Manager, HR Director" placeholder="e.g., Training Manager, HR Director"
className="text-body" className="text-body"
/> />
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<Label htmlFor="teamSize" className="text-body font-medium">Expected Group Size *</Label> <Label htmlFor="teamSize" className="text-body font-medium">Expected Group Size *</Label>
<Select value={bookingForm.teamSize} onValueChange={(value) => setBookingForm({...bookingForm, teamSize: value})}> <Select value={bookingForm.teamSize} onValueChange={(value) => setBookingForm({ ...bookingForm, teamSize: value })}>
<SelectTrigger className="text-body"> <SelectTrigger className="text-body">
<SelectValue placeholder="Select group size" /> <SelectValue placeholder="Select group size" />
</SelectTrigger> </SelectTrigger>
@@ -1508,10 +1509,10 @@ export function LearningFacility() {
</Select> </Select>
</div> </div>
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<Label htmlFor="facilityZone" className="text-body font-medium">Preferred Learning Zone</Label> <Label htmlFor="facilityZone" className="text-body font-medium">Preferred Learning Zone</Label>
<Select value={bookingForm.facilityZone} onValueChange={(value) => setBookingForm({...bookingForm, facilityZone: value})}> <Select value={bookingForm.facilityZone} onValueChange={(value) => setBookingForm({ ...bookingForm, facilityZone: value })}>
<SelectTrigger className="text-body"> <SelectTrigger className="text-body">
<SelectValue placeholder="Select preferred zone (optional)" /> <SelectValue placeholder="Select preferred zone (optional)" />
</SelectTrigger> </SelectTrigger>
@@ -1524,29 +1525,29 @@ export function LearningFacility() {
</SelectContent> </SelectContent>
</Select> </Select>
</div> </div>
<div className="space-y-2"> <div className="space-y-2">
<Label htmlFor="requirements" className="text-body font-medium">Additional Requirements</Label> <Label htmlFor="requirements" className="text-body font-medium">Additional Requirements</Label>
<Textarea <Textarea
id="requirements" id="requirements"
value={bookingForm.additionalRequirements} value={bookingForm.additionalRequirements}
onChange={(e) => setBookingForm({...bookingForm, additionalRequirements: e.target.value})} onChange={(e) => setBookingForm({ ...bookingForm, additionalRequirements: e.target.value })}
placeholder="Please share any specific requirements, preferred dates, catering needs, accommodation requirements, etc." placeholder="Please share any specific requirements, preferred dates, catering needs, accommodation requirements, etc."
rows={4} rows={4}
className="text-body resize-none" className="text-body resize-none"
/> />
</div> </div>
<div className="flex flex-col sm:flex-row gap-3 justify-end pt-4"> <div className="flex flex-col sm:flex-row gap-3 justify-end pt-4">
<Button <Button
type="button" type="button"
variant="outline" variant="outline"
onClick={() => setIsBookingModalOpen(false)} onClick={() => setIsBookingModalOpen(false)}
className="text-body" className="text-body"
> >
Cancel Cancel
</Button> </Button>
<Button <Button
type="submit" type="submit"
className="text-body px-8" className="text-body px-8"
style={{ style={{
@@ -1564,7 +1565,7 @@ export function LearningFacility() {
</Dialog> </Dialog>
{/* Testimonials Section - Using home page testimonials with custom headers */} {/* Testimonials Section - Using home page testimonials with custom headers */}
<TestimonialsSection <TestimonialsSection
title="Guest Experiences" title="Guest Experiences"
subtitle="Hear from clients and partners who have experienced the transformational power of our purpose-built learning environment." subtitle="Hear from clients and partners who have experienced the transformational power of our purpose-built learning environment."
tagText="Facility Excellence" tagText="Facility Excellence"

26
src/global.d.ts vendored Normal file
View File

@@ -0,0 +1,26 @@
// declarations.d.ts
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" {
import * as React from "react";
const ReactComponent: React.FunctionComponent<
React.SVGProps<SVGSVGElement> & { title?: string }
>;
export { ReactComponent };
const src: string;
export default src;
}

93
src/pages/HomePage.tsx Normal file
View File

@@ -0,0 +1,93 @@
import React from 'react';
import HeroSection from '../components/HeroSection';
import { StatsSection } from '../components/StatsSection';
import { LogosSection } from '../components/LogosSection';
import { ServicesSection } from '../components/ServicesSection';
import { VirtualSpaceSection } from '../components/VirtualSpaceSection';
import { TestimonialsSection } from '../components/TestimonialsSection';
import { UpcomingWebinarsSection } from '../components/UpcomingWebinarsSection';
import { InsightsSection } from '../components/InsightsSection';
import { WhitepapersSection } from '../components/WhitepapersSection';
import { CTABannerSection } from '../components/CTABannerSection';
import { motion } from "motion/react";
import { PrimaryCTAButton } from '../components/PrimaryCTAButton';
import { BrandedTag } from '../components/about/BrandedTag';
import { useNavigate } from 'react-router-dom';
const HomePage: React.FC = () => {
const navigate = useNavigate();
return (
<>
<HeroSection />
<StatsSection />
<LogosSection />
<ServicesSection />
<div>
<div className="mx-auto text-center py-16 px-4 bg-gradient-to-r from-blue-900 via-gray-400 to-black exp-our-head-tab-sec" >
{/* Branded Tag */}
<motion.div
initial={{ opacity: 0, y: -20 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.6 }}
viewport={{ once: true }}
>
<BrandedTag
text="Virtual Learning Environment"
className="justify-center"
variant="white"
/>
</motion.div>
{/* Main Heading */}
<motion.h2
className="text-5xl font-bold leading-tight mb-4 max-lg:text-4xl max-md:text-3xl text-white"
initial={{ opacity: 0, y: 30 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8, delay: 0.2 }}
viewport={{ once: true }}
>
Experience Our Space Virtually
</motion.h2>
{/* Subheading */}
<motion.p
className="text-lg leading-relaxed max-w-2xl mx-auto max-lg:text-base mb-6 text-white/90"
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8, delay: 0.4 }}
viewport={{ once: true }}
>
Take a virtual walk through our state-of-the-art facility designed to inspire leadership excellence and foster collaborative learning.
</motion.p>
{/* Main CTA Button - Explore Our Space */}
<motion.div
className="flex justify-center"
initial={{ opacity: 0, y: 20 }}
whileInView={{ opacity: 1, y: 0 }}
transition={{ duration: 0.8, delay: 0.6 }}
viewport={{ once: true }}
>
<div className="hero-slide-button">
<PrimaryCTAButton
text="Explore Our Space"
onClick={() => navigate('/services/learning-facility')}
ariaLabel="Explore our virtual learning space and facilities"
/>
</div>
</motion.div>
</div>
<VirtualSpaceSection />
</div>
<TestimonialsSection />
<UpcomingWebinarsSection />
<InsightsSection />
<WhitepapersSection />
<CTABannerSection />
</>
);
};
export default HomePage;

File diff suppressed because it is too large Load Diff

21
tsconfig.json Normal file
View File

@@ -0,0 +1,21 @@
{
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": false,
"skipLibCheck": true,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "ESNext",
"moduleResolution": "Node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}

8
tsconfig.node.json Normal file
View File

@@ -0,0 +1,8 @@
{
"compilerOptions": {
"composite": true,
"module": "ESNext",
"moduleResolution": "Node"
},
"include": ["vite.config.ts"]
}