UNPKG

hotel-ai-widget

Version:

A customizable hotel chat widget for React and vanilla HTML

72 lines (71 loc) 12.6 kB
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; import { Car, ChevronDown, Clock, CreditCard, Hotel, Landmark, MapPin, Plane, } from "lucide-react"; import { useEffect, useState } from "react"; export const InclusionSection = ({ className = "", isStreaming, itinerary, }) => { const [expandedInclusionCategories, setExpandedInclusionCategories] = useState([]); useEffect(() => { setExpandedInclusionCategories([ "attractions", "hotels", "flights", "transport", ]); }, []); 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: _jsx("div", { className: "animate-spin rounded-full h-6 w-6 border-t-2 border-blue-500" }) })) : !itinerary ? (_jsx("div", { className: "flex-1 flex items-center justify-center", children: _jsxs("div", { className: "text-center py-8", children: [_jsx(Hotel, { className: "w-8 h-8 text-gray-300 mx-auto mb-2" }), _jsx("p", { className: "text-gray-500 text-xs", children: "No inclusions available" }), _jsx("p", { className: "text-xs text-gray-400 mt-1", children: "Ask me to create an itinerary!" })] }) })) : (_jsxs(_Fragment, { children: [_jsx("div", { className: "bg-white px-3 py-2 border-b flex-shrink-0 border-gray-300", children: _jsx("h1", { className: "text-sm font-bold", children: "Inclusions" }) }), _jsx("div", { className: "flex-1 px-3 py-2 overflow-y-auto", children: (() => { const inclusionData = itinerary.data.itinerarySummary.find((item) => item["view-type"] === "inclusions"); if (!inclusionData) { return (_jsxs("div", { className: "text-center py-8", children: [_jsx(Hotel, { className: "w-8 h-8 text-gray-300 mx-auto mb-2" }), _jsx("p", { className: "text-gray-500 text-xs", children: "No inclusions available" })] })); } return (_jsx("div", { className: "space-y-4", children: inclusionData.inclusions.inclusions.length > 0 && inclusionData.inclusions.inclusions.map((item, itemIndex) => { const attractions = item.attractions || []; const hotels = item.hotels || []; const flights = item.flights || []; const transport = item.transport || []; const validAttractions = attractions.filter((attr) => attr.metadata && attr.metadata.length > 0); const validFlights = flights.filter((flight) => flight.metadata && flight.metadata.length > 0); const validTransport = transport.filter((trans) => trans.metadata && trans.metadata.length > 0); const validHotels = hotels; return (_jsxs("div", { className: "space-y-3", children: [validAttractions.length > 0 && (_jsxs("div", { children: [_jsxs("button", { onClick: () => { setExpandedInclusionCategories((prev) => prev.includes("attractions") ? prev.filter((cat) => cat !== "attractions") : [...prev, "attractions"]); }, className: "flex items-center gap-2 w-full text-left mb-2", children: [_jsx(ChevronDown, { className: `w-3 h-3 text-gray-500 transition-transform ${expandedInclusionCategories.includes("attractions") ? "rotate-0" : "-rotate-90"}` }), _jsxs("h3", { className: "text-xs font-semibold", children: ["Attractions (", validAttractions.length, ")"] })] }), _jsx("div", { className: `overflow-hidden transition-all duration-300 ${expandedInclusionCategories.includes("attractions") ? "max-h-96 opacity-100" : "max-h-0 opacity-0"}`, children: _jsx("div", { className: "space-y-2", children: validAttractions.map((attraction, idx) => (_jsx("div", { className: "border border-gray-100 rounded-lg p-2", children: _jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Landmark, { className: "w-3 h-3 text-gray-500 mt-0.5 flex-shrink-0" }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("h4", { className: "font-medium text-xs mb-1", children: attraction.metadata[0]?.name || "Attraction" }), attraction.metadata[0] ?.description && (_jsx("p", { className: "text-xs text-gray-600 mb-1", children: attraction.metadata[0] .description })), _jsxs("div", { className: "flex flex-wrap gap-2 text-xs text-gray-500", children: [attraction.time && (_jsxs("span", { className: "flex items-center gap-1", children: [_jsx(Clock, { className: "w-2 h-2" }), attraction.time] })), attraction.metadata[0] ?.payment && (_jsxs("span", { className: "flex items-center gap-1", children: [_jsx(CreditCard, { className: "w-2 h-2" }), attraction.metadata[0] .payment] }))] })] })] }) }, idx))) }) })] })), validHotels.length > 0 && (_jsxs("div", { children: [_jsxs("button", { onClick: () => { setExpandedInclusionCategories((prev) => prev.includes("hotels") ? prev.filter((cat) => cat !== "hotels") : [...prev, "hotels"]); }, className: "flex items-center gap-2 w-full text-left mb-2", children: [_jsx(ChevronDown, { className: `w-3 h-3 text-gray-500 transition-transform ${expandedInclusionCategories.includes("hotels") ? "rotate-0" : "-rotate-90"}` }), _jsxs("h3", { className: "text-xs font-semibold", children: ["Hotels (", validHotels.length, ")"] })] }), _jsx("div", { className: `overflow-hidden transition-all duration-300 ${expandedInclusionCategories.includes("hotels") ? "max-h-96 opacity-100" : "max-h-0 opacity-0"}`, children: _jsx("div", { className: "space-y-2", children: validHotels.map((hotel, idx) => (_jsx("div", { className: "border border-gray-100 rounded-lg p-2", children: _jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Hotel, { className: "w-3 h-3 text-gray-500 mt-0.5 flex-shrink-0" }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("h4", { className: "font-medium text-xs mb-1", children: hotel.name || "Hotel" }), _jsxs("div", { className: "flex flex-wrap gap-2 text-xs text-gray-500", children: [hotel["check-in"] && (_jsxs("span", { className: "flex items-center gap-1", children: [_jsx(Clock, { className: "w-2 h-2" }), "Check-in: ", hotel["check-in"]] })), hotel["check-out"] && (_jsxs("span", { className: "flex items-center gap-1", children: [_jsx(Clock, { className: "w-2 h-2" }), "Check-out:", " ", hotel["check-out"]] }))] })] })] }) }, idx))) }) })] })), validFlights.length > 0 && (_jsxs("div", { children: [_jsxs("button", { onClick: () => { setExpandedInclusionCategories((prev) => prev.includes("flights") ? prev.filter((cat) => cat !== "flights") : [...prev, "flights"]); }, className: "flex items-center gap-2 w-full text-left mb-2", children: [_jsx(ChevronDown, { className: `w-3 h-3 text-gray-500 transition-transform ${expandedInclusionCategories.includes("flights") ? "rotate-0" : "-rotate-90"}` }), _jsxs("h3", { className: "text-xs font-semibold", children: ["Flights (", validFlights.length, ")"] })] }), _jsx("div", { className: `overflow-hidden transition-all duration-300 ${expandedInclusionCategories.includes("flights") ? "max-h-96 opacity-100" : "max-h-0 opacity-0"}`, children: _jsx("div", { className: "space-y-2", children: validFlights.map((flight, idx) => (_jsx("div", { className: "border border-gray-100 rounded-lg p-2", children: _jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Plane, { className: "w-3 h-3 text-gray-500 mt-0.5 flex-shrink-0" }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("h4", { className: "font-medium text-xs mb-1", children: flight.metadata[0]?.airline || "Flight" }), _jsxs("div", { className: "flex flex-wrap gap-2 text-xs text-gray-500", children: [flight.date && (_jsxs("span", { className: "flex items-center gap-1", children: [_jsx(Clock, { className: "w-2 h-2" }), flight.date] })), flight.metadata[0]?.from && flight.metadata[0]?.to && (_jsxs("span", { className: "flex items-center gap-1", children: [_jsx(MapPin, { className: "w-2 h-2" }), flight.metadata[0].from, " \u2192", " ", flight.metadata[0].to] }))] })] })] }) }, idx))) }) })] })), validTransport.length > 0 && (_jsxs("div", { children: [_jsxs("button", { onClick: () => { setExpandedInclusionCategories((prev) => prev.includes("transport") ? prev.filter((cat) => cat !== "transport") : [...prev, "transport"]); }, className: "flex items-center gap-2 w-full text-left mb-2", children: [_jsx(ChevronDown, { className: `w-3 h-3 text-gray-500 transition-transform ${expandedInclusionCategories.includes("transport") ? "rotate-0" : "-rotate-90"}` }), _jsxs("h3", { className: "text-xs font-semibold", children: ["Transport (", validTransport.length, ")"] })] }), _jsx("div", { className: `overflow-hidden transition-all duration-300 ${expandedInclusionCategories.includes("transport") ? "max-h-96 opacity-100" : "max-h-0 opacity-0"}`, children: _jsx("div", { className: "space-y-2", children: validTransport.map((item, idx) => (_jsx("div", { className: "border border-gray-100 rounded-lg p-2", children: _jsxs("div", { className: "flex items-start gap-2", children: [_jsx(Car, { className: "w-3 h-3 text-gray-500 mt-0.5 flex-shrink-0" }), _jsxs("div", { className: "flex-1 min-w-0", children: [_jsx("h4", { className: "font-medium text-xs mb-1", children: item.metadata[0]?.["transport-type"] || "Transport" }), _jsxs("div", { className: "flex flex-wrap gap-2 text-xs text-gray-500", children: [item.time && (_jsxs("span", { className: "flex items-center gap-1", children: [_jsx(Clock, { className: "w-2 h-2" }), item.time] })), item.metadata[0]?.payment && (_jsxs("span", { className: "flex items-center gap-1", children: [_jsx(CreditCard, { className: "w-2 h-2" }), item.metadata[0].payment] }))] })] })] }) }, idx))) }) })] }))] }, itemIndex)); }) })); })() })] })) })); };