636 lines
37 KiB
TypeScript
636 lines
37 KiB
TypeScript
import React, { useState, useEffect } from 'react';
|
|
import {
|
|
Hotel,
|
|
Heart,
|
|
MapPin,
|
|
Phone,
|
|
Mail,
|
|
Linkedin,
|
|
Twitter
|
|
} from 'lucide-react';
|
|
import * as LucideIcons from 'lucide-react';
|
|
import { Link } from 'react-router-dom';
|
|
import { pageContentService } from '../services/api';
|
|
import type { PageContent } from '../services/api/pageContentService';
|
|
import { useCompanySettings } from '../contexts/CompanySettingsContext';
|
|
|
|
const AboutPage: React.FC = () => {
|
|
const { settings } = useCompanySettings();
|
|
const [pageContent, setPageContent] = useState<PageContent | null>(null);
|
|
|
|
useEffect(() => {
|
|
const fetchPageContent = async () => {
|
|
try {
|
|
const response = await pageContentService.getAboutContent();
|
|
if (response.status === 'success' && response.data?.page_content) {
|
|
setPageContent(response.data.page_content);
|
|
|
|
|
|
if (response.data.page_content.meta_title) {
|
|
document.title = response.data.page_content.meta_title;
|
|
}
|
|
if (response.data.page_content.meta_description) {
|
|
let metaDescription = document.querySelector('meta[name="description"]');
|
|
if (!metaDescription) {
|
|
metaDescription = document.createElement('meta');
|
|
metaDescription.setAttribute('name', 'description');
|
|
document.head.appendChild(metaDescription);
|
|
}
|
|
metaDescription.setAttribute('content', response.data.page_content.meta_description);
|
|
}
|
|
}
|
|
} catch (err: any) {
|
|
console.error('Error fetching page content:', err);
|
|
|
|
}
|
|
};
|
|
|
|
fetchPageContent();
|
|
}, []);
|
|
|
|
|
|
const displayPhone = settings.company_phone || '+1 (234) 567-890';
|
|
const displayEmail = settings.company_email || 'info@luxuryhotel.com';
|
|
const displayAddress = settings.company_address || '123 Luxury Street\nCity, State 12345\nCountry';
|
|
|
|
|
|
const defaultValues = [
|
|
{
|
|
icon: 'Heart',
|
|
title: 'Passion',
|
|
description: 'We are passionate about hospitality and dedicated to creating exceptional experiences for every guest.'
|
|
},
|
|
{
|
|
icon: 'Award',
|
|
title: 'Excellence',
|
|
description: 'We strive for excellence in every aspect of our service, from the smallest detail to the grandest gesture.'
|
|
},
|
|
{
|
|
icon: 'Shield',
|
|
title: 'Integrity',
|
|
description: 'We conduct our business with honesty, transparency, and respect for our guests and community.'
|
|
},
|
|
{
|
|
icon: 'Users',
|
|
title: 'Service',
|
|
description: 'Our guests are at the heart of everything we do. Your comfort and satisfaction are our top priorities.'
|
|
}
|
|
];
|
|
|
|
const defaultFeatures = [
|
|
{
|
|
icon: 'Star',
|
|
title: 'Premium Accommodations',
|
|
description: 'Luxuriously appointed rooms and suites designed for ultimate comfort and relaxation.'
|
|
},
|
|
{
|
|
icon: 'Clock',
|
|
title: '24/7 Service',
|
|
description: 'Round-the-clock concierge and room service to attend to your needs at any time.'
|
|
},
|
|
{
|
|
icon: 'Award',
|
|
title: 'Award-Winning',
|
|
description: 'Recognized for excellence in hospitality and guest satisfaction.'
|
|
}
|
|
];
|
|
|
|
const values = pageContent?.values && pageContent.values.length > 0
|
|
? pageContent.values.map((v: any) => ({
|
|
icon: v.icon || defaultValues.find(d => d.title === v.title)?.icon || 'Heart',
|
|
title: v.title,
|
|
description: v.description
|
|
}))
|
|
: defaultValues;
|
|
|
|
const features = pageContent?.features && pageContent.features.length > 0
|
|
? pageContent.features.map((f: any) => ({
|
|
icon: f.icon || defaultFeatures.find(d => d.title === f.title)?.icon || 'Star',
|
|
title: f.title,
|
|
description: f.description
|
|
}))
|
|
: defaultFeatures;
|
|
|
|
|
|
const team = pageContent?.team && typeof pageContent.team === 'string'
|
|
? JSON.parse(pageContent.team)
|
|
: (Array.isArray(pageContent?.team) ? pageContent.team : []);
|
|
const timeline = pageContent?.timeline && typeof pageContent.timeline === 'string'
|
|
? JSON.parse(pageContent.timeline)
|
|
: (Array.isArray(pageContent?.timeline) ? pageContent.timeline : []);
|
|
const achievements = pageContent?.achievements && typeof pageContent.achievements === 'string'
|
|
? JSON.parse(pageContent.achievements)
|
|
: (Array.isArray(pageContent?.achievements) ? pageContent.achievements : []);
|
|
|
|
|
|
const getIconComponent = (iconName?: string) => {
|
|
if (!iconName) return Heart;
|
|
const IconComponent = (LucideIcons as any)[iconName] || Heart;
|
|
return IconComponent;
|
|
};
|
|
|
|
return (
|
|
<div className="min-h-screen bg-gradient-to-b from-slate-50 via-white to-slate-50">
|
|
{}
|
|
<div className={`relative ${pageContent?.about_hero_image ? '' : 'bg-gradient-to-br from-slate-900 via-slate-800 to-slate-900'} text-white py-20 md:py-24 ${pageContent?.about_hero_image ? 'h-[400px] md:h-[450px] lg:h-[500px]' : ''} overflow-hidden`}>
|
|
{pageContent?.about_hero_image && (
|
|
<div className="absolute inset-0">
|
|
<img
|
|
src={pageContent.about_hero_image.startsWith('http') ? pageContent.about_hero_image : `${import.meta.env.VITE_API_URL?.replace('/api', '') || 'http://localhost:8000'}/${pageContent.about_hero_image}`}
|
|
alt="About Hero"
|
|
className="w-full h-full object-cover scale-105 transition-transform duration-[20s] ease-out hover:scale-100"
|
|
/>
|
|
<div className="absolute inset-0 bg-gradient-to-b from-black/70 via-black/50 to-black/70"></div>
|
|
<div className="absolute inset-0 bg-gradient-to-r from-[#d4af37]/10 via-transparent to-[#d4af37]/10"></div>
|
|
</div>
|
|
)}
|
|
{!pageContent?.about_hero_image && (
|
|
<div className="absolute inset-0">
|
|
<div className="absolute inset-0 bg-[radial-gradient(circle_at_50%_50%,rgba(212,175,55,0.1),transparent_70%)]"></div>
|
|
<div className="absolute top-0 left-0 w-full h-full bg-[linear-gradient(45deg,transparent_30%,rgba(212,175,55,0.05)_50%,transparent_70%)]"></div>
|
|
</div>
|
|
)}
|
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
|
|
<div className="max-w-4xl mx-auto text-center">
|
|
{!pageContent?.about_hero_image && (
|
|
<div className="flex justify-center mb-8">
|
|
<div className="relative">
|
|
<div className="absolute inset-0 bg-gradient-to-br from-[#d4af37] via-[#f5d76e] to-[#d4af37] rounded-full blur-3xl opacity-40 animate-pulse"></div>
|
|
<div className="relative bg-gradient-to-br from-[#d4af37] to-[#c9a227] p-6 rounded-2xl shadow-2xl shadow-[#d4af37]/30">
|
|
<Hotel className="w-12 h-12 md:w-16 md:h-16 text-white drop-shadow-lg" />
|
|
</div>
|
|
</div>
|
|
</div>
|
|
)}
|
|
<div className="mb-6">
|
|
<div className="inline-block mb-4">
|
|
<div className="h-px w-20 bg-gradient-to-r from-transparent via-[#d4af37] to-transparent mx-auto"></div>
|
|
</div>
|
|
</div>
|
|
<h1 className="text-5xl md:text-6xl lg:text-7xl font-serif font-light mb-6 tracking-[0.02em] leading-tight">
|
|
<span className="bg-gradient-to-b from-white via-[#f5d76e] to-[#d4af37] bg-clip-text text-transparent drop-shadow-2xl">
|
|
{pageContent?.title || 'About Luxury Hotel'}
|
|
</span>
|
|
</h1>
|
|
<p className="text-lg md:text-xl lg:text-2xl text-gray-200 font-light leading-relaxed max-w-2xl mx-auto tracking-wide">
|
|
{pageContent?.subtitle || pageContent?.description || 'Where Excellence Meets Unforgettable Experiences'}
|
|
</p>
|
|
<div className="mt-8">
|
|
<div className="inline-block">
|
|
<div className="h-px w-20 bg-gradient-to-r from-transparent via-[#d4af37] to-transparent mx-auto"></div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{}
|
|
<section className="py-20 md:py-28 bg-white relative overflow-hidden">
|
|
<div className="absolute top-0 left-0 w-full h-px bg-gradient-to-r from-transparent via-[#d4af37]/30 to-transparent"></div>
|
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8">
|
|
<div className="max-w-5xl mx-auto">
|
|
<div className="text-center mb-16">
|
|
<div className="inline-block mb-4">
|
|
<span className="text-sm font-semibold text-[#d4af37] tracking-[0.2em] uppercase">Our Heritage</span>
|
|
</div>
|
|
<h2 className="text-4xl md:text-5xl lg:text-6xl font-serif font-light text-gray-900 mb-6 tracking-tight">
|
|
Our Story
|
|
</h2>
|
|
<div className="flex items-center justify-center gap-4 mb-6">
|
|
<div className="h-px w-12 bg-gradient-to-r from-transparent to-[#d4af37]"></div>
|
|
<div className="w-2 h-2 bg-[#d4af37] rounded-full"></div>
|
|
<div className="h-px w-12 bg-gradient-to-l from-transparent to-[#d4af37]"></div>
|
|
</div>
|
|
</div>
|
|
<div className="prose prose-lg md:prose-xl max-w-none text-gray-700 leading-relaxed space-y-8">
|
|
{pageContent?.story_content ? (
|
|
<div
|
|
className="text-lg md:text-xl leading-relaxed font-light tracking-wide"
|
|
dangerouslySetInnerHTML={{ __html: pageContent.story_content.replace(/\n/g, '<br />') }}
|
|
/>
|
|
) : (
|
|
<>
|
|
<p className="text-lg md:text-xl leading-relaxed font-light tracking-wide first-letter:text-5xl first-letter:font-serif first-letter:text-[#d4af37] first-letter:float-left first-letter:mr-2 first-letter:leading-none">
|
|
Welcome to Luxury Hotel, where timeless elegance meets modern sophistication.
|
|
Since our founding, we have been dedicated to providing exceptional hospitality
|
|
and creating unforgettable memories for our guests.
|
|
</p>
|
|
<p className="text-lg md:text-xl leading-relaxed font-light tracking-wide">
|
|
Nestled in the heart of the city, our hotel combines classic architecture with
|
|
contemporary amenities, offering a perfect blend of comfort and luxury. Every
|
|
detail has been carefully curated to ensure your stay exceeds expectations.
|
|
</p>
|
|
<p className="text-lg md:text-xl leading-relaxed font-light tracking-wide">
|
|
Our commitment to excellence extends beyond our beautiful rooms and facilities.
|
|
We believe in creating meaningful connections with our guests, understanding
|
|
their needs, and delivering personalized service that makes each visit special.
|
|
</p>
|
|
</>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
<div className="absolute bottom-0 left-0 w-full h-px bg-gradient-to-r from-transparent via-[#d4af37]/30 to-transparent"></div>
|
|
</section>
|
|
|
|
{}
|
|
<section className="py-20 md:py-28 bg-gradient-to-b from-slate-50 via-white to-slate-50 relative">
|
|
<div className="absolute inset-0 bg-[radial-gradient(circle_at_30%_50%,rgba(212,175,55,0.03),transparent_50%)]"></div>
|
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
|
|
<div className="max-w-7xl mx-auto">
|
|
<div className="text-center mb-16">
|
|
<div className="inline-block mb-4">
|
|
<span className="text-sm font-semibold text-[#d4af37] tracking-[0.2em] uppercase">Core Principles</span>
|
|
</div>
|
|
<h2 className="text-4xl md:text-5xl lg:text-6xl font-serif font-light text-gray-900 mb-6 tracking-tight">
|
|
Our Values
|
|
</h2>
|
|
<div className="flex items-center justify-center gap-4 mb-6">
|
|
<div className="h-px w-12 bg-gradient-to-r from-transparent to-[#d4af37]"></div>
|
|
<div className="w-2 h-2 bg-[#d4af37] rounded-full"></div>
|
|
<div className="h-px w-12 bg-gradient-to-l from-transparent to-[#d4af37]"></div>
|
|
</div>
|
|
</div>
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6 lg:gap-8">
|
|
{values.map((value, index) => (
|
|
<div
|
|
key={value.title}
|
|
className="group relative bg-white/80 backdrop-blur-sm p-8 rounded-2xl shadow-lg hover:shadow-2xl transition-all duration-500 border border-gray-100 hover:border-[#d4af37]/30 hover:-translate-y-2"
|
|
style={{ animationDelay: `${index * 0.1}s` }}
|
|
>
|
|
<div className="absolute top-0 right-0 w-32 h-32 bg-gradient-to-br from-[#d4af37]/5 to-transparent rounded-bl-full opacity-0 group-hover:opacity-100 transition-opacity duration-500"></div>
|
|
<div className="relative">
|
|
<div className="w-16 h-16 bg-gradient-to-br from-[#d4af37] via-[#f5d76e] to-[#d4af37] rounded-xl flex items-center justify-center mb-6 shadow-lg shadow-[#d4af37]/20 group-hover:scale-110 group-hover:rotate-3 transition-transform duration-500">
|
|
{(() => {
|
|
const ValueIcon = getIconComponent(value.icon);
|
|
return <ValueIcon className="w-8 h-8 text-white drop-shadow-md" />;
|
|
})()}
|
|
</div>
|
|
<h3 className="text-xl md:text-2xl font-serif font-semibold text-gray-900 mb-3 group-hover:text-[#d4af37] transition-colors duration-300">
|
|
{value.title}
|
|
</h3>
|
|
<p className="text-gray-600 leading-relaxed font-light text-sm md:text-base">
|
|
{value.description}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{}
|
|
<section className="py-20 md:py-28 bg-white relative overflow-hidden">
|
|
<div className="absolute inset-0 bg-[linear-gradient(135deg,transparent_0%,rgba(212,175,55,0.02)_50%,transparent_100%)]"></div>
|
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
|
|
<div className="max-w-7xl mx-auto">
|
|
<div className="text-center mb-16">
|
|
<div className="inline-block mb-4">
|
|
<span className="text-sm font-semibold text-[#d4af37] tracking-[0.2em] uppercase">Excellence Defined</span>
|
|
</div>
|
|
<h2 className="text-4xl md:text-5xl lg:text-6xl font-serif font-light text-gray-900 mb-6 tracking-tight">
|
|
Why Choose Us
|
|
</h2>
|
|
<div className="flex items-center justify-center gap-4 mb-6">
|
|
<div className="h-px w-12 bg-gradient-to-r from-transparent to-[#d4af37]"></div>
|
|
<div className="w-2 h-2 bg-[#d4af37] rounded-full"></div>
|
|
<div className="h-px w-12 bg-gradient-to-l from-transparent to-[#d4af37]"></div>
|
|
</div>
|
|
</div>
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 lg:gap-12">
|
|
{features.map((feature, index) => {
|
|
const FeatureIcon = getIconComponent(feature.icon);
|
|
return (
|
|
<div
|
|
key={feature.title || index}
|
|
className="group text-center p-8 relative"
|
|
style={{ animationDelay: `${index * 0.1}s` }}
|
|
>
|
|
<div className="absolute inset-0 bg-gradient-to-br from-[#d4af37]/5 to-transparent rounded-3xl opacity-0 group-hover:opacity-100 transition-opacity duration-500"></div>
|
|
<div className="relative">
|
|
<div className="w-20 h-20 bg-gradient-to-br from-[#d4af37] via-[#f5d76e] to-[#d4af37] rounded-2xl flex items-center justify-center mx-auto mb-6 shadow-xl shadow-[#d4af37]/30 group-hover:scale-110 group-hover:shadow-2xl group-hover:shadow-[#d4af37]/40 transition-all duration-500">
|
|
<FeatureIcon className="w-10 h-10 text-white drop-shadow-lg" />
|
|
</div>
|
|
<h3 className="text-xl md:text-2xl font-serif font-semibold text-gray-900 mb-4 group-hover:text-[#d4af37] transition-colors duration-300">
|
|
{feature.title}
|
|
</h3>
|
|
<p className="text-gray-600 leading-relaxed font-light text-sm md:text-base">
|
|
{feature.description}
|
|
</p>
|
|
</div>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
|
|
{}
|
|
{(pageContent?.mission || pageContent?.vision) && (
|
|
<section className="py-20 md:py-28 bg-gradient-to-br from-slate-900 via-slate-800 to-slate-900 relative overflow-hidden">
|
|
<div className="absolute inset-0">
|
|
<div className="absolute inset-0 bg-[radial-gradient(circle_at_50%_50%,rgba(212,175,55,0.1),transparent_70%)]"></div>
|
|
<div className="absolute top-0 left-0 w-full h-full bg-[linear-gradient(45deg,transparent_30%,rgba(212,175,55,0.05)_50%,transparent_70%)]"></div>
|
|
</div>
|
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
|
|
<div className="max-w-7xl mx-auto grid grid-cols-1 md:grid-cols-2 gap-8 lg:gap-12">
|
|
{pageContent.mission && (
|
|
<div className="group relative bg-white/95 backdrop-blur-sm p-10 md:p-12 rounded-2xl shadow-2xl border border-[#d4af37]/20 hover:border-[#d4af37]/40 transition-all duration-500 hover:shadow-[#d4af37]/20 hover:-translate-y-1">
|
|
<div className="absolute top-0 right-0 w-40 h-40 bg-gradient-to-br from-[#d4af37]/10 to-transparent rounded-bl-full opacity-0 group-hover:opacity-100 transition-opacity duration-500"></div>
|
|
<div className="relative">
|
|
<div className="flex items-center gap-3 mb-6">
|
|
<div className="w-1 h-12 bg-gradient-to-b from-[#d4af37] to-[#f5d76e] rounded-full"></div>
|
|
<h2 className="text-3xl md:text-4xl font-serif font-light text-gray-900">Our Mission</h2>
|
|
</div>
|
|
<p className="text-gray-700 leading-relaxed text-base md:text-lg font-light tracking-wide">{pageContent.mission}</p>
|
|
</div>
|
|
</div>
|
|
)}
|
|
{pageContent.vision && (
|
|
<div className="group relative bg-white/95 backdrop-blur-sm p-10 md:p-12 rounded-2xl shadow-2xl border border-[#d4af37]/20 hover:border-[#d4af37]/40 transition-all duration-500 hover:shadow-[#d4af37]/20 hover:-translate-y-1">
|
|
<div className="absolute top-0 right-0 w-40 h-40 bg-gradient-to-br from-[#d4af37]/10 to-transparent rounded-bl-full opacity-0 group-hover:opacity-100 transition-opacity duration-500"></div>
|
|
<div className="relative">
|
|
<div className="flex items-center gap-3 mb-6">
|
|
<div className="w-1 h-12 bg-gradient-to-b from-[#d4af37] to-[#f5d76e] rounded-full"></div>
|
|
<h2 className="text-3xl md:text-4xl font-serif font-light text-gray-900">Our Vision</h2>
|
|
</div>
|
|
<p className="text-gray-700 leading-relaxed text-base md:text-lg font-light tracking-wide">{pageContent.vision}</p>
|
|
</div>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</section>
|
|
)}
|
|
|
|
{}
|
|
{team && team.length > 0 && (
|
|
<section className="py-20 md:py-28 bg-gradient-to-b from-white via-slate-50 to-white relative">
|
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8">
|
|
<div className="max-w-7xl mx-auto">
|
|
<div className="text-center mb-16">
|
|
<div className="inline-block mb-4">
|
|
<span className="text-sm font-semibold text-[#d4af37] tracking-[0.2em] uppercase">Meet The Experts</span>
|
|
</div>
|
|
<h2 className="text-4xl md:text-5xl lg:text-6xl font-serif font-light text-gray-900 mb-6 tracking-tight">
|
|
Our Team
|
|
</h2>
|
|
<div className="flex items-center justify-center gap-4 mb-6">
|
|
<div className="h-px w-12 bg-gradient-to-r from-transparent to-[#d4af37]"></div>
|
|
<div className="w-2 h-2 bg-[#d4af37] rounded-full"></div>
|
|
<div className="h-px w-12 bg-gradient-to-l from-transparent to-[#d4af37]"></div>
|
|
</div>
|
|
</div>
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 lg:gap-10">
|
|
{team.map((member: any, index: number) => (
|
|
<div
|
|
key={index}
|
|
className="group relative bg-white rounded-2xl shadow-xl overflow-hidden hover:shadow-2xl transition-all duration-500 border border-gray-100 hover:border-[#d4af37]/30 hover:-translate-y-2"
|
|
>
|
|
<div className="absolute inset-0 bg-gradient-to-br from-[#d4af37]/5 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500 z-10"></div>
|
|
{member.image && (
|
|
<div className="relative overflow-hidden h-72">
|
|
<img
|
|
src={member.image.startsWith('http') ? member.image : `${import.meta.env.VITE_API_URL?.replace('/api', '') || 'http://localhost:8000'}/${member.image}`}
|
|
alt={member.name}
|
|
className="w-full h-full object-cover group-hover:scale-110 transition-transform duration-700"
|
|
/>
|
|
<div className="absolute inset-0 bg-gradient-to-t from-black/20 to-transparent opacity-0 group-hover:opacity-100 transition-opacity duration-500"></div>
|
|
</div>
|
|
)}
|
|
<div className="p-8 relative z-10">
|
|
<h3 className="text-2xl font-serif font-semibold text-gray-900 mb-2 group-hover:text-[#d4af37] transition-colors duration-300">{member.name}</h3>
|
|
<p className="text-[#d4af37] font-medium mb-4 text-sm tracking-wide uppercase">{member.role}</p>
|
|
{member.bio && <p className="text-gray-600 text-sm mb-6 leading-relaxed font-light">{member.bio}</p>}
|
|
{member.social_links && (
|
|
<div className="flex gap-4 pt-4 border-t border-gray-100">
|
|
{member.social_links.linkedin && (
|
|
<a
|
|
href={member.social_links.linkedin}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="w-10 h-10 rounded-full bg-gray-100 flex items-center justify-center text-gray-600 hover:bg-[#d4af37] hover:text-white transition-all duration-300 group-hover:scale-110"
|
|
>
|
|
<Linkedin className="w-5 h-5" />
|
|
</a>
|
|
)}
|
|
{member.social_links.twitter && (
|
|
<a
|
|
href={member.social_links.twitter}
|
|
target="_blank"
|
|
rel="noopener noreferrer"
|
|
className="w-10 h-10 rounded-full bg-gray-100 flex items-center justify-center text-gray-600 hover:bg-[#d4af37] hover:text-white transition-all duration-300 group-hover:scale-110"
|
|
>
|
|
<Twitter className="w-5 h-5" />
|
|
</a>
|
|
)}
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
)}
|
|
|
|
{}
|
|
{timeline && timeline.length > 0 && (
|
|
<section className="py-20 md:py-28 bg-gradient-to-b from-slate-50 via-white to-slate-50 relative overflow-hidden">
|
|
<div className="absolute inset-0 bg-[radial-gradient(circle_at_70%_50%,rgba(212,175,55,0.03),transparent_50%)]"></div>
|
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
|
|
<div className="max-w-6xl mx-auto">
|
|
<div className="text-center mb-16">
|
|
<div className="inline-block mb-4">
|
|
<span className="text-sm font-semibold text-[#d4af37] tracking-[0.2em] uppercase">Our Journey</span>
|
|
</div>
|
|
<h2 className="text-4xl md:text-5xl lg:text-6xl font-serif font-light text-gray-900 mb-6 tracking-tight">
|
|
Our History
|
|
</h2>
|
|
<div className="flex items-center justify-center gap-4 mb-6">
|
|
<div className="h-px w-12 bg-gradient-to-r from-transparent to-[#d4af37]"></div>
|
|
<div className="w-2 h-2 bg-[#d4af37] rounded-full"></div>
|
|
<div className="h-px w-12 bg-gradient-to-l from-transparent to-[#d4af37]"></div>
|
|
</div>
|
|
</div>
|
|
<div className="relative">
|
|
<div className="absolute left-8 md:left-1/2 transform md:-translate-x-1/2 w-1 h-full bg-gradient-to-b from-[#d4af37] via-[#f5d76e] to-[#d4af37] shadow-lg"></div>
|
|
<div className="space-y-12 md:space-y-16">
|
|
{timeline.map((event: any, index: number) => (
|
|
<div key={index} className={`relative flex items-center ${index % 2 === 0 ? 'md:flex-row' : 'md:flex-row-reverse'}`}>
|
|
<div className="absolute left-6 md:left-1/2 transform md:-translate-x-1/2 w-6 h-6 bg-gradient-to-br from-[#d4af37] to-[#c9a227] rounded-full border-4 border-white shadow-xl z-10 group-hover:scale-125 transition-transform duration-300"></div>
|
|
<div className={`ml-20 md:ml-0 md:w-5/12 ${index % 2 === 0 ? 'md:mr-auto md:pr-8' : 'md:ml-auto md:pl-8'}`}>
|
|
<div className="group bg-white/90 backdrop-blur-sm p-8 rounded-2xl shadow-xl hover:shadow-2xl transition-all duration-500 border border-gray-100 hover:border-[#d4af37]/30">
|
|
<div className="flex items-center gap-3 mb-4">
|
|
<div className="text-[#d4af37] font-bold text-2xl md:text-3xl font-serif">{event.year}</div>
|
|
<div className="h-px flex-1 bg-gradient-to-r from-[#d4af37] to-transparent"></div>
|
|
</div>
|
|
<h3 className="text-2xl md:text-3xl font-serif font-semibold text-gray-900 mb-3 group-hover:text-[#d4af37] transition-colors duration-300">{event.title}</h3>
|
|
<p className="text-gray-600 leading-relaxed font-light mb-4">{event.description}</p>
|
|
{event.image && (
|
|
<div className="mt-6 overflow-hidden rounded-xl">
|
|
<img
|
|
src={event.image.startsWith('http') ? event.image : `${import.meta.env.VITE_API_URL?.replace('/api', '') || 'http://localhost:8000'}/${event.image}`}
|
|
alt={event.title}
|
|
className="w-full h-56 md:h-64 object-cover group-hover:scale-110 transition-transform duration-700"
|
|
/>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
))}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
)}
|
|
|
|
{}
|
|
{achievements && achievements.length > 0 && (
|
|
<section className="py-20 md:py-28 bg-white relative overflow-hidden">
|
|
<div className="absolute inset-0 bg-[linear-gradient(135deg,transparent_0%,rgba(212,175,55,0.02)_50%,transparent_100%)]"></div>
|
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
|
|
<div className="max-w-7xl mx-auto">
|
|
<div className="text-center mb-16">
|
|
<div className="inline-block mb-4">
|
|
<span className="text-sm font-semibold text-[#d4af37] tracking-[0.2em] uppercase">Recognition</span>
|
|
</div>
|
|
<h2 className="text-4xl md:text-5xl lg:text-6xl font-serif font-light text-gray-900 mb-6 tracking-tight">
|
|
Achievements & Awards
|
|
</h2>
|
|
<div className="flex items-center justify-center gap-4 mb-6">
|
|
<div className="h-px w-12 bg-gradient-to-r from-transparent to-[#d4af37]"></div>
|
|
<div className="w-2 h-2 bg-[#d4af37] rounded-full"></div>
|
|
<div className="h-px w-12 bg-gradient-to-l from-transparent to-[#d4af37]"></div>
|
|
</div>
|
|
</div>
|
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-8 lg:gap-10">
|
|
{achievements.map((achievement: any, index: number) => {
|
|
const AchievementIcon = getIconComponent(achievement.icon);
|
|
return (
|
|
<div
|
|
key={index}
|
|
className="group relative bg-gradient-to-br from-white to-slate-50 p-8 rounded-2xl shadow-xl hover:shadow-2xl transition-all duration-500 border border-gray-100 hover:border-[#d4af37]/40 hover:-translate-y-2"
|
|
>
|
|
<div className="absolute top-0 right-0 w-32 h-32 bg-gradient-to-br from-[#d4af37]/10 to-transparent rounded-bl-full opacity-0 group-hover:opacity-100 transition-opacity duration-500"></div>
|
|
<div className="relative">
|
|
<div className="flex items-center gap-4 mb-6">
|
|
<div className="w-16 h-16 bg-gradient-to-br from-[#d4af37] via-[#f5d76e] to-[#d4af37] rounded-xl flex items-center justify-center shadow-lg shadow-[#d4af37]/20 group-hover:scale-110 group-hover:rotate-3 transition-transform duration-500">
|
|
<AchievementIcon className="w-8 h-8 text-white drop-shadow-md" />
|
|
</div>
|
|
{achievement.year && (
|
|
<div className="text-[#d4af37] font-bold text-2xl font-serif">{achievement.year}</div>
|
|
)}
|
|
</div>
|
|
<h3 className="text-xl md:text-2xl font-serif font-semibold text-gray-900 mb-3 group-hover:text-[#d4af37] transition-colors duration-300">{achievement.title}</h3>
|
|
<p className="text-gray-600 text-sm md:text-base leading-relaxed font-light mb-4">{achievement.description}</p>
|
|
{achievement.image && (
|
|
<div className="mt-6 overflow-hidden rounded-xl">
|
|
<img
|
|
src={achievement.image.startsWith('http') ? achievement.image : `${import.meta.env.VITE_API_URL?.replace('/api', '') || 'http://localhost:8000'}/${achievement.image}`}
|
|
alt={achievement.title}
|
|
className="w-full h-40 object-cover group-hover:scale-110 transition-transform duration-700"
|
|
/>
|
|
</div>
|
|
)}
|
|
</div>
|
|
</div>
|
|
);
|
|
})}
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
)}
|
|
|
|
{}
|
|
<section className="py-20 md:py-28 bg-gradient-to-br from-slate-50 via-white to-slate-50 relative overflow-hidden">
|
|
<div className="absolute inset-0 bg-[radial-gradient(circle_at_50%_50%,rgba(212,175,55,0.03),transparent_70%)]"></div>
|
|
<div className="container mx-auto px-4 sm:px-6 lg:px-8 relative z-10">
|
|
<div className="max-w-6xl mx-auto">
|
|
<div className="text-center mb-16">
|
|
<div className="inline-block mb-4">
|
|
<span className="text-sm font-semibold text-[#d4af37] tracking-[0.2em] uppercase">Connect With Us</span>
|
|
</div>
|
|
<h2 className="text-4xl md:text-5xl lg:text-6xl font-serif font-light text-gray-900 mb-6 tracking-tight">
|
|
Get In Touch
|
|
</h2>
|
|
<div className="flex items-center justify-center gap-4 mb-6">
|
|
<div className="h-px w-12 bg-gradient-to-r from-transparent to-[#d4af37]"></div>
|
|
<div className="w-2 h-2 bg-[#d4af37] rounded-full"></div>
|
|
<div className="h-px w-12 bg-gradient-to-l from-transparent to-[#d4af37]"></div>
|
|
</div>
|
|
<p className="text-gray-600 mt-6 text-lg font-light max-w-2xl mx-auto">
|
|
We'd love to hear from you. Contact us for reservations or inquiries.
|
|
</p>
|
|
</div>
|
|
<div className="grid grid-cols-1 md:grid-cols-3 gap-8 lg:gap-10 mb-16">
|
|
<div className="group text-center p-8 bg-white/80 backdrop-blur-sm rounded-2xl shadow-xl hover:shadow-2xl transition-all duration-500 border border-gray-100 hover:border-[#d4af37]/40 hover:-translate-y-2">
|
|
<div className="w-16 h-16 bg-gradient-to-br from-[#d4af37] via-[#f5d76e] to-[#d4af37] rounded-2xl flex items-center justify-center mx-auto mb-6 shadow-lg shadow-[#d4af37]/20 group-hover:scale-110 group-hover:rotate-3 transition-transform duration-500">
|
|
<MapPin className="w-8 h-8 text-white drop-shadow-md" />
|
|
</div>
|
|
<h3 className="text-xl font-serif font-semibold text-gray-900 mb-4 group-hover:text-[#d4af37] transition-colors duration-300">
|
|
Address
|
|
</h3>
|
|
<p className="text-gray-600 leading-relaxed font-light">
|
|
{displayAddress
|
|
.split('\n').map((line, i) => (
|
|
<React.Fragment key={i}>
|
|
{line}
|
|
{i < displayAddress.split('\n').length - 1 && <br />}
|
|
</React.Fragment>
|
|
))}
|
|
</p>
|
|
</div>
|
|
<div className="group text-center p-8 bg-white/80 backdrop-blur-sm rounded-2xl shadow-xl hover:shadow-2xl transition-all duration-500 border border-gray-100 hover:border-[#d4af37]/40 hover:-translate-y-2" style={{ animationDelay: '0.1s' }}>
|
|
<div className="w-16 h-16 bg-gradient-to-br from-[#d4af37] via-[#f5d76e] to-[#d4af37] rounded-2xl flex items-center justify-center mx-auto mb-6 shadow-lg shadow-[#d4af37]/20 group-hover:scale-110 group-hover:rotate-3 transition-transform duration-500">
|
|
<Phone className="w-8 h-8 text-white drop-shadow-md" />
|
|
</div>
|
|
<h3 className="text-xl font-serif font-semibold text-gray-900 mb-4 group-hover:text-[#d4af37] transition-colors duration-300">
|
|
Phone
|
|
</h3>
|
|
<p className="text-gray-600 font-light">
|
|
<a href={`tel:${displayPhone.replace(/\s+/g, '').replace(/[()]/g, '')}`} className="hover:text-[#d4af37] transition-colors duration-300">
|
|
{displayPhone}
|
|
</a>
|
|
</p>
|
|
</div>
|
|
<div className="group text-center p-8 bg-white/80 backdrop-blur-sm rounded-2xl shadow-xl hover:shadow-2xl transition-all duration-500 border border-gray-100 hover:border-[#d4af37]/40 hover:-translate-y-2" style={{ animationDelay: '0.2s' }}>
|
|
<div className="w-16 h-16 bg-gradient-to-br from-[#d4af37] via-[#f5d76e] to-[#d4af37] rounded-2xl flex items-center justify-center mx-auto mb-6 shadow-lg shadow-[#d4af37]/20 group-hover:scale-110 group-hover:rotate-3 transition-transform duration-500">
|
|
<Mail className="w-8 h-8 text-white drop-shadow-md" />
|
|
</div>
|
|
<h3 className="text-xl font-serif font-semibold text-gray-900 mb-4 group-hover:text-[#d4af37] transition-colors duration-300">
|
|
Email
|
|
</h3>
|
|
<p className="text-gray-600 font-light">
|
|
<a href={`mailto:${displayEmail}`} className="hover:text-[#d4af37] transition-colors duration-300">
|
|
{displayEmail}
|
|
</a>
|
|
</p>
|
|
</div>
|
|
</div>
|
|
<div className="text-center">
|
|
<Link
|
|
to="/rooms"
|
|
className="group inline-flex items-center space-x-3 px-10 py-4 bg-gradient-to-r from-[#d4af37] via-[#f5d76e] to-[#d4af37] text-white rounded-xl hover:shadow-2xl hover:shadow-[#d4af37]/40 transition-all duration-500 font-medium text-lg tracking-wide relative overflow-hidden"
|
|
>
|
|
<span className="relative z-10">Explore Our Rooms</span>
|
|
<Hotel className="w-5 h-5 relative z-10 group-hover:translate-x-1 transition-transform duration-300" />
|
|
<div className="absolute inset-0 bg-gradient-to-r from-[#f5d76e] to-[#d4af37] opacity-0 group-hover:opacity-100 transition-opacity duration-500"></div>
|
|
</Link>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</section>
|
|
</div>
|
|
);
|
|
};
|
|
|
|
export default AboutPage;
|
|
|