pagination added in artical and other changes

This commit is contained in:
priyanshuvish
2025-09-30 15:56:17 +05:30
parent c67ace8edb
commit 7b8fe79917
11 changed files with 2369 additions and 934 deletions

View File

@@ -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}