This commit is contained in:
Vula Builder
2026-06-23 08:39:14 +00:00
parent 0350aec5be
commit ff8d52dddb
@@ -0,0 +1,122 @@
'use client'
import { useState } from "react"
import { useMedusaProducts } from "@/hooks/useMedusaProducts"
import Button from "@/components/ui/Button"
import Badge from "@/components/ui/Badge"
import { Card, CardHeader, CardTitle, CardContent, CardFooter } from "@/components/ui/Card"
import { Shield, Tv, Wifi, Wind } from 'lucide-react'
export default function ThemedEnSuiteSection() {
const { products: rooms, isLoading, error } = useMedusaProducts({ limit: 8 })
if (isLoading) {
return (
<section data-vula-section="themedensuite" id="themed-en-suite" className="py-20 bg-white">
<div className="max-w-7xl mx-auto px-4 text-center">
<div className="w-8 h-8 border-4 border-[#d4af37] border-t-transparent rounded-full animate-spin mx-auto" />
</div>
</section>
)
}
if (error) {
return (
<section id="themed-en-suite" className="py-20 bg-white">
<div className="max-w-7xl mx-auto px-4 text-center">
<p className="text-red-500">Unable to load rooms. Please try again later.</p>
</div>
</section>
)
}
const displayRooms = (rooms ?? []).slice(0, 8)
if (displayRooms.length === 0) {
return (
<section id="themed-en-suite" className="py-20 bg-white">
<div className="max-w-7xl mx-auto px-4 text-center">
<p className="text-muted-foreground">No rooms currently available. Check back soon.</p>
</div>
</section>
)
}
return (
<section id="themed-en-suite" className="py-20 bg-white">
<div className="max-w-7xl mx-auto px-4">
<div className="text-center mb-12">
<h2 className="text-3xl md:text-4xl font-bold text-[#111827]">
Themed En-Suite Rooms
</h2>
<p className="text-[#8b5a3c] mt-4 max-w-2xl mx-auto text-lg">
Each room is uniquely styled with its own personality air-conditioned, with DStv and premium comfort.
</p>
</div>
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-6">
{displayRooms.map((room) => {
const price = room.variants?.[0]?.prices?.[0]
const formattedPrice = price
? `R${(price.amount / 100).toFixed(2)}`
: ""
return (
<Card key={room.id} className="overflow-hidden shadow-card hover:shadow-lifted transition-all duration-200 ease-out">
<div className="aspect-video overflow-hidden">
{room.thumbnail ? (
<img
src={room.thumbnail}
alt={room.title}
className="w-full h-full object-cover hover:scale-105 transition-transform duration-500 ease-out"
/>
) : (
<div className="w-full h-full bg-gray-200 flex items-center justify-center text-gray-400">
<Tv className="w-12 h-12" />
</div>
)}
</div>
<CardHeader>
<CardTitle className="text-lg text-[#111827]">{room.title}</CardTitle>
</CardHeader>
<CardContent className="text-sm text-[#8b5a3c]">
<p className="mb-3 line-clamp-2">{room.description}</p>
<div className="flex flex-wrap gap-2">
<Badge className="bg-[#16a34a] text-white flex items-center gap-1">
<Wind className="w-3 h-3" /> Air-con
</Badge>
<Badge className="bg-[#d4af37] text-white flex items-center gap-1">
<Tv className="w-3 h-3" /> DStv
</Badge>
</div>
</CardContent>
<CardFooter className="flex items-center justify-between border-t border-border pt-4">
{formattedPrice && (
<span className="font-bold text-[#111827]">{formattedPrice} / night</span>
)}
<Button
variant="default"
size="sm"
className="bg-[#d4af37] hover:bg-[#b8962f] text-white"
>
<a href={`/booking/${room.id}`}>Book Now</a>
</Button>
</CardFooter>
</Card>
)
})}
</div>
<div className="text-center mt-10">
<Button
variant="secondary"
size="lg"
className="border-[#8b5a3c] text-[#8b5a3c] hover:bg-[#8b5a3c] hover:text-white"
>
<a href="/services">View All Rooms</a>
</Button>
</div>
</div>
</section>
)
}