This commit is contained in:
Flatlogic Bot 2026-03-09 03:44:15 +00:00
parent 9b5dc68a86
commit fcdc4650eb
4 changed files with 435 additions and 149 deletions

View File

@ -100,6 +100,8 @@ require('./auth/auth');
app.use(bodyParser.json());
app.use('/api/auth', authRoutes);
const publicBookingRoutes = require('./routes/public_booking');
app.use('/api/public_booking', publicBookingRoutes);
app.use('/api/file', fileRoutes);
app.use('/api/pexels', pexelsRoutes);
app.enable('trust proxy');

View File

@ -0,0 +1,24 @@
const express = require('express');
const Booking_requestsService = require('../services/booking_requests');
const wrapAsync = require('../helpers').wrapAsync;
const router = express.Router();
router.post('/', wrapAsync(async (req, res) => {
const data = req.body;
// Check if the data is wrapped in a "data" object, if not, use the body itself
const bookingData = data.data ? data.data : data;
// Set default status to new and channel to website_form
if (bookingData) {
bookingData.status = 'new';
bookingData.channel = 'website_form';
bookingData.requested_at = new Date();
}
await Booking_requestsService.create(bookingData, null);
res.status(200).send(true);
}));
module.exports = router;

219
frontend/src/pages/book.tsx Normal file
View File

@ -0,0 +1,219 @@
import React, { useState } from 'react';
import type { ReactElement } from 'react';
import Head from 'next/head';
import Link from 'next/link';
import axios from 'axios';
import LayoutGuest from '../layouts/Guest';
import { getPageTitle } from '../config';
export default function BookYourStay() {
const [formData, setFormData] = useState({
guest_full_name: '',
guest_email: '',
guest_phone: '',
check_in: '',
check_out: '',
adults: 1,
children: 0,
special_requests: '',
preferred_contact: 'WhatsApp',
});
const [isSubmitting, setIsSubmitting] = useState(false);
const [submitSuccess, setSubmitSuccess] = useState(false);
const [errorMsg, setErrorMsg] = useState('');
const handleChange = (e: React.ChangeEvent<HTMLInputElement | HTMLTextAreaElement | HTMLSelectElement>) => {
const { name, value } = e.target;
setFormData(prev => ({ ...prev, [name]: value }));
};
const validate = () => {
if (!formData.guest_full_name) return 'Name is required.';
if (!formData.guest_email) return 'Email is required.';
if (!formData.guest_phone) return 'Phone is required.';
if (!formData.check_in) return 'Check-in date is required.';
if (!formData.check_out) return 'Check-out date is required.';
if (new Date(formData.check_out) <= new Date(formData.check_in)) {
return 'Check-out date must be after check-in date.';
}
const emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
if (!emailRegex.test(formData.guest_email)) {
return 'Please enter a valid email address.';
}
return null;
};
const handleSubmit = async (e: React.FormEvent) => {
e.preventDefault();
setErrorMsg('');
const validationError = validate();
if (validationError) {
setErrorMsg(validationError);
return;
}
setIsSubmitting(true);
try {
await axios.post('/public_booking', {
data: formData
});
setSubmitSuccess(true);
} catch (error) {
console.error(error);
setErrorMsg('An error occurred while submitting your request. Please try again or contact us directly.');
} finally {
setIsSubmitting(false);
}
};
return (
<div className="font-sans text-[#1A1A1A] bg-[#F5EFE6] min-h-screen">
<Head>
<title>{getPageTitle('Book Your Stay')}</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
<link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,600;1,400&family=Inter:wght@300;400;500;600&family=Playfair+Display:ital,wght@0,400;0,600;0,700;1,400&display=swap" rel="stylesheet" />
<style>{`
.font-heading { font-family: 'Playfair Display', serif; }
.font-body { font-family: 'Inter', sans-serif; }
.font-accent { font-family: 'Cormorant Garamond', serif; }
`}</style>
</Head>
{/* Header */}
<header className="bg-[#1E3D2B] text-[#FFFFFF] py-6 px-6 shadow-md relative z-10">
<div className="max-w-4xl mx-auto flex justify-between items-center">
<Link href="/" className="font-heading text-2xl text-[#D6B56C]">Hôtel Marhaba</Link>
<Link href="/" className="font-body text-sm hover:text-[#D6B56C] transition-colors"> Back to Home</Link>
</div>
</header>
<main className="max-w-3xl mx-auto px-6 py-12">
<div className="bg-[#FFFFFF] shadow-xl rounded-xl p-8 md:p-12 relative overflow-hidden">
{submitSuccess ? (
<div className="text-center py-16">
<div className="w-20 h-20 bg-[#D6B56C] rounded-full flex items-center justify-center mx-auto mb-6">
<svg className="w-10 h-10 text-[#FFFFFF]" fill="none" stroke="currentColor" viewBox="0 0 24 24">
<path strokeLinecap="round" strokeLinejoin="round" strokeWidth="2" d="M5 13l4 4L19 7"></path>
</svg>
</div>
<h2 className="font-heading text-4xl text-[#1E3D2B] mb-4">Request Received</h2>
<p className="font-body text-lg text-[#1A1A1A] mb-8">
Thank you for choosing Hôtel Marhaba. Your booking request has been successfully submitted. Our team will contact you shortly to confirm your reservation and arrange payment.
</p>
<div className="bg-[#F5EFE6] p-6 rounded-lg text-left mb-8 inline-block max-w-lg mx-auto w-full">
<p className="font-body font-semibold mb-2">Next Steps:</p>
<ul className="list-disc list-inside font-body text-sm space-y-1 ml-4">
<li>We will review your requested dates and room availability.</li>
<li>You will receive a confirmation call or email within 24 hours.</li>
<li>Payment details will be provided upon confirmation.</li>
</ul>
</div>
<br/>
<Link href="/" className="bg-[#1E3D2B] hover:bg-[#152e20] text-[#FFFFFF] font-body font-medium py-3 px-8 rounded transition-colors duration-300">
Return to Home
</Link>
</div>
) : (
<>
<div className="text-center mb-10">
<h1 className="font-heading text-4xl md:text-5xl text-[#1E3D2B] mb-4">Book Your Stay</h1>
<p className="font-body text-[#1A1A1A] text-lg max-w-lg mx-auto">
Submit your reservation request below, and we will contact you promptly to confirm your booking at our historic oasis.
</p>
</div>
{errorMsg && (
<div className="bg-red-50 text-red-600 p-4 rounded mb-6 font-body text-sm border-l-4 border-red-500">
{errorMsg}
</div>
)}
<form onSubmit={handleSubmit} className="space-y-6 font-body">
{/* Dates & Guests */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div>
<label className="block text-sm font-semibold text-[#1E3D2B] mb-1">Check-in Date *</label>
<input type="date" name="check_in" value={formData.check_in} onChange={handleChange} required className="w-full border border-gray-300 rounded px-4 py-3 focus:ring-2 focus:ring-[#D6B56C] focus:border-transparent outline-none" />
</div>
<div>
<label className="block text-sm font-semibold text-[#1E3D2B] mb-1">Check-out Date *</label>
<input type="date" name="check_out" value={formData.check_out} onChange={handleChange} required className="w-full border border-gray-300 rounded px-4 py-3 focus:ring-2 focus:ring-[#D6B56C] focus:border-transparent outline-none" />
</div>
<div>
<label className="block text-sm font-semibold text-[#1E3D2B] mb-1">Adults</label>
<select name="adults" value={formData.adults} onChange={handleChange} className="w-full border border-gray-300 rounded px-4 py-3 focus:ring-2 focus:ring-[#D6B56C] focus:border-transparent outline-none">
{[1, 2, 3, 4, 5, 6].map(n => <option key={n} value={n}>{n}</option>)}
</select>
</div>
<div>
<label className="block text-sm font-semibold text-[#1E3D2B] mb-1">Children</label>
<select name="children" value={formData.children} onChange={handleChange} className="w-full border border-gray-300 rounded px-4 py-3 focus:ring-2 focus:ring-[#D6B56C] focus:border-transparent outline-none">
{[0, 1, 2, 3, 4].map(n => <option key={n} value={n}>{n}</option>)}
</select>
</div>
</div>
<hr className="border-gray-200" />
{/* Contact Info */}
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
<div className="md:col-span-2">
<label className="block text-sm font-semibold text-[#1E3D2B] mb-1">Full Name *</label>
<input type="text" name="guest_full_name" value={formData.guest_full_name} onChange={handleChange} required placeholder="John Doe" className="w-full border border-gray-300 rounded px-4 py-3 focus:ring-2 focus:ring-[#D6B56C] focus:border-transparent outline-none" />
</div>
<div>
<label className="block text-sm font-semibold text-[#1E3D2B] mb-1">Email Address *</label>
<input type="email" name="guest_email" value={formData.guest_email} onChange={handleChange} required placeholder="john@example.com" className="w-full border border-gray-300 rounded px-4 py-3 focus:ring-2 focus:ring-[#D6B56C] focus:border-transparent outline-none" />
</div>
<div>
<label className="block text-sm font-semibold text-[#1E3D2B] mb-1">Phone Number *</label>
<input type="tel" name="guest_phone" value={formData.guest_phone} onChange={handleChange} required placeholder="+213 00 00 00 00" className="w-full border border-gray-300 rounded px-4 py-3 focus:ring-2 focus:ring-[#D6B56C] focus:border-transparent outline-none" />
</div>
</div>
{/* Additional Info */}
<div>
<label className="block text-sm font-semibold text-[#1E3D2B] mb-1">Special Requests or Notes</label>
<textarea name="special_requests" value={formData.special_requests} onChange={handleChange} rows={4} placeholder="Any specific room preferences or arrival time?" className="w-full border border-gray-300 rounded px-4 py-3 focus:ring-2 focus:ring-[#D6B56C] focus:border-transparent outline-none"></textarea>
</div>
<button
type="submit"
disabled={isSubmitting}
className={`w-full bg-[#1E3D2B] text-[#FFFFFF] font-body font-medium py-4 rounded text-lg transition-colors duration-300 flex justify-center items-center ${isSubmitting ? 'opacity-70 cursor-not-allowed' : 'hover:bg-[#152e20]'}`}
>
{isSubmitting ? (
<>
<svg className="animate-spin -ml-1 mr-3 h-5 w-5 text-white" xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24">
<circle className="opacity-25" cx="12" cy="12" r="10" stroke="currentColor" strokeWidth="4"></circle>
<path className="opacity-75" fill="currentColor" d="M4 12a8 8 0 018-8V0C5.373 0 0 5.373 0 12h4zm2 5.291A7.962 7.962 0 014 12H0c0 3.042 1.135 5.824 3 7.938l3-2.647z"></path>
</svg>
Submitting Request...
</>
) : 'Submit Booking Request'}
</button>
</form>
</>
)}
</div>
</main>
<footer className="bg-[#1A1A1A] py-8 text-[#FFFFFF] mt-12">
<div className="max-w-4xl mx-auto px-6 text-center font-body text-sm text-gray-400">
<p>© 2026 Hôtel Marhaba. All rights reserved.</p>
</div>
</footer>
</div>
);
}
BookYourStay.getLayout = function getLayout(page: ReactElement) {
return <>{page}</>;
};

View File

@ -1,166 +1,207 @@
import React, { useEffect, useState } from 'react';
import React from 'react';
import type { ReactElement } from 'react';
import Head from 'next/head';
import Link from 'next/link';
import BaseButton from '../components/BaseButton';
import CardBox from '../components/CardBox';
import SectionFullScreen from '../components/SectionFullScreen';
import LayoutGuest from '../layouts/Guest';
import BaseDivider from '../components/BaseDivider';
import BaseButtons from '../components/BaseButtons';
import { getPageTitle } from '../config';
import { useAppSelector } from '../stores/hooks';
import CardBoxComponentTitle from "../components/CardBoxComponentTitle";
import { getPexelsImage, getPexelsVideo } from '../helpers/pexels';
export default function Starter() {
const [illustrationImage, setIllustrationImage] = useState({
src: undefined,
photographer: undefined,
photographer_url: undefined,
})
const [illustrationVideo, setIllustrationVideo] = useState({video_files: []})
const [contentType, setContentType] = useState('image');
const [contentPosition, setContentPosition] = useState('left');
const textColor = useAppSelector((state) => state.style.linkColor);
const title = 'Hotel Marhaba Luxury Site'
// Fetch Pexels image/video
useEffect(() => {
async function fetchData() {
const image = await getPexelsImage();
const video = await getPexelsVideo();
setIllustrationImage(image);
setIllustrationVideo(video);
}
fetchData();
}, []);
const imageBlock = (image) => (
<div
className='hidden md:flex flex-col justify-end relative flex-grow-0 flex-shrink-0 w-1/3'
style={{
backgroundImage: `${
image
? `url(${image?.src?.original})`
: 'linear-gradient(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.5))'
}`,
backgroundSize: 'cover',
backgroundPosition: 'left center',
backgroundRepeat: 'no-repeat',
}}
>
<div className='flex justify-center w-full bg-blue-300/20'>
<a
className='text-[8px]'
href={image?.photographer_url}
target='_blank'
rel='noreferrer'
>
Photo by {image?.photographer} on Pexels
</a>
</div>
</div>
);
const videoBlock = (video) => {
if (video?.video_files?.length > 0) {
return (
<div className='hidden md:flex flex-col justify-end relative flex-grow-0 flex-shrink-0 w-1/3'>
<video
className='absolute top-0 left-0 w-full h-full object-cover'
autoPlay
loop
muted
>
<source src={video?.video_files[0]?.link} type='video/mp4'/>
Your browser does not support the video tag.
</video>
<div className='flex justify-center w-full bg-blue-300/20 z-10'>
<a
className='text-[8px]'
href={video?.user?.url}
target='_blank'
rel='noreferrer'
>
Video by {video.user.name} on Pexels
</a>
</div>
</div>)
}
};
return (
<div
style={
contentPosition === 'background'
? {
backgroundImage: `${
illustrationImage
? `url(${illustrationImage.src?.original})`
: 'linear-gradient(rgba(255, 255, 255, 0.5), rgba(255, 255, 255, 0.5))'
}`,
backgroundSize: 'cover',
backgroundPosition: 'left center',
backgroundRepeat: 'no-repeat',
}
: {}
}
>
<div className="font-sans text-[#1A1A1A] bg-[#F5EFE6] min-h-screen">
<Head>
<title>{getPageTitle('Starter Page')}</title>
<title>{getPageTitle('Welcome')}</title>
<link rel="preconnect" href="https://fonts.googleapis.com" />
<link rel="preconnect" href="https://fonts.gstatic.com" crossOrigin="anonymous" />
<link href="https://fonts.googleapis.com/css2?family=Cormorant+Garamond:ital,wght@0,400;0,600;1,400&family=Inter:wght@300;400;500;600&family=Playfair+Display:ital,wght@0,400;0,600;0,700;1,400&display=swap" rel="stylesheet" />
<style>{`
.font-heading { font-family: 'Playfair Display', serif; }
.font-body { font-family: 'Inter', sans-serif; }
.font-accent { font-family: 'Cormorant Garamond', serif; }
`}</style>
</Head>
<SectionFullScreen bg='violet'>
<div
className={`flex ${
contentPosition === 'right' ? 'flex-row-reverse' : 'flex-row'
} min-h-screen w-full`}
>
{contentType === 'image' && contentPosition !== 'background'
? imageBlock(illustrationImage)
: null}
{contentType === 'video' && contentPosition !== 'background'
? videoBlock(illustrationVideo)
: null}
<div className='flex items-center justify-center flex-col space-y-4 w-full lg:w-full'>
<CardBox className='w-full md:w-3/5 lg:w-2/3'>
<CardBoxComponentTitle title="Welcome to your Hotel Marhaba Luxury Site app!"/>
<div className="space-y-3">
<p className='text-center text-gray-500'>This is a React.js/Node.js app generated by the <a className={`${textColor}`} href="https://flatlogic.com/generator">Flatlogic Web App Generator</a></p>
<p className='text-center text-gray-500'>For guides and documentation please check
your local README.md and the <a className={`${textColor}`} href="https://flatlogic.com/documentation">Flatlogic documentation</a></p>
</div>
<BaseButtons>
<BaseButton
href='/login'
label='Login'
color='info'
className='w-full'
/>
</BaseButtons>
</CardBox>
{/* Hero Section */}
<section className="relative w-full h-screen min-h-[600px] flex items-center justify-center overflow-hidden">
<div
className="absolute inset-0 z-0 bg-cover bg-center"
style={{
backgroundImage: "url('https://www.fernandpouillon.com/uploads/3/9/3/8/3938813/laghouatt-22_14_orig.jpg')",
}}
>
<div className="absolute inset-0 bg-[#1A1A1A] bg-opacity-40"></div>
<div className="absolute bottom-0 left-0 right-0 h-32 bg-gradient-to-t from-[#F5EFE6] to-transparent"></div>
</div>
</div>
</SectionFullScreen>
<div className='bg-black text-white flex flex-col text-center justify-center md:flex-row'>
<p className='py-6 text-sm'>© 2026 <span>{title}</span>. All rights reserved</p>
<Link className='py-6 ml-4 text-sm' href='/privacy-policy/'>
Privacy Policy
</Link>
</div>
<div className="relative z-10 text-center px-6 max-w-4xl mx-auto mt-20">
<h1 className="font-heading text-5xl md:text-7xl text-[#FFFFFF] mb-6 drop-shadow-lg">
Welcome to Hôtel Marhaba
</h1>
<p className="font-body text-lg md:text-2xl text-[#FFFFFF] mb-10 font-light drop-shadow-md max-w-2xl mx-auto">
A peaceful oasis in the heart of Laghouat, where architecture, gardens, and Algerian hospitality meet.
</p>
<div className="flex flex-col sm:flex-row justify-center gap-4">
<Link href="/book" className="bg-[#D6B56C] hover:bg-[#c2a159] text-[#1A1A1A] font-body font-medium py-3 px-8 rounded transition-colors duration-300">
Book Your Stay
</Link>
<Link href="#discover" className="bg-transparent border border-[#FFFFFF] text-[#FFFFFF] hover:bg-[#FFFFFF] hover:text-[#1A1A1A] font-body font-medium py-3 px-8 rounded transition-colors duration-300">
Discover the Hotel
</Link>
</div>
</div>
</section>
{/* Trust Section */}
<section id="trust" className="py-20 bg-[#F5EFE6]">
<div className="max-w-6xl mx-auto px-6">
<div className="text-center mb-12">
<h2 className="font-heading text-4xl text-[#1E3D2B] mb-4">Loved by Travelers</h2>
<div className="flex items-center justify-center gap-2 mb-2">
<span className="text-[#D6B56C] text-2xl"></span>
<span className="text-[#D6B56C] text-2xl"></span>
<span className="text-[#D6B56C] text-2xl"></span>
<span className="text-[#D6B56C] text-2xl"></span>
<span className="text-gray-300 text-2xl"></span>
</div>
<p className="font-body text-[#1A1A1A] font-medium">4.0 Average Rating</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-8">
<div className="bg-[#FFFFFF] p-8 rounded-xl shadow-sm flex flex-col justify-between border-t-4 border-[#D6B56C]">
<p className="font-accent italic text-lg text-[#1A1A1A] mb-4">&quot;Excellent rooms and a very helpful manager who speaks good English.&quot;</p>
<p className="font-body text-sm font-semibold text-[#1E3D2B]"> Guest Review</p>
</div>
<div className="bg-[#FFFFFF] p-8 rounded-xl shadow-sm flex flex-col justify-between border-t-4 border-[#1E3D2B]">
<p className="font-accent italic text-lg text-[#1A1A1A] mb-4">&quot;The garden is like an oasis.&quot;</p>
<p className="font-body text-sm font-semibold text-[#1E3D2B]"> Visitor</p>
</div>
<div className="bg-[#FFFFFF] p-8 rounded-xl shadow-sm flex flex-col justify-between border-t-4 border-[#D6B56C]">
<p className="font-accent italic text-lg text-[#1A1A1A] mb-4">&quot;One of the best hotels in Laghouat.&quot;</p>
<p className="font-body text-sm font-semibold text-[#1E3D2B]"> Google Review</p>
</div>
<div className="bg-[#FFFFFF] p-8 rounded-xl shadow-sm flex flex-col justify-between border-t-4 border-[#1E3D2B]">
<p className="font-accent italic text-lg text-[#1A1A1A] mb-4">&quot;Beautiful architecture and pleasant surroundings.&quot;</p>
<p className="font-body text-sm font-semibold text-[#1E3D2B]"> Traveler</p>
</div>
</div>
</div>
</section>
{/* The Story & Architecture Section */}
<section id="discover" className="py-24 bg-[#FFFFFF]">
<div className="max-w-6xl mx-auto px-6">
<div className="flex flex-col lg:flex-row items-center gap-16">
<div className="lg:w-1/2">
<h2 className="font-heading text-sm uppercase tracking-widest text-[#D6B56C] mb-2">The Story</h2>
<h3 className="font-heading text-4xl md:text-5xl text-[#1E3D2B] mb-6">A Historic Architectural Oasis</h3>
<p className="font-body text-[#1A1A1A] mb-6 leading-relaxed text-lg">
Designed in the spirit of the legendary architect <strong>Fernand Pouillon</strong>, Hôtel Marhaba is one of Laghouat&apos;s most distinctive landmarks. The property embodies a profound respect for the surrounding landscape and traditional Algerian aesthetics.
</p>
<p className="font-body text-[#1A1A1A] mb-8 leading-relaxed">
Having recently undergone a thoughtful renovation, the hotel effortlessly blends historical charm with modern comfort. Every archway and stone path tells a story of hospitality that has welcomed travelers to the Sahara for generations.
</p>
<Link href="/book" className="inline-block border-b-2 border-[#D6B56C] text-[#1E3D2B] font-heading font-semibold pb-1 hover:text-[#D6B56C] transition-colors">
Book Your Experience
</Link>
</div>
<div className="lg:w-1/2">
<img src="https://imgv2-2-f.scribdassets.com/img/document/929563449/original/c3e373047e/1?v=1" alt="Historic Architecture" className="w-full h-[500px] object-cover rounded-2xl shadow-xl" />
</div>
</div>
</div>
</section>
{/* Rooms & Garden Section */}
<section className="py-24 bg-[#F5EFE6]">
<div className="max-w-6xl mx-auto px-6">
<div className="flex flex-col-reverse lg:flex-row items-center gap-16">
<div className="lg:w-1/2 grid grid-cols-2 gap-4">
<img src="https://images.trvl-media.com/lodging/38000000/37220000/37215100/37215091/86a76116.jpg?impolicy=resizecrop&ra=fill&rh=575&rw=575" alt="Hotel Room" className="w-full h-72 object-cover rounded-tl-[3rem] rounded-br-[3rem] shadow-lg" />
<img src="https://media.joinup.travel/storage/hotel/50678/photos/20.jpg" alt="Oasis Garden" className="w-full h-72 object-cover rounded-tr-[3rem] rounded-bl-[3rem] shadow-lg mt-12" />
</div>
<div className="lg:w-1/2">
<h2 className="font-heading text-sm uppercase tracking-widest text-[#D6B56C] mb-2">Rest & Relax</h2>
<h3 className="font-heading text-4xl md:text-5xl text-[#1E3D2B] mb-6">Tranquil Rooms & Lush Gardens</h3>
<p className="font-body text-[#1A1A1A] mb-6 leading-relaxed text-lg">
Step away from the vibrant energy of the city center into our peaceful oasis. Our rooms offer excellent value and quiet comfort, featuring modern amenities wrapped in traditional design.
</p>
<p className="font-body text-[#1A1A1A] mb-8 leading-relaxed">
Wander through our spectacular interior gardens, shaded by towering palms and echoing with the sound of fountains. It is the perfect place to enjoy a morning coffee or an evening tea, surrounded by nature.
</p>
<Link href="/book" className="inline-block bg-[#1E3D2B] text-[#FFFFFF] font-body font-medium py-3 px-8 rounded hover:bg-[#152e20] transition-colors">
View Availability
</Link>
</div>
</div>
</div>
</section>
{/* Amenities / Highlights */}
<section className="py-20 bg-[#1A1A1A] text-[#FFFFFF]">
<div className="max-w-6xl mx-auto px-6">
<div className="grid grid-cols-1 md:grid-cols-3 gap-12 text-center">
<div>
<div className="text-[#D6B56C] text-4xl mb-4">📍</div>
<h4 className="font-heading text-2xl mb-2">Prime Location</h4>
<p className="font-body text-gray-400">Conveniently situated in Laghouat city center, putting the best of the city right at your doorstep.</p>
</div>
<div>
<div className="text-[#D6B56C] text-4xl mb-4">🍽</div>
<h4 className="font-heading text-2xl mb-2">Authentic Dining</h4>
<p className="font-body text-gray-400">Enjoy traditional Algerian flavors and international dishes in our beautifully appointed restaurant.</p>
</div>
<div>
<div className="text-[#D6B56C] text-4xl mb-4">🤝</div>
<h4 className="font-heading text-2xl mb-2">Friendly Staff</h4>
<p className="font-body text-gray-400">Our dedicated team is celebrated for their warm hospitality and readiness to assist in multiple languages.</p>
</div>
</div>
</div>
</section>
{/* Booking / CTA Section */}
<section id="book" className="py-32 bg-[#1E3D2B] text-[#FFFFFF] relative overflow-hidden">
<div className="absolute inset-0 opacity-10">
<div className="w-[800px] h-[800px] border border-white rounded-full absolute -top-[400px] -right-[400px]"></div>
<div className="w-[600px] h-[600px] border border-white rounded-full absolute -bottom-[300px] -left-[300px]"></div>
</div>
<div className="relative z-10 max-w-4xl mx-auto px-6 text-center">
<h2 className="font-heading text-5xl mb-6">Experience Laghouat&apos;s Architectural Gem</h2>
<p className="font-body text-xl mb-12 text-[#F5EFE6] opacity-90 max-w-2xl mx-auto">
Ready to discover where history meets comfort? Secure your dates today.
</p>
<div className="flex flex-col sm:flex-row justify-center gap-6">
<Link href="/book" className="bg-[#D6B56C] hover:bg-[#c2a159] text-[#1A1A1A] font-body font-medium py-4 px-12 rounded text-lg transition-colors duration-300">
Book Your Stay
</Link>
<a href="https://wa.me/21300000000" target="_blank" rel="noreferrer" className="bg-transparent border-2 border-[#D6B56C] text-[#D6B56C] hover:bg-[#D6B56C] hover:text-[#1A1A1A] font-body font-medium py-4 px-12 rounded text-lg transition-colors duration-300">
Contact via WhatsApp
</a>
</div>
</div>
</section>
{/* Footer */}
<footer className="bg-[#1A1A1A] py-16 text-[#FFFFFF] border-t border-gray-800">
<div className="max-w-6xl mx-auto px-6 flex flex-col md:flex-row justify-between items-center">
<div className="mb-8 md:mb-0 text-center md:text-left">
<h4 className="font-heading text-3xl text-[#D6B56C] mb-2">Hôtel Marhaba</h4>
<p className="font-body text-sm text-gray-400">A Desert Oasis of Hospitality.</p>
</div>
<div className="flex flex-wrap justify-center gap-6 font-body text-sm">
<Link href="/book" className="hover:text-[#D6B56C] transition-colors">Book Now</Link>
<Link href="#" className="hover:text-[#D6B56C] transition-colors">Privacy Policy</Link>
<Link href="#" className="hover:text-[#D6B56C] transition-colors">Terms of Service</Link>
<span className="text-gray-700">|</span>
<Link href="/login" className="hover:text-[#D6B56C] transition-colors text-gray-400">Staff Login</Link>
</div>
</div>
<div className="max-w-6xl mx-auto px-6 mt-12 text-center text-xs text-gray-600 font-body">
© 2026 Hôtel Marhaba, Laghouat. Built with care.
</div>
</footer>
</div>
);
}
Starter.getLayout = function getLayout(page: ReactElement) {
return <LayoutGuest>{page}</LayoutGuest>;
};
return <>{page}</>;
};