| 1 |
import { r as reactExports, j as jsxRuntimeExports, D as Loader2, S as Sparkles, aB as Wand2, bD as Pencil, bi as Scissors, bE as Maximize2, bh as Heart, ax as X, aA as Check, Q as AlertTriangle, az as AlertCircle, aQ as Eye, aE as HelpCircle, J as RefreshCw, ar as Clock, aD as CheckCircle2, u as useQuery, e as Tag, aw as Plus, bc as ChevronUp, x as ChevronDown, p as Calendar, V as ExternalLink, a5 as React, bF as CheckSquare, I as User, q as MapPin, n as Star, t as useQueryClient, k as FileText, as as DollarSign, bG as BookOpen, aS as Image, b6 as Download, aO as Search, l as Settings, v as useMutation, aG as Copy, bH as Lightbulb, b2 as Database, bI as History, aV as Save, bj as Send, aC as ChevronLeft, y as ChevronRight, bJ as Box, m as BarChart3, aN as Trash2, bb as GripVertical, aR as Upload, U as Users, bK as Home, bL as Car } from "./react-vendor-xzSqHjRF.js"; |
| 2 |
import { i as isAiEligible, a as isAiModuleEnabled, b as isAiReady, c as aiApi, M as Modal, B as Button, p as parseItineraryText, C as Card, d as CardContent, e as Badge, T as TimePicker, S as Select, f as CardHeader, g as CardTitle, h as CardDescription, u as usePermissions, j as getErrorContext, A as Alert, H as HelpText, k as ConfirmationDialog, l as buildYatraSinglePublicUrls, m as isWordPressPlainPermalink, D as DatePicker, I as IconPicker, L as LocationPicker, R as RichTextEditor, n as prepareWordPressMediaFrameOpen, o as fetchSettings } from "../../admin/dist/js/app.js"; |
| 3 |
import { _ as __$1, I as Input, a as apiClient, b as apiService, u as useToast, w as wpService, h as getCurrencySymbol, s as sprintf } from "./index-CbMRo6lO.js"; |
| 4 |
import { d as detectClarification, B as BuildItineraryModal } from "./BuildItineraryModal-ZwjF_pCL.js"; |
| 5 |
import { P as ProBadge, M as MultiSelect, a as ProFeature } from "./ProFeature-97ewna1x.js"; |
| 6 |
const IMPROVE_OPTIONS = [ |
| 7 |
{ task: "improve-tighten", label: "Tighten", icon: Scissors }, |
| 8 |
{ task: "improve-lengthen", label: "Lengthen", icon: Maximize2 }, |
| 9 |
{ task: "improve-tone-warmer", label: "Warmer tone", icon: Heart }, |
| 10 |
{ task: "improve-tone-formal", label: "More formal", icon: Pencil }, |
| 11 |
{ task: "improve-tone-shorter", label: "Make shorter", icon: Scissors } |
| 12 |
]; |
| 13 |
const AiFieldAffordance = ({ |
| 14 |
task, |
| 15 |
value, |
| 16 |
onAccept, |
| 17 |
buildContext, |
| 18 |
label, |
| 19 |
allowImprove = true, |
| 20 |
disabled = false, |
| 21 |
className = "" |
| 22 |
}) => { |
| 23 |
const [open, setOpen] = reactExports.useState(false); |
| 24 |
const [showImprove, setShowImprove] = reactExports.useState(false); |
| 25 |
const [isRunning, setIsRunning] = reactExports.useState(false); |
| 26 |
const [error, setError] = reactExports.useState(null); |
| 27 |
const [preview, setPreview] = reactExports.useState(null); |
| 28 |
const wrapperRef = reactExports.useRef(null); |
| 29 |
const gateBlocks = disabled || !isAiEligible() || !isAiModuleEnabled(); |
| 30 |
const ready = isAiReady(); |
| 31 |
reactExports.useEffect(() => { |
| 32 |
if (!open) return; |
| 33 |
const onDoc = (e) => { |
| 34 |
if (wrapperRef.current && !wrapperRef.current.contains(e.target)) { |
| 35 |
setOpen(false); |
| 36 |
setShowImprove(false); |
| 37 |
} |
| 38 |
}; |
| 39 |
document.addEventListener("mousedown", onDoc); |
| 40 |
return () => document.removeEventListener("mousedown", onDoc); |
| 41 |
}, [open]); |
| 42 |
const runGenerate = reactExports.useCallback(async () => { |
| 43 |
setOpen(false); |
| 44 |
setShowImprove(false); |
| 45 |
setError(null); |
| 46 |
setIsRunning(true); |
| 47 |
try { |
| 48 |
const ctx = buildContext(); |
| 49 |
const res = await aiApi.generate(task, ctx); |
| 50 |
setPreview({ text: res.text, source: "generate", task }); |
| 51 |
} catch (e) { |
| 52 |
setError(extractError$1(e)); |
| 53 |
} finally { |
| 54 |
setIsRunning(false); |
| 55 |
} |
| 56 |
}, [task, buildContext]); |
| 57 |
const runImprove = reactExports.useCallback( |
| 58 |
async (improveTask) => { |
| 59 |
setOpen(false); |
| 60 |
setShowImprove(false); |
| 61 |
setError(null); |
| 62 |
setIsRunning(true); |
| 63 |
try { |
| 64 |
const res = await aiApi.improve(improveTask, value); |
| 65 |
setPreview({ text: res.text, source: "improve", task: improveTask }); |
| 66 |
} catch (e) { |
| 67 |
setError(extractError$1(e)); |
| 68 |
} finally { |
| 69 |
setIsRunning(false); |
| 70 |
} |
| 71 |
}, |
| 72 |
[value] |
| 73 |
); |
| 74 |
const accept = () => { |
| 75 |
if (!preview) return; |
| 76 |
onAccept(preview.text); |
| 77 |
setPreview(null); |
| 78 |
}; |
| 79 |
const reject = () => setPreview(null); |
| 80 |
const tryAgain = () => { |
| 81 |
if (!preview) return; |
| 82 |
if (preview.source === "improve") { |
| 83 |
runImprove(preview.task); |
| 84 |
} else { |
| 85 |
runGenerate(); |
| 86 |
} |
| 87 |
}; |
| 88 |
const hasValue = value.trim() !== ""; |
| 89 |
if (gateBlocks) { |
| 90 |
return null; |
| 91 |
} |
| 92 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { ref: wrapperRef, className: `relative inline-block ${className}`, children: [ |
| 93 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 94 |
"button", |
| 95 |
{ |
| 96 |
type: "button", |
| 97 |
onClick: () => { |
| 98 |
if (!ready) { |
| 99 |
setError( |
| 100 |
__$1( |
| 101 |
"Add an API key in Yatra → AI Assistant before using this.", |
| 102 |
"yatra" |
| 103 |
) |
| 104 |
); |
| 105 |
return; |
| 106 |
} |
| 107 |
setOpen((v) => !v); |
| 108 |
setShowImprove(false); |
| 109 |
setError(null); |
| 110 |
}, |
| 111 |
disabled: isRunning, |
| 112 |
title: __$1("AI Assistant", "yatra"), |
| 113 |
className: `inline-flex h-7 w-7 items-center justify-center rounded-md border border-transparent text-gray-400 hover:bg-blue-50 hover:text-blue-600 hover:border-blue-200 disabled:opacity-50 dark:hover:bg-blue-900/20 dark:hover:text-blue-300 ${isRunning ? "animate-pulse" : ""}`, |
| 114 |
"aria-label": __$1("AI Assistant", "yatra"), |
| 115 |
children: isRunning ? /* @__PURE__ */ jsxRuntimeExports.jsx(Loader2, { className: "h-4 w-4 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "h-4 w-4" }) |
| 116 |
} |
| 117 |
), |
| 118 |
open && !preview && /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 119 |
"div", |
| 120 |
{ |
| 121 |
className: "absolute right-0 z-30 mt-1 w-56 rounded-md border border-gray-200 bg-white p-1 text-sm shadow-lg dark:border-gray-700 dark:bg-gray-800", |
| 122 |
role: "menu", |
| 123 |
children: [ |
| 124 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 125 |
"button", |
| 126 |
{ |
| 127 |
type: "button", |
| 128 |
onClick: runGenerate, |
| 129 |
className: "flex w-full items-center gap-2 rounded px-2 py-1.5 text-left text-gray-700 hover:bg-blue-50 dark:text-gray-200 dark:hover:bg-blue-900/30", |
| 130 |
children: [ |
| 131 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Wand2, { className: "h-4 w-4 text-blue-500" }), |
| 132 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex-1", children: [ |
| 133 |
hasValue ? __$1("Regenerate", "yatra") : __$1("Generate", "yatra"), |
| 134 |
" ", |
| 135 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-gray-400", children: [ |
| 136 |
"— ", |
| 137 |
label |
| 138 |
] }) |
| 139 |
] }) |
| 140 |
] |
| 141 |
} |
| 142 |
), |
| 143 |
allowImprove && hasValue && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ |
| 144 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 145 |
"button", |
| 146 |
{ |
| 147 |
type: "button", |
| 148 |
onClick: () => setShowImprove((v) => !v), |
| 149 |
className: "mt-0.5 flex w-full items-center gap-2 rounded px-2 py-1.5 text-left text-gray-700 hover:bg-blue-50 dark:text-gray-200 dark:hover:bg-blue-900/30", |
| 150 |
children: [ |
| 151 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Pencil, { className: "h-4 w-4 text-blue-500" }), |
| 152 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1", children: __$1("Improve this", "yatra") }), |
| 153 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-400", children: showImprove ? "▴" : "▾" }) |
| 154 |
] |
| 155 |
} |
| 156 |
), |
| 157 |
showImprove && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ml-2 mt-0.5 border-l border-gray-100 pl-2 dark:border-gray-700", children: IMPROVE_OPTIONS.map((opt) => { |
| 158 |
const Icon = opt.icon; |
| 159 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 160 |
"button", |
| 161 |
{ |
| 162 |
type: "button", |
| 163 |
onClick: () => runImprove(opt.task), |
| 164 |
className: "flex w-full items-center gap-2 rounded px-2 py-1.5 text-left text-gray-700 hover:bg-blue-50 dark:text-gray-200 dark:hover:bg-blue-900/30", |
| 165 |
children: [ |
| 166 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Icon, { className: "h-3.5 w-3.5 text-blue-400" }), |
| 167 |
__$1(opt.label, "yatra") |
| 168 |
] |
| 169 |
}, |
| 170 |
opt.task |
| 171 |
); |
| 172 |
}) }) |
| 173 |
] }) |
| 174 |
] |
| 175 |
} |
| 176 |
), |
| 177 |
preview && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "absolute right-0 z-30 mt-1 w-[420px] max-w-[90vw] rounded-md border border-blue-200 bg-white p-3 text-sm shadow-xl dark:border-blue-500/40 dark:bg-gray-800", children: [ |
| 178 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-2 flex items-center gap-2 text-xs font-medium text-blue-600 dark:text-blue-300", children: [ |
| 179 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "h-3.5 w-3.5" }), |
| 180 |
preview.source === "improve" ? __$1("AI improved your text", "yatra") : __$1("AI generated this draft", "yatra") |
| 181 |
] }), |
| 182 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "max-h-72 overflow-y-auto whitespace-pre-wrap rounded border border-gray-100 bg-gray-50 p-2 text-xs text-gray-800 dark:border-gray-700 dark:bg-gray-900 dark:text-gray-200", children: preview.text || /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-400", children: __$1("(empty response)", "yatra") }) }), |
| 183 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2 flex items-center justify-end gap-2", children: [ |
| 184 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 185 |
"button", |
| 186 |
{ |
| 187 |
type: "button", |
| 188 |
onClick: tryAgain, |
| 189 |
className: "rounded border border-gray-200 px-2 py-1 text-xs text-gray-600 hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-700", |
| 190 |
children: __$1("Try again", "yatra") |
| 191 |
} |
| 192 |
), |
| 193 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 194 |
"button", |
| 195 |
{ |
| 196 |
type: "button", |
| 197 |
onClick: reject, |
| 198 |
className: "inline-flex items-center gap-1 rounded border border-gray-200 px-2 py-1 text-xs text-gray-600 hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-700", |
| 199 |
children: [ |
| 200 |
/* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "h-3 w-3" }), |
| 201 |
__$1("Discard", "yatra") |
| 202 |
] |
| 203 |
} |
| 204 |
), |
| 205 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 206 |
"button", |
| 207 |
{ |
| 208 |
type: "button", |
| 209 |
onClick: accept, |
| 210 |
disabled: !preview.text, |
| 211 |
className: "inline-flex items-center gap-1 rounded bg-blue-600 px-3 py-1 text-xs font-medium text-white hover:bg-blue-700 disabled:opacity-50", |
| 212 |
children: [ |
| 213 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "h-3 w-3" }), |
| 214 |
__$1("Accept", "yatra") |
| 215 |
] |
| 216 |
} |
| 217 |
) |
| 218 |
] }) |
| 219 |
] }), |
| 220 |
error && !preview && /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 221 |
"div", |
| 222 |
{ |
| 223 |
className: "absolute right-0 z-30 mt-1 w-72 rounded-md border border-red-200 bg-white p-2 text-xs text-red-700 shadow-lg dark:border-red-500/40 dark:bg-gray-800 dark:text-red-300", |
| 224 |
role: "alert", |
| 225 |
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-2", children: [ |
| 226 |
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertTriangle, { className: "mt-0.5 h-3.5 w-3.5 shrink-0" }), |
| 227 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1", children: error }), |
| 228 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 229 |
"button", |
| 230 |
{ |
| 231 |
type: "button", |
| 232 |
onClick: () => setError(null), |
| 233 |
className: "text-red-400 hover:text-red-600", |
| 234 |
"aria-label": __$1("Dismiss", "yatra"), |
| 235 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "h-3.5 w-3.5" }) |
| 236 |
} |
| 237 |
) |
| 238 |
] }) |
| 239 |
} |
| 240 |
) |
| 241 |
] }); |
| 242 |
}; |
| 243 |
function extractError$1(e) { |
| 244 |
var _a; |
| 245 |
if (!e) return "AI request failed."; |
| 246 |
const data = ((_a = e == null ? void 0 : e.response) == null ? void 0 : _a.data) ?? (e == null ? void 0 : e.data) ?? null; |
| 247 |
if (data && typeof data === "object") { |
| 248 |
if (typeof data.message === "string") return data.message; |
| 249 |
if (Array.isArray(data.errors)) { |
| 250 |
return data.errors.map((x) => (x == null ? void 0 : x.message) ?? String(x)).join("; "); |
| 251 |
} |
| 252 |
} |
| 253 |
if (typeof (e == null ? void 0 : e.message) === "string") return e.message; |
| 254 |
return String(e); |
| 255 |
} |
| 256 |
function plainTextToHtml(text) { |
| 257 |
if (!text) return ""; |
| 258 |
const escape = (s) => s.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">"); |
| 259 |
const paragraphs = text.replace(/\r\n?/g, "\n").split(/\n{2,}/).map((p) => p.trim()).filter((p) => p !== ""); |
| 260 |
return paragraphs.map((p) => `<p>${escape(p).replace(/\n/g, "<br>")}</p>`).join(""); |
| 261 |
} |
| 262 |
function decodeAmenityList(text) { |
| 263 |
return text.split(/\r?\n/).map( |
| 264 |
(line) => line.replace(/^[\s\-\*••]+/, "").trim() |
| 265 |
).filter((line) => line !== "" && !/^Day\s+\d+/i.test(line)).map((title) => ({ title, description: "" })); |
| 266 |
} |
| 267 |
function decodeItinerary(text) { |
| 268 |
const parsed = parseItineraryText(text); |
| 269 |
return parsed.map((p) => ({ |
| 270 |
day: p.day, |
| 271 |
day_title: p.day_title, |
| 272 |
entries: [ |
| 273 |
{ |
| 274 |
id: `ai-day-${p.day}-${Date.now()}`, |
| 275 |
day: p.day, |
| 276 |
day_title: p.day_title, |
| 277 |
item_type_id: "", |
| 278 |
item_id: "", |
| 279 |
item_type: "Activity", |
| 280 |
title: p.day_title || `Day ${p.day}`, |
| 281 |
description: p.description, |
| 282 |
start_time: "", |
| 283 |
end_time: "", |
| 284 |
time_type: "flexible", |
| 285 |
cost_per_person: false, |
| 286 |
included_items: [], |
| 287 |
excluded_items: [], |
| 288 |
images: [], |
| 289 |
status: "active" |
| 290 |
} |
| 291 |
] |
| 292 |
})); |
| 293 |
} |
| 294 |
const ALL_TASKS = [ |
| 295 |
{ |
| 296 |
key: "short_description", |
| 297 |
label: __$1("Short description", "yatra"), |
| 298 |
task: "trip-short-description", |
| 299 |
decode: (t) => t.trim(), |
| 300 |
preview: (v) => String(v ?? "") |
| 301 |
}, |
| 302 |
{ |
| 303 |
key: "description", |
| 304 |
label: __$1("Trip description", "yatra"), |
| 305 |
task: "trip-description", |
| 306 |
// RichTextEditor expects HTML — wrap LLM's plain-text paragraphs in <p>. |
| 307 |
decode: (t) => plainTextToHtml(t), |
| 308 |
preview: (v) => typeof v === "string" ? v.replace(/<\/p>\s*<p>/gi, "\n\n").replace(/<[^>]+>/g, "").trim() : "" |
| 309 |
}, |
| 310 |
{ |
| 311 |
key: "highlights", |
| 312 |
label: __$1("Highlights", "yatra"), |
| 313 |
task: "trip-highlights", |
| 314 |
// TripForm's `highlights` field is a string[] — each line of the |
| 315 |
// LLM output becomes one bullet, stripping any accidental leading |
| 316 |
// bullets / dashes the model may have added despite the prompt. |
| 317 |
decode: (t) => t.split(/\r?\n/).map((l) => l.replace(/^[\s\-\*•·●]+/, "").trim()).filter((l) => l !== ""), |
| 318 |
preview: (v) => Array.isArray(v) ? v.map((s) => `• ${s}`).join("\n") : "" |
| 319 |
}, |
| 320 |
{ |
| 321 |
key: "included_items", |
| 322 |
label: __$1("What's included", "yatra"), |
| 323 |
task: "trip-included-items", |
| 324 |
decode: (t) => decodeAmenityList(t), |
| 325 |
preview: (v) => Array.isArray(v) ? v.map((i) => `• ${i.title}`).join("\n") : "" |
| 326 |
}, |
| 327 |
{ |
| 328 |
key: "excluded_items", |
| 329 |
label: __$1("What's excluded", "yatra"), |
| 330 |
task: "trip-excluded-items", |
| 331 |
decode: (t) => decodeAmenityList(t), |
| 332 |
preview: (v) => Array.isArray(v) ? v.map((i) => `• ${i.title}`).join("\n") : "" |
| 333 |
}, |
| 334 |
{ |
| 335 |
key: "cancellation_policy", |
| 336 |
label: __$1("Cancellation policy", "yatra"), |
| 337 |
task: "trip-cancellation-policy", |
| 338 |
decode: (t) => t.trim(), |
| 339 |
preview: (v) => String(v ?? "") |
| 340 |
}, |
| 341 |
{ |
| 342 |
key: "itinerary_days", |
| 343 |
label: __$1("Day-by-day itinerary", "yatra"), |
| 344 |
task: "trip-itinerary", |
| 345 |
decode: (t) => decodeItinerary(t), |
| 346 |
preview: (v) => Array.isArray(v) ? v.map( |
| 347 |
(d) => { |
| 348 |
var _a; |
| 349 |
return `Day ${d.day}: ${d.day_title || ""} |
| 350 |
${((_a = d.entries[0]) == null ? void 0 : _a.description) ?? ""}`; |
| 351 |
} |
| 352 |
).join("\n\n") : "" |
| 353 |
}, |
| 354 |
{ |
| 355 |
key: "meta_title", |
| 356 |
label: __$1("SEO meta title", "yatra"), |
| 357 |
task: "seo-meta-title", |
| 358 |
decode: (t) => t.trim().slice(0, 60), |
| 359 |
preview: (v) => String(v ?? "") |
| 360 |
}, |
| 361 |
{ |
| 362 |
key: "meta_description", |
| 363 |
label: __$1("SEO meta description", "yatra"), |
| 364 |
task: "seo-meta-description", |
| 365 |
decode: (t) => t.trim().slice(0, 160), |
| 366 |
preview: (v) => String(v ?? "") |
| 367 |
} |
| 368 |
]; |
| 369 |
const AutoFillTripModal = ({ |
| 370 |
open, |
| 371 |
onClose, |
| 372 |
buildContext, |
| 373 |
onFieldsAccepted, |
| 374 |
itineraryOnly = false |
| 375 |
}) => { |
| 376 |
const initialRows = reactExports.useMemo( |
| 377 |
() => ALL_TASKS.map((spec) => ({ |
| 378 |
spec, |
| 379 |
selected: itineraryOnly ? spec.key === "itinerary_days" : true, |
| 380 |
status: "idle", |
| 381 |
accepted: false |
| 382 |
})), |
| 383 |
[itineraryOnly] |
| 384 |
); |
| 385 |
const [rows, setRows] = reactExports.useState(initialRows); |
| 386 |
const [phase, setPhase] = reactExports.useState("setup"); |
| 387 |
const [extraContext, setExtraContext] = reactExports.useState(""); |
| 388 |
reactExports.useEffect(() => { |
| 389 |
if (open) { |
| 390 |
setRows(initialRows); |
| 391 |
setPhase("setup"); |
| 392 |
setExtraContext(""); |
| 393 |
} |
| 394 |
}, [open, initialRows]); |
| 395 |
if (!open) return null; |
| 396 |
if (!isAiReady()) { |
| 397 |
return /* @__PURE__ */ jsxRuntimeExports.jsx(Modal, { isOpen: open, onClose, size: "md", hideHeader: true, hideFooter: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-6 max-w-md", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-3", children: [ |
| 398 |
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "h-5 w-5 text-amber-500 mt-0.5" }), |
| 399 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 400 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-semibold text-gray-900 dark:text-white", children: __$1("AI Assistant not configured", "yatra") }), |
| 401 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-sm text-gray-600 dark:text-gray-300", children: __$1( |
| 402 |
"Add an OpenAI or Anthropic key under Yatra → AI Assistant first.", |
| 403 |
"yatra" |
| 404 |
) }), |
| 405 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-3 flex gap-2", children: [ |
| 406 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Button, { asChild: true, children: /* @__PURE__ */ jsxRuntimeExports.jsx("a", { href: "admin.php?page=yatra&subpage=ai-assistant", children: __$1("Open AI settings", "yatra") }) }), |
| 407 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", onClick: onClose, children: __$1("Cancel", "yatra") }) |
| 408 |
] }) |
| 409 |
] }) |
| 410 |
] }) }) }); |
| 411 |
} |
| 412 |
const selectedCount = rows.filter((r) => r.selected).length; |
| 413 |
const generatedCount = rows.filter((r) => r.status === "done").length; |
| 414 |
const failedCount = rows.filter((r) => r.status === "failed").length; |
| 415 |
const needsContextCount = rows.filter( |
| 416 |
(r) => r.status === "needs_context" |
| 417 |
).length; |
| 418 |
const allDone = rows.filter((r) => r.selected).every( |
| 419 |
(r) => r.status === "done" || r.status === "failed" || r.status === "needs_context" |
| 420 |
); |
| 421 |
const toggle = (key) => setRows( |
| 422 |
(prev) => prev.map( |
| 423 |
(r) => r.spec.key === key ? { ...r, selected: !r.selected } : r |
| 424 |
) |
| 425 |
); |
| 426 |
const toggleAccept = (key) => setRows( |
| 427 |
(prev) => prev.map( |
| 428 |
(r) => r.spec.key === key && r.status === "done" ? { ...r, accepted: !r.accepted } : r |
| 429 |
) |
| 430 |
); |
| 431 |
const runOneTask = async (taskKey, extraSuffix = "") => { |
| 432 |
setRows( |
| 433 |
(prev) => prev.map( |
| 434 |
(row) => row.spec.key === taskKey ? { |
| 435 |
...row, |
| 436 |
status: "running", |
| 437 |
error: void 0, |
| 438 |
clarificationMessage: void 0, |
| 439 |
clarificationQuestions: void 0 |
| 440 |
} : row |
| 441 |
) |
| 442 |
); |
| 443 |
const spec = ALL_TASKS.find((t) => t.key === taskKey); |
| 444 |
if (!spec) return; |
| 445 |
const combinedContext = [extraContext.trim(), extraSuffix.trim()].filter((s) => s !== "").join("\n\n"); |
| 446 |
const ctx = { |
| 447 |
...buildContext(), |
| 448 |
extra_context: combinedContext |
| 449 |
}; |
| 450 |
try { |
| 451 |
const res = await aiApi.generate(spec.task, ctx); |
| 452 |
const clarification = detectClarification(res.text, { |
| 453 |
expectDayHeads: spec.task === "trip-itinerary" |
| 454 |
}); |
| 455 |
if (clarification.isClarification) { |
| 456 |
setRows( |
| 457 |
(prev) => prev.map( |
| 458 |
(row) => row.spec.key === taskKey ? { |
| 459 |
...row, |
| 460 |
status: "needs_context", |
| 461 |
clarificationMessage: clarification.message, |
| 462 |
clarificationQuestions: clarification.questions, |
| 463 |
retryContext: "" |
| 464 |
} : row |
| 465 |
) |
| 466 |
); |
| 467 |
return; |
| 468 |
} |
| 469 |
const decoded = spec.decode(res.text, ctx); |
| 470 |
const preview = spec.preview(decoded); |
| 471 |
setRows( |
| 472 |
(prev) => prev.map( |
| 473 |
(row) => row.spec.key === taskKey ? { |
| 474 |
...row, |
| 475 |
status: "done", |
| 476 |
decoded, |
| 477 |
preview, |
| 478 |
accepted: true |
| 479 |
} : row |
| 480 |
) |
| 481 |
); |
| 482 |
} catch (e) { |
| 483 |
const msg = extractError(e); |
| 484 |
setRows( |
| 485 |
(prev) => prev.map( |
| 486 |
(row) => row.spec.key === taskKey ? { |
| 487 |
...row, |
| 488 |
status: "failed", |
| 489 |
error: msg |
| 490 |
} : row |
| 491 |
) |
| 492 |
); |
| 493 |
} |
| 494 |
}; |
| 495 |
const runGenerations = async () => { |
| 496 |
setPhase("running"); |
| 497 |
const selected = rows.filter((r) => r.selected).map((r) => r.spec.key); |
| 498 |
await Promise.all(selected.map((k) => runOneTask(k))); |
| 499 |
setPhase("preview"); |
| 500 |
}; |
| 501 |
const retryWithContext = (taskKey) => { |
| 502 |
var _a; |
| 503 |
const row = rows.find((r) => r.spec.key === taskKey); |
| 504 |
const suffix = ((_a = row == null ? void 0 : row.retryContext) == null ? void 0 : _a.trim()) ?? ""; |
| 505 |
if (suffix === "") return; |
| 506 |
void runOneTask(taskKey, suffix); |
| 507 |
}; |
| 508 |
const updateRetryContext = (taskKey, value) => setRows( |
| 509 |
(prev) => prev.map( |
| 510 |
(row) => row.spec.key === taskKey ? { ...row, retryContext: value } : row |
| 511 |
) |
| 512 |
); |
| 513 |
const applyAccepted = () => { |
| 514 |
const updates = {}; |
| 515 |
for (const r of rows) { |
| 516 |
if (r.status === "done" && r.accepted && r.decoded !== void 0) { |
| 517 |
updates[r.spec.key] = r.decoded; |
| 518 |
} |
| 519 |
} |
| 520 |
onFieldsAccepted(updates); |
| 521 |
onClose(); |
| 522 |
}; |
| 523 |
return /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 524 |
Modal, |
| 525 |
{ |
| 526 |
isOpen: open, |
| 527 |
onClose, |
| 528 |
size: "xl", |
| 529 |
hideHeader: true, |
| 530 |
hideFooter: true, |
| 531 |
bodyScrollClassName: "overflow-visible", |
| 532 |
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex h-[80vh] max-h-[800px] min-w-[640px] max-w-[920px] flex-col", children: [ |
| 533 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between border-b border-gray-200 px-6 py-4 dark:border-gray-700", children: [ |
| 534 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ |
| 535 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "h-5 w-5 text-blue-600" }), |
| 536 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: itineraryOnly ? __$1("Generate itinerary", "yatra") : __$1("Auto-fill trip with AI", "yatra") }) |
| 537 |
] }), |
| 538 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 539 |
"button", |
| 540 |
{ |
| 541 |
type: "button", |
| 542 |
onClick: onClose, |
| 543 |
className: "rounded text-gray-400 hover:text-gray-600", |
| 544 |
"aria-label": __$1("Close", "yatra"), |
| 545 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "h-5 w-5" }) |
| 546 |
} |
| 547 |
) |
| 548 |
] }), |
| 549 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 overflow-y-auto px-6 py-4", children: [ |
| 550 |
phase === "setup" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [ |
| 551 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-300", children: itineraryOnly ? __$1( |
| 552 |
"AI will generate a day-by-day itinerary grounded in this trip's facts. Existing itinerary will be replaced when you accept the result.", |
| 553 |
"yatra" |
| 554 |
) : __$1( |
| 555 |
"Pick the sections to generate. AI runs them in parallel, then you review each result before anything touches the form.", |
| 556 |
"yatra" |
| 557 |
) }), |
| 558 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-md border border-blue-200 bg-blue-50/40 p-3 dark:border-blue-500/40 dark:bg-blue-900/20", children: [ |
| 559 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 560 |
"label", |
| 561 |
{ |
| 562 |
htmlFor: "autofill-context", |
| 563 |
className: "mb-1 flex items-center gap-1.5 text-xs font-medium text-blue-900 dark:text-blue-200", |
| 564 |
children: [ |
| 565 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "h-3.5 w-3.5" }), |
| 566 |
__$1("Tell AI about this trip", "yatra"), |
| 567 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ml-1 rounded bg-blue-200 px-1.5 py-0.5 text-[10px] font-semibold uppercase text-blue-800 dark:bg-blue-900/60 dark:text-blue-200", children: __$1("Recommended", "yatra") }) |
| 568 |
] |
| 569 |
} |
| 570 |
), |
| 571 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 572 |
"textarea", |
| 573 |
{ |
| 574 |
id: "autofill-context", |
| 575 |
rows: 4, |
| 576 |
className: "w-full rounded-md border border-blue-200 bg-white p-2 text-sm focus:outline-none focus:ring-2 focus:ring-blue-400 dark:border-blue-500/40 dark:bg-gray-800", |
| 577 |
placeholder: __$1( |
| 578 |
"e.g. 7-day cultural trek to Dhaka, moderate difficulty. Includes food tours, rickshaw rides, old town walking tour. Best for ages 18-65. Mid-range hotels.", |
| 579 |
"yatra" |
| 580 |
), |
| 581 |
value: extraContext, |
| 582 |
onChange: (e) => setExtraContext(e.target.value) |
| 583 |
} |
| 584 |
), |
| 585 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-[11px] text-blue-700 dark:text-blue-300", children: __$1( |
| 586 |
"The more facts you share, the better the output. Existing fields on the form (title, destinations, duration) are also passed automatically.", |
| 587 |
"yatra" |
| 588 |
) }) |
| 589 |
] }), |
| 590 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "rounded-md border border-gray-200 dark:border-gray-700", children: rows.map((r) => /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 591 |
"label", |
| 592 |
{ |
| 593 |
className: "flex items-center gap-3 border-b border-gray-100 px-3 py-2 last:border-b-0 dark:border-gray-700", |
| 594 |
children: [ |
| 595 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 596 |
"input", |
| 597 |
{ |
| 598 |
type: "checkbox", |
| 599 |
checked: r.selected, |
| 600 |
onChange: () => toggle(r.spec.key) |
| 601 |
} |
| 602 |
), |
| 603 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm text-gray-900 dark:text-white", children: r.spec.label }), |
| 604 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ml-auto text-xs text-gray-400", children: r.spec.task }) |
| 605 |
] |
| 606 |
}, |
| 607 |
r.spec.key |
| 608 |
)) }), |
| 609 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: [ |
| 610 |
__$1("Tokens count against your provider plan.", "yatra"), |
| 611 |
" ", |
| 612 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 613 |
"a", |
| 614 |
{ |
| 615 |
className: "text-blue-600 underline dark:text-blue-300", |
| 616 |
href: "admin.php?page=yatra&subpage=ai-assistant", |
| 617 |
target: "_blank", |
| 618 |
rel: "noopener noreferrer", |
| 619 |
children: __$1("See usage", "yatra") |
| 620 |
} |
| 621 |
) |
| 622 |
] }) |
| 623 |
] }), |
| 624 |
phase !== "setup" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: rows.filter((r) => r.selected).map((r) => /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 625 |
TaskRowView, |
| 626 |
{ |
| 627 |
row: r, |
| 628 |
onToggleAccept: () => toggleAccept(r.spec.key), |
| 629 |
onRetryContextChange: (v) => updateRetryContext(r.spec.key, v), |
| 630 |
onRetry: () => retryWithContext(r.spec.key) |
| 631 |
}, |
| 632 |
r.spec.key |
| 633 |
)) }) |
| 634 |
] }), |
| 635 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between border-t border-gray-200 px-6 py-3 dark:border-gray-700", children: [ |
| 636 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs text-gray-500 dark:text-gray-400", children: [ |
| 637 |
phase === "setup" && (selectedCount === 0 ? __$1("Pick at least one section.", "yatra") : `${selectedCount} ${__$1("sections selected.", "yatra")}`), |
| 638 |
phase === "running" && `${__$1("Generating…", "yatra")} ${generatedCount}/${selectedCount}`, |
| 639 |
phase === "preview" && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ |
| 640 |
`${generatedCount} ${__$1("ready", "yatra")}`, |
| 641 |
needsContextCount > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ml-2 text-amber-600 dark:text-amber-300", children: `${needsContextCount} ${__$1("need more info", "yatra")}` }), |
| 642 |
failedCount > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ml-2 text-red-500", children: `${failedCount} ${__$1("failed", "yatra")}` }) |
| 643 |
] }) |
| 644 |
] }), |
| 645 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [ |
| 646 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Button, { variant: "outline", onClick: onClose, children: __$1("Cancel", "yatra") }), |
| 647 |
phase === "setup" && /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { onClick: runGenerations, disabled: selectedCount === 0, children: [ |
| 648 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "mr-2 h-4 w-4" }), |
| 649 |
__$1("Generate", "yatra") |
| 650 |
] }), |
| 651 |
phase === "preview" && /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 652 |
Button, |
| 653 |
{ |
| 654 |
onClick: applyAccepted, |
| 655 |
disabled: !rows.some((r) => r.accepted && r.status === "done"), |
| 656 |
children: [ |
| 657 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "mr-2 h-4 w-4" }), |
| 658 |
__$1("Apply accepted", "yatra") |
| 659 |
] |
| 660 |
} |
| 661 |
), |
| 662 |
phase === "running" && !allDone && /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { disabled: true, children: [ |
| 663 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Loader2, { className: "mr-2 h-4 w-4 animate-spin" }), |
| 664 |
__$1("Working…", "yatra") |
| 665 |
] }) |
| 666 |
] }) |
| 667 |
] }) |
| 668 |
] }) |
| 669 |
} |
| 670 |
); |
| 671 |
}; |
| 672 |
const TaskRowView = ({ row, onToggleAccept, onRetryContextChange, onRetry }) => { |
| 673 |
const [expanded, setExpanded] = reactExports.useState(false); |
| 674 |
const retryDisabled = (row.retryContext ?? "").trim() === ""; |
| 675 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "rounded-md border border-gray-200 p-3 dark:border-gray-700", children: [ |
| 676 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ |
| 677 |
/* @__PURE__ */ jsxRuntimeExports.jsx(StatusBadge, { status: row.status }), |
| 678 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium text-sm text-gray-900 dark:text-white", children: row.spec.label }), |
| 679 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ml-auto flex items-center gap-2", children: row.status === "done" && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ |
| 680 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 681 |
"button", |
| 682 |
{ |
| 683 |
type: "button", |
| 684 |
onClick: () => setExpanded((v) => !v), |
| 685 |
className: "inline-flex items-center gap-1 rounded border border-gray-200 px-2 py-0.5 text-xs text-gray-600 hover:bg-gray-50 dark:border-gray-600 dark:text-gray-300 dark:hover:bg-gray-700", |
| 686 |
children: [ |
| 687 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Eye, { className: "h-3 w-3" }), |
| 688 |
expanded ? __$1("Hide", "yatra") : __$1("Preview", "yatra") |
| 689 |
] |
| 690 |
} |
| 691 |
), |
| 692 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex items-center gap-1 text-xs", children: [ |
| 693 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 694 |
"input", |
| 695 |
{ |
| 696 |
type: "checkbox", |
| 697 |
checked: row.accepted, |
| 698 |
onChange: onToggleAccept |
| 699 |
} |
| 700 |
), |
| 701 |
__$1("Apply", "yatra") |
| 702 |
] }) |
| 703 |
] }) }) |
| 704 |
] }), |
| 705 |
expanded && row.status === "done" && /* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "mt-2 max-h-64 overflow-y-auto whitespace-pre-wrap rounded bg-gray-50 p-2 text-xs text-gray-800 dark:bg-gray-900 dark:text-gray-200", children: row.preview || /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-gray-400", children: __$1("(empty)", "yatra") }) }), |
| 706 |
row.status === "needs_context" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2 space-y-2 rounded-md border border-amber-200 bg-amber-50/60 p-3 text-xs dark:border-amber-500/40 dark:bg-amber-900/20", children: [ |
| 707 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-2 text-amber-900 dark:text-amber-200", children: [ |
| 708 |
/* @__PURE__ */ jsxRuntimeExports.jsx(HelpCircle, { className: "mt-0.5 h-3.5 w-3.5 shrink-0" }), |
| 709 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [ |
| 710 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium", children: __$1( |
| 711 |
"AI needs a few more details to write something useful.", |
| 712 |
"yatra" |
| 713 |
) }), |
| 714 |
row.clarificationMessage && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-amber-800/90 dark:text-amber-200/90", children: row.clarificationMessage }), |
| 715 |
row.clarificationQuestions && row.clarificationQuestions.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { className: "mt-1.5 list-disc space-y-0.5 pl-4 text-amber-900 dark:text-amber-200", children: row.clarificationQuestions.map((q, i) => /* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: q }, i)) }) |
| 716 |
] }) |
| 717 |
] }), |
| 718 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 719 |
"textarea", |
| 720 |
{ |
| 721 |
rows: 3, |
| 722 |
placeholder: __$1( |
| 723 |
"Type the answers here — e.g. duration, activities, difficulty, best season…", |
| 724 |
"yatra" |
| 725 |
), |
| 726 |
value: row.retryContext ?? "", |
| 727 |
onChange: (e) => onRetryContextChange(e.target.value), |
| 728 |
className: "w-full rounded-md border border-amber-200 bg-white p-2 text-sm focus:outline-none focus:ring-2 focus:ring-amber-400 dark:border-amber-500/40 dark:bg-gray-800" |
| 729 |
} |
| 730 |
), |
| 731 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 732 |
Button, |
| 733 |
{ |
| 734 |
type: "button", |
| 735 |
size: "sm", |
| 736 |
onClick: onRetry, |
| 737 |
disabled: retryDisabled, |
| 738 |
children: [ |
| 739 |
/* @__PURE__ */ jsxRuntimeExports.jsx(RefreshCw, { className: "mr-2 h-3.5 w-3.5" }), |
| 740 |
__$1("Try again with this", "yatra") |
| 741 |
] |
| 742 |
} |
| 743 |
) }) |
| 744 |
] }), |
| 745 |
row.status === "failed" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2 flex items-start gap-2 rounded bg-red-50 p-2 text-xs text-red-700 dark:bg-red-900/30 dark:text-red-300", children: [ |
| 746 |
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "mt-0.5 h-3.5 w-3.5 shrink-0" }), |
| 747 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1", children: row.error }) |
| 748 |
] }) |
| 749 |
] }); |
| 750 |
}; |
| 751 |
const StatusBadge = ({ status }) => { |
| 752 |
if (status === "idle") { |
| 753 |
return /* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "h-4 w-4 text-gray-400" }); |
| 754 |
} |
| 755 |
if (status === "running") { |
| 756 |
return /* @__PURE__ */ jsxRuntimeExports.jsx(Loader2, { className: "h-4 w-4 animate-spin text-blue-500" }); |
| 757 |
} |
| 758 |
if (status === "done") { |
| 759 |
return /* @__PURE__ */ jsxRuntimeExports.jsx(CheckCircle2, { className: "h-4 w-4 text-green-500" }); |
| 760 |
} |
| 761 |
return /* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "h-4 w-4 text-red-500" }); |
| 762 |
}; |
| 763 |
function extractError(e) { |
| 764 |
var _a; |
| 765 |
if (!e) return "Generation failed."; |
| 766 |
const data = ((_a = e == null ? void 0 : e.response) == null ? void 0 : _a.data) ?? (e == null ? void 0 : e.data) ?? null; |
| 767 |
if (data && typeof data === "object" && typeof data.message === "string") { |
| 768 |
return data.message; |
| 769 |
} |
| 770 |
return (e == null ? void 0 : e.message) || "Generation failed."; |
| 771 |
} |
| 772 |
const MEAL_PLAN_SELECT_OPTIONS = [ |
| 773 |
{ value: "", label: __$1("Select meal plan", "yatra") }, |
| 774 |
{ value: "breakfast", label: __$1("Breakfast Only", "yatra") }, |
| 775 |
{ |
| 776 |
value: "half_board", |
| 777 |
label: __$1("Half Board (Breakfast + Dinner)", "yatra") |
| 778 |
}, |
| 779 |
{ value: "full_board", label: __$1("Full Board (All Meals)", "yatra") }, |
| 780 |
{ value: "all_inclusive", label: __$1("All Inclusive", "yatra") }, |
| 781 |
{ value: "none", label: __$1("No Meals Included", "yatra") } |
| 782 |
]; |
| 783 |
function parseAttributeFieldOptions(field_options) { |
| 784 |
if (Array.isArray(field_options)) { |
| 785 |
return field_options.filter((o) => o && typeof o === "object").map((o) => ({ |
| 786 |
label: String((o == null ? void 0 : o.label) ?? ""), |
| 787 |
value: String((o == null ? void 0 : o.value) ?? "") |
| 788 |
})).filter((o) => o.label !== "" || o.value !== ""); |
| 789 |
} |
| 790 |
if (typeof field_options === "string" && field_options.trim()) { |
| 791 |
try { |
| 792 |
const p = JSON.parse(field_options); |
| 793 |
if (Array.isArray(p)) { |
| 794 |
return p.filter((o) => o && typeof o === "object").map((o) => ({ |
| 795 |
label: String((o == null ? void 0 : o.label) ?? ""), |
| 796 |
value: String((o == null ? void 0 : o.value) ?? "") |
| 797 |
})).filter((o) => o.label !== "" || o.value !== ""); |
| 798 |
} |
| 799 |
} catch { |
| 800 |
return []; |
| 801 |
} |
| 802 |
} |
| 803 |
return []; |
| 804 |
} |
| 805 |
function normalizeAttributeStoredValue(fieldType, raw) { |
| 806 |
if (fieldType === "checkbox") { |
| 807 |
if (Array.isArray(raw)) { |
| 808 |
return raw.map((v) => String(v)); |
| 809 |
} |
| 810 |
if (typeof raw === "string") { |
| 811 |
const t = raw.trim(); |
| 812 |
if (t.startsWith("[")) { |
| 813 |
try { |
| 814 |
const p = JSON.parse(t); |
| 815 |
if (Array.isArray(p)) { |
| 816 |
return p.map((v) => String(v)); |
| 817 |
} |
| 818 |
} catch { |
| 819 |
} |
| 820 |
} |
| 821 |
return t ? [t] : []; |
| 822 |
} |
| 823 |
if (typeof raw === "boolean") { |
| 824 |
return raw ? ["1"] : []; |
| 825 |
} |
| 826 |
return []; |
| 827 |
} |
| 828 |
if (raw === null || raw === void 0) { |
| 829 |
return ""; |
| 830 |
} |
| 831 |
return typeof raw === "string" ? raw : String(raw); |
| 832 |
} |
| 833 |
const TripAttributesSection = ({ |
| 834 |
formData, |
| 835 |
handleFieldChange, |
| 836 |
tripId, |
| 837 |
isEditMode = false, |
| 838 |
tripAttributesData = {}, |
| 839 |
// Add this prop |
| 840 |
tripAttributesReady = true |
| 841 |
}) => { |
| 842 |
const [selectedAttributes, setSelectedAttributes] = reactExports.useState([]); |
| 843 |
const [attributeValues, setAttributeValues] = reactExports.useState( |
| 844 |
{} |
| 845 |
); |
| 846 |
const [showAttributeDropdown, setShowAttributeDropdown] = reactExports.useState(false); |
| 847 |
const isInitializing = reactExports.useRef(true); |
| 848 |
const { data: attributesData, isLoading: isLoadingAttributes } = useQuery({ |
| 849 |
queryKey: ["attributes"], |
| 850 |
queryFn: async () => { |
| 851 |
const response = await apiClient.get("/attributes?status=publish"); |
| 852 |
const rawData = (response == null ? void 0 : response.data) ?? []; |
| 853 |
const list = Array.isArray(rawData) ? rawData : Array.isArray(rawData == null ? void 0 : rawData.data) ? rawData.data : []; |
| 854 |
return list.map((item) => ({ |
| 855 |
...item, |
| 856 |
id: Number(item == null ? void 0 : item.id) || 0 |
| 857 |
})); |
| 858 |
} |
| 859 |
}); |
| 860 |
reactExports.useEffect(() => { |
| 861 |
if (!isInitializing.current) return; |
| 862 |
if (isEditMode && tripId && !tripAttributesReady) { |
| 863 |
return; |
| 864 |
} |
| 865 |
if (isEditMode && tripAttributesData && Object.keys(tripAttributesData).length > 0) { |
| 866 |
const attributeIds = Object.keys(tripAttributesData).map( |
| 867 |
(id) => Number(id) |
| 868 |
); |
| 869 |
setSelectedAttributes(attributeIds); |
| 870 |
setAttributeValues(tripAttributesData); |
| 871 |
isInitializing.current = false; |
| 872 |
} else if (formData.attributes && Object.keys(formData.attributes).length > 0 && isInitializing.current) { |
| 873 |
const attributeIds = Object.keys(formData.attributes).map( |
| 874 |
(id) => Number(id) |
| 875 |
); |
| 876 |
setSelectedAttributes(attributeIds); |
| 877 |
setAttributeValues(formData.attributes); |
| 878 |
isInitializing.current = false; |
| 879 |
} else { |
| 880 |
isInitializing.current = false; |
| 881 |
} |
| 882 |
}, [ |
| 883 |
tripAttributesData, |
| 884 |
formData.attributes, |
| 885 |
isEditMode, |
| 886 |
tripId, |
| 887 |
tripAttributesReady |
| 888 |
]); |
| 889 |
const handleAddAttribute = (attributeId) => { |
| 890 |
if (!selectedAttributes.includes(attributeId)) { |
| 891 |
const newSelectedAttributes = [...selectedAttributes, attributeId]; |
| 892 |
setSelectedAttributes(newSelectedAttributes); |
| 893 |
if (!attributeValues[attributeId]) { |
| 894 |
const newAttributeValues = { ...attributeValues, [attributeId]: "" }; |
| 895 |
setAttributeValues(newAttributeValues); |
| 896 |
handleFieldChange("attributes", newAttributeValues); |
| 897 |
} |
| 898 |
setShowAttributeDropdown(false); |
| 899 |
} |
| 900 |
}; |
| 901 |
const handleRemoveAttribute = (attributeId) => { |
| 902 |
const newSelectedAttributes = selectedAttributes.filter( |
| 903 |
(id) => id !== attributeId |
| 904 |
); |
| 905 |
const newAttributeValues = { ...attributeValues }; |
| 906 |
delete newAttributeValues[attributeId]; |
| 907 |
setSelectedAttributes(newSelectedAttributes); |
| 908 |
setAttributeValues(newAttributeValues); |
| 909 |
handleFieldChange("attributes", newAttributeValues); |
| 910 |
}; |
| 911 |
const handleAttributeValueChange = (attributeId, value) => { |
| 912 |
const newAttributeValues = { ...attributeValues, [attributeId]: value }; |
| 913 |
setAttributeValues(newAttributeValues); |
| 914 |
handleFieldChange("attributes", newAttributeValues); |
| 915 |
}; |
| 916 |
const renderAttributeInput = (attribute) => { |
| 917 |
const raw = attributeValues[attribute.id]; |
| 918 |
const value = normalizeAttributeStoredValue(attribute.field_type, raw); |
| 919 |
switch (attribute.field_type) { |
| 920 |
case "text_field": |
| 921 |
case "email": |
| 922 |
case "url": |
| 923 |
return /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 924 |
Input, |
| 925 |
{ |
| 926 |
type: attribute.field_type === "email" ? "email" : attribute.field_type === "url" ? "url" : "text", |
| 927 |
value, |
| 928 |
onChange: (e) => handleAttributeValueChange(attribute.id, e.target.value), |
| 929 |
placeholder: attribute.placeholder || __$1("Enter value", "yatra"), |
| 930 |
className: "mt-2" |
| 931 |
} |
| 932 |
); |
| 933 |
case "number": |
| 934 |
return /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 935 |
Input, |
| 936 |
{ |
| 937 |
type: "number", |
| 938 |
value, |
| 939 |
onChange: (e) => handleAttributeValueChange(attribute.id, e.target.value), |
| 940 |
placeholder: attribute.placeholder || __$1("Enter number", "yatra"), |
| 941 |
className: "mt-2" |
| 942 |
} |
| 943 |
); |
| 944 |
case "textarea": |
| 945 |
return /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 946 |
"textarea", |
| 947 |
{ |
| 948 |
value, |
| 949 |
onChange: (e) => handleAttributeValueChange(attribute.id, e.target.value), |
| 950 |
placeholder: attribute.placeholder || __$1("Enter text", "yatra"), |
| 951 |
rows: 3, |
| 952 |
className: "flex w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-sm ring-offset-white placeholder:text-gray-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 dark:bg-gray-800 dark:ring-offset-gray-900 dark:placeholder:text-gray-400 dark:focus-visible:ring-blue-400 resize-none mt-2" |
| 953 |
} |
| 954 |
); |
| 955 |
case "select": { |
| 956 |
const options = parseAttributeFieldOptions(attribute.field_options); |
| 957 |
const strVal = typeof value === "string" ? value : ""; |
| 958 |
if (options.length === 0) { |
| 959 |
return /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 text-sm text-amber-600 dark:text-amber-500", children: __$1( |
| 960 |
"This attribute has no options configured. Edit the attribute to add choices.", |
| 961 |
"yatra" |
| 962 |
) }); |
| 963 |
} |
| 964 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 965 |
Select, |
| 966 |
{ |
| 967 |
value: strVal, |
| 968 |
onChange: (e) => handleAttributeValueChange(attribute.id, e.target.value), |
| 969 |
className: "mt-2", |
| 970 |
children: [ |
| 971 |
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "", children: __$1("Select an option", "yatra") }), |
| 972 |
options.map((option, index) => /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: option.value, children: option.label || option.value }, `${option.value}-${index}`)) |
| 973 |
] |
| 974 |
} |
| 975 |
); |
| 976 |
} |
| 977 |
case "radio": { |
| 978 |
const options = parseAttributeFieldOptions(attribute.field_options); |
| 979 |
const strVal = typeof value === "string" ? value : ""; |
| 980 |
if (options.length === 0) { |
| 981 |
return /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 text-sm text-amber-600 dark:text-amber-500", children: __$1( |
| 982 |
"This attribute has no options configured. Edit the attribute to add choices.", |
| 983 |
"yatra" |
| 984 |
) }); |
| 985 |
} |
| 986 |
return /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 987 |
"div", |
| 988 |
{ |
| 989 |
className: "mt-2 space-y-2", |
| 990 |
role: "radiogroup", |
| 991 |
"aria-label": attribute.name, |
| 992 |
children: options.map((option, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 993 |
"label", |
| 994 |
{ |
| 995 |
className: "flex items-center gap-2 cursor-pointer text-sm text-gray-700 dark:text-gray-300", |
| 996 |
children: [ |
| 997 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 998 |
"input", |
| 999 |
{ |
| 1000 |
type: "radio", |
| 1001 |
name: `yatra-attr-${attribute.id}`, |
| 1002 |
value: option.value, |
| 1003 |
checked: String(strVal) === String(option.value), |
| 1004 |
onChange: () => handleAttributeValueChange(attribute.id, option.value), |
| 1005 |
className: "border-gray-300 text-blue-600 focus:ring-blue-500" |
| 1006 |
} |
| 1007 |
), |
| 1008 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: option.label || option.value }) |
| 1009 |
] |
| 1010 |
}, |
| 1011 |
`${option.value}-${index}` |
| 1012 |
)) |
| 1013 |
} |
| 1014 |
); |
| 1015 |
} |
| 1016 |
case "checkbox": { |
| 1017 |
const options = parseAttributeFieldOptions(attribute.field_options); |
| 1018 |
const selected = Array.isArray(value) ? value.map(String) : []; |
| 1019 |
if (options.length === 0) { |
| 1020 |
return /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 text-sm text-amber-600 dark:text-amber-500", children: __$1( |
| 1021 |
"This attribute has no options configured. Edit the attribute to add choices.", |
| 1022 |
"yatra" |
| 1023 |
) }); |
| 1024 |
} |
| 1025 |
const toggle = (optValue, checked) => { |
| 1026 |
const next = checked ? [...selected.filter((v) => v !== optValue), optValue] : selected.filter((v) => v !== optValue); |
| 1027 |
handleAttributeValueChange(attribute.id, next); |
| 1028 |
}; |
| 1029 |
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2 space-y-2", children: options.map((option, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 1030 |
"label", |
| 1031 |
{ |
| 1032 |
className: "flex items-center gap-2 cursor-pointer text-sm text-gray-700 dark:text-gray-300", |
| 1033 |
children: [ |
| 1034 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 1035 |
"input", |
| 1036 |
{ |
| 1037 |
type: "checkbox", |
| 1038 |
checked: selected.includes(String(option.value)), |
| 1039 |
onChange: (e) => toggle(String(option.value), e.target.checked), |
| 1040 |
className: "rounded border-gray-300 text-blue-600 focus:ring-blue-500" |
| 1041 |
} |
| 1042 |
), |
| 1043 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: option.label || option.value }) |
| 1044 |
] |
| 1045 |
}, |
| 1046 |
`${option.value}-${index}` |
| 1047 |
)) }); |
| 1048 |
} |
| 1049 |
case "file": |
| 1050 |
return /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 1051 |
Input, |
| 1052 |
{ |
| 1053 |
type: "text", |
| 1054 |
value: typeof value === "string" ? value : "", |
| 1055 |
onChange: (e) => handleAttributeValueChange(attribute.id, e.target.value), |
| 1056 |
placeholder: attribute.placeholder || __$1("File URL or attachment path", "yatra"), |
| 1057 |
className: "mt-2" |
| 1058 |
} |
| 1059 |
); |
| 1060 |
case "date": |
| 1061 |
return /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 1062 |
Input, |
| 1063 |
{ |
| 1064 |
type: "date", |
| 1065 |
value, |
| 1066 |
onChange: (e) => handleAttributeValueChange(attribute.id, e.target.value), |
| 1067 |
className: "mt-2" |
| 1068 |
} |
| 1069 |
); |
| 1070 |
case "time": |
| 1071 |
return /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 1072 |
TimePicker, |
| 1073 |
{ |
| 1074 |
value: Array.isArray(value) ? value[0] ?? "" : value, |
| 1075 |
onChange: (newValue) => handleAttributeValueChange(attribute.id, newValue), |
| 1076 |
placeholder: "Select time", |
| 1077 |
className: "mt-2 w-full" |
| 1078 |
} |
| 1079 |
); |
| 1080 |
case "color": |
| 1081 |
return /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 1082 |
Input, |
| 1083 |
{ |
| 1084 |
type: "color", |
| 1085 |
value, |
| 1086 |
onChange: (e) => handleAttributeValueChange(attribute.id, e.target.value), |
| 1087 |
className: "mt-2 h-10 w-20" |
| 1088 |
} |
| 1089 |
); |
| 1090 |
default: |
| 1091 |
return /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 1092 |
Input, |
| 1093 |
{ |
| 1094 |
type: "text", |
| 1095 |
value, |
| 1096 |
onChange: (e) => handleAttributeValueChange(attribute.id, e.target.value), |
| 1097 |
placeholder: attribute.placeholder || __$1("Enter value", "yatra"), |
| 1098 |
className: "mt-2" |
| 1099 |
} |
| 1100 |
); |
| 1101 |
} |
| 1102 |
}; |
| 1103 |
const availableAttributes = (attributesData == null ? void 0 : attributesData.filter( |
| 1104 |
(attr) => attr.status === "publish" && !selectedAttributes.includes(attr.id) |
| 1105 |
)) || []; |
| 1106 |
if (isEditMode && tripId && !tripAttributesReady) { |
| 1107 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", "aria-busy": "true", children: [ |
| 1108 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-1/3 animate-pulse" }), |
| 1109 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: [1, 2, 3].map((i) => /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 1110 |
"div", |
| 1111 |
{ |
| 1112 |
className: "h-16 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" |
| 1113 |
}, |
| 1114 |
i |
| 1115 |
)) }) |
| 1116 |
] }); |
| 1117 |
} |
| 1118 |
if (isLoadingAttributes) { |
| 1119 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ |
| 1120 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 bg-gray-200 dark:bg-gray-700 rounded w-1/3 animate-pulse" }), |
| 1121 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: [1, 2, 3].map((i) => /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 1122 |
"div", |
| 1123 |
{ |
| 1124 |
className: "h-16 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" |
| 1125 |
}, |
| 1126 |
i |
| 1127 |
)) }) |
| 1128 |
] }); |
| 1129 |
} |
| 1130 |
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-4", children: !attributesData || attributesData.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx(Card, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "p-6 text-center", children: [ |
| 1131 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Tag, { className: "w-12 h-12 text-gray-400 mx-auto" }) }), |
| 1132 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-semibold text-gray-900 dark:text-white mb-2", children: __$1("No Attributes Found", "yatra") }), |
| 1133 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-600 dark:text-gray-400 mb-4", children: __$1( |
| 1134 |
"Attributes allow you to add custom fields to your trips that are not included in the main plugin features. You can create any type of custom attribute you need.", |
| 1135 |
"yatra" |
| 1136 |
) }), |
| 1137 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 1138 |
"a", |
| 1139 |
{ |
| 1140 |
href: "/wp-admin/admin.php?page=yatra&subpage=trips&tab=attributes&action=create", |
| 1141 |
target: "_blank", |
| 1142 |
rel: "noopener noreferrer", |
| 1143 |
className: "inline-flex items-center gap-2 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white text-sm font-medium rounded-lg transition-colors", |
| 1144 |
children: [ |
| 1145 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4" }), |
| 1146 |
__$1("Create Your First Attribute", "yatra") |
| 1147 |
] |
| 1148 |
} |
| 1149 |
) |
| 1150 |
] }) }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ |
| 1151 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Card, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "p-4", children: [ |
| 1152 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 1153 |
Button, |
| 1154 |
{ |
| 1155 |
type: "button", |
| 1156 |
onClick: () => setShowAttributeDropdown(!showAttributeDropdown), |
| 1157 |
className: "w-full justify-between h-auto py-3 px-4 border-2 border-dashed border-gray-300 dark:border-gray-600 hover:border-blue-500 dark:hover:border-blue-400 transition-colors", |
| 1158 |
variant: "outline", |
| 1159 |
children: [ |
| 1160 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ |
| 1161 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4" }), |
| 1162 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: __$1("Add Attribute", "yatra") }) |
| 1163 |
] }), |
| 1164 |
showAttributeDropdown ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronUp, { className: "w-4 h-4" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "w-4 h-4" }) |
| 1165 |
] |
| 1166 |
} |
| 1167 |
), |
| 1168 |
showAttributeDropdown && availableAttributes.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-3 border border-gray-200 dark:border-gray-700 rounded-lg bg-white dark:bg-gray-800 shadow-lg", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "max-h-60 overflow-y-auto", children: availableAttributes.map((attribute) => /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 1169 |
"button", |
| 1170 |
{ |
| 1171 |
type: "button", |
| 1172 |
onClick: () => handleAddAttribute(attribute.id), |
| 1173 |
className: "w-full text-left px-4 py-3 hover:bg-gray-50 dark:hover:bg-gray-700 border-b border-gray-100 dark:border-gray-700 last:border-b-0 transition-colors", |
| 1174 |
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [ |
| 1175 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 1176 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "font-medium text-gray-900 dark:text-white", children: attribute.name }), |
| 1177 |
attribute.description && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-sm text-gray-500 dark:text-gray-400 mt-1", children: attribute.description }) |
| 1178 |
] }), |
| 1179 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ |
| 1180 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "outline", className: "text-xs", children: attribute.field_type.replace("_", " ") }), |
| 1181 |
attribute.required && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "error", className: "text-xs", children: __$1("Required", "yatra") }) |
| 1182 |
] }) |
| 1183 |
] }) |
| 1184 |
}, |
| 1185 |
attribute.id |
| 1186 |
)) }) }), |
| 1187 |
showAttributeDropdown && availableAttributes.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-3 p-4 text-center bg-gray-50 dark:bg-gray-800 rounded-lg", children: [ |
| 1188 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400 mb-3", children: __$1("No attributes available to add", "yatra") }), |
| 1189 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 1190 |
"a", |
| 1191 |
{ |
| 1192 |
href: "/wp-admin/admin.php?page=yatra&subpage=trips&tab=attributes&action=create", |
| 1193 |
target: "_blank", |
| 1194 |
rel: "noopener noreferrer", |
| 1195 |
className: "inline-flex items-center gap-2 px-4 py-2 bg-blue-600 hover:bg-blue-700 text-white text-sm font-medium rounded-lg transition-colors", |
| 1196 |
children: [ |
| 1197 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4" }), |
| 1198 |
__$1("Create New Attribute", "yatra") |
| 1199 |
] |
| 1200 |
} |
| 1201 |
) |
| 1202 |
] }) |
| 1203 |
] }) }), |
| 1204 |
selectedAttributes.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-4", children: selectedAttributes.map((attributeId) => { |
| 1205 |
const attribute = attributesData == null ? void 0 : attributesData.find( |
| 1206 |
(attr) => attr.id === attributeId |
| 1207 |
); |
| 1208 |
if (!attribute) { |
| 1209 |
return /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 1210 |
Card, |
| 1211 |
{ |
| 1212 |
className: "border-orange-200 bg-orange-50 dark:bg-orange-900/20", |
| 1213 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { className: "p-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [ |
| 1214 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 1215 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("h4", { className: "font-medium text-orange-900 dark:text-orange-100", children: [ |
| 1216 |
"Attribute ID ", |
| 1217 |
attributeId, |
| 1218 |
" (Not Found)" |
| 1219 |
] }), |
| 1220 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-orange-700 dark:text-orange-300", children: [ |
| 1221 |
"Value:", |
| 1222 |
" ", |
| 1223 |
JSON.stringify(attributeValues[attributeId]) |
| 1224 |
] }) |
| 1225 |
] }), |
| 1226 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 1227 |
Button, |
| 1228 |
{ |
| 1229 |
type: "button", |
| 1230 |
variant: "ghost", |
| 1231 |
size: "sm", |
| 1232 |
onClick: () => handleRemoveAttribute(attributeId), |
| 1233 |
className: "text-red-500 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-900/20", |
| 1234 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-4 h-4" }) |
| 1235 |
} |
| 1236 |
) |
| 1237 |
] }) }) |
| 1238 |
}, |
| 1239 |
attributeId |
| 1240 |
); |
| 1241 |
} |
| 1242 |
return /* @__PURE__ */ jsxRuntimeExports.jsx(Card, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "p-4", children: [ |
| 1243 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-3", children: [ |
| 1244 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ |
| 1245 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Tag, { className: "w-4 h-4 text-blue-500" }), |
| 1246 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "font-medium text-gray-900 dark:text-white", children: attribute.name }) |
| 1247 |
] }), |
| 1248 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 1249 |
Button, |
| 1250 |
{ |
| 1251 |
type: "button", |
| 1252 |
variant: "ghost", |
| 1253 |
size: "sm", |
| 1254 |
onClick: () => handleRemoveAttribute(attribute.id), |
| 1255 |
className: "text-red-500 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-900/20", |
| 1256 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-4 h-4" }) |
| 1257 |
} |
| 1258 |
) |
| 1259 |
] }), |
| 1260 |
attribute.description && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-3", children: attribute.description }), |
| 1261 |
renderAttributeInput(attribute) |
| 1262 |
] }) }, attribute.id); |
| 1263 |
}) }) |
| 1264 |
] }) }); |
| 1265 |
}; |
| 1266 |
const SectionHeader = ({ |
| 1267 |
icon: Icon, |
| 1268 |
title, |
| 1269 |
description |
| 1270 |
}) => { |
| 1271 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-4", children: [ |
| 1272 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-2", children: [ |
| 1273 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Icon, { className: "w-5 h-5 text-gray-500" }), |
| 1274 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: __$1(title, title) }) |
| 1275 |
] }), |
| 1276 |
description && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400", children: __$1(description, description) }) |
| 1277 |
] }); |
| 1278 |
}; |
| 1279 |
const ItinerarySection = ({ |
| 1280 |
formData, |
| 1281 |
isEditMode, |
| 1282 |
tripId |
| 1283 |
}) => { |
| 1284 |
const itineraryLink = reactExports.useMemo(() => { |
| 1285 |
var _a; |
| 1286 |
if (!isEditMode || !tripId) return null; |
| 1287 |
return `${((_a = window.yatraAdmin) == null ? void 0 : _a.siteUrl) || ""}/wp-admin/admin.php?page=yatra&subpage=itinerary&tab=itinerary&trip_id=${tripId}`; |
| 1288 |
}, [isEditMode, tripId]); |
| 1289 |
return /* @__PURE__ */ jsxRuntimeExports.jsx(jsxRuntimeExports.Fragment, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [ |
| 1290 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 1291 |
SectionHeader, |
| 1292 |
{ |
| 1293 |
icon: Calendar, |
| 1294 |
title: "Itinerary Builder", |
| 1295 |
description: "Create detailed day-by-day itineraries with our professional itinerary builder" |
| 1296 |
} |
| 1297 |
), |
| 1298 |
itineraryLink ? /* @__PURE__ */ jsxRuntimeExports.jsx(Card, { className: "border-2 border-dashed border-blue-300 dark:border-blue-700 bg-gradient-to-br from-blue-50 to-indigo-50 dark:from-blue-950/30 dark:to-indigo-950/30", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { className: "p-8", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center space-y-4", children: [ |
| 1299 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "inline-flex items-center justify-center w-16 h-16 rounded-full bg-blue-100 dark:bg-blue-900/50 mb-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Calendar, { className: "h-8 w-8 text-blue-600 dark:text-blue-400" }) }), |
| 1300 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 1301 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-xl font-semibold text-gray-900 dark:text-white mb-2", children: __$1("Professional Itinerary Builder", "yatra") }), |
| 1302 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-600 dark:text-gray-400 max-w-2xl mx-auto", children: __$1( |
| 1303 |
"Create detailed day-by-day itineraries with activities, meals, accommodation, transportation, and more. Build professional trip schedules that help travelers understand the complete experience.", |
| 1304 |
"yatra" |
| 1305 |
) }) |
| 1306 |
] }), |
| 1307 |
formData.itinerary_days && formData.itinerary_days.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-4 max-w-md mx-auto", children: [ |
| 1308 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white dark:bg-gray-800 rounded-lg p-3 shadow-sm", children: [ |
| 1309 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-2xl font-bold text-blue-600 dark:text-blue-400", children: formData.itinerary_days.length }), |
| 1310 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-gray-600 dark:text-gray-400", children: formData.itinerary_days.length === 1 ? __$1("Day", "yatra") : __$1("Days", "yatra") }) |
| 1311 |
] }), |
| 1312 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white dark:bg-gray-800 rounded-lg p-3 shadow-sm", children: [ |
| 1313 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-2xl font-bold text-green-600 dark:text-green-400", children: formData.itinerary_days.reduce( |
| 1314 |
(sum, day) => { |
| 1315 |
var _a; |
| 1316 |
return sum + (((_a = day.entries) == null ? void 0 : _a.length) || 0); |
| 1317 |
}, |
| 1318 |
0 |
| 1319 |
) }), |
| 1320 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-gray-600 dark:text-gray-400", children: __$1("Activities", "yatra") }) |
| 1321 |
] }) |
| 1322 |
] }), |
| 1323 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 1324 |
Button, |
| 1325 |
{ |
| 1326 |
type: "button", |
| 1327 |
onClick: () => window.open( |
| 1328 |
itineraryLink, |
| 1329 |
"_blank", |
| 1330 |
"noopener,noreferrer" |
| 1331 |
), |
| 1332 |
className: "bg-blue-600 hover:bg-blue-700 text-white font-semibold px-8 py-6 text-base shadow-lg hover:shadow-xl transition-all", |
| 1333 |
size: "lg", |
| 1334 |
children: [ |
| 1335 |
/* @__PURE__ */ jsxRuntimeExports.jsx(ExternalLink, { className: "h-5 w-5 mr-2" }), |
| 1336 |
__$1("Launch Itinerary Builder", "yatra") |
| 1337 |
] |
| 1338 |
} |
| 1339 |
) }) |
| 1340 |
] }) }) }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Card, { className: "border-2 border-dashed border-amber-300 dark:border-amber-700 bg-amber-50 dark:bg-amber-950/30", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "p-6 text-center", children: [ |
| 1341 |
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "h-12 w-12 text-amber-600 dark:text-amber-400 mx-auto mb-3" }), |
| 1342 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-semibold text-gray-900 dark:text-white mb-2", children: __$1("Save Trip First", "yatra") }), |
| 1343 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-600 dark:text-gray-400", children: __$1( |
| 1344 |
"Please save this trip first to access the itinerary builder. The builder will automatically load this trip for you.", |
| 1345 |
"yatra" |
| 1346 |
) }) |
| 1347 |
] }) }) |
| 1348 |
] }) }); |
| 1349 |
}; |
| 1350 |
const Textarea = ({ value, onChange, placeholder, rows = 3, className = "" }) => /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 1351 |
"textarea", |
| 1352 |
{ |
| 1353 |
value, |
| 1354 |
onChange, |
| 1355 |
placeholder, |
| 1356 |
rows, |
| 1357 |
className: `w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-md shadow-sm focus:outline-none focus:ring-2 focus:ring-blue-500 focus:border-blue-500 dark:bg-gray-700 dark:text-white ${className}` |
| 1358 |
} |
| 1359 |
); |
| 1360 |
const IncludedSection = ({ |
| 1361 |
formData, |
| 1362 |
handleFieldChange |
| 1363 |
}) => { |
| 1364 |
const [newIncludedItem, setNewIncludedItem] = React.useState( |
| 1365 |
{ |
| 1366 |
title: "", |
| 1367 |
description: "" |
| 1368 |
} |
| 1369 |
); |
| 1370 |
const [newExcludedItem, setNewExcludedItem] = React.useState( |
| 1371 |
{ |
| 1372 |
title: "", |
| 1373 |
description: "" |
| 1374 |
} |
| 1375 |
); |
| 1376 |
const included_items = formData.included_items || []; |
| 1377 |
const excluded_items = formData.excluded_items || []; |
| 1378 |
const addIncludedItem = () => { |
| 1379 |
if (newIncludedItem.title.trim()) { |
| 1380 |
const updatedItems = [...included_items, { ...newIncludedItem }]; |
| 1381 |
handleFieldChange("included_items", updatedItems); |
| 1382 |
setNewIncludedItem({ title: "", description: "" }); |
| 1383 |
} |
| 1384 |
}; |
| 1385 |
const addExcludedItem = () => { |
| 1386 |
if (newExcludedItem.title.trim()) { |
| 1387 |
const updatedItems = [...excluded_items, { ...newExcludedItem }]; |
| 1388 |
handleFieldChange("excluded_items", updatedItems); |
| 1389 |
setNewExcludedItem({ title: "", description: "" }); |
| 1390 |
} |
| 1391 |
}; |
| 1392 |
const removeIncludedItem = (index) => { |
| 1393 |
const updatedItems = included_items.filter( |
| 1394 |
(_, i) => i !== index |
| 1395 |
); |
| 1396 |
handleFieldChange("included_items", updatedItems); |
| 1397 |
}; |
| 1398 |
const removeExcludedItem = (index) => { |
| 1399 |
const updatedItems = excluded_items.filter( |
| 1400 |
(_, i) => i !== index |
| 1401 |
); |
| 1402 |
handleFieldChange("excluded_items", updatedItems); |
| 1403 |
}; |
| 1404 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [ |
| 1405 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 1406 |
SectionHeader, |
| 1407 |
{ |
| 1408 |
icon: CheckSquare, |
| 1409 |
title: "What's Included & Excluded", |
| 1410 |
description: "Specify what is included and excluded in your trip pricing" |
| 1411 |
} |
| 1412 |
), |
| 1413 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: [ |
| 1414 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Card, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "p-6", children: [ |
| 1415 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-4", children: [ |
| 1416 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-semibold text-green-700 dark:text-green-400", children: __$1("What's Included", "yatra") }), |
| 1417 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 1418 |
Badge, |
| 1419 |
{ |
| 1420 |
variant: "success", |
| 1421 |
className: "bg-green-100 text-green-800 dark:bg-green-900/20 dark:text-green-400", |
| 1422 |
children: [ |
| 1423 |
included_items.length, |
| 1424 |
" ", |
| 1425 |
__$1("items", "yatra") |
| 1426 |
] |
| 1427 |
} |
| 1428 |
) |
| 1429 |
] }), |
| 1430 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4 mb-6 p-4 bg-gradient-to-r from-green-50 to-emerald-50 dark:from-green-950/20 dark:to-emerald-950/20 rounded-xl border border-green-200 dark:border-green-800 shadow-sm", children: [ |
| 1431 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [ |
| 1432 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 1433 |
Input, |
| 1434 |
{ |
| 1435 |
placeholder: __$1( |
| 1436 |
"Item title (e.g., Airport Transfer)", |
| 1437 |
"yatra" |
| 1438 |
), |
| 1439 |
value: newIncludedItem.title, |
| 1440 |
onChange: (e) => setNewIncludedItem({ |
| 1441 |
...newIncludedItem, |
| 1442 |
title: e.target.value |
| 1443 |
}), |
| 1444 |
className: "border-green-300 dark:border-green-700 focus:ring-green-500 focus:border-green-500" |
| 1445 |
} |
| 1446 |
), |
| 1447 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 1448 |
Textarea, |
| 1449 |
{ |
| 1450 |
placeholder: __$1("Detailed description (optional)", "yatra"), |
| 1451 |
value: newIncludedItem.description, |
| 1452 |
onChange: (e) => setNewIncludedItem({ |
| 1453 |
...newIncludedItem, |
| 1454 |
description: e.target.value |
| 1455 |
}), |
| 1456 |
rows: 3, |
| 1457 |
className: "border-green-300 dark:border-green-700 focus:ring-green-500 focus:border-green-500 resize-none" |
| 1458 |
} |
| 1459 |
) |
| 1460 |
] }), |
| 1461 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 1462 |
Button, |
| 1463 |
{ |
| 1464 |
onClick: addIncludedItem, |
| 1465 |
disabled: !newIncludedItem.title.trim(), |
| 1466 |
size: "sm", |
| 1467 |
className: "w-full bg-green-600 hover:bg-green-700 text-white border-green-600 hover:border-green-700 transition-all duration-200 shadow-sm hover:shadow-md", |
| 1468 |
children: [ |
| 1469 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4 mr-2" }), |
| 1470 |
__$1("Add Included Item", "yatra") |
| 1471 |
] |
| 1472 |
} |
| 1473 |
) |
| 1474 |
] }), |
| 1475 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2", children: included_items.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center py-8 text-gray-500 dark:text-gray-400", children: [ |
| 1476 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CheckSquare, { className: "w-12 h-12 mx-auto mb-2 opacity-50" }), |
| 1477 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: __$1("No included items added yet", "yatra") }) |
| 1478 |
] }) : included_items.map((item, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 1479 |
"div", |
| 1480 |
{ |
| 1481 |
className: "group flex items-start justify-between p-4 bg-white dark:bg-gray-800 rounded-xl border border-green-200 dark:border-green-800 shadow-sm hover:shadow-md transition-all duration-200", |
| 1482 |
children: [ |
| 1483 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 pr-3", children: [ |
| 1484 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("h4", { className: "font-semibold text-gray-900 dark:text-white mb-2 flex items-center gap-2", children: [ |
| 1485 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-2 h-2 bg-green-500 rounded-full flex-shrink-0" }), |
| 1486 |
item.title |
| 1487 |
] }), |
| 1488 |
item.description && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400 leading-relaxed bg-gray-50 dark:bg-gray-700/50 p-3 rounded-lg", children: item.description }) |
| 1489 |
] }), |
| 1490 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 1491 |
Button, |
| 1492 |
{ |
| 1493 |
variant: "ghost", |
| 1494 |
size: "sm", |
| 1495 |
onClick: () => removeIncludedItem(index), |
| 1496 |
className: "text-red-500 hover:text-red-700 hover:bg-red-50 dark:text-red-400 dark:hover:text-red-300 dark:hover:bg-red-900/20 opacity-0 group-hover:opacity-100 transition-all duration-200 p-2", |
| 1497 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-4 h-4" }) |
| 1498 |
} |
| 1499 |
) |
| 1500 |
] |
| 1501 |
}, |
| 1502 |
index |
| 1503 |
)) }) |
| 1504 |
] }) }), |
| 1505 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Card, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "p-6", children: [ |
| 1506 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-4", children: [ |
| 1507 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-semibold text-red-700 dark:text-red-400", children: __$1("What's Excluded", "yatra") }), |
| 1508 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 1509 |
Badge, |
| 1510 |
{ |
| 1511 |
variant: "error", |
| 1512 |
className: "bg-red-100 text-red-800 dark:bg-red-900/20 dark:text-red-400", |
| 1513 |
children: [ |
| 1514 |
excluded_items.length, |
| 1515 |
" ", |
| 1516 |
__$1("items", "yatra") |
| 1517 |
] |
| 1518 |
} |
| 1519 |
) |
| 1520 |
] }), |
| 1521 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4 mb-6 p-4 bg-gradient-to-r from-red-50 to-rose-50 dark:from-red-950/20 dark:to-rose-950/20 rounded-xl border border-red-200 dark:border-red-800 shadow-sm", children: [ |
| 1522 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [ |
| 1523 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 1524 |
Input, |
| 1525 |
{ |
| 1526 |
placeholder: __$1( |
| 1527 |
"Item title (e.g., International Flights)", |
| 1528 |
"yatra" |
| 1529 |
), |
| 1530 |
value: newExcludedItem.title, |
| 1531 |
onChange: (e) => setNewExcludedItem({ |
| 1532 |
...newExcludedItem, |
| 1533 |
title: e.target.value |
| 1534 |
}), |
| 1535 |
className: "border-red-300 dark:border-red-700 focus:ring-red-500 focus:border-red-500" |
| 1536 |
} |
| 1537 |
), |
| 1538 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 1539 |
Textarea, |
| 1540 |
{ |
| 1541 |
placeholder: __$1("Detailed description (optional)", "yatra"), |
| 1542 |
value: newExcludedItem.description, |
| 1543 |
onChange: (e) => setNewExcludedItem({ |
| 1544 |
...newExcludedItem, |
| 1545 |
description: e.target.value |
| 1546 |
}), |
| 1547 |
rows: 3, |
| 1548 |
className: "border-red-300 dark:border-red-700 focus:ring-red-500 focus:border-red-500 resize-none" |
| 1549 |
} |
| 1550 |
) |
| 1551 |
] }), |
| 1552 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 1553 |
Button, |
| 1554 |
{ |
| 1555 |
onClick: addExcludedItem, |
| 1556 |
disabled: !newExcludedItem.title.trim(), |
| 1557 |
size: "sm", |
| 1558 |
className: "w-full bg-red-600 hover:bg-red-700 text-white border-red-600 hover:border-red-700 transition-all duration-200 shadow-sm hover:shadow-md", |
| 1559 |
children: [ |
| 1560 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4 mr-2" }), |
| 1561 |
__$1("Add Excluded Item", "yatra") |
| 1562 |
] |
| 1563 |
} |
| 1564 |
) |
| 1565 |
] }), |
| 1566 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2", children: excluded_items.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center py-8 text-gray-500 dark:text-gray-400", children: [ |
| 1567 |
/* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-12 h-12 mx-auto mb-2 opacity-50" }), |
| 1568 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: __$1("No excluded items added yet", "yatra") }) |
| 1569 |
] }) : excluded_items.map((item, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 1570 |
"div", |
| 1571 |
{ |
| 1572 |
className: "group flex items-start justify-between p-4 bg-white dark:bg-gray-800 rounded-xl border border-red-200 dark:border-red-800 shadow-sm hover:shadow-md transition-all duration-200", |
| 1573 |
children: [ |
| 1574 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 pr-3", children: [ |
| 1575 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("h4", { className: "font-semibold text-gray-900 dark:text-white mb-2 flex items-center gap-2", children: [ |
| 1576 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-2 h-2 bg-red-500 rounded-full flex-shrink-0" }), |
| 1577 |
item.title |
| 1578 |
] }), |
| 1579 |
item.description && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400 leading-relaxed bg-gray-50 dark:bg-gray-700/50 p-3 rounded-lg", children: item.description }) |
| 1580 |
] }), |
| 1581 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 1582 |
Button, |
| 1583 |
{ |
| 1584 |
variant: "ghost", |
| 1585 |
size: "sm", |
| 1586 |
onClick: () => removeExcludedItem(index), |
| 1587 |
className: "text-red-500 hover:text-red-700 hover:bg-red-50 dark:text-red-400 dark:hover:text-red-300 dark:hover:bg-red-900/20 opacity-0 group-hover:opacity-100 transition-all duration-200 p-2", |
| 1588 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-4 h-4" }) |
| 1589 |
} |
| 1590 |
) |
| 1591 |
] |
| 1592 |
}, |
| 1593 |
index |
| 1594 |
)) }) |
| 1595 |
] }) }) |
| 1596 |
] }), |
| 1597 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Card, { className: "border-blue-200 dark:border-blue-800 bg-blue-50 dark:bg-blue-950/20", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { className: "p-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start space-x-3", children: [ |
| 1598 |
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-5 h-5 text-blue-600 dark:text-blue-400 mt-0.5 flex-shrink-0" }), |
| 1599 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-sm text-blue-800 dark:text-blue-200", children: [ |
| 1600 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-medium mb-1", children: __$1("Tips for Included/Excluded Items:", "yatra") }), |
| 1601 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("ul", { className: "list-disc list-inside space-y-1 text-blue-700 dark:text-blue-300", children: [ |
| 1602 |
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: __$1( |
| 1603 |
"Be specific about what's included (meals, transport, guides, etc.)", |
| 1604 |
"yatra" |
| 1605 |
) }), |
| 1606 |
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: __$1( |
| 1607 |
"Clearly mention what's NOT included to avoid confusion", |
| 1608 |
"yatra" |
| 1609 |
) }), |
| 1610 |
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: __$1("Include items that affect pricing decisions", "yatra") }), |
| 1611 |
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: __$1("Keep descriptions concise but informative", "yatra") }) |
| 1612 |
] }) |
| 1613 |
] }) |
| 1614 |
] }) }) }) |
| 1615 |
] }); |
| 1616 |
}; |
| 1617 |
const __ = (text) => { |
| 1618 |
var _a, _b; |
| 1619 |
return ((_b = (_a = window == null ? void 0 : window.yatraAdmin) == null ? void 0 : _a.translations) == null ? void 0 : _b[text]) || text; |
| 1620 |
}; |
| 1621 |
const TestimonialsSelector = ({ |
| 1622 |
tripId, |
| 1623 |
selectedReviewIds, |
| 1624 |
onChange |
| 1625 |
}) => { |
| 1626 |
const [reviews, setReviews] = reactExports.useState([]); |
| 1627 |
const [loading, setLoading] = reactExports.useState(false); |
| 1628 |
const [error, setError] = reactExports.useState(null); |
| 1629 |
reactExports.useEffect(() => { |
| 1630 |
if (tripId) { |
| 1631 |
fetchReviews(); |
| 1632 |
} else { |
| 1633 |
setReviews([]); |
| 1634 |
} |
| 1635 |
}, [tripId]); |
| 1636 |
const fetchReviews = async () => { |
| 1637 |
if (!tripId) return; |
| 1638 |
setLoading(true); |
| 1639 |
setError(null); |
| 1640 |
try { |
| 1641 |
const data = await apiService.getReviews({ |
| 1642 |
trip_id: tripId, |
| 1643 |
status: "approved", |
| 1644 |
per_page: 100 |
| 1645 |
}); |
| 1646 |
setReviews(data.data || []); |
| 1647 |
} catch (err) { |
| 1648 |
console.error("Error fetching reviews:", err); |
| 1649 |
setError(__("Failed to load reviews. Please try again.")); |
| 1650 |
} finally { |
| 1651 |
setLoading(false); |
| 1652 |
} |
| 1653 |
}; |
| 1654 |
const toggleReview = (reviewId) => { |
| 1655 |
const newSelection = selectedReviewIds.includes(reviewId) ? selectedReviewIds.filter((id) => id !== reviewId) : [...selectedReviewIds, reviewId]; |
| 1656 |
onChange(newSelection); |
| 1657 |
}; |
| 1658 |
const formatDate = (dateString) => { |
| 1659 |
const date = new Date(dateString); |
| 1660 |
return date.toLocaleDateString(void 0, { |
| 1661 |
year: "numeric", |
| 1662 |
month: "short", |
| 1663 |
day: "numeric" |
| 1664 |
}); |
| 1665 |
}; |
| 1666 |
const renderStars = (rating) => { |
| 1667 |
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex gap-0.5", children: [1, 2, 3, 4, 5].map((star) => /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 1668 |
Star, |
| 1669 |
{ |
| 1670 |
className: `w-4 h-4 ${star <= rating ? "fill-yellow-400 text-yellow-400" : "text-gray-300 dark:text-gray-600"}` |
| 1671 |
}, |
| 1672 |
star |
| 1673 |
)) }); |
| 1674 |
}; |
| 1675 |
if (!tripId) { |
| 1676 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [ |
| 1677 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { children: [ |
| 1678 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __("Testimonials") }), |
| 1679 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: __("Select reviews to display as testimonials") }) |
| 1680 |
] }), |
| 1681 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-6 border-2 border-dashed border-gray-300 dark:border-gray-700 rounded-lg text-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400", children: __("Save the trip first to select testimonials from reviews") }) }) }) |
| 1682 |
] }); |
| 1683 |
} |
| 1684 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [ |
| 1685 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { children: [ |
| 1686 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __("Testimonials") }), |
| 1687 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: __( |
| 1688 |
"Select approved reviews to display as testimonials on the trip page" |
| 1689 |
) }) |
| 1690 |
] }), |
| 1691 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { children: loading ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-center py-8", children: [ |
| 1692 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Loader2, { className: "w-6 h-6 animate-spin text-blue-600" }), |
| 1693 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ml-2 text-sm text-gray-600 dark:text-gray-400", children: __("Loading reviews...") }) |
| 1694 |
] }) : error ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-4 bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg", children: [ |
| 1695 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-red-600 dark:text-red-400", children: error }), |
| 1696 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 1697 |
Button, |
| 1698 |
{ |
| 1699 |
type: "button", |
| 1700 |
variant: "outline", |
| 1701 |
size: "sm", |
| 1702 |
onClick: fetchReviews, |
| 1703 |
className: "mt-2", |
| 1704 |
children: __("Retry") |
| 1705 |
} |
| 1706 |
) |
| 1707 |
] }) : reviews.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-6 border-2 border-dashed border-gray-300 dark:border-gray-700 rounded-lg text-center", children: [ |
| 1708 |
/* @__PURE__ */ jsxRuntimeExports.jsx(User, { className: "w-8 h-8 text-gray-300 dark:text-gray-600 mx-auto mb-2" }), |
| 1709 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-2", children: __("No approved reviews yet") }), |
| 1710 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-500", children: __( |
| 1711 |
"Reviews will appear here once customers submit and they are approved" |
| 1712 |
) }) |
| 1713 |
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [ |
| 1714 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-3", children: [ |
| 1715 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400", children: selectedReviewIds.length > 0 ? __(`${selectedReviewIds.length} review(s) selected`) : __("Select reviews to feature as testimonials") }), |
| 1716 |
selectedReviewIds.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 1717 |
Button, |
| 1718 |
{ |
| 1719 |
type: "button", |
| 1720 |
variant: "ghost", |
| 1721 |
size: "sm", |
| 1722 |
onClick: () => onChange([]), |
| 1723 |
className: "text-xs", |
| 1724 |
children: __("Clear all") |
| 1725 |
} |
| 1726 |
) |
| 1727 |
] }), |
| 1728 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2 max-h-96 overflow-y-auto", children: reviews.map((review) => /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 1729 |
"div", |
| 1730 |
{ |
| 1731 |
className: `p-4 border rounded-lg cursor-pointer transition-all ${selectedReviewIds.includes(review.id) ? "border-blue-500 bg-blue-50 dark:bg-blue-900/20" : "border-gray-200 dark:border-gray-700 hover:border-gray-300 dark:hover:border-gray-600"}`, |
| 1732 |
onClick: () => toggleReview(review.id), |
| 1733 |
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-3", children: [ |
| 1734 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 1735 |
"input", |
| 1736 |
{ |
| 1737 |
type: "checkbox", |
| 1738 |
checked: selectedReviewIds.includes(review.id), |
| 1739 |
onChange: () => toggleReview(review.id), |
| 1740 |
className: "mt-1 w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500" |
| 1741 |
} |
| 1742 |
), |
| 1743 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-w-0", children: [ |
| 1744 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-2 mb-2", children: [ |
| 1745 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [ |
| 1746 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-1", children: [ |
| 1747 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium text-gray-900 dark:text-white", children: review.author_name }), |
| 1748 |
review.author_location && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1 text-xs text-gray-500 dark:text-gray-400", children: [ |
| 1749 |
/* @__PURE__ */ jsxRuntimeExports.jsx(MapPin, { className: "w-3 h-3" }), |
| 1750 |
review.author_location |
| 1751 |
] }) |
| 1752 |
] }), |
| 1753 |
renderStars(review.rating) |
| 1754 |
] }), |
| 1755 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex items-center gap-1 text-xs text-gray-500 dark:text-gray-400 whitespace-nowrap", children: [ |
| 1756 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Calendar, { className: "w-3 h-3" }), |
| 1757 |
formatDate(review.created_at) |
| 1758 |
] }) |
| 1759 |
] }), |
| 1760 |
review.title && /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "font-medium text-sm text-gray-900 dark:text-white mb-1", children: review.title }), |
| 1761 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400 line-clamp-2", children: review.content }), |
| 1762 |
selectedReviewIds.includes(review.id) && /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "info", className: "mt-2", children: __("Selected as testimonial") }) |
| 1763 |
] }) |
| 1764 |
] }) |
| 1765 |
}, |
| 1766 |
review.id |
| 1767 |
)) }) |
| 1768 |
] }) }) |
| 1769 |
] }); |
| 1770 |
}; |
| 1771 |
const sanitizeTextForSEO = (text, maxLength = 160) => { |
| 1772 |
if (!text) return ""; |
| 1773 |
const plainText = text.replace(/<[^>]*>/g, ""); |
| 1774 |
const decodedText = plainText.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, '"').replace(/'/g, "'").replace(/ /g, " "); |
| 1775 |
const cleanText = decodedText.replace(/\s+/g, " ").trim(); |
| 1776 |
if (cleanText.length > maxLength) { |
| 1777 |
return cleanText.substring(0, maxLength) + "..."; |
| 1778 |
} |
| 1779 |
return cleanText; |
| 1780 |
}; |
| 1781 |
const extractArrayPayload = (payload) => { |
| 1782 |
var _a; |
| 1783 |
if (!payload) return []; |
| 1784 |
if (Array.isArray(payload)) return payload; |
| 1785 |
if (Array.isArray(payload.data)) return payload.data; |
| 1786 |
if (Array.isArray((_a = payload == null ? void 0 : payload.data) == null ? void 0 : _a.data)) return payload.data.data; |
| 1787 |
return []; |
| 1788 |
}; |
| 1789 |
const normalizeAmenityItems = (items) => { |
| 1790 |
if (!items) return []; |
| 1791 |
if (Array.isArray(items)) { |
| 1792 |
return items.map((item) => { |
| 1793 |
if (typeof item === "string") { |
| 1794 |
return { title: item, description: "" }; |
| 1795 |
} |
| 1796 |
if (item && typeof item === "object") { |
| 1797 |
const obj = item; |
| 1798 |
return { |
| 1799 |
title: (obj.title ?? "").toString(), |
| 1800 |
description: (obj.description ?? "").toString() |
| 1801 |
}; |
| 1802 |
} |
| 1803 |
return { title: String(item), description: "" }; |
| 1804 |
}).filter((item) => item.title.trim().length > 0); |
| 1805 |
} |
| 1806 |
if (typeof items === "string") { |
| 1807 |
try { |
| 1808 |
const parsed = JSON.parse(items); |
| 1809 |
if (Array.isArray(parsed)) { |
| 1810 |
return normalizeAmenityItems(parsed); |
| 1811 |
} |
| 1812 |
} catch { |
| 1813 |
return [{ title: items, description: "" }]; |
| 1814 |
} |
| 1815 |
} |
| 1816 |
return []; |
| 1817 |
}; |
| 1818 |
function buildTripAiContext(formData) { |
| 1819 |
const amenityTitles = (items) => Array.isArray(items) ? items.map((it) => typeof it === "string" ? it : (it == null ? void 0 : it.title) || (it == null ? void 0 : it.label)).filter((s) => typeof s === "string" && s.trim() !== "") : []; |
| 1820 |
return { |
| 1821 |
name: (formData == null ? void 0 : formData.title) ?? "", |
| 1822 |
short_description: (formData == null ? void 0 : formData.short_description) ?? "", |
| 1823 |
description: stripHtml((formData == null ? void 0 : formData.description) ?? ""), |
| 1824 |
destinations: namesFromIds(formData == null ? void 0 : formData.destinations), |
| 1825 |
categories: namesFromIds(formData == null ? void 0 : formData.categories), |
| 1826 |
activities: namesFromIds(formData == null ? void 0 : formData.activities), |
| 1827 |
difficulty_level: (formData == null ? void 0 : formData.difficulty_level) ?? "", |
| 1828 |
duration_days: (formData == null ? void 0 : formData.duration_days) ?? "", |
| 1829 |
duration_nights: (formData == null ? void 0 : formData.duration_nights) ?? "", |
| 1830 |
duration_hours: (formData == null ? void 0 : formData.duration_hours) ?? "", |
| 1831 |
best_season: (formData == null ? void 0 : formData.best_season) ?? "", |
| 1832 |
price: (formData == null ? void 0 : formData.price) ?? "", |
| 1833 |
deposit_percentage: (formData == null ? void 0 : formData.deposit_percentage) ?? "", |
| 1834 |
booking_deadline_hours: (formData == null ? void 0 : formData.booking_deadline_hours) ?? "", |
| 1835 |
age_min: (formData == null ? void 0 : formData.age_min) ?? "", |
| 1836 |
age_max: (formData == null ? void 0 : formData.age_max) ?? "", |
| 1837 |
accommodation_type: (formData == null ? void 0 : formData.accommodation_type) ?? "", |
| 1838 |
transportation_included: (formData == null ? void 0 : formData.transportation_included) ?? "", |
| 1839 |
included_items: amenityTitles(formData == null ? void 0 : formData.included_items), |
| 1840 |
excluded_items: amenityTitles(formData == null ? void 0 : formData.excluded_items) |
| 1841 |
}; |
| 1842 |
} |
| 1843 |
function stripHtml(value) { |
| 1844 |
if (!value) return ""; |
| 1845 |
return value.replace(/<[^>]*>/g, " ").replace(/\s+/g, " ").trim(); |
| 1846 |
} |
| 1847 |
function namesFromIds(value) { |
| 1848 |
if (!Array.isArray(value)) return []; |
| 1849 |
return value.map((item) => { |
| 1850 |
if (typeof item === "string") return item; |
| 1851 |
if (item && typeof item === "object") { |
| 1852 |
return item.name || item.label || item.title || ""; |
| 1853 |
} |
| 1854 |
return ""; |
| 1855 |
}).filter((s) => typeof s === "string" && s.trim() !== ""); |
| 1856 |
} |
| 1857 |
const TripForm = () => { |
| 1858 |
var _a, _b, _c, _d, _e, _f; |
| 1859 |
const queryClient = useQueryClient(); |
| 1860 |
const { can, isPro } = usePermissions(); |
| 1861 |
const { showToast } = useToast(); |
| 1862 |
const [aiModalOpen, setAiModalOpen] = reactExports.useState(false); |
| 1863 |
const [aiModalMode, setAiModalMode] = reactExports.useState("all"); |
| 1864 |
const [itineraryBuildOpen, setItineraryBuildOpen] = reactExports.useState(false); |
| 1865 |
const [featuredImagePreview, setFeaturedImagePreview] = reactExports.useState(""); |
| 1866 |
const [isResolvingFeaturedImage, setIsResolvingFeaturedImage] = reactExports.useState(false); |
| 1867 |
const featuredImageCache = reactExports.useRef({}); |
| 1868 |
const mediaBaseUrl = reactExports.useMemo(() => { |
| 1869 |
var _a2; |
| 1870 |
const apiUrl = (_a2 = window == null ? void 0 : window.yatraAdmin) == null ? void 0 : _a2.apiUrl; |
| 1871 |
return apiUrl ? apiUrl.replace(/\/yatra\/v1\/?$/, "") : ""; |
| 1872 |
}, []); |
| 1873 |
const getInitialSection = () => { |
| 1874 |
const urlParams = new URLSearchParams(window.location.search); |
| 1875 |
const sectionFromUrl = urlParams.get("section"); |
| 1876 |
const validSections = [ |
| 1877 |
"basic", |
| 1878 |
"location", |
| 1879 |
"duration", |
| 1880 |
"pricing", |
| 1881 |
"booking", |
| 1882 |
"attributes", |
| 1883 |
"itinerary", |
| 1884 |
"included", |
| 1885 |
"media", |
| 1886 |
"downloads", |
| 1887 |
"categorization", |
| 1888 |
"faqs", |
| 1889 |
"seo", |
| 1890 |
"advanced" |
| 1891 |
]; |
| 1892 |
if (sectionFromUrl && validSections.includes(sectionFromUrl)) { |
| 1893 |
return sectionFromUrl; |
| 1894 |
} |
| 1895 |
return "basic"; |
| 1896 |
}; |
| 1897 |
const [currentSection, setCurrentSection] = reactExports.useState(getInitialSection); |
| 1898 |
const [visitedSections, setVisitedSections] = reactExports.useState( |
| 1899 |
() => /* @__PURE__ */ new Set([getInitialSection()]) |
| 1900 |
); |
| 1901 |
const [showCategorySelector, setShowCategorySelector] = reactExports.useState(false); |
| 1902 |
const [showLandmarkDialog, setShowLandmarkDialog] = reactExports.useState(false); |
| 1903 |
const [landmarkInput, setLandmarkInput] = reactExports.useState(""); |
| 1904 |
const [tripDetailsTab, setTripDetailsTab] = reactExports.useState("itinerary"); |
| 1905 |
reactExports.useEffect(() => { |
| 1906 |
setVisitedSections((prev) => /* @__PURE__ */ new Set([...prev, currentSection])); |
| 1907 |
const url = new URL(window.location.href); |
| 1908 |
url.searchParams.set("section", currentSection); |
| 1909 |
window.history.replaceState({}, "", url.toString()); |
| 1910 |
}, [currentSection]); |
| 1911 |
const [showHighlightModal, setShowHighlightModal] = reactExports.useState(false); |
| 1912 |
const [modalInput, setModalInput] = reactExports.useState({ |
| 1913 |
text: "", |
| 1914 |
question: "", |
| 1915 |
answer: "" |
| 1916 |
}); |
| 1917 |
const [showRevisionsDialog, setShowRevisionsDialog] = reactExports.useState(false); |
| 1918 |
const [selectedRevisionId, setSelectedRevisionId] = reactExports.useState( |
| 1919 |
null |
| 1920 |
); |
| 1921 |
const [showRevisionConfirm, setShowRevisionConfirm] = reactExports.useState(false); |
| 1922 |
const [simpleMode, setSimpleMode] = reactExports.useState(false); |
| 1923 |
const [showSlugPreview, setShowSlugPreview] = reactExports.useState(true); |
| 1924 |
const [dummyDataIndex, setDummyDataIndex] = reactExports.useState(0); |
| 1925 |
const dummyRevisions = [ |
| 1926 |
{ |
| 1927 |
id: 1, |
| 1928 |
version: 3, |
| 1929 |
created_by_name: "Admin User", |
| 1930 |
created_at: (/* @__PURE__ */ new Date()).toISOString() |
| 1931 |
}, |
| 1932 |
{ |
| 1933 |
id: 2, |
| 1934 |
version: 2, |
| 1935 |
created_by_name: "Admin User", |
| 1936 |
created_at: new Date(Date.now() - 864e5).toISOString() |
| 1937 |
}, |
| 1938 |
{ |
| 1939 |
id: 3, |
| 1940 |
version: 1, |
| 1941 |
created_by_name: "Admin User", |
| 1942 |
created_at: new Date(Date.now() - 1728e5).toISOString() |
| 1943 |
} |
| 1944 |
]; |
| 1945 |
const dummyTripsData = [ |
| 1946 |
{ |
| 1947 |
// Trip 1: Beach Adventure |
| 1948 |
title: "7-Day Bali Beach Adventure", |
| 1949 |
slug: "7-day-bali-beach-adventure", |
| 1950 |
description: "Escape to paradise with our 7-day Bali beach adventure. Experience pristine beaches, explore ancient temples, enjoy world-class spa treatments, and immerse yourself in the rich Balinese culture. This carefully curated journey combines relaxation with adventure, offering the perfect balance for travelers seeking both tranquility and excitement.", |
| 1951 |
short_description: "Escape to paradise with our 7-day Bali beach adventure featuring pristine beaches, ancient temples, and cultural immersion.", |
| 1952 |
highlights: [ |
| 1953 |
"Pristine white sand beaches", |
| 1954 |
"Ancient temple visits", |
| 1955 |
"Traditional spa treatments", |
| 1956 |
"Cultural dance performances", |
| 1957 |
"Sunset dinners by the ocean" |
| 1958 |
], |
| 1959 |
trip_details: "This comprehensive 7-day journey takes you through the best of Bali. Start your adventure in Seminyak with its trendy beach clubs and world-class restaurants. Visit the iconic Tanah Lot Temple perched on a rock formation in the sea. Explore the cultural heart of Ubud, known for its rice terraces, monkey forest, and art galleries. Enjoy traditional Balinese spa treatments and witness captivating cultural performances. End your trip with a relaxing stay at a beachfront resort where you can unwind and reflect on your incredible journey.", |
| 1960 |
what_makes_special: "This trip offers exclusive access to private beach areas, personalized cultural experiences, and a perfect blend of relaxation and adventure. Our local guides share insider knowledge and hidden gems that most tourists never discover.", |
| 1961 |
trip_story: "Imagine waking up to the gentle sound of waves lapping against the shore. As the sun rises over the horizon, you step onto your private balcony to witness a breathtaking sunrise. Your day begins with a traditional Balinese breakfast before heading out to explore ancient temples that have stood for centuries. In the afternoon, you find yourself surrounded by emerald-green rice terraces, learning about traditional farming methods from local farmers. As evening approaches, you're treated to a mesmerizing cultural dance performance followed by a candlelit dinner on the beach. This is more than a vacation—it's a journey into the heart and soul of Bali.", |
| 1962 |
video_url: "https://www.youtube.com/watch?v=example1", |
| 1963 |
virtual_tour_url: "", |
| 1964 |
testimonial_review_ids: [], |
| 1965 |
// Will be populated from actual reviews |
| 1966 |
destinations: [], |
| 1967 |
// Will be populated based on available destinations |
| 1968 |
starting_location: "Ngurah Rai International Airport (DPS)", |
| 1969 |
ending_location: "Seminyak Beach Resort", |
| 1970 |
countries: ["Indonesia"], |
| 1971 |
regions: ["Bali"], |
| 1972 |
starting_latitude: "-8.3405", |
| 1973 |
starting_longitude: "115.0920", |
| 1974 |
ending_latitude: "-8.5069", |
| 1975 |
ending_longitude: "115.2625", |
| 1976 |
landmarks: [ |
| 1977 |
"Tanah Lot Temple", |
| 1978 |
"Ubud Monkey Forest", |
| 1979 |
"Tegallalang Rice Terrace", |
| 1980 |
"Seminyak Beach" |
| 1981 |
], |
| 1982 |
trip_type: "multi_day", |
| 1983 |
duration_days: "7", |
| 1984 |
duration_nights: "6", |
| 1985 |
duration_hours: "", |
| 1986 |
available_from: new Date(Date.now() + 30 * 24 * 60 * 60 * 1e3).toISOString().split("T")[0], |
| 1987 |
// 30 days from now |
| 1988 |
available_to: new Date(Date.now() + 365 * 24 * 60 * 60 * 1e3).toISOString().split("T")[0], |
| 1989 |
// 1 year from now |
| 1990 |
booking_window_days: "30", |
| 1991 |
seasonal_availability: "Year-round", |
| 1992 |
best_season: "April to October", |
| 1993 |
peak_season: "July to August", |
| 1994 |
off_season: "November to March", |
| 1995 |
activity_types: [], |
| 1996 |
// Will be populated based on available activities |
| 1997 |
difficulty_level: "", |
| 1998 |
trip_category: [], |
| 1999 |
tags: ["family-friendly", "beach", "relaxation", "cultural", "spa"], |
| 2000 |
featured_priority: "featured", |
| 2001 |
accommodation_type: "Resort", |
| 2002 |
meal_plan: "breakfast", |
| 2003 |
accommodation_details: "4-star beachfront resort with private balconies, infinity pool, and spa facilities", |
| 2004 |
transportation_included: true, |
| 2005 |
pickup_location: "Ngurah Rai International Airport", |
| 2006 |
dropoff_location: "Seminyak Beach Resort", |
| 2007 |
transportation_details: "Private air-conditioned vehicle with professional driver", |
| 2008 |
pricing_type: "traveler_based", |
| 2009 |
original_price: "", |
| 2010 |
discounted_price: "", |
| 2011 |
price_types: [ |
| 2012 |
{ category_id: 1, original_price: "1250", discounted_price: "" }, |
| 2013 |
{ category_id: 2, original_price: "625", discounted_price: "" }, |
| 2014 |
{ category_id: 3, original_price: "0", discounted_price: "" } |
| 2015 |
], |
| 2016 |
deposit_amount: "300", |
| 2017 |
deposit_percentage: "", |
| 2018 |
payment_terms: "50% deposit required at booking, remaining 50% due 30 days before departure", |
| 2019 |
max_travelers: "12", |
| 2020 |
min_travelers: "2", |
| 2021 |
booking_deadline_hours: "24", |
| 2022 |
cancellation_policy: "Free cancellation up to 30 days before departure. 50% refund for cancellations 15-30 days before. No refund for cancellations less than 15 days before.", |
| 2023 |
age_min: "8", |
| 2024 |
age_max: "", |
| 2025 |
physical_requirements: "Moderate fitness level required. Some walking involved but no strenuous activities.", |
| 2026 |
visa_requirements: "Visa on arrival available for most nationalities. Valid passport required with at least 6 months validity.", |
| 2027 |
vaccination_requirements: "No mandatory vaccinations. Recommended: Hepatitis A, Typhoid, and routine vaccinations.", |
| 2028 |
disable_booking: false, |
| 2029 |
has_default_time_slots: false, |
| 2030 |
default_time_slots: [], |
| 2031 |
departure_time: "", |
| 2032 |
included_items: [ |
| 2033 |
{ |
| 2034 |
title: "Accommodation", |
| 2035 |
description: "6 nights at 4-star beachfront resort" |
| 2036 |
}, |
| 2037 |
{ title: "Breakfast", description: "Daily breakfast included" }, |
| 2038 |
{ |
| 2039 |
title: "Airport transfers", |
| 2040 |
description: "Private transfers to and from airport" |
| 2041 |
}, |
| 2042 |
{ |
| 2043 |
title: "Temple visits", |
| 2044 |
description: "Entrance fees to all temples included" |
| 2045 |
}, |
| 2046 |
{ |
| 2047 |
title: "Cultural performances", |
| 2048 |
description: "Traditional dance show tickets" |
| 2049 |
}, |
| 2050 |
{ |
| 2051 |
title: "Professional guide", |
| 2052 |
description: "English-speaking local guide" |
| 2053 |
} |
| 2054 |
], |
| 2055 |
excluded_items: [ |
| 2056 |
{ |
| 2057 |
title: "International flights", |
| 2058 |
description: "Flights to and from Bali not included" |
| 2059 |
}, |
| 2060 |
{ |
| 2061 |
title: "Lunch and dinner", |
| 2062 |
description: "Meals other than breakfast" |
| 2063 |
}, |
| 2064 |
{ |
| 2065 |
title: "Travel insurance", |
| 2066 |
description: "Travel insurance recommended but not included" |
| 2067 |
}, |
| 2068 |
{ |
| 2069 |
title: "Personal expenses", |
| 2070 |
description: "Souvenirs, tips, and personal items" |
| 2071 |
} |
| 2072 |
], |
| 2073 |
itinerary_days: [], |
| 2074 |
gallery_images: [], |
| 2075 |
featured_image: null, |
| 2076 |
downloadable_items: [], |
| 2077 |
faqs: [ |
| 2078 |
{ |
| 2079 |
question: "What is the best time to visit Bali?", |
| 2080 |
answer: "The best time to visit Bali is during the dry season from April to October, when you can expect sunny days and minimal rainfall." |
| 2081 |
}, |
| 2082 |
{ |
| 2083 |
question: "Do I need a visa?", |
| 2084 |
answer: "Most nationalities can get a visa on arrival at the airport. A valid passport with at least 6 months validity is required." |
| 2085 |
}, |
| 2086 |
{ |
| 2087 |
question: "What should I pack?", |
| 2088 |
answer: "Pack light, breathable clothing, swimwear, sunscreen, insect repellent, and comfortable walking shoes. Modest clothing is required for temple visits." |
| 2089 |
} |
| 2090 |
], |
| 2091 |
frontend_tabs: [ |
| 2092 |
{ |
| 2093 |
id: "overview", |
| 2094 |
label: "Overview", |
| 2095 |
enabled: true, |
| 2096 |
order: 1, |
| 2097 |
content_type: "general", |
| 2098 |
icon: { type: "icon", value: "book-open" } |
| 2099 |
}, |
| 2100 |
{ |
| 2101 |
id: "itinerary", |
| 2102 |
label: "Itinerary", |
| 2103 |
enabled: true, |
| 2104 |
order: 2, |
| 2105 |
content_type: "itinerary", |
| 2106 |
icon: { type: "icon", value: "calendar" } |
| 2107 |
}, |
| 2108 |
{ |
| 2109 |
id: "included", |
| 2110 |
label: "Included", |
| 2111 |
enabled: true, |
| 2112 |
order: 3, |
| 2113 |
content_type: "included_excluded", |
| 2114 |
icon: { type: "icon", value: "check" } |
| 2115 |
}, |
| 2116 |
{ |
| 2117 |
id: "location", |
| 2118 |
label: "Location", |
| 2119 |
enabled: true, |
| 2120 |
order: 4, |
| 2121 |
content_type: "gallery", |
| 2122 |
icon: { type: "icon", value: "map-pin" } |
| 2123 |
}, |
| 2124 |
{ |
| 2125 |
id: "important_info", |
| 2126 |
label: "Important Info", |
| 2127 |
enabled: true, |
| 2128 |
order: 5, |
| 2129 |
content_type: "general", |
| 2130 |
icon: { type: "icon", value: "file-text" } |
| 2131 |
}, |
| 2132 |
{ |
| 2133 |
id: "downloads", |
| 2134 |
label: "Downloads", |
| 2135 |
enabled: true, |
| 2136 |
order: 6, |
| 2137 |
content_type: "downloads", |
| 2138 |
icon: { type: "icon", value: "download" } |
| 2139 |
}, |
| 2140 |
{ |
| 2141 |
id: "faq", |
| 2142 |
label: "FAQ", |
| 2143 |
enabled: true, |
| 2144 |
order: 7, |
| 2145 |
content_type: "faqs", |
| 2146 |
icon: { type: "icon", value: "help-circle" } |
| 2147 |
}, |
| 2148 |
{ |
| 2149 |
id: "trip_story", |
| 2150 |
label: "Story", |
| 2151 |
enabled: true, |
| 2152 |
order: 8, |
| 2153 |
content_type: "custom", |
| 2154 |
custom_content: "", |
| 2155 |
icon: { type: "icon", value: "book" } |
| 2156 |
}, |
| 2157 |
{ |
| 2158 |
id: "what_makes_special", |
| 2159 |
label: "Special", |
| 2160 |
enabled: true, |
| 2161 |
order: 9, |
| 2162 |
content_type: "custom", |
| 2163 |
custom_content: "", |
| 2164 |
icon: { type: "icon", value: "star" } |
| 2165 |
}, |
| 2166 |
{ |
| 2167 |
id: "testimonials", |
| 2168 |
label: "Testimonials", |
| 2169 |
enabled: true, |
| 2170 |
order: 10, |
| 2171 |
content_type: "reviews", |
| 2172 |
icon: { type: "icon", value: "message-circle" } |
| 2173 |
} |
| 2174 |
], |
| 2175 |
availability_dates: [], |
| 2176 |
status: "draft", |
| 2177 |
scheduled_publish_date: "", |
| 2178 |
scheduled_unpublish_date: "", |
| 2179 |
version: 1, |
| 2180 |
seasonal_auto_enable: false, |
| 2181 |
seasonal_enable_date: "", |
| 2182 |
seasonal_disable_date: "", |
| 2183 |
meta_title: "7-Day Bali Beach Adventure | Luxury Beach Resort Experience", |
| 2184 |
meta_description: "Experience the best of Bali with our 7-day beach adventure. Pristine beaches, ancient temples, cultural immersion, and world-class spa treatments await.", |
| 2185 |
meta_keywords: "Bali, beach vacation, cultural tour, spa retreat, Indonesia travel", |
| 2186 |
attributes: {} |
| 2187 |
}, |
| 2188 |
{ |
| 2189 |
// Trip 2: Mountain Trekking Adventure |
| 2190 |
title: "Everest Base Camp Trek - 14 Days", |
| 2191 |
slug: "everest-base-camp-trek-14-days", |
| 2192 |
description: "Embark on the adventure of a lifetime with our 14-day Everest Base Camp trek. This challenging yet rewarding journey takes you through the heart of the Himalayas, passing through traditional Sherpa villages, ancient monasteries, and breathtaking mountain landscapes. Experience the rich culture of the Khumbu region while pushing your limits to reach the base of the world's highest mountain.", |
| 2193 |
short_description: "Embark on the adventure of a lifetime with our 14-day Everest Base Camp trek through the heart of the Himalayas.", |
| 2194 |
highlights: [ |
| 2195 |
"Trek to Everest Base Camp (5,364m)", |
| 2196 |
"Visit ancient Buddhist monasteries", |
| 2197 |
"Experience Sherpa culture", |
| 2198 |
"Breathtaking mountain views", |
| 2199 |
"Professional mountain guides" |
| 2200 |
], |
| 2201 |
trip_details: "This 14-day trekking adventure begins in Kathmandu, where you'll prepare for your journey and meet your experienced guides. Fly to Lukla, the gateway to the Khumbu region, and begin your trek through the stunning Himalayan landscape. Pass through traditional Sherpa villages like Namche Bazaar, Tengboche, and Dingboche, each offering unique cultural experiences and acclimatization opportunities. Visit ancient monasteries, learn about Sherpa traditions, and witness the daily life of mountain communities. The journey culminates at Everest Base Camp, where you'll stand in the shadow of the world's highest peak. Along the way, you'll be treated to spectacular views of peaks like Ama Dablam, Lhotse, and of course, Mount Everest itself.", |
| 2202 |
what_makes_special: "Our trek includes experienced mountain guides, proper acclimatization schedules, high-altitude porters, and comprehensive safety equipment. We prioritize responsible tourism, supporting local communities and ensuring minimal environmental impact.", |
| 2203 |
trip_story: "The crisp mountain air fills your lungs as you take your first steps on the trail. With each passing day, the mountains grow larger, the air thinner, and the sense of accomplishment greater. You wake before dawn to witness the sun painting the peaks in shades of gold and pink. You share meals with Sherpa families, learning about their way of life and the challenges they face in this harsh yet beautiful environment. As you approach Base Camp, the anticipation builds. When you finally arrive, standing at 5,364 meters with Everest towering above, you realize this is more than a trek—it's a transformation. The journey changes you, teaching resilience, appreciation for nature, and respect for the mountains and the people who call them home.", |
| 2204 |
video_url: "https://www.youtube.com/watch?v=example2", |
| 2205 |
virtual_tour_url: "", |
| 2206 |
testimonial_review_ids: [], |
| 2207 |
// Will be populated from actual reviews |
| 2208 |
destinations: [], |
| 2209 |
// Will be populated |
| 2210 |
starting_location: "Kathmandu International Airport", |
| 2211 |
ending_location: "Lukla Airport", |
| 2212 |
countries: ["Nepal"], |
| 2213 |
regions: ["Khumbu Region"], |
| 2214 |
starting_latitude: "27.9881", |
| 2215 |
starting_longitude: "86.9250", |
| 2216 |
ending_latitude: "27.6837", |
| 2217 |
ending_longitude: "86.7330", |
| 2218 |
landmarks: [ |
| 2219 |
"Mount Everest", |
| 2220 |
"Namche Bazaar", |
| 2221 |
"Tengboche Monastery", |
| 2222 |
"Kala Patthar" |
| 2223 |
], |
| 2224 |
trip_type: "multi_day", |
| 2225 |
duration_days: "14", |
| 2226 |
duration_nights: "13", |
| 2227 |
duration_hours: "", |
| 2228 |
available_from: new Date(Date.now() + 60 * 24 * 60 * 60 * 1e3).toISOString().split("T")[0], |
| 2229 |
available_to: new Date(Date.now() + 365 * 24 * 60 * 60 * 1e3).toISOString().split("T")[0], |
| 2230 |
booking_window_days: "60", |
| 2231 |
seasonal_availability: "March to May, September to November", |
| 2232 |
best_season: "October to November", |
| 2233 |
peak_season: "October to November", |
| 2234 |
off_season: "December to February, June to August", |
| 2235 |
activity_types: [], |
| 2236 |
difficulty_level: "", |
| 2237 |
trip_category: [], |
| 2238 |
tags: ["trekking", "mountains", "adventure", "challenging", "everest"], |
| 2239 |
featured_priority: "featured", |
| 2240 |
accommodation_type: "Teahouse", |
| 2241 |
meal_plan: "full_board", |
| 2242 |
accommodation_details: "Traditional teahouses along the route with basic amenities. Rooms are shared, and facilities become more basic as altitude increases.", |
| 2243 |
transportation_included: true, |
| 2244 |
pickup_location: "Kathmandu International Airport", |
| 2245 |
dropoff_location: "Lukla Airport", |
| 2246 |
transportation_details: "Domestic flights Kathmandu-Lukla-Kathmandu included. Airport transfers included.", |
| 2247 |
pricing_type: "regular", |
| 2248 |
original_price: "1899", |
| 2249 |
discounted_price: "1699", |
| 2250 |
deposit_amount: "500", |
| 2251 |
deposit_percentage: "", |
| 2252 |
payment_terms: "50% deposit required at booking, remaining 50% due 60 days before departure", |
| 2253 |
max_travelers: "12", |
| 2254 |
min_travelers: "2", |
| 2255 |
booking_deadline_hours: "24", |
| 2256 |
cancellation_policy: "Free cancellation up to 60 days before departure. 50% refund for cancellations 30-60 days before. No refund for cancellations less than 30 days before.", |
| 2257 |
age_min: "18", |
| 2258 |
age_max: "65", |
| 2259 |
physical_requirements: "Excellent physical fitness required. Previous trekking experience recommended. Must be able to walk 6-8 hours daily at high altitude.", |
| 2260 |
visa_requirements: "Tourist visa required for Nepal. Can be obtained on arrival at airport or in advance. Valid passport required.", |
| 2261 |
vaccination_requirements: "Recommended: Hepatitis A, Typhoid, Japanese Encephalitis, and routine vaccinations. Consult with travel health clinic.", |
| 2262 |
disable_booking: false, |
| 2263 |
has_default_time_slots: false, |
| 2264 |
default_time_slots: [], |
| 2265 |
departure_time: "", |
| 2266 |
included_items: [ |
| 2267 |
{ |
| 2268 |
title: "Accommodation", |
| 2269 |
description: "13 nights in teahouses along the route" |
| 2270 |
}, |
| 2271 |
{ |
| 2272 |
title: "All meals", |
| 2273 |
description: "Breakfast, lunch, and dinner included" |
| 2274 |
}, |
| 2275 |
{ |
| 2276 |
title: "Professional guides", |
| 2277 |
description: "Experienced mountain guides and porters" |
| 2278 |
}, |
| 2279 |
{ |
| 2280 |
title: "Permits", |
| 2281 |
description: "TIMS and Sagarmatha National Park permits" |
| 2282 |
}, |
| 2283 |
{ |
| 2284 |
title: "Domestic flights", |
| 2285 |
description: "Kathmandu-Lukla-Kathmandu flights" |
| 2286 |
}, |
| 2287 |
{ |
| 2288 |
title: "Equipment", |
| 2289 |
description: "Sleeping bag and down jacket rental" |
| 2290 |
} |
| 2291 |
], |
| 2292 |
excluded_items: [ |
| 2293 |
{ |
| 2294 |
title: "International flights", |
| 2295 |
description: "Flights to and from Kathmandu" |
| 2296 |
}, |
| 2297 |
{ |
| 2298 |
title: "Travel insurance", |
| 2299 |
description: "Comprehensive travel and medical insurance required" |
| 2300 |
}, |
| 2301 |
{ |
| 2302 |
title: "Personal equipment", |
| 2303 |
description: "Trekking boots, clothing, and personal items" |
| 2304 |
}, |
| 2305 |
{ |
| 2306 |
title: "Tips", |
| 2307 |
description: "Tips for guides and porters (recommended)" |
| 2308 |
}, |
| 2309 |
{ |
| 2310 |
title: "Personal expenses", |
| 2311 |
description: "Drinks, snacks, and souvenirs" |
| 2312 |
} |
| 2313 |
], |
| 2314 |
itinerary_days: [], |
| 2315 |
gallery_images: [], |
| 2316 |
featured_image: null, |
| 2317 |
downloadable_items: [], |
| 2318 |
faqs: [ |
| 2319 |
{ |
| 2320 |
question: "How difficult is the trek?", |
| 2321 |
answer: "This is a challenging trek requiring excellent physical fitness. You'll be walking 6-8 hours daily at high altitude. Previous trekking experience is recommended." |
| 2322 |
}, |
| 2323 |
{ |
| 2324 |
question: "What is the altitude at Base Camp?", |
| 2325 |
answer: "Everest Base Camp is located at 5,364 meters (17,598 feet) above sea level." |
| 2326 |
}, |
| 2327 |
{ |
| 2328 |
question: "What happens if I get altitude sickness?", |
| 2329 |
answer: "Our guides are trained to recognize and treat altitude sickness. We have proper acclimatization schedules and emergency descent plans in place." |
| 2330 |
} |
| 2331 |
], |
| 2332 |
frontend_tabs: [ |
| 2333 |
{ |
| 2334 |
id: "overview", |
| 2335 |
label: "Overview", |
| 2336 |
enabled: true, |
| 2337 |
order: 1, |
| 2338 |
content_type: "general", |
| 2339 |
icon: { type: "icon", value: "book-open" } |
| 2340 |
}, |
| 2341 |
{ |
| 2342 |
id: "itinerary", |
| 2343 |
label: "Itinerary", |
| 2344 |
enabled: true, |
| 2345 |
order: 2, |
| 2346 |
content_type: "itinerary", |
| 2347 |
icon: { type: "icon", value: "calendar" } |
| 2348 |
}, |
| 2349 |
{ |
| 2350 |
id: "included", |
| 2351 |
label: "Included", |
| 2352 |
enabled: true, |
| 2353 |
order: 3, |
| 2354 |
content_type: "included_excluded", |
| 2355 |
icon: { type: "icon", value: "check" } |
| 2356 |
}, |
| 2357 |
{ |
| 2358 |
id: "location", |
| 2359 |
label: "Location", |
| 2360 |
enabled: true, |
| 2361 |
order: 4, |
| 2362 |
content_type: "gallery", |
| 2363 |
icon: { type: "icon", value: "map-pin" } |
| 2364 |
}, |
| 2365 |
{ |
| 2366 |
id: "important_info", |
| 2367 |
label: "Important Info", |
| 2368 |
enabled: true, |
| 2369 |
order: 5, |
| 2370 |
content_type: "general", |
| 2371 |
icon: { type: "icon", value: "info" } |
| 2372 |
}, |
| 2373 |
{ |
| 2374 |
id: "downloads", |
| 2375 |
label: "Downloads", |
| 2376 |
enabled: true, |
| 2377 |
order: 6, |
| 2378 |
content_type: "downloads", |
| 2379 |
icon: { type: "icon", value: "download" } |
| 2380 |
}, |
| 2381 |
{ |
| 2382 |
id: "faq", |
| 2383 |
label: "FAQ", |
| 2384 |
enabled: true, |
| 2385 |
order: 7, |
| 2386 |
content_type: "faqs", |
| 2387 |
icon: { type: "icon", value: "help-circle" } |
| 2388 |
}, |
| 2389 |
{ |
| 2390 |
id: "trip_story", |
| 2391 |
label: "Story", |
| 2392 |
enabled: true, |
| 2393 |
order: 8, |
| 2394 |
content_type: "custom", |
| 2395 |
custom_content: "", |
| 2396 |
icon: { type: "icon", value: "book" } |
| 2397 |
}, |
| 2398 |
{ |
| 2399 |
id: "what_makes_special", |
| 2400 |
label: "Special", |
| 2401 |
enabled: true, |
| 2402 |
order: 9, |
| 2403 |
content_type: "custom", |
| 2404 |
custom_content: "", |
| 2405 |
icon: { type: "icon", value: "star" } |
| 2406 |
}, |
| 2407 |
{ |
| 2408 |
id: "testimonials", |
| 2409 |
label: "Testimonials", |
| 2410 |
enabled: true, |
| 2411 |
order: 10, |
| 2412 |
content_type: "reviews", |
| 2413 |
icon: { type: "icon", value: "message-circle" } |
| 2414 |
} |
| 2415 |
], |
| 2416 |
availability_dates: [], |
| 2417 |
status: "draft", |
| 2418 |
scheduled_publish_date: "", |
| 2419 |
scheduled_unpublish_date: "", |
| 2420 |
version: 1, |
| 2421 |
seasonal_auto_enable: false, |
| 2422 |
seasonal_enable_date: "", |
| 2423 |
seasonal_disable_date: "", |
| 2424 |
meta_title: "Everest Base Camp Trek - 14 Days | Ultimate Himalayan Adventure", |
| 2425 |
meta_description: "Embark on the adventure of a lifetime with our 14-day Everest Base Camp trek. Experience Sherpa culture, ancient monasteries, and breathtaking mountain views.", |
| 2426 |
meta_keywords: "Everest Base Camp, trekking, Nepal, Himalayas, adventure travel, mountain trek", |
| 2427 |
attributes: {}, |
| 2428 |
price_types: [] |
| 2429 |
}, |
| 2430 |
{ |
| 2431 |
// Trip 3: European City Tour |
| 2432 |
title: "European Grand Tour - 10 Days", |
| 2433 |
slug: "european-grand-tour-10-days", |
| 2434 |
description: "Discover the best of Europe with our 10-day grand tour covering Paris, Rome, and Barcelona. Experience world-famous landmarks, indulge in exquisite cuisine, explore rich history and art, and immerse yourself in diverse European cultures. This carefully crafted journey takes you through three of Europe's most iconic cities, each offering unique experiences and unforgettable memories.", |
| 2435 |
short_description: "Discover the best of Europe with our 10-day grand tour covering Paris, Rome, and Barcelona.", |
| 2436 |
highlights: [ |
| 2437 |
"Eiffel Tower and Louvre Museum", |
| 2438 |
"Colosseum and Vatican City", |
| 2439 |
"Sagrada Familia and Park Güell", |
| 2440 |
"World-class cuisine", |
| 2441 |
"Professional local guides" |
| 2442 |
], |
| 2443 |
trip_details: "Begin your European adventure in the City of Light—Paris. Explore iconic landmarks like the Eiffel Tower, Louvre Museum, and Notre-Dame Cathedral. Stroll along the Champs-Élysées, enjoy a Seine River cruise, and indulge in French pastries at charming cafés. Next, travel to Rome, the Eternal City, where ancient history comes alive. Visit the Colosseum, Roman Forum, and Vatican City with its stunning Sistine Chapel. Enjoy authentic Italian cuisine and gelato while exploring cobblestone streets. Conclude your journey in Barcelona, Spain's vibrant cultural capital. Admire Gaudí's architectural masterpieces including the Sagrada Familia and Park Güell. Experience the lively atmosphere of Las Ramblas, enjoy tapas and sangria, and relax on beautiful Mediterranean beaches.", |
| 2444 |
what_makes_special: "This tour includes skip-the-line tickets to major attractions, private guided tours in each city, and carefully selected accommodations in prime locations. Our small group size ensures personalized attention and authentic local experiences.", |
| 2445 |
trip_story: "Your European adventure begins as you step off the plane in Paris, greeted by the elegant architecture and romantic atmosphere that has inspired artists for centuries. Each day brings new discoveries—from the artistic treasures of the Louvre to the bohemian charm of Montmartre. In Rome, you walk in the footsteps of emperors and gladiators, feeling the weight of history in every ancient stone. The Vatican's art and architecture leave you in awe, while a simple plate of pasta in a local trattoria reminds you that the best experiences are often the simplest. Barcelona welcomes you with its unique blend of Gothic and Modernist architecture, vibrant street life, and Mediterranean warmth. As you watch the sunset from Park Güell, you realize that this journey has not just shown you three cities—it has shown you three different ways of living, three different approaches to art and culture, and three different reasons to fall in love with Europe.", |
| 2446 |
video_url: "https://www.youtube.com/watch?v=example3", |
| 2447 |
virtual_tour_url: "", |
| 2448 |
testimonial_review_ids: [], |
| 2449 |
// Will be populated from actual reviews |
| 2450 |
destinations: [], |
| 2451 |
starting_location: "Charles de Gaulle Airport (CDG)", |
| 2452 |
ending_location: "El Prat Airport (BCN)", |
| 2453 |
countries: ["France", "Italy", "Spain"], |
| 2454 |
regions: ["Île-de-France", "Lazio", "Catalonia"], |
| 2455 |
starting_latitude: "48.8566", |
| 2456 |
starting_longitude: "2.3522", |
| 2457 |
ending_latitude: "41.3792", |
| 2458 |
ending_longitude: "2.1281", |
| 2459 |
landmarks: [ |
| 2460 |
"Eiffel Tower", |
| 2461 |
"Colosseum", |
| 2462 |
"Sagrada Familia", |
| 2463 |
"Louvre Museum", |
| 2464 |
"Vatican City" |
| 2465 |
], |
| 2466 |
trip_type: "multi_day", |
| 2467 |
duration_days: "10", |
| 2468 |
duration_nights: "9", |
| 2469 |
duration_hours: "", |
| 2470 |
available_from: new Date(Date.now() + 45 * 24 * 60 * 60 * 1e3).toISOString().split("T")[0], |
| 2471 |
available_to: new Date(Date.now() + 365 * 24 * 60 * 60 * 1e3).toISOString().split("T")[0], |
| 2472 |
booking_window_days: "45", |
| 2473 |
seasonal_availability: "Year-round", |
| 2474 |
best_season: "April to June, September to October", |
| 2475 |
peak_season: "June to August", |
| 2476 |
off_season: "November to March", |
| 2477 |
activity_types: [], |
| 2478 |
difficulty_level: "", |
| 2479 |
trip_category: [], |
| 2480 |
tags: ["cultural", "city-tour", "history", "art", "food"], |
| 2481 |
featured_priority: "featured", |
| 2482 |
accommodation_type: "Hotel", |
| 2483 |
meal_plan: "breakfast", |
| 2484 |
accommodation_details: "4-star hotels in city centers with easy access to major attractions", |
| 2485 |
transportation_included: true, |
| 2486 |
pickup_location: "Charles de Gaulle Airport", |
| 2487 |
dropoff_location: "El Prat Airport", |
| 2488 |
transportation_details: "High-speed train between cities, private transfers, and metro passes included", |
| 2489 |
pricing_type: "regular", |
| 2490 |
original_price: "2499", |
| 2491 |
discounted_price: "", |
| 2492 |
price_types: [], |
| 2493 |
deposit_amount: "600", |
| 2494 |
deposit_percentage: "", |
| 2495 |
payment_terms: "40% deposit required at booking, remaining 60% due 45 days before departure", |
| 2496 |
max_travelers: "20", |
| 2497 |
min_travelers: "4", |
| 2498 |
booking_deadline_hours: "24", |
| 2499 |
cancellation_policy: "Free cancellation up to 45 days before departure. 75% refund for cancellations 30-45 days before. 50% refund for cancellations 15-30 days before. No refund for cancellations less than 15 days before.", |
| 2500 |
age_min: "", |
| 2501 |
age_max: "", |
| 2502 |
physical_requirements: "Moderate walking required. Some sites involve stairs and uneven surfaces. Suitable for most fitness levels.", |
| 2503 |
visa_requirements: "Schengen visa required for most non-EU nationals. Apply well in advance as processing can take several weeks.", |
| 2504 |
vaccination_requirements: "No mandatory vaccinations. Routine vaccinations recommended.", |
| 2505 |
disable_booking: false, |
| 2506 |
has_default_time_slots: false, |
| 2507 |
default_time_slots: [], |
| 2508 |
departure_time: "", |
| 2509 |
included_items: [ |
| 2510 |
{ |
| 2511 |
title: "Accommodation", |
| 2512 |
description: "9 nights in 4-star city center hotels" |
| 2513 |
}, |
| 2514 |
{ title: "Breakfast", description: "Daily breakfast included" }, |
| 2515 |
{ |
| 2516 |
title: "Transportation", |
| 2517 |
description: "High-speed trains, airport transfers, and city metro passes" |
| 2518 |
}, |
| 2519 |
{ |
| 2520 |
title: "Guided tours", |
| 2521 |
description: "Professional local guides in each city" |
| 2522 |
}, |
| 2523 |
{ |
| 2524 |
title: "Skip-the-line tickets", |
| 2525 |
description: "Priority access to major attractions" |
| 2526 |
}, |
| 2527 |
{ |
| 2528 |
title: "Welcome dinner", |
| 2529 |
description: "Traditional welcome dinner in Paris" |
| 2530 |
} |
| 2531 |
], |
| 2532 |
excluded_items: [ |
| 2533 |
{ |
| 2534 |
title: "International flights", |
| 2535 |
description: "Flights to Paris and from Barcelona" |
| 2536 |
}, |
| 2537 |
{ |
| 2538 |
title: "Lunch and dinner", |
| 2539 |
description: "Meals other than breakfast and welcome dinner" |
| 2540 |
}, |
| 2541 |
{ |
| 2542 |
title: "Travel insurance", |
| 2543 |
description: "Travel insurance recommended" |
| 2544 |
}, |
| 2545 |
{ |
| 2546 |
title: "Personal expenses", |
| 2547 |
description: "Souvenirs, tips, and personal items" |
| 2548 |
} |
| 2549 |
], |
| 2550 |
itinerary_days: [], |
| 2551 |
gallery_images: [], |
| 2552 |
featured_image: null, |
| 2553 |
downloadable_items: [], |
| 2554 |
faqs: [ |
| 2555 |
{ |
| 2556 |
question: "Do I need a visa?", |
| 2557 |
answer: "Most non-EU nationals need a Schengen visa. Apply at the embassy of your first entry country (France) well in advance." |
| 2558 |
}, |
| 2559 |
{ |
| 2560 |
question: "What languages are spoken?", |
| 2561 |
answer: "English-speaking guides provided. Local languages are French, Italian, and Spanish, but English is widely spoken in tourist areas." |
| 2562 |
}, |
| 2563 |
{ |
| 2564 |
question: "Is this suitable for families?", |
| 2565 |
answer: "Yes, this tour is family-friendly. However, some museums and sites may have age restrictions for children." |
| 2566 |
} |
| 2567 |
], |
| 2568 |
frontend_tabs: [ |
| 2569 |
{ |
| 2570 |
id: "overview", |
| 2571 |
label: "Overview", |
| 2572 |
enabled: true, |
| 2573 |
order: 1, |
| 2574 |
content_type: "general", |
| 2575 |
icon: { type: "icon", value: "book-open" } |
| 2576 |
}, |
| 2577 |
{ |
| 2578 |
id: "itinerary", |
| 2579 |
label: "Itinerary", |
| 2580 |
enabled: true, |
| 2581 |
order: 2, |
| 2582 |
content_type: "itinerary", |
| 2583 |
icon: { type: "icon", value: "calendar" } |
| 2584 |
}, |
| 2585 |
{ |
| 2586 |
id: "included", |
| 2587 |
label: "Included", |
| 2588 |
enabled: true, |
| 2589 |
order: 3, |
| 2590 |
content_type: "included_excluded", |
| 2591 |
icon: { type: "icon", value: "check" } |
| 2592 |
}, |
| 2593 |
{ |
| 2594 |
id: "location", |
| 2595 |
label: "Location", |
| 2596 |
enabled: true, |
| 2597 |
order: 4, |
| 2598 |
content_type: "gallery", |
| 2599 |
icon: { type: "icon", value: "map-pin" } |
| 2600 |
}, |
| 2601 |
{ |
| 2602 |
id: "important_info", |
| 2603 |
label: "Important Info", |
| 2604 |
enabled: true, |
| 2605 |
order: 5, |
| 2606 |
content_type: "general", |
| 2607 |
icon: { type: "icon", value: "info" } |
| 2608 |
}, |
| 2609 |
{ |
| 2610 |
id: "downloads", |
| 2611 |
label: "Downloads", |
| 2612 |
enabled: true, |
| 2613 |
order: 6, |
| 2614 |
content_type: "downloads", |
| 2615 |
icon: { type: "icon", value: "download" } |
| 2616 |
}, |
| 2617 |
{ |
| 2618 |
id: "faq", |
| 2619 |
label: "FAQ", |
| 2620 |
enabled: true, |
| 2621 |
order: 7, |
| 2622 |
content_type: "faqs", |
| 2623 |
icon: { type: "icon", value: "help-circle" } |
| 2624 |
}, |
| 2625 |
{ |
| 2626 |
id: "trip_story", |
| 2627 |
label: "Story", |
| 2628 |
enabled: true, |
| 2629 |
order: 8, |
| 2630 |
content_type: "custom", |
| 2631 |
custom_content: "", |
| 2632 |
icon: { type: "icon", value: "book" } |
| 2633 |
}, |
| 2634 |
{ |
| 2635 |
id: "what_makes_special", |
| 2636 |
label: "Special", |
| 2637 |
enabled: true, |
| 2638 |
order: 9, |
| 2639 |
content_type: "custom", |
| 2640 |
custom_content: "", |
| 2641 |
icon: { type: "icon", value: "star" } |
| 2642 |
}, |
| 2643 |
{ |
| 2644 |
id: "testimonials", |
| 2645 |
label: "Testimonials", |
| 2646 |
enabled: true, |
| 2647 |
order: 10, |
| 2648 |
content_type: "reviews", |
| 2649 |
icon: { type: "icon", value: "message-circle" } |
| 2650 |
} |
| 2651 |
], |
| 2652 |
availability_dates: [], |
| 2653 |
status: "draft", |
| 2654 |
scheduled_publish_date: "", |
| 2655 |
scheduled_unpublish_date: "", |
| 2656 |
version: 1, |
| 2657 |
seasonal_auto_enable: false, |
| 2658 |
seasonal_enable_date: "", |
| 2659 |
seasonal_disable_date: "", |
| 2660 |
meta_title: "European Grand Tour - 10 Days | Paris, Rome & Barcelona", |
| 2661 |
meta_description: "Discover the best of Europe with our 10-day grand tour covering Paris, Rome, and Barcelona. Experience iconic landmarks, world-class cuisine, and rich history.", |
| 2662 |
meta_keywords: "Europe tour, Paris, Rome, Barcelona, European travel, cultural tour", |
| 2663 |
attributes: {} |
| 2664 |
} |
| 2665 |
]; |
| 2666 |
const [formData, setFormData] = reactExports.useState({ |
| 2667 |
title: "", |
| 2668 |
slug: "", |
| 2669 |
description: "", |
| 2670 |
highlights: [], |
| 2671 |
trip_details: "", |
| 2672 |
short_description: "", |
| 2673 |
what_makes_special: "", |
| 2674 |
trip_story: "", |
| 2675 |
video_url: "", |
| 2676 |
virtual_tour_url: "", |
| 2677 |
testimonial_review_ids: [], |
| 2678 |
destinations: [], |
| 2679 |
// Array of destination IDs |
| 2680 |
starting_location: "", |
| 2681 |
ending_location: "", |
| 2682 |
countries: [], |
| 2683 |
regions: [], |
| 2684 |
starting_latitude: "", |
| 2685 |
starting_longitude: "", |
| 2686 |
ending_latitude: "", |
| 2687 |
ending_longitude: "", |
| 2688 |
landmarks: [], |
| 2689 |
trip_type: "multi_day", |
| 2690 |
duration_days: "", |
| 2691 |
duration_nights: "", |
| 2692 |
duration_hours: "", |
| 2693 |
available_from: "", |
| 2694 |
available_to: "", |
| 2695 |
booking_window_days: "", |
| 2696 |
seasonal_availability: "", |
| 2697 |
best_season: "", |
| 2698 |
peak_season: "", |
| 2699 |
off_season: "", |
| 2700 |
activity_types: [], |
| 2701 |
// Array of activity IDs |
| 2702 |
difficulty_level: "", |
| 2703 |
trip_category: [], |
| 2704 |
tags: [], |
| 2705 |
featured_priority: "none", |
| 2706 |
accommodation_type: "", |
| 2707 |
meal_plan: "", |
| 2708 |
accommodation_details: "", |
| 2709 |
transportation_included: false, |
| 2710 |
pickup_location: "", |
| 2711 |
dropoff_location: "", |
| 2712 |
transportation_details: "", |
| 2713 |
pricing_type: "regular", |
| 2714 |
original_price: "", |
| 2715 |
discounted_price: "", |
| 2716 |
price_types: [], |
| 2717 |
deposit_amount: "", |
| 2718 |
deposit_percentage: "", |
| 2719 |
payment_terms: "", |
| 2720 |
max_travelers: "10", |
| 2721 |
min_travelers: "2", |
| 2722 |
booking_deadline_hours: "24", |
| 2723 |
cancellation_policy: "Flexible", |
| 2724 |
age_min: "18", |
| 2725 |
age_max: "65", |
| 2726 |
physical_requirements: "Moderate", |
| 2727 |
visa_requirements: "Schengen visa", |
| 2728 |
vaccination_requirements: "COVID-19 vaccination", |
| 2729 |
disable_booking: false, |
| 2730 |
has_default_time_slots: false, |
| 2731 |
default_time_slots: [], |
| 2732 |
departure_time: "09:00", |
| 2733 |
included_items: [], |
| 2734 |
excluded_items: [], |
| 2735 |
attributes: {}, |
| 2736 |
// attribute_id -> value mapping |
| 2737 |
itinerary_days: [], |
| 2738 |
gallery_images: [], |
| 2739 |
featured_image: null, |
| 2740 |
downloadable_items: [], |
| 2741 |
faqs: [], |
| 2742 |
frontend_tabs: [ |
| 2743 |
{ |
| 2744 |
id: "overview", |
| 2745 |
label: "Overview", |
| 2746 |
enabled: true, |
| 2747 |
order: 1, |
| 2748 |
content_type: "general", |
| 2749 |
icon: { type: "icon", value: "book-open" } |
| 2750 |
}, |
| 2751 |
{ |
| 2752 |
id: "itinerary", |
| 2753 |
label: "Itinerary", |
| 2754 |
enabled: true, |
| 2755 |
order: 2, |
| 2756 |
content_type: "itinerary", |
| 2757 |
icon: { type: "icon", value: "calendar" } |
| 2758 |
}, |
| 2759 |
{ |
| 2760 |
id: "included", |
| 2761 |
label: "Included", |
| 2762 |
enabled: true, |
| 2763 |
order: 3, |
| 2764 |
content_type: "included_excluded", |
| 2765 |
icon: { type: "icon", value: "check" } |
| 2766 |
}, |
| 2767 |
{ |
| 2768 |
id: "location", |
| 2769 |
label: "Location", |
| 2770 |
enabled: true, |
| 2771 |
order: 4, |
| 2772 |
content_type: "gallery", |
| 2773 |
icon: { type: "icon", value: "map-pin" } |
| 2774 |
}, |
| 2775 |
{ |
| 2776 |
id: "important_info", |
| 2777 |
label: "Important Info", |
| 2778 |
enabled: true, |
| 2779 |
order: 5, |
| 2780 |
content_type: "general", |
| 2781 |
icon: { type: "icon", value: "info" } |
| 2782 |
}, |
| 2783 |
{ |
| 2784 |
id: "downloads", |
| 2785 |
label: "Downloads", |
| 2786 |
enabled: true, |
| 2787 |
order: 6, |
| 2788 |
content_type: "downloads", |
| 2789 |
icon: { type: "icon", value: "download" } |
| 2790 |
}, |
| 2791 |
{ |
| 2792 |
id: "faq", |
| 2793 |
label: "FAQ", |
| 2794 |
enabled: true, |
| 2795 |
order: 7, |
| 2796 |
content_type: "faqs", |
| 2797 |
icon: { type: "icon", value: "help-circle" } |
| 2798 |
}, |
| 2799 |
{ |
| 2800 |
id: "trip_story", |
| 2801 |
label: "Story", |
| 2802 |
enabled: true, |
| 2803 |
order: 8, |
| 2804 |
content_type: "custom", |
| 2805 |
custom_content: "", |
| 2806 |
icon: { type: "icon", value: "book" } |
| 2807 |
}, |
| 2808 |
{ |
| 2809 |
id: "what_makes_special", |
| 2810 |
label: "Special", |
| 2811 |
enabled: true, |
| 2812 |
order: 9, |
| 2813 |
content_type: "custom", |
| 2814 |
custom_content: "", |
| 2815 |
icon: { type: "icon", value: "star" } |
| 2816 |
}, |
| 2817 |
{ |
| 2818 |
id: "testimonials", |
| 2819 |
label: "Testimonials", |
| 2820 |
enabled: true, |
| 2821 |
order: 10, |
| 2822 |
content_type: "reviews", |
| 2823 |
icon: { type: "icon", value: "message-circle" } |
| 2824 |
} |
| 2825 |
], |
| 2826 |
availability_dates: [], |
| 2827 |
status: "draft", |
| 2828 |
scheduled_publish_date: "", |
| 2829 |
scheduled_unpublish_date: "", |
| 2830 |
version: 1, |
| 2831 |
seasonal_auto_enable: false, |
| 2832 |
seasonal_enable_date: "", |
| 2833 |
seasonal_disable_date: "", |
| 2834 |
meta_title: "", |
| 2835 |
meta_description: "", |
| 2836 |
meta_keywords: "" |
| 2837 |
}); |
| 2838 |
const [errors, setErrors] = reactExports.useState({}); |
| 2839 |
const [isSubmitting, setIsSubmitting] = reactExports.useState(false); |
| 2840 |
const [copiedErrorDetails, setCopiedErrorDetails] = reactExports.useState(false); |
| 2841 |
const copyErrorDetailsToClipboard = (text) => { |
| 2842 |
var _a2; |
| 2843 |
if (!text) return; |
| 2844 |
const fallbackCopy = () => { |
| 2845 |
const textarea = document.createElement("textarea"); |
| 2846 |
textarea.value = text; |
| 2847 |
textarea.style.position = "fixed"; |
| 2848 |
textarea.style.opacity = "0"; |
| 2849 |
document.body.appendChild(textarea); |
| 2850 |
textarea.select(); |
| 2851 |
try { |
| 2852 |
document.execCommand("copy"); |
| 2853 |
} catch (e) { |
| 2854 |
} |
| 2855 |
document.body.removeChild(textarea); |
| 2856 |
setCopiedErrorDetails(true); |
| 2857 |
setTimeout(() => setCopiedErrorDetails(false), 1500); |
| 2858 |
}; |
| 2859 |
try { |
| 2860 |
if ((_a2 = navigator == null ? void 0 : navigator.clipboard) == null ? void 0 : _a2.writeText) { |
| 2861 |
navigator.clipboard.writeText(text).then(() => { |
| 2862 |
setCopiedErrorDetails(true); |
| 2863 |
setTimeout(() => setCopiedErrorDetails(false), 1500); |
| 2864 |
}).catch(() => fallbackCopy()); |
| 2865 |
} else { |
| 2866 |
fallbackCopy(); |
| 2867 |
} |
| 2868 |
} catch { |
| 2869 |
fallbackCopy(); |
| 2870 |
} |
| 2871 |
}; |
| 2872 |
const action = reactExports.useMemo(() => { |
| 2873 |
const params = new URLSearchParams(window.location.search); |
| 2874 |
return params.get("action") || "create"; |
| 2875 |
}, []); |
| 2876 |
const tripId = reactExports.useMemo(() => { |
| 2877 |
const params = new URLSearchParams(window.location.search); |
| 2878 |
return params.get("id") ? parseInt(params.get("id") || "0") : null; |
| 2879 |
}, []); |
| 2880 |
const isEditMode = action === "edit" && tripId !== null; |
| 2881 |
const { data: travelerCategoriesData, isLoading: isLoadingCategories } = useQuery({ |
| 2882 |
queryKey: ["traveler-categories"], |
| 2883 |
queryFn: async () => { |
| 2884 |
var _a2; |
| 2885 |
try { |
| 2886 |
const response = await apiClient.get("/traveler-categories", { |
| 2887 |
params: { |
| 2888 |
per_page: 100, |
| 2889 |
status: "publish" |
| 2890 |
// Only get published categories |
| 2891 |
} |
| 2892 |
}); |
| 2893 |
const categories = ((_a2 = response == null ? void 0 : response.data) == null ? void 0 : _a2.data) || (response == null ? void 0 : response.data) || response || []; |
| 2894 |
return Array.isArray(categories) ? categories : []; |
| 2895 |
} catch (error) { |
| 2896 |
showToast( |
| 2897 |
(error == null ? void 0 : error.message) || __$1("Failed to load traveler categories", "yatra"), |
| 2898 |
"error" |
| 2899 |
); |
| 2900 |
return []; |
| 2901 |
} |
| 2902 |
}, |
| 2903 |
enabled: can("yatra_view_trips") && (currentSection === "pricing" || visitedSections.has("pricing")), |
| 2904 |
staleTime: 5 * 60 * 1e3 |
| 2905 |
// Cache for 5 minutes |
| 2906 |
}); |
| 2907 |
const activeCategories = reactExports.useMemo(() => { |
| 2908 |
const categories = travelerCategoriesData || []; |
| 2909 |
return categories.filter( |
| 2910 |
(cat) => cat.status === "active" || cat.status === "publish" |
| 2911 |
); |
| 2912 |
}, [travelerCategoriesData]); |
| 2913 |
const { data: settingsData } = useQuery({ |
| 2914 |
queryKey: ["settings"], |
| 2915 |
queryFn: async () => { |
| 2916 |
try { |
| 2917 |
const response = await fetchSettings(); |
| 2918 |
return response; |
| 2919 |
} catch (error) { |
| 2920 |
return { currency: "USD" }; |
| 2921 |
} |
| 2922 |
}, |
| 2923 |
enabled: can("yatra_view_trips") |
| 2924 |
}); |
| 2925 |
const cur = settingsData == null ? void 0 : settingsData.currency; |
| 2926 |
const defCur = settingsData == null ? void 0 : settingsData.default_currency; |
| 2927 |
const globalCurrency = typeof cur === "string" && cur.length > 0 ? cur : typeof defCur === "string" && defCur.length > 0 ? defCur : "USD"; |
| 2928 |
const { data: activitiesData } = useQuery({ |
| 2929 |
queryKey: ["activities-published"], |
| 2930 |
queryFn: async () => { |
| 2931 |
try { |
| 2932 |
const response = await apiClient.get("/activities", { |
| 2933 |
params: { |
| 2934 |
per_page: 100, |
| 2935 |
status: "publish" |
| 2936 |
// Only get published activities |
| 2937 |
} |
| 2938 |
}); |
| 2939 |
return response.data || []; |
| 2940 |
} catch (error) { |
| 2941 |
showToast( |
| 2942 |
(error == null ? void 0 : error.message) || __$1("Failed to load activities", "yatra"), |
| 2943 |
"error" |
| 2944 |
); |
| 2945 |
return []; |
| 2946 |
} |
| 2947 |
}, |
| 2948 |
enabled: can("yatra_view_trips") && (currentSection === "categorization" || visitedSections.has("categorization")), |
| 2949 |
staleTime: 5 * 60 * 1e3 |
| 2950 |
// Cache for 5 minutes |
| 2951 |
}); |
| 2952 |
const { data: tripCategoriesResponse } = useQuery({ |
| 2953 |
queryKey: ["trip-categories", "published"], |
| 2954 |
queryFn: async () => { |
| 2955 |
try { |
| 2956 |
const response = await apiClient.get("/trip-categories", { |
| 2957 |
params: { |
| 2958 |
per_page: 100, |
| 2959 |
status: "publish", |
| 2960 |
hierarchical: true, |
| 2961 |
orderby: "name", |
| 2962 |
order: "ASC" |
| 2963 |
} |
| 2964 |
}); |
| 2965 |
return response; |
| 2966 |
} catch (error) { |
| 2967 |
showToast( |
| 2968 |
(error == null ? void 0 : error.message) || __$1("Failed to load trip categories", "yatra"), |
| 2969 |
"error" |
| 2970 |
); |
| 2971 |
return []; |
| 2972 |
} |
| 2973 |
}, |
| 2974 |
enabled: can("yatra_view_trips"), |
| 2975 |
staleTime: 5 * 60 * 1e3 |
| 2976 |
// Cache for 5 minutes |
| 2977 |
}); |
| 2978 |
const { |
| 2979 |
data: difficultyLevelsResponse, |
| 2980 |
isLoading: isLoadingDifficultyLevels |
| 2981 |
} = useQuery({ |
| 2982 |
queryKey: ["difficulty-levels", "published"], |
| 2983 |
queryFn: async () => { |
| 2984 |
try { |
| 2985 |
const response = await apiClient.get("/difficulty-levels", { |
| 2986 |
params: { |
| 2987 |
per_page: 100, |
| 2988 |
status: "publish", |
| 2989 |
orderby: "sorting", |
| 2990 |
order: "ASC" |
| 2991 |
} |
| 2992 |
}); |
| 2993 |
return response.data || []; |
| 2994 |
} catch (error) { |
| 2995 |
showToast( |
| 2996 |
(error == null ? void 0 : error.message) || __$1("Failed to load difficulty levels", "yatra"), |
| 2997 |
"error" |
| 2998 |
); |
| 2999 |
return []; |
| 3000 |
} |
| 3001 |
}, |
| 3002 |
enabled: can("yatra_view_trips") && (currentSection === "categorization" || visitedSections.has("categorization")), |
| 3003 |
staleTime: 5 * 60 * 1e3 |
| 3004 |
// Cache for 5 minutes |
| 3005 |
}); |
| 3006 |
const tripCategories = reactExports.useMemo(() => { |
| 3007 |
const payload = extractArrayPayload(tripCategoriesResponse); |
| 3008 |
return payload.filter((category) => { |
| 3009 |
if (!category) return false; |
| 3010 |
if (typeof category !== "object") return false; |
| 3011 |
if ("status" in category && category.status && category.status !== "publish") { |
| 3012 |
return false; |
| 3013 |
} |
| 3014 |
return true; |
| 3015 |
}); |
| 3016 |
}, [tripCategoriesResponse]); |
| 3017 |
const difficultyLevels = reactExports.useMemo(() => { |
| 3018 |
const payload = extractArrayPayload(difficultyLevelsResponse); |
| 3019 |
return payload.filter((level) => { |
| 3020 |
if (!level) return false; |
| 3021 |
if (typeof level !== "object") return false; |
| 3022 |
if ("status" in level && level.status && level.status !== "publish") { |
| 3023 |
return false; |
| 3024 |
} |
| 3025 |
return true; |
| 3026 |
}); |
| 3027 |
}, [difficultyLevelsResponse]); |
| 3028 |
const { data: destinationsData } = useQuery({ |
| 3029 |
queryKey: ["destinations-published"], |
| 3030 |
queryFn: async () => { |
| 3031 |
try { |
| 3032 |
const response = await apiClient.get("/destinations", { |
| 3033 |
params: { |
| 3034 |
per_page: 100, |
| 3035 |
status: "publish" |
| 3036 |
// Only get published destinations |
| 3037 |
} |
| 3038 |
}); |
| 3039 |
return response.data || []; |
| 3040 |
} catch (error) { |
| 3041 |
showToast( |
| 3042 |
(error == null ? void 0 : error.message) || __$1("Failed to load destinations", "yatra"), |
| 3043 |
"error" |
| 3044 |
); |
| 3045 |
return []; |
| 3046 |
} |
| 3047 |
}, |
| 3048 |
enabled: can("yatra_view_trips") && (isEditMode || currentSection === "location" || visitedSections.has("location")), |
| 3049 |
staleTime: 5 * 60 * 1e3 |
| 3050 |
// Cache for 5 minutes |
| 3051 |
}); |
| 3052 |
const { |
| 3053 |
data: tripData, |
| 3054 |
isLoading: isLoadingTrip, |
| 3055 |
error: tripError |
| 3056 |
} = useQuery({ |
| 3057 |
queryKey: ["trip", tripId], |
| 3058 |
queryFn: async () => { |
| 3059 |
if (!tripId) return null; |
| 3060 |
try { |
| 3061 |
const response = await apiClient.get(`/trips/${tripId}`); |
| 3062 |
const tripData2 = (response == null ? void 0 : response.data) || response; |
| 3063 |
return tripData2; |
| 3064 |
} catch (error) { |
| 3065 |
console.error("Error loading trip:", error); |
| 3066 |
showToast( |
| 3067 |
(error == null ? void 0 : error.message) || __$1("Failed to load trip data", "yatra"), |
| 3068 |
"error" |
| 3069 |
); |
| 3070 |
throw error; |
| 3071 |
} |
| 3072 |
}, |
| 3073 |
enabled: !!tripId && isEditMode, |
| 3074 |
staleTime: 0 |
| 3075 |
// Always fetch fresh data to ensure downloadable items persist after save |
| 3076 |
}); |
| 3077 |
const tripErrorContext = reactExports.useMemo( |
| 3078 |
() => getErrorContext(tripError), |
| 3079 |
[tripError] |
| 3080 |
); |
| 3081 |
const tripAttributesQueryEnabled = Boolean(tripId && isEditMode); |
| 3082 |
const { data: tripAttributesData, isPending: isTripAttributesPending } = useQuery({ |
| 3083 |
queryKey: ["trip-attributes", tripId], |
| 3084 |
queryFn: async () => { |
| 3085 |
var _a2; |
| 3086 |
if (!tripId) return {}; |
| 3087 |
try { |
| 3088 |
const response = await apiClient.get(`/trips/${tripId}/attributes`); |
| 3089 |
let payload = response == null ? void 0 : response.data; |
| 3090 |
if (!payload || !Array.isArray(payload)) { |
| 3091 |
payload = response; |
| 3092 |
} |
| 3093 |
if (!payload || !Array.isArray(payload)) { |
| 3094 |
payload = (_a2 = response == null ? void 0 : response.data) == null ? void 0 : _a2.data; |
| 3095 |
} |
| 3096 |
const attributes = Array.isArray(payload) ? payload : Array.isArray(payload == null ? void 0 : payload.data) ? payload.data : []; |
| 3097 |
const attributesMap = {}; |
| 3098 |
attributes.forEach((attr) => { |
| 3099 |
const attributeId = Number(attr.attribute_id || attr.id); |
| 3100 |
if (attributeId) { |
| 3101 |
let value = ""; |
| 3102 |
if (attr.relationship_metadata) { |
| 3103 |
try { |
| 3104 |
const metadata = typeof attr.relationship_metadata === "string" ? JSON.parse(attr.relationship_metadata) : attr.relationship_metadata; |
| 3105 |
value = metadata.value || ""; |
| 3106 |
} catch (e) { |
| 3107 |
console.warn( |
| 3108 |
"Failed to parse relationship_metadata:", |
| 3109 |
attr.relationship_metadata, |
| 3110 |
e |
| 3111 |
); |
| 3112 |
value = ""; |
| 3113 |
} |
| 3114 |
} else { |
| 3115 |
value = attr.value || ""; |
| 3116 |
} |
| 3117 |
attributesMap[attributeId] = value; |
| 3118 |
} |
| 3119 |
}); |
| 3120 |
return attributesMap; |
| 3121 |
} catch (error) { |
| 3122 |
console.error("Failed to fetch trip attributes:", error); |
| 3123 |
return {}; |
| 3124 |
} |
| 3125 |
}, |
| 3126 |
enabled: tripAttributesQueryEnabled, |
| 3127 |
staleTime: 5 * 60 * 1e3 |
| 3128 |
// Cache for 5 minutes |
| 3129 |
}); |
| 3130 |
const tripAttributesReady = !tripAttributesQueryEnabled || !isTripAttributesPending; |
| 3131 |
const normalizeHighlights = (highlights) => { |
| 3132 |
if (!highlights) return []; |
| 3133 |
if (Array.isArray(highlights)) { |
| 3134 |
return highlights.map((h) => { |
| 3135 |
if (typeof h === "string") return h; |
| 3136 |
if (h && typeof h === "object") { |
| 3137 |
return h.highlight_text || h.text || h.title || String(h); |
| 3138 |
} |
| 3139 |
return String(h); |
| 3140 |
}).filter((h) => h.trim().length > 0); |
| 3141 |
} |
| 3142 |
if (typeof highlights === "string") { |
| 3143 |
try { |
| 3144 |
const parsed = JSON.parse(highlights); |
| 3145 |
return normalizeHighlights(parsed); |
| 3146 |
} catch { |
| 3147 |
return [highlights]; |
| 3148 |
} |
| 3149 |
} |
| 3150 |
return []; |
| 3151 |
}; |
| 3152 |
const normalizeDownloadableItems = (items) => { |
| 3153 |
if (!items || !Array.isArray(items)) return []; |
| 3154 |
return items.filter((row) => row && typeof row === "object").map((row, idx) => { |
| 3155 |
const rawVisibility = row.visibility ?? "booked_only"; |
| 3156 |
const mappedVisibility = rawVisibility === "paid_only" ? "booked_only" : rawVisibility; |
| 3157 |
const safeVisibility = [ |
| 3158 |
"public", |
| 3159 |
"logged_in", |
| 3160 |
"booked_only" |
| 3161 |
].includes(mappedVisibility) ? mappedVisibility : "booked_only"; |
| 3162 |
const title = (row.title ?? row.download_title ?? row.downlaod_title ?? "").toString(); |
| 3163 |
const description = (row.description ?? row.download_description ?? row.downlaod_description ?? "").toString(); |
| 3164 |
const attachmentIdRaw = row.attachment_id ?? row.download_file ?? row.downlaod_file; |
| 3165 |
const attachmentUrl = (row.attachment_url ?? row.content_url ?? "").toString(); |
| 3166 |
const attachmentTitle = (row.attachment_title ?? "").toString(); |
| 3167 |
const enabledRaw = row.enabled ?? row.is_downloadable ?? row.download_enabled ?? row.downlaod_enabled; |
| 3168 |
return { |
| 3169 |
id: row.id != null ? Number(row.id) : null, |
| 3170 |
title, |
| 3171 |
description, |
| 3172 |
attachment_id: attachmentIdRaw != null ? Number(attachmentIdRaw) : null, |
| 3173 |
attachment_url: attachmentUrl, |
| 3174 |
attachment_title: attachmentTitle, |
| 3175 |
visibility: safeVisibility, |
| 3176 |
enabled: enabledRaw != null ? Boolean(enabledRaw) : true, |
| 3177 |
sort_order: row.sort_order != null ? Number(row.sort_order) : idx + 1 |
| 3178 |
}; |
| 3179 |
}); |
| 3180 |
}; |
| 3181 |
const extractIds = (items) => { |
| 3182 |
if (!items || !Array.isArray(items)) return []; |
| 3183 |
return items.map((item) => { |
| 3184 |
if (typeof item === "number") return item; |
| 3185 |
if (typeof item === "string") return parseInt(item) || 0; |
| 3186 |
if (item && typeof item === "object") { |
| 3187 |
return item.id || item.destination_id || item.activity_id || item.category_id || 0; |
| 3188 |
} |
| 3189 |
return 0; |
| 3190 |
}).filter((id) => !isNaN(id) && id > 0); |
| 3191 |
}; |
| 3192 |
const normalizeItineraryDays = (days) => { |
| 3193 |
if (!days) return []; |
| 3194 |
if (Array.isArray(days)) return days; |
| 3195 |
if (typeof days === "string") { |
| 3196 |
try { |
| 3197 |
const parsed = JSON.parse(days); |
| 3198 |
return Array.isArray(parsed) ? parsed : []; |
| 3199 |
} catch { |
| 3200 |
return []; |
| 3201 |
} |
| 3202 |
} |
| 3203 |
return []; |
| 3204 |
}; |
| 3205 |
const normalizeAvailabilityDates = (dates) => { |
| 3206 |
if (!dates) return []; |
| 3207 |
if (Array.isArray(dates)) return dates; |
| 3208 |
if (typeof dates === "string") { |
| 3209 |
try { |
| 3210 |
const parsed = JSON.parse(dates); |
| 3211 |
return Array.isArray(parsed) ? parsed : []; |
| 3212 |
} catch { |
| 3213 |
return []; |
| 3214 |
} |
| 3215 |
} |
| 3216 |
return []; |
| 3217 |
}; |
| 3218 |
const normalizeGalleryImages = (images) => { |
| 3219 |
if (!images) return []; |
| 3220 |
if (Array.isArray(images)) { |
| 3221 |
return images.map((img) => { |
| 3222 |
if (typeof img === "string") { |
| 3223 |
return { id: 0, url: img }; |
| 3224 |
} |
| 3225 |
if (img && typeof img === "object") { |
| 3226 |
return { |
| 3227 |
id: img.id || img.image_id || 0, |
| 3228 |
url: img.url || img.image_url || img.src || "", |
| 3229 |
thumbnail_url: img.thumbnail_url || img.thumb_url || "", |
| 3230 |
alt_text: img.alt_text || img.alt || "", |
| 3231 |
caption: img.caption || img.title || "" |
| 3232 |
}; |
| 3233 |
} |
| 3234 |
return { id: 0, url: "" }; |
| 3235 |
}).filter((item) => item.url); |
| 3236 |
} |
| 3237 |
if (typeof images === "string") { |
| 3238 |
try { |
| 3239 |
const parsed = JSON.parse(images); |
| 3240 |
return normalizeGalleryImages(parsed); |
| 3241 |
} catch { |
| 3242 |
return [{ id: 0, url: images }]; |
| 3243 |
} |
| 3244 |
} |
| 3245 |
return []; |
| 3246 |
}; |
| 3247 |
const normalizeFaqs = (faqs) => { |
| 3248 |
if (!faqs || !Array.isArray(faqs)) return []; |
| 3249 |
return faqs.map((faq) => { |
| 3250 |
if (faq && typeof faq === "object") { |
| 3251 |
return { |
| 3252 |
question: faq.question || "", |
| 3253 |
answer: faq.answer || "" |
| 3254 |
}; |
| 3255 |
} |
| 3256 |
return { question: "", answer: "" }; |
| 3257 |
}).filter((faq) => faq.question && faq.answer); |
| 3258 |
}; |
| 3259 |
reactExports.useEffect(() => { |
| 3260 |
var _a2, _b2, _c2, _d2, _e2, _f2, _g, _h, _i, _j, _k, _l, _m, _n, _o, _p, _q, _r, _s; |
| 3261 |
if (!tripData || !isEditMode) { |
| 3262 |
return; |
| 3263 |
} |
| 3264 |
const currentItineraryDays = formData.itinerary_days || []; |
| 3265 |
const currentGalleryImages = formData.gallery_images || []; |
| 3266 |
const shouldPreserveItinerary = currentItineraryDays.length > 0; |
| 3267 |
const shouldPreserveGallery = currentGalleryImages.length > 0; |
| 3268 |
setFormData({ |
| 3269 |
title: tripData.title || "", |
| 3270 |
slug: tripData.slug || "", |
| 3271 |
description: tripData.description || "", |
| 3272 |
highlights: normalizeHighlights(tripData.highlights), |
| 3273 |
trip_details: tripData.trip_details || "", |
| 3274 |
short_description: tripData.short_description || "", |
| 3275 |
what_makes_special: tripData.what_makes_special || "", |
| 3276 |
trip_story: tripData.trip_story || "", |
| 3277 |
video_url: tripData.video_url || "", |
| 3278 |
virtual_tour_url: tripData.virtual_tour_url || "", |
| 3279 |
testimonial_review_ids: Array.isArray(tripData.testimonial_review_ids) ? tripData.testimonial_review_ids : [], |
| 3280 |
destinations: extractIds(tripData.destinations || []), |
| 3281 |
starting_location: tripData.starting_location || "", |
| 3282 |
ending_location: tripData.ending_location || "", |
| 3283 |
countries: Array.isArray(tripData.countries) ? tripData.countries : [], |
| 3284 |
regions: Array.isArray(tripData.regions) ? tripData.regions : [], |
| 3285 |
starting_latitude: ((_a2 = tripData.starting_latitude) == null ? void 0 : _a2.toString()) || "", |
| 3286 |
starting_longitude: ((_b2 = tripData.starting_longitude) == null ? void 0 : _b2.toString()) || "", |
| 3287 |
ending_latitude: ((_c2 = tripData.ending_latitude) == null ? void 0 : _c2.toString()) || "", |
| 3288 |
ending_longitude: ((_d2 = tripData.ending_longitude) == null ? void 0 : _d2.toString()) || "", |
| 3289 |
landmarks: Array.isArray(tripData.landmarks) ? tripData.landmarks : [], |
| 3290 |
trip_type: tripData.trip_type || (tripData.duration_days && parseInt(((_e2 = tripData.duration_days) == null ? void 0 : _e2.toString()) || "0") === 1 ? "single_day" : "multi_day"), |
| 3291 |
duration_days: ((_f2 = tripData.duration_days) == null ? void 0 : _f2.toString()) || "", |
| 3292 |
duration_nights: ((_g = tripData.duration_nights) == null ? void 0 : _g.toString()) || "", |
| 3293 |
duration_hours: ((_h = tripData.duration_hours) == null ? void 0 : _h.toString()) || "", |
| 3294 |
available_from: tripData.available_from || "", |
| 3295 |
available_to: tripData.available_to || "", |
| 3296 |
booking_window_days: ((_i = tripData.booking_window_days) == null ? void 0 : _i.toString()) || "", |
| 3297 |
seasonal_availability: tripData.seasonal_availability || "", |
| 3298 |
best_season: tripData.best_season || "", |
| 3299 |
peak_season: tripData.peak_season || "", |
| 3300 |
off_season: tripData.off_season || "", |
| 3301 |
activity_types: extractIds(tripData.activity_types || []), |
| 3302 |
difficulty_level: ((_j = tripData.difficulty_level) == null ? void 0 : _j.toString()) || "", |
| 3303 |
trip_category: extractIds(tripData.trip_category || []), |
| 3304 |
tags: Array.isArray(tripData.tags) ? tripData.tags : [], |
| 3305 |
featured_priority: tripData.featured_priority || "none", |
| 3306 |
accommodation_type: tripData.accommodation_type || "", |
| 3307 |
meal_plan: tripData.meal_plan || "", |
| 3308 |
accommodation_details: tripData.accommodation_details || "", |
| 3309 |
transportation_included: tripData.transportation_included || false, |
| 3310 |
pickup_location: tripData.pickup_location || "", |
| 3311 |
dropoff_location: tripData.dropoff_location || "", |
| 3312 |
transportation_details: tripData.transportation_details || "", |
| 3313 |
pricing_type: tripData.pricing_type || (tripData.price_types && Array.isArray(tripData.price_types) && tripData.price_types.length > 0 ? "traveler_based" : "regular"), |
| 3314 |
original_price: ((_k = tripData.original_price) == null ? void 0 : _k.toString()) || "", |
| 3315 |
discounted_price: ((_l = tripData.discounted_price) == null ? void 0 : _l.toString()) || "", |
| 3316 |
price_types: Array.isArray(tripData.price_types) ? tripData.price_types.map((pt) => { |
| 3317 |
var _a3, _b3; |
| 3318 |
return { |
| 3319 |
category_id: Number(pt.category_id) || 0, |
| 3320 |
original_price: ((_a3 = pt.original_price) == null ? void 0 : _a3.toString()) || "", |
| 3321 |
discounted_price: ((_b3 = pt.discounted_price) == null ? void 0 : _b3.toString()) || "", |
| 3322 |
is_default: Boolean(pt.is_default) |
| 3323 |
}; |
| 3324 |
}) : [], |
| 3325 |
deposit_amount: ((_m = tripData.deposit_amount) == null ? void 0 : _m.toString()) || "", |
| 3326 |
deposit_percentage: ((_n = tripData.deposit_percentage) == null ? void 0 : _n.toString()) || "", |
| 3327 |
payment_terms: tripData.payment_terms || "", |
| 3328 |
max_travelers: ((_o = tripData.max_travelers) == null ? void 0 : _o.toString()) || "", |
| 3329 |
min_travelers: ((_p = tripData.min_travelers) == null ? void 0 : _p.toString()) || "", |
| 3330 |
booking_deadline_hours: tripData.booking_deadline_hours || "", |
| 3331 |
cancellation_policy: tripData.cancellation_policy || "", |
| 3332 |
age_min: ((_q = tripData.age_min) == null ? void 0 : _q.toString()) || "", |
| 3333 |
age_max: ((_r = tripData.age_max) == null ? void 0 : _r.toString()) || "", |
| 3334 |
physical_requirements: tripData.physical_requirements || "", |
| 3335 |
visa_requirements: tripData.visa_requirements || "", |
| 3336 |
vaccination_requirements: tripData.vaccination_requirements || "", |
| 3337 |
disable_booking: Boolean((_s = tripData.custom_fields) == null ? void 0 : _s.disable_booking), |
| 3338 |
// tinyint(1) columns can serialize from PHP/wpdb as the string "0"/"1". |
| 3339 |
// JS treats "0" as truthy, so a plain `value || false` would leave the |
| 3340 |
// checkbox stuck on after the user un-checked + saved. Coerce explicitly. |
| 3341 |
has_default_time_slots: tripData.has_default_time_slots === true || tripData.has_default_time_slots === 1 || tripData.has_default_time_slots === "1", |
| 3342 |
default_time_slots: Array.isArray(tripData.default_time_slots) ? tripData.default_time_slots : tripData.default_time_slots ? JSON.parse(tripData.default_time_slots) : [], |
| 3343 |
departure_time: tripData.departure_time || "09:00", |
| 3344 |
included_items: normalizeAmenityItems(tripData.included_items), |
| 3345 |
excluded_items: normalizeAmenityItems(tripData.excluded_items), |
| 3346 |
// Preserve current itinerary data if it exists, otherwise use database data |
| 3347 |
itinerary_days: shouldPreserveItinerary ? currentItineraryDays : normalizeItineraryDays(tripData.itinerary_days), |
| 3348 |
// Preserve current gallery data if it exists, otherwise use database data |
| 3349 |
gallery_images: shouldPreserveGallery ? currentGalleryImages : normalizeGalleryImages(tripData.gallery_images), |
| 3350 |
featured_image: tripData.featured_image ? Number(tripData.featured_image) : null, |
| 3351 |
downloadable_items: normalizeDownloadableItems( |
| 3352 |
tripData.downloadable_items |
| 3353 |
), |
| 3354 |
faqs: normalizeFaqs(tripData.faqs), |
| 3355 |
frontend_tabs: Array.isArray(tripData.frontend_tabs) ? tripData.frontend_tabs : [ |
| 3356 |
// Core sections (always present) - in logical order |
| 3357 |
{ |
| 3358 |
id: "overview", |
| 3359 |
label: "Overview", |
| 3360 |
enabled: true, |
| 3361 |
order: 1, |
| 3362 |
content_type: "overview", |
| 3363 |
icon: { type: "icon", value: "book" } |
| 3364 |
}, |
| 3365 |
{ |
| 3366 |
id: "itinerary", |
| 3367 |
label: "Itinerary", |
| 3368 |
enabled: true, |
| 3369 |
order: 2, |
| 3370 |
content_type: "itinerary", |
| 3371 |
icon: { type: "icon", value: "calendar" } |
| 3372 |
}, |
| 3373 |
{ |
| 3374 |
id: "included", |
| 3375 |
label: "Included", |
| 3376 |
enabled: true, |
| 3377 |
order: 3, |
| 3378 |
content_type: "included_excluded", |
| 3379 |
icon: { type: "icon", value: "check" } |
| 3380 |
}, |
| 3381 |
{ |
| 3382 |
id: "location", |
| 3383 |
label: "Location", |
| 3384 |
enabled: true, |
| 3385 |
order: 4, |
| 3386 |
content_type: "location", |
| 3387 |
icon: { type: "icon", value: "map-pin" } |
| 3388 |
}, |
| 3389 |
{ |
| 3390 |
id: "important_info", |
| 3391 |
label: "Important Info", |
| 3392 |
enabled: true, |
| 3393 |
order: 5, |
| 3394 |
content_type: "important_info", |
| 3395 |
icon: { type: "icon", value: "info" } |
| 3396 |
}, |
| 3397 |
// Conditional sections (enabled by default, shown conditionally on frontend) |
| 3398 |
{ |
| 3399 |
id: "downloads", |
| 3400 |
label: "Downloads", |
| 3401 |
enabled: true, |
| 3402 |
order: 6, |
| 3403 |
content_type: "downloads", |
| 3404 |
icon: { type: "icon", value: "download" } |
| 3405 |
}, |
| 3406 |
{ |
| 3407 |
id: "faq", |
| 3408 |
label: "FAQ", |
| 3409 |
enabled: true, |
| 3410 |
order: 7, |
| 3411 |
content_type: "faq", |
| 3412 |
icon: { type: "icon", value: "help-circle" } |
| 3413 |
}, |
| 3414 |
{ |
| 3415 |
id: "trip_story", |
| 3416 |
label: "Story", |
| 3417 |
enabled: true, |
| 3418 |
order: 8, |
| 3419 |
content_type: "trip_story", |
| 3420 |
custom_content: "", |
| 3421 |
icon: { type: "icon", value: "book" } |
| 3422 |
}, |
| 3423 |
{ |
| 3424 |
id: "what_makes_special", |
| 3425 |
label: "Special", |
| 3426 |
enabled: true, |
| 3427 |
order: 9, |
| 3428 |
content_type: "what_makes_special", |
| 3429 |
custom_content: "", |
| 3430 |
icon: { type: "icon", value: "star" } |
| 3431 |
}, |
| 3432 |
{ |
| 3433 |
id: "testimonials", |
| 3434 |
label: "Testimonials", |
| 3435 |
enabled: true, |
| 3436 |
order: 10, |
| 3437 |
content_type: "testimonials", |
| 3438 |
icon: { type: "icon", value: "message-circle" } |
| 3439 |
} |
| 3440 |
], |
| 3441 |
availability_dates: normalizeAvailabilityDates( |
| 3442 |
tripData.availability_dates |
| 3443 |
), |
| 3444 |
status: tripData.status || "draft", |
| 3445 |
scheduled_publish_date: tripData.scheduled_publish_date || "", |
| 3446 |
scheduled_unpublish_date: tripData.scheduled_unpublish_date || "", |
| 3447 |
version: tripData.version || 1, |
| 3448 |
seasonal_auto_enable: tripData.seasonal_auto_enable || false, |
| 3449 |
seasonal_enable_date: tripData.seasonal_enable_date || "", |
| 3450 |
seasonal_disable_date: tripData.seasonal_disable_date || "", |
| 3451 |
meta_title: tripData.meta_title || "", |
| 3452 |
meta_description: tripData.meta_description || "", |
| 3453 |
meta_keywords: tripData.meta_keywords || "", |
| 3454 |
attributes: tripAttributesData || {} |
| 3455 |
}); |
| 3456 |
if (tripData.featured_image_url && tripData.featured_image) { |
| 3457 |
const numericId = Number(tripData.featured_image) || 0; |
| 3458 |
setFeaturedImagePreview(tripData.featured_image_url); |
| 3459 |
if (numericId > 0) { |
| 3460 |
featuredImageCache.current[numericId] = tripData.featured_image_url; |
| 3461 |
} |
| 3462 |
} else if (!tripData.featured_image) { |
| 3463 |
setFeaturedImagePreview(""); |
| 3464 |
} |
| 3465 |
}, [tripData, tripAttributesData, destinationsData, isEditMode, tripId]); |
| 3466 |
reactExports.useEffect(() => { |
| 3467 |
let isMounted = true; |
| 3468 |
const resolveFeaturedImage = async () => { |
| 3469 |
const attachmentId = formData.featured_image; |
| 3470 |
if (!attachmentId) { |
| 3471 |
setFeaturedImagePreview(""); |
| 3472 |
return; |
| 3473 |
} |
| 3474 |
const cachedUrl = featuredImageCache.current[attachmentId]; |
| 3475 |
if (cachedUrl) { |
| 3476 |
setFeaturedImagePreview(cachedUrl); |
| 3477 |
return; |
| 3478 |
} |
| 3479 |
if (!mediaBaseUrl) { |
| 3480 |
setFeaturedImagePreview(""); |
| 3481 |
return; |
| 3482 |
} |
| 3483 |
setIsResolvingFeaturedImage(true); |
| 3484 |
try { |
| 3485 |
const data = await wpService.getMedia(attachmentId); |
| 3486 |
const url = (data == null ? void 0 : data.source_url) || ""; |
| 3487 |
if (url && isMounted) { |
| 3488 |
featuredImageCache.current[attachmentId] = url; |
| 3489 |
setFeaturedImagePreview(url); |
| 3490 |
} else if (isMounted) { |
| 3491 |
setFeaturedImagePreview(""); |
| 3492 |
} |
| 3493 |
} catch (error) { |
| 3494 |
console.error("Failed to resolve featured image URL:", error); |
| 3495 |
if (isMounted) { |
| 3496 |
setFeaturedImagePreview(""); |
| 3497 |
} |
| 3498 |
} finally { |
| 3499 |
if (isMounted) { |
| 3500 |
setIsResolvingFeaturedImage(false); |
| 3501 |
} |
| 3502 |
} |
| 3503 |
}; |
| 3504 |
resolveFeaturedImage(); |
| 3505 |
return () => { |
| 3506 |
isMounted = false; |
| 3507 |
}; |
| 3508 |
}, [formData.featured_image, mediaBaseUrl]); |
| 3509 |
const getSectionErrors = (sectionId) => { |
| 3510 |
const errorMap = { |
| 3511 |
basic: [ |
| 3512 |
"title", |
| 3513 |
"slug", |
| 3514 |
"description", |
| 3515 |
"featured_image", |
| 3516 |
"trip_type", |
| 3517 |
"duration_days", |
| 3518 |
"duration_nights", |
| 3519 |
"duration_hours" |
| 3520 |
], |
| 3521 |
location: ["destinations", "starting_location", "ending_location"], |
| 3522 |
duration: ["available_from", "available_to", "booking_window_days"], |
| 3523 |
pricing: ["original_price", "discounted_price", "price_types"], |
| 3524 |
booking: ["min_travelers", "max_travelers", "age_min", "age_max"], |
| 3525 |
attributes: ["attributes"], |
| 3526 |
itinerary: ["itinerary_days"], |
| 3527 |
included: ["included_items", "excluded_items"], |
| 3528 |
media: ["gallery_images", "video_url", "virtual_tour_url"], |
| 3529 |
// Removed featured_image - it's in basic section |
| 3530 |
downloads: ["downloadable_items"], |
| 3531 |
categorization: ["trip_category", "activity_types"], |
| 3532 |
faqs: ["faqs"], |
| 3533 |
seo: ["meta_title", "meta_description"], |
| 3534 |
advanced: [] |
| 3535 |
}; |
| 3536 |
const sectionFields = errorMap[sectionId] || []; |
| 3537 |
const fieldErrors = sectionFields.filter((field) => errors[field]); |
| 3538 |
if (sectionId === "pricing") { |
| 3539 |
const priceTypeErrors = Object.keys(errors).filter( |
| 3540 |
(key) => key.startsWith("price_type_") |
| 3541 |
); |
| 3542 |
return [...fieldErrors, ...priceTypeErrors]; |
| 3543 |
} |
| 3544 |
return fieldErrors; |
| 3545 |
}; |
| 3546 |
const essentialsSections = [ |
| 3547 |
// 1. Trip Basics - What you're offering |
| 3548 |
{ |
| 3549 |
id: "basic", |
| 3550 |
label: __$1("Trip Basics", "yatra"), |
| 3551 |
icon: FileText, |
| 3552 |
required: true, |
| 3553 |
completed: !!(((_a = formData.title) == null ? void 0 : _a.trim()) && ((_b = formData.slug) == null ? void 0 : _b.trim())), |
| 3554 |
hasErrors: getSectionErrors("basic").length > 0 |
| 3555 |
}, |
| 3556 |
// 2. Location & Route - Where it happens |
| 3557 |
{ |
| 3558 |
id: "location", |
| 3559 |
label: __$1("Location & Route", "yatra"), |
| 3560 |
icon: MapPin, |
| 3561 |
required: false, |
| 3562 |
completed: !!(formData.destinations.length > 0), |
| 3563 |
hasErrors: getSectionErrors("location").length > 0 |
| 3564 |
}, |
| 3565 |
// 3. Pricing - How much it costs |
| 3566 |
{ |
| 3567 |
id: "pricing", |
| 3568 |
label: __$1("Pricing", "yatra"), |
| 3569 |
icon: DollarSign, |
| 3570 |
required: true, |
| 3571 |
completed: formData.pricing_type === "regular" ? !!(formData.original_price && parseFloat(formData.original_price) > 0) : formData.price_types.some( |
| 3572 |
(pt) => pt.original_price && parseFloat(pt.original_price) > 0 |
| 3573 |
), |
| 3574 |
hasErrors: getSectionErrors("pricing").length > 0 |
| 3575 |
}, |
| 3576 |
// 4. Availability & Booking - When available + booking rules (merged duration + booking) |
| 3577 |
{ |
| 3578 |
id: "duration", |
| 3579 |
label: __$1("Availability & Booking", "yatra"), |
| 3580 |
icon: Calendar, |
| 3581 |
required: false, |
| 3582 |
completed: !!(formData.available_from || formData.available_to || formData.min_travelers && formData.max_travelers), |
| 3583 |
hasErrors: getSectionErrors("duration").length > 0 || getSectionErrors("booking").length > 0 |
| 3584 |
} |
| 3585 |
]; |
| 3586 |
const detailsSections = [ |
| 3587 |
// 5. Trip Details - Description + Itinerary + Included/Excluded (merged 3 sections) |
| 3588 |
{ |
| 3589 |
id: "itinerary", |
| 3590 |
label: __$1("Trip Details", "yatra"), |
| 3591 |
icon: BookOpen, |
| 3592 |
required: false, |
| 3593 |
completed: formData.itinerary_days.length > 0 || formData.included_items.length > 0 || formData.excluded_items.length > 0, |
| 3594 |
hasErrors: getSectionErrors("itinerary").length > 0 || getSectionErrors("included").length > 0 |
| 3595 |
} |
| 3596 |
]; |
| 3597 |
const optimizationSections = [ |
| 3598 |
// 6. Media & Gallery - Photos, videos, testimonials |
| 3599 |
{ |
| 3600 |
id: "media", |
| 3601 |
label: __$1("Media & Gallery", "yatra"), |
| 3602 |
icon: Image, |
| 3603 |
required: false, |
| 3604 |
completed: formData.gallery_images.length > 0 || !!formData.video_url, |
| 3605 |
hasErrors: getSectionErrors("media").length > 0 |
| 3606 |
}, |
| 3607 |
...[ |
| 3608 |
{ |
| 3609 |
id: "downloads", |
| 3610 |
label: __$1("Downloads", "yatra"), |
| 3611 |
icon: Download, |
| 3612 |
required: false, |
| 3613 |
completed: (formData.downloadable_items || []).length > 0, |
| 3614 |
hasErrors: getSectionErrors("downloads").length > 0 |
| 3615 |
} |
| 3616 |
], |
| 3617 |
// 7. Categories & Attributes - Classification + Custom Attributes (merged 2 sections) |
| 3618 |
{ |
| 3619 |
id: "categorization", |
| 3620 |
label: __$1("Categories & Attributes", "yatra"), |
| 3621 |
icon: Tag, |
| 3622 |
required: false, |
| 3623 |
completed: !!(formData.trip_category || formData.activity_types.length > 0 || formData.tags.length > 0 || formData.attributes && Object.keys(formData.attributes).length > 0), |
| 3624 |
hasErrors: getSectionErrors("categorization").length > 0 || getSectionErrors("attributes").length > 0 |
| 3625 |
}, |
| 3626 |
// 8. SEO & Marketing - SEO + FAQs (merged, fixed duplicate) |
| 3627 |
{ |
| 3628 |
id: "seo", |
| 3629 |
label: __$1("SEO & Marketing", "yatra"), |
| 3630 |
icon: Search, |
| 3631 |
required: false, |
| 3632 |
completed: !!(formData.meta_title || formData.meta_description || formData.faqs.length > 0), |
| 3633 |
hasErrors: getSectionErrors("seo").length > 0 || getSectionErrors("faqs").length > 0 |
| 3634 |
} |
| 3635 |
]; |
| 3636 |
const advancedSections = [ |
| 3637 |
// 9. Advanced Settings - Publishing, scheduling, technical |
| 3638 |
{ |
| 3639 |
id: "advanced", |
| 3640 |
label: __$1("Advanced Settings", "yatra"), |
| 3641 |
icon: Settings, |
| 3642 |
required: false, |
| 3643 |
completed: false, |
| 3644 |
hasErrors: false |
| 3645 |
} |
| 3646 |
]; |
| 3647 |
const allSections = [ |
| 3648 |
...essentialsSections, |
| 3649 |
...detailsSections, |
| 3650 |
...optimizationSections, |
| 3651 |
...advancedSections |
| 3652 |
]; |
| 3653 |
const currentStepIndex = allSections.findIndex( |
| 3654 |
(s) => s.id === currentSection |
| 3655 |
); |
| 3656 |
const goToNextSection = () => { |
| 3657 |
if (currentStepIndex < allSections.length - 1) { |
| 3658 |
setCurrentSection(allSections[currentStepIndex + 1].id); |
| 3659 |
} |
| 3660 |
}; |
| 3661 |
const goToPreviousSection = () => { |
| 3662 |
if (currentStepIndex > 0) { |
| 3663 |
setCurrentSection(allSections[currentStepIndex - 1].id); |
| 3664 |
} |
| 3665 |
}; |
| 3666 |
reactExports.useEffect(() => { |
| 3667 |
if (formData.duration_days && formData.trip_type === "multi_day" && (!formData.duration_nights || formData.duration_nights === "")) { |
| 3668 |
const days = parseInt(formData.duration_days); |
| 3669 |
if (days > 0 && !isNaN(days)) { |
| 3670 |
setFormData((prev) => ({ |
| 3671 |
...prev, |
| 3672 |
duration_nights: String(Math.max(0, days - 1)) |
| 3673 |
})); |
| 3674 |
} |
| 3675 |
} |
| 3676 |
}, [formData.duration_days, formData.trip_type]); |
| 3677 |
reactExports.useEffect(() => { |
| 3678 |
if (formData.duration_nights && formData.trip_type === "multi_day" && (!formData.duration_days || formData.duration_days === "")) { |
| 3679 |
const nights = parseInt(formData.duration_nights); |
| 3680 |
if (nights > 0 && !isNaN(nights)) { |
| 3681 |
setFormData((prev) => ({ ...prev, duration_days: String(nights + 1) })); |
| 3682 |
} |
| 3683 |
} |
| 3684 |
}, [formData.duration_nights, formData.trip_type]); |
| 3685 |
const generateSlug = (title) => { |
| 3686 |
return title.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, ""); |
| 3687 |
}; |
| 3688 |
const handleTitleChange = (value) => { |
| 3689 |
setFormData((prev) => ({ |
| 3690 |
...prev, |
| 3691 |
title: value, |
| 3692 |
slug: prev.slug || generateSlug(value) |
| 3693 |
})); |
| 3694 |
if (errors.title) { |
| 3695 |
setErrors((prev) => ({ ...prev, title: "" })); |
| 3696 |
} |
| 3697 |
}; |
| 3698 |
const handleFieldChange = (field, value) => { |
| 3699 |
setFormData((prev) => ({ ...prev, [field]: value })); |
| 3700 |
if (errors[field]) { |
| 3701 |
setErrors((prev) => ({ ...prev, [field]: "" })); |
| 3702 |
} |
| 3703 |
if (field === "featured_image") { |
| 3704 |
if (value === null || value === "" || value === void 0) { |
| 3705 |
setFeaturedImagePreview(""); |
| 3706 |
} else { |
| 3707 |
const numericValue = typeof value === "number" ? value : Number(value); |
| 3708 |
if (!numericValue) { |
| 3709 |
setFeaturedImagePreview(""); |
| 3710 |
} else if (featuredImageCache.current[numericValue]) { |
| 3711 |
setFeaturedImagePreview(featuredImageCache.current[numericValue]); |
| 3712 |
} |
| 3713 |
} |
| 3714 |
} |
| 3715 |
}; |
| 3716 |
const handleHighlightAdd = () => { |
| 3717 |
setShowHighlightModal(true); |
| 3718 |
setModalInput({ text: "", question: "", answer: "" }); |
| 3719 |
}; |
| 3720 |
const handleHighlightSave = () => { |
| 3721 |
if (modalInput.text && modalInput.text.trim()) { |
| 3722 |
setFormData((prev) => ({ |
| 3723 |
...prev, |
| 3724 |
highlights: [...prev.highlights, modalInput.text.trim()] |
| 3725 |
})); |
| 3726 |
setShowHighlightModal(false); |
| 3727 |
setModalInput({ text: "", question: "", answer: "" }); |
| 3728 |
} |
| 3729 |
}; |
| 3730 |
const handleHighlightRemove = (index) => { |
| 3731 |
setFormData((prev) => ({ |
| 3732 |
...prev, |
| 3733 |
highlights: prev.highlights.filter((_, i) => i !== index) |
| 3734 |
})); |
| 3735 |
}; |
| 3736 |
const handleFAQAdd = () => { |
| 3737 |
setFormData((prev) => ({ |
| 3738 |
...prev, |
| 3739 |
faqs: [...prev.faqs, { question: "", answer: "" }] |
| 3740 |
})); |
| 3741 |
}; |
| 3742 |
const handleFAQRemove = (index) => { |
| 3743 |
setFormData((prev) => ({ |
| 3744 |
...prev, |
| 3745 |
faqs: prev.faqs.filter((_, i) => i !== index) |
| 3746 |
})); |
| 3747 |
}; |
| 3748 |
const handleFAQChange = (index, field, value) => { |
| 3749 |
setFormData((prev) => ({ |
| 3750 |
...prev, |
| 3751 |
faqs: prev.faqs.map( |
| 3752 |
(faq, i) => i === index ? { ...faq, [field]: value } : faq |
| 3753 |
) |
| 3754 |
})); |
| 3755 |
}; |
| 3756 |
const handleGalleryAdd = () => { |
| 3757 |
if (window.wp && window.wp.media) { |
| 3758 |
const mediaUploader = window.wp.media({ |
| 3759 |
title: __$1("Select Gallery Images", "yatra"), |
| 3760 |
button: { text: __$1("Add to Gallery", "yatra") }, |
| 3761 |
multiple: true, |
| 3762 |
// Allow multiple image selection |
| 3763 |
library: { type: "image" } |
| 3764 |
}); |
| 3765 |
mediaUploader.on("select", () => { |
| 3766 |
const selection = mediaUploader.state().get("selection"); |
| 3767 |
const newImages = []; |
| 3768 |
selection.each((attachment) => { |
| 3769 |
var _a2, _b2, _c2, _d2; |
| 3770 |
const image = attachment.toJSON(); |
| 3771 |
if (image.url) { |
| 3772 |
newImages.push({ |
| 3773 |
id: image.id || 0, |
| 3774 |
url: image.url, |
| 3775 |
thumbnail_url: ((_b2 = (_a2 = image.sizes) == null ? void 0 : _a2.thumbnail) == null ? void 0 : _b2.url) || ((_d2 = (_c2 = image.sizes) == null ? void 0 : _c2.medium) == null ? void 0 : _d2.url) || image.url, |
| 3776 |
alt_text: image.alt || "", |
| 3777 |
caption: image.caption || "" |
| 3778 |
}); |
| 3779 |
} |
| 3780 |
}); |
| 3781 |
if (newImages.length > 0) { |
| 3782 |
setFormData((prev) => ({ |
| 3783 |
...prev, |
| 3784 |
gallery_images: [...prev.gallery_images, ...newImages] |
| 3785 |
})); |
| 3786 |
} |
| 3787 |
}); |
| 3788 |
prepareWordPressMediaFrameOpen(); |
| 3789 |
mediaUploader.open(); |
| 3790 |
} else { |
| 3791 |
showToast( |
| 3792 |
__$1( |
| 3793 |
"Media library not available. Please ensure you are logged in as admin.", |
| 3794 |
"yatra" |
| 3795 |
), |
| 3796 |
"error" |
| 3797 |
); |
| 3798 |
} |
| 3799 |
}; |
| 3800 |
const handleGalleryRemove = (index) => { |
| 3801 |
setFormData((prev) => ({ |
| 3802 |
...prev, |
| 3803 |
gallery_images: prev.gallery_images.filter((_, i) => i !== index) |
| 3804 |
})); |
| 3805 |
}; |
| 3806 |
const handleGalleryReorder = (fromIndex, toIndex) => { |
| 3807 |
setFormData((prev) => { |
| 3808 |
const newImages = [...prev.gallery_images]; |
| 3809 |
const [movedImage] = newImages.splice(fromIndex, 1); |
| 3810 |
newImages.splice(toIndex, 0, movedImage); |
| 3811 |
return { ...prev, gallery_images: newImages }; |
| 3812 |
}); |
| 3813 |
}; |
| 3814 |
const handleDownloadableItemAdd = () => { |
| 3815 |
setFormData((prev) => { |
| 3816 |
var _a2; |
| 3817 |
const nextOrder = (((_a2 = prev.downloadable_items) == null ? void 0 : _a2.length) || 0) + 1; |
| 3818 |
return { |
| 3819 |
...prev, |
| 3820 |
downloadable_items: [ |
| 3821 |
...prev.downloadable_items || [], |
| 3822 |
{ |
| 3823 |
id: null, |
| 3824 |
title: "", |
| 3825 |
description: "", |
| 3826 |
attachment_id: null, |
| 3827 |
attachment_url: "", |
| 3828 |
attachment_title: "", |
| 3829 |
visibility: "booked_only", |
| 3830 |
enabled: true, |
| 3831 |
sort_order: nextOrder |
| 3832 |
} |
| 3833 |
] |
| 3834 |
}; |
| 3835 |
}); |
| 3836 |
}; |
| 3837 |
const handleDownloadableItemRemove = (index) => { |
| 3838 |
setFormData((prev) => ({ |
| 3839 |
...prev, |
| 3840 |
downloadable_items: (prev.downloadable_items || []).filter( |
| 3841 |
(_, i) => i !== index |
| 3842 |
) |
| 3843 |
})); |
| 3844 |
}; |
| 3845 |
const handleDownloadableItemMove = (fromIndex, toIndex) => { |
| 3846 |
setFormData((prev) => { |
| 3847 |
const items = [...prev.downloadable_items || []]; |
| 3848 |
const [moved] = items.splice(fromIndex, 1); |
| 3849 |
items.splice(toIndex, 0, moved); |
| 3850 |
const normalized = items.map((item, idx) => ({ |
| 3851 |
...item, |
| 3852 |
sort_order: idx + 1 |
| 3853 |
})); |
| 3854 |
return { ...prev, downloadable_items: normalized }; |
| 3855 |
}); |
| 3856 |
}; |
| 3857 |
const handleDownloadableItemChange = (index, field, value) => { |
| 3858 |
setFormData((prev) => ({ |
| 3859 |
...prev, |
| 3860 |
downloadable_items: (prev.downloadable_items || []).map( |
| 3861 |
(item, i) => i === index ? { ...item, [field]: value } : item |
| 3862 |
) |
| 3863 |
})); |
| 3864 |
}; |
| 3865 |
const handleDownloadableItemSelectFile = (index) => { |
| 3866 |
if (window.wp && window.wp.media) { |
| 3867 |
const mediaUploader = window.wp.media({ |
| 3868 |
title: __$1("Select File", "yatra"), |
| 3869 |
button: { text: __$1("Use this file", "yatra") }, |
| 3870 |
multiple: false |
| 3871 |
}); |
| 3872 |
mediaUploader.on("select", () => { |
| 3873 |
const selection = mediaUploader.state().get("selection"); |
| 3874 |
const attachment = selection.first(); |
| 3875 |
if (!attachment) return; |
| 3876 |
const file = attachment.toJSON(); |
| 3877 |
handleDownloadableItemChange(index, "attachment_id", file.id || null); |
| 3878 |
handleDownloadableItemChange(index, "attachment_url", file.url || ""); |
| 3879 |
handleDownloadableItemChange( |
| 3880 |
index, |
| 3881 |
"attachment_title", |
| 3882 |
file.title || file.filename || "" |
| 3883 |
); |
| 3884 |
}); |
| 3885 |
prepareWordPressMediaFrameOpen(); |
| 3886 |
mediaUploader.open(); |
| 3887 |
} else { |
| 3888 |
showToast( |
| 3889 |
__$1( |
| 3890 |
"Media library not available. Please ensure you are logged in as admin.", |
| 3891 |
"yatra" |
| 3892 |
), |
| 3893 |
"error" |
| 3894 |
); |
| 3895 |
} |
| 3896 |
}; |
| 3897 |
const handlePriceTypeAdd = (categoryId) => { |
| 3898 |
if (formData.price_types.some( |
| 3899 |
(pt) => Number(pt.category_id) === Number(categoryId) |
| 3900 |
)) { |
| 3901 |
showToast( |
| 3902 |
__$1("This category already has pricing set", "yatra"), |
| 3903 |
"warning" |
| 3904 |
); |
| 3905 |
return; |
| 3906 |
} |
| 3907 |
setFormData((prev) => ({ |
| 3908 |
...prev, |
| 3909 |
price_types: [ |
| 3910 |
...prev.price_types, |
| 3911 |
{ |
| 3912 |
category_id: categoryId, |
| 3913 |
original_price: "", |
| 3914 |
discounted_price: "", |
| 3915 |
is_default: false |
| 3916 |
} |
| 3917 |
] |
| 3918 |
})); |
| 3919 |
}; |
| 3920 |
const handlePriceTypeRemove = (categoryId) => { |
| 3921 |
setFormData((prev) => ({ |
| 3922 |
...prev, |
| 3923 |
price_types: prev.price_types.filter( |
| 3924 |
(pt) => Number(pt.category_id) !== Number(categoryId) |
| 3925 |
) |
| 3926 |
})); |
| 3927 |
}; |
| 3928 |
const handlePriceTypeChange = (categoryId, field, value) => { |
| 3929 |
setFormData((prev) => ({ |
| 3930 |
...prev, |
| 3931 |
price_types: prev.price_types.map( |
| 3932 |
(pt) => Number(pt.category_id) === Number(categoryId) ? { ...pt, [field]: value } : pt |
| 3933 |
) |
| 3934 |
})); |
| 3935 |
}; |
| 3936 |
const handlePriceTypeDefaultChange = (categoryId, isDefault) => { |
| 3937 |
setFormData((prev) => ({ |
| 3938 |
...prev, |
| 3939 |
price_types: prev.price_types.map((pt) => { |
| 3940 |
if (Number(pt.category_id) === Number(categoryId)) { |
| 3941 |
return { ...pt, is_default: isDefault }; |
| 3942 |
} |
| 3943 |
return isDefault ? { ...pt, is_default: false } : pt; |
| 3944 |
}) |
| 3945 |
})); |
| 3946 |
}; |
| 3947 |
const handleTabToggle = (tabId) => { |
| 3948 |
setFormData((prev) => ({ |
| 3949 |
...prev, |
| 3950 |
frontend_tabs: prev.frontend_tabs.map( |
| 3951 |
(tab) => tab.id === tabId ? { ...tab, enabled: !tab.enabled } : tab |
| 3952 |
) |
| 3953 |
})); |
| 3954 |
}; |
| 3955 |
const handleFillDummyData = () => { |
| 3956 |
const nextIndex = (dummyDataIndex + 1) % dummyTripsData.length; |
| 3957 |
setDummyDataIndex(nextIndex); |
| 3958 |
const dummyData = dummyTripsData[nextIndex]; |
| 3959 |
setFormData({ |
| 3960 |
...dummyData, |
| 3961 |
// Ensure arrays are properly set |
| 3962 |
destinations: dummyData.destinations || [], |
| 3963 |
activity_types: dummyData.activity_types || [], |
| 3964 |
price_types: dummyData.price_types || [], |
| 3965 |
included_items: dummyData.included_items || [], |
| 3966 |
excluded_items: dummyData.excluded_items || [], |
| 3967 |
highlights: dummyData.highlights || [], |
| 3968 |
faqs: dummyData.faqs || [], |
| 3969 |
gallery_images: dummyData.gallery_images || [], |
| 3970 |
itinerary_days: dummyData.itinerary_days || [], |
| 3971 |
tags: dummyData.tags || [], |
| 3972 |
testimonial_review_ids: dummyData.testimonial_review_ids || [], |
| 3973 |
countries: dummyData.countries || [], |
| 3974 |
regions: dummyData.regions || [], |
| 3975 |
landmarks: dummyData.landmarks || [], |
| 3976 |
availability_dates: dummyData.availability_dates || [], |
| 3977 |
frontend_tabs: dummyData.frontend_tabs || [], |
| 3978 |
has_default_time_slots: dummyData.has_default_time_slots || false, |
| 3979 |
default_time_slots: dummyData.default_time_slots || [], |
| 3980 |
departure_time: dummyData.departure_time || "09:00", |
| 3981 |
downloadable_items: dummyData.downloadable_items || [] |
| 3982 |
}); |
| 3983 |
showToast( |
| 3984 |
__$1("Dummy data filled", "yatra") + ` (${nextIndex + 1}/${dummyTripsData.length})`, |
| 3985 |
"success" |
| 3986 |
); |
| 3987 |
}; |
| 3988 |
const handleTabLabelChange = (tabId, label) => { |
| 3989 |
setFormData((prev) => ({ |
| 3990 |
...prev, |
| 3991 |
frontend_tabs: prev.frontend_tabs.map( |
| 3992 |
(tab) => tab.id === tabId ? { ...tab, label } : tab |
| 3993 |
) |
| 3994 |
})); |
| 3995 |
}; |
| 3996 |
const handleTabMove = (tabId, direction) => { |
| 3997 |
setFormData((prev) => { |
| 3998 |
const tabs = [...prev.frontend_tabs]; |
| 3999 |
const index = tabs.findIndex((t) => t.id === tabId); |
| 4000 |
if (index === -1) return prev; |
| 4001 |
const newIndex = direction === "up" ? index - 1 : index + 1; |
| 4002 |
if (newIndex < 0 || newIndex >= tabs.length) return prev; |
| 4003 |
[tabs[index], tabs[newIndex]] = [tabs[newIndex], tabs[index]]; |
| 4004 |
tabs.forEach((tab, i) => { |
| 4005 |
tab.order = i + 1; |
| 4006 |
}); |
| 4007 |
return { ...prev, frontend_tabs: tabs }; |
| 4008 |
}); |
| 4009 |
}; |
| 4010 |
const handleTabRemove = (tabId) => { |
| 4011 |
setFormData((prev) => ({ |
| 4012 |
...prev, |
| 4013 |
frontend_tabs: prev.frontend_tabs.filter((tab) => tab.id !== tabId).map((tab, i) => ({ ...tab, order: i + 1 })) |
| 4014 |
})); |
| 4015 |
}; |
| 4016 |
const handleTabAdd = () => { |
| 4017 |
const newTabId = `custom_${Date.now()}`; |
| 4018 |
const maxOrder = Math.max(...formData.frontend_tabs.map((t) => t.order), 0); |
| 4019 |
setFormData((prev) => ({ |
| 4020 |
...prev, |
| 4021 |
frontend_tabs: [ |
| 4022 |
...prev.frontend_tabs, |
| 4023 |
{ |
| 4024 |
id: newTabId, |
| 4025 |
label: __$1("New Tab", "yatra"), |
| 4026 |
enabled: true, |
| 4027 |
order: maxOrder + 1, |
| 4028 |
content_type: "custom", |
| 4029 |
custom_content: "" |
| 4030 |
} |
| 4031 |
] |
| 4032 |
})); |
| 4033 |
}; |
| 4034 |
const handleTabContentTypeChange = (tabId, contentType) => { |
| 4035 |
setFormData((prev) => ({ |
| 4036 |
...prev, |
| 4037 |
frontend_tabs: prev.frontend_tabs.map( |
| 4038 |
(tab) => tab.id === tabId ? { ...tab, content_type: contentType } : tab |
| 4039 |
) |
| 4040 |
})); |
| 4041 |
}; |
| 4042 |
const handleTabCustomContentChange = (tabId, content) => { |
| 4043 |
setFormData((prev) => ({ |
| 4044 |
...prev, |
| 4045 |
frontend_tabs: prev.frontend_tabs.map( |
| 4046 |
(tab) => tab.id === tabId ? { ...tab, custom_content: content } : tab |
| 4047 |
) |
| 4048 |
})); |
| 4049 |
}; |
| 4050 |
const handleTabIconChange = (tabId, icon) => { |
| 4051 |
setFormData((prev) => ({ |
| 4052 |
...prev, |
| 4053 |
frontend_tabs: prev.frontend_tabs.map( |
| 4054 |
(tab) => tab.id === tabId ? { ...tab, icon } : tab |
| 4055 |
) |
| 4056 |
})); |
| 4057 |
}; |
| 4058 |
const [draggedTab, setDraggedTab] = reactExports.useState(null); |
| 4059 |
const [dragOverTab, setDragOverTab] = reactExports.useState(null); |
| 4060 |
const handleDragStart = (e, tabId) => { |
| 4061 |
setDraggedTab(tabId); |
| 4062 |
e.dataTransfer.effectAllowed = "move"; |
| 4063 |
}; |
| 4064 |
const handleDragOver = (e) => { |
| 4065 |
e.preventDefault(); |
| 4066 |
e.dataTransfer.dropEffect = "move"; |
| 4067 |
}; |
| 4068 |
const handleDragEnter = (tabId) => { |
| 4069 |
setDragOverTab(tabId); |
| 4070 |
}; |
| 4071 |
const handleDragLeave = () => { |
| 4072 |
setDragOverTab(null); |
| 4073 |
}; |
| 4074 |
const handleDrop = (e, targetTabId) => { |
| 4075 |
e.preventDefault(); |
| 4076 |
setDragOverTab(null); |
| 4077 |
if (!draggedTab || draggedTab === targetTabId) { |
| 4078 |
setDraggedTab(null); |
| 4079 |
return; |
| 4080 |
} |
| 4081 |
setFormData((prev) => { |
| 4082 |
const tabs = [...prev.frontend_tabs]; |
| 4083 |
const draggedIndex = tabs.findIndex((t) => t.id === draggedTab); |
| 4084 |
const targetIndex = tabs.findIndex((t) => t.id === targetTabId); |
| 4085 |
if (draggedIndex === -1 || targetIndex === -1) { |
| 4086 |
return prev; |
| 4087 |
} |
| 4088 |
const [draggedTabObj] = tabs.splice(draggedIndex, 1); |
| 4089 |
tabs.splice(targetIndex, 0, draggedTabObj); |
| 4090 |
tabs.forEach((tab, i) => { |
| 4091 |
tab.order = i + 1; |
| 4092 |
}); |
| 4093 |
return { ...prev, frontend_tabs: tabs }; |
| 4094 |
}); |
| 4095 |
setDraggedTab(null); |
| 4096 |
}; |
| 4097 |
const handleDragEnd = () => { |
| 4098 |
setDraggedTab(null); |
| 4099 |
setDragOverTab(null); |
| 4100 |
}; |
| 4101 |
const buildEssentialFieldErrors = () => { |
| 4102 |
const newErrors = {}; |
| 4103 |
if (!formData.title.trim()) { |
| 4104 |
newErrors.title = __$1("Title is required", "yatra"); |
| 4105 |
} |
| 4106 |
if (!formData.slug.trim()) { |
| 4107 |
newErrors.slug = __$1("Slug is required", "yatra"); |
| 4108 |
} else if (!/^[\p{L}\p{N}-]+$/u.test(formData.slug)) { |
| 4109 |
newErrors.slug = __$1( |
| 4110 |
"Slug can only contain letters, numbers, and hyphens", |
| 4111 |
"yatra" |
| 4112 |
); |
| 4113 |
} |
| 4114 |
return newErrors; |
| 4115 |
}; |
| 4116 |
const validateForm = () => { |
| 4117 |
const newErrors = buildEssentialFieldErrors(); |
| 4118 |
setErrors(newErrors); |
| 4119 |
return Object.keys(newErrors).length === 0; |
| 4120 |
}; |
| 4121 |
const saveMutation = useMutation({ |
| 4122 |
mutationFn: async (data) => { |
| 4123 |
const payload = { |
| 4124 |
title: data.title.trim(), |
| 4125 |
slug: data.slug.trim(), |
| 4126 |
description: data.description.trim(), |
| 4127 |
short_description: data.short_description.trim(), |
| 4128 |
highlights: data.highlights, |
| 4129 |
trip_details: data.trip_details.trim(), |
| 4130 |
what_makes_special: data.what_makes_special.trim(), |
| 4131 |
trip_story: data.trip_story.trim(), |
| 4132 |
video_url: data.video_url.trim(), |
| 4133 |
virtual_tour_url: data.virtual_tour_url.trim(), |
| 4134 |
testimonial_review_ids: Array.isArray(data.testimonial_review_ids) ? data.testimonial_review_ids.filter( |
| 4135 |
(id) => id !== null && id !== void 0 && id > 0 |
| 4136 |
) : [], |
| 4137 |
destinations: data.destinations || [], |
| 4138 |
// Array of destination IDs |
| 4139 |
starting_location: data.starting_location.trim(), |
| 4140 |
ending_location: data.ending_location.trim(), |
| 4141 |
countries: data.countries || [], |
| 4142 |
regions: data.regions || [], |
| 4143 |
starting_latitude: data.starting_latitude ? parseFloat(data.starting_latitude) : null, |
| 4144 |
starting_longitude: data.starting_longitude ? parseFloat(data.starting_longitude) : null, |
| 4145 |
ending_latitude: data.ending_latitude ? parseFloat(data.ending_latitude) : null, |
| 4146 |
ending_longitude: data.ending_longitude ? parseFloat(data.ending_longitude) : null, |
| 4147 |
landmarks: data.landmarks || [], |
| 4148 |
trip_type: data.trip_type, |
| 4149 |
duration_days: data.duration_days ? parseInt(data.duration_days) : null, |
| 4150 |
duration_nights: data.duration_nights ? parseInt(data.duration_nights) : null, |
| 4151 |
available_from: data.available_from || null, |
| 4152 |
available_to: data.available_to || null, |
| 4153 |
booking_window_days: data.booking_window_days ? parseInt(data.booking_window_days) : null, |
| 4154 |
seasonal_availability: data.seasonal_availability || "", |
| 4155 |
best_season: data.best_season.trim(), |
| 4156 |
peak_season: data.peak_season.trim(), |
| 4157 |
off_season: data.off_season.trim(), |
| 4158 |
activity_types: data.activity_types || [], |
| 4159 |
// Array of activity IDs |
| 4160 |
difficulty_level: parseInt(data.difficulty_level) || null, |
| 4161 |
trip_category: (() => { |
| 4162 |
const rawCategories = data.trip_category || []; |
| 4163 |
if (tripCategories.length === 0) { |
| 4164 |
return rawCategories; |
| 4165 |
} |
| 4166 |
const validCategories = rawCategories.filter((_catId) => { |
| 4167 |
return true; |
| 4168 |
}); |
| 4169 |
return validCategories; |
| 4170 |
})(), |
| 4171 |
tags: data.tags || [], |
| 4172 |
accommodation_type: data.accommodation_type || "", |
| 4173 |
meal_plan: data.meal_plan || "", |
| 4174 |
accommodation_details: data.accommodation_details.trim(), |
| 4175 |
transportation_included: data.transportation_included || false, |
| 4176 |
pickup_location: data.pickup_location.trim(), |
| 4177 |
dropoff_location: data.dropoff_location.trim(), |
| 4178 |
transportation_details: data.transportation_details.trim(), |
| 4179 |
pricing_type: data.pricing_type, |
| 4180 |
original_price: data.pricing_type === "regular" ? data.original_price ? parseFloat(data.original_price) : null : null, |
| 4181 |
discounted_price: data.pricing_type === "regular" ? data.discounted_price ? parseFloat(data.discounted_price) : null : null, |
| 4182 |
price_types: data.pricing_type === "traveler_based" ? data.price_types.map((pt) => ({ |
| 4183 |
category_id: pt.category_id, |
| 4184 |
is_default: Boolean(pt.is_default), |
| 4185 |
original_price: pt.original_price ? parseFloat(pt.original_price) : null, |
| 4186 |
discounted_price: pt.discounted_price ? parseFloat(pt.discounted_price) : null |
| 4187 |
})) : [], |
| 4188 |
deposit_amount: data.deposit_amount ? parseFloat(data.deposit_amount) : null, |
| 4189 |
deposit_percentage: data.deposit_percentage ? parseFloat(data.deposit_percentage) : null, |
| 4190 |
payment_terms: data.payment_terms.trim(), |
| 4191 |
max_travelers: data.max_travelers ? parseInt(data.max_travelers) : null, |
| 4192 |
min_travelers: data.min_travelers ? parseInt(data.min_travelers) : null, |
| 4193 |
booking_deadline_hours: data.booking_deadline_hours || null, |
| 4194 |
cancellation_policy: data.cancellation_policy || "", |
| 4195 |
custom_fields: { disable_booking: data.disable_booking }, |
| 4196 |
age_min: data.age_min ? parseInt(data.age_min) : null, |
| 4197 |
age_max: data.age_max ? parseInt(data.age_max) : null, |
| 4198 |
physical_requirements: data.physical_requirements.trim(), |
| 4199 |
visa_requirements: data.visa_requirements.trim(), |
| 4200 |
vaccination_requirements: data.vaccination_requirements.trim(), |
| 4201 |
has_default_time_slots: data.has_default_time_slots || false, |
| 4202 |
default_time_slots: JSON.stringify(data.default_time_slots || []), |
| 4203 |
departure_time: data.departure_time || "09:00", |
| 4204 |
included_items: (data.included_items || []).map((item) => { |
| 4205 |
var _a2, _b2; |
| 4206 |
return { |
| 4207 |
title: ((_a2 = item.title) == null ? void 0 : _a2.trim()) || "", |
| 4208 |
description: ((_b2 = item.description) == null ? void 0 : _b2.trim()) || "" |
| 4209 |
}; |
| 4210 |
}).filter((item) => item.title), |
| 4211 |
excluded_items: (data.excluded_items || []).map((item) => { |
| 4212 |
var _a2, _b2; |
| 4213 |
return { |
| 4214 |
title: ((_a2 = item.title) == null ? void 0 : _a2.trim()) || "", |
| 4215 |
description: ((_b2 = item.description) == null ? void 0 : _b2.trim()) || "" |
| 4216 |
}; |
| 4217 |
}).filter((item) => item.title), |
| 4218 |
itinerary_days: data.itinerary_days || [], |
| 4219 |
gallery_images: data.gallery_images || [], |
| 4220 |
featured_image: data.featured_image ?? null, |
| 4221 |
faqs: data.faqs || [], |
| 4222 |
frontend_tabs: data.frontend_tabs.map((tab) => ({ |
| 4223 |
id: tab.id, |
| 4224 |
label: tab.label, |
| 4225 |
enabled: tab.enabled, |
| 4226 |
order: tab.order, |
| 4227 |
content_type: tab.content_type, |
| 4228 |
custom_content: tab.custom_content || null, |
| 4229 |
icon: tab.icon || null |
| 4230 |
})), |
| 4231 |
availability_dates: data.availability_dates.map((avail) => ({ |
| 4232 |
id: avail.id, |
| 4233 |
departure_date: avail.departure_date || null, |
| 4234 |
arrival_date: avail.arrival_date || null, |
| 4235 |
seats_remaining: avail.seats_remaining || null, |
| 4236 |
original_price: avail.original_price ? parseFloat(avail.original_price) : null, |
| 4237 |
discounted_price: avail.discounted_price ? parseFloat(avail.discounted_price) : null, |
| 4238 |
discount_percentage: avail.discount_percentage ? parseFloat(avail.discount_percentage) : null, |
| 4239 |
status: avail.status || "available", |
| 4240 |
from_location: avail.from_location || null, |
| 4241 |
to_location: avail.to_location || null, |
| 4242 |
from_latitude: avail.from_latitude || null, |
| 4243 |
from_longitude: avail.from_longitude || null, |
| 4244 |
to_latitude: avail.to_latitude || null, |
| 4245 |
to_longitude: avail.to_longitude || null |
| 4246 |
})), |
| 4247 |
status: data.status === "publish" ? "publish" : "draft", |
| 4248 |
scheduled_publish_date: data.scheduled_publish_date || null, |
| 4249 |
scheduled_unpublish_date: data.scheduled_unpublish_date || null, |
| 4250 |
version: data.version || 1, |
| 4251 |
seasonal_auto_enable: data.seasonal_auto_enable || false, |
| 4252 |
seasonal_enable_date: data.seasonal_enable_date || null, |
| 4253 |
seasonal_disable_date: data.seasonal_disable_date || null, |
| 4254 |
meta_title: data.meta_title || "", |
| 4255 |
meta_description: data.meta_description || "", |
| 4256 |
meta_keywords: data.meta_keywords || "", |
| 4257 |
attributes: data.attributes || {}, |
| 4258 |
featured_priority: data.featured_priority |
| 4259 |
}; |
| 4260 |
{ |
| 4261 |
payload.downloadable_items = (data.downloadable_items || []).map((item, idx) => ({ |
| 4262 |
id: item.id ?? null, |
| 4263 |
title: (item.title || "").trim(), |
| 4264 |
description: item.description || "", |
| 4265 |
attachment_id: item.attachment_id ?? null, |
| 4266 |
visibility: item.visibility || "booked_only", |
| 4267 |
enabled: item.enabled !== false, |
| 4268 |
sort_order: item.sort_order != null ? item.sort_order : idx + 1, |
| 4269 |
attachment_url: item.attachment_url || "", |
| 4270 |
attachment_title: item.attachment_title || "", |
| 4271 |
// Prefixed keys (requested) |
| 4272 |
download_title: (item.title || "").trim(), |
| 4273 |
download_description: item.description || "", |
| 4274 |
download_visibility: item.visibility || "booked_only", |
| 4275 |
download_enabled: item.enabled !== false, |
| 4276 |
download_file: item.attachment_id ?? null |
| 4277 |
})).filter((item) => item.title); |
| 4278 |
} |
| 4279 |
if (isEditMode && tripId) { |
| 4280 |
const response = await apiClient.put(`/trips/${tripId}`, payload); |
| 4281 |
return response.data || response; |
| 4282 |
} else { |
| 4283 |
const response = await apiClient.post("/trips", payload); |
| 4284 |
return response.data || response; |
| 4285 |
} |
| 4286 |
}, |
| 4287 |
onSuccess: (data, variables) => { |
| 4288 |
queryClient.invalidateQueries({ queryKey: ["trips"] }); |
| 4289 |
queryClient.invalidateQueries({ queryKey: ["trip", tripId] }); |
| 4290 |
queryClient.refetchQueries({ queryKey: ["trip", tripId] }); |
| 4291 |
setIsSubmitting(false); |
| 4292 |
let successMessage; |
| 4293 |
if (isEditMode) { |
| 4294 |
successMessage = variables.status === "publish" ? __$1("Trip updated and published successfully", "yatra") : __$1("Trip updated successfully", "yatra"); |
| 4295 |
} else { |
| 4296 |
successMessage = variables.status === "publish" ? __$1("Trip created and published successfully", "yatra") : __$1("Trip saved as draft successfully", "yatra"); |
| 4297 |
} |
| 4298 |
showToast(successMessage, "success"); |
| 4299 |
if (!isEditMode && (data == null ? void 0 : data.id)) { |
| 4300 |
setTimeout(() => { |
| 4301 |
var _a2; |
| 4302 |
window.location.href = `${((_a2 = window.yatraAdmin) == null ? void 0 : _a2.siteUrl) || ""}/wp-admin/admin.php?page=yatra&subpage=trips&action=edit&id=${data.id}`; |
| 4303 |
}, 1e3); |
| 4304 |
} |
| 4305 |
}, |
| 4306 |
onError: (error) => { |
| 4307 |
var _a2, _b2; |
| 4308 |
const errorMessage = ((_b2 = (_a2 = error == null ? void 0 : error.response) == null ? void 0 : _a2.data) == null ? void 0 : _b2.message) || (error == null ? void 0 : error.message) || __$1("An error occurred while saving", "yatra"); |
| 4309 |
showToast(errorMessage, "error"); |
| 4310 |
setErrors({ submit: errorMessage }); |
| 4311 |
setIsSubmitting(false); |
| 4312 |
} |
| 4313 |
}); |
| 4314 |
const validateDraft = () => { |
| 4315 |
const newErrors = buildEssentialFieldErrors(); |
| 4316 |
setErrors(newErrors); |
| 4317 |
return Object.keys(newErrors).length === 0; |
| 4318 |
}; |
| 4319 |
const handleSaveDraft = async () => { |
| 4320 |
if (!validateDraft()) { |
| 4321 |
showToast( |
| 4322 |
__$1("Please add a trip title and URL before saving.", "yatra"), |
| 4323 |
"error" |
| 4324 |
); |
| 4325 |
return; |
| 4326 |
} |
| 4327 |
setIsSubmitting(true); |
| 4328 |
saveMutation.mutate({ ...formData, status: "draft" }); |
| 4329 |
}; |
| 4330 |
const handlePublish = async () => { |
| 4331 |
if (!validateForm()) { |
| 4332 |
const firstError = Object.keys(errors)[0]; |
| 4333 |
if (firstError) { |
| 4334 |
showToast( |
| 4335 |
__$1("Trip title and slug are required before publishing.", "yatra"), |
| 4336 |
"error" |
| 4337 |
); |
| 4338 |
const errorElement = document.querySelector( |
| 4339 |
`[name="${firstError}"], #${firstError}` |
| 4340 |
); |
| 4341 |
if (errorElement) { |
| 4342 |
errorElement.scrollIntoView({ behavior: "smooth", block: "center" }); |
| 4343 |
} |
| 4344 |
} |
| 4345 |
return; |
| 4346 |
} |
| 4347 |
setIsSubmitting(true); |
| 4348 |
saveMutation.mutate({ ...formData, status: "publish" }); |
| 4349 |
}; |
| 4350 |
reactExports.useEffect(() => { |
| 4351 |
const onKeyDown = (e) => { |
| 4352 |
if (e.key !== "Enter" || e.shiftKey || e.ctrlKey || e.metaKey || e.altKey) |
| 4353 |
return; |
| 4354 |
const target = e.target; |
| 4355 |
if (!target) return; |
| 4356 |
const tag = target.tagName.toLowerCase(); |
| 4357 |
const isTextarea = tag === "textarea"; |
| 4358 |
const isButton = tag === "button"; |
| 4359 |
const isLink = tag === "a"; |
| 4360 |
const isContentEditable = target.getAttribute("contenteditable") === "true"; |
| 4361 |
if (isTextarea || isButton || isLink || isContentEditable) return; |
| 4362 |
const inputType = target.type; |
| 4363 |
if (["submit", "button", "file"].includes(inputType)) return; |
| 4364 |
e.preventDefault(); |
| 4365 |
if (!isSubmitting) { |
| 4366 |
handlePublish(); |
| 4367 |
} |
| 4368 |
}; |
| 4369 |
window.addEventListener("keydown", onKeyDown); |
| 4370 |
return () => window.removeEventListener("keydown", onKeyDown); |
| 4371 |
}, [isSubmitting, handlePublish]); |
| 4372 |
const revisions = dummyRevisions; |
| 4373 |
const handlePreview = async () => { |
| 4374 |
var _a2; |
| 4375 |
const slug = (formData.slug || "").trim(); |
| 4376 |
if (!slug) { |
| 4377 |
showToast( |
| 4378 |
__$1( |
| 4379 |
"Trip slug is missing. Please add a slug before previewing.", |
| 4380 |
"yatra" |
| 4381 |
), |
| 4382 |
"error" |
| 4383 |
); |
| 4384 |
return; |
| 4385 |
} |
| 4386 |
const siteUrl = ((_a2 = window == null ? void 0 : window.yatraAdmin) == null ? void 0 : _a2.siteUrl) || ""; |
| 4387 |
const { plainUrl, prettyUrl } = buildYatraSinglePublicUrls({ |
| 4388 |
entity: "trip", |
| 4389 |
slug, |
| 4390 |
siteUrl, |
| 4391 |
bases: settingsData |
| 4392 |
}); |
| 4393 |
if (isWordPressPlainPermalink()) { |
| 4394 |
window.open(plainUrl, "_blank", "noopener,noreferrer"); |
| 4395 |
return; |
| 4396 |
} |
| 4397 |
let apiPermalink = (tripData == null ? void 0 : tripData.permalink) || (tripData == null ? void 0 : tripData.url); |
| 4398 |
if (!apiPermalink && tripId) { |
| 4399 |
try { |
| 4400 |
const detail = await apiClient.get(`/trips/${tripId}`); |
| 4401 |
apiPermalink = (detail == null ? void 0 : detail.permalink) || (detail == null ? void 0 : detail.url) || apiPermalink; |
| 4402 |
} catch (error) { |
| 4403 |
} |
| 4404 |
} |
| 4405 |
if (apiPermalink) { |
| 4406 |
window.open(apiPermalink, "_blank", "noopener,noreferrer"); |
| 4407 |
return; |
| 4408 |
} |
| 4409 |
window.open(prettyUrl, "_blank", "noopener,noreferrer"); |
| 4410 |
}; |
| 4411 |
const handleRevisionClick = (revisionId) => { |
| 4412 |
setSelectedRevisionId(revisionId); |
| 4413 |
setShowRevisionConfirm(true); |
| 4414 |
}; |
| 4415 |
const handleRevisionConfirm = () => { |
| 4416 |
if (selectedRevisionId) { |
| 4417 |
showToast(__$1("Revision feature is coming soon", "yatra"), "info"); |
| 4418 |
} |
| 4419 |
setShowRevisionConfirm(false); |
| 4420 |
setShowRevisionsDialog(false); |
| 4421 |
setSelectedRevisionId(null); |
| 4422 |
}; |
| 4423 |
if (isEditMode && isLoadingTrip) { |
| 4424 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-h-0 flex flex-col bg-white dark:bg-gray-900 overflow-hidden", children: [ |
| 4425 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-white dark:bg-gray-900 border-b border-gray-200 dark:border-gray-800 px-6 py-4 flex items-center justify-between", children: [ |
| 4426 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-4 min-w-0 flex-1", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [ |
| 4427 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-6 w-64 bg-gray-200 dark:bg-gray-700 rounded animate-pulse mb-2" }), |
| 4428 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [ |
| 4429 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-5 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }), |
| 4430 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-6 w-28 bg-gray-200 dark:bg-gray-700 rounded-full animate-pulse" }) |
| 4431 |
] }) |
| 4432 |
] }) }), |
| 4433 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ |
| 4434 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-9 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }), |
| 4435 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-9 w-24 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }), |
| 4436 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-9 w-32 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }), |
| 4437 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-9 w-36 bg-blue-200 dark:bg-blue-800 rounded animate-pulse" }) |
| 4438 |
] }) |
| 4439 |
] }), |
| 4440 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-gray-50 dark:bg-gray-800/50 border-b border-gray-200 dark:border-gray-700 px-4 py-2.5", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-4", children: [ |
| 4441 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-9 w-24 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }), |
| 4442 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 flex flex-col items-center gap-1 max-w-md mx-4", children: [ |
| 4443 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-3 w-24 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }), |
| 4444 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-full h-1.5 bg-gray-200 dark:bg-gray-700 rounded-full animate-pulse" }), |
| 4445 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-2.5 w-32 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }) |
| 4446 |
] }), |
| 4447 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-9 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }) |
| 4448 |
] }) }), |
| 4449 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 flex overflow-hidden", children: [ |
| 4450 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-80 bg-gray-50 dark:bg-gray-900 border-r border-gray-200 dark:border-gray-800 overflow-y-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-5 pb-8 space-y-6", children: [ |
| 4451 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 4452 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-3.5 w-24 bg-gray-200 dark:bg-gray-700 rounded animate-pulse mb-3 px-1" }), |
| 4453 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-0.5", children: [...Array(8)].map((_, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 4454 |
"div", |
| 4455 |
{ |
| 4456 |
className: "flex items-center gap-2 px-3 py-2.5 rounded-md", |
| 4457 |
children: [ |
| 4458 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-4 h-4 bg-gray-200 dark:bg-gray-700 rounded animate-pulse flex-shrink-0" }), |
| 4459 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 flex-1 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }) |
| 4460 |
] |
| 4461 |
}, |
| 4462 |
`essentials-${i}` |
| 4463 |
)) }) |
| 4464 |
] }), |
| 4465 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 4466 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-3.5 w-28 bg-gray-200 dark:bg-gray-700 rounded animate-pulse mb-3 px-1" }), |
| 4467 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-0.5", children: [...Array(9)].map((_, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 4468 |
"div", |
| 4469 |
{ |
| 4470 |
className: "flex items-center gap-2 px-3 py-2.5 rounded-md", |
| 4471 |
children: [ |
| 4472 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-4 h-4 bg-gray-200 dark:bg-gray-700 rounded animate-pulse flex-shrink-0" }), |
| 4473 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 flex-1 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }) |
| 4474 |
] |
| 4475 |
}, |
| 4476 |
`marketing-${i}` |
| 4477 |
)) }) |
| 4478 |
] }), |
| 4479 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 px-3 py-2.5 rounded-md", children: [ |
| 4480 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-4 h-4 bg-gray-200 dark:bg-gray-700 rounded animate-pulse flex-shrink-0" }), |
| 4481 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }) |
| 4482 |
] }) }) |
| 4483 |
] }) }), |
| 4484 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-y-auto p-6", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "max-w-4xl mx-auto space-y-6", children: [ |
| 4485 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-4", children: [ |
| 4486 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-5 h-5 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }), |
| 4487 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-6 w-56 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }) |
| 4488 |
] }), |
| 4489 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 w-96 bg-gray-200 dark:bg-gray-700 rounded animate-pulse mb-6" }), |
| 4490 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Card, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "p-6 space-y-6", children: [ |
| 4491 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [ |
| 4492 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-3.5 w-12 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }), |
| 4493 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 w-full bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }) |
| 4494 |
] }), |
| 4495 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [ |
| 4496 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-3.5 w-10 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }), |
| 4497 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 w-full bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }) |
| 4498 |
] }), |
| 4499 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [ |
| 4500 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-3.5 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }), |
| 4501 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-32 w-full bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }) |
| 4502 |
] }), |
| 4503 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [ |
| 4504 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-3.5 w-28 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }), |
| 4505 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-48 w-full bg-gray-200 dark:bg-gray-700 rounded-lg animate-pulse" }) |
| 4506 |
] }), |
| 4507 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid grid-cols-2 gap-4", children: [...Array(4)].map((_, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [ |
| 4508 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-3.5 w-24 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }), |
| 4509 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 w-full bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }) |
| 4510 |
] }, `grid-${i}`)) }) |
| 4511 |
] }) }) |
| 4512 |
] }) }) |
| 4513 |
] }) |
| 4514 |
] }); |
| 4515 |
} |
| 4516 |
if (isEditMode && tripError) { |
| 4517 |
const requestInfo = tripErrorContext.requestInfo || (tripError == null ? void 0 : tripError.config) || {}; |
| 4518 |
const method = ((_d = (_c = requestInfo.method || "GET").toUpperCase) == null ? void 0 : _d.call(_c)) || "GET"; |
| 4519 |
const url = requestInfo.url || ((_e = tripError == null ? void 0 : tripError.config) == null ? void 0 : _e.url) || ""; |
| 4520 |
const payload = requestInfo.payload || ((_f = tripError == null ? void 0 : tripError.config) == null ? void 0 : _f.data) || ""; |
| 4521 |
const composedErrorText = `Method: ${method} |
| 4522 |
URL: ${url} |
| 4523 |
Payload: ${payload || "N/A"} |
| 4524 |
|
| 4525 |
${tripErrorContext.details || ""}`; |
| 4526 |
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "min-h-screen flex items-center justify-center bg-white", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-full max-w-5xl px-6 py-12", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative flex flex-col items-center text-center gap-4 rounded-2xl border border-dashed border-[#fddfe1] bg-gradient-to-br from-[#fff7f8] via-white to-[#fff9f5] p-10 shadow-sm", children: [ |
| 4527 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-16 h-16 rounded-2xl bg-white border border-[#ffdede] flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4528 |
"svg", |
| 4529 |
{ |
| 4530 |
className: "w-10 h-10 text-red-500", |
| 4531 |
fill: "none", |
| 4532 |
stroke: "currentColor", |
| 4533 |
viewBox: "0 0 24 24", |
| 4534 |
strokeWidth: "1.8", |
| 4535 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4536 |
"path", |
| 4537 |
{ |
| 4538 |
strokeLinecap: "round", |
| 4539 |
strokeLinejoin: "round", |
| 4540 |
d: "M12 9v4m0 4h.01M10.29 3.86L2.82 17a2 2 0 001.71 3h14.94a2 2 0 001.71-3L13.71 3.86a2 2 0 00-3.42 0z" |
| 4541 |
} |
| 4542 |
) |
| 4543 |
} |
| 4544 |
) }), |
| 4545 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1", children: [ |
| 4546 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-2xl font-semibold text-gray-900", children: __$1("Error Loading Trips", "yatra") }), |
| 4547 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600", children: __$1( |
| 4548 |
"We couldn’t connect to the trips service. Please refresh or try again shortly.", |
| 4549 |
"yatra" |
| 4550 |
) }) |
| 4551 |
] }), |
| 4552 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap gap-2 justify-center", children: [ |
| 4553 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4554 |
Button, |
| 4555 |
{ |
| 4556 |
onClick: () => queryClient.invalidateQueries({ queryKey: ["trip", tripId] }), |
| 4557 |
children: __$1("Try again", "yatra") |
| 4558 |
} |
| 4559 |
), |
| 4560 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4561 |
Button, |
| 4562 |
{ |
| 4563 |
variant: "outline", |
| 4564 |
onClick: () => { |
| 4565 |
if (typeof window !== "undefined") { |
| 4566 |
window.open( |
| 4567 |
"https://wordpress.org/support/plugin/yatra", |
| 4568 |
"_blank" |
| 4569 |
); |
| 4570 |
} |
| 4571 |
}, |
| 4572 |
children: __$1("Visit support center", "yatra") |
| 4573 |
} |
| 4574 |
) |
| 4575 |
] }), |
| 4576 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-full mt-10", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative w-full text-left rounded-2xl border border-gray-200 bg-white shadow-sm space-y-0", children: [ |
| 4577 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between px-5 py-3 border-b border-gray-200", children: [ |
| 4578 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium text-gray-800", children: __$1("Technical details", "yatra") }), |
| 4579 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4580 |
Button, |
| 4581 |
{ |
| 4582 |
type: "button", |
| 4583 |
size: "sm", |
| 4584 |
variant: "ghost", |
| 4585 |
className: "flex items-center gap-2 text-gray-600 hover:text-gray-900", |
| 4586 |
onClick: () => copyErrorDetailsToClipboard(composedErrorText), |
| 4587 |
children: copiedErrorDetails ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ |
| 4588 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "w-4 h-4" }), |
| 4589 |
__$1("Copied", "yatra") |
| 4590 |
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ |
| 4591 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "w-4 h-4" }), |
| 4592 |
__$1("Copy details", "yatra") |
| 4593 |
] }) |
| 4594 |
} |
| 4595 |
) |
| 4596 |
] }), |
| 4597 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "px-5 py-3 border-b border-gray-200 space-y-2 text-sm text-left text-gray-800", children: [ |
| 4598 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 4599 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: __$1("Method:", "yatra") }), |
| 4600 |
" ", |
| 4601 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: method }) |
| 4602 |
] }), |
| 4603 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "break-all", children: [ |
| 4604 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: __$1("URL:", "yatra") }), |
| 4605 |
" ", |
| 4606 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: url || __$1("N/A", "yatra") }) |
| 4607 |
] }), |
| 4608 |
payload && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 4609 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium block mb-1", children: __$1("Payload:", "yatra") }), |
| 4610 |
/* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "max-h-40 overflow-auto px-3 py-2 rounded bg-gray-50 text-xs font-mono text-gray-900 whitespace-pre-wrap border border-gray-200", children: payload }) |
| 4611 |
] }) |
| 4612 |
] }), |
| 4613 |
/* @__PURE__ */ jsxRuntimeExports.jsx("pre", { className: "max-h-56 overflow-auto px-5 py-3 text-xs leading-relaxed font-mono text-gray-900 whitespace-pre-wrap bg-white", children: tripErrorContext.details || JSON.stringify( |
| 4614 |
{ |
| 4615 |
message: tripError instanceof Error ? tripError.message : __$1("Failed to load trip data", "yatra"), |
| 4616 |
method, |
| 4617 |
url, |
| 4618 |
payload |
| 4619 |
}, |
| 4620 |
null, |
| 4621 |
2 |
| 4622 |
) }) |
| 4623 |
] }) }) |
| 4624 |
] }) }) }); |
| 4625 |
} |
| 4626 |
const renderSectionContent = () => { |
| 4627 |
var _a2; |
| 4628 |
switch (currentSection) { |
| 4629 |
case "basic": |
| 4630 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [ |
| 4631 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-3", children: [ |
| 4632 |
/* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { className: "w-5 h-5 text-blue-600 dark:text-blue-400" }), |
| 4633 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: __$1("Basic Information", "yatra") }), |
| 4634 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4635 |
Badge, |
| 4636 |
{ |
| 4637 |
variant: "outline", |
| 4638 |
className: "ml-2 text-xs bg-blue-50 dark:bg-blue-900/20 text-blue-700 dark:text-blue-300 border-blue-200 dark:border-blue-800", |
| 4639 |
children: __$1("Start Here", "yatra") |
| 4640 |
} |
| 4641 |
) |
| 4642 |
] }), |
| 4643 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-blue-50 dark:bg-blue-900/20 border-l-4 border-blue-500 dark:border-blue-400 p-3 rounded-r-md mb-6", children: [ |
| 4644 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-blue-900 dark:text-blue-100 font-medium mb-1", children: __$1("💡 Getting Started", "yatra") }), |
| 4645 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-blue-800 dark:text-blue-200", children: __$1( |
| 4646 |
"Only the Trip Title and Trip URL are required to create a draft. Everything else is optional for now, but filling it in is highly recommended for better discovery and conversions.", |
| 4647 |
"yatra" |
| 4648 |
) }) |
| 4649 |
] }), |
| 4650 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [ |
| 4651 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-4", children: [ |
| 4652 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-1.5", children: [ |
| 4653 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 4654 |
"label", |
| 4655 |
{ |
| 4656 |
htmlFor: "title", |
| 4657 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 flex items-center gap-1.5", |
| 4658 |
children: [ |
| 4659 |
__$1("Trip Title", "yatra"), |
| 4660 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4661 |
Badge, |
| 4662 |
{ |
| 4663 |
variant: "outline", |
| 4664 |
className: "ml-1 text-[10px] px-1.5 py-0 bg-red-50 dark:bg-red-900/20 text-red-600 dark:text-red-400 border-red-200 dark:border-red-800", |
| 4665 |
children: __$1("Required", "yatra") |
| 4666 |
} |
| 4667 |
), |
| 4668 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4669 |
"button", |
| 4670 |
{ |
| 4671 |
type: "button", |
| 4672 |
className: "text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 ml-auto", |
| 4673 |
title: __$1( |
| 4674 |
"A catchy title that describes your trip. Recommended: 50-60 characters for best SEO results.", |
| 4675 |
"yatra" |
| 4676 |
), |
| 4677 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(HelpCircle, { className: "w-3.5 h-3.5" }) |
| 4678 |
} |
| 4679 |
) |
| 4680 |
] |
| 4681 |
} |
| 4682 |
), |
| 4683 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 4684 |
"span", |
| 4685 |
{ |
| 4686 |
className: `text-xs font-medium ${formData.title.length > 60 ? "text-red-600 dark:text-red-400" : formData.title.length >= 50 ? "text-green-600 dark:text-green-400" : "text-gray-500 dark:text-gray-400"}`, |
| 4687 |
children: [ |
| 4688 |
formData.title.length, |
| 4689 |
"/60" |
| 4690 |
] |
| 4691 |
} |
| 4692 |
) |
| 4693 |
] }), |
| 4694 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4695 |
HelpText, |
| 4696 |
{ |
| 4697 |
text: __$1( |
| 4698 |
'💡 Tip: Include your destination and trip length. Example: "Bali Beach Retreat - 7 Days" or "Paris City Tour - Half Day"', |
| 4699 |
"yatra" |
| 4700 |
), |
| 4701 |
className: "mb-2" |
| 4702 |
} |
| 4703 |
), |
| 4704 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4705 |
Input, |
| 4706 |
{ |
| 4707 |
id: "title", |
| 4708 |
type: "text", |
| 4709 |
value: formData.title, |
| 4710 |
onChange: (e) => handleTitleChange(e.target.value), |
| 4711 |
placeholder: __$1("e.g., Bali Beach Retreat - 7 Days", "yatra"), |
| 4712 |
maxLength: 100, |
| 4713 |
className: `${errors.title ? "border-red-500" : formData.title && formData.title.length <= 60 ? "border-green-500" : ""} transition-colors`, |
| 4714 |
required: true |
| 4715 |
} |
| 4716 |
), |
| 4717 |
errors.title ? /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-1.5 text-sm text-red-600 dark:text-red-400 flex items-center gap-1", children: [ |
| 4718 |
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }), |
| 4719 |
errors.title |
| 4720 |
] }) : formData.title && formData.title.length > 60 && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-1.5 text-xs text-yellow-600 dark:text-yellow-400 flex items-center gap-1", children: [ |
| 4721 |
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-3.5 h-3.5" }), |
| 4722 |
__$1( |
| 4723 |
"Title is longer than recommended for SEO (60 characters)", |
| 4724 |
"yatra" |
| 4725 |
) |
| 4726 |
] }) |
| 4727 |
] }), |
| 4728 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-4", children: [ |
| 4729 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-1.5", children: [ |
| 4730 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 4731 |
"label", |
| 4732 |
{ |
| 4733 |
htmlFor: "slug", |
| 4734 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 flex items-center gap-1.5", |
| 4735 |
children: [ |
| 4736 |
__$1("Trip URL", "yatra"), |
| 4737 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4738 |
Badge, |
| 4739 |
{ |
| 4740 |
variant: "outline", |
| 4741 |
className: "ml-1 text-[10px] px-1.5 py-0 bg-red-50 dark:bg-red-900/20 text-red-600 dark:text-red-400 border-red-200 dark:border-red-800", |
| 4742 |
children: __$1("Required", "yatra") |
| 4743 |
} |
| 4744 |
), |
| 4745 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4746 |
"button", |
| 4747 |
{ |
| 4748 |
type: "button", |
| 4749 |
className: "text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 ml-auto", |
| 4750 |
title: __$1( |
| 4751 |
"The web address for your trip page. Auto-generated from your title, but you can customize it.", |
| 4752 |
"yatra" |
| 4753 |
), |
| 4754 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(HelpCircle, { className: "w-3.5 h-3.5" }) |
| 4755 |
} |
| 4756 |
) |
| 4757 |
] |
| 4758 |
} |
| 4759 |
), |
| 4760 |
showSlugPreview && formData.slug && /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4761 |
"button", |
| 4762 |
{ |
| 4763 |
type: "button", |
| 4764 |
onClick: () => setShowSlugPreview(false), |
| 4765 |
className: "text-xs text-blue-600 dark:text-blue-400 hover:underline", |
| 4766 |
children: __$1("Hide", "yatra") |
| 4767 |
} |
| 4768 |
) |
| 4769 |
] }), |
| 4770 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4771 |
HelpText, |
| 4772 |
{ |
| 4773 |
text: __$1( |
| 4774 |
"💡 This is automatically created from your title. You usually don't need to change it unless you want a custom web address.", |
| 4775 |
"yatra" |
| 4776 |
), |
| 4777 |
className: "mb-2" |
| 4778 |
} |
| 4779 |
), |
| 4780 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4781 |
Input, |
| 4782 |
{ |
| 4783 |
id: "slug", |
| 4784 |
type: "text", |
| 4785 |
value: formData.slug, |
| 4786 |
onChange: (e) => handleFieldChange("slug", e.target.value), |
| 4787 |
placeholder: __$1("bali-beach-retreat-7-days", "yatra"), |
| 4788 |
className: `font-mono text-sm ${errors.slug ? "border-red-500" : ""}`, |
| 4789 |
required: true |
| 4790 |
} |
| 4791 |
), |
| 4792 |
errors.slug && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-1.5 text-sm text-red-600 dark:text-red-400 flex items-center gap-1", children: [ |
| 4793 |
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }), |
| 4794 |
errors.slug |
| 4795 |
] }), |
| 4796 |
showSlugPreview && formData.slug && !errors.slug && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2 p-2.5 bg-blue-50 dark:bg-blue-900/20 rounded text-xs text-gray-600 dark:text-gray-400 border border-blue-200 dark:border-blue-800 flex items-center justify-between", children: [ |
| 4797 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 4798 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-gray-500 dark:text-gray-400", children: [ |
| 4799 |
__$1("Preview URL:", "yatra"), |
| 4800 |
" " |
| 4801 |
] }), |
| 4802 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono text-blue-600 dark:text-blue-400", children: [ |
| 4803 |
((_a2 = window.yatraAdmin) == null ? void 0 : _a2.siteUrl) || "yoursite.com", |
| 4804 |
"/", |
| 4805 |
(settingsData == null ? void 0 : settingsData.trip_base) || "trip", |
| 4806 |
"/", |
| 4807 |
formData.slug |
| 4808 |
] }) |
| 4809 |
] }), |
| 4810 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4811 |
"button", |
| 4812 |
{ |
| 4813 |
type: "button", |
| 4814 |
onClick: () => { |
| 4815 |
var _a3; |
| 4816 |
const tripBase = (settingsData == null ? void 0 : settingsData.trip_base) || "trip"; |
| 4817 |
const url = `${((_a3 = window.yatraAdmin) == null ? void 0 : _a3.siteUrl) || "yoursite.com"}/${tripBase}/${formData.slug}`; |
| 4818 |
navigator.clipboard.writeText(url); |
| 4819 |
showToast( |
| 4820 |
__$1("URL copied to clipboard", "yatra"), |
| 4821 |
"success" |
| 4822 |
); |
| 4823 |
}, |
| 4824 |
className: "ml-2 text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 flex items-center gap-1", |
| 4825 |
title: __$1("Copy URL", "yatra"), |
| 4826 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "w-3.5 h-3.5" }) |
| 4827 |
} |
| 4828 |
) |
| 4829 |
] }), |
| 4830 |
!showSlugPreview && formData.slug && /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4831 |
"button", |
| 4832 |
{ |
| 4833 |
type: "button", |
| 4834 |
onClick: () => setShowSlugPreview(true), |
| 4835 |
className: "mt-2 text-xs text-blue-600 dark:text-blue-400 hover:underline", |
| 4836 |
children: __$1("Show URL Preview", "yatra") |
| 4837 |
} |
| 4838 |
) |
| 4839 |
] }), |
| 4840 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-4", children: [ |
| 4841 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-1.5", children: [ |
| 4842 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-xs font-normal text-gray-500 dark:text-gray-400 flex items-center gap-1.5", children: [ |
| 4843 |
__$1("Short Description", "yatra"), |
| 4844 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4845 |
Badge, |
| 4846 |
{ |
| 4847 |
variant: "outline", |
| 4848 |
className: "ml-1 text-[10px] px-1.5 py-0 bg-amber-50 dark:bg-amber-900/20 text-amber-600 dark:text-amber-400 border-amber-200 dark:border-amber-800", |
| 4849 |
children: __$1("Recommended", "yatra") |
| 4850 |
} |
| 4851 |
), |
| 4852 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4853 |
"button", |
| 4854 |
{ |
| 4855 |
type: "button", |
| 4856 |
className: "text-gray-400 hover:text-gray-600 dark:hover:text-gray-300", |
| 4857 |
title: __$1( |
| 4858 |
"A brief summary that appears in listings. Recommended: 100-150 characters for best results.", |
| 4859 |
"yatra" |
| 4860 |
), |
| 4861 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(HelpCircle, { className: "w-3.5 h-3.5" }) |
| 4862 |
} |
| 4863 |
) |
| 4864 |
] }), |
| 4865 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ |
| 4866 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 4867 |
"span", |
| 4868 |
{ |
| 4869 |
className: `text-xs font-medium ${formData.short_description.length > 200 ? "text-red-600 dark:text-red-400" : formData.short_description.length >= 100 && formData.short_description.length <= 150 ? "text-green-600 dark:text-green-400" : formData.short_description.length > 0 ? "text-yellow-600 dark:text-yellow-400" : "text-gray-500 dark:text-gray-400"}`, |
| 4870 |
children: [ |
| 4871 |
formData.short_description.length, |
| 4872 |
"/200" |
| 4873 |
] |
| 4874 |
} |
| 4875 |
), |
| 4876 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4877 |
AiFieldAffordance, |
| 4878 |
{ |
| 4879 |
task: "trip-short-description", |
| 4880 |
label: __$1("Short Description", "yatra"), |
| 4881 |
value: formData.short_description, |
| 4882 |
onAccept: (v) => handleFieldChange("short_description", v), |
| 4883 |
buildContext: () => buildTripAiContext(formData) |
| 4884 |
} |
| 4885 |
) |
| 4886 |
] }) |
| 4887 |
] }), |
| 4888 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4889 |
HelpText, |
| 4890 |
{ |
| 4891 |
text: __$1( |
| 4892 |
'💡 Write 2-3 sentences that grab attention! This appears in trip listings. Example: "Escape to paradise with our 7-day Bali beach retreat. Experience stunning sunsets, world-class diving, and authentic local culture."', |
| 4893 |
"yatra" |
| 4894 |
), |
| 4895 |
className: "mb-2" |
| 4896 |
} |
| 4897 |
), |
| 4898 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4899 |
RichTextEditor, |
| 4900 |
{ |
| 4901 |
value: formData.short_description, |
| 4902 |
onChange: (value) => handleFieldChange("short_description", value), |
| 4903 |
placeholder: __$1( |
| 4904 |
"Escape to paradise with our 7-day Bali beach retreat...", |
| 4905 |
"yatra" |
| 4906 |
), |
| 4907 |
minHeight: 120 |
| 4908 |
} |
| 4909 |
), |
| 4910 |
formData.short_description.length > 0 && formData.short_description.length < 100 && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-1.5 text-xs text-yellow-600 dark:text-yellow-400 flex items-center gap-1", children: [ |
| 4911 |
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-3.5 h-3.5" }), |
| 4912 |
__$1( |
| 4913 |
"Consider adding more details (recommended: 100-150 characters)", |
| 4914 |
"yatra" |
| 4915 |
) |
| 4916 |
] }) |
| 4917 |
] }), |
| 4918 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-4", children: [ |
| 4919 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-1.5", children: [ |
| 4920 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-xs font-normal text-gray-500 dark:text-gray-400 flex items-center gap-1.5", children: [ |
| 4921 |
__$1("Trip Description", "yatra"), |
| 4922 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4923 |
Badge, |
| 4924 |
{ |
| 4925 |
variant: "outline", |
| 4926 |
className: "ml-1 text-[10px] px-1.5 py-0 bg-amber-50 dark:bg-amber-900/20 text-amber-600 dark:text-amber-400 border-amber-200 dark:border-amber-800", |
| 4927 |
children: __$1("Recommended", "yatra") |
| 4928 |
} |
| 4929 |
) |
| 4930 |
] }), |
| 4931 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4932 |
AiFieldAffordance, |
| 4933 |
{ |
| 4934 |
task: "trip-description", |
| 4935 |
label: __$1("Description", "yatra"), |
| 4936 |
value: formData.description, |
| 4937 |
onAccept: (v) => handleFieldChange("description", v), |
| 4938 |
buildContext: () => buildTripAiContext(formData) |
| 4939 |
} |
| 4940 |
) |
| 4941 |
] }), |
| 4942 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4943 |
HelpText, |
| 4944 |
{ |
| 4945 |
text: __$1( |
| 4946 |
"💡 Tell travelers what makes your trip special! Describe the experience, highlights, and what they'll see. Write 2-4 paragraphs. Be enthusiastic and detailed!", |
| 4947 |
"💡 Tell travelers what makes your trip special! Describe the experience, highlights, and what they'll see. Write 2-4 paragraphs. Be enthusiastic and detailed!" |
| 4948 |
), |
| 4949 |
className: "mb-2" |
| 4950 |
} |
| 4951 |
), |
| 4952 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4953 |
RichTextEditor, |
| 4954 |
{ |
| 4955 |
value: formData.description, |
| 4956 |
onChange: (value) => handleFieldChange("description", value), |
| 4957 |
placeholder: __$1( |
| 4958 |
"Escape to paradise with our 7-day Bali beach retreat... Or describe your single day trip experience...", |
| 4959 |
"yatra" |
| 4960 |
), |
| 4961 |
minHeight: 260 |
| 4962 |
} |
| 4963 |
), |
| 4964 |
errors.description && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-1.5 text-sm text-red-600 dark:text-red-400 flex items-center gap-1", children: [ |
| 4965 |
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }), |
| 4966 |
errors.description |
| 4967 |
] }) |
| 4968 |
] }), |
| 4969 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-6", children: [ |
| 4970 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5 flex items-center gap-1.5", children: [ |
| 4971 |
__$1("Featured Image", "yatra"), |
| 4972 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4973 |
Badge, |
| 4974 |
{ |
| 4975 |
variant: "outline", |
| 4976 |
className: "ml-1 text-[10px] px-1.5 py-0 bg-amber-50 dark:bg-amber-900/20 text-amber-600 dark:text-amber-400 border-amber-200 dark:border-amber-800", |
| 4977 |
children: __$1("Recommended", "yatra") |
| 4978 |
} |
| 4979 |
), |
| 4980 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4981 |
"button", |
| 4982 |
{ |
| 4983 |
type: "button", |
| 4984 |
className: "text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 ml-auto", |
| 4985 |
title: __$1( |
| 4986 |
"The main image that represents your trip. This appears in listings and as the hero image on the trip page.", |
| 4987 |
"yatra" |
| 4988 |
), |
| 4989 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(HelpCircle, { className: "w-3.5 h-3.5" }) |
| 4990 |
} |
| 4991 |
) |
| 4992 |
] }), |
| 4993 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 4994 |
HelpText, |
| 4995 |
{ |
| 4996 |
text: __$1( |
| 4997 |
"💡 Choose your best photo! This is the first thing travelers see. Use a high-quality image (1200x800px recommended) that shows what makes your trip special.", |
| 4998 |
"yatra" |
| 4999 |
), |
| 5000 |
className: "mb-2" |
| 5001 |
} |
| 5002 |
), |
| 5003 |
formData.featured_image ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative group", children: [ |
| 5004 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5005 |
"div", |
| 5006 |
{ |
| 5007 |
className: `aspect-video bg-gray-100 dark:bg-gray-800 rounded-lg overflow-hidden border-2 ${errors.featured_image ? "border-red-500 dark:border-red-600" : "border-gray-200 dark:border-gray-700"}`, |
| 5008 |
children: featuredImagePreview ? /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5009 |
"img", |
| 5010 |
{ |
| 5011 |
src: featuredImagePreview, |
| 5012 |
alt: __$1("Featured Image", "yatra"), |
| 5013 |
className: "w-full h-full object-cover" |
| 5014 |
} |
| 5015 |
) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center w-full h-full text-sm text-gray-500 dark:text-gray-400", children: isResolvingFeaturedImage ? __$1("Loading image...", "yatra") : __$1("Preview unavailable", "yatra") }) |
| 5016 |
} |
| 5017 |
), |
| 5018 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5019 |
"button", |
| 5020 |
{ |
| 5021 |
type: "button", |
| 5022 |
onClick: () => handleFieldChange("featured_image", null), |
| 5023 |
className: "absolute top-2 right-2 bg-red-600 text-white rounded-full p-1.5 opacity-0 group-hover:opacity-100 transition-opacity", |
| 5024 |
title: __$1("Remove image", "yatra"), |
| 5025 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-4 h-4" }) |
| 5026 |
} |
| 5027 |
) |
| 5028 |
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 5029 |
"button", |
| 5030 |
{ |
| 5031 |
type: "button", |
| 5032 |
onClick: () => { |
| 5033 |
if (window.wp && window.wp.media) { |
| 5034 |
const mediaUploader = window.wp.media({ |
| 5035 |
title: __$1("Select Featured Image", "yatra"), |
| 5036 |
button: { text: __$1("Use this image", "yatra") }, |
| 5037 |
multiple: false |
| 5038 |
}); |
| 5039 |
mediaUploader.on("select", () => { |
| 5040 |
const attachment = mediaUploader.state().get("selection").first().toJSON(); |
| 5041 |
handleFieldChange("featured_image", attachment.id); |
| 5042 |
}); |
| 5043 |
prepareWordPressMediaFrameOpen(); |
| 5044 |
mediaUploader.open(); |
| 5045 |
} |
| 5046 |
}, |
| 5047 |
className: `w-full aspect-video border-2 border-dashed rounded-lg flex flex-col items-center justify-center transition-colors ${errors.featured_image ? "border-red-500 dark:border-red-600 bg-red-50 dark:bg-red-900/20" : "border-gray-300 dark:border-gray-700 hover:border-blue-500 dark:hover:border-blue-400"}`, |
| 5048 |
children: [ |
| 5049 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5050 |
Upload, |
| 5051 |
{ |
| 5052 |
className: `w-10 h-10 mb-2 ${errors.featured_image ? "text-red-400" : "text-gray-400"}` |
| 5053 |
} |
| 5054 |
), |
| 5055 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5056 |
"span", |
| 5057 |
{ |
| 5058 |
className: `text-sm font-medium ${errors.featured_image ? "text-red-600 dark:text-red-400" : "text-gray-600 dark:text-gray-400"}`, |
| 5059 |
children: __$1("Upload Featured Image", "yatra") |
| 5060 |
} |
| 5061 |
), |
| 5062 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5063 |
"span", |
| 5064 |
{ |
| 5065 |
className: `text-xs mt-1 ${errors.featured_image ? "text-red-500 dark:text-red-500" : "text-gray-500 dark:text-gray-500"}`, |
| 5066 |
children: __$1("Recommended: 1200x800px", "yatra") |
| 5067 |
} |
| 5068 |
) |
| 5069 |
] |
| 5070 |
} |
| 5071 |
), |
| 5072 |
errors.featured_image && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-1.5 text-sm text-red-600 dark:text-red-400 flex items-center gap-1", children: [ |
| 5073 |
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }), |
| 5074 |
errors.featured_image |
| 5075 |
] }) |
| 5076 |
] }), |
| 5077 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { className: "mt-6", children: [ |
| 5078 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-2", children: [ |
| 5079 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [ |
| 5080 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __$1("Trip Highlights", "yatra") }), |
| 5081 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: __$1( |
| 5082 |
"Add key highlights that make your trip special. These will be displayed prominently on your trip page.", |
| 5083 |
"yatra" |
| 5084 |
) }) |
| 5085 |
] }), |
| 5086 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5087 |
AiFieldAffordance, |
| 5088 |
{ |
| 5089 |
task: "trip-highlights", |
| 5090 |
label: __$1("Highlights", "yatra"), |
| 5091 |
value: (formData.highlights ?? []).join("\n"), |
| 5092 |
onAccept: (raw) => { |
| 5093 |
const list = raw.split(/\r?\n/).map((l) => l.replace(/^[\s\-\*•·●]+/, "").trim()).filter((l) => l !== ""); |
| 5094 |
handleFieldChange("highlights", list); |
| 5095 |
}, |
| 5096 |
buildContext: () => buildTripAiContext(formData) |
| 5097 |
} |
| 5098 |
) |
| 5099 |
] }) }), |
| 5100 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-3", children: [ |
| 5101 |
formData.highlights.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2", children: formData.highlights.map((highlight, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 5102 |
"div", |
| 5103 |
{ |
| 5104 |
className: "flex items-center gap-2 p-3 bg-gray-50 dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700", |
| 5105 |
children: [ |
| 5106 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CheckCircle2, { className: "w-4 h-4 text-green-600 dark:text-green-400 flex-shrink-0" }), |
| 5107 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 text-sm text-gray-900 dark:text-white", children: highlight }), |
| 5108 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5109 |
Button, |
| 5110 |
{ |
| 5111 |
type: "button", |
| 5112 |
variant: "ghost", |
| 5113 |
size: "sm", |
| 5114 |
onClick: () => handleHighlightRemove(index), |
| 5115 |
className: "text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-900/20", |
| 5116 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-4 h-4" }) |
| 5117 |
} |
| 5118 |
) |
| 5119 |
] |
| 5120 |
}, |
| 5121 |
index |
| 5122 |
)) }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-6 border-2 border-dashed border-gray-300 dark:border-gray-700 rounded-lg text-center", children: [ |
| 5123 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "w-8 h-8 text-gray-300 dark:text-gray-600 mx-auto mb-2" }), |
| 5124 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-3", children: __$1("No highlights added yet", "yatra") }), |
| 5125 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-500 mb-4", children: __$1( |
| 5126 |
'Add key selling points like "Private guide", "All meals included", or "Skip-the-line tickets"', |
| 5127 |
"yatra" |
| 5128 |
) }) |
| 5129 |
] }), |
| 5130 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 5131 |
Button, |
| 5132 |
{ |
| 5133 |
type: "button", |
| 5134 |
variant: "outline", |
| 5135 |
onClick: handleHighlightAdd, |
| 5136 |
className: "w-full", |
| 5137 |
children: [ |
| 5138 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4 mr-2" }), |
| 5139 |
__$1("Add Highlight", "yatra") |
| 5140 |
] |
| 5141 |
} |
| 5142 |
) |
| 5143 |
] }) |
| 5144 |
] }), |
| 5145 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-6 space-y-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t border-gray-200 dark:border-gray-700 pt-6", children: [ |
| 5146 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-sm font-semibold text-gray-900 dark:text-white mb-4", children: __$1("Trip Type & Duration", "yatra") }), |
| 5147 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-4", children: [ |
| 5148 |
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-3", children: __$1("Trip Type", "yatra") }), |
| 5149 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 5150 |
"div", |
| 5151 |
{ |
| 5152 |
className: `grid grid-cols-1 md:grid-cols-2 gap-4 ${errors.trip_type ? "mb-2" : ""}`, |
| 5153 |
children: [ |
| 5154 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 5155 |
"label", |
| 5156 |
{ |
| 5157 |
className: `relative flex cursor-pointer rounded-lg border p-4 focus:outline-none ${formData.trip_type === "single_day" ? "border-blue-600 bg-blue-50 dark:bg-blue-900/20 ring-2 ring-blue-600" : errors.trip_type ? "border-red-500 dark:border-red-600 bg-red-50 dark:bg-red-900/20" : "border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800"}`, |
| 5158 |
children: [ |
| 5159 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5160 |
"input", |
| 5161 |
{ |
| 5162 |
type: "radio", |
| 5163 |
name: "trip_type", |
| 5164 |
value: "single_day", |
| 5165 |
checked: formData.trip_type === "single_day", |
| 5166 |
onChange: (e) => { |
| 5167 |
handleFieldChange("trip_type", e.target.value); |
| 5168 |
if (e.target.value === "single_day") { |
| 5169 |
setFormData((prev) => ({ |
| 5170 |
...prev, |
| 5171 |
duration_days: "1", |
| 5172 |
duration_nights: "0" |
| 5173 |
})); |
| 5174 |
} |
| 5175 |
}, |
| 5176 |
className: "sr-only" |
| 5177 |
} |
| 5178 |
), |
| 5179 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-1", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col", children: [ |
| 5180 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5181 |
"span", |
| 5182 |
{ |
| 5183 |
className: `block text-sm font-semibold ${formData.trip_type === "single_day" ? "text-blue-900 dark:text-blue-300" : "text-gray-900 dark:text-white"}`, |
| 5184 |
children: __$1("Single Day Trip", "yatra") |
| 5185 |
} |
| 5186 |
), |
| 5187 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5188 |
"span", |
| 5189 |
{ |
| 5190 |
className: `mt-1 flex items-center text-sm ${formData.trip_type === "single_day" ? "text-blue-700 dark:text-blue-400" : "text-gray-500 dark:text-gray-400"}`, |
| 5191 |
children: __$1( |
| 5192 |
"Trip completed within one day (no overnight stay)", |
| 5193 |
"yatra" |
| 5194 |
) |
| 5195 |
} |
| 5196 |
) |
| 5197 |
] }) }), |
| 5198 |
formData.trip_type === "single_day" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute top-4 right-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 w-4 rounded-full bg-blue-600" }) }) |
| 5199 |
] |
| 5200 |
} |
| 5201 |
), |
| 5202 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 5203 |
"label", |
| 5204 |
{ |
| 5205 |
className: `relative flex cursor-pointer rounded-lg border p-4 focus:outline-none ${formData.trip_type === "multi_day" ? "border-blue-600 bg-blue-50 dark:bg-blue-900/20 ring-2 ring-blue-600" : errors.trip_type ? "border-red-500 dark:border-red-600 bg-red-50 dark:bg-red-900/20" : "border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800"}`, |
| 5206 |
children: [ |
| 5207 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5208 |
"input", |
| 5209 |
{ |
| 5210 |
type: "radio", |
| 5211 |
name: "trip_type", |
| 5212 |
value: "multi_day", |
| 5213 |
checked: formData.trip_type === "multi_day", |
| 5214 |
onChange: (e) => { |
| 5215 |
handleFieldChange("trip_type", e.target.value); |
| 5216 |
setFormData((prev) => ({ |
| 5217 |
...prev, |
| 5218 |
duration_hours: "" |
| 5219 |
})); |
| 5220 |
}, |
| 5221 |
className: "sr-only" |
| 5222 |
} |
| 5223 |
), |
| 5224 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-1", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col", children: [ |
| 5225 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5226 |
"span", |
| 5227 |
{ |
| 5228 |
className: `block text-sm font-semibold ${formData.trip_type === "multi_day" ? "text-blue-900 dark:text-blue-300" : "text-gray-900 dark:text-white"}`, |
| 5229 |
children: __$1("Multi-Day Trip", "yatra") |
| 5230 |
} |
| 5231 |
), |
| 5232 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5233 |
"span", |
| 5234 |
{ |
| 5235 |
className: `mt-1 flex items-center text-sm ${formData.trip_type === "multi_day" ? "text-blue-700 dark:text-blue-400" : "text-gray-500 dark:text-gray-400"}`, |
| 5236 |
children: __$1( |
| 5237 |
"Trip spans multiple days with overnight stays", |
| 5238 |
"yatra" |
| 5239 |
) |
| 5240 |
} |
| 5241 |
) |
| 5242 |
] }) }), |
| 5243 |
formData.trip_type === "multi_day" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute top-4 right-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 w-4 rounded-full bg-blue-600" }) }) |
| 5244 |
] |
| 5245 |
} |
| 5246 |
) |
| 5247 |
] |
| 5248 |
} |
| 5249 |
), |
| 5250 |
errors.trip_type && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-1.5 text-sm text-red-600 dark:text-red-400 flex items-center gap-1", children: [ |
| 5251 |
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }), |
| 5252 |
errors.trip_type |
| 5253 |
] }) |
| 5254 |
] }), |
| 5255 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [ |
| 5256 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 5257 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5258 |
"label", |
| 5259 |
{ |
| 5260 |
htmlFor: "duration_days", |
| 5261 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", |
| 5262 |
children: __$1("Duration (Days)", "yatra") |
| 5263 |
} |
| 5264 |
), |
| 5265 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5266 |
Input, |
| 5267 |
{ |
| 5268 |
id: "duration_days", |
| 5269 |
type: "number", |
| 5270 |
min: "1", |
| 5271 |
value: formData.duration_days, |
| 5272 |
onChange: (e) => { |
| 5273 |
const days = e.target.value; |
| 5274 |
handleFieldChange("duration_days", days); |
| 5275 |
if (formData.trip_type === "single_day") { |
| 5276 |
setFormData((prev) => ({ |
| 5277 |
...prev, |
| 5278 |
duration_nights: "0" |
| 5279 |
})); |
| 5280 |
} else if (days && parseInt(days) > 1) { |
| 5281 |
const nights = Math.max( |
| 5282 |
0, |
| 5283 |
parseInt(days) - 1 |
| 5284 |
).toString(); |
| 5285 |
setFormData((prev) => ({ |
| 5286 |
...prev, |
| 5287 |
duration_nights: nights |
| 5288 |
})); |
| 5289 |
} |
| 5290 |
}, |
| 5291 |
placeholder: formData.trip_type === "single_day" ? "1" : __$1("e.g., 7", "yatra"), |
| 5292 |
className: errors.duration_days ? "border-red-500" : "", |
| 5293 |
disabled: formData.trip_type === "single_day" |
| 5294 |
} |
| 5295 |
), |
| 5296 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1.5 text-xs text-gray-500 dark:text-gray-400", children: formData.trip_type === "single_day" ? __$1("Single day trips are always 1 day", "yatra") : __$1( |
| 5297 |
"Enter the number of days for your trip", |
| 5298 |
"yatra" |
| 5299 |
) }), |
| 5300 |
errors.duration_days && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-1.5 text-sm text-red-600 dark:text-red-400 flex items-center gap-1", children: [ |
| 5301 |
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }), |
| 5302 |
errors.duration_days |
| 5303 |
] }) |
| 5304 |
] }), |
| 5305 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 5306 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5307 |
"label", |
| 5308 |
{ |
| 5309 |
htmlFor: "duration_nights", |
| 5310 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", |
| 5311 |
children: __$1("Duration (Nights)", "yatra") |
| 5312 |
} |
| 5313 |
), |
| 5314 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5315 |
Input, |
| 5316 |
{ |
| 5317 |
id: "duration_nights", |
| 5318 |
type: "number", |
| 5319 |
min: "0", |
| 5320 |
value: formData.duration_nights, |
| 5321 |
onChange: (e) => handleFieldChange("duration_nights", e.target.value), |
| 5322 |
placeholder: formData.trip_type === "single_day" ? "0" : __$1("e.g., 6", "yatra"), |
| 5323 |
className: errors.duration_nights ? "border-red-500" : "", |
| 5324 |
disabled: formData.trip_type === "single_day" |
| 5325 |
} |
| 5326 |
), |
| 5327 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1.5 text-xs text-gray-500 dark:text-gray-400", children: formData.trip_type === "single_day" ? __$1( |
| 5328 |
"Single day trips have 0 nights (no overnight stay)", |
| 5329 |
"yatra" |
| 5330 |
) : __$1( |
| 5331 |
"Enter the number of nights (typically days - 1)", |
| 5332 |
"yatra" |
| 5333 |
) }), |
| 5334 |
errors.duration_nights && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-1.5 text-sm text-red-600 dark:text-red-400 flex items-center gap-1", children: [ |
| 5335 |
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }), |
| 5336 |
errors.duration_nights |
| 5337 |
] }) |
| 5338 |
] }) |
| 5339 |
] }), |
| 5340 |
formData.trip_type === "single_day" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-4", children: [ |
| 5341 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5342 |
"label", |
| 5343 |
{ |
| 5344 |
htmlFor: "duration_hours", |
| 5345 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", |
| 5346 |
children: __$1("Duration (Hours)", "yatra") |
| 5347 |
} |
| 5348 |
), |
| 5349 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5350 |
Input, |
| 5351 |
{ |
| 5352 |
id: "duration_hours", |
| 5353 |
type: "number", |
| 5354 |
min: "1", |
| 5355 |
max: "24", |
| 5356 |
value: formData.duration_hours, |
| 5357 |
onChange: (e) => handleFieldChange("duration_hours", e.target.value), |
| 5358 |
placeholder: __$1("e.g., 8", "yatra"), |
| 5359 |
className: errors.duration_hours ? "border-red-500" : "" |
| 5360 |
} |
| 5361 |
), |
| 5362 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1.5 text-xs text-gray-500 dark:text-gray-400", children: __$1( |
| 5363 |
"Optional — for an hour-based day tour (e.g. an 8-hour experience). When set, the tour's duration shows in hours and Google Calendar creates a same-day timed event instead of an all-day one. Leave empty for a normal day tour.", |
| 5364 |
"yatra" |
| 5365 |
) }), |
| 5366 |
errors.duration_hours && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-1.5 text-sm text-red-600 dark:text-red-400 flex items-center gap-1", children: [ |
| 5367 |
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }), |
| 5368 |
errors.duration_hours |
| 5369 |
] }) |
| 5370 |
] }) |
| 5371 |
] }) }) |
| 5372 |
] }) |
| 5373 |
] }); |
| 5374 |
case "location": |
| 5375 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ |
| 5376 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2 mb-2", children: [ |
| 5377 |
/* @__PURE__ */ jsxRuntimeExports.jsx(MapPin, { className: "w-5 h-5 text-gray-500" }), |
| 5378 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: __$1("Location & Geography", "yatra") }), |
| 5379 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5380 |
Badge, |
| 5381 |
{ |
| 5382 |
variant: "outline", |
| 5383 |
className: "text-xs bg-amber-50 dark:bg-amber-900/20 text-amber-600 dark:text-amber-300 border-amber-200 dark:border-amber-800", |
| 5384 |
children: __$1("Recommended", "yatra") |
| 5385 |
} |
| 5386 |
) |
| 5387 |
] }), |
| 5388 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-amber-50 dark:bg-amber-900/20 border-l-4 border-amber-500 dark:border-amber-400 p-3 rounded-r-md", children: [ |
| 5389 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium text-amber-900 dark:text-amber-100 mb-1", children: __$1( |
| 5390 |
"Specify where your trip takes place, including destinations, coordinates, and key landmarks.", |
| 5391 |
"yatra" |
| 5392 |
) }), |
| 5393 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-amber-800 dark:text-amber-200", children: __$1( |
| 5394 |
"Optional but highly recommended to help travelers understand the experience.", |
| 5395 |
"yatra" |
| 5396 |
) }) |
| 5397 |
] }), |
| 5398 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-4", children: [ |
| 5399 |
__$1( |
| 5400 |
"Optimize how your trip appears in search engines and social shares", |
| 5401 |
"yatra" |
| 5402 |
), |
| 5403 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block text-xs text-gray-500 dark:text-gray-400 mt-1", children: __$1( |
| 5404 |
"Optional, but completing these fields improves SEO and click-through rates.", |
| 5405 |
"yatra" |
| 5406 |
) }) |
| 5407 |
] }), |
| 5408 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ |
| 5409 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 5410 |
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: __$1("Destinations", "yatra") }), |
| 5411 |
destinationsData && destinationsData.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5412 |
MultiSelect, |
| 5413 |
{ |
| 5414 |
value: formData.destinations.map((id) => id.toString()), |
| 5415 |
onChange: (values) => handleFieldChange( |
| 5416 |
"destinations", |
| 5417 |
values.map((v) => Number(v)) |
| 5418 |
), |
| 5419 |
options: destinationsData.map((destination) => ({ |
| 5420 |
value: destination.id.toString(), |
| 5421 |
label: destination.name || sprintf( |
| 5422 |
// translators: %s: numeric destination ID, used as a fallback when the destination has no name. |
| 5423 |
__$1("Destination #%s", "yatra"), |
| 5424 |
String(destination.id) |
| 5425 |
) |
| 5426 |
})), |
| 5427 |
placeholder: __$1("Select destinations...", "yatra"), |
| 5428 |
searchPlaceholder: __$1("Search destinations...", "yatra"), |
| 5429 |
error: !!errors.destinations |
| 5430 |
} |
| 5431 |
) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-4 border-2 border-dashed border-gray-300 dark:border-gray-700 rounded-lg text-center", children: [ |
| 5432 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400 mb-3", children: __$1( |
| 5433 |
"No destinations available. Please create destinations first.", |
| 5434 |
"yatra" |
| 5435 |
) }), |
| 5436 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [ |
| 5437 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-400 dark:text-gray-500", children: __$1("To create destinations:", "yatra") }), |
| 5438 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("ol", { className: "text-xs text-gray-400 dark:text-gray-500 text-left list-decimal list-inside space-y-1 max-w-md mx-auto", children: [ |
| 5439 |
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: __$1( |
| 5440 |
"Go to Yatra → Destinations in your WordPress admin", |
| 5441 |
"yatra" |
| 5442 |
) }), |
| 5443 |
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: __$1('Click "Add New Destination"', "yatra") }), |
| 5444 |
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: __$1("Enter destination name and details", "yatra") }), |
| 5445 |
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: __$1('Set status to "Published"', "yatra") }) |
| 5446 |
] }), |
| 5447 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 5448 |
"a", |
| 5449 |
{ |
| 5450 |
href: "/wp-admin/admin.php?page=yatra&subpage=trips&tab=destinations&action=create", |
| 5451 |
target: "_blank", |
| 5452 |
rel: "noopener noreferrer", |
| 5453 |
className: "inline-flex items-center px-3 py-1.5 text-xs font-medium text-blue-600 dark:text-blue-400 bg-blue-50 dark:bg-blue-900/20 border border-blue-200 dark:border-blue-800 rounded-md hover:bg-blue-100 dark:hover:bg-blue-900/30 transition-colors", |
| 5454 |
children: [ |
| 5455 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5456 |
"svg", |
| 5457 |
{ |
| 5458 |
className: "w-3 h-3 mr-1", |
| 5459 |
fill: "none", |
| 5460 |
stroke: "currentColor", |
| 5461 |
viewBox: "0 0 24 24", |
| 5462 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5463 |
"path", |
| 5464 |
{ |
| 5465 |
strokeLinecap: "round", |
| 5466 |
strokeLinejoin: "round", |
| 5467 |
strokeWidth: 2, |
| 5468 |
d: "M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14" |
| 5469 |
} |
| 5470 |
) |
| 5471 |
} |
| 5472 |
), |
| 5473 |
__$1("Create Destinations", "yatra") |
| 5474 |
] |
| 5475 |
} |
| 5476 |
) |
| 5477 |
] }) |
| 5478 |
] }), |
| 5479 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5480 |
HelpText, |
| 5481 |
{ |
| 5482 |
text: __$1( |
| 5483 |
"Select all destinations included in this trip", |
| 5484 |
"yatra" |
| 5485 |
), |
| 5486 |
className: "mt-2" |
| 5487 |
} |
| 5488 |
), |
| 5489 |
errors.destinations && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-1.5 text-sm text-red-600 dark:text-red-400 flex items-center gap-1", children: [ |
| 5490 |
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }), |
| 5491 |
errors.destinations |
| 5492 |
] }) |
| 5493 |
] }), |
| 5494 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-8", children: [ |
| 5495 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center space-y-2", children: [ |
| 5496 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-lg font-semibold text-gray-900 dark:text-white flex items-center justify-center gap-2", children: [ |
| 5497 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-6 h-6 bg-gradient-to-br from-blue-500 to-purple-600 rounded-lg flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx(MapPin, { className: "w-3 h-3 text-white" }) }), |
| 5498 |
__$1("Trip Locations", "yatra") |
| 5499 |
] }), |
| 5500 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400 max-w-2xl mx-auto", children: __$1( |
| 5501 |
"Set precise starting and ending points with location names and GPS coordinates. Use manual entry or visual map selection for maximum accuracy.", |
| 5502 |
"yatra" |
| 5503 |
) }) |
| 5504 |
] }), |
| 5505 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-8", children: [ |
| 5506 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [ |
| 5507 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 p-4 bg-gradient-to-r from-blue-50 to-indigo-50 dark:from-blue-900/20 dark:to-indigo-900/20 rounded-xl border border-blue-200 dark:border-blue-800", children: [ |
| 5508 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-10 h-10 bg-gradient-to-br from-blue-500 to-blue-600 rounded-xl flex items-center justify-center shadow-lg", children: /* @__PURE__ */ jsxRuntimeExports.jsx(MapPin, { className: "w-5 h-5 text-white" }) }), |
| 5509 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [ |
| 5510 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-base font-semibold text-blue-900 dark:text-blue-100", children: __$1("Starting Point", "yatra") }), |
| 5511 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-blue-700 dark:text-blue-300", children: __$1("Where the journey begins", "yatra") }) |
| 5512 |
] }), |
| 5513 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ |
| 5514 |
formData.starting_location && /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5515 |
"div", |
| 5516 |
{ |
| 5517 |
className: "w-2 h-2 bg-green-500 rounded-full animate-pulse", |
| 5518 |
title: __$1("Location set", "yatra") |
| 5519 |
} |
| 5520 |
), |
| 5521 |
formData.starting_latitude && formData.starting_longitude && /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5522 |
"div", |
| 5523 |
{ |
| 5524 |
className: "w-2 h-2 bg-blue-500 rounded-full animate-pulse", |
| 5525 |
title: __$1("Coordinates set", "yatra") |
| 5526 |
} |
| 5527 |
) |
| 5528 |
] }) |
| 5529 |
] }), |
| 5530 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ |
| 5531 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [ |
| 5532 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300 flex items-center gap-2", children: [ |
| 5533 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-4 h-4 bg-blue-100 dark:bg-blue-900 rounded flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-bold text-blue-600 dark:text-blue-400", children: "1" }) }), |
| 5534 |
__$1("Starting Location", "yatra") |
| 5535 |
] }), |
| 5536 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ |
| 5537 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: formData.starting_location ? "✓" : __$1("Required", "yatra") }), |
| 5538 |
formData.starting_latitude && formData.starting_longitude && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1 text-xs text-green-600", children: [ |
| 5539 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-2 h-2 bg-green-500 rounded-full" }), |
| 5540 |
__$1("Coords Set", "yatra") |
| 5541 |
] }) |
| 5542 |
] }) |
| 5543 |
] }), |
| 5544 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5545 |
LocationPicker, |
| 5546 |
{ |
| 5547 |
value: { |
| 5548 |
name: formData.starting_location, |
| 5549 |
latitude: formData.starting_latitude, |
| 5550 |
longitude: formData.starting_longitude |
| 5551 |
}, |
| 5552 |
onChange: (locationData) => { |
| 5553 |
handleFieldChange( |
| 5554 |
"starting_location", |
| 5555 |
locationData.name |
| 5556 |
); |
| 5557 |
handleFieldChange( |
| 5558 |
"starting_latitude", |
| 5559 |
locationData.latitude |
| 5560 |
); |
| 5561 |
handleFieldChange( |
| 5562 |
"starting_longitude", |
| 5563 |
locationData.longitude |
| 5564 |
); |
| 5565 |
}, |
| 5566 |
label: "", |
| 5567 |
placeholder: __$1( |
| 5568 |
"Search for starting location...", |
| 5569 |
"yatra" |
| 5570 |
), |
| 5571 |
helpText: "", |
| 5572 |
required: false, |
| 5573 |
defaultMapCenter: formData.starting_latitude && formData.starting_longitude ? [ |
| 5574 |
parseFloat(formData.starting_latitude), |
| 5575 |
parseFloat(formData.starting_longitude) |
| 5576 |
] : [20, 0], |
| 5577 |
defaultZoom: formData.starting_latitude && formData.starting_longitude ? 13 : 2, |
| 5578 |
mapHeight: "300px", |
| 5579 |
showMapButton: false, |
| 5580 |
searchLimit: 8, |
| 5581 |
__: __$1, |
| 5582 |
className: "", |
| 5583 |
mapClassName: "rounded-lg" |
| 5584 |
} |
| 5585 |
) }) |
| 5586 |
] }), |
| 5587 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ |
| 5588 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [ |
| 5589 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300 flex items-center gap-2", children: [ |
| 5590 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-4 h-4 bg-blue-100 dark:bg-blue-900 rounded flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-bold text-blue-600 dark:text-blue-400", children: "2" }) }), |
| 5591 |
__$1("GPS Coordinates", "yatra"), |
| 5592 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: [ |
| 5593 |
"(", |
| 5594 |
__$1("Manual override", "yatra"), |
| 5595 |
")" |
| 5596 |
] }) |
| 5597 |
] }), |
| 5598 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 5599 |
"button", |
| 5600 |
{ |
| 5601 |
type: "button", |
| 5602 |
onClick: () => { |
| 5603 |
if (navigator.geolocation) { |
| 5604 |
navigator.geolocation.getCurrentPosition( |
| 5605 |
(position) => { |
| 5606 |
handleFieldChange( |
| 5607 |
"starting_latitude", |
| 5608 |
position.coords.latitude.toString() |
| 5609 |
); |
| 5610 |
handleFieldChange( |
| 5611 |
"starting_longitude", |
| 5612 |
position.coords.longitude.toString() |
| 5613 |
); |
| 5614 |
}, |
| 5615 |
(error) => { |
| 5616 |
let message = __$1( |
| 5617 |
"Unable to get your location", |
| 5618 |
"yatra" |
| 5619 |
); |
| 5620 |
let showHttpsNotice = false; |
| 5621 |
switch (error.code) { |
| 5622 |
case 1: |
| 5623 |
if (error.message.includes( |
| 5624 |
"secure origins" |
| 5625 |
)) { |
| 5626 |
message = __$1( |
| 5627 |
"Location access requires HTTPS. This feature will work on your live HTTPS site.", |
| 5628 |
"yatra" |
| 5629 |
); |
| 5630 |
showHttpsNotice = true; |
| 5631 |
} else { |
| 5632 |
message = __$1( |
| 5633 |
"Location access denied. Please allow location access in your browser.", |
| 5634 |
"yatra" |
| 5635 |
); |
| 5636 |
} |
| 5637 |
break; |
| 5638 |
case 2: |
| 5639 |
message = __$1( |
| 5640 |
"Location information is unavailable. Please try again.", |
| 5641 |
"yatra" |
| 5642 |
); |
| 5643 |
break; |
| 5644 |
case 3: |
| 5645 |
message = __$1( |
| 5646 |
"Location request timed out. Please try again.", |
| 5647 |
"yatra" |
| 5648 |
); |
| 5649 |
break; |
| 5650 |
} |
| 5651 |
if (showHttpsNotice) { |
| 5652 |
alert( |
| 5653 |
message + "\n\n" + __$1( |
| 5654 |
"For local development, you can:\n1. Use a browser extension that allows geolocation on HTTP\n2. Set up a local HTTPS certificate\n3. Test on your live HTTPS site", |
| 5655 |
"yatra" |
| 5656 |
) |
| 5657 |
); |
| 5658 |
} else { |
| 5659 |
alert(message); |
| 5660 |
} |
| 5661 |
} |
| 5662 |
); |
| 5663 |
} else { |
| 5664 |
alert( |
| 5665 |
__$1( |
| 5666 |
"Geolocation is not supported by your browser", |
| 5667 |
"yatra" |
| 5668 |
) |
| 5669 |
); |
| 5670 |
} |
| 5671 |
}, |
| 5672 |
className: "text-xs bg-green-100 text-green-700 px-3 py-1.5 rounded-lg hover:bg-green-200 transition-colors flex items-center gap-1", |
| 5673 |
children: [ |
| 5674 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-3 h-3", children: /* @__PURE__ */ jsxRuntimeExports.jsx("svg", { fill: "currentColor", viewBox: "0 0 20 20", children: /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5675 |
"path", |
| 5676 |
{ |
| 5677 |
fillRule: "evenodd", |
| 5678 |
d: "M5.05 4.05a7 7 0 119.9 9.9L10 18.9l-4.95-4.95a7 7 0 010-9.9zM10 11a2 2 0 100-4 2 2 0 000 4z", |
| 5679 |
clipRule: "evenodd" |
| 5680 |
} |
| 5681 |
) }) }), |
| 5682 |
__$1("Use Current Location", "yatra") |
| 5683 |
] |
| 5684 |
} |
| 5685 |
) }) |
| 5686 |
] }), |
| 5687 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-3", children: [ |
| 5688 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [ |
| 5689 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-xs font-medium text-gray-600 dark:text-gray-400 flex items-center gap-1", children: [ |
| 5690 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-2 h-2 bg-blue-400 rounded-full" }), |
| 5691 |
__$1("Latitude", "yatra") |
| 5692 |
] }), |
| 5693 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5694 |
Input, |
| 5695 |
{ |
| 5696 |
type: "text", |
| 5697 |
value: formData.starting_latitude, |
| 5698 |
onChange: (e) => handleFieldChange( |
| 5699 |
"starting_latitude", |
| 5700 |
e.target.value |
| 5701 |
), |
| 5702 |
className: "w-full text-sm" |
| 5703 |
} |
| 5704 |
) |
| 5705 |
] }), |
| 5706 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [ |
| 5707 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-xs font-medium text-gray-600 dark:text-gray-400 flex items-center gap-1", children: [ |
| 5708 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-2 h-2 bg-blue-400 rounded-full" }), |
| 5709 |
__$1("Longitude", "yatra") |
| 5710 |
] }), |
| 5711 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5712 |
Input, |
| 5713 |
{ |
| 5714 |
type: "text", |
| 5715 |
value: formData.starting_longitude, |
| 5716 |
onChange: (e) => handleFieldChange( |
| 5717 |
"starting_longitude", |
| 5718 |
e.target.value |
| 5719 |
), |
| 5720 |
placeholder: __$1("e.g., 115.0920", "yatra"), |
| 5721 |
className: "w-full text-sm" |
| 5722 |
} |
| 5723 |
) |
| 5724 |
] }) |
| 5725 |
] }), |
| 5726 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: __$1( |
| 5727 |
"Manual coordinate entry. These will be auto-filled when you select a location from the map above.", |
| 5728 |
"yatra" |
| 5729 |
) }) |
| 5730 |
] }) |
| 5731 |
] }), |
| 5732 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [ |
| 5733 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 p-4 bg-gradient-to-r from-green-50 to-emerald-50 dark:from-green-900/20 dark:to-emerald-900/20 rounded-xl border border-green-200 dark:border-green-800", children: [ |
| 5734 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-10 h-10 bg-gradient-to-br from-green-500 to-green-600 rounded-xl flex items-center justify-center shadow-lg", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CheckCircle2, { className: "w-5 h-5 text-white" }) }), |
| 5735 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [ |
| 5736 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-base font-semibold text-green-900 dark:text-green-100", children: __$1("Ending Point", "yatra") }), |
| 5737 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-green-700 dark:text-green-300", children: __$1("Where the journey concludes", "yatra") }) |
| 5738 |
] }), |
| 5739 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-2", children: formData.ending_location && /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5740 |
"div", |
| 5741 |
{ |
| 5742 |
className: "w-2 h-2 bg-green-500 rounded-full animate-pulse", |
| 5743 |
title: __$1("Location set", "yatra") |
| 5744 |
} |
| 5745 |
) }) |
| 5746 |
] }), |
| 5747 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ |
| 5748 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [ |
| 5749 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300 flex items-center gap-2", children: [ |
| 5750 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-4 h-4 bg-green-100 dark:bg-green-900 rounded flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-bold text-green-600 dark:text-green-400", children: "1" }) }), |
| 5751 |
__$1("Ending Location", "yatra") |
| 5752 |
] }), |
| 5753 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ |
| 5754 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: formData.ending_location ? "✓" : __$1("Required", "yatra") }), |
| 5755 |
formData.ending_latitude && formData.ending_longitude && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1 text-xs text-green-600", children: [ |
| 5756 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-2 h-2 bg-green-500 rounded-full" }), |
| 5757 |
__$1("Coords Set", "yatra") |
| 5758 |
] }) |
| 5759 |
] }) |
| 5760 |
] }), |
| 5761 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5762 |
LocationPicker, |
| 5763 |
{ |
| 5764 |
value: { |
| 5765 |
name: formData.ending_location, |
| 5766 |
latitude: formData.ending_latitude, |
| 5767 |
longitude: formData.ending_longitude |
| 5768 |
}, |
| 5769 |
onChange: (locationData) => { |
| 5770 |
handleFieldChange( |
| 5771 |
"ending_location", |
| 5772 |
locationData.name |
| 5773 |
); |
| 5774 |
handleFieldChange( |
| 5775 |
"ending_latitude", |
| 5776 |
locationData.latitude |
| 5777 |
); |
| 5778 |
handleFieldChange( |
| 5779 |
"ending_longitude", |
| 5780 |
locationData.longitude |
| 5781 |
); |
| 5782 |
}, |
| 5783 |
label: "", |
| 5784 |
placeholder: __$1( |
| 5785 |
"Search for ending location...", |
| 5786 |
"yatra" |
| 5787 |
), |
| 5788 |
helpText: "", |
| 5789 |
required: false, |
| 5790 |
defaultMapCenter: formData.ending_latitude && formData.ending_longitude ? [ |
| 5791 |
parseFloat(formData.ending_latitude), |
| 5792 |
parseFloat(formData.ending_longitude) |
| 5793 |
] : formData.starting_latitude && formData.starting_longitude ? [ |
| 5794 |
parseFloat(formData.starting_latitude), |
| 5795 |
parseFloat(formData.starting_longitude) |
| 5796 |
] : [20, 0], |
| 5797 |
defaultZoom: formData.ending_latitude && formData.ending_longitude ? 13 : formData.starting_latitude && formData.starting_longitude ? 13 : 2, |
| 5798 |
mapHeight: "300px", |
| 5799 |
showMapButton: false, |
| 5800 |
searchLimit: 8, |
| 5801 |
__: __$1, |
| 5802 |
className: "", |
| 5803 |
mapClassName: "rounded-lg" |
| 5804 |
} |
| 5805 |
) }) |
| 5806 |
] }), |
| 5807 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ |
| 5808 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-between", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300 flex items-center gap-2", children: [ |
| 5809 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-4 h-4 bg-green-100 dark:bg-green-900 rounded flex items-center justify-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs font-bold text-green-600 dark:text-green-400", children: "2" }) }), |
| 5810 |
__$1("GPS Coordinates", "yatra"), |
| 5811 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: [ |
| 5812 |
"(", |
| 5813 |
__$1("Optional", "yatra"), |
| 5814 |
")" |
| 5815 |
] }) |
| 5816 |
] }) }), |
| 5817 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-3", children: [ |
| 5818 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [ |
| 5819 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-xs font-medium text-gray-600 dark:text-gray-400 flex items-center gap-1", children: [ |
| 5820 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-2 h-2 bg-green-400 rounded-full" }), |
| 5821 |
__$1("Latitude", "yatra") |
| 5822 |
] }), |
| 5823 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5824 |
Input, |
| 5825 |
{ |
| 5826 |
type: "text", |
| 5827 |
value: formData.ending_latitude || "", |
| 5828 |
onChange: (e) => handleFieldChange( |
| 5829 |
"ending_latitude", |
| 5830 |
e.target.value |
| 5831 |
), |
| 5832 |
placeholder: __$1("e.g., -8.5069", "yatra"), |
| 5833 |
className: "w-full text-sm" |
| 5834 |
} |
| 5835 |
) |
| 5836 |
] }), |
| 5837 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [ |
| 5838 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-xs font-medium text-gray-600 dark:text-gray-400 flex items-center gap-1", children: [ |
| 5839 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-2 h-2 bg-green-400 rounded-full" }), |
| 5840 |
__$1("Longitude", "yatra") |
| 5841 |
] }), |
| 5842 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5843 |
Input, |
| 5844 |
{ |
| 5845 |
type: "text", |
| 5846 |
value: formData.ending_longitude || "", |
| 5847 |
onChange: (e) => handleFieldChange( |
| 5848 |
"ending_longitude", |
| 5849 |
e.target.value |
| 5850 |
), |
| 5851 |
placeholder: __$1("e.g., 115.2625", "yatra"), |
| 5852 |
className: "w-full text-sm" |
| 5853 |
} |
| 5854 |
) |
| 5855 |
] }) |
| 5856 |
] }), |
| 5857 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: __$1( |
| 5858 |
"Optional: Manual coordinate entry. Auto-filled when you select a location from the map above.", |
| 5859 |
"yatra" |
| 5860 |
) }) |
| 5861 |
] }) |
| 5862 |
] }) |
| 5863 |
] }) |
| 5864 |
] }), |
| 5865 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 5866 |
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: __$1("Key Landmarks / Points of Interest", "yatra") }), |
| 5867 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5868 |
HelpText, |
| 5869 |
{ |
| 5870 |
text: __$1( |
| 5871 |
"Add notable landmarks or points of interest visited during this trip", |
| 5872 |
"yatra" |
| 5873 |
), |
| 5874 |
className: "mb-2" |
| 5875 |
} |
| 5876 |
), |
| 5877 |
formData.landmarks.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2 mb-2", children: formData.landmarks.map((landmark, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 5878 |
"div", |
| 5879 |
{ |
| 5880 |
className: "flex items-center gap-2 p-2 bg-gray-50 dark:bg-gray-800 rounded border border-gray-200 dark:border-gray-700", |
| 5881 |
children: [ |
| 5882 |
/* @__PURE__ */ jsxRuntimeExports.jsx(MapPin, { className: "w-4 h-4 text-gray-400 flex-shrink-0" }), |
| 5883 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 text-sm text-gray-900 dark:text-white", children: landmark }), |
| 5884 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5885 |
Button, |
| 5886 |
{ |
| 5887 |
type: "button", |
| 5888 |
variant: "ghost", |
| 5889 |
size: "sm", |
| 5890 |
onClick: () => { |
| 5891 |
const newLandmarks = [...formData.landmarks]; |
| 5892 |
newLandmarks.splice(index, 1); |
| 5893 |
handleFieldChange("landmarks", newLandmarks); |
| 5894 |
}, |
| 5895 |
className: "text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-900/20", |
| 5896 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-4 h-4" }) |
| 5897 |
} |
| 5898 |
) |
| 5899 |
] |
| 5900 |
}, |
| 5901 |
index |
| 5902 |
)) }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-4 border-2 border-dashed border-gray-300 dark:border-gray-700 rounded-lg text-center mb-2", children: [ |
| 5903 |
/* @__PURE__ */ jsxRuntimeExports.jsx(MapPin, { className: "w-6 h-6 text-gray-300 dark:text-gray-600 mx-auto mb-2" }), |
| 5904 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: __$1("No landmarks added yet", "yatra") }) |
| 5905 |
] }), |
| 5906 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 5907 |
Button, |
| 5908 |
{ |
| 5909 |
type: "button", |
| 5910 |
variant: "outline", |
| 5911 |
onClick: () => { |
| 5912 |
setShowLandmarkDialog(true); |
| 5913 |
setLandmarkInput(""); |
| 5914 |
}, |
| 5915 |
className: "w-full", |
| 5916 |
children: [ |
| 5917 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4 mr-2" }), |
| 5918 |
__$1("Add Landmark", "yatra") |
| 5919 |
] |
| 5920 |
} |
| 5921 |
) |
| 5922 |
] }) |
| 5923 |
] }) |
| 5924 |
] }); |
| 5925 |
case "duration": |
| 5926 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [ |
| 5927 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2 mb-2", children: [ |
| 5928 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Calendar, { className: "w-5 h-5 text-gray-500" }), |
| 5929 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: __$1("Availability & Booking", "yatra") }), |
| 5930 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5931 |
Badge, |
| 5932 |
{ |
| 5933 |
variant: "outline", |
| 5934 |
className: "text-xs bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-300 border-blue-200 dark:border-blue-800", |
| 5935 |
children: __$1("Recommended", "yatra") |
| 5936 |
} |
| 5937 |
) |
| 5938 |
] }), |
| 5939 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-4", children: [ |
| 5940 |
__$1("When is it available & who can book it?", "yatra"), |
| 5941 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block text-xs text-gray-500 dark:text-gray-400 mt-1", children: __$1( |
| 5942 |
"Set your trip's availability period, capacity limits, and booking requirements. This helps automate bookings and prevent overbooking.", |
| 5943 |
"yatra" |
| 5944 |
) }) |
| 5945 |
] }), |
| 5946 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [ |
| 5947 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-gray-200 dark:border-gray-700 rounded-lg p-5 bg-gray-50 dark:bg-gray-800/30", children: [ |
| 5948 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-sm font-semibold text-gray-900 dark:text-white mb-4 flex items-center gap-2", children: [ |
| 5949 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Calendar, { className: "w-4 h-4 text-blue-500" }), |
| 5950 |
__$1("Availability Period", "yatra") |
| 5951 |
] }), |
| 5952 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ |
| 5953 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [ |
| 5954 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 5955 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5956 |
"label", |
| 5957 |
{ |
| 5958 |
htmlFor: "available_from", |
| 5959 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", |
| 5960 |
children: __$1("Available From", "yatra") |
| 5961 |
} |
| 5962 |
), |
| 5963 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5964 |
DatePicker, |
| 5965 |
{ |
| 5966 |
value: formData.available_from, |
| 5967 |
onChange: (val) => handleFieldChange("available_from", val), |
| 5968 |
placeholder: __$1("Select date", "yatra") |
| 5969 |
} |
| 5970 |
), |
| 5971 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5972 |
HelpText, |
| 5973 |
{ |
| 5974 |
text: __$1( |
| 5975 |
"Earliest date this trip becomes available for booking", |
| 5976 |
"yatra" |
| 5977 |
), |
| 5978 |
className: "mt-2" |
| 5979 |
} |
| 5980 |
) |
| 5981 |
] }), |
| 5982 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 5983 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5984 |
"label", |
| 5985 |
{ |
| 5986 |
htmlFor: "available_to", |
| 5987 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", |
| 5988 |
children: __$1("Available To", "yatra") |
| 5989 |
} |
| 5990 |
), |
| 5991 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 5992 |
DatePicker, |
| 5993 |
{ |
| 5994 |
value: formData.available_to, |
| 5995 |
onChange: (val) => handleFieldChange("available_to", val), |
| 5996 |
placeholder: __$1("Select date", "yatra") |
| 5997 |
} |
| 5998 |
), |
| 5999 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6000 |
HelpText, |
| 6001 |
{ |
| 6002 |
text: __$1( |
| 6003 |
"Latest date this trip is available for booking", |
| 6004 |
"yatra" |
| 6005 |
), |
| 6006 |
className: "mt-2" |
| 6007 |
} |
| 6008 |
) |
| 6009 |
] }) |
| 6010 |
] }), |
| 6011 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6012 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6013 |
"label", |
| 6014 |
{ |
| 6015 |
htmlFor: "booking_window_days", |
| 6016 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", |
| 6017 |
children: __$1("Booking Window (Days in Advance)", "yatra") |
| 6018 |
} |
| 6019 |
), |
| 6020 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6021 |
Input, |
| 6022 |
{ |
| 6023 |
id: "booking_window_days", |
| 6024 |
type: "number", |
| 6025 |
min: "0", |
| 6026 |
value: formData.booking_window_days, |
| 6027 |
onChange: (e) => handleFieldChange("booking_window_days", e.target.value), |
| 6028 |
placeholder: __$1("e.g., 30", "yatra") |
| 6029 |
} |
| 6030 |
), |
| 6031 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6032 |
HelpText, |
| 6033 |
{ |
| 6034 |
text: __$1( |
| 6035 |
"Minimum days in advance customers can book this trip", |
| 6036 |
"yatra" |
| 6037 |
), |
| 6038 |
className: "mt-2" |
| 6039 |
} |
| 6040 |
) |
| 6041 |
] }), |
| 6042 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6043 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6044 |
"label", |
| 6045 |
{ |
| 6046 |
htmlFor: "seasonal_availability", |
| 6047 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", |
| 6048 |
children: __$1("Seasonal Availability Notes", "yatra") |
| 6049 |
} |
| 6050 |
), |
| 6051 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6052 |
Input, |
| 6053 |
{ |
| 6054 |
id: "seasonal_availability", |
| 6055 |
type: "text", |
| 6056 |
value: formData.seasonal_availability, |
| 6057 |
onChange: (e) => handleFieldChange( |
| 6058 |
"seasonal_availability", |
| 6059 |
e.target.value |
| 6060 |
), |
| 6061 |
placeholder: __$1( |
| 6062 |
"e.g., Available year-round except monsoon season", |
| 6063 |
"yatra" |
| 6064 |
) |
| 6065 |
} |
| 6066 |
), |
| 6067 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6068 |
HelpText, |
| 6069 |
{ |
| 6070 |
text: __$1( |
| 6071 |
"General notes about when this trip is typically available", |
| 6072 |
"yatra" |
| 6073 |
), |
| 6074 |
className: "mt-2" |
| 6075 |
} |
| 6076 |
) |
| 6077 |
] }) |
| 6078 |
] }) |
| 6079 |
] }), |
| 6080 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-gray-200 dark:border-gray-700 rounded-lg p-5 bg-gray-50 dark:bg-gray-800/30", children: [ |
| 6081 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-sm font-semibold text-gray-900 dark:text-white mb-4 flex items-center gap-2", children: [ |
| 6082 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Users, { className: "w-4 h-4 text-blue-500" }), |
| 6083 |
__$1("Capacity & Travelers", "yatra") |
| 6084 |
] }), |
| 6085 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ |
| 6086 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [ |
| 6087 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6088 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6089 |
"label", |
| 6090 |
{ |
| 6091 |
htmlFor: "min_travelers", |
| 6092 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", |
| 6093 |
children: __$1("Minimum Travelers", "yatra") |
| 6094 |
} |
| 6095 |
), |
| 6096 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6097 |
Input, |
| 6098 |
{ |
| 6099 |
id: "min_travelers", |
| 6100 |
type: "number", |
| 6101 |
min: "1", |
| 6102 |
value: formData.min_travelers, |
| 6103 |
onChange: (e) => handleFieldChange("min_travelers", e.target.value), |
| 6104 |
className: errors.min_travelers ? "border-red-500" : "" |
| 6105 |
} |
| 6106 |
), |
| 6107 |
errors.min_travelers && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-1.5 text-sm text-red-600 dark:text-red-400 flex items-center gap-1", children: [ |
| 6108 |
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }), |
| 6109 |
errors.min_travelers |
| 6110 |
] }) |
| 6111 |
] }), |
| 6112 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6113 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6114 |
"label", |
| 6115 |
{ |
| 6116 |
htmlFor: "max_travelers", |
| 6117 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", |
| 6118 |
children: __$1("Maximum Travelers", "yatra") |
| 6119 |
} |
| 6120 |
), |
| 6121 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6122 |
Input, |
| 6123 |
{ |
| 6124 |
id: "max_travelers", |
| 6125 |
type: "number", |
| 6126 |
min: "1", |
| 6127 |
value: formData.max_travelers, |
| 6128 |
onChange: (e) => handleFieldChange("max_travelers", e.target.value), |
| 6129 |
className: errors.max_travelers ? "border-red-500" : "" |
| 6130 |
} |
| 6131 |
), |
| 6132 |
errors.max_travelers && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-1.5 text-sm text-red-600 dark:text-red-400 flex items-center gap-1", children: [ |
| 6133 |
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }), |
| 6134 |
errors.max_travelers |
| 6135 |
] }) |
| 6136 |
] }) |
| 6137 |
] }), |
| 6138 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t border-gray-200 dark:border-gray-700 pt-4 mt-4", children: [ |
| 6139 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-2 mb-3", children: [ |
| 6140 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-sm font-medium text-gray-900 dark:text-white", children: __$1("Fallback Settings", "yatra") }), |
| 6141 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6142 |
"span", |
| 6143 |
{ |
| 6144 |
title: __$1( |
| 6145 |
"These settings are used when the trip has no availability dates or recurring rules set. They provide default values for flexible booking.", |
| 6146 |
"yatra" |
| 6147 |
), |
| 6148 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(HelpCircle, { className: "w-4 h-4 text-gray-400 cursor-help" }) |
| 6149 |
} |
| 6150 |
) |
| 6151 |
] }), |
| 6152 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-4 p-3 bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 rounded-lg", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-2", children: [ |
| 6153 |
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4 text-amber-600 dark:text-amber-400 mt-0.5 flex-shrink-0" }), |
| 6154 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs text-amber-800 dark:text-amber-200", children: [ |
| 6155 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-medium mb-1", children: __$1("When are these settings used?", "yatra") }), |
| 6156 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-amber-700 dark:text-amber-300", children: __$1( |
| 6157 |
"These settings apply ONLY when your trip has ZERO availability dates AND ZERO recurring rules. They provide defaults for flexible booking scenarios.", |
| 6158 |
"yatra" |
| 6159 |
) }) |
| 6160 |
] }) |
| 6161 |
] }) }), |
| 6162 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ |
| 6163 |
formData.trip_type === "single_day" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-4 bg-white dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700", children: [ |
| 6164 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("h5", { className: "text-sm font-medium text-gray-900 dark:text-white mb-3 flex items-center gap-2", children: [ |
| 6165 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "w-4 h-4" }), |
| 6166 |
__$1("Day Tour Time Settings", "yatra") |
| 6167 |
] }), |
| 6168 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-4 p-3 bg-gray-50 dark:bg-gray-800 rounded border border-gray-200 dark:border-gray-700", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-3", children: [ |
| 6169 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6170 |
"input", |
| 6171 |
{ |
| 6172 |
type: "checkbox", |
| 6173 |
id: "has_default_time_slots", |
| 6174 |
checked: formData.has_default_time_slots, |
| 6175 |
onChange: (e) => handleFieldChange( |
| 6176 |
"has_default_time_slots", |
| 6177 |
e.target.checked |
| 6178 |
), |
| 6179 |
className: "mt-0.5 w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500" |
| 6180 |
} |
| 6181 |
), |
| 6182 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [ |
| 6183 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6184 |
"label", |
| 6185 |
{ |
| 6186 |
htmlFor: "has_default_time_slots", |
| 6187 |
className: "text-sm font-medium text-gray-900 dark:text-white cursor-pointer", |
| 6188 |
children: __$1("Enable Multiple Time Slots", "yatra") |
| 6189 |
} |
| 6190 |
), |
| 6191 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-xs text-gray-500 dark:text-gray-400", children: __$1( |
| 6192 |
"Allow customers to select from multiple departure times (e.g., Morning, Afternoon, Evening tours)", |
| 6193 |
"yatra" |
| 6194 |
) }) |
| 6195 |
] }) |
| 6196 |
] }) }), |
| 6197 |
formData.has_default_time_slots && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-4 bg-blue-50 dark:bg-blue-900/20 rounded-lg border border-blue-200 dark:border-blue-800", children: [ |
| 6198 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-3", children: [ |
| 6199 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6200 |
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-gray-900 dark:text-white", children: __$1("Time Slots Configuration", "yatra") }), |
| 6201 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-600 dark:text-gray-400 mt-1", children: __$1( |
| 6202 |
"Add multiple departure times for customers to choose from.", |
| 6203 |
"yatra" |
| 6204 |
) }) |
| 6205 |
] }), |
| 6206 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 6207 |
Button, |
| 6208 |
{ |
| 6209 |
type: "button", |
| 6210 |
variant: "outline", |
| 6211 |
size: "sm", |
| 6212 |
onClick: () => { |
| 6213 |
const newSlot = { |
| 6214 |
id: `slot-${Date.now()}`, |
| 6215 |
time: "09:00", |
| 6216 |
label: "" |
| 6217 |
}; |
| 6218 |
handleFieldChange("default_time_slots", [ |
| 6219 |
...formData.default_time_slots, |
| 6220 |
newSlot |
| 6221 |
]); |
| 6222 |
}, |
| 6223 |
className: "flex items-center gap-1", |
| 6224 |
children: [ |
| 6225 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4" }), |
| 6226 |
__$1("Add Time Slot", "yatra") |
| 6227 |
] |
| 6228 |
} |
| 6229 |
) |
| 6230 |
] }), |
| 6231 |
formData.default_time_slots.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center py-8 border-2 border-dashed border-gray-300 dark:border-gray-600 rounded-lg", children: [ |
| 6232 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "w-8 h-8 mx-auto text-gray-400 mb-2" }), |
| 6233 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400 mb-3", children: __$1("No time slots added yet", "yatra") }), |
| 6234 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 6235 |
Button, |
| 6236 |
{ |
| 6237 |
type: "button", |
| 6238 |
variant: "outline", |
| 6239 |
size: "sm", |
| 6240 |
onClick: () => { |
| 6241 |
const newSlot = { |
| 6242 |
id: `slot-${Date.now()}`, |
| 6243 |
time: "09:00", |
| 6244 |
label: __$1("Morning Tour", "yatra") |
| 6245 |
}; |
| 6246 |
handleFieldChange("default_time_slots", [ |
| 6247 |
newSlot |
| 6248 |
]); |
| 6249 |
}, |
| 6250 |
children: [ |
| 6251 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4 mr-1" }), |
| 6252 |
__$1("Add First Time Slot", "yatra") |
| 6253 |
] |
| 6254 |
} |
| 6255 |
) |
| 6256 |
] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: formData.default_time_slots.map( |
| 6257 |
(slot, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 6258 |
"div", |
| 6259 |
{ |
| 6260 |
className: "flex items-start gap-3 p-3 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700", |
| 6261 |
children: [ |
| 6262 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center w-8 h-8 bg-blue-100 dark:bg-blue-900 rounded-full flex-shrink-0 mt-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-semibold text-blue-600 dark:text-blue-400", children: index + 1 }) }), |
| 6263 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 grid grid-cols-1 md:grid-cols-2 gap-3", children: [ |
| 6264 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6265 |
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1", children: __$1("Time", "yatra") }), |
| 6266 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6267 |
Input, |
| 6268 |
{ |
| 6269 |
type: "time", |
| 6270 |
value: slot.time, |
| 6271 |
onChange: (e) => { |
| 6272 |
const updated = [ |
| 6273 |
...formData.default_time_slots |
| 6274 |
]; |
| 6275 |
updated[index] = { |
| 6276 |
...slot, |
| 6277 |
time: e.target.value |
| 6278 |
}; |
| 6279 |
handleFieldChange( |
| 6280 |
"default_time_slots", |
| 6281 |
updated |
| 6282 |
); |
| 6283 |
}, |
| 6284 |
className: "w-full" |
| 6285 |
} |
| 6286 |
) |
| 6287 |
] }), |
| 6288 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6289 |
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1", children: __$1("Label", "yatra") }), |
| 6290 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6291 |
Input, |
| 6292 |
{ |
| 6293 |
type: "text", |
| 6294 |
value: slot.label, |
| 6295 |
onChange: (e) => { |
| 6296 |
const updated = [ |
| 6297 |
...formData.default_time_slots |
| 6298 |
]; |
| 6299 |
updated[index] = { |
| 6300 |
...slot, |
| 6301 |
label: e.target.value |
| 6302 |
}; |
| 6303 |
handleFieldChange( |
| 6304 |
"default_time_slots", |
| 6305 |
updated |
| 6306 |
); |
| 6307 |
}, |
| 6308 |
placeholder: __$1( |
| 6309 |
"e.g., Morning Tour, Afternoon Tour", |
| 6310 |
"yatra" |
| 6311 |
), |
| 6312 |
className: "w-full" |
| 6313 |
} |
| 6314 |
) |
| 6315 |
] }) |
| 6316 |
] }), |
| 6317 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6318 |
Button, |
| 6319 |
{ |
| 6320 |
type: "button", |
| 6321 |
variant: "ghost", |
| 6322 |
size: "sm", |
| 6323 |
onClick: () => { |
| 6324 |
const updated = formData.default_time_slots.filter( |
| 6325 |
(_, i) => i !== index |
| 6326 |
); |
| 6327 |
handleFieldChange( |
| 6328 |
"default_time_slots", |
| 6329 |
updated |
| 6330 |
); |
| 6331 |
}, |
| 6332 |
className: "text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-900/20 flex-shrink-0 mt-1", |
| 6333 |
title: __$1( |
| 6334 |
"Remove time slot", |
| 6335 |
"yatra" |
| 6336 |
), |
| 6337 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-4 h-4" }) |
| 6338 |
} |
| 6339 |
) |
| 6340 |
] |
| 6341 |
}, |
| 6342 |
slot.id |
| 6343 |
) |
| 6344 |
) }) |
| 6345 |
] }), |
| 6346 |
!formData.has_default_time_slots && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6347 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6348 |
"label", |
| 6349 |
{ |
| 6350 |
htmlFor: "departure_time_single", |
| 6351 |
className: "block text-sm font-medium text-gray-900 dark:text-white mb-2", |
| 6352 |
children: __$1("Default Departure Time", "yatra") |
| 6353 |
} |
| 6354 |
), |
| 6355 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6356 |
Input, |
| 6357 |
{ |
| 6358 |
id: "departure_time_single", |
| 6359 |
type: "time", |
| 6360 |
value: formData.departure_time, |
| 6361 |
onChange: (e) => handleFieldChange( |
| 6362 |
"departure_time", |
| 6363 |
e.target.value |
| 6364 |
), |
| 6365 |
className: "max-w-xs" |
| 6366 |
} |
| 6367 |
), |
| 6368 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 text-xs text-gray-500 dark:text-gray-400", children: __$1( |
| 6369 |
"Single departure time for all bookings when multiple time slots are not enabled.", |
| 6370 |
"yatra" |
| 6371 |
) }) |
| 6372 |
] }) |
| 6373 |
] }), |
| 6374 |
formData.trip_type === "multi_day" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-4 bg-white dark:bg-gray-900 rounded-lg border border-gray-200 dark:border-gray-700", children: [ |
| 6375 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("h5", { className: "text-sm font-medium text-gray-900 dark:text-white mb-3 flex items-center gap-2", children: [ |
| 6376 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Calendar, { className: "w-4 h-4" }), |
| 6377 |
__$1("Multi-Day Trip Departure Settings", "yatra") |
| 6378 |
] }), |
| 6379 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6380 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6381 |
"label", |
| 6382 |
{ |
| 6383 |
htmlFor: "departure_time_multiday", |
| 6384 |
className: "block text-sm font-medium text-gray-900 dark:text-white mb-2", |
| 6385 |
children: __$1("Default Departure Time", "yatra") |
| 6386 |
} |
| 6387 |
), |
| 6388 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6389 |
Input, |
| 6390 |
{ |
| 6391 |
id: "departure_time_multiday", |
| 6392 |
type: "time", |
| 6393 |
value: formData.departure_time, |
| 6394 |
onChange: (e) => handleFieldChange( |
| 6395 |
"departure_time", |
| 6396 |
e.target.value |
| 6397 |
), |
| 6398 |
className: "max-w-xs" |
| 6399 |
} |
| 6400 |
), |
| 6401 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 text-xs text-gray-500 dark:text-gray-400", children: __$1( |
| 6402 |
"Default departure time for trips without specific availability dates.", |
| 6403 |
"yatra" |
| 6404 |
) }) |
| 6405 |
] }) |
| 6406 |
] }), |
| 6407 |
!formData.trip_type && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4 bg-gray-50 dark:bg-gray-800/50 rounded-lg border border-gray-200 dark:border-gray-700 text-center", children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: __$1( |
| 6408 |
"Please select a trip type (Day Tour or Multi-Day) to configure fallback settings.", |
| 6409 |
"yatra" |
| 6410 |
) }) }) |
| 6411 |
] }) |
| 6412 |
] }) |
| 6413 |
] }) |
| 6414 |
] }), |
| 6415 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-gray-200 dark:border-gray-700 rounded-lg p-5 bg-gray-50 dark:bg-gray-800/30", children: [ |
| 6416 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-sm font-semibold text-gray-900 dark:text-white mb-4 flex items-center gap-2", children: [ |
| 6417 |
/* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { className: "w-4 h-4 text-blue-500" }), |
| 6418 |
__$1("Booking Policies", "yatra") |
| 6419 |
] }), |
| 6420 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ |
| 6421 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6422 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-sm font-medium text-gray-900 dark:text-white mb-3", children: __$1("Age Restrictions", "yatra") }), |
| 6423 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [ |
| 6424 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6425 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6426 |
"label", |
| 6427 |
{ |
| 6428 |
htmlFor: "age_min", |
| 6429 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", |
| 6430 |
children: __$1("Minimum Age", "yatra") |
| 6431 |
} |
| 6432 |
), |
| 6433 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6434 |
Input, |
| 6435 |
{ |
| 6436 |
id: "age_min", |
| 6437 |
type: "number", |
| 6438 |
min: "0", |
| 6439 |
value: formData.age_min, |
| 6440 |
onChange: (e) => handleFieldChange("age_min", e.target.value), |
| 6441 |
placeholder: __$1("e.g., 18", "yatra"), |
| 6442 |
className: errors.age_min ? "border-red-500" : "" |
| 6443 |
} |
| 6444 |
), |
| 6445 |
errors.age_min && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-1.5 text-sm text-red-600 dark:text-red-400 flex items-center gap-1", children: [ |
| 6446 |
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }), |
| 6447 |
errors.age_min |
| 6448 |
] }) |
| 6449 |
] }), |
| 6450 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6451 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6452 |
"label", |
| 6453 |
{ |
| 6454 |
htmlFor: "age_max", |
| 6455 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", |
| 6456 |
children: __$1("Maximum Age", "yatra") |
| 6457 |
} |
| 6458 |
), |
| 6459 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6460 |
Input, |
| 6461 |
{ |
| 6462 |
id: "age_max", |
| 6463 |
type: "number", |
| 6464 |
min: "0", |
| 6465 |
value: formData.age_max, |
| 6466 |
onChange: (e) => handleFieldChange("age_max", e.target.value), |
| 6467 |
placeholder: __$1("e.g., 65", "yatra"), |
| 6468 |
className: errors.age_max ? "border-red-500" : "" |
| 6469 |
} |
| 6470 |
), |
| 6471 |
errors.age_max && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-1.5 text-sm text-red-600 dark:text-red-400 flex items-center gap-1", children: [ |
| 6472 |
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }), |
| 6473 |
errors.age_max |
| 6474 |
] }) |
| 6475 |
] }) |
| 6476 |
] }) |
| 6477 |
] }), |
| 6478 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6479 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-sm font-medium text-gray-900 dark:text-white mb-3", children: __$1("Trip Requirements", "yatra") }), |
| 6480 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ |
| 6481 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6482 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6483 |
"label", |
| 6484 |
{ |
| 6485 |
htmlFor: "physical_requirements", |
| 6486 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", |
| 6487 |
children: __$1("Physical Requirements", "yatra") |
| 6488 |
} |
| 6489 |
), |
| 6490 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6491 |
"textarea", |
| 6492 |
{ |
| 6493 |
id: "physical_requirements", |
| 6494 |
value: formData.physical_requirements, |
| 6495 |
onChange: (e) => handleFieldChange( |
| 6496 |
"physical_requirements", |
| 6497 |
e.target.value |
| 6498 |
), |
| 6499 |
placeholder: __$1( |
| 6500 |
"e.g., Moderate fitness level required. Some walking involved but no strenuous activities.", |
| 6501 |
"yatra" |
| 6502 |
), |
| 6503 |
rows: 3, |
| 6504 |
className: "flex w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-sm ring-offset-white placeholder:text-gray-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 dark:bg-gray-800 dark:ring-offset-gray-900 dark:placeholder:text-gray-400 dark:focus-visible:ring-blue-400 resize-none" |
| 6505 |
} |
| 6506 |
) |
| 6507 |
] }), |
| 6508 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6509 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6510 |
"label", |
| 6511 |
{ |
| 6512 |
htmlFor: "visa_requirements", |
| 6513 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", |
| 6514 |
children: __$1("Visa Requirements", "yatra") |
| 6515 |
} |
| 6516 |
), |
| 6517 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6518 |
"textarea", |
| 6519 |
{ |
| 6520 |
id: "visa_requirements", |
| 6521 |
value: formData.visa_requirements, |
| 6522 |
onChange: (e) => handleFieldChange( |
| 6523 |
"visa_requirements", |
| 6524 |
e.target.value |
| 6525 |
), |
| 6526 |
placeholder: __$1( |
| 6527 |
"e.g., Tourist visa required. Can be obtained on arrival or in advance.", |
| 6528 |
"yatra" |
| 6529 |
), |
| 6530 |
rows: 3, |
| 6531 |
className: "flex w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-sm ring-offset-white placeholder:text-gray-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 dark:bg-gray-800 dark:ring-offset-gray-900 dark:placeholder:text-gray-400 dark:focus-visible:ring-blue-400 resize-none" |
| 6532 |
} |
| 6533 |
) |
| 6534 |
] }), |
| 6535 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6536 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6537 |
"label", |
| 6538 |
{ |
| 6539 |
htmlFor: "vaccination_requirements", |
| 6540 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", |
| 6541 |
children: __$1("Vaccination Requirements", "yatra") |
| 6542 |
} |
| 6543 |
), |
| 6544 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6545 |
"textarea", |
| 6546 |
{ |
| 6547 |
id: "vaccination_requirements", |
| 6548 |
value: formData.vaccination_requirements, |
| 6549 |
onChange: (e) => handleFieldChange( |
| 6550 |
"vaccination_requirements", |
| 6551 |
e.target.value |
| 6552 |
), |
| 6553 |
placeholder: __$1( |
| 6554 |
"e.g., No mandatory vaccinations. Recommended: Hepatitis A, Typhoid, and routine vaccinations.", |
| 6555 |
"yatra" |
| 6556 |
), |
| 6557 |
rows: 3, |
| 6558 |
className: "flex w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-sm ring-offset-white placeholder:text-gray-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 dark:bg-gray-800 dark:ring-offset-gray-900 dark:placeholder:text-gray-400 dark:focus-visible:ring-blue-400 resize-none" |
| 6559 |
} |
| 6560 |
) |
| 6561 |
] }) |
| 6562 |
] }) |
| 6563 |
] }), |
| 6564 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6565 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-3", children: [ |
| 6566 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-sm font-medium text-gray-900 dark:text-white", children: __$1("Cancellation Policy", "yatra") }), |
| 6567 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6568 |
AiFieldAffordance, |
| 6569 |
{ |
| 6570 |
task: "trip-cancellation-policy", |
| 6571 |
label: __$1("Cancellation Policy", "yatra"), |
| 6572 |
value: formData.cancellation_policy, |
| 6573 |
onAccept: (v) => handleFieldChange("cancellation_policy", v), |
| 6574 |
buildContext: () => buildTripAiContext(formData) |
| 6575 |
} |
| 6576 |
) |
| 6577 |
] }), |
| 6578 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6579 |
"textarea", |
| 6580 |
{ |
| 6581 |
id: "cancellation_policy", |
| 6582 |
value: formData.cancellation_policy, |
| 6583 |
onChange: (e) => handleFieldChange("cancellation_policy", e.target.value), |
| 6584 |
placeholder: __$1( |
| 6585 |
"e.g., Free cancellation up to 30 days before departure. 50% refund for cancellations 15-30 days before. No refund for cancellations less than 15 days before.", |
| 6586 |
"yatra" |
| 6587 |
), |
| 6588 |
rows: 4, |
| 6589 |
className: "flex w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-sm ring-offset-white placeholder:text-gray-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 dark:bg-gray-800 dark:ring-offset-gray-900 dark:placeholder:text-gray-400 dark:focus-visible:ring-blue-400 resize-none" |
| 6590 |
} |
| 6591 |
) |
| 6592 |
] }) |
| 6593 |
] }) |
| 6594 |
] }), |
| 6595 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-gray-200 dark:border-gray-700 rounded-lg p-5 bg-gray-50 dark:bg-gray-800/30", children: [ |
| 6596 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-sm font-semibold text-gray-900 dark:text-white mb-4 flex items-center gap-2", children: [ |
| 6597 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Calendar, { className: "w-4 h-4 text-blue-500" }), |
| 6598 |
__$1("Booking Availability", "yatra"), |
| 6599 |
/* @__PURE__ */ jsxRuntimeExports.jsx(ProBadge, { isProActive: isPro }) |
| 6600 |
] }), |
| 6601 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6602 |
ProFeature, |
| 6603 |
{ |
| 6604 |
description: __$1( |
| 6605 |
"disable the booking calendar and make trips enquiry-only", |
| 6606 |
"yatra" |
| 6607 |
), |
| 6608 |
moduleName: __$1("Enquiry Only Mode", "yatra"), |
| 6609 |
pricingUrl: "https://wpyatra.com/pricing", |
| 6610 |
isProActive: isPro, |
| 6611 |
isModuleEnabled: isPro, |
| 6612 |
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-3", children: [ |
| 6613 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center h-5 mt-0.5", children: /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6614 |
"input", |
| 6615 |
{ |
| 6616 |
id: "disable_booking", |
| 6617 |
type: "checkbox", |
| 6618 |
checked: formData.disable_booking, |
| 6619 |
onChange: (e) => handleFieldChange("disable_booking", e.target.checked), |
| 6620 |
className: "w-4 h-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600 dark:bg-gray-700 cursor-pointer" |
| 6621 |
} |
| 6622 |
) }), |
| 6623 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6624 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6625 |
"label", |
| 6626 |
{ |
| 6627 |
htmlFor: "disable_booking", |
| 6628 |
className: "block text-sm font-medium text-gray-900 dark:text-white cursor-pointer", |
| 6629 |
children: __$1("Disable Booking Calendar", "yatra") |
| 6630 |
} |
| 6631 |
), |
| 6632 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-xs text-gray-500 dark:text-gray-400", children: __$1( |
| 6633 |
"When enabled, the booking form and date picker will be hidden. Visitors can only send an enquiry for this trip.", |
| 6634 |
"yatra" |
| 6635 |
) }) |
| 6636 |
] }) |
| 6637 |
] }) |
| 6638 |
} |
| 6639 |
) |
| 6640 |
] }), |
| 6641 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-gray-200 dark:border-gray-700 rounded-lg p-5 bg-gray-50 dark:bg-gray-800/30", children: [ |
| 6642 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-sm font-semibold text-gray-900 dark:text-white mb-4 flex items-center gap-2", children: [ |
| 6643 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Home, { className: "w-4 h-4 text-blue-500" }), |
| 6644 |
__$1("Accommodation", "yatra") |
| 6645 |
] }), |
| 6646 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ |
| 6647 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [ |
| 6648 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6649 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6650 |
"label", |
| 6651 |
{ |
| 6652 |
htmlFor: "accommodation_type", |
| 6653 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", |
| 6654 |
children: __$1("Accommodation Type", "yatra") |
| 6655 |
} |
| 6656 |
), |
| 6657 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6658 |
Input, |
| 6659 |
{ |
| 6660 |
id: "accommodation_type", |
| 6661 |
type: "text", |
| 6662 |
value: formData.accommodation_type, |
| 6663 |
onChange: (e) => handleFieldChange( |
| 6664 |
"accommodation_type", |
| 6665 |
e.target.value |
| 6666 |
), |
| 6667 |
placeholder: __$1( |
| 6668 |
"e.g., Hotel, Resort, Teahouse, Camping", |
| 6669 |
"yatra" |
| 6670 |
) |
| 6671 |
} |
| 6672 |
) |
| 6673 |
] }), |
| 6674 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6675 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6676 |
"label", |
| 6677 |
{ |
| 6678 |
htmlFor: "meal_plan", |
| 6679 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", |
| 6680 |
children: __$1("Meal Plan", "yatra") |
| 6681 |
} |
| 6682 |
), |
| 6683 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6684 |
Select, |
| 6685 |
{ |
| 6686 |
id: "meal_plan", |
| 6687 |
value: formData.meal_plan, |
| 6688 |
onChange: (e) => handleFieldChange("meal_plan", e.target.value), |
| 6689 |
children: MEAL_PLAN_SELECT_OPTIONS.map(({ value, label }) => /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6690 |
"option", |
| 6691 |
{ |
| 6692 |
value, |
| 6693 |
children: label |
| 6694 |
}, |
| 6695 |
value || "meal-plan-empty" |
| 6696 |
)) |
| 6697 |
} |
| 6698 |
), |
| 6699 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1.5 text-xs text-gray-500 dark:text-gray-400", children: __$1( |
| 6700 |
"Tells travelers which meals are included with lodging (e.g. breakfast only vs full board).", |
| 6701 |
"yatra" |
| 6702 |
) }) |
| 6703 |
] }) |
| 6704 |
] }), |
| 6705 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6706 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6707 |
"label", |
| 6708 |
{ |
| 6709 |
htmlFor: "accommodation_details", |
| 6710 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", |
| 6711 |
children: __$1("Accommodation Details", "yatra") |
| 6712 |
} |
| 6713 |
), |
| 6714 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6715 |
"textarea", |
| 6716 |
{ |
| 6717 |
id: "accommodation_details", |
| 6718 |
value: formData.accommodation_details, |
| 6719 |
onChange: (e) => handleFieldChange( |
| 6720 |
"accommodation_details", |
| 6721 |
e.target.value |
| 6722 |
), |
| 6723 |
placeholder: __$1( |
| 6724 |
"e.g., 4-star beachfront resort with private balconies, infinity pool, and spa facilities", |
| 6725 |
"yatra" |
| 6726 |
), |
| 6727 |
rows: 3, |
| 6728 |
className: "flex w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-sm ring-offset-white placeholder:text-gray-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 dark:bg-gray-800 dark:ring-offset-gray-900 dark:placeholder:text-gray-400 dark:focus-visible:ring-blue-400 resize-none" |
| 6729 |
} |
| 6730 |
) |
| 6731 |
] }) |
| 6732 |
] }) |
| 6733 |
] }), |
| 6734 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-gray-200 dark:border-gray-700 rounded-lg p-5 bg-gray-50 dark:bg-gray-800/30", children: [ |
| 6735 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-sm font-semibold text-gray-900 dark:text-white mb-4 flex items-center gap-2", children: [ |
| 6736 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Car, { className: "w-4 h-4 text-blue-500" }), |
| 6737 |
__$1("Transportation", "yatra") |
| 6738 |
] }), |
| 6739 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ |
| 6740 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ |
| 6741 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6742 |
"input", |
| 6743 |
{ |
| 6744 |
type: "checkbox", |
| 6745 |
id: "transportation_included", |
| 6746 |
checked: formData.transportation_included, |
| 6747 |
onChange: (e) => handleFieldChange( |
| 6748 |
"transportation_included", |
| 6749 |
e.target.checked |
| 6750 |
), |
| 6751 |
className: "w-4 h-4 text-blue-600 bg-white border-gray-300 rounded focus:ring-blue-500 dark:focus:ring-blue-600 dark:ring-offset-gray-800 focus:ring-2 dark:bg-gray-700 dark:border-gray-600" |
| 6752 |
} |
| 6753 |
), |
| 6754 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6755 |
"label", |
| 6756 |
{ |
| 6757 |
htmlFor: "transportation_included", |
| 6758 |
className: "text-sm font-medium text-gray-900 dark:text-white", |
| 6759 |
children: __$1("Transportation Included", "yatra") |
| 6760 |
} |
| 6761 |
) |
| 6762 |
] }), |
| 6763 |
formData.transportation_included && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ |
| 6764 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [ |
| 6765 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6766 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6767 |
"label", |
| 6768 |
{ |
| 6769 |
htmlFor: "pickup_location", |
| 6770 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", |
| 6771 |
children: __$1("Pickup Location", "yatra") |
| 6772 |
} |
| 6773 |
), |
| 6774 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6775 |
Input, |
| 6776 |
{ |
| 6777 |
id: "pickup_location", |
| 6778 |
type: "text", |
| 6779 |
value: formData.pickup_location, |
| 6780 |
onChange: (e) => handleFieldChange( |
| 6781 |
"pickup_location", |
| 6782 |
e.target.value |
| 6783 |
), |
| 6784 |
placeholder: __$1( |
| 6785 |
"e.g., Airport, Hotel, City Center", |
| 6786 |
"yatra" |
| 6787 |
) |
| 6788 |
} |
| 6789 |
) |
| 6790 |
] }), |
| 6791 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6792 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6793 |
"label", |
| 6794 |
{ |
| 6795 |
htmlFor: "dropoff_location", |
| 6796 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", |
| 6797 |
children: __$1("Dropoff Location", "yatra") |
| 6798 |
} |
| 6799 |
), |
| 6800 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6801 |
Input, |
| 6802 |
{ |
| 6803 |
id: "dropoff_location", |
| 6804 |
type: "text", |
| 6805 |
value: formData.dropoff_location, |
| 6806 |
onChange: (e) => handleFieldChange( |
| 6807 |
"dropoff_location", |
| 6808 |
e.target.value |
| 6809 |
), |
| 6810 |
placeholder: __$1( |
| 6811 |
"e.g., Airport, Hotel, City Center", |
| 6812 |
"yatra" |
| 6813 |
) |
| 6814 |
} |
| 6815 |
) |
| 6816 |
] }) |
| 6817 |
] }), |
| 6818 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6819 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6820 |
"label", |
| 6821 |
{ |
| 6822 |
htmlFor: "transportation_details", |
| 6823 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", |
| 6824 |
children: __$1("Transportation Details", "yatra") |
| 6825 |
} |
| 6826 |
), |
| 6827 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6828 |
"textarea", |
| 6829 |
{ |
| 6830 |
id: "transportation_details", |
| 6831 |
value: formData.transportation_details, |
| 6832 |
onChange: (e) => handleFieldChange( |
| 6833 |
"transportation_details", |
| 6834 |
e.target.value |
| 6835 |
), |
| 6836 |
placeholder: __$1( |
| 6837 |
"e.g., Private air-conditioned vehicle with professional driver", |
| 6838 |
"yatra" |
| 6839 |
), |
| 6840 |
rows: 3, |
| 6841 |
className: "flex w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-sm ring-offset-white placeholder:text-gray-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 dark:bg-gray-800 dark:ring-offset-gray-900 dark:placeholder:text-gray-400 dark:focus-visible:ring-blue-400 resize-none" |
| 6842 |
} |
| 6843 |
) |
| 6844 |
] }) |
| 6845 |
] }) |
| 6846 |
] }) |
| 6847 |
] }) |
| 6848 |
] }) |
| 6849 |
] }); |
| 6850 |
case "categorization": |
| 6851 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [ |
| 6852 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2 mb-2", children: [ |
| 6853 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Tag, { className: "w-5 h-5 text-gray-500" }), |
| 6854 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: __$1("Categories & Attributes", "yatra") }), |
| 6855 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6856 |
Badge, |
| 6857 |
{ |
| 6858 |
variant: "outline", |
| 6859 |
className: "text-xs bg-amber-50 dark:bg-amber-900/20 text-amber-600 dark:text-amber-300 border-amber-200 dark:border-amber-800", |
| 6860 |
children: __$1("Recommended", "yatra") |
| 6861 |
} |
| 6862 |
) |
| 6863 |
] }), |
| 6864 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-4", children: [ |
| 6865 |
__$1("How should travelers find this trip?", "yatra"), |
| 6866 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block text-xs text-gray-500 dark:text-gray-400 mt-1", children: __$1( |
| 6867 |
"Organize your trip with categories, activities, and custom attributes to help travelers discover it through search and filters.", |
| 6868 |
"yatra" |
| 6869 |
) }) |
| 6870 |
] }), |
| 6871 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [ |
| 6872 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-gray-200 dark:border-gray-700 rounded-lg p-5 bg-gray-50 dark:bg-gray-800/30", children: [ |
| 6873 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-sm font-semibold text-gray-900 dark:text-white mb-4 flex items-center gap-2", children: [ |
| 6874 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Tag, { className: "w-4 h-4 text-blue-500" }), |
| 6875 |
__$1("Categories & Classification", "yatra") |
| 6876 |
] }), |
| 6877 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ |
| 6878 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6879 |
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: __$1("Trip Categories", "yatra") }), |
| 6880 |
tripCategories && tripCategories.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6881 |
MultiSelect, |
| 6882 |
{ |
| 6883 |
value: formData.trip_category, |
| 6884 |
onChange: (values) => handleFieldChange( |
| 6885 |
"trip_category", |
| 6886 |
values.map((v) => Number(v)) |
| 6887 |
), |
| 6888 |
options: (() => { |
| 6889 |
const flattenCategories = (cats, prefix = "") => { |
| 6890 |
const result = []; |
| 6891 |
cats.forEach((cat) => { |
| 6892 |
result.push({ |
| 6893 |
value: cat.id, |
| 6894 |
label: prefix + cat.name |
| 6895 |
}); |
| 6896 |
if (cat.subcategories && cat.subcategories.length > 0) { |
| 6897 |
result.push( |
| 6898 |
...flattenCategories( |
| 6899 |
cat.subcategories, |
| 6900 |
prefix + "— " |
| 6901 |
) |
| 6902 |
); |
| 6903 |
} |
| 6904 |
}); |
| 6905 |
return result; |
| 6906 |
}; |
| 6907 |
return flattenCategories(tripCategories); |
| 6908 |
})(), |
| 6909 |
placeholder: __$1("Select categories...", "yatra"), |
| 6910 |
searchPlaceholder: __$1("Search categories...", "yatra") |
| 6911 |
} |
| 6912 |
) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4 border-2 border-dashed border-gray-300 dark:border-gray-700 rounded-lg text-center", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: [ |
| 6913 |
__$1("No categories available. ", "yatra"), |
| 6914 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6915 |
"a", |
| 6916 |
{ |
| 6917 |
href: "/wp-admin/admin.php?page=yatra&subpage=trips&tab=categories", |
| 6918 |
target: "_blank", |
| 6919 |
rel: "noopener noreferrer", |
| 6920 |
className: "text-blue-600 hover:text-blue-700 underline", |
| 6921 |
children: __$1("Create categories here", "yatra") |
| 6922 |
} |
| 6923 |
) |
| 6924 |
] }) }), |
| 6925 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6926 |
HelpText, |
| 6927 |
{ |
| 6928 |
text: __$1( |
| 6929 |
"Select one or more categories for this trip", |
| 6930 |
"yatra" |
| 6931 |
), |
| 6932 |
className: "mt-2" |
| 6933 |
} |
| 6934 |
) |
| 6935 |
] }), |
| 6936 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6937 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6938 |
"label", |
| 6939 |
{ |
| 6940 |
htmlFor: "difficulty_level", |
| 6941 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", |
| 6942 |
children: __$1("Difficulty Level", "yatra") |
| 6943 |
} |
| 6944 |
), |
| 6945 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 6946 |
Select, |
| 6947 |
{ |
| 6948 |
id: "difficulty_level", |
| 6949 |
value: formData.difficulty_level, |
| 6950 |
onChange: (e) => handleFieldChange("difficulty_level", e.target.value), |
| 6951 |
disabled: isLoadingDifficultyLevels, |
| 6952 |
children: [ |
| 6953 |
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "", children: __$1("Select difficulty", "yatra") }), |
| 6954 |
isLoadingDifficultyLevels && /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "", disabled: true, children: __$1("Loading difficulty levels...", "yatra") }), |
| 6955 |
!isLoadingDifficultyLevels && difficultyLevels.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "", disabled: true, children: __$1( |
| 6956 |
"No difficulty levels available - Click below to create", |
| 6957 |
"yatra" |
| 6958 |
) }), |
| 6959 |
!isLoadingDifficultyLevels && difficultyLevels.map((level) => { |
| 6960 |
var _a3; |
| 6961 |
return /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6962 |
"option", |
| 6963 |
{ |
| 6964 |
value: ((_a3 = level.id) == null ? void 0 : _a3.toString()) || "", |
| 6965 |
children: level.name |
| 6966 |
}, |
| 6967 |
`difficulty-${level.id}` |
| 6968 |
); |
| 6969 |
}) |
| 6970 |
] |
| 6971 |
} |
| 6972 |
), |
| 6973 |
!isLoadingDifficultyLevels && difficultyLevels.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-3 p-3 bg-amber-50 dark:bg-amber-900/20 border border-amber-200 dark:border-amber-800 rounded-md", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-amber-700 dark:text-amber-300", children: [ |
| 6974 |
__$1("No difficulty levels available. ", "yatra"), |
| 6975 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6976 |
"a", |
| 6977 |
{ |
| 6978 |
href: "/wp-admin/admin.php?page=yatra&subpage=trips&tab=difficulty-levels", |
| 6979 |
target: "_blank", |
| 6980 |
rel: "noopener noreferrer", |
| 6981 |
className: "text-amber-800 hover:text-amber-900 underline font-medium", |
| 6982 |
children: __$1("Create difficulty levels here", "yatra") |
| 6983 |
} |
| 6984 |
) |
| 6985 |
] }) }), |
| 6986 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 6987 |
HelpText, |
| 6988 |
{ |
| 6989 |
text: __$1( |
| 6990 |
"Physical difficulty level required for this trip", |
| 6991 |
"yatra" |
| 6992 |
), |
| 6993 |
className: "mt-2" |
| 6994 |
} |
| 6995 |
) |
| 6996 |
] }), |
| 6997 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 6998 |
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: __$1("Activity Types", "yatra") }), |
| 6999 |
activitiesData && activitiesData.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7000 |
MultiSelect, |
| 7001 |
{ |
| 7002 |
value: formData.activity_types, |
| 7003 |
onChange: (values) => handleFieldChange( |
| 7004 |
"activity_types", |
| 7005 |
values.map((v) => Number(v)) |
| 7006 |
), |
| 7007 |
options: activitiesData.map((activity) => ({ |
| 7008 |
value: activity.id, |
| 7009 |
label: activity.name |
| 7010 |
})), |
| 7011 |
placeholder: __$1("Select activities...", "yatra"), |
| 7012 |
searchPlaceholder: __$1("Search activities...", "yatra") |
| 7013 |
} |
| 7014 |
) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "p-4 border-2 border-dashed border-gray-300 dark:border-gray-700 rounded-lg text-center", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-gray-500 dark:text-gray-400", children: [ |
| 7015 |
__$1("No activities available. ", "yatra"), |
| 7016 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7017 |
"a", |
| 7018 |
{ |
| 7019 |
href: "/wp-admin/admin.php?page=yatra&subpage=trips&tab=activities", |
| 7020 |
target: "_blank", |
| 7021 |
rel: "noopener noreferrer", |
| 7022 |
className: "text-blue-600 hover:text-blue-700 underline", |
| 7023 |
children: __$1("Create activities here", "yatra") |
| 7024 |
} |
| 7025 |
) |
| 7026 |
] }) }), |
| 7027 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7028 |
HelpText, |
| 7029 |
{ |
| 7030 |
text: __$1( |
| 7031 |
"Select all activities included in this trip", |
| 7032 |
"yatra" |
| 7033 |
), |
| 7034 |
className: "mt-2" |
| 7035 |
} |
| 7036 |
) |
| 7037 |
] }), |
| 7038 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 7039 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7040 |
"label", |
| 7041 |
{ |
| 7042 |
htmlFor: "featured_priority", |
| 7043 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", |
| 7044 |
children: __$1("Featured Priority", "yatra") |
| 7045 |
} |
| 7046 |
), |
| 7047 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 7048 |
Select, |
| 7049 |
{ |
| 7050 |
id: "featured_priority", |
| 7051 |
value: formData.featured_priority, |
| 7052 |
onChange: (e) => handleFieldChange( |
| 7053 |
"featured_priority", |
| 7054 |
e.target.value |
| 7055 |
), |
| 7056 |
children: [ |
| 7057 |
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "none", children: __$1("None", "yatra") }), |
| 7058 |
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "featured", children: __$1("Featured", "yatra") }), |
| 7059 |
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "new", children: __$1("New", "yatra") }), |
| 7060 |
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "limited", children: __$1("Limited Time", "yatra") }) |
| 7061 |
] |
| 7062 |
} |
| 7063 |
), |
| 7064 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7065 |
HelpText, |
| 7066 |
{ |
| 7067 |
text: __$1( |
| 7068 |
"Special designation for frontend display and promotion", |
| 7069 |
"yatra" |
| 7070 |
), |
| 7071 |
className: "mt-2" |
| 7072 |
} |
| 7073 |
) |
| 7074 |
] }) |
| 7075 |
] }) |
| 7076 |
] }), |
| 7077 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-gray-200 dark:border-gray-700 rounded-lg p-5 bg-gray-50 dark:bg-gray-800/30", children: [ |
| 7078 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-sm font-semibold text-gray-900 dark:text-white mb-4 flex items-center gap-2", children: [ |
| 7079 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Settings, { className: "w-4 h-4 text-blue-500" }), |
| 7080 |
__$1("Custom Attributes", "yatra") |
| 7081 |
] }), |
| 7082 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mb-4", children: __$1( |
| 7083 |
"Add custom attributes for advanced filtering and search capabilities.", |
| 7084 |
"yatra" |
| 7085 |
) }), |
| 7086 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7087 |
TripAttributesSection, |
| 7088 |
{ |
| 7089 |
formData, |
| 7090 |
handleFieldChange, |
| 7091 |
tripId: tripId || void 0, |
| 7092 |
isEditMode, |
| 7093 |
tripAttributesData, |
| 7094 |
tripAttributesReady |
| 7095 |
} |
| 7096 |
) |
| 7097 |
] }) |
| 7098 |
] }) |
| 7099 |
] }); |
| 7100 |
case "media": |
| 7101 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [ |
| 7102 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2 mb-2", children: [ |
| 7103 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Image, { className: "w-5 h-5 text-gray-500" }), |
| 7104 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: __$1("Media & Content", "yatra") }), |
| 7105 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7106 |
Badge, |
| 7107 |
{ |
| 7108 |
variant: "outline", |
| 7109 |
className: "text-xs bg-amber-50 dark:bg-amber-900/20 text-amber-600 dark:text-amber-300 border-amber-200 dark:border-amber-800", |
| 7110 |
children: __$1("Recommended", "yatra") |
| 7111 |
} |
| 7112 |
) |
| 7113 |
] }), |
| 7114 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-6", children: [ |
| 7115 |
__$1( |
| 7116 |
"Add visual content, videos, stories, and testimonials to showcase your trip", |
| 7117 |
"yatra" |
| 7118 |
), |
| 7119 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block text-xs text-gray-500 dark:text-gray-400 mt-1", children: __$1( |
| 7120 |
"Optional, but adding rich media greatly increases engagement and conversions.", |
| 7121 |
"yatra" |
| 7122 |
) }) |
| 7123 |
] }), |
| 7124 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [ |
| 7125 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [ |
| 7126 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { children: [ |
| 7127 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __$1("Photo Gallery", "yatra") }), |
| 7128 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: __$1( |
| 7129 |
"Upload images to showcase your trip. These will be displayed on the trip page.", |
| 7130 |
"yatra" |
| 7131 |
) }) |
| 7132 |
] }), |
| 7133 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { children: [ |
| 7134 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 md:grid-cols-3 gap-4 mb-4", children: [ |
| 7135 |
formData.gallery_images.map((image, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative group", children: [ |
| 7136 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "aspect-video bg-gray-100 dark:bg-gray-800 rounded-lg flex items-center justify-center overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7137 |
"img", |
| 7138 |
{ |
| 7139 |
src: image.thumbnail_url || image.url, |
| 7140 |
alt: image.alt_text || `Gallery ${index + 1}`, |
| 7141 |
className: "w-full h-full object-cover" |
| 7142 |
} |
| 7143 |
) }), |
| 7144 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "absolute top-2 left-2 flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity", children: [ |
| 7145 |
index > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7146 |
"button", |
| 7147 |
{ |
| 7148 |
type: "button", |
| 7149 |
onClick: () => handleGalleryReorder(index, index - 1), |
| 7150 |
className: "bg-black/60 text-white rounded p-1 hover:bg-black/80", |
| 7151 |
title: __$1("Move left", "yatra"), |
| 7152 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronLeft, { className: "w-4 h-4" }) |
| 7153 |
} |
| 7154 |
), |
| 7155 |
index < formData.gallery_images.length - 1 && /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7156 |
"button", |
| 7157 |
{ |
| 7158 |
type: "button", |
| 7159 |
onClick: () => handleGalleryReorder(index, index + 1), |
| 7160 |
className: "bg-black/60 text-white rounded p-1 hover:bg-black/80", |
| 7161 |
title: __$1("Move right", "yatra"), |
| 7162 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "w-4 h-4" }) |
| 7163 |
} |
| 7164 |
) |
| 7165 |
] }), |
| 7166 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "absolute bottom-2 left-2 bg-black/60 text-white text-xs px-1.5 py-0.5 rounded", children: index + 1 }), |
| 7167 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7168 |
"button", |
| 7169 |
{ |
| 7170 |
type: "button", |
| 7171 |
onClick: () => handleGalleryRemove(index), |
| 7172 |
className: "absolute top-2 right-2 bg-red-600 text-white rounded-full p-1 opacity-0 group-hover:opacity-100 transition-opacity", |
| 7173 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-4 h-4" }) |
| 7174 |
} |
| 7175 |
) |
| 7176 |
] }, index)), |
| 7177 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 7178 |
"button", |
| 7179 |
{ |
| 7180 |
type: "button", |
| 7181 |
onClick: handleGalleryAdd, |
| 7182 |
className: `aspect-video border-2 border-dashed rounded-lg flex flex-col items-center justify-center transition-colors ${errors.gallery_images ? "border-red-500 dark:border-red-600 bg-red-50 dark:bg-red-900/20" : "border-gray-300 dark:border-gray-700 hover:border-blue-500 dark:hover:border-blue-400"}`, |
| 7183 |
children: [ |
| 7184 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7185 |
Upload, |
| 7186 |
{ |
| 7187 |
className: `w-8 h-8 mb-2 ${errors.gallery_images ? "text-red-400" : "text-gray-400"}` |
| 7188 |
} |
| 7189 |
), |
| 7190 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7191 |
"span", |
| 7192 |
{ |
| 7193 |
className: `text-sm ${errors.gallery_images ? "text-red-600 dark:text-red-400" : "text-gray-600 dark:text-gray-400"}`, |
| 7194 |
children: __$1("Add Image", "yatra") |
| 7195 |
} |
| 7196 |
) |
| 7197 |
] |
| 7198 |
} |
| 7199 |
) |
| 7200 |
] }), |
| 7201 |
errors.gallery_images && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-2 text-sm text-red-600 dark:text-red-400 flex items-center gap-1", children: [ |
| 7202 |
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }), |
| 7203 |
errors.gallery_images |
| 7204 |
] }) |
| 7205 |
] }) |
| 7206 |
] }), |
| 7207 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [ |
| 7208 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { children: [ |
| 7209 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __$1("Video & Virtual Tour", "yatra") }), |
| 7210 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: __$1( |
| 7211 |
"Add video content to showcase your trip visually", |
| 7212 |
"yatra" |
| 7213 |
) }) |
| 7214 |
] }), |
| 7215 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-4", children: [ |
| 7216 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 7217 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: [ |
| 7218 |
__$1("Video URL", "yatra"), |
| 7219 |
" (YouTube/Vimeo)" |
| 7220 |
] }), |
| 7221 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7222 |
HelpText, |
| 7223 |
{ |
| 7224 |
text: __$1( |
| 7225 |
"Paste the full URL from YouTube or Vimeo. The video will be embedded on your trip page.", |
| 7226 |
"yatra" |
| 7227 |
), |
| 7228 |
className: "mb-2" |
| 7229 |
} |
| 7230 |
), |
| 7231 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7232 |
Input, |
| 7233 |
{ |
| 7234 |
type: "url", |
| 7235 |
value: formData.video_url, |
| 7236 |
onChange: (e) => handleFieldChange("video_url", e.target.value), |
| 7237 |
placeholder: "https://www.youtube.com/watch?v=...", |
| 7238 |
className: `font-mono text-xs ${errors.video_url ? "border-red-500" : ""}` |
| 7239 |
} |
| 7240 |
), |
| 7241 |
errors.video_url && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-1.5 text-sm text-red-600 dark:text-red-400 flex items-center gap-1", children: [ |
| 7242 |
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }), |
| 7243 |
errors.video_url |
| 7244 |
] }) |
| 7245 |
] }), |
| 7246 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 7247 |
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: __$1("360° Virtual Tour URL", "yatra") }), |
| 7248 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7249 |
HelpText, |
| 7250 |
{ |
| 7251 |
text: __$1( |
| 7252 |
"Add a link to an interactive 360° virtual tour if available", |
| 7253 |
"yatra" |
| 7254 |
), |
| 7255 |
className: "mb-2" |
| 7256 |
} |
| 7257 |
), |
| 7258 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7259 |
Input, |
| 7260 |
{ |
| 7261 |
type: "url", |
| 7262 |
value: formData.virtual_tour_url, |
| 7263 |
onChange: (e) => handleFieldChange("virtual_tour_url", e.target.value), |
| 7264 |
placeholder: "https://...", |
| 7265 |
className: `font-mono text-xs ${errors.virtual_tour_url ? "border-red-500" : ""}` |
| 7266 |
} |
| 7267 |
), |
| 7268 |
errors.virtual_tour_url && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-1.5 text-sm text-red-600 dark:text-red-400 flex items-center gap-1", children: [ |
| 7269 |
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }), |
| 7270 |
errors.virtual_tour_url |
| 7271 |
] }) |
| 7272 |
] }) |
| 7273 |
] }) |
| 7274 |
] }), |
| 7275 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [ |
| 7276 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { children: [ |
| 7277 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __$1("Trip Story & Special Features", "yatra") }), |
| 7278 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: __$1( |
| 7279 |
"Tell an engaging story and highlight what makes this trip unique", |
| 7280 |
"yatra" |
| 7281 |
) }) |
| 7282 |
] }), |
| 7283 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-4", children: [ |
| 7284 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 7285 |
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: __$1("What Makes This Trip Special", "yatra") }), |
| 7286 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7287 |
HelpText, |
| 7288 |
{ |
| 7289 |
text: __$1( |
| 7290 |
"Highlight the unique selling points and what sets this trip apart from others", |
| 7291 |
"yatra" |
| 7292 |
), |
| 7293 |
className: "mb-2" |
| 7294 |
} |
| 7295 |
), |
| 7296 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7297 |
"textarea", |
| 7298 |
{ |
| 7299 |
value: formData.what_makes_special, |
| 7300 |
onChange: (e) => handleFieldChange("what_makes_special", e.target.value), |
| 7301 |
placeholder: __$1( |
| 7302 |
"Describe what makes this trip unique and special...", |
| 7303 |
"yatra" |
| 7304 |
), |
| 7305 |
rows: 5, |
| 7306 |
className: "flex w-full rounded-md border-2 border-gray-300 bg-white px-4 py-2.5 text-base font-normal text-gray-900 ring-offset-white file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-gray-400 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100 dark:ring-offset-gray-900 dark:placeholder:text-gray-500 dark:focus-visible:ring-blue-400 resize-none transition-colors" |
| 7307 |
} |
| 7308 |
) |
| 7309 |
] }), |
| 7310 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 7311 |
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: __$1("Trip Story / Narrative", "yatra") }), |
| 7312 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7313 |
HelpText, |
| 7314 |
{ |
| 7315 |
text: __$1( |
| 7316 |
"Tell an engaging story about this trip. Use storytelling to connect with potential travelers emotionally", |
| 7317 |
"yatra" |
| 7318 |
), |
| 7319 |
className: "mb-2" |
| 7320 |
} |
| 7321 |
), |
| 7322 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7323 |
"textarea", |
| 7324 |
{ |
| 7325 |
value: formData.trip_story, |
| 7326 |
onChange: (e) => handleFieldChange("trip_story", e.target.value), |
| 7327 |
placeholder: __$1( |
| 7328 |
"Write an engaging narrative about this trip...", |
| 7329 |
"yatra" |
| 7330 |
), |
| 7331 |
rows: 8, |
| 7332 |
className: "flex w-full rounded-md border-2 border-gray-300 bg-white px-4 py-2.5 text-base font-normal text-gray-900 ring-offset-white file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-gray-400 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100 dark:ring-offset-gray-900 dark:placeholder:text-gray-500 dark:focus-visible:ring-blue-400 resize-none transition-colors" |
| 7333 |
} |
| 7334 |
) |
| 7335 |
] }) |
| 7336 |
] }) |
| 7337 |
] }), |
| 7338 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7339 |
TestimonialsSelector, |
| 7340 |
{ |
| 7341 |
tripId, |
| 7342 |
selectedReviewIds: formData.testimonial_review_ids, |
| 7343 |
onChange: (reviewIds) => handleFieldChange("testimonial_review_ids", reviewIds) |
| 7344 |
} |
| 7345 |
) |
| 7346 |
] }) |
| 7347 |
] }); |
| 7348 |
case "downloads": |
| 7349 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [ |
| 7350 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2 mb-2", children: [ |
| 7351 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Download, { className: "w-5 h-5 text-gray-500" }), |
| 7352 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: __$1("Downloads", "yatra") }) |
| 7353 |
] }), |
| 7354 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-6", children: __$1( |
| 7355 |
"Attach files to this trip and control who can access them.", |
| 7356 |
"yatra" |
| 7357 |
) }), |
| 7358 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [ |
| 7359 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { children: [ |
| 7360 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __$1("Downloads", "yatra") }), |
| 7361 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: __$1( |
| 7362 |
"Attach files to this trip and control who can access them.", |
| 7363 |
"yatra" |
| 7364 |
) }) |
| 7365 |
] }), |
| 7366 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-4", children: [ |
| 7367 |
(formData.downloadable_items || []).length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: (formData.downloadable_items || []).map((item, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 7368 |
"div", |
| 7369 |
{ |
| 7370 |
className: "p-4 border border-gray-200 dark:border-gray-700 rounded-lg space-y-3", |
| 7371 |
children: [ |
| 7372 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-2", children: [ |
| 7373 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [ |
| 7374 |
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: __$1("Title", "yatra") }), |
| 7375 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7376 |
Input, |
| 7377 |
{ |
| 7378 |
value: item.title, |
| 7379 |
onChange: (e) => handleDownloadableItemChange( |
| 7380 |
index, |
| 7381 |
"title", |
| 7382 |
e.target.value |
| 7383 |
), |
| 7384 |
placeholder: __$1( |
| 7385 |
"E.g. Packing list, itinerary PDF, waiver form...", |
| 7386 |
"yatra" |
| 7387 |
) |
| 7388 |
} |
| 7389 |
) |
| 7390 |
] }), |
| 7391 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-1 pt-7", children: [ |
| 7392 |
index > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7393 |
Button, |
| 7394 |
{ |
| 7395 |
type: "button", |
| 7396 |
variant: "ghost", |
| 7397 |
size: "sm", |
| 7398 |
onClick: () => handleDownloadableItemMove(index, index - 1), |
| 7399 |
title: __$1("Move up", "yatra"), |
| 7400 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronUp, { className: "w-4 h-4" }) |
| 7401 |
} |
| 7402 |
), |
| 7403 |
index < (formData.downloadable_items || []).length - 1 && /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7404 |
Button, |
| 7405 |
{ |
| 7406 |
type: "button", |
| 7407 |
variant: "ghost", |
| 7408 |
size: "sm", |
| 7409 |
onClick: () => handleDownloadableItemMove(index, index + 1), |
| 7410 |
title: __$1("Move down", "yatra"), |
| 7411 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "w-4 h-4" }) |
| 7412 |
} |
| 7413 |
), |
| 7414 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7415 |
Button, |
| 7416 |
{ |
| 7417 |
type: "button", |
| 7418 |
variant: "ghost", |
| 7419 |
size: "sm", |
| 7420 |
onClick: () => handleDownloadableItemRemove(index), |
| 7421 |
className: "text-red-600 hover:text-red-700", |
| 7422 |
title: __$1("Remove", "yatra"), |
| 7423 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-4 h-4" }) |
| 7424 |
} |
| 7425 |
) |
| 7426 |
] }) |
| 7427 |
] }), |
| 7428 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 7429 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: [ |
| 7430 |
__$1("Description", "yatra"), |
| 7431 |
" (", |
| 7432 |
__$1("Optional", "yatra"), |
| 7433 |
")" |
| 7434 |
] }), |
| 7435 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7436 |
"textarea", |
| 7437 |
{ |
| 7438 |
value: item.description, |
| 7439 |
onChange: (e) => handleDownloadableItemChange( |
| 7440 |
index, |
| 7441 |
"description", |
| 7442 |
e.target.value |
| 7443 |
), |
| 7444 |
rows: 3, |
| 7445 |
className: "flex w-full rounded-md border-2 border-gray-300 bg-white px-4 py-2.5 text-base font-normal text-gray-900 ring-offset-white file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-gray-400 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 dark:bg-gray-800 dark:text-gray-100 dark:ring-offset-gray-900 dark:placeholder:text-gray-500 dark:focus-visible:ring-blue-400 resize-none transition-colors" |
| 7446 |
} |
| 7447 |
) |
| 7448 |
] }), |
| 7449 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [ |
| 7450 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 7451 |
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: __$1("Visibility", "yatra") }), |
| 7452 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 7453 |
Select, |
| 7454 |
{ |
| 7455 |
value: item.visibility, |
| 7456 |
onChange: (e) => handleDownloadableItemChange( |
| 7457 |
index, |
| 7458 |
"visibility", |
| 7459 |
e.target.value |
| 7460 |
), |
| 7461 |
children: [ |
| 7462 |
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "public", children: __$1("Public", "yatra") }), |
| 7463 |
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "logged_in", children: __$1("Private (My Account only)", "yatra") }), |
| 7464 |
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "booked_only", children: __$1( |
| 7465 |
"Private (Booking confirmation only)", |
| 7466 |
"yatra" |
| 7467 |
) }) |
| 7468 |
] |
| 7469 |
} |
| 7470 |
) |
| 7471 |
] }), |
| 7472 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 7473 |
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: __$1("File", "yatra") }), |
| 7474 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ |
| 7475 |
item.attachment_url ? /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7476 |
"a", |
| 7477 |
{ |
| 7478 |
href: item.attachment_url, |
| 7479 |
target: "_blank", |
| 7480 |
rel: "noreferrer", |
| 7481 |
className: "flex-shrink-0", |
| 7482 |
title: __$1("View file", "yatra"), |
| 7483 |
children: /\.(png|jpe?g|gif|webp|bmp|svg)(\?.*)?$/i.test( |
| 7484 |
item.attachment_url |
| 7485 |
) ? /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7486 |
"img", |
| 7487 |
{ |
| 7488 |
src: item.attachment_url, |
| 7489 |
alt: item.attachment_title || __$1("Selected file", "yatra"), |
| 7490 |
className: "w-9 h-9 rounded border border-gray-200 dark:border-gray-700 object-cover bg-white dark:bg-gray-900" |
| 7491 |
} |
| 7492 |
) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-9 h-9 rounded border border-gray-200 dark:border-gray-700 flex items-center justify-center bg-gray-50 dark:bg-gray-900", children: /* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { className: "w-4 h-4 text-gray-500 dark:text-gray-400" }) }) |
| 7493 |
} |
| 7494 |
) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-9 h-9 rounded border border-gray-200 dark:border-gray-700 flex items-center justify-center bg-gray-50 dark:bg-gray-900 flex-shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { className: "w-4 h-4 text-gray-400 dark:text-gray-600" }) }), |
| 7495 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "min-w-0 flex-1", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 min-w-0", children: [ |
| 7496 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 7497 |
Button, |
| 7498 |
{ |
| 7499 |
type: "button", |
| 7500 |
variant: "outline", |
| 7501 |
onClick: () => handleDownloadableItemSelectFile(index), |
| 7502 |
className: "flex items-center gap-2 flex-shrink-0", |
| 7503 |
children: [ |
| 7504 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "w-4 h-4" }), |
| 7505 |
item.attachment_id ? __$1("Change File", "yatra") : __$1("Select File", "yatra") |
| 7506 |
] |
| 7507 |
} |
| 7508 |
), |
| 7509 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-600 dark:text-gray-400 truncate min-w-0", children: item.attachment_title || (item.attachment_id ? `#${item.attachment_id}` : __$1("No file selected", "yatra")) }), |
| 7510 |
item.attachment_url && /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 7511 |
"a", |
| 7512 |
{ |
| 7513 |
href: item.attachment_url, |
| 7514 |
target: "_blank", |
| 7515 |
rel: "noreferrer", |
| 7516 |
className: "text-xs text-blue-600 dark:text-blue-400 hover:underline flex items-center gap-1 flex-shrink-0", |
| 7517 |
children: [ |
| 7518 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Eye, { className: "w-3 h-3" }), |
| 7519 |
__$1("View", "yatra") |
| 7520 |
] |
| 7521 |
} |
| 7522 |
) |
| 7523 |
] }) }) |
| 7524 |
] }) |
| 7525 |
] }) |
| 7526 |
] }), |
| 7527 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-3", children: [ |
| 7528 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 pt-0.5", children: [ |
| 7529 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7530 |
"input", |
| 7531 |
{ |
| 7532 |
type: "checkbox", |
| 7533 |
checked: item.enabled, |
| 7534 |
onChange: (e) => handleDownloadableItemChange( |
| 7535 |
index, |
| 7536 |
"enabled", |
| 7537 |
e.target.checked |
| 7538 |
), |
| 7539 |
className: "h-4 w-4" |
| 7540 |
} |
| 7541 |
), |
| 7542 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: __$1("Enabled", "yatra") }) |
| 7543 |
] }), |
| 7544 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 leading-relaxed", children: __$1( |
| 7545 |
"Controls whether this file appears and is available for download on the trip page. When disabled, the file is completely hidden from users.", |
| 7546 |
"yatra" |
| 7547 |
) }) }) |
| 7548 |
] }) |
| 7549 |
] |
| 7550 |
}, |
| 7551 |
index |
| 7552 |
)) }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-6 border-2 border-dashed border-gray-300 dark:border-gray-700 rounded-lg text-center", children: [ |
| 7553 |
/* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { className: "w-8 h-8 text-gray-300 dark:text-gray-600 mx-auto mb-2" }), |
| 7554 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-3", children: __$1("No downloads added yet", "yatra") }) |
| 7555 |
] }), |
| 7556 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 7557 |
Button, |
| 7558 |
{ |
| 7559 |
type: "button", |
| 7560 |
variant: "outline", |
| 7561 |
onClick: handleDownloadableItemAdd, |
| 7562 |
className: "w-full", |
| 7563 |
children: [ |
| 7564 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4 mr-2" }), |
| 7565 |
__$1("Add Download", "yatra") |
| 7566 |
] |
| 7567 |
} |
| 7568 |
) |
| 7569 |
] }) |
| 7570 |
] }) |
| 7571 |
] }); |
| 7572 |
case "pricing": |
| 7573 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ |
| 7574 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2 mb-2", children: [ |
| 7575 |
/* @__PURE__ */ jsxRuntimeExports.jsx(DollarSign, { className: "w-5 h-5 text-gray-500" }), |
| 7576 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: __$1("Pricing & Payment", "yatra") }), |
| 7577 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7578 |
Badge, |
| 7579 |
{ |
| 7580 |
variant: "outline", |
| 7581 |
className: "text-xs bg-amber-50 dark:bg-amber-900/20 text-amber-600 dark:text-amber-300 border-amber-200 dark:border-amber-800", |
| 7582 |
children: __$1("Recommended", "yatra") |
| 7583 |
} |
| 7584 |
) |
| 7585 |
] }), |
| 7586 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-4", children: [ |
| 7587 |
__$1("How much does it cost?", "yatra"), |
| 7588 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block text-xs text-gray-500 dark:text-gray-400 mt-1", children: __$1( |
| 7589 |
"Set pricing for different traveler types and payment options. Optional for drafts, but adding pricing now makes publishing easier.", |
| 7590 |
"yatra" |
| 7591 |
) }) |
| 7592 |
] }), |
| 7593 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ |
| 7594 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 7595 |
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-3", children: __$1("Pricing Type", "yatra") }), |
| 7596 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [ |
| 7597 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 7598 |
"label", |
| 7599 |
{ |
| 7600 |
className: `relative flex cursor-pointer rounded-lg border p-4 focus:outline-none ${formData.pricing_type === "regular" ? "border-blue-600 bg-blue-50 dark:bg-blue-900/20 ring-2 ring-blue-600" : "border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800"}`, |
| 7601 |
children: [ |
| 7602 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7603 |
"input", |
| 7604 |
{ |
| 7605 |
type: "radio", |
| 7606 |
name: "pricing_type", |
| 7607 |
value: "regular", |
| 7608 |
checked: formData.pricing_type === "regular", |
| 7609 |
onChange: (e) => handleFieldChange("pricing_type", e.target.value), |
| 7610 |
className: "sr-only" |
| 7611 |
} |
| 7612 |
), |
| 7613 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-1", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col", children: [ |
| 7614 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7615 |
"span", |
| 7616 |
{ |
| 7617 |
className: `block text-sm font-semibold ${formData.pricing_type === "regular" ? "text-blue-900 dark:text-blue-300" : "text-gray-900 dark:text-white"}`, |
| 7618 |
children: __$1("Regular Pricing", "yatra") |
| 7619 |
} |
| 7620 |
), |
| 7621 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7622 |
"span", |
| 7623 |
{ |
| 7624 |
className: `mt-1 flex items-center text-sm ${formData.pricing_type === "regular" ? "text-blue-700 dark:text-blue-400" : "text-gray-500 dark:text-gray-400"}`, |
| 7625 |
children: __$1("Set a single price for all travelers", "yatra") |
| 7626 |
} |
| 7627 |
) |
| 7628 |
] }) }), |
| 7629 |
formData.pricing_type === "regular" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute top-4 right-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 w-4 rounded-full bg-blue-600" }) }) |
| 7630 |
] |
| 7631 |
} |
| 7632 |
), |
| 7633 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 7634 |
"label", |
| 7635 |
{ |
| 7636 |
className: `relative flex cursor-pointer rounded-lg border p-4 focus:outline-none ${formData.pricing_type === "traveler_based" ? "border-blue-600 bg-blue-50 dark:bg-blue-900/20 ring-2 ring-blue-600" : "border-gray-300 dark:border-gray-600 bg-white dark:bg-gray-800"}`, |
| 7637 |
children: [ |
| 7638 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7639 |
"input", |
| 7640 |
{ |
| 7641 |
type: "radio", |
| 7642 |
name: "pricing_type", |
| 7643 |
value: "traveler_based", |
| 7644 |
checked: formData.pricing_type === "traveler_based", |
| 7645 |
onChange: (e) => handleFieldChange("pricing_type", e.target.value), |
| 7646 |
className: "sr-only" |
| 7647 |
} |
| 7648 |
), |
| 7649 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-1", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col", children: [ |
| 7650 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7651 |
"span", |
| 7652 |
{ |
| 7653 |
className: `block text-sm font-semibold ${formData.pricing_type === "traveler_based" ? "text-blue-900 dark:text-blue-300" : "text-gray-900 dark:text-white"}`, |
| 7654 |
children: __$1("Traveler-Based Pricing", "yatra") |
| 7655 |
} |
| 7656 |
), |
| 7657 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7658 |
"span", |
| 7659 |
{ |
| 7660 |
className: `mt-1 flex items-center text-sm ${formData.pricing_type === "traveler_based" ? "text-blue-700 dark:text-blue-400" : "text-gray-500 dark:text-gray-400"}`, |
| 7661 |
children: __$1( |
| 7662 |
"Set different prices for each traveler category", |
| 7663 |
"yatra" |
| 7664 |
) |
| 7665 |
} |
| 7666 |
) |
| 7667 |
] }) }), |
| 7668 |
formData.pricing_type === "traveler_based" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute top-4 right-4", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 w-4 rounded-full bg-blue-600" }) }) |
| 7669 |
] |
| 7670 |
} |
| 7671 |
) |
| 7672 |
] }) |
| 7673 |
] }), |
| 7674 |
formData.pricing_type === "regular" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [ |
| 7675 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 7676 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: [ |
| 7677 |
__$1("Original Price", "yatra"), |
| 7678 |
" (", |
| 7679 |
__$1("Optional", "yatra"), |
| 7680 |
")" |
| 7681 |
] }), |
| 7682 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [ |
| 7683 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-500 text-sm", children: getCurrencySymbol(globalCurrency) }), |
| 7684 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7685 |
Input, |
| 7686 |
{ |
| 7687 |
type: "number", |
| 7688 |
step: "0.01", |
| 7689 |
min: "0", |
| 7690 |
value: formData.original_price, |
| 7691 |
onChange: (e) => handleFieldChange("original_price", e.target.value), |
| 7692 |
placeholder: "0.00", |
| 7693 |
className: `pl-7 ${errors.original_price ? "border-red-500" : ""}` |
| 7694 |
} |
| 7695 |
) |
| 7696 |
] }), |
| 7697 |
errors.original_price && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-xs text-red-600", children: errors.original_price }) |
| 7698 |
] }), |
| 7699 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 7700 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: [ |
| 7701 |
__$1("Discounted Price", "yatra"), |
| 7702 |
" (", |
| 7703 |
__$1("Optional", "yatra"), |
| 7704 |
")" |
| 7705 |
] }), |
| 7706 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [ |
| 7707 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-500 text-sm", children: getCurrencySymbol(globalCurrency) }), |
| 7708 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7709 |
Input, |
| 7710 |
{ |
| 7711 |
type: "number", |
| 7712 |
step: "0.01", |
| 7713 |
min: "0", |
| 7714 |
value: formData.discounted_price, |
| 7715 |
onChange: (e) => handleFieldChange( |
| 7716 |
"discounted_price", |
| 7717 |
e.target.value |
| 7718 |
), |
| 7719 |
placeholder: "0.00", |
| 7720 |
className: `pl-7 ${errors.discounted_price ? "border-red-500" : ""}` |
| 7721 |
} |
| 7722 |
) |
| 7723 |
] }), |
| 7724 |
errors.discounted_price && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-xs text-red-600", children: errors.discounted_price }) |
| 7725 |
] }) |
| 7726 |
] }) }), |
| 7727 |
formData.pricing_type === "traveler_based" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 7728 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-between mb-3", children: /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400", children: __$1("Traveler Category Pricing", "yatra") }) }), |
| 7729 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mb-3", children: __$1( |
| 7730 |
"Add pricing for traveler categories. Categories are managed in Traveler Categories page.", |
| 7731 |
"yatra" |
| 7732 |
) }), |
| 7733 |
isLoadingCategories ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center justify-center py-8", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Loader2, { className: "w-6 h-6 animate-spin text-gray-400" }) }) : activeCategories.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-6 border border-gray-200 dark:border-gray-700 rounded-lg text-center", children: [ |
| 7734 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-3", children: __$1("No active traveler categories found.", "yatra") }), |
| 7735 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 7736 |
Button, |
| 7737 |
{ |
| 7738 |
type: "button", |
| 7739 |
variant: "outline", |
| 7740 |
onClick: () => window.location.href = "?page=yatra&subpage=traveler-categories&action=create", |
| 7741 |
className: "flex items-center gap-2 mx-auto", |
| 7742 |
children: [ |
| 7743 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4" }), |
| 7744 |
__$1("Create Category", "yatra") |
| 7745 |
] |
| 7746 |
} |
| 7747 |
) |
| 7748 |
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ |
| 7749 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [ |
| 7750 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 7751 |
Button, |
| 7752 |
{ |
| 7753 |
type: "button", |
| 7754 |
variant: "outline", |
| 7755 |
onClick: () => setShowCategorySelector(!showCategorySelector), |
| 7756 |
className: "flex items-center gap-2", |
| 7757 |
disabled: activeCategories.filter( |
| 7758 |
(cat) => !formData.price_types.some( |
| 7759 |
(pt) => Number(pt.category_id) === Number(cat.id) |
| 7760 |
) |
| 7761 |
).length === 0, |
| 7762 |
children: [ |
| 7763 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4" }), |
| 7764 |
__$1("Add Pricing", "yatra") |
| 7765 |
] |
| 7766 |
} |
| 7767 |
), |
| 7768 |
showCategorySelector && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ |
| 7769 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7770 |
"div", |
| 7771 |
{ |
| 7772 |
className: "fixed inset-0 z-10", |
| 7773 |
onClick: () => setShowCategorySelector(false) |
| 7774 |
} |
| 7775 |
), |
| 7776 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute top-full left-0 mt-2 w-full max-w-md bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-lg shadow-lg z-20 max-h-96 overflow-y-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-2", children: [ |
| 7777 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs font-medium text-gray-700 dark:text-gray-300 px-3 py-2 mb-1", children: __$1( |
| 7778 |
"Select a category to add pricing", |
| 7779 |
"yatra" |
| 7780 |
) }), |
| 7781 |
activeCategories.filter( |
| 7782 |
(cat) => !formData.price_types.some( |
| 7783 |
(pt) => Number(pt.category_id) === Number(cat.id) |
| 7784 |
) |
| 7785 |
).length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-3 py-4 text-sm text-gray-500 dark:text-gray-400 text-center", children: __$1( |
| 7786 |
"All categories have pricing added", |
| 7787 |
"yatra" |
| 7788 |
) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1", children: activeCategories.filter( |
| 7789 |
(cat) => !formData.price_types.some( |
| 7790 |
(pt) => Number(pt.category_id) === Number(cat.id) |
| 7791 |
) |
| 7792 |
).map((category) => { |
| 7793 |
const ageRange = category.age_min !== void 0 || category.age_max !== void 0 ? category.age_min !== void 0 && category.age_max !== void 0 ? `${category.age_min}-${category.age_max} ${__$1("years", "yatra")}` : category.age_min !== void 0 ? `${category.age_min}+ ${__$1("years", "yatra")}` : category.age_max !== void 0 ? `${__$1("Under", "yatra")} ${category.age_max} ${__$1("years", "yatra")}` : "" : null; |
| 7794 |
const pricingMode = category.pricing_mode || "per_person"; |
| 7795 |
const hasMin = category.min_pax !== null && category.min_pax !== void 0; |
| 7796 |
const hasMax = category.max_pax !== null && category.max_pax !== void 0; |
| 7797 |
let pricingLabel = ""; |
| 7798 |
if (pricingMode === "per_group") { |
| 7799 |
if (hasMin && hasMax) { |
| 7800 |
pricingLabel = `${__$1("Per group", "yatra")} (${category.min_pax}-${category.max_pax})`; |
| 7801 |
} else if (hasMin) { |
| 7802 |
pricingLabel = `${__$1("Per group", "yatra")} (${__$1("From", "yatra")} ${category.min_pax})`; |
| 7803 |
} else if (hasMax) { |
| 7804 |
pricingLabel = `${__$1("Per group", "yatra")} (${__$1("Up to", "yatra")} ${category.max_pax})`; |
| 7805 |
} else { |
| 7806 |
pricingLabel = __$1( |
| 7807 |
"Per group", |
| 7808 |
"yatra" |
| 7809 |
); |
| 7810 |
} |
| 7811 |
} else { |
| 7812 |
pricingLabel = __$1( |
| 7813 |
"Per person", |
| 7814 |
"yatra" |
| 7815 |
); |
| 7816 |
} |
| 7817 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 7818 |
"button", |
| 7819 |
{ |
| 7820 |
type: "button", |
| 7821 |
onClick: () => { |
| 7822 |
handlePriceTypeAdd(category.id); |
| 7823 |
setShowCategorySelector(false); |
| 7824 |
}, |
| 7825 |
className: "w-full text-left px-3 py-2 rounded-md hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors", |
| 7826 |
children: [ |
| 7827 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "font-medium text-sm text-gray-900 dark:text-white", children: [ |
| 7828 |
category.label, |
| 7829 |
ageRange && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "ml-2 text-xs font-normal text-gray-500 dark:text-gray-400", children: [ |
| 7830 |
"(", |
| 7831 |
ageRange, |
| 7832 |
")" |
| 7833 |
] }) |
| 7834 |
] }), |
| 7835 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs text-gray-500 dark:text-gray-400 mt-0.5", children: [ |
| 7836 |
category.description, |
| 7837 |
pricingLabel && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "ml-1 text-[11px] font-medium text-gray-600 dark:text-gray-300", children: [ |
| 7838 |
"• ", |
| 7839 |
pricingLabel |
| 7840 |
] }) |
| 7841 |
] }) |
| 7842 |
] |
| 7843 |
}, |
| 7844 |
category.id |
| 7845 |
); |
| 7846 |
}) }) |
| 7847 |
] }) }) |
| 7848 |
] }) |
| 7849 |
] }), |
| 7850 |
formData.price_types.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: formData.price_types.map((priceType, index) => { |
| 7851 |
const category = activeCategories.find( |
| 7852 |
(cat) => Number(cat.id) === Number(priceType.category_id) |
| 7853 |
); |
| 7854 |
if (!category) { |
| 7855 |
return null; |
| 7856 |
} |
| 7857 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 7858 |
"div", |
| 7859 |
{ |
| 7860 |
className: "p-4 border border-blue-300 dark:border-blue-700 bg-blue-50 dark:bg-blue-900/20 rounded-lg", |
| 7861 |
children: [ |
| 7862 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between mb-3", children: [ |
| 7863 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [ |
| 7864 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-2 mb-1", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("h4", { className: "text-sm font-semibold text-gray-900 dark:text-white", children: [ |
| 7865 |
category.label, |
| 7866 |
(category.age_min !== void 0 || category.age_max !== void 0) && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "ml-2 text-xs font-normal text-gray-500 dark:text-gray-400", children: [ |
| 7867 |
"(", |
| 7868 |
category.age_min !== void 0 && category.age_max !== void 0 ? `${category.age_min}-${category.age_max} ${__$1("years", "yatra")}` : category.age_min !== void 0 ? `${category.age_min}+ ${__$1("years", "yatra")}` : category.age_max !== void 0 ? `${__$1("Under", "yatra")} ${category.age_max} ${__$1("years", "yatra")}` : "", |
| 7869 |
")" |
| 7870 |
] }), |
| 7871 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ml-2 inline-flex items-center gap-1 text-[11px] font-medium text-gray-600 dark:text-gray-300", children: (() => { |
| 7872 |
const pricingMode = category.pricing_mode || "per_person"; |
| 7873 |
const hasMin = category.min_pax !== null && category.min_pax !== void 0; |
| 7874 |
const hasMax = category.max_pax !== null && category.max_pax !== void 0; |
| 7875 |
if (pricingMode === "per_group") { |
| 7876 |
if (hasMin && hasMax) { |
| 7877 |
return `${__$1("Per group", "yatra")} (${category.min_pax}-${category.max_pax})`; |
| 7878 |
} |
| 7879 |
if (hasMin) { |
| 7880 |
return `${__$1("Per group", "yatra")} (${__$1("From", "yatra")} ${category.min_pax})`; |
| 7881 |
} |
| 7882 |
if (hasMax) { |
| 7883 |
return `${__$1("Per group", "yatra")} (${__$1("Up to", "yatra")} ${category.max_pax})`; |
| 7884 |
} |
| 7885 |
return __$1("Per group", "yatra"); |
| 7886 |
} |
| 7887 |
return __$1("Per person", "yatra"); |
| 7888 |
})() }) |
| 7889 |
] }) }), |
| 7890 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-600 dark:text-gray-400", children: category.description }) |
| 7891 |
] }), |
| 7892 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7893 |
"button", |
| 7894 |
{ |
| 7895 |
type: "button", |
| 7896 |
onClick: () => handlePriceTypeRemove(category.id), |
| 7897 |
className: "p-1 text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-900/20 rounded transition-colors", |
| 7898 |
title: __$1("Remove Pricing", "yatra"), |
| 7899 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-4 h-4" }) |
| 7900 |
} |
| 7901 |
) |
| 7902 |
] }), |
| 7903 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-3", children: [ |
| 7904 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 7905 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1.5", children: [ |
| 7906 |
__$1("Original Price", "yatra"), |
| 7907 |
" (", |
| 7908 |
__$1("Optional", "yatra"), |
| 7909 |
")" |
| 7910 |
] }), |
| 7911 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [ |
| 7912 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-500 text-sm", children: getCurrencySymbol(globalCurrency) }), |
| 7913 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7914 |
Input, |
| 7915 |
{ |
| 7916 |
type: "number", |
| 7917 |
step: "0.01", |
| 7918 |
min: "0", |
| 7919 |
value: priceType.original_price, |
| 7920 |
onChange: (e) => handlePriceTypeChange( |
| 7921 |
category.id, |
| 7922 |
"original_price", |
| 7923 |
e.target.value |
| 7924 |
), |
| 7925 |
placeholder: "0.00", |
| 7926 |
className: `pl-7 ${errors[`price_type_${index}_original`] ? "border-red-500" : ""}` |
| 7927 |
} |
| 7928 |
) |
| 7929 |
] }), |
| 7930 |
errors[`price_type_${index}_original`] && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-xs text-red-600 dark:text-red-400", children: errors[`price_type_${index}_original`] }) |
| 7931 |
] }), |
| 7932 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 7933 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1.5", children: [ |
| 7934 |
__$1("Discounted Price", "yatra"), |
| 7935 |
" (", |
| 7936 |
__$1("Optional", "yatra"), |
| 7937 |
")" |
| 7938 |
] }), |
| 7939 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [ |
| 7940 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-500 text-sm", children: getCurrencySymbol(globalCurrency) }), |
| 7941 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7942 |
Input, |
| 7943 |
{ |
| 7944 |
type: "number", |
| 7945 |
step: "0.01", |
| 7946 |
min: "0", |
| 7947 |
value: priceType.discounted_price, |
| 7948 |
onChange: (e) => handlePriceTypeChange( |
| 7949 |
category.id, |
| 7950 |
"discounted_price", |
| 7951 |
e.target.value |
| 7952 |
), |
| 7953 |
placeholder: "0.00", |
| 7954 |
className: `pl-7 ${errors[`price_type_${index}_discounted`] ? "border-red-500" : ""}` |
| 7955 |
} |
| 7956 |
) |
| 7957 |
] }), |
| 7958 |
errors[`price_type_${index}_discounted`] && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-xs text-red-600 dark:text-red-400", children: errors[`price_type_${index}_discounted`] }) |
| 7959 |
] }) |
| 7960 |
] }), |
| 7961 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-3 flex items-center justify-between", children: [ |
| 7962 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "inline-flex items-center gap-2 text-xs font-medium text-gray-700 dark:text-gray-300", children: [ |
| 7963 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 7964 |
"input", |
| 7965 |
{ |
| 7966 |
type: "checkbox", |
| 7967 |
checked: Boolean(priceType.is_default), |
| 7968 |
onChange: (e) => handlePriceTypeDefaultChange( |
| 7969 |
category.id, |
| 7970 |
e.target.checked |
| 7971 |
), |
| 7972 |
className: "h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600" |
| 7973 |
} |
| 7974 |
), |
| 7975 |
__$1( |
| 7976 |
"Default price (used on page load)", |
| 7977 |
"yatra" |
| 7978 |
) |
| 7979 |
] }), |
| 7980 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[11px] text-gray-500 dark:text-gray-400", children: __$1("Traveler-based pricing only", "yatra") }) |
| 7981 |
] }) |
| 7982 |
] |
| 7983 |
}, |
| 7984 |
priceType.category_id |
| 7985 |
); |
| 7986 |
}) }), |
| 7987 |
formData.price_types.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-6 border-2 border-dashed border-gray-300 dark:border-gray-700 rounded-lg text-center", children: [ |
| 7988 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Tag, { className: "w-8 h-8 text-gray-300 dark:text-gray-600 mx-auto mb-2" }), |
| 7989 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400", children: __$1( |
| 7990 |
"No pricing added yet. Select a category above to add pricing.", |
| 7991 |
"yatra" |
| 7992 |
) }) |
| 7993 |
] }) |
| 7994 |
] }), |
| 7995 |
errors.price_types && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "mt-2 text-sm text-red-600 dark:text-red-400 flex items-center gap-1", children: [ |
| 7996 |
/* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }), |
| 7997 |
errors.price_types |
| 7998 |
] }) |
| 7999 |
] }), |
| 8000 |
(() => { |
| 8001 |
var _a3, _b2; |
| 8002 |
const flexiblePaymentsEnabled = Boolean( |
| 8003 |
(_a3 = window == null ? void 0 : window.yatraAdmin) == null ? void 0 : _a3.flexiblePaymentsEnabled |
| 8004 |
); |
| 8005 |
const isLocked = !flexiblePaymentsEnabled; |
| 8006 |
const siteUrl = ((_b2 = window == null ? void 0 : window.yatraAdmin) == null ? void 0 : _b2.siteUrl) || "/wp-admin/admin.php?page=yatra"; |
| 8007 |
const modulesPageUrl = `${siteUrl}/wp-admin/admin.php?page=yatra&subpage=modules`; |
| 8008 |
const pricingUrl = "https://mantrabrain.com/yatra-pricing/"; |
| 8009 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t border-gray-200 dark:border-gray-700 pt-4", children: [ |
| 8010 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-sm font-semibold text-gray-900 dark:text-white mb-3 flex items-center", children: [ |
| 8011 |
__$1("Deposit & Payment Terms", "yatra"), |
| 8012 |
isLocked && /* @__PURE__ */ jsxRuntimeExports.jsx(ProBadge, { isProActive: isPro }) |
| 8013 |
] }), |
| 8014 |
isLocked && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-3 p-3 bg-gradient-to-r from-purple-50 to-blue-50 dark:from-purple-900/20 dark:to-blue-900/20 border border-purple-200 dark:border-purple-800 rounded-md text-xs text-purple-900 dark:text-purple-100 flex items-start gap-2", children: [ |
| 8015 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8016 |
"svg", |
| 8017 |
{ |
| 8018 |
className: "w-4 h-4 mt-0.5 text-purple-500 flex-shrink-0", |
| 8019 |
fill: "none", |
| 8020 |
stroke: "currentColor", |
| 8021 |
viewBox: "0 0 24 24", |
| 8022 |
"aria-hidden": "true", |
| 8023 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8024 |
"path", |
| 8025 |
{ |
| 8026 |
strokeLinecap: "round", |
| 8027 |
strokeLinejoin: "round", |
| 8028 |
strokeWidth: 2, |
| 8029 |
d: "M12 15v2m-6 4h12a2 2 0 002-2v-6a2 2 0 00-2-2H6a2 2 0 00-2 2v6a2 2 0 002 2zm10-10V7a4 4 0 00-8 0v4h8z" |
| 8030 |
} |
| 8031 |
) |
| 8032 |
} |
| 8033 |
), |
| 8034 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1", children: isPro ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ |
| 8035 |
__$1( |
| 8036 |
"Per-trip deposits need the Flexible Payments module.", |
| 8037 |
"yatra" |
| 8038 |
), |
| 8039 |
" ", |
| 8040 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8041 |
"a", |
| 8042 |
{ |
| 8043 |
href: modulesPageUrl, |
| 8044 |
target: "_blank", |
| 8045 |
rel: "noopener noreferrer", |
| 8046 |
className: "underline font-medium", |
| 8047 |
children: __$1("Activate module", "yatra") |
| 8048 |
} |
| 8049 |
) |
| 8050 |
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ |
| 8051 |
__$1( |
| 8052 |
"Per-trip deposit amount, percentage and custom payment terms are a Yatra Pro feature.", |
| 8053 |
"yatra" |
| 8054 |
), |
| 8055 |
" ", |
| 8056 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8057 |
"a", |
| 8058 |
{ |
| 8059 |
href: pricingUrl, |
| 8060 |
target: "_blank", |
| 8061 |
rel: "noopener noreferrer", |
| 8062 |
className: "underline font-medium", |
| 8063 |
children: __$1("Upgrade to Pro", "yatra") |
| 8064 |
} |
| 8065 |
) |
| 8066 |
] }) }) |
| 8067 |
] }), |
| 8068 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 8069 |
"fieldset", |
| 8070 |
{ |
| 8071 |
disabled: isLocked, |
| 8072 |
className: isLocked ? "opacity-60 cursor-not-allowed select-none" : "", |
| 8073 |
"aria-label": isLocked ? __$1( |
| 8074 |
"Deposit & Payment Terms (Pro feature, disabled)", |
| 8075 |
"yatra" |
| 8076 |
) : void 0, |
| 8077 |
children: [ |
| 8078 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [ |
| 8079 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 8080 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8081 |
"label", |
| 8082 |
{ |
| 8083 |
htmlFor: "deposit_amount", |
| 8084 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", |
| 8085 |
children: __$1("Deposit Amount", "yatra") |
| 8086 |
} |
| 8087 |
), |
| 8088 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [ |
| 8089 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-500", children: getCurrencySymbol(globalCurrency) }), |
| 8090 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8091 |
Input, |
| 8092 |
{ |
| 8093 |
id: "deposit_amount", |
| 8094 |
type: "number", |
| 8095 |
step: "0.01", |
| 8096 |
min: "0", |
| 8097 |
value: formData.deposit_amount, |
| 8098 |
onChange: (e) => handleFieldChange( |
| 8099 |
"deposit_amount", |
| 8100 |
e.target.value |
| 8101 |
), |
| 8102 |
placeholder: "0.00", |
| 8103 |
className: "pl-7" |
| 8104 |
} |
| 8105 |
) |
| 8106 |
] }) |
| 8107 |
] }), |
| 8108 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 8109 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8110 |
"label", |
| 8111 |
{ |
| 8112 |
htmlFor: "deposit_percentage", |
| 8113 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", |
| 8114 |
children: __$1("Deposit Percentage", "yatra") |
| 8115 |
} |
| 8116 |
), |
| 8117 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [ |
| 8118 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8119 |
Input, |
| 8120 |
{ |
| 8121 |
id: "deposit_percentage", |
| 8122 |
type: "number", |
| 8123 |
step: "0.01", |
| 8124 |
min: "0", |
| 8125 |
max: "100", |
| 8126 |
value: formData.deposit_percentage, |
| 8127 |
onChange: (e) => handleFieldChange( |
| 8128 |
"deposit_percentage", |
| 8129 |
e.target.value |
| 8130 |
), |
| 8131 |
placeholder: "0", |
| 8132 |
className: "pr-7" |
| 8133 |
} |
| 8134 |
), |
| 8135 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-500", children: "%" }) |
| 8136 |
] }) |
| 8137 |
] }) |
| 8138 |
] }), |
| 8139 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-4", children: [ |
| 8140 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8141 |
"label", |
| 8142 |
{ |
| 8143 |
htmlFor: "payment_terms", |
| 8144 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", |
| 8145 |
children: __$1("Payment Terms", "yatra") |
| 8146 |
} |
| 8147 |
), |
| 8148 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8149 |
"textarea", |
| 8150 |
{ |
| 8151 |
id: "payment_terms", |
| 8152 |
value: formData.payment_terms, |
| 8153 |
onChange: (e) => handleFieldChange("payment_terms", e.target.value), |
| 8154 |
placeholder: __$1( |
| 8155 |
"e.g., 50% deposit required at booking, balance due 30 days before departure", |
| 8156 |
"yatra" |
| 8157 |
), |
| 8158 |
rows: 2, |
| 8159 |
className: "flex w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-sm ring-offset-white placeholder:text-gray-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 dark:bg-gray-800 dark:ring-offset-gray-900 dark:placeholder:text-gray-400 dark:focus-visible:ring-blue-400 resize-none" |
| 8160 |
} |
| 8161 |
) |
| 8162 |
] }) |
| 8163 |
] |
| 8164 |
} |
| 8165 |
) |
| 8166 |
] }); |
| 8167 |
})() |
| 8168 |
] }) |
| 8169 |
] }); |
| 8170 |
case "attributes": |
| 8171 |
setCurrentSection("categorization"); |
| 8172 |
return null; |
| 8173 |
case "itinerary": |
| 8174 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [ |
| 8175 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2 mb-2", children: [ |
| 8176 |
/* @__PURE__ */ jsxRuntimeExports.jsx(BookOpen, { className: "w-5 h-5 text-gray-500" }), |
| 8177 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: __$1("Trip Details", "yatra") }), |
| 8178 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8179 |
Badge, |
| 8180 |
{ |
| 8181 |
variant: "outline", |
| 8182 |
className: "text-xs bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-300 border-blue-200 dark:border-blue-800", |
| 8183 |
children: __$1("Recommended", "yatra") |
| 8184 |
} |
| 8185 |
) |
| 8186 |
] }), |
| 8187 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-4", children: [ |
| 8188 |
__$1("What will travelers experience?", "yatra"), |
| 8189 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block text-xs text-gray-500 dark:text-gray-400 mt-1", children: __$1( |
| 8190 |
"Build your day-by-day itinerary and list what's included/excluded to set clear expectations.", |
| 8191 |
"yatra" |
| 8192 |
) }) |
| 8193 |
] }), |
| 8194 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border-b border-gray-200 dark:border-gray-700", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("nav", { className: "flex gap-6", "aria-label": "Trip Details Tabs", children: [ |
| 8195 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8196 |
"button", |
| 8197 |
{ |
| 8198 |
onClick: () => setTripDetailsTab("itinerary"), |
| 8199 |
className: `pb-3 px-1 border-b-2 font-medium text-sm transition-colors ${tripDetailsTab === "itinerary" ? "border-blue-500 text-blue-600 dark:text-blue-400" : "border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-300"}`, |
| 8200 |
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ |
| 8201 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Calendar, { className: "w-4 h-4" }), |
| 8202 |
__$1("Itinerary", "yatra") |
| 8203 |
] }) |
| 8204 |
} |
| 8205 |
), |
| 8206 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8207 |
"button", |
| 8208 |
{ |
| 8209 |
onClick: () => setTripDetailsTab("included"), |
| 8210 |
className: `pb-3 px-1 border-b-2 font-medium text-sm transition-colors ${tripDetailsTab === "included" ? "border-blue-500 text-blue-600 dark:text-blue-400" : "border-transparent text-gray-500 hover:text-gray-700 hover:border-gray-300 dark:text-gray-400 dark:hover:text-gray-300"}`, |
| 8211 |
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ |
| 8212 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CheckSquare, { className: "w-4 h-4" }), |
| 8213 |
__$1("Included/Excluded", "yatra") |
| 8214 |
] }) |
| 8215 |
} |
| 8216 |
) |
| 8217 |
] }) }), |
| 8218 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-6", children: [ |
| 8219 |
tripDetailsTab === "itinerary" && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ |
| 8220 |
isAiEligible() && isAiModuleEnabled() && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-4 flex items-center justify-between rounded-md border border-blue-200 bg-blue-50/40 px-3 py-2 dark:border-blue-500/40 dark:bg-blue-900/20", children: [ |
| 8221 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs text-blue-900 dark:text-blue-200", children: [ |
| 8222 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "mr-1 inline h-3.5 w-3.5" }), |
| 8223 |
isEditMode ? __$1( |
| 8224 |
"Let AI draft a day-by-day plan with real activity blocks — you can edit each day after.", |
| 8225 |
"yatra" |
| 8226 |
) : __$1( |
| 8227 |
"Save the trip first to enable AI itinerary generation — the agent needs a trip ID to attach days to.", |
| 8228 |
"yatra" |
| 8229 |
) |
| 8230 |
] }), |
| 8231 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 8232 |
Button, |
| 8233 |
{ |
| 8234 |
type: "button", |
| 8235 |
size: "sm", |
| 8236 |
variant: "outline", |
| 8237 |
className: "border-blue-300 text-blue-700 hover:bg-blue-100 dark:border-blue-500/60 dark:text-blue-200", |
| 8238 |
disabled: !isEditMode || !tripId, |
| 8239 |
onClick: () => { |
| 8240 |
if (isEditMode && tripId) { |
| 8241 |
setItineraryBuildOpen(true); |
| 8242 |
} |
| 8243 |
}, |
| 8244 |
children: [ |
| 8245 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "mr-1 h-3.5 w-3.5" }), |
| 8246 |
__$1("Build with AI", "yatra") |
| 8247 |
] |
| 8248 |
} |
| 8249 |
) |
| 8250 |
] }), |
| 8251 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8252 |
ItinerarySection, |
| 8253 |
{ |
| 8254 |
formData, |
| 8255 |
isEditMode, |
| 8256 |
tripId |
| 8257 |
} |
| 8258 |
) |
| 8259 |
] }), |
| 8260 |
tripDetailsTab === "included" && /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8261 |
IncludedSection, |
| 8262 |
{ |
| 8263 |
formData, |
| 8264 |
errors, |
| 8265 |
handleFieldChange |
| 8266 |
} |
| 8267 |
) |
| 8268 |
] }) |
| 8269 |
] }); |
| 8270 |
case "included": |
| 8271 |
setCurrentSection("itinerary"); |
| 8272 |
setTripDetailsTab("included"); |
| 8273 |
return null; |
| 8274 |
case "faqs": |
| 8275 |
setCurrentSection("seo"); |
| 8276 |
return null; |
| 8277 |
case "seo": |
| 8278 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [ |
| 8279 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2 mb-2", children: [ |
| 8280 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Search, { className: "w-5 h-5 text-gray-500" }), |
| 8281 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: __$1("SEO & Marketing", "yatra") }), |
| 8282 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8283 |
Badge, |
| 8284 |
{ |
| 8285 |
variant: "outline", |
| 8286 |
className: "text-xs bg-amber-50 dark:bg-amber-900/20 text-amber-600 dark:text-amber-300 border-amber-200 dark:border-amber-800", |
| 8287 |
children: __$1("Recommended", "yatra") |
| 8288 |
} |
| 8289 |
) |
| 8290 |
] }), |
| 8291 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-4", children: [ |
| 8292 |
__$1("How will people find & trust this trip?", "yatra"), |
| 8293 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block text-xs text-gray-500 dark:text-gray-400 mt-1", children: __$1( |
| 8294 |
"Optimize for search engines and answer common questions to build trust and improve discoverability.", |
| 8295 |
"yatra" |
| 8296 |
) }) |
| 8297 |
] }), |
| 8298 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [ |
| 8299 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-gray-200 dark:border-gray-700 rounded-lg p-5 bg-gray-50 dark:bg-gray-800/30", children: [ |
| 8300 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-sm font-semibold text-gray-900 dark:text-white mb-4 flex items-center gap-2", children: [ |
| 8301 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Search, { className: "w-4 h-4 text-blue-500" }), |
| 8302 |
__$1("Search Engine Optimization", "yatra") |
| 8303 |
] }), |
| 8304 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ |
| 8305 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 8306 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-1.5", children: [ |
| 8307 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8308 |
"label", |
| 8309 |
{ |
| 8310 |
htmlFor: "meta_title", |
| 8311 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400", |
| 8312 |
children: __$1("Meta Title", "yatra") |
| 8313 |
} |
| 8314 |
), |
| 8315 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8316 |
AiFieldAffordance, |
| 8317 |
{ |
| 8318 |
task: "seo-meta-title", |
| 8319 |
label: __$1("Meta Title", "yatra"), |
| 8320 |
value: formData.meta_title, |
| 8321 |
onAccept: (v) => handleFieldChange("meta_title", v.slice(0, 60)), |
| 8322 |
buildContext: () => buildTripAiContext(formData) |
| 8323 |
} |
| 8324 |
) |
| 8325 |
] }), |
| 8326 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8327 |
Input, |
| 8328 |
{ |
| 8329 |
id: "meta_title", |
| 8330 |
type: "text", |
| 8331 |
value: formData.meta_title, |
| 8332 |
onChange: (e) => handleFieldChange("meta_title", e.target.value), |
| 8333 |
placeholder: formData.title || __$1("Trip Title", "yatra"), |
| 8334 |
maxLength: 60 |
| 8335 |
} |
| 8336 |
), |
| 8337 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8338 |
HelpText, |
| 8339 |
{ |
| 8340 |
text: __$1( |
| 8341 |
"Best for search engines: 50-60 characters. Include main keywords.", |
| 8342 |
"yatra" |
| 8343 |
), |
| 8344 |
className: "mt-1" |
| 8345 |
} |
| 8346 |
) |
| 8347 |
] }), |
| 8348 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 8349 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-1.5", children: [ |
| 8350 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8351 |
"label", |
| 8352 |
{ |
| 8353 |
htmlFor: "meta_description", |
| 8354 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400", |
| 8355 |
children: __$1("Meta Description", "yatra") |
| 8356 |
} |
| 8357 |
), |
| 8358 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8359 |
AiFieldAffordance, |
| 8360 |
{ |
| 8361 |
task: "seo-meta-description", |
| 8362 |
label: __$1("Meta Description", "yatra"), |
| 8363 |
value: formData.meta_description, |
| 8364 |
onAccept: (v) => handleFieldChange("meta_description", v.slice(0, 160)), |
| 8365 |
buildContext: () => buildTripAiContext(formData) |
| 8366 |
} |
| 8367 |
) |
| 8368 |
] }), |
| 8369 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8370 |
"textarea", |
| 8371 |
{ |
| 8372 |
id: "meta_description", |
| 8373 |
value: formData.meta_description, |
| 8374 |
onChange: (e) => handleFieldChange("meta_description", e.target.value), |
| 8375 |
rows: 3, |
| 8376 |
maxLength: 160, |
| 8377 |
className: "flex w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-sm ring-offset-white placeholder:text-gray-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 dark:bg-gray-800 dark:ring-offset-gray-900 dark:placeholder:text-gray-400 dark:focus-visible:ring-blue-400 resize-none", |
| 8378 |
placeholder: __$1( |
| 8379 |
"Compelling description that includes key travel terms...", |
| 8380 |
"yatra" |
| 8381 |
) |
| 8382 |
} |
| 8383 |
), |
| 8384 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8385 |
HelpText, |
| 8386 |
{ |
| 8387 |
text: __$1( |
| 8388 |
"160 characters max. Include location, duration, and key features.", |
| 8389 |
"yatra" |
| 8390 |
), |
| 8391 |
className: "mt-1" |
| 8392 |
} |
| 8393 |
) |
| 8394 |
] }), |
| 8395 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 8396 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8397 |
"label", |
| 8398 |
{ |
| 8399 |
htmlFor: "meta_keywords", |
| 8400 |
className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", |
| 8401 |
children: __$1("Meta Keywords", "yatra") |
| 8402 |
} |
| 8403 |
), |
| 8404 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8405 |
Input, |
| 8406 |
{ |
| 8407 |
id: "meta_keywords", |
| 8408 |
type: "text", |
| 8409 |
value: formData.meta_keywords, |
| 8410 |
onChange: (e) => handleFieldChange("meta_keywords", e.target.value), |
| 8411 |
placeholder: __$1( |
| 8412 |
"adventure, travel, tour, guide, experience", |
| 8413 |
"yatra" |
| 8414 |
) |
| 8415 |
} |
| 8416 |
), |
| 8417 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8418 |
HelpText, |
| 8419 |
{ |
| 8420 |
text: __$1( |
| 8421 |
"Comma-separated keywords. Include location, activities, and travel terms.", |
| 8422 |
"yatra" |
| 8423 |
), |
| 8424 |
className: "mt-1" |
| 8425 |
} |
| 8426 |
) |
| 8427 |
] }) |
| 8428 |
] }), |
| 8429 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [ |
| 8430 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { children: [ |
| 8431 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __$1("SEO Preview", "yatra") }), |
| 8432 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: __$1( |
| 8433 |
"Preview how your trip appears in search results", |
| 8434 |
"yatra" |
| 8435 |
) }) |
| 8436 |
] }), |
| 8437 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { className: "space-y-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-gray-50 dark:bg-gray-800 p-4 rounded-lg", children: [ |
| 8438 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-gray-500 dark:text-gray-400 mb-2", children: __$1("Google Search Result Preview", "yatra") }), |
| 8439 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [ |
| 8440 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-blue-800 dark:text-blue-400 text-sm font-medium", children: sanitizeTextForSEO( |
| 8441 |
formData.meta_title || formData.title || "Trip Title", |
| 8442 |
60 |
| 8443 |
) }), |
| 8444 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-green-700 dark:text-green-400 text-sm", children: formData.meta_description ? sanitizeTextForSEO(formData.meta_description, 150) : formData.description ? sanitizeTextForSEO(formData.description, 150) : "Trip description..." }), |
| 8445 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-gray-600 dark:text-gray-400 text-xs", children: [ |
| 8446 |
window.location.hostname, |
| 8447 |
"/trip/", |
| 8448 |
formData.slug || "trip-slug" |
| 8449 |
] }) |
| 8450 |
] }) |
| 8451 |
] }) }) |
| 8452 |
] }) |
| 8453 |
] }), |
| 8454 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border border-gray-200 dark:border-gray-700 rounded-lg p-5 bg-gray-50 dark:bg-gray-800/30", children: [ |
| 8455 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-4 flex items-center justify-between gap-2", children: [ |
| 8456 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-sm font-semibold text-gray-900 dark:text-white flex items-center gap-2", children: [ |
| 8457 |
/* @__PURE__ */ jsxRuntimeExports.jsx(HelpCircle, { className: "w-4 h-4 text-blue-500" }), |
| 8458 |
__$1("Frequently Asked Questions", "yatra") |
| 8459 |
] }), |
| 8460 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8461 |
AiFieldAffordance, |
| 8462 |
{ |
| 8463 |
task: "trip-faq", |
| 8464 |
label: __$1("FAQ", "yatra"), |
| 8465 |
value: (formData.faqs ?? []).map((f) => `Q: ${f.question} |
| 8466 |
A: ${f.answer}`).join("\n\n"), |
| 8467 |
onAccept: (raw) => { |
| 8468 |
const parsed = []; |
| 8469 |
const blocks = raw.replace(/\r\n?/g, "\n").split(/\n{2,}/); |
| 8470 |
for (const block of blocks) { |
| 8471 |
const q = block.match(/^\s*Q[:\.\-]\s*(.+)/im); |
| 8472 |
const a = block.match(/A[:\.\-]\s*([\s\S]+)/im); |
| 8473 |
if (q) { |
| 8474 |
parsed.push({ |
| 8475 |
question: q[1].trim(), |
| 8476 |
answer: a ? a[1].trim() : "" |
| 8477 |
}); |
| 8478 |
} |
| 8479 |
} |
| 8480 |
if (parsed.length > 0) { |
| 8481 |
handleFieldChange("faqs", parsed); |
| 8482 |
} |
| 8483 |
}, |
| 8484 |
buildContext: () => buildTripAiContext(formData) |
| 8485 |
} |
| 8486 |
) |
| 8487 |
] }), |
| 8488 |
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mb-4", children: __$1( |
| 8489 |
"Answer common questions to build trust and reduce support inquiries. FAQs also help with SEO.", |
| 8490 |
"yatra" |
| 8491 |
) }), |
| 8492 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ |
| 8493 |
formData.faqs.map((faq, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 8494 |
"div", |
| 8495 |
{ |
| 8496 |
className: "border border-gray-200 dark:border-gray-700 rounded-lg p-4 bg-white dark:bg-gray-900", |
| 8497 |
children: [ |
| 8498 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between mb-3", children: [ |
| 8499 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("h4", { className: "text-sm font-medium text-gray-900 dark:text-white", children: [ |
| 8500 |
__$1("FAQ", "yatra"), |
| 8501 |
" ", |
| 8502 |
index + 1 |
| 8503 |
] }), |
| 8504 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8505 |
"button", |
| 8506 |
{ |
| 8507 |
type: "button", |
| 8508 |
onClick: () => handleFAQRemove(index), |
| 8509 |
className: "text-red-600 hover:text-red-700", |
| 8510 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-4 h-4" }) |
| 8511 |
} |
| 8512 |
) |
| 8513 |
] }), |
| 8514 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [ |
| 8515 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 8516 |
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: __$1("Question", "yatra") }), |
| 8517 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8518 |
Input, |
| 8519 |
{ |
| 8520 |
type: "text", |
| 8521 |
value: faq.question, |
| 8522 |
onChange: (e) => handleFAQChange(index, "question", e.target.value), |
| 8523 |
placeholder: __$1("Enter question...", "yatra") |
| 8524 |
} |
| 8525 |
) |
| 8526 |
] }), |
| 8527 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 8528 |
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: __$1("Answer", "yatra") }), |
| 8529 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8530 |
"textarea", |
| 8531 |
{ |
| 8532 |
value: faq.answer, |
| 8533 |
onChange: (e) => handleFAQChange(index, "answer", e.target.value), |
| 8534 |
placeholder: __$1("Enter answer...", "yatra"), |
| 8535 |
rows: 3, |
| 8536 |
className: "flex w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-sm ring-offset-white placeholder:text-gray-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 dark:bg-gray-800 dark:ring-offset-gray-900 dark:placeholder:text-gray-400 dark:focus-visible:ring-blue-400 resize-none" |
| 8537 |
} |
| 8538 |
) |
| 8539 |
] }) |
| 8540 |
] }) |
| 8541 |
] |
| 8542 |
}, |
| 8543 |
index |
| 8544 |
)), |
| 8545 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 8546 |
Button, |
| 8547 |
{ |
| 8548 |
type: "button", |
| 8549 |
variant: "outline", |
| 8550 |
onClick: handleFAQAdd, |
| 8551 |
className: "w-full", |
| 8552 |
children: [ |
| 8553 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4 mr-2" }), |
| 8554 |
__$1("Add FAQ", "yatra") |
| 8555 |
] |
| 8556 |
} |
| 8557 |
) |
| 8558 |
] }) |
| 8559 |
] }) |
| 8560 |
] }) |
| 8561 |
] }); |
| 8562 |
case "advanced": |
| 8563 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [ |
| 8564 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2 mb-2", children: [ |
| 8565 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Settings, { className: "w-5 h-5 text-gray-500" }), |
| 8566 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: __$1("Lifecycle Management", "yatra") }), |
| 8567 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8568 |
Badge, |
| 8569 |
{ |
| 8570 |
variant: "outline", |
| 8571 |
className: "text-xs bg-purple-50 dark:bg-purple-900/20 text-purple-600 dark:text-purple-300 border-purple-200 dark:border-purple-800", |
| 8572 |
children: __$1("Power Users", "yatra") |
| 8573 |
} |
| 8574 |
) |
| 8575 |
] }), |
| 8576 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-4", children: [ |
| 8577 |
__$1("When should this trip be published or archived?", "yatra"), |
| 8578 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block text-xs text-gray-500 dark:text-gray-400 mt-1", children: __$1( |
| 8579 |
"Schedule automatic publishing and unpublishing for seasonal trips. Optional but useful for managing trip lifecycles.", |
| 8580 |
"yatra" |
| 8581 |
) }) |
| 8582 |
] }), |
| 8583 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [ |
| 8584 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { children: [ |
| 8585 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __$1("Version Control", "yatra") }), |
| 8586 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: __$1("Track changes and version history", "yatra") }) |
| 8587 |
] }), |
| 8588 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { className: "space-y-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 8589 |
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: __$1("Version", "yatra") }), |
| 8590 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8591 |
Input, |
| 8592 |
{ |
| 8593 |
type: "number", |
| 8594 |
value: formData.version, |
| 8595 |
onChange: (e) => handleFieldChange( |
| 8596 |
"version", |
| 8597 |
parseInt(e.target.value) || 1 |
| 8598 |
), |
| 8599 |
min: "1", |
| 8600 |
readOnly: true, |
| 8601 |
className: "bg-gray-50 dark:bg-gray-800" |
| 8602 |
} |
| 8603 |
), |
| 8604 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8605 |
HelpText, |
| 8606 |
{ |
| 8607 |
text: __$1( |
| 8608 |
"Version number is automatically incremented when changes are saved", |
| 8609 |
"yatra" |
| 8610 |
), |
| 8611 |
className: "mt-2" |
| 8612 |
} |
| 8613 |
) |
| 8614 |
] }) }) |
| 8615 |
] }), |
| 8616 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [ |
| 8617 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { children: [ |
| 8618 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __$1("Scheduled Publishing", "yatra") }), |
| 8619 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: __$1( |
| 8620 |
"Automatically publish or unpublish your trip on specific dates", |
| 8621 |
"yatra" |
| 8622 |
) }) |
| 8623 |
] }), |
| 8624 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-4", children: [ |
| 8625 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 8626 |
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: __$1("Schedule Publish Date", "yatra") }), |
| 8627 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8628 |
DatePicker, |
| 8629 |
{ |
| 8630 |
value: formData.scheduled_publish_date, |
| 8631 |
onChange: (val) => handleFieldChange("scheduled_publish_date", val), |
| 8632 |
placeholder: __$1("Select date", "yatra") |
| 8633 |
} |
| 8634 |
), |
| 8635 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8636 |
HelpText, |
| 8637 |
{ |
| 8638 |
text: __$1( |
| 8639 |
"Trip will be automatically published on this date and time", |
| 8640 |
"yatra" |
| 8641 |
), |
| 8642 |
className: "mt-2" |
| 8643 |
} |
| 8644 |
) |
| 8645 |
] }), |
| 8646 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 8647 |
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: __$1("Schedule Unpublish Date", "yatra") }), |
| 8648 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8649 |
DatePicker, |
| 8650 |
{ |
| 8651 |
value: formData.scheduled_unpublish_date, |
| 8652 |
onChange: (val) => handleFieldChange("scheduled_unpublish_date", val), |
| 8653 |
placeholder: __$1("Select date", "yatra") |
| 8654 |
} |
| 8655 |
), |
| 8656 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8657 |
HelpText, |
| 8658 |
{ |
| 8659 |
text: __$1( |
| 8660 |
"Trip will be automatically unpublished (archived) on this date and time", |
| 8661 |
"yatra" |
| 8662 |
), |
| 8663 |
className: "mt-2" |
| 8664 |
} |
| 8665 |
) |
| 8666 |
] }) |
| 8667 |
] }) |
| 8668 |
] }), |
| 8669 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [ |
| 8670 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { children: [ |
| 8671 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __$1("Seasonal Auto-Enable/Disable", "yatra") }), |
| 8672 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: __$1( |
| 8673 |
"Automatically enable or disable trip availability based on seasonal dates", |
| 8674 |
"yatra" |
| 8675 |
) }) |
| 8676 |
] }), |
| 8677 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-4", children: [ |
| 8678 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ |
| 8679 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8680 |
"input", |
| 8681 |
{ |
| 8682 |
type: "checkbox", |
| 8683 |
id: "seasonal_auto_enable", |
| 8684 |
checked: formData.seasonal_auto_enable, |
| 8685 |
onChange: (e) => handleFieldChange( |
| 8686 |
"seasonal_auto_enable", |
| 8687 |
e.target.checked |
| 8688 |
), |
| 8689 |
className: "w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500" |
| 8690 |
} |
| 8691 |
), |
| 8692 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8693 |
"label", |
| 8694 |
{ |
| 8695 |
htmlFor: "seasonal_auto_enable", |
| 8696 |
className: "text-sm font-medium text-gray-700 dark:text-gray-300", |
| 8697 |
children: __$1("Enable seasonal auto-management", "yatra") |
| 8698 |
} |
| 8699 |
) |
| 8700 |
] }), |
| 8701 |
formData.seasonal_auto_enable && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ |
| 8702 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 8703 |
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: __$1("Auto-Enable Date", "yatra") }), |
| 8704 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8705 |
DatePicker, |
| 8706 |
{ |
| 8707 |
value: formData.seasonal_enable_date, |
| 8708 |
onChange: (val) => handleFieldChange("seasonal_enable_date", val), |
| 8709 |
placeholder: __$1("Select date", "yatra") |
| 8710 |
} |
| 8711 |
), |
| 8712 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8713 |
HelpText, |
| 8714 |
{ |
| 8715 |
text: __$1( |
| 8716 |
"Trip will become available for booking on this date", |
| 8717 |
"yatra" |
| 8718 |
), |
| 8719 |
className: "mt-2" |
| 8720 |
} |
| 8721 |
) |
| 8722 |
] }), |
| 8723 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 8724 |
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: __$1("Auto-Disable Date", "yatra") }), |
| 8725 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8726 |
DatePicker, |
| 8727 |
{ |
| 8728 |
value: formData.seasonal_disable_date, |
| 8729 |
onChange: (val) => handleFieldChange("seasonal_disable_date", val), |
| 8730 |
placeholder: __$1("Select date", "yatra") |
| 8731 |
} |
| 8732 |
), |
| 8733 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8734 |
HelpText, |
| 8735 |
{ |
| 8736 |
text: __$1( |
| 8737 |
"Trip will become unavailable for booking on this date", |
| 8738 |
"yatra" |
| 8739 |
), |
| 8740 |
className: "mt-2" |
| 8741 |
} |
| 8742 |
) |
| 8743 |
] }) |
| 8744 |
] }) |
| 8745 |
] }) |
| 8746 |
] }), |
| 8747 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [ |
| 8748 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { children: [ |
| 8749 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __$1("Frontend Tabs Management", "yatra") }), |
| 8750 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: __$1( |
| 8751 |
"Manage which tabs appear on the trip single page and in what order. Enable or disable tabs, customize labels, and reorder them.", |
| 8752 |
"yatra" |
| 8753 |
) }) |
| 8754 |
] }), |
| 8755 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { children: [ |
| 8756 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: [...formData.frontend_tabs].sort((a, b) => a.order - b.order).map((tab, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 8757 |
"div", |
| 8758 |
{ |
| 8759 |
draggable: true, |
| 8760 |
onDragStart: (e) => handleDragStart(e, tab.id), |
| 8761 |
onDragOver: handleDragOver, |
| 8762 |
onDragEnter: () => handleDragEnter(tab.id), |
| 8763 |
onDragLeave: handleDragLeave, |
| 8764 |
onDrop: (e) => handleDrop(e, tab.id), |
| 8765 |
onDragEnd: handleDragEnd, |
| 8766 |
className: `p-4 rounded-lg border cursor-move relative ${tab.enabled ? "bg-gray-50 dark:bg-gray-850 border-gray-200 dark:border-gray-700 shadow-sm" : "bg-gray-100 dark:bg-gray-900 border-gray-200 dark:border-gray-700 opacity-60 shadow-sm"} ${draggedTab === tab.id ? "opacity-50 scale-95 shadow-lg" : ""} ${dragOverTab === tab.id && draggedTab !== tab.id ? "border-blue-400 bg-blue-50 dark:bg-blue-900/20" : ""}`, |
| 8767 |
children: [ |
| 8768 |
tab.content_type === "custom" && /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8769 |
Button, |
| 8770 |
{ |
| 8771 |
type: "button", |
| 8772 |
variant: "ghost", |
| 8773 |
size: "sm", |
| 8774 |
onClick: () => handleTabRemove(tab.id), |
| 8775 |
className: "absolute top-2 right-2 h-10 w-10 p-0 text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-900/20", |
| 8776 |
title: __$1("Delete tab", "yatra"), |
| 8777 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "w-5 h-5" }) |
| 8778 |
} |
| 8779 |
), |
| 8780 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 mb-3", children: [ |
| 8781 |
/* @__PURE__ */ jsxRuntimeExports.jsx(GripVertical, { className: "w-6 h-6 text-gray-400 cursor-grab active:cursor-grabbing" }), |
| 8782 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [ |
| 8783 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-2", children: [ |
| 8784 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8785 |
Input, |
| 8786 |
{ |
| 8787 |
type: "text", |
| 8788 |
value: tab.label, |
| 8789 |
onChange: (e) => handleTabLabelChange(tab.id, e.target.value), |
| 8790 |
className: "text-sm font-medium flex-1", |
| 8791 |
disabled: !tab.enabled, |
| 8792 |
placeholder: __$1("Tab Label", "yatra") |
| 8793 |
} |
| 8794 |
), |
| 8795 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "outline", className: "text-xs", children: tab.content_type }) |
| 8796 |
] }), |
| 8797 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-2", children: tab.enabled ? /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8798 |
IconPicker, |
| 8799 |
{ |
| 8800 |
value: tab.icon || null, |
| 8801 |
onChange: (value) => handleTabIconChange(tab.id, value), |
| 8802 |
label: __$1("Tab Icon", "yatra"), |
| 8803 |
helpText: __$1( |
| 8804 |
"Select an icon or upload an image for this tab", |
| 8805 |
"yatra" |
| 8806 |
), |
| 8807 |
size: "sm" |
| 8808 |
} |
| 8809 |
) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "opacity-50", children: /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8810 |
IconPicker, |
| 8811 |
{ |
| 8812 |
value: tab.icon || null, |
| 8813 |
onChange: () => { |
| 8814 |
}, |
| 8815 |
label: __$1("Tab Icon", "yatra"), |
| 8816 |
helpText: __$1( |
| 8817 |
"Enable this tab to select an icon", |
| 8818 |
"yatra" |
| 8819 |
), |
| 8820 |
size: "sm" |
| 8821 |
} |
| 8822 |
) }) }), |
| 8823 |
tab.content_type === "custom" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2", children: [ |
| 8824 |
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1.5", children: __$1("Custom Content", "yatra") }), |
| 8825 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8826 |
"textarea", |
| 8827 |
{ |
| 8828 |
value: tab.custom_content || "", |
| 8829 |
onChange: (e) => handleTabCustomContentChange( |
| 8830 |
tab.id, |
| 8831 |
e.target.value |
| 8832 |
), |
| 8833 |
rows: 3, |
| 8834 |
disabled: !tab.enabled, |
| 8835 |
placeholder: __$1( |
| 8836 |
"Enter custom content for this tab...", |
| 8837 |
"yatra" |
| 8838 |
), |
| 8839 |
className: "flex w-full rounded-md border border-gray-300 bg-white px-3 py-2 text-sm ring-offset-white placeholder:text-gray-500 focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-blue-500 focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50 dark:border-gray-600 dark:bg-gray-800 dark:ring-offset-gray-900 dark:placeholder:text-gray-400 dark:focus-visible:ring-blue-400 resize-none" |
| 8840 |
} |
| 8841 |
) |
| 8842 |
] }), |
| 8843 |
tab.content_type !== "custom" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2", children: /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 8844 |
Select, |
| 8845 |
{ |
| 8846 |
value: tab.content_type, |
| 8847 |
onChange: (e) => handleTabContentTypeChange( |
| 8848 |
tab.id, |
| 8849 |
e.target.value |
| 8850 |
), |
| 8851 |
disabled: !tab.enabled, |
| 8852 |
className: "text-xs", |
| 8853 |
children: [ |
| 8854 |
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "overview", children: __$1("Overview", "yatra") }), |
| 8855 |
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "itinerary", children: __$1("Itinerary", "yatra") }), |
| 8856 |
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "included_excluded", children: __$1("Included", "yatra") }), |
| 8857 |
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "location", children: __$1("Location", "yatra") }), |
| 8858 |
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "important_info", children: __$1("Important Info", "yatra") }), |
| 8859 |
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "downloads", children: __$1("Downloads", "yatra") }), |
| 8860 |
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "faq", children: __$1("FAQ", "yatra") }), |
| 8861 |
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "trip_story", children: __$1("Story", "yatra") }), |
| 8862 |
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "what_makes_special", children: __$1("Special", "yatra") }), |
| 8863 |
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "testimonials", children: __$1("Testimonials", "yatra") }), |
| 8864 |
/* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "custom", children: __$1("Custom Content", "yatra") }) |
| 8865 |
] |
| 8866 |
} |
| 8867 |
) }) |
| 8868 |
] }), |
| 8869 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [ |
| 8870 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8871 |
Button, |
| 8872 |
{ |
| 8873 |
type: "button", |
| 8874 |
variant: "ghost", |
| 8875 |
size: "sm", |
| 8876 |
onClick: () => handleTabMove(tab.id, "up"), |
| 8877 |
disabled: index === 0, |
| 8878 |
className: "h-10 w-10 p-0", |
| 8879 |
title: __$1("Move up", "yatra"), |
| 8880 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronUp, { className: "w-5 h-5" }) |
| 8881 |
} |
| 8882 |
), |
| 8883 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8884 |
Button, |
| 8885 |
{ |
| 8886 |
type: "button", |
| 8887 |
variant: "ghost", |
| 8888 |
size: "sm", |
| 8889 |
onClick: () => handleTabMove(tab.id, "down"), |
| 8890 |
disabled: index === formData.frontend_tabs.length - 1, |
| 8891 |
className: "h-10 w-10 p-0", |
| 8892 |
title: __$1("Move down", "yatra"), |
| 8893 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "w-5 h-5" }) |
| 8894 |
} |
| 8895 |
), |
| 8896 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [ |
| 8897 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8898 |
"input", |
| 8899 |
{ |
| 8900 |
type: "checkbox", |
| 8901 |
checked: tab.enabled, |
| 8902 |
onChange: () => handleTabToggle(tab.id), |
| 8903 |
className: "w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500" |
| 8904 |
} |
| 8905 |
), |
| 8906 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: tab.enabled ? __$1("Enabled", "yatra") : __$1("Disabled", "yatra") }) |
| 8907 |
] }) |
| 8908 |
] }) |
| 8909 |
] }) |
| 8910 |
] |
| 8911 |
}, |
| 8912 |
tab.id |
| 8913 |
)) }), |
| 8914 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-4 pt-4 border-t border-gray-200 dark:border-gray-700", children: /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 8915 |
Button, |
| 8916 |
{ |
| 8917 |
type: "button", |
| 8918 |
variant: "outline", |
| 8919 |
onClick: handleTabAdd, |
| 8920 |
className: "w-full", |
| 8921 |
children: [ |
| 8922 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4 mr-2" }), |
| 8923 |
__$1("Add Custom Tab", "yatra") |
| 8924 |
] |
| 8925 |
} |
| 8926 |
) }) |
| 8927 |
] }) |
| 8928 |
] }) |
| 8929 |
] }); |
| 8930 |
default: |
| 8931 |
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-center py-8 text-gray-500", children: __$1("Section content coming soon...", "yatra") }); |
| 8932 |
} |
| 8933 |
}; |
| 8934 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-h-0 flex flex-col bg-white dark:bg-gray-900 overflow-hidden", children: [ |
| 8935 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-gray-100 dark:bg-gray-800 border-b border-gray-200 dark:border-gray-700 px-4 py-3 flex items-center justify-between", children: [ |
| 8936 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-4 min-w-0 flex-1", children: [ |
| 8937 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [ |
| 8938 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h1", { className: "text-base font-semibold text-gray-900 dark:text-white truncate", children: formData.title || __$1("New Trip", "yatra") }), |
| 8939 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-2 mt-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8940 |
Badge, |
| 8941 |
{ |
| 8942 |
variant: "outline", |
| 8943 |
className: `bg-white dark:bg-gray-700 border-gray-300 dark:border-gray-600 ${formData.status === "publish" ? "text-green-700 dark:text-green-400 border-green-300 dark:border-green-800" : formData.status === "review" ? "text-yellow-700 dark:text-yellow-400 border-yellow-300 dark:border-yellow-800" : formData.status === "approved" ? "text-blue-700 dark:text-blue-400 border-blue-300 dark:border-blue-800" : formData.status === "suspended" ? "text-orange-700 dark:text-orange-400 border-orange-300 dark:border-orange-800" : formData.status === "archived" ? "text-gray-700 dark:text-gray-400 border-gray-300 dark:border-gray-600" : "text-gray-700 dark:text-gray-300"}`, |
| 8944 |
children: formData.status === "draft" ? __$1("Draft", "yatra") : formData.status === "review" ? __$1("Review", "yatra") : formData.status === "approved" ? __$1("Approved", "yatra") : formData.status === "publish" ? __$1("Published", "yatra") : formData.status === "suspended" ? __$1("Suspended", "yatra") : __$1("Archived", "yatra") |
| 8945 |
} |
| 8946 |
) }) |
| 8947 |
] }), |
| 8948 |
!isEditMode && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-2 px-2 py-1 rounded-md bg-gray-50 dark:bg-gray-700/50 flex-shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 8949 |
"button", |
| 8950 |
{ |
| 8951 |
onClick: () => setSimpleMode(!simpleMode), |
| 8952 |
className: "flex items-center gap-1.5 text-xs text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-200", |
| 8953 |
title: simpleMode ? __$1("Switch to Advanced Mode", "yatra") : __$1("Switch to Simple Mode", "yatra"), |
| 8954 |
children: [ |
| 8955 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 8956 |
Lightbulb, |
| 8957 |
{ |
| 8958 |
className: `w-3.5 h-3.5 ${simpleMode ? "text-yellow-500" : ""}` |
| 8959 |
} |
| 8960 |
), |
| 8961 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: simpleMode ? __$1("Simple", "yatra") : __$1("Advanced", "yatra") }) |
| 8962 |
] |
| 8963 |
} |
| 8964 |
) }), |
| 8965 |
!isEditMode && /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 8966 |
Button, |
| 8967 |
{ |
| 8968 |
variant: "ghost", |
| 8969 |
size: "sm", |
| 8970 |
onClick: () => { |
| 8971 |
showToast( |
| 8972 |
__$1("Guided tour feature coming soon!", "yatra"), |
| 8973 |
"info" |
| 8974 |
); |
| 8975 |
}, |
| 8976 |
className: "text-xs text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-200 flex-shrink-0", |
| 8977 |
children: [ |
| 8978 |
/* @__PURE__ */ jsxRuntimeExports.jsx(BookOpen, { className: "w-3.5 h-3.5 mr-1" }), |
| 8979 |
__$1("Take a Tour", "yatra") |
| 8980 |
] |
| 8981 |
} |
| 8982 |
), |
| 8983 |
!isEditMode && /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 8984 |
Button, |
| 8985 |
{ |
| 8986 |
variant: "ghost", |
| 8987 |
size: "sm", |
| 8988 |
onClick: handleFillDummyData, |
| 8989 |
className: "text-xs text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-200 flex-shrink-0", |
| 8990 |
title: __$1("Fill form with dummy data", "yatra"), |
| 8991 |
children: [ |
| 8992 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Database, { className: "w-3.5 h-3.5 mr-1" }), |
| 8993 |
__$1("Fill Dummy Data", "yatra"), |
| 8994 |
" (", |
| 8995 |
dummyDataIndex + 1, |
| 8996 |
"/", |
| 8997 |
dummyTripsData.length, |
| 8998 |
")" |
| 8999 |
] |
| 9000 |
} |
| 9001 |
) |
| 9002 |
] }), |
| 9003 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [ |
| 9004 |
isEditMode && /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 9005 |
Button, |
| 9006 |
{ |
| 9007 |
variant: "outline", |
| 9008 |
onClick: () => setShowRevisionsDialog(true), |
| 9009 |
className: "text-gray-700 dark:text-gray-300 border-gray-300 dark:border-gray-600 hover:bg-gray-50 dark:hover:bg-gray-700", |
| 9010 |
children: [ |
| 9011 |
/* @__PURE__ */ jsxRuntimeExports.jsx(History, { className: "w-4 h-4 mr-2" }), |
| 9012 |
__$1("Revisions", "yatra") |
| 9013 |
] |
| 9014 |
} |
| 9015 |
), |
| 9016 |
isAiEligible() && isAiModuleEnabled() && /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 9017 |
Button, |
| 9018 |
{ |
| 9019 |
type: "button", |
| 9020 |
onClick: () => { |
| 9021 |
setAiModalMode("all"); |
| 9022 |
setAiModalOpen(true); |
| 9023 |
}, |
| 9024 |
className: "bg-gradient-to-r from-purple-600 to-indigo-600 text-white border-0 hover:from-purple-700 hover:to-indigo-700", |
| 9025 |
title: __$1( |
| 9026 |
"Generate description, itinerary, included items, SEO meta, and more — from this trip's facts.", |
| 9027 |
"yatra" |
| 9028 |
), |
| 9029 |
children: [ |
| 9030 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "w-4 h-4 mr-2" }), |
| 9031 |
__$1("Auto-fill with AI", "yatra") |
| 9032 |
] |
| 9033 |
} |
| 9034 |
), |
| 9035 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 9036 |
Button, |
| 9037 |
{ |
| 9038 |
variant: "outline", |
| 9039 |
onClick: handlePreview, |
| 9040 |
className: "text-gray-700 dark:text-gray-300 border-gray-300 dark:border-gray-600 hover:bg-gray-50 dark:hover:bg-gray-700", |
| 9041 |
disabled: !formData.slug, |
| 9042 |
children: [ |
| 9043 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Eye, { className: "w-4 h-4 mr-2" }), |
| 9044 |
__$1("Preview", "yatra") |
| 9045 |
] |
| 9046 |
} |
| 9047 |
), |
| 9048 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 9049 |
Button, |
| 9050 |
{ |
| 9051 |
variant: "outline", |
| 9052 |
onClick: handleSaveDraft, |
| 9053 |
disabled: isSubmitting, |
| 9054 |
className: "text-gray-700 dark:text-gray-300 border-gray-300 dark:border-gray-600 hover:bg-gray-50 dark:hover:bg-gray-700", |
| 9055 |
children: [ |
| 9056 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Save, { className: "w-4 h-4 mr-2" }), |
| 9057 |
isEditMode ? __$1("Update Draft", "yatra") : __$1("Save Draft", "yatra") |
| 9058 |
] |
| 9059 |
} |
| 9060 |
), |
| 9061 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative group", children: [ |
| 9062 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9063 |
Button, |
| 9064 |
{ |
| 9065 |
onClick: handlePublish, |
| 9066 |
disabled: isSubmitting, |
| 9067 |
className: "bg-blue-600 hover:bg-blue-700 text-white border-0 relative", |
| 9068 |
children: isSubmitting ? /* @__PURE__ */ jsxRuntimeExports.jsx(Loader2, { className: "w-4 h-4 mr-2 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [ |
| 9069 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Send, { className: "w-4 h-4 mr-2" }), |
| 9070 |
isEditMode ? __$1("Update Trip", "yatra") : __$1("Publish Trip", "yatra"), |
| 9071 |
/* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "w-4 h-4 ml-2" }) |
| 9072 |
] }) |
| 9073 |
} |
| 9074 |
), |
| 9075 |
!isSubmitting && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute right-0 top-full mt-1 w-48 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 rounded-md shadow-lg opacity-0 invisible group-hover:opacity-100 group-hover:visible transition-all duration-200 z-50", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "py-1", children: [ |
| 9076 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9077 |
"button", |
| 9078 |
{ |
| 9079 |
type: "button", |
| 9080 |
onClick: () => { |
| 9081 |
handleFieldChange("status", "draft"); |
| 9082 |
handleSaveDraft(); |
| 9083 |
}, |
| 9084 |
className: "w-full text-left px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 flex items-center gap-2", |
| 9085 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: __$1("Save as Draft", "yatra") }) |
| 9086 |
} |
| 9087 |
), |
| 9088 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9089 |
"button", |
| 9090 |
{ |
| 9091 |
type: "button", |
| 9092 |
onClick: () => { |
| 9093 |
handleFieldChange("status", "review"); |
| 9094 |
handlePublish(); |
| 9095 |
}, |
| 9096 |
className: "w-full text-left px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 flex items-center gap-2", |
| 9097 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: __$1("Save for Review", "yatra") }) |
| 9098 |
} |
| 9099 |
), |
| 9100 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9101 |
"button", |
| 9102 |
{ |
| 9103 |
type: "button", |
| 9104 |
onClick: () => { |
| 9105 |
handleFieldChange("status", "approved"); |
| 9106 |
handlePublish(); |
| 9107 |
}, |
| 9108 |
className: "w-full text-left px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 flex items-center gap-2", |
| 9109 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: __$1("Mark as Approved", "yatra") }) |
| 9110 |
} |
| 9111 |
), |
| 9112 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 9113 |
"button", |
| 9114 |
{ |
| 9115 |
type: "button", |
| 9116 |
onClick: handlePublish, |
| 9117 |
className: "w-full text-left px-4 py-2 text-sm text-blue-600 dark:text-blue-400 hover:bg-blue-50 dark:hover:bg-blue-900/20 font-medium flex items-center gap-2", |
| 9118 |
children: [ |
| 9119 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "w-4 h-4" }), |
| 9120 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: isEditMode ? __$1("Update & Publish", "yatra") : __$1("Publish", "yatra") }) |
| 9121 |
] |
| 9122 |
} |
| 9123 |
), |
| 9124 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9125 |
"button", |
| 9126 |
{ |
| 9127 |
type: "button", |
| 9128 |
onClick: () => { |
| 9129 |
handleFieldChange("status", "suspended"); |
| 9130 |
handlePublish(); |
| 9131 |
}, |
| 9132 |
className: "w-full text-left px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 flex items-center gap-2", |
| 9133 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: __$1("Suspend", "yatra") }) |
| 9134 |
} |
| 9135 |
), |
| 9136 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9137 |
"button", |
| 9138 |
{ |
| 9139 |
type: "button", |
| 9140 |
onClick: () => { |
| 9141 |
handleFieldChange("status", "archived"); |
| 9142 |
handlePublish(); |
| 9143 |
}, |
| 9144 |
className: "w-full text-left px-4 py-2 text-sm text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-700 flex items-center gap-2", |
| 9145 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: __$1("Archive", "yatra") }) |
| 9146 |
} |
| 9147 |
) |
| 9148 |
] }) }) |
| 9149 |
] }) |
| 9150 |
] }) |
| 9151 |
] }), |
| 9152 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "bg-gray-50 dark:bg-gray-800/50 border-b border-gray-200 dark:border-gray-700 px-4 py-2.5", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between gap-4", children: [ |
| 9153 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 9154 |
Button, |
| 9155 |
{ |
| 9156 |
variant: "outline", |
| 9157 |
size: "default", |
| 9158 |
onClick: goToPreviousSection, |
| 9159 |
disabled: currentStepIndex === 0, |
| 9160 |
className: "flex items-center gap-2 text-sm font-semibold border-2 border-blue-400 dark:border-blue-600 bg-blue-50 dark:bg-blue-900/30 hover:bg-blue-100 dark:hover:bg-blue-900/50 hover:border-blue-500 dark:hover:border-blue-500 text-blue-700 dark:text-blue-300 shadow-sm disabled:opacity-40 disabled:cursor-not-allowed flex-shrink-0 px-4 py-2", |
| 9161 |
children: [ |
| 9162 |
/* @__PURE__ */ jsxRuntimeExports.jsx(ChevronLeft, { className: "w-4 h-4" }), |
| 9163 |
__$1("Previous", "yatra") |
| 9164 |
] |
| 9165 |
} |
| 9166 |
), |
| 9167 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 9168 |
Button, |
| 9169 |
{ |
| 9170 |
variant: "outline", |
| 9171 |
size: "default", |
| 9172 |
onClick: goToNextSection, |
| 9173 |
disabled: currentStepIndex >= allSections.length - 1, |
| 9174 |
className: "flex items-center gap-2 text-sm font-semibold border-2 border-blue-400 dark:border-blue-600 bg-blue-50 dark:bg-blue-900/30 hover:bg-blue-100 dark:hover:bg-blue-900/50 hover:border-blue-500 dark:hover:border-blue-500 text-blue-700 dark:text-blue-300 shadow-sm disabled:opacity-40 disabled:cursor-not-allowed flex-shrink-0 px-4 py-2", |
| 9175 |
children: [ |
| 9176 |
__$1("Next", "yatra"), |
| 9177 |
/* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "w-4 h-4" }) |
| 9178 |
] |
| 9179 |
} |
| 9180 |
) |
| 9181 |
] }) }), |
| 9182 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-1 min-h-0 p-0", children: [ |
| 9183 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-80 bg-gray-50 dark:bg-gray-900 border-r border-gray-200 dark:border-gray-800 overflow-y-auto overflow-x-hidden flex-shrink-0 min-h-0", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-5 pb-8 space-y-6", children: [ |
| 9184 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 9185 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-3 px-1", children: [ |
| 9186 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 flex-1", children: [ |
| 9187 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Box, { className: "w-3.5 h-3.5 text-red-500 dark:text-red-400 flex-shrink-0" }), |
| 9188 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-[10px] font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-widest", children: __$1("PHASE 1: ESSENTIALS", "yatra") }) |
| 9189 |
] }), |
| 9190 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9191 |
Badge, |
| 9192 |
{ |
| 9193 |
variant: "outline", |
| 9194 |
className: "text-[9px] px-1.5 py-0 bg-red-50 dark:bg-red-900/20 text-red-600 dark:text-red-400 border-red-200 dark:border-red-800", |
| 9195 |
children: __$1("Must Complete", "yatra") |
| 9196 |
} |
| 9197 |
) |
| 9198 |
] }), |
| 9199 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-0.5", children: essentialsSections.map((section, index) => { |
| 9200 |
const Icon = section.icon; |
| 9201 |
const isActive = currentSection === section.id; |
| 9202 |
const isNext = !section.completed && essentialsSections.slice(0, index).every((s) => s.completed); |
| 9203 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 9204 |
"button", |
| 9205 |
{ |
| 9206 |
type: "button", |
| 9207 |
onClick: () => setCurrentSection(section.id), |
| 9208 |
className: `w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-normal transition-all duration-200 text-left group border relative ${isActive ? "bg-blue-50 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 shadow-sm border-blue-200 dark:border-blue-800" : isNext ? "border-amber-200 dark:border-amber-800 bg-amber-50/50 dark:bg-amber-900/10 text-gray-700 dark:text-gray-300 hover:bg-amber-50 dark:hover:bg-amber-900/20" : "border-transparent text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800/50 hover:text-gray-900 dark:hover:text-gray-100"}`, |
| 9209 |
children: [ |
| 9210 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [ |
| 9211 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9212 |
"span", |
| 9213 |
{ |
| 9214 |
className: `text-[10px] font-bold w-5 h-5 flex items-center justify-center rounded-full ${isActive ? "bg-blue-600 text-white dark:bg-blue-500" : isNext ? "bg-amber-500 text-white" : section.completed ? "bg-green-500 text-white" : section.hasErrors ? "bg-red-500 text-white" : "bg-gray-300 dark:bg-gray-700 text-gray-600 dark:text-gray-400"}`, |
| 9215 |
children: index + 1 |
| 9216 |
} |
| 9217 |
), |
| 9218 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9219 |
Icon, |
| 9220 |
{ |
| 9221 |
className: `w-4 h-4 transition-colors ${isActive ? "text-blue-600 dark:text-blue-400" : isNext ? "text-amber-600 dark:text-amber-400" : section.hasErrors ? "text-red-600 dark:text-red-400" : "text-gray-400 dark:text-gray-500 group-hover:text-gray-600 dark:group-hover:text-gray-400"}` |
| 9222 |
} |
| 9223 |
) |
| 9224 |
] }), |
| 9225 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex-1 min-w-0 break-words leading-snug", children: [ |
| 9226 |
section.label, |
| 9227 |
section.required && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ml-1 text-[9px] text-red-500", children: "*" }) |
| 9228 |
] }), |
| 9229 |
section.hasErrors && /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9230 |
"span", |
| 9231 |
{ |
| 9232 |
className: "flex-shrink-0 w-2 h-2 bg-red-500 rounded-full", |
| 9233 |
title: __$1("This section has errors", "yatra") |
| 9234 |
} |
| 9235 |
) |
| 9236 |
] |
| 9237 |
}, |
| 9238 |
section.id |
| 9239 |
); |
| 9240 |
}) }) |
| 9241 |
] }), |
| 9242 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 9243 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-3 px-1", children: [ |
| 9244 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 flex-1", children: [ |
| 9245 |
/* @__PURE__ */ jsxRuntimeExports.jsx(BookOpen, { className: "w-3.5 h-3.5 text-blue-500 dark:text-blue-400 flex-shrink-0" }), |
| 9246 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-[10px] font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-widest", children: __$1("PHASE 2: DETAILS", "yatra") }) |
| 9247 |
] }), |
| 9248 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9249 |
Badge, |
| 9250 |
{ |
| 9251 |
variant: "outline", |
| 9252 |
className: "text-[9px] px-1.5 py-0 bg-blue-50 dark:bg-blue-900/20 text-blue-600 dark:text-blue-400 border-blue-200 dark:border-blue-800", |
| 9253 |
children: __$1("Recommended", "yatra") |
| 9254 |
} |
| 9255 |
) |
| 9256 |
] }), |
| 9257 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-0.5", children: detailsSections.map((section, index) => { |
| 9258 |
const Icon = section.icon; |
| 9259 |
const isActive = currentSection === section.id; |
| 9260 |
const sectionNumber = essentialsSections.length + index + 1; |
| 9261 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 9262 |
"button", |
| 9263 |
{ |
| 9264 |
type: "button", |
| 9265 |
onClick: () => setCurrentSection(section.id), |
| 9266 |
className: `w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-normal transition-all duration-200 text-left group border ${isActive ? "bg-blue-50 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 shadow-sm border-blue-200 dark:border-blue-800" : section.hasErrors ? "border-red-200 dark:border-red-800 bg-red-50/50 dark:bg-red-900/10" : "border-transparent text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800/50 hover:text-gray-900 dark:hover:text-gray-100"}`, |
| 9267 |
children: [ |
| 9268 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [ |
| 9269 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9270 |
"span", |
| 9271 |
{ |
| 9272 |
className: `text-[10px] font-bold w-5 h-5 flex items-center justify-center rounded-full ${isActive ? "bg-blue-600 text-white dark:bg-blue-500" : section.completed ? "bg-green-500 text-white" : section.hasErrors ? "bg-red-500 text-white" : "bg-gray-300 dark:bg-gray-700 text-gray-600 dark:text-gray-400"}`, |
| 9273 |
children: sectionNumber |
| 9274 |
} |
| 9275 |
), |
| 9276 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9277 |
Icon, |
| 9278 |
{ |
| 9279 |
className: `w-4 h-4 transition-colors ${isActive ? "text-blue-600 dark:text-blue-400" : section.hasErrors ? "text-red-600 dark:text-red-400" : "text-gray-400 dark:text-gray-500 group-hover:text-gray-600 dark:group-hover:text-gray-400"}` |
| 9280 |
} |
| 9281 |
) |
| 9282 |
] }), |
| 9283 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 min-w-0 break-words leading-snug", children: section.label }), |
| 9284 |
section.hasErrors && /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9285 |
"span", |
| 9286 |
{ |
| 9287 |
className: "flex-shrink-0 w-2 h-2 bg-red-500 rounded-full", |
| 9288 |
title: __$1("This section has errors", "yatra") |
| 9289 |
} |
| 9290 |
) |
| 9291 |
] |
| 9292 |
}, |
| 9293 |
section.id |
| 9294 |
); |
| 9295 |
}) }) |
| 9296 |
] }), |
| 9297 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 9298 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-3 px-1", children: [ |
| 9299 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 flex-1", children: [ |
| 9300 |
/* @__PURE__ */ jsxRuntimeExports.jsx(BarChart3, { className: "w-3.5 h-3.5 text-purple-500 dark:text-purple-400 flex-shrink-0" }), |
| 9301 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-[10px] font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-widest", children: __$1("PHASE 3: OPTIMIZATION", "yatra") }) |
| 9302 |
] }), |
| 9303 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9304 |
Badge, |
| 9305 |
{ |
| 9306 |
variant: "outline", |
| 9307 |
className: "text-[9px] px-1.5 py-0 bg-purple-50 dark:bg-purple-900/20 text-purple-600 dark:text-purple-400 border-purple-200 dark:border-purple-800", |
| 9308 |
children: __$1("Optional", "yatra") |
| 9309 |
} |
| 9310 |
) |
| 9311 |
] }), |
| 9312 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-0.5", children: optimizationSections.map((section, index) => { |
| 9313 |
const Icon = section.icon; |
| 9314 |
const isActive = currentSection === section.id; |
| 9315 |
const sectionNumber = essentialsSections.length + detailsSections.length + index + 1; |
| 9316 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 9317 |
"button", |
| 9318 |
{ |
| 9319 |
type: "button", |
| 9320 |
onClick: () => setCurrentSection(section.id), |
| 9321 |
className: `w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-normal transition-all duration-200 text-left group border ${isActive ? "bg-blue-50 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 shadow-sm border-blue-200 dark:border-blue-800" : section.hasErrors ? "border-red-200 dark:border-red-800 bg-red-50/50 dark:bg-red-900/10" : "border-transparent text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800/50 hover:text-gray-900 dark:hover:text-gray-100"}`, |
| 9322 |
children: [ |
| 9323 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [ |
| 9324 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9325 |
"span", |
| 9326 |
{ |
| 9327 |
className: `text-[10px] font-bold w-5 h-5 flex items-center justify-center rounded-full ${isActive ? "bg-blue-600 text-white dark:bg-blue-500" : section.completed ? "bg-green-500 text-white" : section.hasErrors ? "bg-red-500 text-white" : "bg-gray-300 dark:bg-gray-700 text-gray-600 dark:text-gray-400"}`, |
| 9328 |
children: sectionNumber |
| 9329 |
} |
| 9330 |
), |
| 9331 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9332 |
Icon, |
| 9333 |
{ |
| 9334 |
className: `w-4 h-4 transition-colors ${isActive ? "text-blue-600 dark:text-blue-400" : section.hasErrors ? "text-red-600 dark:text-red-400" : "text-gray-400 dark:text-gray-500 group-hover:text-gray-600 dark:group-hover:text-gray-400"}` |
| 9335 |
} |
| 9336 |
) |
| 9337 |
] }), |
| 9338 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 min-w-0 break-words leading-snug", children: section.label }), |
| 9339 |
section.hasErrors && /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9340 |
"span", |
| 9341 |
{ |
| 9342 |
className: "flex-shrink-0 w-2 h-2 bg-red-500 rounded-full", |
| 9343 |
title: __$1("This section has errors", "yatra") |
| 9344 |
} |
| 9345 |
) |
| 9346 |
] |
| 9347 |
}, |
| 9348 |
section.id |
| 9349 |
); |
| 9350 |
}) }) |
| 9351 |
] }), |
| 9352 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "pb-12", children: [ |
| 9353 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-3 px-1", children: [ |
| 9354 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 flex-1", children: [ |
| 9355 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Settings, { className: "w-3.5 h-3.5 text-gray-400 dark:text-gray-500 flex-shrink-0" }), |
| 9356 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-[10px] font-semibold text-gray-500 dark:text-gray-400 uppercase tracking-widest", children: __$1("PHASE 4: ADVANCED", "yatra") }) |
| 9357 |
] }), |
| 9358 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9359 |
Badge, |
| 9360 |
{ |
| 9361 |
variant: "outline", |
| 9362 |
className: "text-[9px] px-1.5 py-0 bg-gray-50 dark:bg-gray-900/20 text-gray-600 dark:text-gray-400 border-gray-200 dark:border-gray-800", |
| 9363 |
children: __$1("Power Users", "yatra") |
| 9364 |
} |
| 9365 |
) |
| 9366 |
] }), |
| 9367 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-0.5", children: advancedSections.map((section, index) => { |
| 9368 |
const Icon = section.icon; |
| 9369 |
const isActive = currentSection === section.id; |
| 9370 |
const sectionNumber = essentialsSections.length + detailsSections.length + optimizationSections.length + index + 1; |
| 9371 |
return /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 9372 |
"button", |
| 9373 |
{ |
| 9374 |
type: "button", |
| 9375 |
onClick: () => setCurrentSection(section.id), |
| 9376 |
className: `w-full flex items-center gap-3 px-3 py-2.5 rounded-lg text-sm font-normal transition-all duration-200 text-left group border ${isActive ? "bg-blue-50 dark:bg-blue-900/30 text-blue-700 dark:text-blue-300 shadow-sm border-blue-200 dark:border-blue-800" : "border-transparent text-gray-700 dark:text-gray-300 hover:bg-gray-100 dark:hover:bg-gray-800/50 hover:text-gray-900 dark:hover:text-gray-100"}`, |
| 9377 |
children: [ |
| 9378 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [ |
| 9379 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9380 |
"span", |
| 9381 |
{ |
| 9382 |
className: `text-[10px] font-bold w-5 h-5 flex items-center justify-center rounded-full ${isActive ? "bg-blue-600 text-white dark:bg-blue-500" : "bg-gray-300 dark:bg-gray-700 text-gray-600 dark:text-gray-400"}`, |
| 9383 |
children: sectionNumber |
| 9384 |
} |
| 9385 |
), |
| 9386 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9387 |
Icon, |
| 9388 |
{ |
| 9389 |
className: `w-4 h-4 transition-colors ${isActive ? "text-blue-600 dark:text-blue-400" : "text-gray-400 dark:text-gray-500 group-hover:text-gray-600 dark:group-hover:text-gray-400"}` |
| 9390 |
} |
| 9391 |
) |
| 9392 |
] }), |
| 9393 |
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 min-w-0 break-words leading-snug", children: section.label }) |
| 9394 |
] |
| 9395 |
}, |
| 9396 |
section.id |
| 9397 |
); |
| 9398 |
}) }) |
| 9399 |
] }) |
| 9400 |
] }) }), |
| 9401 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1 overflow-y-auto bg-white dark:bg-gray-900", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-6 pb-24 max-w-4xl", children: [ |
| 9402 |
errors.submit && /* @__PURE__ */ jsxRuntimeExports.jsx(Alert, { variant: "error", className: "mb-4", children: errors.submit }), |
| 9403 |
renderSectionContent() |
| 9404 |
] }) }) |
| 9405 |
] }), |
| 9406 |
showHighlightModal && /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9407 |
"div", |
| 9408 |
{ |
| 9409 |
className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50", |
| 9410 |
onClick: () => setShowHighlightModal(false), |
| 9411 |
children: /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 9412 |
"div", |
| 9413 |
{ |
| 9414 |
className: "bg-white dark:bg-gray-800 rounded-lg p-6 max-w-md w-full mx-4 shadow-xl", |
| 9415 |
onClick: (e) => e.stopPropagation(), |
| 9416 |
children: [ |
| 9417 |
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-semibold text-gray-900 dark:text-white mb-4", children: __$1("Add Highlight", "yatra") }), |
| 9418 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ |
| 9419 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 9420 |
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: __$1("Highlight Text", "yatra") }), |
| 9421 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9422 |
Input, |
| 9423 |
{ |
| 9424 |
type: "text", |
| 9425 |
value: modalInput.text, |
| 9426 |
onChange: (e) => setModalInput({ ...modalInput, text: e.target.value }), |
| 9427 |
placeholder: __$1("e.g., Private guide included", "yatra"), |
| 9428 |
autoFocus: true, |
| 9429 |
onKeyDown: (e) => { |
| 9430 |
if (e.key === "Enter") { |
| 9431 |
e.preventDefault(); |
| 9432 |
handleHighlightSave(); |
| 9433 |
} |
| 9434 |
} |
| 9435 |
} |
| 9436 |
), |
| 9437 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9438 |
HelpText, |
| 9439 |
{ |
| 9440 |
text: __$1( |
| 9441 |
'Keep it short and impactful. Examples: "All meals included", "Skip-the-line tickets", "Free airport transfer"', |
| 9442 |
"yatra" |
| 9443 |
), |
| 9444 |
className: "mt-2" |
| 9445 |
} |
| 9446 |
) |
| 9447 |
] }), |
| 9448 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-end gap-2", children: [ |
| 9449 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9450 |
Button, |
| 9451 |
{ |
| 9452 |
variant: "outline", |
| 9453 |
onClick: () => setShowHighlightModal(false), |
| 9454 |
children: __$1("Cancel", "yatra") |
| 9455 |
} |
| 9456 |
), |
| 9457 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9458 |
Button, |
| 9459 |
{ |
| 9460 |
onClick: handleHighlightSave, |
| 9461 |
disabled: !modalInput.text.trim(), |
| 9462 |
children: __$1("Add", "yatra") |
| 9463 |
} |
| 9464 |
) |
| 9465 |
] }) |
| 9466 |
] }) |
| 9467 |
] |
| 9468 |
} |
| 9469 |
) |
| 9470 |
} |
| 9471 |
), |
| 9472 |
showRevisionsDialog && /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9473 |
"div", |
| 9474 |
{ |
| 9475 |
className: "fixed inset-0 z-[9998] flex items-center justify-center bg-black/50 backdrop-blur-sm", |
| 9476 |
onClick: () => setShowRevisionsDialog(false), |
| 9477 |
children: /* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 9478 |
Card, |
| 9479 |
{ |
| 9480 |
className: "w-full max-w-2xl max-h-[80vh] mx-4 shadow-xl overflow-hidden flex flex-col", |
| 9481 |
onClick: (e) => e.stopPropagation(), |
| 9482 |
children: [ |
| 9483 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { className: "pb-3 flex-shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [ |
| 9484 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(CardTitle, { className: "text-lg flex items-center gap-2", children: [ |
| 9485 |
/* @__PURE__ */ jsxRuntimeExports.jsx(History, { className: "w-5 h-5" }), |
| 9486 |
__$1("Trip Revisions", "yatra") |
| 9487 |
] }), |
| 9488 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9489 |
"button", |
| 9490 |
{ |
| 9491 |
onClick: () => setShowRevisionsDialog(false), |
| 9492 |
className: "text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors", |
| 9493 |
"aria-label": __$1("Close", "yatra"), |
| 9494 |
children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-5 h-5" }) |
| 9495 |
} |
| 9496 |
) |
| 9497 |
] }) }), |
| 9498 |
/* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { className: "flex-1 overflow-y-auto pb-4", children: revisions.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-center py-8 text-gray-500 dark:text-gray-400", children: __$1("No revisions found", "yatra") }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2", children: revisions.map((revision) => /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9499 |
"div", |
| 9500 |
{ |
| 9501 |
className: "p-4 border border-gray-200 dark:border-gray-700 rounded-lg hover:bg-gray-50 dark:hover:bg-gray-800 cursor-pointer transition-colors", |
| 9502 |
onClick: () => handleRevisionClick(revision.id), |
| 9503 |
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [ |
| 9504 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [ |
| 9505 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-1", children: [ |
| 9506 |
/* @__PURE__ */ jsxRuntimeExports.jsxs(Badge, { variant: "outline", children: [ |
| 9507 |
"v", |
| 9508 |
revision.version |
| 9509 |
] }), |
| 9510 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm font-medium text-gray-900 dark:text-white", children: [ |
| 9511 |
__$1("Revision", "yatra"), |
| 9512 |
" ", |
| 9513 |
revision.version |
| 9514 |
] }) |
| 9515 |
] }), |
| 9516 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs text-gray-500 dark:text-gray-400", children: [ |
| 9517 |
__$1("Created by", "yatra"), |
| 9518 |
" ", |
| 9519 |
revision.created_by_name, |
| 9520 |
" •", |
| 9521 |
" ", |
| 9522 |
new Date(revision.created_at).toLocaleString() |
| 9523 |
] }) |
| 9524 |
] }), |
| 9525 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9526 |
Button, |
| 9527 |
{ |
| 9528 |
variant: "outline", |
| 9529 |
size: "sm", |
| 9530 |
onClick: (e) => { |
| 9531 |
e.stopPropagation(); |
| 9532 |
handleRevisionClick(revision.id); |
| 9533 |
}, |
| 9534 |
children: __$1("Use This Revision", "yatra") |
| 9535 |
} |
| 9536 |
) |
| 9537 |
] }) |
| 9538 |
}, |
| 9539 |
revision.id |
| 9540 |
)) }) }) |
| 9541 |
] |
| 9542 |
} |
| 9543 |
) |
| 9544 |
} |
| 9545 |
), |
| 9546 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9547 |
ConfirmationDialog, |
| 9548 |
{ |
| 9549 |
isOpen: showRevisionConfirm, |
| 9550 |
onClose: () => { |
| 9551 |
setShowRevisionConfirm(false); |
| 9552 |
setSelectedRevisionId(null); |
| 9553 |
}, |
| 9554 |
onConfirm: handleRevisionConfirm, |
| 9555 |
title: __$1("Use This Revision?", "yatra"), |
| 9556 |
message: __$1( |
| 9557 |
"Do you want to use this revision? This will replace all current form data with the revision data.", |
| 9558 |
"yatra" |
| 9559 |
), |
| 9560 |
confirmText: __$1("Yes, Use This Revision", "yatra"), |
| 9561 |
cancelText: __$1("Cancel", "yatra"), |
| 9562 |
variant: "info", |
| 9563 |
isLoading: false |
| 9564 |
} |
| 9565 |
), |
| 9566 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9567 |
Modal, |
| 9568 |
{ |
| 9569 |
isOpen: showLandmarkDialog, |
| 9570 |
onClose: () => { |
| 9571 |
setShowLandmarkDialog(false); |
| 9572 |
setLandmarkInput(""); |
| 9573 |
}, |
| 9574 |
title: __$1("Add Landmark", "yatra"), |
| 9575 |
description: __$1( |
| 9576 |
"Enter the name of the landmark or point of interest", |
| 9577 |
"yatra" |
| 9578 |
), |
| 9579 |
size: "sm", |
| 9580 |
hideFooter: false, |
| 9581 |
footer: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2 justify-end", children: [ |
| 9582 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9583 |
Button, |
| 9584 |
{ |
| 9585 |
variant: "outline", |
| 9586 |
onClick: () => { |
| 9587 |
setShowLandmarkDialog(false); |
| 9588 |
setLandmarkInput(""); |
| 9589 |
}, |
| 9590 |
children: __$1("Cancel", "yatra") |
| 9591 |
} |
| 9592 |
), |
| 9593 |
/* @__PURE__ */ jsxRuntimeExports.jsxs( |
| 9594 |
Button, |
| 9595 |
{ |
| 9596 |
onClick: () => { |
| 9597 |
if (landmarkInput.trim()) { |
| 9598 |
handleFieldChange("landmarks", [ |
| 9599 |
...formData.landmarks, |
| 9600 |
landmarkInput.trim() |
| 9601 |
]); |
| 9602 |
setLandmarkInput(""); |
| 9603 |
setShowLandmarkDialog(false); |
| 9604 |
} |
| 9605 |
}, |
| 9606 |
disabled: !landmarkInput.trim(), |
| 9607 |
children: [ |
| 9608 |
/* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4 mr-2" }), |
| 9609 |
__$1("Add Landmark", "yatra") |
| 9610 |
] |
| 9611 |
} |
| 9612 |
) |
| 9613 |
] }), |
| 9614 |
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [ |
| 9615 |
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [ |
| 9616 |
/* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: __$1("Landmark Name", "yatra") }), |
| 9617 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9618 |
Input, |
| 9619 |
{ |
| 9620 |
type: "text", |
| 9621 |
value: landmarkInput, |
| 9622 |
onChange: (e) => setLandmarkInput(e.target.value), |
| 9623 |
placeholder: __$1( |
| 9624 |
"e.g., Eiffel Tower, Central Park, Grand Canyon", |
| 9625 |
"yatra" |
| 9626 |
), |
| 9627 |
className: "w-full", |
| 9628 |
autoFocus: true, |
| 9629 |
onKeyDown: (e) => { |
| 9630 |
if (e.key === "Enter" && landmarkInput.trim()) { |
| 9631 |
handleFieldChange("landmarks", [ |
| 9632 |
...formData.landmarks, |
| 9633 |
landmarkInput.trim() |
| 9634 |
]); |
| 9635 |
setLandmarkInput(""); |
| 9636 |
setShowLandmarkDialog(false); |
| 9637 |
} |
| 9638 |
} |
| 9639 |
} |
| 9640 |
) |
| 9641 |
] }), |
| 9642 |
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-gray-500 dark:text-gray-400", children: __$1( |
| 9643 |
"Examples: Famous monuments, natural landmarks, historical sites, viewpoints, or points of interest that travelers will visit during this trip.", |
| 9644 |
"yatra" |
| 9645 |
) }) |
| 9646 |
] }) |
| 9647 |
} |
| 9648 |
), |
| 9649 |
/* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9650 |
AutoFillTripModal, |
| 9651 |
{ |
| 9652 |
open: aiModalOpen, |
| 9653 |
onClose: () => setAiModalOpen(false), |
| 9654 |
buildContext: () => buildTripAiContext(formData), |
| 9655 |
itineraryOnly: aiModalMode === "itinerary", |
| 9656 |
onFieldsAccepted: (updates) => { |
| 9657 |
for (const [key, value] of Object.entries(updates)) { |
| 9658 |
handleFieldChange(key, value); |
| 9659 |
} |
| 9660 |
} |
| 9661 |
} |
| 9662 |
), |
| 9663 |
isEditMode && tripId && /* @__PURE__ */ jsxRuntimeExports.jsx( |
| 9664 |
BuildItineraryModal, |
| 9665 |
{ |
| 9666 |
open: itineraryBuildOpen, |
| 9667 |
onClose: () => setItineraryBuildOpen(false), |
| 9668 |
tripId, |
| 9669 |
tripName: (formData == null ? void 0 : formData.title) || __$1("Trip", "yatra"), |
| 9670 |
tripDurationDays: Number(formData == null ? void 0 : formData.duration_days) || 0, |
| 9671 |
onApplied: () => { |
| 9672 |
setItineraryBuildOpen(false); |
| 9673 |
} |
| 9674 |
} |
| 9675 |
) |
| 9676 |
] }); |
| 9677 |
}; |
| 9678 |
export { |
| 9679 |
TripForm as default |
| 9680 |
}; |
| 9681 |
//# sourceMappingURL=TripForm-BXbs0ZCP.js.map |
| 9682 |
|