hotel-ai-widget
Version:
A customizable hotel chat widget for React and vanilla HTML
34 lines (33 loc) • 6.95 kB
JavaScript
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
import { ChevronDown, Grid, ImageIcon, List } from "lucide-react";
import { useState } from "react";
export const HotelImagesSection = ({ className = "", hotelImagesData, isStreaming, }) => {
const [viewMode, setViewMode] = useState("grid");
const [expandedCategories, setExpandedCategories] = useState([]);
const [selectedImage, setSelectedImage] = useState(null);
console.log('hotelImagesData', hotelImagesData);
return (_jsx("div", { className: `flex-1 flex flex-col overflow-hidden ${className}`, children: isStreaming ? (_jsx("div", { className: "flex-1 flex items-center justify-center", children: _jsxs("div", { className: "text-center", children: [_jsx("div", { className: "animate-spin rounded-full h-6 w-6 border-t-2 border-blue-500 mx-auto mb-2" }), _jsx("p", { className: "text-xs text-gray-500", children: "Loading hotel images..." })] }) })) : !hotelImagesData || !hotelImagesData.length ? (_jsx("div", { className: "flex-1 flex items-center justify-center", children: _jsxs("div", { className: "text-center py-8", children: [_jsx(ImageIcon, { className: "w-8 h-8 text-gray-300 mx-auto mb-3" }), _jsx("p", { className: "text-gray-500 text-xs", children: "No images found" }), _jsx("p", { className: "text-xs text-gray-400 mt-1", children: "Ask me to show hotel images!" })] }) })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "bg-white px-3 py-2 border-b flex-shrink-0 border-gray-300", children: _jsxs("div", { className: "flex items-center justify-between", children: [_jsxs("div", { className: "flex items-baseline gap-2", children: [_jsx("h1", { className: "text-sm font-bold", children: "Hotel Images" }), _jsxs("span", { className: "text-xs text-gray-500", children: [hotelImagesData.length, " images"] })] }), _jsxs("div", { className: "flex items-center gap-1 bg-gray-100 rounded-lg p-0.5", children: [_jsx("button", { onClick: () => setViewMode("grid"), className: `p-1 rounded-md transition-colors ${viewMode === "grid"
? "bg-white text-gray-900 shadow-sm"
: "text-gray-500 hover:text-gray-700"}`, children: _jsx(Grid, { className: "w-3 h-3" }) }), _jsx("button", { onClick: () => setViewMode("list"), className: `p-1 rounded-md transition-colors ${viewMode === "list"
? "bg-white text-gray-900 shadow-sm"
: "text-gray-500 hover:text-gray-700"}`, children: _jsx(List, { className: "w-3 h-3" }) })] })] }) }), _jsx("div", { className: "flex-1 px-3 py-2 overflow-y-auto", children: (() => {
const imagesByCategory = hotelImagesData.reduce((acc, image) => {
const category = image.image_type || "Other";
if (!acc[category]) {
acc[category] = [];
}
acc[category].push(image);
return acc;
}, {});
const categories = Object.keys(imagesByCategory);
return categories.map((category) => (_jsxs("div", { className: "mb-4 last:mb-0", children: [_jsxs("button", { onClick: () => {
setExpandedCategories((prev) => prev.includes(category)
? prev.filter((c) => c !== category)
: [...prev, category]);
}, className: "flex items-center gap-2 w-full text-left mb-3 group", children: [_jsx(ChevronDown, { className: `flex-shrink-0 text-gray-500 transition-transform duration-300 ease-in-out w-3 h-3 ${expandedCategories.includes(category)
? "rotate-0"
: "-rotate-90"}` }), _jsxs("div", { children: [_jsx("h2", { className: "text-xs font-semibold group-hover:text-gray-700 transition-colors capitalize", children: category }), _jsxs("p", { className: "text-xs text-gray-500", children: [imagesByCategory[category].length, " images"] })] })] }), _jsx("div", { className: `overflow-hidden transition-all duration-300 ease-in-out ${expandedCategories.includes(category)
? "max-h-[1000px] opacity-100"
: "max-h-0 opacity-0"}`, children: viewMode === "grid" ? (_jsx("div", { className: "grid grid-cols-2 gap-2", children: imagesByCategory[category].map((image, idx) => (_jsxs("div", { className: "bg-white border border-gray-200 rounded-lg overflow-hidden hover:border-gray-300 transition-all duration-200 group", children: [_jsx("div", { className: "aspect-video relative overflow-hidden", children: _jsx("img", { src: image.image_url || "/placeholder.svg", alt: image.description || "Hotel image", className: "cursor-pointer w-full h-full object-cover group-hover:scale-105 transition-transform duration-300", loading: "lazy", onClick: () => setSelectedImage(image.image_url) }) }), image.description && (_jsx("div", { className: "p-2", children: _jsx("p", { className: "text-xs text-gray-600 line-clamp-2", children: image.description }) }))] }, idx))) })) : (_jsx("div", { className: "space-y-2", children: imagesByCategory[category].map((image, idx) => (_jsx("div", { className: "bg-white border border-gray-200 rounded-lg p-2 hover:border-gray-300 transition-all duration-200", children: _jsxs("div", { className: "flex gap-2", children: [_jsx("div", { className: "w-12 h-9 rounded-lg overflow-hidden flex-shrink-0", children: _jsx("img", { src: image.image_url || "/placeholder.svg", alt: image.description || "Hotel image", className: "cursor-pointer w-full h-full object-cover", loading: "lazy", onClick: () => setSelectedImage(image.image_url) }) }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("h3", { className: "font-medium text-gray-900 mb-1 truncate text-xs", children: image.description || "Hotel image" }), image.description && (_jsx("p", { className: "text-xs text-gray-600 line-clamp-2", children: image.description }))] })] }) }, idx))) })) })] }, category)));
})() }), selectedImage && (_jsx("div", { className: "fixed inset-0 bg-black/70 z-50 flex items-center justify-center", onClick: () => setSelectedImage(null), children: _jsxs("div", { className: "relative max-w-4xl w-full p-4", onClick: (e) => e.stopPropagation(), children: [_jsx("button", { className: "absolute top-4 right-4 text-white text-xl bg-black/50 rounded-full p-2 hover:bg-black px-3 pb-1", onClick: () => setSelectedImage(null), children: "\u00D7" }), _jsx("img", { src: selectedImage || "/placeholder.svg", alt: "Expanded", className: "max-h-[80vh] w-full object-contain rounded-lg shadow-xl" })] }) }))] })) }));
};