pagination added in artical and other changes
This commit is contained in:
@@ -1,9 +1,9 @@
|
||||
import React, { useState } from "react";
|
||||
import { motion } from "motion/react";
|
||||
import {
|
||||
Building,
|
||||
Users,
|
||||
Presentation,
|
||||
import {
|
||||
Building,
|
||||
Users,
|
||||
Presentation,
|
||||
Coffee,
|
||||
Play,
|
||||
Calendar,
|
||||
@@ -22,7 +22,7 @@ import { Label } from "./ui/label";
|
||||
import { Textarea } from "./ui/textarea";
|
||||
import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from "./ui/select";
|
||||
import { navigateTo } from "./Router";
|
||||
|
||||
import kautilya from "../assets/Kautilya.png";
|
||||
// Calendar helper functions
|
||||
const getDaysInMonth = (date: Date) => {
|
||||
return new Date(date.getFullYear(), date.getMonth() + 1, 0).getDate();
|
||||
@@ -41,7 +41,7 @@ const isDateAvailable = (date: Date) => {
|
||||
today.setHours(0, 0, 0, 0);
|
||||
const selectedDate = new Date(date);
|
||||
selectedDate.setHours(0, 0, 0, 0);
|
||||
|
||||
|
||||
// Available if it's today or in the future, and not a Sunday
|
||||
return selectedDate >= today && selectedDate.getDay() !== 0;
|
||||
};
|
||||
@@ -117,7 +117,7 @@ function FacilityCard({ facility, index }: FacilityCardProps) {
|
||||
transition={{ duration: 0.7, delay: index * 0.15 }}
|
||||
viewport={{ once: true, margin: "-50px" }}
|
||||
>
|
||||
|
||||
|
||||
{/* Background Image - Full Height */}
|
||||
<div className="absolute inset-0">
|
||||
<ImageWithFallback
|
||||
@@ -133,10 +133,10 @@ function FacilityCard({ facility, index }: FacilityCardProps) {
|
||||
<div className="relative z-10 h-full flex flex-col justify-end p-8 max-lg:p-6">
|
||||
{/* Icon */}
|
||||
<div className="flex justify-center mb-4">
|
||||
<div
|
||||
<div
|
||||
className="w-16 h-16 rounded-2xl flex items-center justify-center bg-white/20 backdrop-blur-sm border border-white/30"
|
||||
>
|
||||
<IconComponent
|
||||
<IconComponent
|
||||
className="w-8 h-8 text-white"
|
||||
/>
|
||||
</div>
|
||||
@@ -164,14 +164,14 @@ function FacilityCard({ facility, index }: FacilityCardProps) {
|
||||
}
|
||||
|
||||
// Modal Component for Virtual Tour and Booking
|
||||
function BookingModal({
|
||||
facility,
|
||||
isOpen,
|
||||
onClose
|
||||
}: {
|
||||
facility: typeof facilities[0] | null;
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
function BookingModal({
|
||||
facility,
|
||||
isOpen,
|
||||
onClose
|
||||
}: {
|
||||
facility: typeof facilities[0] | null;
|
||||
isOpen: boolean;
|
||||
onClose: () => void;
|
||||
}) {
|
||||
const [bookingForm, setBookingForm] = useState<BookingFormData>({
|
||||
companyName: '',
|
||||
@@ -257,7 +257,7 @@ function BookingModal({
|
||||
for (let day = 1; day <= daysInMonth; day++) {
|
||||
const date = new Date(currentMonth.getFullYear(), currentMonth.getMonth(), day);
|
||||
const isAvailable = isDateAvailable(date);
|
||||
const isSelected = selectedDate &&
|
||||
const isSelected = selectedDate &&
|
||||
date.getFullYear() === selectedDate.getFullYear() &&
|
||||
date.getMonth() === selectedDate.getMonth() &&
|
||||
date.getDate() === selectedDate.getDate();
|
||||
@@ -325,7 +325,7 @@ function BookingModal({
|
||||
</div>
|
||||
|
||||
{/* Calendar Footer - Compact */}
|
||||
<div className="pt-2 border-t border-gray-200">
|
||||
{/* <div className="pt-2 border-t border-gray-200">
|
||||
<div className="flex items-center justify-center gap-3 text-xs text-gray-500">
|
||||
<div className="flex items-center gap-1">
|
||||
<div className="w-2 h-2 rounded-full bg-primary"></div>
|
||||
@@ -336,7 +336,7 @@ function BookingModal({
|
||||
<span>Available</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div> */}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
@@ -344,21 +344,21 @@ function BookingModal({
|
||||
if (!isOpen || !facility) return null;
|
||||
|
||||
return (
|
||||
<div
|
||||
<div
|
||||
className="fixed inset-0 bg-black/60 flex items-center justify-center p-2 lg:p-4 z-popup-modal virtual-space-modal-overlay"
|
||||
onClick={onClose}
|
||||
>
|
||||
<div
|
||||
<div
|
||||
className="bg-white rounded-xl lg:rounded-2xl max-w-5xl w-full h-[85vh] overflow-hidden virtual-space-modal-container flex flex-col"
|
||||
onClick={(e) => e.stopPropagation()}
|
||||
>
|
||||
{/* Modal Header - Compact */}
|
||||
<div
|
||||
<div
|
||||
className="flex items-center justify-between p-4 lg:p-6 border-b flex-shrink-0"
|
||||
style={{ backgroundColor: 'rgba(4, 4, 91, 0.02)' }}
|
||||
>
|
||||
<div className="flex items-center gap-3 lg:gap-4">
|
||||
<div
|
||||
<div
|
||||
className="w-10 h-10 lg:w-12 lg:h-12 rounded-lg flex items-center justify-center"
|
||||
style={{ backgroundColor: 'var(--color-primary)' }}
|
||||
>
|
||||
@@ -394,7 +394,7 @@ function BookingModal({
|
||||
<Play className="w-4 h-4 text-primary" />
|
||||
<h3 className="text-small lg:text-body font-semibold">Virtual Tour</h3>
|
||||
</div>
|
||||
|
||||
|
||||
{/* Virtual Tour Container - Developer-Ready for 360 Viewer or Video */}
|
||||
<div className="aspect-video rounded-lg overflow-hidden bg-gray-100 shadow-md relative">
|
||||
{/*
|
||||
@@ -409,7 +409,7 @@ function BookingModal({
|
||||
Current implementation: Fallback video iframe
|
||||
Replace the entire div below with your 360 viewer component
|
||||
*/}
|
||||
<div
|
||||
<div
|
||||
id={`virtual-tour-container-${facility.id}`}
|
||||
className="w-full h-full relative"
|
||||
data-facility-id={facility.id}
|
||||
@@ -417,35 +417,22 @@ function BookingModal({
|
||||
data-tour-type="360-viewer" // Change to "video" for video fallback
|
||||
>
|
||||
{/* Fallback: Video iframe - Replace this entire section with 360 viewer */}
|
||||
<iframe
|
||||
{/* <iframe
|
||||
src={facility.videoUrl}
|
||||
title={`${facility.name} Virtual Tour`}
|
||||
className="w-full h-full"
|
||||
allowFullScreen
|
||||
frameBorder="0"
|
||||
/> */}
|
||||
|
||||
<ImageWithFallback
|
||||
src={kautilya}
|
||||
alt={`${facility.name} Virtual Tour`}
|
||||
className="w-full h-full object-cover"
|
||||
/>
|
||||
|
||||
{/* 360 Viewer Placeholder - Remove iframe above and uncomment/implement below */}
|
||||
{/*
|
||||
Example A-Frame 360 implementation:
|
||||
<a-scene
|
||||
embedded
|
||||
style={{width: '100%', height: '100%'}}
|
||||
vr-mode-ui="enabled: false"
|
||||
>
|
||||
<a-sky src={facility.panoramaUrl || facility.image} />
|
||||
<a-camera wasd-controls-enabled="false" look-controls="enabled: true" />
|
||||
</a-scene>
|
||||
*/}
|
||||
|
||||
{/* Alternative: Custom 360 Photo Viewer Container */}
|
||||
{/*
|
||||
<div className="w-full h-full" id={`pannellum-${facility.id}`}>
|
||||
// Pannellum or other 360 viewer initialization
|
||||
</div>
|
||||
*/}
|
||||
|
||||
</div>
|
||||
|
||||
|
||||
{/* Interactive Controls Overlay (optional) */}
|
||||
<div className="absolute bottom-2 left-2 right-2 flex justify-between items-center pointer-events-none">
|
||||
<div className="bg-black/20 backdrop-blur-sm rounded px-2 py-1">
|
||||
@@ -457,7 +444,7 @@ function BookingModal({
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
{/* Compact Info Section */}
|
||||
<div className="flex-1 min-h-0 space-y-2 lg:space-y-3">
|
||||
{/* About - Compact */}
|
||||
@@ -467,14 +454,14 @@ function BookingModal({
|
||||
{facility.description}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
|
||||
{/* Features - Compact */}
|
||||
<div className="bg-gray-50 rounded-lg p-2 lg:p-3">
|
||||
<h4 className="text-small font-semibold mb-2">Key Features</h4>
|
||||
<div className="space-y-1">
|
||||
{facility.features.slice(0, 3).map((feature, index) => (
|
||||
<div key={index} className="flex items-center gap-2">
|
||||
<div
|
||||
<div
|
||||
className="w-1.5 h-1.5 rounded-full flex-shrink-0"
|
||||
style={{ backgroundColor: 'var(--color-primary)' }}
|
||||
/>
|
||||
@@ -526,7 +513,7 @@ function BookingModal({
|
||||
<h4 className="text-small font-medium text-primary">Company Information</h4>
|
||||
<div className="w-10 h-0.5 bg-primary"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="space-y-2">
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-2">
|
||||
<div>
|
||||
@@ -556,7 +543,7 @@ function BookingModal({
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-2">
|
||||
<div>
|
||||
<Label htmlFor="email" className="text-xs font-normal text-black mb-1 block">
|
||||
@@ -586,13 +573,13 @@ function BookingModal({
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="grid grid-cols-1 lg:grid-cols-2 gap-2">
|
||||
<div>
|
||||
<Label htmlFor="role" className="text-xs font-normal text-black mb-1 block">
|
||||
Your Role *
|
||||
</Label>
|
||||
<Select value={bookingForm.role} onValueChange={(value:string) => 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">
|
||||
<SelectValue placeholder="Role" className="text-gray-400 opacity-50" />
|
||||
</SelectTrigger>
|
||||
@@ -610,7 +597,7 @@ function BookingModal({
|
||||
<Label htmlFor="teamSize" className="text-xs font-normal text-black mb-1 block">
|
||||
Expected Team Size *
|
||||
</Label>
|
||||
<Select value={bookingForm.teamSize} onValueChange={(value:string) => 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">
|
||||
<SelectValue placeholder="Size" className="text-gray-400 opacity-50" />
|
||||
</SelectTrigger>
|
||||
@@ -633,7 +620,7 @@ function BookingModal({
|
||||
<h4 className="text-small font-medium text-primary">Select Your Date</h4>
|
||||
<div className="w-10 h-0.5 bg-primary"></div>
|
||||
</div>
|
||||
|
||||
|
||||
<div className="space-y-3">
|
||||
{/* Selected Facility Info */}
|
||||
{/* <div className="bg-blue-50 rounded p-2 border border-blue-100">
|
||||
@@ -662,8 +649,8 @@ function BookingModal({
|
||||
<div className="flex items-center gap-2">
|
||||
<Calendar className="w-3 h-3 text-green-600" />
|
||||
<span className="text-xs font-medium text-green-800">
|
||||
Selected: {selectedDate.toLocaleDateString('en-US', {
|
||||
month: 'short',
|
||||
Selected: {selectedDate.toLocaleDateString('en-US', {
|
||||
month: 'short',
|
||||
day: 'numeric',
|
||||
year: 'numeric'
|
||||
})}
|
||||
@@ -672,7 +659,7 @@ function BookingModal({
|
||||
</div>
|
||||
)}
|
||||
</div>
|
||||
|
||||
|
||||
{/* Additional Requirements */}
|
||||
<div>
|
||||
<Label htmlFor="additionalRequirements" className="text-xs font-normal text-black mb-1 block">
|
||||
@@ -756,21 +743,21 @@ export function VirtualSpaceSection() {
|
||||
<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 exp-our-head-desktop-sec">
|
||||
{/* Branded Tag */}
|
||||
<motion.div
|
||||
<motion.div
|
||||
initial={{ opacity: 0, y: -20 }}
|
||||
whileInView={{ opacity: 1, y: 0 }}
|
||||
transition={{ duration: 0.6 }}
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<BrandedTag
|
||||
text="Virtual Learning Environment"
|
||||
<BrandedTag
|
||||
text="Virtual Learning Environment"
|
||||
className="justify-center"
|
||||
variant="white"
|
||||
/>
|
||||
</motion.div>
|
||||
|
||||
{/* Main Heading */}
|
||||
<motion.h2
|
||||
<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 }}
|
||||
@@ -781,7 +768,7 @@ export function VirtualSpaceSection() {
|
||||
</motion.h2>
|
||||
|
||||
{/* Subheading */}
|
||||
<motion.p
|
||||
<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 }}
|
||||
@@ -800,7 +787,7 @@ export function VirtualSpaceSection() {
|
||||
viewport={{ once: true }}
|
||||
>
|
||||
<div className="hero-slide-button">
|
||||
<PrimaryCTAButton
|
||||
<PrimaryCTAButton
|
||||
text="Book Now"
|
||||
onClick={handleBookNow}
|
||||
ariaLabel="Book our virtual learning space and facilities"
|
||||
@@ -815,7 +802,7 @@ export function VirtualSpaceSection() {
|
||||
</div>
|
||||
|
||||
{/* Booking Modal */}
|
||||
<BookingModal
|
||||
<BookingModal
|
||||
facility={selectedFacility}
|
||||
isOpen={isModalOpen}
|
||||
onClose={handleCloseModal}
|
||||
|
||||
Reference in New Issue
Block a user