const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["../../../dist/js/TripForm-DEQpXvzy.js","../../../dist/js/react-vendor-CithbthY.js","../css/react-vendor.css","../../../dist/js/index-Dec_weLB.js","../css/index.css","../../../dist/js/BuildItineraryModal-CzFq1WTm.js","../../../dist/js/ProFeature-DE6oH70S.js","../../../dist/js/Settings-BCwXvDOi.js","../../../dist/js/Team-M9W1qR00.js","../../../dist/js/Reports-JeXttK0I.js","../../../dist/js/DiscountForm-DYxWHwCn.js","../../../dist/js/ApplicableTripSelector-BZ25j59n.js","../../../dist/js/Itinerary-C1e5Vxj0.js","../../../dist/js/RecurringRuleForm-fKEgpUir.js","./Whatsapp.js","../../../dist/js/module-skeleton-CpoAoviJ.js","../../../dist/js/ChannelManager-DZ64KNZZ.js","../../../dist/js/Webhooks-Cb89OgkB.js","../../../dist/js/ScheduledPayments-BnLNP2BI.js","../../../dist/js/TripConsentForm-C4az7Muo.js","../../../dist/js/BookingForm-hQVneAfI.js","../../../dist/js/ViewBooking-CgYCok3W.js","../../../dist/js/AvailabilityForm-D4S_wB_o.js","../../../dist/js/DynamicPricing-CBtPFtKK.js","../../../dist/js/RuleTypeSelectionModal-_WAr6JyA.js","../../../dist/js/toggle-CKa3ExrH.js","../../../dist/js/DynamicPricingRuleForm-C99aT0Zu.js","../../../dist/js/AiAssistant-Bu_zHUnt.js","../../../dist/js/AbandonedRecovery-BHbQat9C.js","../../../dist/js/WhiteLabel-DsK2IbJo.js"])))=>i.map(i=>d[i]); var __defProp = Object.defineProperty; var __defNormalProp = (obj, key2, value) => key2 in obj ? __defProp(obj, key2, { enumerable: true, configurable: true, writable: true, value }) : obj[key2] = value; var __publicField = (obj, key2, value) => __defNormalProp(obj, typeof key2 !== "symbol" ? key2 + "" : key2, value); import { r as reactExports, j as jsxRuntimeExports, W as Wrench, N as Network, M as MessageCircle, S as Sparkles, R as RotateCcw, P as Puzzle, a as MessageSquare, b as Plane, B as BadgePercent, c as Route, F as FileSignature, K as Key, d as Mail, C as Crown, A as Activity, L as List, T as TrendingUp, e as Tag, f as FolderTree, U as Users, g as CircleUser, h as Package, i as CreditCard, k as FileText, l as Settings$1, m as BarChart3, n as Star, o as CalendarDays, p as CalendarClock, q as Calendar$1, s as MapPin, t as LayoutDashboard, u as useQuery, v as useQueryClient, w as useMutation, Z as Zap, x as Webhook, y as ChevronDown, z as ChevronRight, D as ArrowLeft, G as Gift, E as Loader2, H as Sun, I as Moon, J as User, O as RefreshCw, Q as Inbox, V as AlertTriangle, X as ExternalLink, Y as isObjectLike_1, _ as _baseGetTag, $ as isArray_1, a0 as _MapCache, a1 as getDefaultExportFromCjs, a2 as _Symbol, a3 as isObject$5, a4 as isFunction, a5 as reactIsExports, a6 as React, a7 as _Stack, a8 as _baseIsEqual, a9 as isObject_1, aa as keys_1, ab as isLength_1, ac as _isIndex, ad as isArguments_1, ae as _Set, af as _setToArray, ag as _SetCache, ah as _cacheHas, ai as _arrayPush, aj as isArrayLike_1, ak as _baseUnary, al as _getNative, am as eq_1, an as _root, ao as isEqual, ap as Animate, aq as _overArg, ar as _arraySome, as as Clock, at as DollarSign, au as ArrowRight, av as Shield, aw as CheckCircle, ax as Plus, ay as X, az as reactDomExports, aA as AlertCircle, aB as Check, aC as Wand2, aD as ChevronLeft, aE as CheckCircle2, aF as HelpCircle, aG as Info, aH as Copy, aI as MoreVertical, aJ as Columns, aK as PenSquare, aL as ArrowUp, aM as ArrowDown, aN as Archive, aO as Trash2, aP as Search, aQ as ArrowUpDown, aR as Eye, aS as Upload, aT as Image, aU as ReactQuill, aV as Pen, aW as Save, aX as Download, aY as CircleDollarSign, aZ as Undo2, a_ as Phone, a$ as PauseCircle, b0 as ShieldX, b1 as ShieldOff, b2 as Globe, b3 as Award, b4 as Database, b5 as Folder, b6 as Mountain, b7 as UserCheck, b8 as Server, b9 as XCircle, ba as Video, bb as Lock, bc as GripVertical, bd as ChevronUp, be as Play, bf as ClipboardCopy, bg as Ban, bh as Bell, bi as Heart, bj as Scissors, bk as Send, bl as Filter, bm as ArrowUpRight, bn as ClipboardCheck, bo as PenTool, bp as Camera, bq as BarChart$1, br as Megaphone, bs as Compass, bt as GitBranch, bu as Pause, bv as Settings2, bw as Code, bx as Bug, by as EyeOff, bz as QueryClient, bA as client, bB as QueryClientProvider } from "../../../dist/js/react-vendor-CithbthY.js"; import { a as apiClient, A as API_ENDPOINTS, u as useToast, _ as __, b as apiService, n as normalizeCurrencyPosition, t as toDateValue, f as formatYatraMoney, r as readYatraCurrencyPositionFromWindow, s as sprintf, c as brandName, d as formatDateForInput, I as Input, e as formatDate$1, g as todayYmd, S as SearchableSelect, h as getCurrencySymbol, i as getCountryName, j as ajaxService, T as ToastProvider, E as ErrorBoundary } from "../../../dist/js/index-Dec_weLB.js"; const scriptRel = "modulepreload"; const assetsURL = function(dep, importerUrl) { return new URL(dep, importerUrl).href; }; const seen = {}; const __vitePreload = function preload(baseModule, deps, importerUrl) { let promise = Promise.resolve(); if (deps && deps.length > 0) { const links = document.getElementsByTagName("link"); const cspNonceMeta = document.querySelector( "meta[property=csp-nonce]" ); const cspNonce = (cspNonceMeta == null ? void 0 : cspNonceMeta.nonce) || (cspNonceMeta == null ? void 0 : cspNonceMeta.getAttribute("nonce")); promise = Promise.allSettled( deps.map((dep) => { dep = assetsURL(dep, importerUrl); if (dep in seen) return; seen[dep] = true; const isCss = dep.endsWith(".css"); const cssSelector = isCss ? '[rel="stylesheet"]' : ""; const isBaseRelative = !!importerUrl; if (isBaseRelative) { for (let i = links.length - 1; i >= 0; i--) { const link22 = links[i]; if (link22.href === dep && (!isCss || link22.rel === "stylesheet")) { return; } } } else if (document.querySelector(`link[href="${dep}"]${cssSelector}`)) { return; } const link2 = document.createElement("link"); link2.rel = isCss ? "stylesheet" : scriptRel; if (!isCss) { link2.as = "script"; } link2.crossOrigin = ""; link2.href = dep; if (cspNonce) { link2.setAttribute("nonce", cspNonce); } document.head.appendChild(link2); if (isCss) { return new Promise((res, rej) => { link2.addEventListener("load", res); link2.addEventListener( "error", () => rej(new Error(`Unable to preload CSS for ${dep}`)) ); }); } }) ); } function handlePreloadError(err) { const e = new Event("vite:preloadError", { cancelable: true }); e.payload = err; window.dispatchEvent(e); if (!e.defaultPrevented) { throw err; } } return promise.then((res) => { for (const item of res || []) { if (item.status !== "rejected") continue; handlePreloadError(item.reason); } return baseModule().catch(handlePreloadError); }); }; const Button = reactExports.forwardRef( ({ className = "", variant = "default", size = "default", asChild = false, children, ...props }, ref) => { const baseClasses = "inline-flex items-center justify-center rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50"; const variantClasses = { default: "bg-blue-600 text-white hover:bg-blue-700 dark:bg-blue-500 dark:hover:bg-blue-600", outline: "border border-gray-300 bg-transparent hover:bg-gray-100 dark:border-gray-600 dark:hover:bg-gray-800", ghost: "hover:bg-gray-100 dark:hover:bg-gray-800", destructive: "bg-red-600 text-white hover:bg-red-700 dark:bg-red-500 dark:hover:bg-red-600" }; const sizeClasses2 = { default: "h-10 px-4 py-2", sm: "h-9 rounded-md px-3", lg: "h-11 rounded-md px-8", icon: "h-10 w-10" }; const mergedClassName = `${baseClasses} ${variantClasses[variant]} ${sizeClasses2[size]} ${className}`; if (asChild && reactExports.isValidElement(children)) { const child = children; const childClassName = child.props.className; return reactExports.cloneElement(child, { ...props, className: `${mergedClassName}${childClassName ? ` ${childClassName}` : ""}` }); } return /* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: mergedClassName, ref, ...props, children }); } ); Button.displayName = "Button"; const Tooltip$1 = ({ content, children, side = "top", className = "" }) => { const id = reactExports.useId(); const [open, setOpen] = reactExports.useState(false); if (!content) { return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className, children }); } const popoverPos = { top: "bottom-full left-1/2 -translate-x-1/2 mb-1.5", bottom: "top-full left-1/2 -translate-x-1/2 mt-1.5", left: "right-full top-1/2 -translate-y-1/2 mr-1.5", right: "left-full top-1/2 -translate-y-1/2 ml-1.5" }; const arrowPos = { top: "top-full left-1/2 -translate-x-1/2 border-t-gray-900 dark:border-t-gray-100", bottom: "bottom-full left-1/2 -translate-x-1/2 border-b-gray-900 dark:border-b-gray-100", left: "left-full top-1/2 -translate-y-1/2 border-l-gray-900 dark:border-l-gray-100", right: "right-full top-1/2 -translate-y-1/2 border-r-gray-900 dark:border-r-gray-100" }; const arrowStyle = { top: "border-x-transparent border-b-transparent", bottom: "border-x-transparent border-t-transparent", left: "border-y-transparent border-r-transparent", right: "border-y-transparent border-l-transparent" }; return /* @__PURE__ */ jsxRuntimeExports.jsxs( "span", { className: `relative inline-flex items-center ${className}`, onMouseEnter: () => setOpen(true), onMouseLeave: () => setOpen(false), onFocus: () => setOpen(true), onBlur: () => setOpen(false), onKeyDown: (e) => { if (e.key === "Escape") setOpen(false); }, children: [ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { "aria-describedby": open ? id : void 0, tabIndex: 0, children }), open && /* @__PURE__ */ jsxRuntimeExports.jsxs( "span", { id, role: "tooltip", className: `absolute z-50 pointer-events-none whitespace-normal break-words rounded-md bg-gray-900 px-2.5 py-1.5 text-xs font-normal leading-snug text-white shadow-lg max-w-xs w-max dark:bg-gray-100 dark:text-gray-900 ${popoverPos[side]}`, children: [ content, /* @__PURE__ */ jsxRuntimeExports.jsx( "span", { "aria-hidden": "true", className: `absolute h-0 w-0 border-[6px] ${arrowStyle[side]} ${arrowPos[side]}` } ) ] } ) ] } ); }; function unwrapApiPayload(raw) { if (raw !== null && typeof raw === "object") { const r2 = raw; if (r2.success === true && "data" in r2) { return r2.data; } } return raw; } async function fetchSettings() { return unwrapApiPayload( await apiClient.get(API_ENDPOINTS.SETTINGS) ); } async function saveSettings(data) { return apiClient.put(API_ENDPOINTS.SETTINGS, data); } async function previewCoreEmailTemplate(payload) { const response = await apiClient.post( API_ENDPOINTS.SETTINGS_EMAIL_TEMPLATE_PREVIEW, payload ); return unwrapApiPayload(response); } async function fetchWordPressPages() { return apiClient.get(API_ENDPOINTS.SETTINGS_PAGES); } async function postFlushRewriteRules() { return apiClient.post(API_ENDPOINTS.SETTINGS_FLUSH_REWRITE_RULES); } async function fetchBookingPageShortcodeStatus(pageId) { return apiClient.get(API_ENDPOINTS.SETTINGS_CHECK_SHORTCODE(pageId)); } async function postInsertBookingShortcode(pageId) { return apiClient.post(API_ENDPOINTS.SETTINGS_INSERT_SHORTCODE(pageId)); } async function fetchPaymentGatewayDefinitions() { return apiClient.get(API_ENDPOINTS.PAYMENT_GATEWAY_DEFINITIONS); } const usePermissions = () => { const permissions = reactExports.useMemo(() => { var _a; return ((_a = window.yatraAdmin) == null ? void 0 : _a.permissions) || []; }, []); const roles = reactExports.useMemo(() => { var _a; return ((_a = window.yatraAdmin) == null ? void 0 : _a.roles) || []; }, []); const capabilities = reactExports.useMemo(() => { var _a; return ((_a = window.yatraAdmin) == null ? void 0 : _a.capabilities) || {}; }, []); const isPro = reactExports.useMemo(() => { var _a; return ((_a = window.yatraAdmin) == null ? void 0 : _a.isPro) || false; }, []); const can = reactExports.useCallback( (capability) => { var _a; if (capabilities[capability] === true) { return true; } const userCaps = (_a = window.yatraAdmin) == null ? void 0 : _a.userCaps; if (Array.isArray(userCaps) && userCaps.includes(capability)) { return true; } if (permissions.includes(capability)) { return true; } const adm = window.yatraAdmin; if (adm) { if (adm.isWpAdmin === true || adm.isWpAdmin === "1" || adm.isWpAdmin === 1) { return true; } if (Array.isArray(adm.roles) && adm.roles.includes("administrator")) { return true; } if (adm.capabilities && adm.capabilities["manage_options"] === true) { return true; } } if (capability.startsWith("yatra_pro_") && !isPro) { return false; } return false; }, [capabilities, permissions, isPro] ); const hasRole = (role) => { return roles.includes(role); }; return { can, hasRole, isPro, permissions, roles }; }; const ConditionalRender = ({ children, capability, role, requirePro = false, fallback = null, className = "" }) => { const { can, hasRole, isPro } = usePermissions(); let shouldRender = true; if (capability && !can(capability)) { shouldRender = false; } if (role && !hasRole(role)) { shouldRender = false; } if (requirePro && !isPro) { shouldRender = false; } if (!shouldRender) { return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: fallback }); } return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className, children }); }; const DEFAULT_MENU_ITEMS = [ { slug: "dashboard", label: "Dashboard", iconName: "LayoutDashboard" }, { slug: "trips", label: "Trips", iconName: "MapPin", submenu: [ { key: "trips.all", parentSlug: "trips", tab: "all", label: "All Trips", iconName: "List" }, { key: "trips.activities", parentSlug: "trips", tab: "activities", label: "Activities", iconName: "Activity" }, { key: "trips.destinations", parentSlug: "trips", tab: "destinations", label: "Destinations", iconName: "Route" }, { key: "trips.categories", parentSlug: "trips", tab: "categories", label: "Categories", iconName: "FolderTree" }, { key: "trips.difficulty-levels", parentSlug: "trips", tab: "difficulty-levels", label: "Difficulty Levels", iconName: "TrendingUp" }, { key: "trips.availability", parentSlug: "trips", tab: "availability", label: "Availability", iconName: "CalendarDays" }, { key: "trips.attributes", parentSlug: "trips", tab: "attributes", label: "Attributes", iconName: "Tag" }, { key: "trips.additional-services", parentSlug: "trips", tab: "additional-services", label: "Additional Services", iconName: "Package" }, { key: "trips.trip-consent", parentSlug: "trips", tab: "trip-consent", label: "Trip Consent", iconName: "FileSignature" } ] }, { slug: "traveler-categories", label: "Traveler Categories", iconName: "Users" }, { slug: "itinerary", label: "Itinerary", iconName: "Route", submenu: [ { key: "itinerary.item-types", parentSlug: "itinerary", tab: "item-types", label: "Item Types", iconName: "Tag" }, { key: "itinerary.items", parentSlug: "itinerary", tab: "items", label: "Items", iconName: "Route" }, { key: "itinerary.itinerary", parentSlug: "itinerary", tab: "itinerary", label: "Itinerary", iconName: "FileText" } ] }, { slug: "departures", label: "Departures", iconName: "Calendar" }, { slug: "discounts", label: "Discounts", iconName: "BadgePercent" }, { slug: "payments", label: "Payments", iconName: "CreditCard", submenu: [ { key: "payments.all", parentSlug: "payments", tab: "all", label: "All Payments", iconName: "CreditCard" }, // Pro "Scheduled Payments" module. Listed so it can be reordered or // hidden in the menu customizer; actual visibility is still gated on the // module flag at render time, like every other Pro-gated entry. { key: "payments.scheduled", parentSlug: "payments", tab: "scheduled", label: "Scheduled", iconName: "CalendarClock" } ] }, { slug: "bookings", label: "Bookings", iconName: "Calendar" }, { slug: "customers", label: "Customers", iconName: "UserCircle" }, { slug: "travelers", label: "Travelers", iconName: "Plane" }, { slug: "enquiries", label: "Enquiries", iconName: "MessageSquare" }, { slug: "reviews", label: "Reviews", iconName: "Star" }, { slug: "reports", label: "Reports", iconName: "BarChart3" }, { slug: "email-automation", label: "Email", iconName: "Mail" }, { slug: "abandoned-recovery", label: "Abandoned Recovery", iconName: "RotateCcw" }, { slug: "dynamic-pricing", label: "Dynamic Pricing", iconName: "TrendingUp" }, { slug: "modules", label: "Modules", iconName: "Puzzle" }, { slug: "white-label", label: "White Label", iconName: "Crown" }, { slug: "ai-assistant", label: "AI Assistant", iconName: "Sparkles" }, { slug: "whatsapp", label: "WhatsApp", iconName: "MessageCircle" }, { slug: "channel-manager", label: "Channel Manager", iconName: "Network" }, { slug: "webhooks", label: "Webhooks", iconName: "Webhook" }, { slug: "team", label: "Team & Access", iconName: "Users" }, { slug: "license", label: "License", iconName: "Key" }, { slug: "settings", label: "Settings", iconName: "Settings" } ]; function readMenuOrder() { var _a; const raw = (_a = window.yatraAdmin) == null ? void 0 : _a.brandMenuOrder; if (Array.isArray(raw)) { return { "": raw.filter((s2) => typeof s2 === "string") }; } if (raw && typeof raw === "object") { const out = {}; for (const [key2, list] of Object.entries(raw)) { if (typeof key2 === "string" && Array.isArray(list)) { out[key2] = list.filter((s2) => typeof s2 === "string"); } } return out; } return {}; } function readUiChrome() { var _a; const raw = (_a = window.yatraAdmin) == null ? void 0 : _a.brandUiChrome; if (!raw || typeof raw !== "object") return {}; return raw; } function readMenuOverrides() { var _a; const raw = (_a = window.yatraAdmin) == null ? void 0 : _a.brandMenuOverrides; if (!raw || typeof raw !== "object") return {}; return raw; } const ICON_MAP = { LayoutDashboard, MapPin, Calendar: Calendar$1, CalendarClock, CalendarDays, Star, BarChart3, Settings: Settings$1, Wrench, FileText, CreditCard, Package, UserCircle: CircleUser, Users, FolderTree, Tag, TrendingUp, List, Activity, Crown, Mail, Key, FileSignature, Route, BadgePercent, Plane, MessageSquare, Puzzle, RotateCcw, Sparkles, MessageCircle, Network, Tools: Wrench }; const accessibility = { label: "Accessibility", category: "general", svg: ' ' }; const activity = { label: "Activity", category: "activity", svg: '' }; const anchor = { label: "Anchor", category: "activity", svg: ' ' }; const archive = { label: "Archive", category: "media", svg: '' }; const award = { label: "Award", category: "general", svg: ' ' }; const backpack = { label: "Backpack", category: "general", svg: ' ' }; const banknote = { label: "Banknote", category: "general", svg: ' ' }; const beach = { label: "Beach", category: "activity", svg: '' }; const bed = { label: "Bed", category: "accommodation", svg: '' }; const bell = { label: "Bell", category: "general", svg: ' ' }; const bike = { label: "Bike", category: "activity", svg: ' ' }; const binoculars = { label: "Binoculars", category: "activity", svg: ' ' }; const bluetooth = { label: "Bluetooth", category: "general", svg: ' ' }; const book = { label: "Education", category: "general", svg: '' }; const bookmark = { label: "Bookmark", category: "general", svg: ' ' }; const briefcase = { label: "Briefcase", category: "general", svg: ' ' }; const brush = { label: "Brush", category: "general", svg: ' ' }; const building = { label: "Building", category: "accommodation", svg: '' }; const bus = { label: "Bus", category: "transport", svg: '' }; const cactus = { label: "Cactus", category: "activity", svg: '' }; const cake = { label: "Cake", category: "food", svg: ' ' }; const calendar$1 = { label: "Calendar", category: "travel", svg: '' }; const camera = { label: "Photography", category: "activity", svg: '' }; const campfire = { label: "Campfire", category: "activity", svg: '' }; const car = { label: "Car", category: "transport", svg: '' }; const caravan = { label: "Caravan", category: "transport", svg: ' ' }; const castle = { label: "Castle", category: "accommodation", svg: ' ' }; const check = { label: "Check", category: "general", svg: '' }; const church = { label: "Church", category: "accommodation", svg: ' ' }; const climbing = { label: "Climbing", category: "activity", svg: '' }; const clock = { label: "Time", category: "travel", svg: '' }; const cloud = { label: "Cloud", category: "general", svg: ' ' }; const coffee = { label: "Coffee", category: "food", svg: '' }; const compass = { label: "Compass", category: "activity", svg: ' ' }; const construction = { label: "Construction", category: "general", svg: ' ' }; const cookie = { label: "Cookie", category: "food", svg: ' ' }; const crown = { label: "Crown", category: "general", svg: ' ' }; const diamond = { label: "Diamond", category: "general", svg: ' ' }; const download = { label: "Download", category: "media", svg: '' }; const droplet = { label: "Droplet", category: "general", svg: ' ' }; const drum = { label: "Drum", category: "general", svg: ' ' }; const dumbbell = { label: "Dumbbell", category: "activity", svg: ' ' }; const earth = { label: "Earth", category: "travel", svg: ' ' }; const eye = { label: "Sightseeing", category: "activity", svg: '' }; const fan = { label: "Fan", category: "general", svg: ' ' }; const feather = { label: "Feather", category: "general", svg: ' ' }; const film = { label: "Film", category: "general", svg: ' ' }; const filter = { label: "Filter", category: "general", svg: ' ' }; const fish = { label: "Fish", category: "activity", svg: ' ' }; const flag = { label: "Flag", category: "activity", svg: ' ' }; const flame = { label: "Adventure", category: "activity", svg: '' }; const footprints = { label: "Hiking", category: "activity", svg: '' }; const fuel = { label: "Fuel", category: "transport", svg: ' ' }; const gamepad = { label: "Entertainment", category: "general", svg: '' }; const gift = { label: "Gift", category: "general", svg: ' ' }; const globe = { label: "Globe", category: "media", svg: '' }; const hammer = { label: "Hammer", category: "general", svg: ' ' }; const handshake = { label: "Handshake", category: "general", svg: ' ' }; const headphones = { label: "Headphones", category: "general", svg: ' ' }; const heart = { label: "Wellness", category: "general", svg: '' }; const helicopter = { label: "Helicopter", category: "activity", svg: '' }; const helmet = { label: "Helmet", category: "activity", svg: '' }; const hexagon = { label: "Hexagon", category: "general", svg: ' ' }; const hotel = { label: "Hotel", category: "accommodation", svg: '' }; const hourglass = { label: "Hourglass", category: "general", svg: ' ' }; const house = { label: "House", category: "accommodation", svg: ' ' }; const image = { label: "Image", category: "general", svg: '' }; const info = { label: "Info", category: "general", svg: '' }; const island = { label: "Island", category: "general", svg: '' }; const kayak = { label: "Kayak", category: "activity", svg: '' }; const key = { label: "Key", category: "general", svg: ' ' }; const lake = { label: "Lake", category: "general", svg: '' }; const landmark = { label: "Landmark", category: "general", svg: ' ' }; const languages = { label: "Languages", category: "travel", svg: ' ' }; const link = { label: "Link", category: "general", svg: ' ' }; const lock = { label: "Lock", category: "media", svg: '' }; const luggage = { label: "Luggage", category: "transport", svg: ' ' }; const mailbox = { label: "Mailbox", category: "general", svg: ' ' }; const map$4 = { label: "Map", category: "activity", svg: ' ' }; const martini = { label: "Martini", category: "food", svg: ' ' }; const medal = { label: "Medal", category: "activity", svg: ' ' }; const mic = { label: "Mic", category: "general", svg: ' ' }; const milestone = { label: "Milestone", category: "general", svg: ' ' }; const moon = { label: "Rest", category: "general", svg: '' }; const mountain = { label: "Mountain", category: "activity", svg: '' }; const museum = { label: "Museum", category: "general", svg: '' }; const music = { label: "Music", category: "general", svg: '' }; const navigation = { label: "Navigation", category: "transport", svg: ' ' }; const newspaper = { label: "Newspaper", category: "general", svg: ' ' }; const octagon = { label: "Octagon", category: "general", svg: ' ' }; const palette = { label: "Palette", category: "general", svg: '' }; const passport = { label: "Passport", category: "general", svg: '' }; const percent = { label: "Percent", category: "general", svg: ' ' }; const phone = { label: "Phone", category: "general", svg: ' ' }; const pill = { label: "Pill", category: "general", svg: ' ' }; const pin = { label: "Pin", category: "general", svg: ' ' }; const pizza = { label: "Pizza", category: "food", svg: ' ' }; const plane = { label: "Plane", category: "transport", svg: '' }; const play = { label: "Play", category: "media", svg: '' }; const plug = { label: "Plug", category: "general", svg: ' ' }; const plus = { label: "Plus", category: "general", svg: '' }; const pool = { label: "Pool", category: "general", svg: '' }; const power = { label: "Power", category: "general", svg: ' ' }; const pyramid = { label: "Pyramid", category: "general", svg: '' }; const rabbit = { label: "Rabbit", category: "activity", svg: ' ' }; const rainbow = { label: "Rainbow", category: "general", svg: ' ' }; const refrigerator = { label: "Refrigerator", category: "general", svg: ' ' }; const ribbon = { label: "Ribbon", category: "general", svg: ' ' }; const rocket = { label: "Rocket", category: "general", svg: ' ' }; const route = { label: "Route", category: "transport", svg: ' ' }; const ruler = { label: "Ruler", category: "general", svg: ' ' }; const sailboat = { label: "Sailboat", category: "transport", svg: ' ' }; const sandwich = { label: "Sandwich", category: "food", svg: ' ' }; const scale = { label: "Scale", category: "general", svg: ' ' }; const school = { label: "School", category: "general", svg: ' ' }; const scroll = { label: "Scroll", category: "general", svg: ' ' }; const search = { label: "Search", category: "general", svg: '' }; const settings = { label: "Settings", category: "general", svg: ' ' }; const shell = { label: "Shell", category: "general", svg: ' ' }; const shield = { label: "Shield", category: "general", svg: ' ' }; const ship = { label: "Ship", category: "transport", svg: ' ' }; const shirt = { label: "Shirt", category: "general", svg: ' ' }; const shopping = { label: "Shopping", category: "general", svg: '' }; const shovel = { label: "Shovel", category: "general", svg: ' ' }; const signpost = { label: "Signpost", category: "general", svg: ' ' }; const smartphone = { label: "Smartphone", category: "general", svg: ' ' }; const snowflake = { label: "Snowflake", category: "activity", svg: ' ' }; const spa = { label: "Spa", category: "general", svg: '' }; const sparkles = { label: "Sparkles", category: "general", svg: ' ' }; const star = { label: "Featured", category: "general", svg: '' }; const suitcase = { label: "Suitcase", category: "general", svg: '' }; const sun = { label: "Sun", category: "activity", svg: ' ' }; const sunrise = { label: "Sunrise", category: "activity", svg: ' ' }; const sunset = { label: "Sunset", category: "activity", svg: ' ' }; const surfboard = { label: "Surfboard", category: "activity", svg: '' }; const tablet = { label: "Tablet", category: "general", svg: ' ' }; const tag = { label: "Tag", category: "general", svg: '' }; const target = { label: "Target", category: "activity", svg: '' }; const telescope = { label: "Telescope", category: "activity", svg: ' ' }; const tent = { label: "Tent", category: "accommodation", svg: ' ' }; const thermometer = { label: "Thermometer", category: "general", svg: ' ' }; const ticket = { label: "Ticket", category: "transport", svg: ' ' }; const tickets = { label: "Tickets", category: "transport", svg: ' ' }; const timer = { label: "Timer", category: "general", svg: ' ' }; const tractor = { label: "Tractor", category: "general", svg: ' ' }; const trees = { label: "Trees", category: "activity", svg: ' ' }; const trophy = { label: "Trophy", category: "activity", svg: ' ' }; const truck = { label: "Truck", category: "general", svg: ' ' }; const umbrella = { label: "Umbrella", category: "activity", svg: ' ' }; const usb = { label: "Usb", category: "general", svg: ' ' }; const users = { label: "Users", category: "general", svg: '' }; const utensils = { label: "Meal", category: "food", svg: '' }; const video = { label: "Video", category: "media", svg: '' }; const volcano = { label: "Volcano", category: "general", svg: '' }; const volleyball = { label: "Volleyball", category: "activity", svg: ' ' }; const wallet = { label: "Wallet", category: "general", svg: ' ' }; const watch = { label: "Watch", category: "general", svg: ' ' }; const waves = { label: "Water Sports", category: "activity", svg: '' }; const webcam = { label: "Webcam", category: "general", svg: ' ' }; const weight = { label: "Weight", category: "general", svg: ' ' }; const wheat = { label: "Wheat", category: "general", svg: ' ' }; const wifi = { label: "Wifi", category: "general", svg: ' ' }; const wind = { label: "Wind", category: "general", svg: ' ' }; const wine = { label: "Wine", category: "food", svg: ' ' }; const wrench = { label: "Wrench", category: "general", svg: ' ' }; const x$1 = { label: "X", category: "general", svg: '' }; const zap = { label: "Energy", category: "activity", svg: '' }; const yatraIconsManifest = { accessibility, activity, anchor, archive, award, backpack, banknote, beach, bed, "bed-double": { label: "Bed Double", category: "accommodation", svg: ' ' }, "bed-single": { label: "Bed Single", category: "accommodation", svg: ' ' }, bell, "bell-ring": { label: "Bell Ring", category: "general", svg: ' ' }, bike, binoculars, bluetooth, book, bookmark, briefcase, brush, building, bus, "bus-front": { label: "Bus Front", category: "transport", svg: ' ' }, cactus, cake, calendar: calendar$1, camera, campfire, car, "car-front": { label: "Car Front", category: "transport", svg: ' ' }, "car-taxi-front": { label: "Car Taxi Front", category: "transport", svg: ' ' }, caravan, castle, check, "chef-hat": { label: "Chef Hat", category: "food", svg: '' }, "chevron-left": { label: "Chevron Left", category: "general", svg: '' }, "chevron-right": { label: "Chevron Right", category: "general", svg: '' }, church, climbing, clock, cloud, "cloud-rain": { label: "Cloud Rain", category: "general", svg: ' ' }, "cloud-sun": { label: "Cloud Sun", category: "general", svg: ' ' }, coffee, compass, construction, cookie, "credit-card": { label: "Credit Card", category: "general", svg: ' ' }, crown, "cup-soda": { label: "Cup Soda", category: "food", svg: ' ' }, diamond, "dollar-sign": { label: "Price", category: "general", svg: '' }, "door-open": { label: "Door Open", category: "accommodation", svg: ' ' }, download, droplet, drum, dumbbell, earth, "earth-lock": { label: "Earth Lock", category: "travel", svg: ' ' }, eye, "eye-off": { label: "Hide", category: "general", svg: '' }, fan, feather, "ferris-wheel": { label: "Ferris Wheel", category: "activity", svg: '' }, "file-text": { label: "Document", category: "media", svg: '' }, film, filter, "first-aid": { label: "First Aid", category: "safety", svg: '' }, fish, flag, flame, "flower-2": { label: "Flower 2", category: "activity", svg: ' ' }, footprints, fuel, gamepad, gift, "glass-water": { label: "Glass Water", category: "food", svg: ' ' }, globe, "globe-lock": { label: "Globe Lock", category: "travel", svg: ' ' }, "graduation-cap": { label: "Graduation Cap", category: "general", svg: ' ' }, hammer, handshake, headphones, heart, helicopter, helmet, "help-circle": { label: "Help", category: "general", svg: '' }, hexagon, "hot-air-balloon": { label: "Hot Air Balloon", category: "activity", svg: '' }, hotel, hourglass, house, "ice-cream-bowl": { label: "Ice Cream Bowl", category: "food", svg: ' ' }, "id-card": { label: "Id Card", category: "travel", svg: ' ' }, image, info, island, kayak, key, lake, landmark, languages, "life-buoy": { label: "Life Buoy", category: "activity", svg: ' ' }, link, lock, luggage, mailbox, map: map$4, "map-pin": { label: "Location", category: "travel", svg: '' }, "map-pin-check": { label: "Map Pin Check", category: "activity", svg: ' ' }, "map-pin-check-inside": { label: "Map Pin Check Inside", category: "activity", svg: ' ' }, "map-pin-house": { label: "Map Pin House", category: "activity", svg: ' ' }, "map-pin-plus": { label: "Map Pin Plus", category: "activity", svg: ' ' }, "map-pin-plus-inside": { label: "Map Pin Plus Inside", category: "activity", svg: ' ' }, "map-pinned": { label: "Map Pinned", category: "activity", svg: ' ' }, martini, medal, "message-circle": { label: "Message", category: "general", svg: '' }, mic, milestone, moon, "moon-star": { label: "Moon Star", category: "activity", svg: ' ' }, mountain, "mountain-snow": { label: "Mountain Snow", category: "activity", svg: ' ' }, museum, music, navigation, "navigation-2": { label: "Navigation 2", category: "transport", svg: ' ' }, newspaper, octagon, "package": { label: "Package", category: "general", svg: '' }, "package-open": { label: "Package Open", category: "general", svg: ' ' }, palette, "palm-tree": { label: "Palm Tree", category: "general", svg: '' }, "party-popper": { label: "Party Popper", category: "general", svg: ' ' }, passport, "paw-print": { label: "Paw Print", category: "general", svg: '' }, "pen-line": { label: "Pen Line", category: "general", svg: ' ' }, percent, phone, "piggy-bank": { label: "Piggy Bank", category: "general", svg: ' ' }, pill, pin, pizza, plane, "plane-landing": { label: "Plane Landing", category: "transport", svg: ' ' }, "plane-takeoff": { label: "Plane Takeoff", category: "transport", svg: ' ' }, play, plug, plus, pool, power, pyramid, "qr-code": { label: "Qr Code", category: "general", svg: ' ' }, rabbit, rainbow, refrigerator, ribbon, rocket, route, ruler, sailboat, sandwich, scale, "scan-barcode": { label: "Scan Barcode", category: "travel", svg: ' ' }, "scan-qr-code": { label: "Scan Qr Code", category: "travel", svg: ' ' }, school, scroll, search, settings, shell, shield, ship, "ship-wheel": { label: "Ship Wheel", category: "transport", svg: ' ' }, shirt, shopping, "shopping-cart": { label: "Shopping Cart", category: "general", svg: '' }, shovel, signpost, "signpost-big": { label: "Signpost Big", category: "travel", svg: ' ' }, smartphone, "snorkel-mask": { label: "Snorkel Mask", category: "activity", svg: '' }, snowflake, spa, sparkles, star, suitcase, sun, sunrise, sunset, surfboard, tablet, tag, target, telescope, tent, "tent-tree": { label: "Tent Tree", category: "accommodation", svg: ' ' }, thermometer, ticket, "ticket-check": { label: "Ticket Check", category: "transport", svg: ' ' }, "ticket-minus": { label: "Ticket Minus", category: "transport", svg: ' ' }, "ticket-percent": { label: "Ticket Percent", category: "transport", svg: ' ' }, "ticket-plus": { label: "Ticket Plus", category: "transport", svg: ' ' }, "ticket-slash": { label: "Ticket Slash", category: "transport", svg: ' ' }, "ticket-x": { label: "Ticket X", category: "transport", svg: ' ' }, tickets, "tickets-plane": { label: "Tickets Plane", category: "transport", svg: ' ' }, timer, tractor, "train-front": { label: "Train Front", category: "transport", svg: ' ' }, "train-front-tunnel": { label: "Train Front Tunnel", category: "transport", svg: ' ' }, "train-track": { label: "Train Track", category: "transport", svg: ' ' }, "tram-front": { label: "Tram Front", category: "transport", svg: ' ' }, "trash-2": { label: "Trash 2", category: "general", svg: ' ' }, "tree-deciduous": { label: "Tree Deciduous", category: "activity", svg: ' ' }, "tree-pine": { label: "Tree Pine", category: "activity", svg: ' ' }, trees, trophy, truck, umbrella, usb, users, utensils, video, volcano, volleyball, wallet, watch, waves, "waves-ladder": { label: "Waves Ladder", category: "activity", svg: ' ' }, webcam, weight, wheat, wifi, wind, wine, "wine-glass": { label: "Wine Glass", category: "food", svg: '' }, wrench, x: x$1, zap }; function getIconOptions() { const m = yatraIconsManifest; const slugToLabel = (slug) => slug.split(/[-_\s]+/).filter(Boolean).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" "); return Object.entries(m).map(([name, meta]) => { const safeMeta = meta || {}; return { name, label: typeof safeMeta.label === "string" && safeMeta.label.length > 0 ? safeMeta.label : slugToLabel(name), category: typeof safeMeta.category === "string" && safeMeta.category.length > 0 ? safeMeta.category : "general", svg: safeMeta.svg || "" }; }); } function getYatraIconSvg(slug) { var _a; const m = yatraIconsManifest; return ((_a = m[slug]) == null ? void 0 : _a.svg) ?? null; } const solid = [ "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "address-book", "address-card", "align-center", "align-justify", "align-left", "align-right", "anchor", "anchor-circle-check", "anchor-circle-exclamation", "anchor-circle-xmark", "anchor-lock", "angle-down", "angle-left", "angle-right", "angle-up", "angles-down", "angles-left", "angles-right", "angles-up", "ankh", "apple-whole", "archway", "arrow-down", "arrow-down-1-9", "arrow-down-9-1", "arrow-down-a-z", "arrow-down-long", "arrow-down-short-wide", "arrow-down-up-across-line", "arrow-down-up-lock", "arrow-down-wide-short", "arrow-down-z-a", "arrow-left", "arrow-left-long", "arrow-pointer", "arrow-right", "arrow-right-arrow-left", "arrow-right-from-bracket", "arrow-right-long", "arrow-right-to-bracket", "arrow-right-to-city", "arrow-rotate-left", "arrow-rotate-right", "arrow-trend-down", "arrow-trend-up", "arrow-turn-down", "arrow-turn-up", "arrow-up", "arrow-up-1-9", "arrow-up-9-1", "arrow-up-a-z", "arrow-up-from-bracket", "arrow-up-from-ground-water", "arrow-up-from-water-pump", "arrow-up-long", "arrow-up-right-dots", "arrow-up-right-from-square", "arrow-up-short-wide", "arrow-up-wide-short", "arrow-up-z-a", "arrows-down-to-line", "arrows-down-to-people", "arrows-left-right", "arrows-left-right-to-line", "arrows-rotate", "arrows-spin", "arrows-split-up-and-left", "arrows-to-circle", "arrows-to-dot", "arrows-to-eye", "arrows-turn-right", "arrows-turn-to-dots", "arrows-up-down", "arrows-up-down-left-right", "arrows-up-to-line", "asterisk", "at", "atom", "audio-description", "austral-sign", "award", "b", "baby", "baby-carriage", "backward", "backward-fast", "backward-step", "bacon", "bacteria", "bacterium", "bag-shopping", "bahai", "baht-sign", "ban", "ban-smoking", "bandage", "bangladeshi-taka-sign", "barcode", "bars", "bars-progress", "bars-staggered", "baseball", "baseball-bat-ball", "basket-shopping", "basketball", "bath", "battery-empty", "battery-full", "battery-half", "battery-quarter", "battery-three-quarters", "bed", "bed-pulse", "beer-mug-empty", "bell", "bell-concierge", "bell-slash", "bezier-curve", "bicycle", "binoculars", "biohazard", "bitcoin-sign", "blender", "blender-phone", "blog", "bold", "bolt", "bolt-lightning", "bomb", "bone", "bong", "book", "book-atlas", "book-bible", "book-bookmark", "book-journal-whills", "book-medical", "book-open", "book-open-reader", "book-quran", "book-skull", "book-tanakh", "bookmark", "border-all", "border-none", "border-top-left", "bore-hole", "bottle-droplet", "bottle-water", "bowl-food", "bowl-rice", "bowling-ball", "box", "box-archive", "box-open", "box-tissue", "boxes-packing", "boxes-stacked", "braille", "brain", "brazilian-real-sign", "bread-slice", "bridge", "bridge-circle-check", "bridge-circle-exclamation", "bridge-circle-xmark", "bridge-lock", "bridge-water", "briefcase", "briefcase-medical", "broom", "broom-ball", "brush", "bucket", "bug", "bug-slash", "bugs", "building", "building-circle-arrow-right", "building-circle-check", "building-circle-exclamation", "building-circle-xmark", "building-columns", "building-flag", "building-lock", "building-ngo", "building-shield", "building-un", "building-user", "building-wheat", "bullhorn", "bullseye", "burger", "burst", "bus", "bus-simple", "business-time", "c", "cable-car", "cake-candles", "calculator", "calendar", "calendar-check", "calendar-day", "calendar-days", "calendar-minus", "calendar-plus", "calendar-week", "calendar-xmark", "camera", "camera-retro", "camera-rotate", "campground", "candy-cane", "cannabis", "capsules", "car", "car-battery", "car-burst", "car-on", "car-rear", "car-side", "car-tunnel", "caravan", "caret-down", "caret-left", "caret-right", "caret-up", "carrot", "cart-arrow-down", "cart-flatbed", "cart-flatbed-suitcase", "cart-plus", "cart-shopping", "cash-register", "cat", "cedi-sign", "cent-sign", "certificate", "chair", "chalkboard", "chalkboard-user", "champagne-glasses", "charging-station", "chart-area", "chart-bar", "chart-column", "chart-diagram", "chart-gantt", "chart-line", "chart-pie", "chart-simple", "check", "check-double", "check-to-slot", "cheese", "chess", "chess-bishop", "chess-board", "chess-king", "chess-knight", "chess-pawn", "chess-queen", "chess-rook", "chevron-down", "chevron-left", "chevron-right", "chevron-up", "child", "child-combatant", "child-dress", "child-reaching", "children", "church", "circle", "circle-arrow-down", "circle-arrow-left", "circle-arrow-right", "circle-arrow-up", "circle-check", "circle-chevron-down", "circle-chevron-left", "circle-chevron-right", "circle-chevron-up", "circle-dollar-to-slot", "circle-dot", "circle-down", "circle-exclamation", "circle-h", "circle-half-stroke", "circle-info", "circle-left", "circle-minus", "circle-nodes", "circle-notch", "circle-pause", "circle-play", "circle-plus", "circle-question", "circle-radiation", "circle-right", "circle-stop", "circle-up", "circle-user", "circle-xmark", "city", "clapperboard", "clipboard", "clipboard-check", "clipboard-list", "clipboard-question", "clipboard-user", "clock", "clock-rotate-left", "clone", "closed-captioning", "cloud", "cloud-arrow-down", "cloud-arrow-up", "cloud-bolt", "cloud-meatball", "cloud-moon", "cloud-moon-rain", "cloud-rain", "cloud-showers-heavy", "cloud-showers-water", "cloud-sun", "cloud-sun-rain", "clover", "code", "code-branch", "code-commit", "code-compare", "code-fork", "code-merge", "code-pull-request", "coins", "colon-sign", "comment", "comment-dollar", "comment-dots", "comment-medical", "comment-nodes", "comment-slash", "comment-sms", "comments", "comments-dollar", "compact-disc", "compass", "compass-drafting", "compress", "computer", "computer-mouse", "cookie", "cookie-bite", "copy", "copyright", "couch", "cow", "credit-card", "crop", "crop-simple", "cross", "crosshairs", "crow", "crown", "crutch", "cruzeiro-sign", "cube", "cubes", "cubes-stacked", "d", "database", "delete-left", "democrat", "desktop", "dharmachakra", "diagram-next", "diagram-predecessor", "diagram-project", "diagram-successor", "diamond", "diamond-turn-right", "dice", "dice-d20", "dice-d6", "dice-five", "dice-four", "dice-one", "dice-six", "dice-three", "dice-two", "disease", "display", "divide", "dna", "dog", "dollar-sign", "dolly", "dong-sign", "door-closed", "door-open", "dove", "down-left-and-up-right-to-center", "down-long", "download", "dragon", "draw-polygon", "droplet", "droplet-slash", "drum", "drum-steelpan", "drumstick-bite", "dumbbell", "dumpster", "dumpster-fire", "dungeon", "e", "ear-deaf", "ear-listen", "earth-africa", "earth-americas", "earth-asia", "earth-europe", "earth-oceania", "egg", "eject", "elevator", "ellipsis", "ellipsis-vertical", "envelope", "envelope-circle-check", "envelope-open", "envelope-open-text", "envelopes-bulk", "equals", "eraser", "ethernet", "euro-sign", "exclamation", "expand", "explosion", "eye", "eye-dropper", "eye-low-vision", "eye-slash", "f", "face-angry", "face-dizzy", "face-flushed", "face-frown", "face-frown-open", "face-grimace", "face-grin", "face-grin-beam", "face-grin-beam-sweat", "face-grin-hearts", "face-grin-squint", "face-grin-squint-tears", "face-grin-stars", "face-grin-tears", "face-grin-tongue", "face-grin-tongue-squint", "face-grin-tongue-wink", "face-grin-wide", "face-grin-wink", "face-kiss", "face-kiss-beam", "face-kiss-wink-heart", "face-laugh", "face-laugh-beam", "face-laugh-squint", "face-laugh-wink", "face-meh", "face-meh-blank", "face-rolling-eyes", "face-sad-cry", "face-sad-tear", "face-smile", "face-smile-beam", "face-smile-wink", "face-surprise", "face-tired", "fan", "faucet", "faucet-drip", "fax", "feather", "feather-pointed", "ferry", "file", "file-arrow-down", "file-arrow-up", "file-audio", "file-circle-check", "file-circle-exclamation", "file-circle-minus", "file-circle-plus", "file-circle-question", "file-circle-xmark", "file-code", "file-contract", "file-csv", "file-excel", "file-export", "file-fragment", "file-half-dashed", "file-image", "file-import", "file-invoice", "file-invoice-dollar", "file-lines", "file-medical", "file-pdf", "file-pen", "file-powerpoint", "file-prescription", "file-shield", "file-signature", "file-video", "file-waveform", "file-word", "file-zipper", "fill", "fill-drip", "film", "filter", "filter-circle-dollar", "filter-circle-xmark", "fingerprint", "fire", "fire-burner", "fire-extinguisher", "fire-flame-curved", "fire-flame-simple", "fish", "fish-fins", "flag", "flag-checkered", "flag-usa", "flask", "flask-vial", "floppy-disk", "florin-sign", "folder", "folder-closed", "folder-minus", "folder-open", "folder-plus", "folder-tree", "font", "font-awesome", "football", "forward", "forward-fast", "forward-step", "franc-sign", "frog", "futbol", "g", "gamepad", "gas-pump", "gauge", "gauge-high", "gauge-simple", "gauge-simple-high", "gavel", "gear", "gears", "gem", "genderless", "ghost", "gift", "gifts", "glass-water", "glass-water-droplet", "glasses", "globe", "golf-ball-tee", "gopuram", "graduation-cap", "greater-than", "greater-than-equal", "grip", "grip-lines", "grip-lines-vertical", "grip-vertical", "group-arrows-rotate", "guarani-sign", "guitar", "gun", "h", "hammer", "hamsa", "hand", "hand-back-fist", "hand-dots", "hand-fist", "hand-holding", "hand-holding-dollar", "hand-holding-droplet", "hand-holding-hand", "hand-holding-heart", "hand-holding-medical", "hand-lizard", "hand-middle-finger", "hand-peace", "hand-point-down", "hand-point-left", "hand-point-right", "hand-point-up", "hand-pointer", "hand-scissors", "hand-sparkles", "hand-spock", "handcuffs", "hands", "hands-asl-interpreting", "hands-bound", "hands-bubbles", "hands-clapping", "hands-holding", "hands-holding-child", "hands-holding-circle", "hands-praying", "handshake", "handshake-angle", "handshake-simple", "handshake-simple-slash", "handshake-slash", "hanukiah", "hard-drive", "hashtag", "hat-cowboy", "hat-cowboy-side", "hat-wizard", "head-side-cough", "head-side-cough-slash", "head-side-mask", "head-side-virus", "heading", "headphones", "headphones-simple", "headset", "heart", "heart-circle-bolt", "heart-circle-check", "heart-circle-exclamation", "heart-circle-minus", "heart-circle-plus", "heart-circle-xmark", "heart-crack", "heart-pulse", "helicopter", "helicopter-symbol", "helmet-safety", "helmet-un", "hexagon-nodes", "hexagon-nodes-bolt", "highlighter", "hill-avalanche", "hill-rockslide", "hippo", "hockey-puck", "holly-berry", "horse", "horse-head", "hospital", "hospital-user", "hot-tub-person", "hotdog", "hotel", "hourglass", "hourglass-end", "hourglass-half", "hourglass-start", "house", "house-chimney", "house-chimney-crack", "house-chimney-medical", "house-chimney-user", "house-chimney-window", "house-circle-check", "house-circle-exclamation", "house-circle-xmark", "house-crack", "house-fire", "house-flag", "house-flood-water", "house-flood-water-circle-arrow-right", "house-laptop", "house-lock", "house-medical", "house-medical-circle-check", "house-medical-circle-exclamation", "house-medical-circle-xmark", "house-medical-flag", "house-signal", "house-tsunami", "house-user", "hryvnia-sign", "hurricane", "i", "i-cursor", "ice-cream", "icicles", "icons", "id-badge", "id-card", "id-card-clip", "igloo", "image", "image-portrait", "images", "inbox", "indent", "indian-rupee-sign", "industry", "infinity", "info", "italic", "j", "jar", "jar-wheat", "jedi", "jet-fighter", "jet-fighter-up", "joint", "jug-detergent", "k", "kaaba", "key", "keyboard", "khanda", "kip-sign", "kit-medical", "kitchen-set", "kiwi-bird", "l", "land-mine-on", "landmark", "landmark-dome", "landmark-flag", "language", "laptop", "laptop-code", "laptop-file", "laptop-medical", "lari-sign", "layer-group", "leaf", "left-long", "left-right", "lemon", "less-than", "less-than-equal", "life-ring", "lightbulb", "lines-leaning", "link", "link-slash", "lira-sign", "list", "list-check", "list-ol", "list-ul", "litecoin-sign", "location-arrow", "location-crosshairs", "location-dot", "location-pin", "location-pin-lock", "lock", "lock-open", "locust", "lungs", "lungs-virus", "m", "magnet", "magnifying-glass", "magnifying-glass-arrow-right", "magnifying-glass-chart", "magnifying-glass-dollar", "magnifying-glass-location", "magnifying-glass-minus", "magnifying-glass-plus", "manat-sign", "map", "map-location", "map-location-dot", "map-pin", "marker", "mars", "mars-and-venus", "mars-and-venus-burst", "mars-double", "mars-stroke", "mars-stroke-right", "mars-stroke-up", "martini-glass", "martini-glass-citrus", "martini-glass-empty", "mask", "mask-face", "mask-ventilator", "masks-theater", "mattress-pillow", "maximize", "medal", "memory", "menorah", "mercury", "message", "meteor", "microchip", "microphone", "microphone-lines", "microphone-lines-slash", "microphone-slash", "microscope", "mill-sign", "minimize", "minus", "mitten", "mobile", "mobile-button", "mobile-retro", "mobile-screen", "mobile-screen-button", "money-bill", "money-bill-1", "money-bill-1-wave", "money-bill-transfer", "money-bill-trend-up", "money-bill-wave", "money-bill-wheat", "money-bills", "money-check", "money-check-dollar", "monument", "moon", "mortar-pestle", "mosque", "mosquito", "mosquito-net", "motorcycle", "mound", "mountain", "mountain-city", "mountain-sun", "mug-hot", "mug-saucer", "music", "n", "naira-sign", "network-wired", "neuter", "newspaper", "not-equal", "notdef", "note-sticky", "notes-medical", "o", "object-group", "object-ungroup", "oil-can", "oil-well", "om", "otter", "outdent", "p", "pager", "paint-roller", "paintbrush", "palette", "pallet", "panorama", "paper-plane", "paperclip", "parachute-box", "paragraph", "passport", "paste", "pause", "paw", "peace", "pen", "pen-clip", "pen-fancy", "pen-nib", "pen-ruler", "pen-to-square", "pencil", "people-arrows", "people-carry-box", "people-group", "people-line", "people-pulling", "people-robbery", "people-roof", "pepper-hot", "percent", "person", "person-arrow-down-to-line", "person-arrow-up-from-line", "person-biking", "person-booth", "person-breastfeeding", "person-burst", "person-cane", "person-chalkboard", "person-circle-check", "person-circle-exclamation", "person-circle-minus", "person-circle-plus", "person-circle-question", "person-circle-xmark", "person-digging", "person-dots-from-line", "person-dress", "person-dress-burst", "person-drowning", "person-falling", "person-falling-burst", "person-half-dress", "person-harassing", "person-hiking", "person-military-pointing", "person-military-rifle", "person-military-to-person", "person-praying", "person-pregnant", "person-rays", "person-rifle", "person-running", "person-shelter", "person-skating", "person-skiing", "person-skiing-nordic", "person-snowboarding", "person-swimming", "person-through-window", "person-walking", "person-walking-arrow-loop-left", "person-walking-arrow-right", "person-walking-dashed-line-arrow-right", "person-walking-luggage", "person-walking-with-cane", "peseta-sign", "peso-sign", "phone", "phone-flip", "phone-slash", "phone-volume", "photo-film", "piggy-bank", "pills", "pizza-slice", "place-of-worship", "plane", "plane-arrival", "plane-circle-check", "plane-circle-exclamation", "plane-circle-xmark", "plane-departure", "plane-lock", "plane-slash", "plane-up", "plant-wilt", "plate-wheat", "play", "plug", "plug-circle-bolt", "plug-circle-check", "plug-circle-exclamation", "plug-circle-minus", "plug-circle-plus", "plug-circle-xmark", "plus", "plus-minus", "podcast", "poo", "poo-storm", "poop", "power-off", "prescription", "prescription-bottle", "prescription-bottle-medical", "print", "pump-medical", "pump-soap", "puzzle-piece", "q", "qrcode", "question", "quote-left", "quote-right", "r", "radiation", "radio", "rainbow", "ranking-star", "receipt", "record-vinyl", "rectangle-ad", "rectangle-list", "rectangle-xmark", "recycle", "registered", "repeat", "reply", "reply-all", "republican", "restroom", "retweet", "ribbon", "right-from-bracket", "right-left", "right-long", "right-to-bracket", "ring", "road", "road-barrier", "road-bridge", "road-circle-check", "road-circle-exclamation", "road-circle-xmark", "road-lock", "road-spikes", "robot", "rocket", "rotate", "rotate-left", "rotate-right", "route", "rss", "ruble-sign", "rug", "ruler", "ruler-combined", "ruler-horizontal", "ruler-vertical", "rupee-sign", "rupiah-sign", "s", "sack-dollar", "sack-xmark", "sailboat", "satellite", "satellite-dish", "scale-balanced", "scale-unbalanced", "scale-unbalanced-flip", "school", "school-circle-check", "school-circle-exclamation", "school-circle-xmark", "school-flag", "school-lock", "scissors", "screwdriver", "screwdriver-wrench", "scroll", "scroll-torah", "sd-card", "section", "seedling", "server", "shapes", "share", "share-from-square", "share-nodes", "sheet-plastic", "shekel-sign", "shield", "shield-cat", "shield-dog", "shield-halved", "shield-heart", "shield-virus", "ship", "shirt", "shoe-prints", "shop", "shop-lock", "shop-slash", "shower", "shrimp", "shuffle", "shuttle-space", "sign-hanging", "signal", "signature", "signs-post", "sim-card", "sink", "sitemap", "skull", "skull-crossbones", "slash", "sleigh", "sliders", "smog", "smoking", "snowflake", "snowman", "snowplow", "soap", "socks", "solar-panel", "sort", "sort-down", "sort-up", "spa", "spaghetti-monster-flying", "spell-check", "spider", "spinner", "splotch", "spoon", "spray-can", "spray-can-sparkles", "square", "square-arrow-up-right", "square-binary", "square-caret-down", "square-caret-left", "square-caret-right", "square-caret-up", "square-check", "square-envelope", "square-full", "square-h", "square-minus", "square-nfi", "square-parking", "square-pen", "square-person-confined", "square-phone", "square-phone-flip", "square-plus", "square-poll-horizontal", "square-poll-vertical", "square-root-variable", "square-rss", "square-share-nodes", "square-up-right", "square-virus", "square-xmark", "staff-snake", "stairs", "stamp", "stapler", "star", "star-and-crescent", "star-half", "star-half-stroke", "star-of-david", "star-of-life", "sterling-sign", "stethoscope", "stop", "stopwatch", "stopwatch-20", "store", "store-slash", "street-view", "strikethrough", "stroopwafel", "subscript", "suitcase", "suitcase-medical", "suitcase-rolling", "sun", "sun-plant-wilt", "superscript", "swatchbook", "synagogue", "syringe", "t", "table", "table-cells", "table-cells-column-lock", "table-cells-large", "table-cells-row-lock", "table-cells-row-unlock", "table-columns", "table-list", "table-tennis-paddle-ball", "tablet", "tablet-button", "tablet-screen-button", "tablets", "tachograph-digital", "tag", "tags", "tape", "tarp", "tarp-droplet", "taxi", "teeth", "teeth-open", "temperature-arrow-down", "temperature-arrow-up", "temperature-empty", "temperature-full", "temperature-half", "temperature-high", "temperature-low", "temperature-quarter", "temperature-three-quarters", "tenge-sign", "tent", "tent-arrow-down-to-line", "tent-arrow-left-right", "tent-arrow-turn-left", "tent-arrows-down", "tents", "terminal", "text-height", "text-slash", "text-width", "thermometer", "thumbs-down", "thumbs-up", "thumbtack", "thumbtack-slash", "ticket", "ticket-simple", "timeline", "toggle-off", "toggle-on", "toilet", "toilet-paper", "toilet-paper-slash", "toilet-portable", "toilets-portable", "toolbox", "tooth", "torii-gate", "tornado", "tower-broadcast", "tower-cell", "tower-observation", "tractor", "trademark", "traffic-light", "trailer", "train", "train-subway", "train-tram", "transgender", "trash", "trash-arrow-up", "trash-can", "trash-can-arrow-up", "tree", "tree-city", "triangle-exclamation", "trophy", "trowel", "trowel-bricks", "truck", "truck-arrow-right", "truck-droplet", "truck-fast", "truck-field", "truck-field-un", "truck-front", "truck-medical", "truck-monster", "truck-moving", "truck-pickup", "truck-plane", "truck-ramp-box", "tty", "turkish-lira-sign", "turn-down", "turn-up", "tv", "u", "umbrella", "umbrella-beach", "underline", "universal-access", "unlock", "unlock-keyhole", "up-down", "up-down-left-right", "up-long", "up-right-and-down-left-from-center", "up-right-from-square", "upload", "user", "user-astronaut", "user-check", "user-clock", "user-doctor", "user-gear", "user-graduate", "user-group", "user-injured", "user-large", "user-large-slash", "user-lock", "user-minus", "user-ninja", "user-nurse", "user-pen", "user-plus", "user-secret", "user-shield", "user-slash", "user-tag", "user-tie", "user-xmark", "users", "users-between-lines", "users-gear", "users-line", "users-rays", "users-rectangle", "users-slash", "users-viewfinder", "utensils", "v", "van-shuttle", "vault", "vector-square", "venus", "venus-double", "venus-mars", "vest", "vest-patches", "vial", "vial-circle-check", "vial-virus", "vials", "video", "video-slash", "vihara", "virus", "virus-covid", "virus-covid-slash", "virus-slash", "viruses", "voicemail", "volcano", "volleyball", "volume-high", "volume-low", "volume-off", "volume-xmark", "vr-cardboard", "w", "walkie-talkie", "wallet", "wand-magic", "wand-magic-sparkles", "wand-sparkles", "warehouse", "water", "water-ladder", "wave-square", "web-awesome", "weight-hanging", "weight-scale", "wheat-awn", "wheat-awn-circle-exclamation", "wheelchair", "wheelchair-move", "whiskey-glass", "wifi", "wind", "window-maximize", "window-minimize", "window-restore", "wine-bottle", "wine-glass", "wine-glass-empty", "won-sign", "worm", "wrench", "x", "x-ray", "xmark", "xmarks-lines", "y", "yen-sign", "yin-yang", "z" ]; const regular = [ "address-book", "address-card", "bell", "bell-slash", "bookmark", "building", "calendar", "calendar-check", "calendar-days", "calendar-minus", "calendar-plus", "calendar-xmark", "chart-bar", "chess-bishop", "chess-king", "chess-knight", "chess-pawn", "chess-queen", "chess-rook", "circle", "circle-check", "circle-dot", "circle-down", "circle-left", "circle-pause", "circle-play", "circle-question", "circle-right", "circle-stop", "circle-up", "circle-user", "circle-xmark", "clipboard", "clock", "clone", "closed-captioning", "comment", "comment-dots", "comments", "compass", "copy", "copyright", "credit-card", "envelope", "envelope-open", "eye", "eye-slash", "face-angry", "face-dizzy", "face-flushed", "face-frown", "face-frown-open", "face-grimace", "face-grin", "face-grin-beam", "face-grin-beam-sweat", "face-grin-hearts", "face-grin-squint", "face-grin-squint-tears", "face-grin-stars", "face-grin-tears", "face-grin-tongue", "face-grin-tongue-squint", "face-grin-tongue-wink", "face-grin-wide", "face-grin-wink", "face-kiss", "face-kiss-beam", "face-kiss-wink-heart", "face-laugh", "face-laugh-beam", "face-laugh-squint", "face-laugh-wink", "face-meh", "face-meh-blank", "face-rolling-eyes", "face-sad-cry", "face-sad-tear", "face-smile", "face-smile-beam", "face-smile-wink", "face-surprise", "face-tired", "file", "file-audio", "file-code", "file-excel", "file-image", "file-lines", "file-pdf", "file-powerpoint", "file-video", "file-word", "file-zipper", "flag", "floppy-disk", "folder", "folder-closed", "folder-open", "font-awesome", "futbol", "gem", "hand", "hand-back-fist", "hand-lizard", "hand-peace", "hand-point-down", "hand-point-left", "hand-point-right", "hand-point-up", "hand-pointer", "hand-scissors", "hand-spock", "handshake", "hard-drive", "heart", "hospital", "hourglass", "hourglass-half", "id-badge", "id-card", "image", "images", "keyboard", "lemon", "life-ring", "lightbulb", "map", "message", "money-bill-1", "moon", "newspaper", "note-sticky", "object-group", "object-ungroup", "paper-plane", "paste", "pen-to-square", "rectangle-list", "rectangle-xmark", "registered", "share-from-square", "snowflake", "square", "square-caret-down", "square-caret-left", "square-caret-right", "square-caret-up", "square-check", "square-full", "square-minus", "square-plus", "star", "star-half", "star-half-stroke", "sun", "thumbs-down", "thumbs-up", "trash-can", "user", "window-maximize", "window-minimize", "window-restore" ]; const faManifest = { solid, regular }; const manifest = faManifest; function humanizeIconName(iconName) { return iconName.split("-").filter(Boolean).map((w) => w.charAt(0).toUpperCase() + w.slice(1)).join(" "); } function toPickerItems(names, style) { return names.map((name) => ({ name, label: humanizeIconName(name), style })); } const FA_FREE_SOLID_PICKER = toPickerItems( manifest.solid, "fa-solid" ); const FA_FREE_REGULAR_PICKER = toPickerItems( manifest.regular, "fa-regular" ); [ ...FA_FREE_SOLID_PICKER, ...FA_FREE_REGULAR_PICKER ]; const FA_SOLID_NAME_SET = new Set(manifest.solid); const FA_REGULAR_NAME_SET = new Set(manifest.regular); const IconSelector = ({ iconName, provider = "yatra", className = "w-5 h-5", size }) => { const sizeStyle = size !== void 0 ? { fontSize: size, width: size, height: size, lineHeight: 1, display: "inline-flex", alignItems: "center", justifyContent: "center" } : void 0; if (provider === "fa-solid" || provider === "fa-regular") { const ok = provider === "fa-regular" ? FA_REGULAR_NAME_SET.has(iconName) : FA_SOLID_NAME_SET.has(iconName); if (ok) { const prefix2 = provider === "fa-regular" ? "fa-regular" : "fa-solid"; return /* @__PURE__ */ jsxRuntimeExports.jsx( "i", { className: `${prefix2} fa-${iconName} ${className}`, style: sizeStyle, "aria-hidden": "true" } ); } return /* @__PURE__ */ jsxRuntimeExports.jsx(Package, { className, style: sizeStyle }); } const svg = getYatraIconSvg(iconName); if (svg) { return /* @__PURE__ */ jsxRuntimeExports.jsx( "span", { className: `inline-flex items-center justify-center ${className}`, dangerouslySetInnerHTML: { __html: svg }, style: sizeStyle } ); } return /* @__PURE__ */ jsxRuntimeExports.jsx(Package, { className, style: sizeStyle }); }; function isPickerValue(value) { return typeof value === "object" && value !== null && "type" in value && "value" in value; } const attachmentUrlCache = /* @__PURE__ */ new Map(); const attachmentUrlInFlight = /* @__PURE__ */ new Map(); function resolveAttachmentUrl(id) { var _a, _b; const cached = attachmentUrlCache.get(id); if (cached !== void 0) return Promise.resolve(cached); const pending = attachmentUrlInFlight.get(id); if (pending) return pending; const apiUrl = ((_b = (_a = window.yatraAdmin) == null ? void 0 : _a.apiUrl) == null ? void 0 : _b.replace("/yatra/v1", "")) ?? ""; if (!apiUrl) return Promise.resolve(""); const promise = fetch(`${apiUrl}/wp/v2/media/${id}`).then((r2) => r2.json()).then((data) => { const url = (data == null ? void 0 : data.source_url) ?? ""; if (url) attachmentUrlCache.set(id, url); return url; }).catch(() => "").finally(() => { attachmentUrlInFlight.delete(id); }); attachmentUrlInFlight.set(id, promise); return promise; } const ImageOverride = ({ value, className }) => { const initial = value.startsWith("http://") || value.startsWith("https://") || value.startsWith("/") ? value : attachmentUrlCache.get(value) ?? ""; const [resolved, setResolved] = reactExports.useState(initial); reactExports.useEffect(() => { if (resolved) return; if (!/^\d+$/.test(value)) return; let cancelled = false; resolveAttachmentUrl(value).then((url) => { if (!cancelled && url) setResolved(url); }); return () => { cancelled = true; }; }, [value, resolved]); if (!resolved) return null; return /* @__PURE__ */ jsxRuntimeExports.jsx( "img", { src: resolved, alt: "", className: `${className} object-contain`, "aria-hidden": "true" } ); }; const MenuIcon = ({ icon, fallback: Fallback, className = "h-4 w-4" }) => { if (isPickerValue(icon)) { if (icon.type === "image" && icon.value) { return /* @__PURE__ */ jsxRuntimeExports.jsx(ImageOverride, { value: icon.value, className }); } if (icon.type === "icon" && icon.value) { return /* @__PURE__ */ jsxRuntimeExports.jsx( IconSelector, { iconName: icon.value, provider: icon.provider ?? "yatra", className } ); } } if (typeof icon === "string" && icon !== "" && ICON_MAP[icon]) { const Lucide = ICON_MAP[icon]; return /* @__PURE__ */ jsxRuntimeExports.jsx(Lucide, { className }); } return /* @__PURE__ */ jsxRuntimeExports.jsx(Fallback, { className }); }; const Card = reactExports.forwardRef( ({ className = "", ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx( "div", { ref, className: `rounded-lg border border-gray-100 dark:border-gray-700/50 bg-white dark:bg-gray-800 flex flex-col py-4 ${className}`, ...props } ) ); Card.displayName = "Card"; const CardHeader = reactExports.forwardRef( ({ className = "", ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx( "div", { ref, className: `flex flex-col space-y-0.5 p-3 pb-2 border-b border-gray-100 dark:border-gray-700/50 ${className}`, ...props } ) ); CardHeader.displayName = "CardHeader"; const CardTitle = reactExports.forwardRef(({ className = "", ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx( "h3", { ref, className: `text-base font-semibold text-gray-900 dark:text-white ${className}`, ...props } )); CardTitle.displayName = "CardTitle"; const CardDescription = reactExports.forwardRef(({ className = "", ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx( "p", { ref, className: `text-sm text-gray-500 dark:text-gray-400 ${className}`, ...props } )); CardDescription.displayName = "CardDescription"; const CardContent = reactExports.forwardRef( ({ className = "", ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx("div", { ref, className: `p-3 flex-1 ${className}`, ...props }) ); CardContent.displayName = "CardContent"; const CardFooter = reactExports.forwardRef( ({ className = "", ...props }, ref) => /* @__PURE__ */ jsxRuntimeExports.jsx( "div", { ref, className: `flex items-center p-6 pt-0 ${className}`, ...props } ) ); CardFooter.displayName = "CardFooter"; const Badge = reactExports.forwardRef( ({ className = "", variant = "default", ...props }, ref) => { const variantClasses = { default: "bg-gray-100 text-gray-800 dark:bg-gray-700 dark:text-gray-300", success: "bg-green-100 text-green-800 dark:bg-green-900/20 dark:text-green-400", warning: "bg-yellow-100 text-yellow-800 dark:bg-yellow-900/20 dark:text-yellow-400", error: "bg-red-100 text-red-800 dark:bg-red-900/20 dark:text-red-400", info: "bg-blue-100 text-blue-800 dark:bg-blue-900/20 dark:text-blue-400", outline: "border border-gray-300 dark:border-gray-600 bg-transparent text-gray-700 dark:text-gray-300" }; return /* @__PURE__ */ jsxRuntimeExports.jsx( "div", { ref, className: `inline-flex items-center rounded-full px-2.5 py-0.5 text-xs font-medium ${variantClasses[variant]} ${className}`, ...props } ); } ); Badge.displayName = "Badge"; const fetchModules = async () => { const response = await apiClient.get("/modules"); if (Array.isArray(response)) { return response; } if (Array.isArray(response == null ? void 0 : response.data)) { return response.data; } return []; }; const useModulesQuery = (options2) => { return useQuery({ queryKey: ["modules"], queryFn: fetchModules, staleTime: 0, ...options2 }); }; const formatNamesList = (names) => { if (names.length <= 2) { return names.join(", "); } return `${names.slice(0, 2).join(", ")} ${__("and", "yatra")} ${names.length - 2} ${__("more", "yatra")}`; }; const useToggleModule = () => { const queryClient2 = useQueryClient(); const { showToast } = useToast(); return useMutation({ mutationFn: async ({ slug, enabled }) => { const response = await apiClient.post( `/modules/${slug}/toggle`, { enabled } ); return Array.isArray(response == null ? void 0 : response.data) ? response.data : []; }, onSuccess: (data, variables) => { queryClient2.setQueryData(["modules"], data); if (window.yatraAdmin) { const enabledModules = data.filter((m) => m.enabled); window.yatraAdmin.emailAutomationEnabled = enabledModules.some( (m) => m.slug === "email_automation" || m.slug === "email-automation" ); window.yatraAdmin.tripConsentEnabled = enabledModules.some( (m) => m.slug === "trip_consent" || m.slug === "trip-consent" ); window.yatraAdmin.additionalServicesEnabled = enabledModules.some( (m) => m.slug === "additional_services" || m.slug === "additional-services" ); window.yatraAdmin.abandonedBookingRecoveryEnabled = enabledModules.some( (m) => m.slug === "abandoned_booking_recovery" || m.slug === "abandoned-booking-recovery" ); window.yatraAdmin.dynamicPricingEnabled = enabledModules.some( (m) => m.slug === "dynamic_pricing" || m.slug === "dynamic-pricing" ); window.yatraAdmin.flexiblePaymentsEnabled = enabledModules.some( (m) => m.slug === "flexible_payments" ); window.yatraAdmin.dynamicFormFieldEnabled = enabledModules.some( (m) => m.slug === "dynamic_form_field" ); window.yatraAdmin.customLandingPagesModuleEnabled = enabledModules.some( (m) => m.slug === "custom_landing_pages" ); window.yatraAdmin.showGoogleCalendarSettingsUI = enabledModules.some( (m) => m.slug === "google_calendar" || m.slug === "google-calendar" ); window.yatraAdmin.advancedDiscountEnabled = enabledModules.some( (m) => m.slug === "advanced_discount" || m.slug === "advanced-discount" ); window.yatraAdmin.aiAssistantEnabled = enabledModules.some( (m) => m.slug === "ai_assistant" || m.slug === "ai-assistant" ); window.yatraAdmin.whiteLabelEnabled = enabledModules.some( (m) => m.slug === "white_label" || m.slug === "white-label" ); window.yatraAdmin.whatsappEnabled = enabledModules.some( (m) => m.slug === "whatsapp" ); window.yatraAdmin.channelManagerEnabled = enabledModules.some( (m) => m.slug === "channel_manager" || m.slug === "channel-manager" ); window.yatraAdmin.webhooksEnabled = enabledModules.some( (m) => m.slug === "webhooks" ); window.yatraAdmin.scheduledPaymentsEnabled = enabledModules.some( (m) => m.slug === "scheduled_payments" || m.slug === "scheduled-payments" ); window.yatraAdmin.teamEnabled = enabledModules.some( (m) => m.slug === "team" ); window.yatraAdmin.showMailchimpSettingsUI = enabledModules.some( (m) => m.slug === "mailchimp" ); window.yatraAdmin.showFacebookPixelSettingsUI = enabledModules.some( (m) => m.slug === "facebook_pixel" ); window.yatraAdmin.showGoogleAnalyticsSettingsUI = enabledModules.some( (m) => m.slug === "google_analytics" ); window.dispatchEvent( new CustomEvent("yatra-modules-updated", { detail: { enabledModules, updatedModule: variables } }) ); const urlKey = window.__yatraUrlKey || 0; window.__yatraUrlKey = urlKey + 1; window.dispatchEvent(new CustomEvent("yatra-force-nav-refresh")); } const label = variables.name || variables.slug; showToast( variables.enabled ? __("{module} enabled successfully.", "yatra").replace( "{module}", label ) : __("{module} disabled successfully.", "yatra").replace( "{module}", label ), "success" ); }, onError: (error) => { showToast( error.message || __("Failed to update module.", "yatra"), "error" ); } }); }; const useBulkToggleModules = () => { const queryClient2 = useQueryClient(); const { showToast } = useToast(); return useMutation({ mutationFn: async (items) => { const response = await apiClient.post( "/modules/bulk-toggle", { items } ); return Array.isArray(response == null ? void 0 : response.data) ? response.data : []; }, onSuccess: (data, variables = [], context) => { queryClient2.setQueryData(["modules"], data); const response = context; if (response == null ? void 0 : response.message) { showToast(response.message, "warning"); } if (window.yatraAdmin && data) { const enabledModules = data.filter((m) => m.enabled); window.yatraAdmin.emailAutomationEnabled = enabledModules.some( (m) => m.slug === "email_automation" || m.slug === "email-automation" ); window.yatraAdmin.tripConsentEnabled = enabledModules.some( (m) => m.slug === "trip_consent" || m.slug === "trip-consent" ); window.yatraAdmin.additionalServicesEnabled = enabledModules.some( (m) => m.slug === "additional_services" || m.slug === "additional-services" ); window.yatraAdmin.abandonedBookingRecoveryEnabled = enabledModules.some( (m) => m.slug === "abandoned_booking_recovery" || m.slug === "abandoned-booking-recovery" ); window.yatraAdmin.dynamicPricingEnabled = enabledModules.some( (m) => m.slug === "dynamic_pricing" || m.slug === "dynamic-pricing" ); window.yatraAdmin.flexiblePaymentsEnabled = enabledModules.some( (m) => m.slug === "flexible_payments" ); window.yatraAdmin.dynamicFormFieldEnabled = enabledModules.some( (m) => m.slug === "dynamic_form_field" ); window.yatraAdmin.customLandingPagesModuleEnabled = enabledModules.some( (m) => m.slug === "custom_landing_pages" ); window.yatraAdmin.showGoogleCalendarSettingsUI = enabledModules.some( (m) => m.slug === "google_calendar" || m.slug === "google-calendar" ); window.yatraAdmin.advancedDiscountEnabled = enabledModules.some( (m) => m.slug === "advanced_discount" || m.slug === "advanced-discount" ); window.yatraAdmin.aiAssistantEnabled = enabledModules.some( (m) => m.slug === "ai_assistant" || m.slug === "ai-assistant" ); window.yatraAdmin.whiteLabelEnabled = enabledModules.some( (m) => m.slug === "white_label" || m.slug === "white-label" ); window.yatraAdmin.whatsappEnabled = enabledModules.some( (m) => m.slug === "whatsapp" ); window.yatraAdmin.channelManagerEnabled = enabledModules.some( (m) => m.slug === "channel_manager" || m.slug === "channel-manager" ); window.yatraAdmin.webhooksEnabled = enabledModules.some( (m) => m.slug === "webhooks" ); window.yatraAdmin.scheduledPaymentsEnabled = enabledModules.some( (m) => m.slug === "scheduled_payments" || m.slug === "scheduled-payments" ); window.yatraAdmin.teamEnabled = enabledModules.some( (m) => m.slug === "team" ); window.yatraAdmin.showMailchimpSettingsUI = enabledModules.some( (m) => m.slug === "mailchimp" ); window.yatraAdmin.showFacebookPixelSettingsUI = enabledModules.some( (m) => m.slug === "facebook_pixel" ); window.yatraAdmin.showGoogleAnalyticsSettingsUI = enabledModules.some( (m) => m.slug === "google_analytics" ); window.dispatchEvent( new CustomEvent("yatra-modules-updated", { detail: { enabledModules, updatedModules: variables || [] } }) ); const urlKey = window.__yatraUrlKey || 0; window.__yatraUrlKey = urlKey + 1; window.dispatchEvent(new CustomEvent("yatra-force-nav-refresh")); } if (!(response == null ? void 0 : response.message) && variables.length > 0) { const names = variables.map((item) => item.name || item.slug); const summary = formatNamesList(names); const message2 = variables[0].enabled ? __("Enabled: {modules}", "yatra").replace("{modules}", summary) : __("Disabled: {modules}", "yatra").replace("{modules}", summary); showToast(message2, "success"); } else if (!(response == null ? void 0 : response.message)) { showToast(__("Modules updated successfully.", "yatra"), "success"); } }, onError: (error) => { showToast( error.message || __("Failed to update modules.", "yatra"), "error" ); } }); }; const isProPluginActive = () => { var _a; const raw = (_a = window.yatraAdmin) == null ? void 0 : _a.isPro; let isPro = false; if (raw === true || raw === "true" || raw === 1 || raw === "1" || raw === "yes") { isPro = true; } else if (raw === false || raw === "false" || raw === 0 || raw === "0" || raw === "no") { isPro = false; } return isPro; }; const isModuleActive = (moduleName) => { var _a; if (!isProPluginActive()) { return false; } if (!moduleName || typeof moduleName !== "string") { return false; } const camelCaseName = moduleName.replace( /_([a-z])/g, (_, letter) => letter.toUpperCase() ); const localizedKey = camelCaseName + "Enabled"; const raw = (_a = window.yatraAdmin) == null ? void 0 : _a[localizedKey]; let isActive = false; if (raw === true || raw === "true" || raw === 1 || raw === "1" || raw === "yes") { isActive = true; } else if (raw === false || raw === "false" || raw === 0 || raw === "0" || raw === "no") { isActive = false; } return isActive; }; const isEmailAutomationModuleEnabled = () => isModuleActive("email_automation"); function navigateMenu(subpage, tabOrParams) { const pathname = window.location.pathname; const page = new URLSearchParams(window.location.search).get("page") || "yatra"; const sp = new URLSearchParams(); sp.set("page", page); if (subpage === "dashboard") ; else { sp.set("subpage", subpage); if (typeof tabOrParams === "string") { if (tabOrParams !== "") { sp.set("tab", tabOrParams); } } else if (tabOrParams && typeof tabOrParams === "object") { Object.entries(tabOrParams).forEach(([key2, value]) => { if (value === void 0 || value === null || value === "") return; sp.set(key2, String(value)); }); } } const newUrl = `${pathname}?${sp.toString()}`; window.history.pushState({}, "", newUrl); window.dispatchEvent(new PopStateEvent("popstate")); } const useNavigate = () => { const navigate = (params) => { const urlParams = new URLSearchParams(window.location.search); const setParam = (key2, value) => { if (value === void 0 || value === null) { urlParams.delete(key2); } else { urlParams.set(key2, value.toString()); } }; const standardKeys = ["subpage", "tab", "action", "id"]; standardKeys.forEach((key2) => { if (Object.prototype.hasOwnProperty.call(params, key2)) { setParam(key2, params[key2]); } }); Object.keys(params).forEach((key2) => { if (!standardKeys.includes(key2)) { setParam(key2, params[key2]); } }); const newUrl = `${window.location.pathname}?${urlParams.toString()}`; window.history.pushState({}, "", newUrl); window.dispatchEvent(new PopStateEvent("popstate")); }; return { navigate, navigateMenu }; }; const subscribers = /* @__PURE__ */ new Set(); function getSnapshot() { const w = window.yatraAdmin; if (!w) return {}; return { teamEnabled: w.teamEnabled, isWpAdmin: w.isWpAdmin, userCaps: w.userCaps, userScopes: w.userScopes }; } function emit() { subscribers.forEach((cb) => cb()); } function setUserCaps(caps) { if (window.yatraAdmin) { window.yatraAdmin.userCaps = [...caps]; emit(); } } function canCap(cap) { return evaluateCap(getSnapshot(), cap); } function evaluateCap(snapshot, cap) { if (!cap) return true; if (snapshot.isWpAdmin === true) return true; const caps = snapshot.userCaps; if (!Array.isArray(caps)) return true; return caps.includes(cap); } const SUBPAGE_TO_SECTION = { bookings: "bookings", payments: "payments", enquiries: "enquiries", reviews: "reviews", "abandoned-recovery": "abandoned" }; const NEW_COUNTS_QUERY_KEY = ["yatra", "admin", "new-counts"]; function useNotificationCounts() { return useQuery({ queryKey: NEW_COUNTS_QUERY_KEY, queryFn: async () => { const res = await apiClient.get("/admin/new-counts"); return (res == null ? void 0 : res.counts) ?? {}; }, // Pick up new orders/payments while the admin sits on another page, // without hammering the server. staleTime: 3e4, refetchInterval: 6e4, refetchOnWindowFocus: true, // A failed counts call must never break the admin UI — just render no badge. retry: 1 }); } function useMarkSectionSeen() { const queryClient2 = useQueryClient(); return useMutation({ mutationFn: async (section) => { return apiClient.post("/admin/mark-seen", { section }); }, onSuccess: () => { queryClient2.invalidateQueries({ queryKey: NEW_COUNTS_QUERY_KEY }); } }); } const InlineNotices = () => { const [notices, setNotices] = reactExports.useState([]); const load = reactExports.useCallback(async () => { try { const res = await apiService.getNotices(); const data = res == null ? void 0 : res.data; setNotices(Array.isArray(data) ? data : []); } catch { setNotices([]); } }, []); reactExports.useEffect(() => { load(); }, [load]); const dismiss = reactExports.useCallback( async (id) => { setNotices((prev) => prev.filter((n) => n.id !== id)); try { await apiService.dismissNotice(id); } catch { load(); } }, [load] ); if (notices.length === 0) { return null; } const renderUpgradeNotice = (n) => { const primary = Array.isArray(n.actions) ? n.actions[0] : void 0; return /* @__PURE__ */ jsxRuntimeExports.jsx( "div", { className: "mx-6 mt-4 border border-amber-200/60 dark:border-amber-900/40 rounded-xl overflow-hidden bg-amber-50/60 dark:bg-amber-950/20 shadow-sm", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border-l-4 border-amber-400", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-4", children: [ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-4", children: [ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-3 min-w-0", children: [ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-9 h-9 rounded-lg bg-amber-100/70 dark:bg-amber-900/20 border border-amber-200/60 dark:border-amber-900/40 flex items-center justify-center shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Crown, { className: "w-5 h-5 text-amber-700 dark:text-amber-300" }) }), /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-semibold text-gray-900 dark:text-gray-100", children: n.title || __("Upgrade to Pro", "yatra") }), /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-gray-600 dark:text-gray-300 mt-1", children: n.message }) ] }) ] }), /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 shrink-0", children: [ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[11px] font-bold px-2 py-0.5 rounded-full bg-amber-500 text-white", children: __("LIMITED TIME", "yatra") }), /* @__PURE__ */ jsxRuntimeExports.jsx( "button", { type: "button", onClick: () => dismiss(n.id), className: "text-gray-400 hover:text-gray-700 dark:hover:text-gray-200", "aria-label": __("Dismiss notice", "yatra"), children: "×" } ) ] }) ] }), /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-3 rounded-lg bg-amber-100/50 dark:bg-amber-900/15 border-l-4 border-amber-400 px-3 py-2 text-amber-800 dark:text-amber-200 text-sm font-medium flex items-center gap-2", children: [ /* @__PURE__ */ jsxRuntimeExports.jsx(Zap, { className: "w-4 h-4" }), __( "Special Offer: Upgrade today and save 30%+ with premium features and priority support.", "yatra" ) ] }), /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-4 flex items-center gap-3", children: [ (primary == null ? void 0 : primary.url) && (primary == null ? void 0 : primary.label) && /* @__PURE__ */ jsxRuntimeExports.jsxs( "a", { href: primary.url, target: primary.target, rel: primary.target === "_blank" ? "noopener noreferrer" : void 0, className: "inline-flex items-center gap-2 px-3 py-1.5 rounded-md bg-amber-500 hover:bg-amber-600 text-white text-xs font-semibold transition-colors", children: [ /* @__PURE__ */ jsxRuntimeExports.jsx(Zap, { className: "w-4 h-4" }), primary.label ] } ), /* @__PURE__ */ jsxRuntimeExports.jsx( "button", { type: "button", onClick: () => dismiss(n.id), className: "text-sm text-gray-500 hover:text-gray-800 dark:text-gray-400 dark:hover:text-gray-200", children: __("Maybe later", "yatra") } ) ] }) ] }) }) }, n.id ); }; return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: notices.map((n) => { if (n.id === "buy_pro") { return renderUpgradeNotice(n); } const primary = Array.isArray(n.actions) ? n.actions[0] : void 0; return /* @__PURE__ */ jsxRuntimeExports.jsx( "div", { className: "mx-6 mt-4 border border-gray-200 dark:border-gray-800 rounded-xl bg-white dark:bg-gray-900 shadow-sm", role: "status", "aria-live": "polite", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-4 flex items-start justify-between gap-4", children: [ /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-3 min-w-0", children: [ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-10 h-10 rounded-lg bg-blue-50 dark:bg-blue-950/30 border border-blue-200/60 dark:border-blue-900/40 flex items-center justify-center shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Star, { className: "w-5 h-5 text-blue-700 dark:text-blue-300" }) }), /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [ n.title && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-semibold text-gray-900 dark:text-gray-100", children: n.title }), /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-gray-700 dark:text-gray-300 mt-1", children: n.message }) ] }) ] }), /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 shrink-0", children: [ (primary == null ? void 0 : primary.url) && (primary == null ? void 0 : primary.label) && /* @__PURE__ */ jsxRuntimeExports.jsx( "a", { href: primary.url, target: primary.target, rel: primary.target === "_blank" ? "noopener noreferrer" : void 0, className: "inline-flex items-center px-3 py-1.5 rounded-md bg-blue-600 hover:bg-blue-700 text-white text-xs font-semibold transition-colors", children: primary.label } ), /* @__PURE__ */ jsxRuntimeExports.jsx( "button", { type: "button", onClick: () => dismiss(n.id), className: "text-gray-400 hover:text-gray-700 dark:hover:text-gray-200", "aria-label": __("Dismiss notice", "yatra"), children: "×" } ) ] }) ] }) }, n.id ); }) }); }; function extractGravatarUrl(avatarHtml, size) { if (!avatarHtml) { return `https://www.gravatar.com/avatar/00000000000000000000000000000000?s=${size}&d=identicon&r=pg`; } const imgMatch = avatarHtml.match(/]+src=["']([^"']+)["']/i); if (imgMatch && imgMatch[1]) { return imgMatch[1].replace(/s=\d+/, `s=${size}`); } return `https://www.gravatar.com/avatar/00000000000000000000000000000000?s=${size}&d=identicon&r=pg`; } function getGravatarUrl(size) { var _a; const avatarHtml = ((_a = window == null ? void 0 : window.yatraAdmin) == null ? void 0 : _a.currentUserAvatar) || ""; return extractGravatarUrl(avatarHtml, size); } const Layout = ({ children }) => { var _a, _b, _c, _d, _e, _f, _g, _h, _i, _j, _k, _l; const [darkMode, setDarkMode] = reactExports.useState(() => { const saved = localStorage.getItem("yatra-dark-mode"); return saved === "true"; }); reactExports.useEffect(() => { const root2 = document.documentElement; if (darkMode) { root2.classList.add("dark"); localStorage.setItem("yatra-dark-mode", "true"); } else { root2.classList.remove("dark"); localStorage.setItem("yatra-dark-mode", "false"); } }, [darkMode]); const [isModulesPanelOpen, setIsModulesPanelOpen] = reactExports.useState(false); const [isUserDropdownOpen, setIsUserDropdownOpen] = reactExports.useState(false); const modulesPanelRef = reactExports.useRef(null); const userDropdownRef = reactExports.useRef(null); const [licenseStatus, setLicenseStatus] = reactExports.useState( ((_a = window.yatraAdmin) == null ? void 0 : _a.licenseStatus) || null ); const { showToast } = useToast(); const flushRewriteRulesMutation = useMutation({ mutationFn: async () => postFlushRewriteRules(), onSuccess: () => { showToast(__("Rewrite rules flushed successfully", "yatra"), "success"); }, onError: (error) => { showToast( (error == null ? void 0 : error.message) || __("Failed to flush rewrite rules", "yatra"), "error" ); } }); const { data: modulesData, isLoading: isLoadingModules } = useModulesQuery({ enabled: isModulesPanelOpen }); const toggleModuleMutation = useToggleModule(); const safeModulesData = Array.isArray(modulesData) ? modulesData : []; const modulesPreview = reactExports.useMemo( () => safeModulesData.slice(0, 3), [safeModulesData] ); const handleQuickToggle = (module, enabled) => { toggleModuleMutation.mutate({ slug: module.slug, enabled, name: module.name }); }; const [urlKey, setUrlKey] = reactExports.useState(0); const [navRefreshKey, setNavRefreshKey] = reactExports.useState(0); const handleMenuNavClick = reactExports.useCallback( (e, subpage, tab) => { if (e.metaKey || e.ctrlKey || e.altKey || e.shiftKey || e.button !== 0) { return; } e.preventDefault(); navigateMenu(subpage, tab); }, [] ); reactExports.useEffect(() => { const handleClickOutside = (event) => { if (modulesPanelRef.current && !modulesPanelRef.current.contains(event.target)) { setIsModulesPanelOpen(false); } if (userDropdownRef.current && !userDropdownRef.current.contains(event.target)) { setIsUserDropdownOpen(false); } }; document.addEventListener("mousedown", handleClickOutside); return () => document.removeEventListener("mousedown", handleClickOutside); }, []); reactExports.useEffect(() => { const handleLocationChange = () => { setUrlKey((prev) => prev + 1); }; window.addEventListener("popstate", handleLocationChange); const interval = setInterval(() => { const currentSearch = window.location.search; if (currentSearch !== window.__lastSearch) { window.__lastSearch = currentSearch; handleLocationChange(); } }, 100); return () => { window.removeEventListener("popstate", handleLocationChange); clearInterval(interval); }; }, []); reactExports.useEffect(() => { const handleModuleUpdate = () => { setNavRefreshKey((prev) => prev + 1); setUrlKey((prev) => prev + 1); }; const handleForceRefresh = () => { setNavRefreshKey((prev) => prev + 1); setUrlKey((prev) => prev + 1); }; const handleLicenseStatusUpdate = (event) => { var _a2; const newStatus = (_a2 = event.detail) == null ? void 0 : _a2.status; if (newStatus) { setLicenseStatus(newStatus); } }; window.addEventListener("yatra-modules-updated", handleModuleUpdate); window.addEventListener("yatra-force-nav-refresh", handleForceRefresh); window.addEventListener( "yatra-license-status-updated", handleLicenseStatusUpdate ); return () => { window.removeEventListener("yatra-modules-updated", handleModuleUpdate); window.removeEventListener("yatra-force-nav-refresh", handleForceRefresh); window.removeEventListener( "yatra-license-status-updated", handleLicenseStatusUpdate ); }; }, []); reactExports.useEffect(() => { if (!isModulesPanelOpen) return; const handleClickOutside = (event) => { if (modulesPanelRef.current && !modulesPanelRef.current.contains(event.target)) { setIsModulesPanelOpen(false); } }; document.addEventListener("mousedown", handleClickOutside); return () => document.removeEventListener("mousedown", handleClickOutside); }, [isModulesPanelOpen]); const currentSubpage = reactExports.useMemo(() => { const params = new URLSearchParams(window.location.search); return params.get("subpage") || "dashboard"; }, [urlKey]); const { data: newCounts } = useNotificationCounts(); const getNewCount = (subpage) => { const section = SUBPAGE_TO_SECTION[subpage]; if (!section) return 0; const value = newCounts == null ? void 0 : newCounts[section]; return typeof value === "number" && value > 0 ? value : 0; }; const currentTab = reactExports.useMemo(() => { const params = new URLSearchParams(window.location.search); return params.get("tab") || "all"; }, [urlKey]); const currentAction = reactExports.useMemo(() => { const params = new URLSearchParams(window.location.search); return params.get("action"); }, [urlKey]); const isTripFormPage = reactExports.useMemo(() => { return currentSubpage === "trips" && (currentTab === "all" || !currentTab) && (currentAction === "create" || currentAction === "edit"); }, [currentSubpage, currentTab, currentAction, urlKey]); const [expandedMenus, setExpandedMenus] = reactExports.useState(() => { const params = new URLSearchParams(window.location.search); const subpage = params.get("subpage") || "dashboard"; return DEFAULT_MENU_ITEMS.some( (item) => { var _a2; return item.slug === subpage && (((_a2 = item.submenu) == null ? void 0 : _a2.length) ?? 0) > 0; } ) ? [subpage] : []; }); const baseUrl = reactExports.useMemo(() => { var _a2; return ((_a2 = window.yatraAdmin) == null ? void 0 : _a2.siteUrl) ? `${window.yatraAdmin.siteUrl}/wp-admin/admin.php?page=yatra` : "/wp-admin/admin.php?page=yatra"; }, []); const menuItems = reactExports.useMemo( // Every menu label is wrapped in __() with a literal string so // gettext extraction (scripts/extract-js-pot.mjs) picks them up // and Loco / Poedit / wp i18n can translate them. Previously most // were raw English literals — translations existed in the .po but // never reached the UI because there was no translation lookup at // render time. Wrapping is the WordPress-canonical way; the // pre_load_script_translations filter then delivers the locale // data to wp.i18n on every admin page load. () => { var _a2, _b2, _c2, _d2, _e2, _f2, _g2, _h2, _i2, _j2, _k2, _l2, _m; return [ { subpage: "dashboard", label: __("Dashboard", "yatra"), icon: LayoutDashboard, cap: "yatra_access_admin" }, { subpage: "trips", label: __("Trips", "yatra"), icon: MapPin, cap: "yatra_view_trips", submenu: [ { tab: "all", label: __("All Trips", "yatra"), icon: List }, { tab: "activities", label: __("Activities", "yatra"), icon: Activity }, { tab: "destinations", label: __("Destinations", "yatra"), icon: Route }, { tab: "categories", label: __("Categories", "yatra"), icon: FolderTree }, { tab: "difficulty-levels", label: __("Difficulty Levels", "yatra"), icon: TrendingUp }, // Availability - FREE feature, always show { tab: "availability", label: __("Availability", "yatra"), icon: CalendarDays }, // Attributes - FREE feature, always show { tab: "attributes", label: __("Attributes", "yatra"), icon: Tag }, // Additional Services - show only if Pro plugin is active and module is enabled ...isProPluginActive() && isModuleActive("additional_services") ? [ { tab: "additional-services", label: __("Additional Services", "yatra"), icon: Package, isPremium: true } ] : [], // Trip Consent - show only if Pro plugin is active and module is enabled ...isProPluginActive() && isModuleActive("trip_consent") ? [ { tab: "trip-consent", label: __("Trip Consent", "yatra"), icon: FileSignature, isPremium: true } ] : [] ] }, { subpage: "traveler-categories", label: __("Traveler Categories", "yatra"), icon: CircleUser, cap: "yatra_manage_trip_taxonomies" }, { subpage: "itinerary", label: __("Itinerary", "yatra"), icon: FileText, cap: "yatra_edit_trips", submenu: [ { tab: "item-types", label: __("Item Types", "yatra"), icon: Tag }, { tab: "items", label: __("Items", "yatra"), icon: Route }, { tab: "itinerary", label: __("Itinerary", "yatra"), icon: FileText } ] }, // Departures - FREE feature, always show { subpage: "departures", label: __("Departures", "yatra"), icon: Calendar$1, cap: "yatra_view_departures" }, { subpage: "discounts", label: __("Discounts", "yatra"), icon: BadgePercent, cap: "yatra_manage_discounts" }, { subpage: "payments", label: __("Payments", "yatra"), icon: CreditCard, cap: "yatra_view_financial_reports", // Payments only becomes a parent when the Pro "Scheduled Payments" // module is enabled — otherwise there is nothing to nest and it stays // exactly as it was: a single item that navigates straight to the // payments list. Children are only rendered for a visible parent, so // the pair inherits the Payments capability gate. // // `undefined` rather than an empty array: the rest of this component // treats "has a submenu" as truthiness, and an empty array would read // as a parent with no matching child — which would stop the Payments // item highlighting on its own page. submenu: ((_a2 = window.yatraAdmin) == null ? void 0 : _a2.scheduledPaymentsEnabled) ? [ { tab: "all", label: __("All Payments", "yatra"), icon: CreditCard }, { // "Scheduled" alone — the parent already says Payments. This // label is also the page's heading (the top bar reads it from // the active submenu item). tab: "scheduled", label: __("Scheduled", "yatra"), icon: CalendarClock, isPremium: true } ] : void 0 }, { subpage: "bookings", label: __("Bookings", "yatra"), icon: Calendar$1, cap: "yatra_view_bookings" }, { subpage: "customers", label: __("Customers", "yatra"), icon: CircleUser, cap: "yatra_view_customers" }, { subpage: "travelers", label: __("Travelers", "yatra"), icon: Plane, cap: "yatra_view_customers" }, { subpage: "enquiries", label: __("Enquiries", "yatra"), icon: MessageSquare, cap: "yatra_view_enquiries" }, { subpage: "reviews", label: __("Reviews", "yatra"), icon: Star, cap: "yatra_view_reviews" }, { subpage: "reports", label: __("Reports", "yatra"), icon: BarChart3, cap: "yatra_view_operational_reports" }, // Email — SMTP & transactional for all; Pro adds automation tabs on the same screen { subpage: "email-automation", label: __("Email", "yatra"), icon: Mail, isPremium: false, cap: "yatra_manage_emails" }, // Abandoned Booking Recovery - show only if Pro plugin is active and module is enabled ...isProPluginActive() && isModuleActive("abandoned_booking_recovery") ? [ { subpage: "abandoned-recovery", label: __("Abandoned Recovery", "yatra"), icon: RotateCcw, isPremium: true, cap: "yatra_manage_email_automation" } ] : [], // Dynamic Pricing - show only if Pro plugin is active and module is enabled ...isProPluginActive() && isModuleActive("dynamic_pricing") ? [ { subpage: "dynamic-pricing", label: __("Dynamic Pricing", "yatra"), icon: TrendingUp, isPremium: true, cap: "yatra_edit_trips" } ] : [], { subpage: "modules", label: __("Modules", "yatra"), icon: Puzzle, cap: "yatra_manage_modules" }, // White Label — only when the Agency-tier module is actually enabled. // (Agency license alone is not enough; the module toggle must be on, // otherwise users would see a link to a disabled feature. To get // here for the first time, an Agency admin enables the module from // Yatra → Modules.) The `whiteLabelEnabled` flag from // AdminAssetsProvider already implies Agency-active. // White Label — needs Agency-tier license AND module toggle on. // Mirrors the AI Assistant gate below so both menus appear / // disappear instantly when their module toggles, while staying // license-safe if the client-side `whiteLabelEnabled` flag is // ever stale or over-eager. AdminAssetsProvider seeds both // `isAgency` and `whiteLabelEnabled`; useModules.ts updates the // latter on toggle and fires `yatra-modules-updated` which bumps // navRefreshKey → this memo recomputes → menu appears. ...((_b2 = window.yatraAdmin) == null ? void 0 : _b2.isAgency) && ((_c2 = window.yatraAdmin) == null ? void 0 : _c2.whiteLabelEnabled) ? [ { subpage: "white-label", label: __("White Label", "yatra"), icon: Crown, isPremium: true, cap: "yatra_manage_white_label" } ] : [], // AI Assistant — only when BOTH the license tier qualifies // (Growth or Agency) AND the module toggle is on. Operators who // disable the module shouldn't keep seeing the menu item — it // would lead to a settings page they've explicitly opted out of. // The toggle handler in useModules.ts updates // window.yatraAdmin.aiAssistantEnabled and fires // `yatra-modules-updated`, which bumps navRefreshKey so this // memo recomputes immediately without a page reload. ...((_d2 = window.yatraAdmin) == null ? void 0 : _d2.isAiEligible) && ((_e2 = window.yatraAdmin) == null ? void 0 : _e2.aiAssistantEnabled) ? [ { subpage: "ai-assistant", label: __("AI Assistant", "yatra"), icon: Sparkles, isPremium: true, cap: "yatra_manage_ai" } ] : [], // WhatsApp Notifications — Growth/Agency module. Same gate // pattern as AI Assistant: needs the AI-eligibility flag (which // is the Growth-or-Agency tier check) AND the module toggle on. // useModules.ts updates `whatsappEnabled` on toggle + fires // `yatra-modules-updated` so this menu appears instantly without // a page reload. ...((_f2 = window.yatraAdmin) == null ? void 0 : _f2.isAiEligible) && ((_g2 = window.yatraAdmin) == null ? void 0 : _g2.whatsappEnabled) ? [ { subpage: "whatsapp", label: __("WhatsApp", "yatra"), icon: MessageCircle, isPremium: true, cap: "yatra_manage_whatsapp" } ] : [], // Channel Manager — Agency-tier OTA distribution hub. Same gate // pattern as White Label: needs the Agency license AND the module // toggle on. useModules.ts updates `channelManagerEnabled` on // toggle + fires `yatra-modules-updated` so this menu appears // instantly without a page reload. ...((_h2 = window.yatraAdmin) == null ? void 0 : _h2.isAgency) && ((_i2 = window.yatraAdmin) == null ? void 0 : _i2.channelManagerEnabled) ? [ { subpage: "channel-manager", label: __("Channel Manager", "yatra"), icon: Network, isPremium: true, cap: "yatra_manage_channel_manager" } ] : [], // Webhooks — Agency-tier outbound integration hub. Same gate // as Channel Manager / White Label: Agency license + module on. ...((_j2 = window.yatraAdmin) == null ? void 0 : _j2.isAgency) && ((_k2 = window.yatraAdmin) == null ? void 0 : _k2.webhooksEnabled) ? [ { subpage: "webhooks", label: __("Webhooks", "yatra"), icon: Webhook, isPremium: true, cap: "yatra_manage_webhooks" } ] : [], // Team & Access — Agency-tier granular roles + capability-level // access + audit log. Gate matches Webhooks: Agency license + // module on. The page itself is also cap-gated server-side; the // sidebar entry is just UX. ...((_l2 = window.yatraAdmin) == null ? void 0 : _l2.isAgency) && ((_m = window.yatraAdmin) == null ? void 0 : _m.teamEnabled) ? [ { subpage: "team", label: __("Team & Access", "yatra"), icon: Users, isPremium: true, cap: "yatra_manage_team" } ] : [], { subpage: "license", label: __("License", "yatra"), icon: Key, cap: "yatra_manage_settings" }, { subpage: "settings", label: __("Settings", "yatra"), icon: Settings$1, cap: "yatra_manage_settings" } ].filter((item) => !item.cap || canCap(item.cap)); }, // eslint-disable-next-line react-hooks/exhaustive-deps [navRefreshKey] ); const brandedMenuItems = reactExports.useMemo(() => { const overrides = readMenuOverrides(); const orderMap = readMenuOrder(); const atoms = []; const atomByKey = /* @__PURE__ */ new Map(); const apply2 = (key2, defaultParent, base, fallbackLabel) => { const ov = overrides[key2]; if (ov == null ? void 0 : ov.hidden) return null; const labelOverride = (ov == null ? void 0 : ov.label) && typeof ov.label === "string" && ov.label.trim() !== "" ? ov.label : null; const atom = { key: key2, defaultParent, label: labelOverride ?? fallbackLabel, iconOverride: ov == null ? void 0 : ov.icon, icon: base.icon, subpage: base.subpage ?? defaultParent ?? key2, tab: base.tab, isPremium: base.isPremium }; atoms.push(atom); atomByKey.set(key2, atom); return atom; }; for (const item of menuItems) { apply2(item.subpage, "", item, item.label); if (item.submenu) { for (const sub of item.submenu) { apply2( `${item.subpage}.${sub.tab}`, item.subpage, { icon: sub.icon, subpage: item.subpage, tab: sub.tab }, sub.label ); } } } const effectiveParent = (atom) => { var _a2; const ov = overrides[atom.key]; if (ov && typeof ov.parent === "string") { if (ov.parent === "") return ""; if (((_a2 = atomByKey.get(ov.parent)) == null ? void 0 : _a2.defaultParent) === "") return ov.parent; } return atom.defaultParent; }; const groups = /* @__PURE__ */ new Map(); for (const atom of atoms) { const parent = effectiveParent(atom); if (parent === atom.key) continue; const list = groups.get(parent) ?? []; list.push(atom); groups.set(parent, list); } const orderGroup = (parent, group) => { const saved = orderMap[parent] ?? []; if (saved.length === 0) return group; const byKey = new Map(group.map((a2) => [a2.key, a2])); const seen2 = /* @__PURE__ */ new Set(); const ordered = []; for (const k2 of saved) { const atom = byKey.get(k2); if (atom && !seen2.has(k2)) { ordered.push(atom); seen2.add(k2); } } for (const atom of group) { if (!seen2.has(atom.key)) ordered.push(atom); } return ordered; }; const topLevel = orderGroup("", groups.get("") ?? []); return topLevel.map((atom) => { const childAtoms = orderGroup(atom.key, groups.get(atom.key) ?? []); return { // React key. NOT `subpage`: a child promoted to top-level keeps its // parent's subpage (`payments.scheduled` → subpage `payments`), so two // siblings could share it. Duplicate keys make React reconcile the // wrong nodes and throw "removeChild ... not a child of this node". menuKey: atom.key, subpage: atom.subpage, label: atom.label, icon: atom.icon, iconOverride: atom.iconOverride, isPremium: atom.isPremium, submenu: childAtoms.length ? childAtoms.map((child) => ({ // Unique per child, for the same reason as `menuKey` above: // subpage + tab can repeat once items are moved between parents. menuKey: child.key, // Submenu rendering supports both legacy intra-parent items // (matching parent's subpage) and promoted/demoted items // that point at their own subpage. tab: child.defaultParent === atom.subpage ? child.tab : void 0, label: child.label, icon: child.icon, iconOverride: child.iconOverride, // Promoted top-level items now-as-children get an absolute href. href: child.defaultParent === atom.subpage ? void 0 : `${baseUrl}&subpage=${child.subpage}${child.tab ? `&tab=${child.tab}` : ""}`, subpage: child.subpage, tab_orig: child.tab })) : void 0 }; }); }, [menuItems, baseUrl]); reactExports.useEffect(() => { const parentOfCurrentPage = brandedMenuItems.find( (item) => { var _a2; return item.subpage === currentSubpage && (((_a2 = item.submenu) == null ? void 0 : _a2.length) ?? 0) > 0; } ); if (!parentOfCurrentPage) { return; } setExpandedMenus( (prev) => prev.includes(parentOfCurrentPage.subpage) ? prev : [...prev, parentOfCurrentPage.subpage] ); }, [currentSubpage, urlKey, brandedMenuItems]); const uiChrome = reactExports.useMemo(() => readUiChrome(), []); const isActive = (subpage, tab) => { if (subpage === "settings" && currentSubpage === "google-calendar") { return true; } if (tab) { return currentSubpage === subpage && currentTab === tab; } if (currentSubpage === subpage) { const menuItem = menuItems.find((item) => item.subpage === subpage); if (menuItem == null ? void 0 : menuItem.submenu) { return menuItem.submenu.some((sub) => sub.tab === currentTab); } return true; } return false; }; const isMenuExpanded = (subpage) => { return expandedMenus.includes(subpage); }; const toggleMenu = (subpage) => { setExpandedMenus( (prev) => prev.includes(subpage) ? prev.filter((m) => m !== subpage) : [...prev, subpage] ); }; const getUrl = (subpage, tab) => { if (subpage === "dashboard") { return baseUrl; } if (tab) { return `${baseUrl}&subpage=${subpage}&tab=${tab}`; } return `${baseUrl}&subpage=${subpage}`; }; return /* @__PURE__ */ jsxRuntimeExports.jsx( "div", { className: `min-h-screen ${darkMode ? "dark bg-gray-900" : "bg-gray-50"}`, children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex h-screen overflow-hidden", children: [ /* @__PURE__ */ jsxRuntimeExports.jsxs("aside", { className: "w-64 bg-white dark:bg-gray-800 border-r border-gray-200 dark:border-gray-700 flex flex-col", children: [ /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-16 px-6 flex items-center justify-center border-b border-gray-200 dark:border-gray-700", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-col gap-1", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [ (() => { var _a2, _b2; const brandName2 = ((_a2 = window.yatraAdmin) == null ? void 0 : _a2.brandName) || "Yatra"; const brandInitial = brandName2.charAt(0).toUpperCase() || "Y"; return ((_b2 = window.yatraAdmin) == null ? void 0 : _b2.brandLogoUrl) ? /* @__PURE__ */ jsxRuntimeExports.jsx( "img", { src: window.yatraAdmin.brandLogoUrl, alt: brandName2, width: 32, height: 32, className: "w-8 h-8 rounded-lg object-contain shrink-0 bg-blue-600 p-1 border border-blue-700 dark:border-blue-500" } ) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-8 h-8 bg-blue-600 rounded-lg flex items-center justify-center shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-white font-bold text-lg", children: brandInitial }) }); })(), /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col", children: [ /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xl font-bold text-gray-900 dark:text-white", children: ((_b = window.yatraAdmin) == null ? void 0 : _b.brandName) || "Yatra" }), !uiChrome.hideVersion && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 text-[10px] text-gray-500 dark:text-gray-400", children: [ /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { children: [ "v", ((_c = window.yatraAdmin) == null ? void 0 : _c.version) || "1.0.0" ] }), ((_d = window.yatraAdmin) == null ? void 0 : _d.proVersion) && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "px-1.5 py-0.5 bg-green-100 dark:bg-green-900/30 text-green-600 dark:text-green-400 rounded font-medium", children: [ "Pro v", (_e = window.yatraAdmin) == null ? void 0 : _e.proVersion ] }) ] }) ] }) ] }) }) }), /* @__PURE__ */ jsxRuntimeExports.jsx("nav", { className: "flex-1 p-4 space-y-1 overflow-y-auto", children: brandedMenuItems.map((item) => { const Icon = item.icon; const hasSubmenu = item.submenu && item.submenu.length > 0; const isExpanded = hasSubmenu && isMenuExpanded(item.subpage); const active = isActive(item.subpage); return ( // Keyed by the unique menu key, and by the item's shape: when a // module toggle turns a plain item into a parent (Payments → // All Payments / Scheduled) the branch below swaps an for a //