PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.17
Yatra – Travel Booking & Tour Operator Software v3.0.17
3.0.17 3.0.16 3.0.15 3.0.14 3.0.14.1 3.0.14.2 3.0.12 3.0.13 3.0.11 3.0.10 3.0.9 3.0.8 3.0.7 3.0.6 3.0.5 3.0.5.1 3.0.4 3.0.3 3.0.2.9 3.0.2.7 3.0.2.8 3.0.2.6 trunk 1.0.0 2.0.0 All 85 releases
yatra / assets / dist / js / TripForm-DEQpXvzy.js

TripForm-DEQpXvzy.js in Yatra – Travel Booking & Tour Operator Software 3.0.17, at assets/dist/js/TripForm-DEQpXvzy.js

9,690 lines 499.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { r as reactExports, j as jsxRuntimeExports, E as Loader2, S as Sparkles, aC as Wand2, bF as Pencil, bj as Scissors, bG as Maximize2, bi as Heart, ay as X, aB as Check, V as AlertTriangle, aA as AlertCircle, aR as Eye, aF as HelpCircle, O as RefreshCw, as as Clock, aE as CheckCircle2, u as useQuery, e as Tag, ax as Plus, bd as ChevronUp, y as ChevronDown, q as Calendar, X as ExternalLink, a6 as React, bH as CheckSquare, J as User, s as MapPin, n as Star, v as useQueryClient, k as FileText, at as DollarSign, bI as BookOpen, aT as Image, aX as Download, aP as Search, l as Settings, w as useMutation, aH as Copy, bJ as Lightbulb, b4 as Database, bK as History, aW as Save, bk as Send, aD as ChevronLeft, z as ChevronRight, bL as Box, m as BarChart3, aO as Trash2, bc as GripVertical, aS as Upload, U as Users, bM as Home, bN as Car } from "./react-vendor-CithbthY.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, n as MultiSelect, L as LocationPicker, R as RichTextEditor, o as prepareWordPressMediaFrameOpen, q 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-Dec_weLB.js";
4 import { d as detectClarification, B as BuildItineraryModal } from "./BuildItineraryModal-CzFq1WTm.js";
5 import { P as ProBadge, a as ProFeature } from "./ProFeature-DE6oH70S.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, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;");
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(/&amp;/g, "&").replace(/&lt;/g, "<").replace(/&gt;/g, ">").replace(/&quot;/g, '"').replace(/&#39;/g, "'").replace(/&nbsp;/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;
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 // 0 / null both mean "not hour-based" — show an empty field, not "0".
3294 duration_hours: tripData.duration_hours ? String(tripData.duration_hours) : "",
3295 available_from: tripData.available_from || "",
3296 available_to: tripData.available_to || "",
3297 booking_window_days: ((_h = tripData.booking_window_days) == null ? void 0 : _h.toString()) || "",
3298 seasonal_availability: tripData.seasonal_availability || "",
3299 best_season: tripData.best_season || "",
3300 peak_season: tripData.peak_season || "",
3301 off_season: tripData.off_season || "",
3302 activity_types: extractIds(tripData.activity_types || []),
3303 difficulty_level: ((_i = tripData.difficulty_level) == null ? void 0 : _i.toString()) || "",
3304 trip_category: extractIds(tripData.trip_category || []),
3305 tags: Array.isArray(tripData.tags) ? tripData.tags : [],
3306 featured_priority: tripData.featured_priority || "none",
3307 accommodation_type: tripData.accommodation_type || "",
3308 meal_plan: tripData.meal_plan || "",
3309 accommodation_details: tripData.accommodation_details || "",
3310 transportation_included: tripData.transportation_included || false,
3311 pickup_location: tripData.pickup_location || "",
3312 dropoff_location: tripData.dropoff_location || "",
3313 transportation_details: tripData.transportation_details || "",
3314 pricing_type: tripData.pricing_type || (tripData.price_types && Array.isArray(tripData.price_types) && tripData.price_types.length > 0 ? "traveler_based" : "regular"),
3315 original_price: ((_j = tripData.original_price) == null ? void 0 : _j.toString()) || "",
3316 discounted_price: ((_k = tripData.discounted_price) == null ? void 0 : _k.toString()) || "",
3317 price_types: Array.isArray(tripData.price_types) ? tripData.price_types.map((pt) => {
3318 var _a3, _b3;
3319 return {
3320 category_id: Number(pt.category_id) || 0,
3321 original_price: ((_a3 = pt.original_price) == null ? void 0 : _a3.toString()) || "",
3322 discounted_price: ((_b3 = pt.discounted_price) == null ? void 0 : _b3.toString()) || "",
3323 is_default: Boolean(pt.is_default)
3324 };
3325 }) : [],
3326 deposit_amount: ((_l = tripData.deposit_amount) == null ? void 0 : _l.toString()) || "",
3327 deposit_percentage: ((_m = tripData.deposit_percentage) == null ? void 0 : _m.toString()) || "",
3328 payment_terms: tripData.payment_terms || "",
3329 max_travelers: ((_n = tripData.max_travelers) == null ? void 0 : _n.toString()) || "",
3330 min_travelers: ((_o = tripData.min_travelers) == null ? void 0 : _o.toString()) || "",
3331 booking_deadline_hours: tripData.booking_deadline_hours || "",
3332 cancellation_policy: tripData.cancellation_policy || "",
3333 age_min: ((_p = tripData.age_min) == null ? void 0 : _p.toString()) || "",
3334 age_max: ((_q = tripData.age_max) == null ? void 0 : _q.toString()) || "",
3335 physical_requirements: tripData.physical_requirements || "",
3336 visa_requirements: tripData.visa_requirements || "",
3337 vaccination_requirements: tripData.vaccination_requirements || "",
3338 disable_booking: Boolean((_r = tripData.custom_fields) == null ? void 0 : _r.disable_booking),
3339 // tinyint(1) columns can serialize from PHP/wpdb as the string "0"/"1".
3340 // JS treats "0" as truthy, so a plain `value || false` would leave the
3341 // checkbox stuck on after the user un-checked + saved. Coerce explicitly.
3342 has_default_time_slots: tripData.has_default_time_slots === true || tripData.has_default_time_slots === 1 || tripData.has_default_time_slots === "1",
3343 default_time_slots: Array.isArray(tripData.default_time_slots) ? tripData.default_time_slots : tripData.default_time_slots ? JSON.parse(tripData.default_time_slots) : [],
3344 departure_time: tripData.departure_time || "09:00",
3345 included_items: normalizeAmenityItems(tripData.included_items),
3346 excluded_items: normalizeAmenityItems(tripData.excluded_items),
3347 // Preserve current itinerary data if it exists, otherwise use database data
3348 itinerary_days: shouldPreserveItinerary ? currentItineraryDays : normalizeItineraryDays(tripData.itinerary_days),
3349 // Preserve current gallery data if it exists, otherwise use database data
3350 gallery_images: shouldPreserveGallery ? currentGalleryImages : normalizeGalleryImages(tripData.gallery_images),
3351 featured_image: tripData.featured_image ? Number(tripData.featured_image) : null,
3352 downloadable_items: normalizeDownloadableItems(
3353 tripData.downloadable_items
3354 ),
3355 faqs: normalizeFaqs(tripData.faqs),
3356 frontend_tabs: Array.isArray(tripData.frontend_tabs) ? tripData.frontend_tabs : [
3357 // Core sections (always present) - in logical order
3358 {
3359 id: "overview",
3360 label: "Overview",
3361 enabled: true,
3362 order: 1,
3363 content_type: "overview",
3364 icon: { type: "icon", value: "book" }
3365 },
3366 {
3367 id: "itinerary",
3368 label: "Itinerary",
3369 enabled: true,
3370 order: 2,
3371 content_type: "itinerary",
3372 icon: { type: "icon", value: "calendar" }
3373 },
3374 {
3375 id: "included",
3376 label: "Included",
3377 enabled: true,
3378 order: 3,
3379 content_type: "included_excluded",
3380 icon: { type: "icon", value: "check" }
3381 },
3382 {
3383 id: "location",
3384 label: "Location",
3385 enabled: true,
3386 order: 4,
3387 content_type: "location",
3388 icon: { type: "icon", value: "map-pin" }
3389 },
3390 {
3391 id: "important_info",
3392 label: "Important Info",
3393 enabled: true,
3394 order: 5,
3395 content_type: "important_info",
3396 icon: { type: "icon", value: "info" }
3397 },
3398 // Conditional sections (enabled by default, shown conditionally on frontend)
3399 {
3400 id: "downloads",
3401 label: "Downloads",
3402 enabled: true,
3403 order: 6,
3404 content_type: "downloads",
3405 icon: { type: "icon", value: "download" }
3406 },
3407 {
3408 id: "faq",
3409 label: "FAQ",
3410 enabled: true,
3411 order: 7,
3412 content_type: "faq",
3413 icon: { type: "icon", value: "help-circle" }
3414 },
3415 {
3416 id: "trip_story",
3417 label: "Story",
3418 enabled: true,
3419 order: 8,
3420 content_type: "trip_story",
3421 custom_content: "",
3422 icon: { type: "icon", value: "book" }
3423 },
3424 {
3425 id: "what_makes_special",
3426 label: "Special",
3427 enabled: true,
3428 order: 9,
3429 content_type: "what_makes_special",
3430 custom_content: "",
3431 icon: { type: "icon", value: "star" }
3432 },
3433 {
3434 id: "testimonials",
3435 label: "Testimonials",
3436 enabled: true,
3437 order: 10,
3438 content_type: "testimonials",
3439 icon: { type: "icon", value: "message-circle" }
3440 }
3441 ],
3442 availability_dates: normalizeAvailabilityDates(
3443 tripData.availability_dates
3444 ),
3445 status: tripData.status || "draft",
3446 scheduled_publish_date: tripData.scheduled_publish_date || "",
3447 scheduled_unpublish_date: tripData.scheduled_unpublish_date || "",
3448 version: tripData.version || 1,
3449 seasonal_auto_enable: tripData.seasonal_auto_enable || false,
3450 seasonal_enable_date: tripData.seasonal_enable_date || "",
3451 seasonal_disable_date: tripData.seasonal_disable_date || "",
3452 meta_title: tripData.meta_title || "",
3453 meta_description: tripData.meta_description || "",
3454 meta_keywords: tripData.meta_keywords || "",
3455 attributes: tripAttributesData || {}
3456 });
3457 if (tripData.featured_image_url && tripData.featured_image) {
3458 const numericId = Number(tripData.featured_image) || 0;
3459 setFeaturedImagePreview(tripData.featured_image_url);
3460 if (numericId > 0) {
3461 featuredImageCache.current[numericId] = tripData.featured_image_url;
3462 }
3463 } else if (!tripData.featured_image) {
3464 setFeaturedImagePreview("");
3465 }
3466 }, [tripData, tripAttributesData, destinationsData, isEditMode, tripId]);
3467 reactExports.useEffect(() => {
3468 let isMounted = true;
3469 const resolveFeaturedImage = async () => {
3470 const attachmentId = formData.featured_image;
3471 if (!attachmentId) {
3472 setFeaturedImagePreview("");
3473 return;
3474 }
3475 const cachedUrl = featuredImageCache.current[attachmentId];
3476 if (cachedUrl) {
3477 setFeaturedImagePreview(cachedUrl);
3478 return;
3479 }
3480 if (!mediaBaseUrl) {
3481 setFeaturedImagePreview("");
3482 return;
3483 }
3484 setIsResolvingFeaturedImage(true);
3485 try {
3486 const data = await wpService.getMedia(attachmentId);
3487 const url = (data == null ? void 0 : data.source_url) || "";
3488 if (url && isMounted) {
3489 featuredImageCache.current[attachmentId] = url;
3490 setFeaturedImagePreview(url);
3491 } else if (isMounted) {
3492 setFeaturedImagePreview("");
3493 }
3494 } catch (error) {
3495 console.error("Failed to resolve featured image URL:", error);
3496 if (isMounted) {
3497 setFeaturedImagePreview("");
3498 }
3499 } finally {
3500 if (isMounted) {
3501 setIsResolvingFeaturedImage(false);
3502 }
3503 }
3504 };
3505 resolveFeaturedImage();
3506 return () => {
3507 isMounted = false;
3508 };
3509 }, [formData.featured_image, mediaBaseUrl]);
3510 const getSectionErrors = (sectionId) => {
3511 const errorMap = {
3512 basic: [
3513 "title",
3514 "slug",
3515 "description",
3516 "featured_image",
3517 "trip_type",
3518 "duration_days",
3519 "duration_nights",
3520 "duration_hours"
3521 ],
3522 location: ["destinations", "starting_location", "ending_location"],
3523 duration: ["available_from", "available_to", "booking_window_days"],
3524 pricing: ["original_price", "discounted_price", "price_types"],
3525 booking: ["min_travelers", "max_travelers", "age_min", "age_max"],
3526 attributes: ["attributes"],
3527 itinerary: ["itinerary_days"],
3528 included: ["included_items", "excluded_items"],
3529 media: ["gallery_images", "video_url", "virtual_tour_url"],
3530 // Removed featured_image - it's in basic section
3531 downloads: ["downloadable_items"],
3532 categorization: ["trip_category", "activity_types"],
3533 faqs: ["faqs"],
3534 seo: ["meta_title", "meta_description"],
3535 advanced: []
3536 };
3537 const sectionFields = errorMap[sectionId] || [];
3538 const fieldErrors = sectionFields.filter((field) => errors[field]);
3539 if (sectionId === "pricing") {
3540 const priceTypeErrors = Object.keys(errors).filter(
3541 (key) => key.startsWith("price_type_")
3542 );
3543 return [...fieldErrors, ...priceTypeErrors];
3544 }
3545 return fieldErrors;
3546 };
3547 const essentialsSections = [
3548 // 1. Trip Basics - What you're offering
3549 {
3550 id: "basic",
3551 label: __$1("Trip Basics", "yatra"),
3552 icon: FileText,
3553 required: true,
3554 completed: !!(((_a = formData.title) == null ? void 0 : _a.trim()) && ((_b = formData.slug) == null ? void 0 : _b.trim())),
3555 hasErrors: getSectionErrors("basic").length > 0
3556 },
3557 // 2. Location & Route - Where it happens
3558 {
3559 id: "location",
3560 label: __$1("Location & Route", "yatra"),
3561 icon: MapPin,
3562 required: false,
3563 completed: !!(formData.destinations.length > 0),
3564 hasErrors: getSectionErrors("location").length > 0
3565 },
3566 // 3. Pricing - How much it costs
3567 {
3568 id: "pricing",
3569 label: __$1("Pricing", "yatra"),
3570 icon: DollarSign,
3571 required: true,
3572 completed: formData.pricing_type === "regular" ? !!(formData.original_price && parseFloat(formData.original_price) > 0) : formData.price_types.some(
3573 (pt) => pt.original_price && parseFloat(pt.original_price) > 0
3574 ),
3575 hasErrors: getSectionErrors("pricing").length > 0
3576 },
3577 // 4. Availability & Booking - When available + booking rules (merged duration + booking)
3578 {
3579 id: "duration",
3580 label: __$1("Availability & Booking", "yatra"),
3581 icon: Calendar,
3582 required: false,
3583 completed: !!(formData.available_from || formData.available_to || formData.min_travelers && formData.max_travelers),
3584 hasErrors: getSectionErrors("duration").length > 0 || getSectionErrors("booking").length > 0
3585 }
3586 ];
3587 const detailsSections = [
3588 // 5. Trip Details - Description + Itinerary + Included/Excluded (merged 3 sections)
3589 {
3590 id: "itinerary",
3591 label: __$1("Trip Details", "yatra"),
3592 icon: BookOpen,
3593 required: false,
3594 completed: formData.itinerary_days.length > 0 || formData.included_items.length > 0 || formData.excluded_items.length > 0,
3595 hasErrors: getSectionErrors("itinerary").length > 0 || getSectionErrors("included").length > 0
3596 }
3597 ];
3598 const optimizationSections = [
3599 // 6. Media & Gallery - Photos, videos, testimonials
3600 {
3601 id: "media",
3602 label: __$1("Media & Gallery", "yatra"),
3603 icon: Image,
3604 required: false,
3605 completed: formData.gallery_images.length > 0 || !!formData.video_url,
3606 hasErrors: getSectionErrors("media").length > 0
3607 },
3608 ...[
3609 {
3610 id: "downloads",
3611 label: __$1("Downloads", "yatra"),
3612 icon: Download,
3613 required: false,
3614 completed: (formData.downloadable_items || []).length > 0,
3615 hasErrors: getSectionErrors("downloads").length > 0
3616 }
3617 ],
3618 // 7. Categories & Attributes - Classification + Custom Attributes (merged 2 sections)
3619 {
3620 id: "categorization",
3621 label: __$1("Categories & Attributes", "yatra"),
3622 icon: Tag,
3623 required: false,
3624 completed: !!(formData.trip_category || formData.activity_types.length > 0 || formData.tags.length > 0 || formData.attributes && Object.keys(formData.attributes).length > 0),
3625 hasErrors: getSectionErrors("categorization").length > 0 || getSectionErrors("attributes").length > 0
3626 },
3627 // 8. SEO & Marketing - SEO + FAQs (merged, fixed duplicate)
3628 {
3629 id: "seo",
3630 label: __$1("SEO & Marketing", "yatra"),
3631 icon: Search,
3632 required: false,
3633 completed: !!(formData.meta_title || formData.meta_description || formData.faqs.length > 0),
3634 hasErrors: getSectionErrors("seo").length > 0 || getSectionErrors("faqs").length > 0
3635 }
3636 ];
3637 const advancedSections = [
3638 // 9. Advanced Settings - Publishing, scheduling, technical
3639 {
3640 id: "advanced",
3641 label: __$1("Advanced Settings", "yatra"),
3642 icon: Settings,
3643 required: false,
3644 completed: false,
3645 hasErrors: false
3646 }
3647 ];
3648 const allSections = [
3649 ...essentialsSections,
3650 ...detailsSections,
3651 ...optimizationSections,
3652 ...advancedSections
3653 ];
3654 const currentStepIndex = allSections.findIndex(
3655 (s) => s.id === currentSection
3656 );
3657 const goToNextSection = () => {
3658 if (currentStepIndex < allSections.length - 1) {
3659 setCurrentSection(allSections[currentStepIndex + 1].id);
3660 }
3661 };
3662 const goToPreviousSection = () => {
3663 if (currentStepIndex > 0) {
3664 setCurrentSection(allSections[currentStepIndex - 1].id);
3665 }
3666 };
3667 reactExports.useEffect(() => {
3668 if (formData.duration_days && formData.trip_type === "multi_day" && (!formData.duration_nights || formData.duration_nights === "")) {
3669 const days = parseInt(formData.duration_days);
3670 if (days > 0 && !isNaN(days)) {
3671 setFormData((prev) => ({
3672 ...prev,
3673 duration_nights: String(Math.max(0, days - 1))
3674 }));
3675 }
3676 }
3677 }, [formData.duration_days, formData.trip_type]);
3678 reactExports.useEffect(() => {
3679 if (formData.duration_nights && formData.trip_type === "multi_day" && (!formData.duration_days || formData.duration_days === "")) {
3680 const nights = parseInt(formData.duration_nights);
3681 if (nights > 0 && !isNaN(nights)) {
3682 setFormData((prev) => ({ ...prev, duration_days: String(nights + 1) }));
3683 }
3684 }
3685 }, [formData.duration_nights, formData.trip_type]);
3686 const generateSlug = (title) => {
3687 return title.toLowerCase().trim().replace(/[^\w\s-]/g, "").replace(/[\s_-]+/g, "-").replace(/^-+|-+$/g, "");
3688 };
3689 const handleTitleChange = (value) => {
3690 setFormData((prev) => ({
3691 ...prev,
3692 title: value,
3693 slug: prev.slug || generateSlug(value)
3694 }));
3695 if (errors.title) {
3696 setErrors((prev) => ({ ...prev, title: "" }));
3697 }
3698 };
3699 const handleFieldChange = (field, value) => {
3700 setFormData((prev) => ({ ...prev, [field]: value }));
3701 if (errors[field]) {
3702 setErrors((prev) => ({ ...prev, [field]: "" }));
3703 }
3704 if (field === "featured_image") {
3705 if (value === null || value === "" || value === void 0) {
3706 setFeaturedImagePreview("");
3707 } else {
3708 const numericValue = typeof value === "number" ? value : Number(value);
3709 if (!numericValue) {
3710 setFeaturedImagePreview("");
3711 } else if (featuredImageCache.current[numericValue]) {
3712 setFeaturedImagePreview(featuredImageCache.current[numericValue]);
3713 }
3714 }
3715 }
3716 };
3717 const handleHighlightAdd = () => {
3718 setShowHighlightModal(true);
3719 setModalInput({ text: "", question: "", answer: "" });
3720 };
3721 const handleHighlightSave = () => {
3722 if (modalInput.text && modalInput.text.trim()) {
3723 setFormData((prev) => ({
3724 ...prev,
3725 highlights: [...prev.highlights, modalInput.text.trim()]
3726 }));
3727 setShowHighlightModal(false);
3728 setModalInput({ text: "", question: "", answer: "" });
3729 }
3730 };
3731 const handleHighlightRemove = (index) => {
3732 setFormData((prev) => ({
3733 ...prev,
3734 highlights: prev.highlights.filter((_, i) => i !== index)
3735 }));
3736 };
3737 const handleFAQAdd = () => {
3738 setFormData((prev) => ({
3739 ...prev,
3740 faqs: [...prev.faqs, { question: "", answer: "" }]
3741 }));
3742 };
3743 const handleFAQRemove = (index) => {
3744 setFormData((prev) => ({
3745 ...prev,
3746 faqs: prev.faqs.filter((_, i) => i !== index)
3747 }));
3748 };
3749 const handleFAQChange = (index, field, value) => {
3750 setFormData((prev) => ({
3751 ...prev,
3752 faqs: prev.faqs.map(
3753 (faq, i) => i === index ? { ...faq, [field]: value } : faq
3754 )
3755 }));
3756 };
3757 const handleGalleryAdd = () => {
3758 if (window.wp && window.wp.media) {
3759 const mediaUploader = window.wp.media({
3760 title: __$1("Select Gallery Images", "yatra"),
3761 button: { text: __$1("Add to Gallery", "yatra") },
3762 multiple: true,
3763 // Allow multiple image selection
3764 library: { type: "image" }
3765 });
3766 mediaUploader.on("select", () => {
3767 const selection = mediaUploader.state().get("selection");
3768 const newImages = [];
3769 selection.each((attachment) => {
3770 var _a2, _b2, _c2, _d2;
3771 const image = attachment.toJSON();
3772 if (image.url) {
3773 newImages.push({
3774 id: image.id || 0,
3775 url: image.url,
3776 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,
3777 alt_text: image.alt || "",
3778 caption: image.caption || ""
3779 });
3780 }
3781 });
3782 if (newImages.length > 0) {
3783 setFormData((prev) => ({
3784 ...prev,
3785 gallery_images: [...prev.gallery_images, ...newImages]
3786 }));
3787 }
3788 });
3789 prepareWordPressMediaFrameOpen();
3790 mediaUploader.open();
3791 } else {
3792 showToast(
3793 __$1(
3794 "Media library not available. Please ensure you are logged in as admin.",
3795 "yatra"
3796 ),
3797 "error"
3798 );
3799 }
3800 };
3801 const handleGalleryRemove = (index) => {
3802 setFormData((prev) => ({
3803 ...prev,
3804 gallery_images: prev.gallery_images.filter((_, i) => i !== index)
3805 }));
3806 };
3807 const handleGalleryReorder = (fromIndex, toIndex) => {
3808 setFormData((prev) => {
3809 const newImages = [...prev.gallery_images];
3810 const [movedImage] = newImages.splice(fromIndex, 1);
3811 newImages.splice(toIndex, 0, movedImage);
3812 return { ...prev, gallery_images: newImages };
3813 });
3814 };
3815 const handleDownloadableItemAdd = () => {
3816 setFormData((prev) => {
3817 var _a2;
3818 const nextOrder = (((_a2 = prev.downloadable_items) == null ? void 0 : _a2.length) || 0) + 1;
3819 return {
3820 ...prev,
3821 downloadable_items: [
3822 ...prev.downloadable_items || [],
3823 {
3824 id: null,
3825 title: "",
3826 description: "",
3827 attachment_id: null,
3828 attachment_url: "",
3829 attachment_title: "",
3830 visibility: "booked_only",
3831 enabled: true,
3832 sort_order: nextOrder
3833 }
3834 ]
3835 };
3836 });
3837 };
3838 const handleDownloadableItemRemove = (index) => {
3839 setFormData((prev) => ({
3840 ...prev,
3841 downloadable_items: (prev.downloadable_items || []).filter(
3842 (_, i) => i !== index
3843 )
3844 }));
3845 };
3846 const handleDownloadableItemMove = (fromIndex, toIndex) => {
3847 setFormData((prev) => {
3848 const items = [...prev.downloadable_items || []];
3849 const [moved] = items.splice(fromIndex, 1);
3850 items.splice(toIndex, 0, moved);
3851 const normalized = items.map((item, idx) => ({
3852 ...item,
3853 sort_order: idx + 1
3854 }));
3855 return { ...prev, downloadable_items: normalized };
3856 });
3857 };
3858 const handleDownloadableItemChange = (index, field, value) => {
3859 setFormData((prev) => ({
3860 ...prev,
3861 downloadable_items: (prev.downloadable_items || []).map(
3862 (item, i) => i === index ? { ...item, [field]: value } : item
3863 )
3864 }));
3865 };
3866 const handleDownloadableItemSelectFile = (index) => {
3867 if (window.wp && window.wp.media) {
3868 const mediaUploader = window.wp.media({
3869 title: __$1("Select File", "yatra"),
3870 button: { text: __$1("Use this file", "yatra") },
3871 multiple: false
3872 });
3873 mediaUploader.on("select", () => {
3874 const selection = mediaUploader.state().get("selection");
3875 const attachment = selection.first();
3876 if (!attachment) return;
3877 const file = attachment.toJSON();
3878 handleDownloadableItemChange(index, "attachment_id", file.id || null);
3879 handleDownloadableItemChange(index, "attachment_url", file.url || "");
3880 handleDownloadableItemChange(
3881 index,
3882 "attachment_title",
3883 file.title || file.filename || ""
3884 );
3885 });
3886 prepareWordPressMediaFrameOpen();
3887 mediaUploader.open();
3888 } else {
3889 showToast(
3890 __$1(
3891 "Media library not available. Please ensure you are logged in as admin.",
3892 "yatra"
3893 ),
3894 "error"
3895 );
3896 }
3897 };
3898 const handlePriceTypeAdd = (categoryId) => {
3899 if (formData.price_types.some(
3900 (pt) => Number(pt.category_id) === Number(categoryId)
3901 )) {
3902 showToast(
3903 __$1("This category already has pricing set", "yatra"),
3904 "warning"
3905 );
3906 return;
3907 }
3908 setFormData((prev) => ({
3909 ...prev,
3910 price_types: [
3911 ...prev.price_types,
3912 {
3913 category_id: categoryId,
3914 original_price: "",
3915 discounted_price: "",
3916 is_default: false
3917 }
3918 ]
3919 }));
3920 };
3921 const handlePriceTypeRemove = (categoryId) => {
3922 setFormData((prev) => ({
3923 ...prev,
3924 price_types: prev.price_types.filter(
3925 (pt) => Number(pt.category_id) !== Number(categoryId)
3926 )
3927 }));
3928 };
3929 const handlePriceTypeChange = (categoryId, field, value) => {
3930 setFormData((prev) => ({
3931 ...prev,
3932 price_types: prev.price_types.map(
3933 (pt) => Number(pt.category_id) === Number(categoryId) ? { ...pt, [field]: value } : pt
3934 )
3935 }));
3936 };
3937 const handlePriceTypeDefaultChange = (categoryId, isDefault) => {
3938 setFormData((prev) => ({
3939 ...prev,
3940 price_types: prev.price_types.map((pt) => {
3941 if (Number(pt.category_id) === Number(categoryId)) {
3942 return { ...pt, is_default: isDefault };
3943 }
3944 return isDefault ? { ...pt, is_default: false } : pt;
3945 })
3946 }));
3947 };
3948 const handleTabToggle = (tabId) => {
3949 setFormData((prev) => ({
3950 ...prev,
3951 frontend_tabs: prev.frontend_tabs.map(
3952 (tab) => tab.id === tabId ? { ...tab, enabled: !tab.enabled } : tab
3953 )
3954 }));
3955 };
3956 const handleFillDummyData = () => {
3957 const nextIndex = (dummyDataIndex + 1) % dummyTripsData.length;
3958 setDummyDataIndex(nextIndex);
3959 const dummyData = dummyTripsData[nextIndex];
3960 setFormData({
3961 ...dummyData,
3962 // Ensure arrays are properly set
3963 destinations: dummyData.destinations || [],
3964 activity_types: dummyData.activity_types || [],
3965 price_types: dummyData.price_types || [],
3966 included_items: dummyData.included_items || [],
3967 excluded_items: dummyData.excluded_items || [],
3968 highlights: dummyData.highlights || [],
3969 faqs: dummyData.faqs || [],
3970 gallery_images: dummyData.gallery_images || [],
3971 itinerary_days: dummyData.itinerary_days || [],
3972 tags: dummyData.tags || [],
3973 testimonial_review_ids: dummyData.testimonial_review_ids || [],
3974 countries: dummyData.countries || [],
3975 regions: dummyData.regions || [],
3976 landmarks: dummyData.landmarks || [],
3977 availability_dates: dummyData.availability_dates || [],
3978 frontend_tabs: dummyData.frontend_tabs || [],
3979 has_default_time_slots: dummyData.has_default_time_slots || false,
3980 default_time_slots: dummyData.default_time_slots || [],
3981 departure_time: dummyData.departure_time || "09:00",
3982 downloadable_items: dummyData.downloadable_items || []
3983 });
3984 showToast(
3985 __$1("Dummy data filled", "yatra") + ` (${nextIndex + 1}/${dummyTripsData.length})`,
3986 "success"
3987 );
3988 };
3989 const handleTabLabelChange = (tabId, label) => {
3990 setFormData((prev) => ({
3991 ...prev,
3992 frontend_tabs: prev.frontend_tabs.map(
3993 (tab) => tab.id === tabId ? { ...tab, label } : tab
3994 )
3995 }));
3996 };
3997 const handleTabMove = (tabId, direction) => {
3998 setFormData((prev) => {
3999 const tabs = [...prev.frontend_tabs];
4000 const index = tabs.findIndex((t) => t.id === tabId);
4001 if (index === -1) return prev;
4002 const newIndex = direction === "up" ? index - 1 : index + 1;
4003 if (newIndex < 0 || newIndex >= tabs.length) return prev;
4004 [tabs[index], tabs[newIndex]] = [tabs[newIndex], tabs[index]];
4005 tabs.forEach((tab, i) => {
4006 tab.order = i + 1;
4007 });
4008 return { ...prev, frontend_tabs: tabs };
4009 });
4010 };
4011 const handleTabRemove = (tabId) => {
4012 setFormData((prev) => ({
4013 ...prev,
4014 frontend_tabs: prev.frontend_tabs.filter((tab) => tab.id !== tabId).map((tab, i) => ({ ...tab, order: i + 1 }))
4015 }));
4016 };
4017 const handleTabAdd = () => {
4018 const newTabId = `custom_${Date.now()}`;
4019 const maxOrder = Math.max(...formData.frontend_tabs.map((t) => t.order), 0);
4020 setFormData((prev) => ({
4021 ...prev,
4022 frontend_tabs: [
4023 ...prev.frontend_tabs,
4024 {
4025 id: newTabId,
4026 label: __$1("New Tab", "yatra"),
4027 enabled: true,
4028 order: maxOrder + 1,
4029 content_type: "custom",
4030 custom_content: ""
4031 }
4032 ]
4033 }));
4034 };
4035 const handleTabContentTypeChange = (tabId, contentType) => {
4036 setFormData((prev) => ({
4037 ...prev,
4038 frontend_tabs: prev.frontend_tabs.map(
4039 (tab) => tab.id === tabId ? { ...tab, content_type: contentType } : tab
4040 )
4041 }));
4042 };
4043 const handleTabCustomContentChange = (tabId, content) => {
4044 setFormData((prev) => ({
4045 ...prev,
4046 frontend_tabs: prev.frontend_tabs.map(
4047 (tab) => tab.id === tabId ? { ...tab, custom_content: content } : tab
4048 )
4049 }));
4050 };
4051 const handleTabIconChange = (tabId, icon) => {
4052 setFormData((prev) => ({
4053 ...prev,
4054 frontend_tabs: prev.frontend_tabs.map(
4055 (tab) => tab.id === tabId ? { ...tab, icon } : tab
4056 )
4057 }));
4058 };
4059 const [draggedTab, setDraggedTab] = reactExports.useState(null);
4060 const [dragOverTab, setDragOverTab] = reactExports.useState(null);
4061 const handleDragStart = (e, tabId) => {
4062 setDraggedTab(tabId);
4063 e.dataTransfer.effectAllowed = "move";
4064 };
4065 const handleDragOver = (e) => {
4066 e.preventDefault();
4067 e.dataTransfer.dropEffect = "move";
4068 };
4069 const handleDragEnter = (tabId) => {
4070 setDragOverTab(tabId);
4071 };
4072 const handleDragLeave = () => {
4073 setDragOverTab(null);
4074 };
4075 const handleDrop = (e, targetTabId) => {
4076 e.preventDefault();
4077 setDragOverTab(null);
4078 if (!draggedTab || draggedTab === targetTabId) {
4079 setDraggedTab(null);
4080 return;
4081 }
4082 setFormData((prev) => {
4083 const tabs = [...prev.frontend_tabs];
4084 const draggedIndex = tabs.findIndex((t) => t.id === draggedTab);
4085 const targetIndex = tabs.findIndex((t) => t.id === targetTabId);
4086 if (draggedIndex === -1 || targetIndex === -1) {
4087 return prev;
4088 }
4089 const [draggedTabObj] = tabs.splice(draggedIndex, 1);
4090 tabs.splice(targetIndex, 0, draggedTabObj);
4091 tabs.forEach((tab, i) => {
4092 tab.order = i + 1;
4093 });
4094 return { ...prev, frontend_tabs: tabs };
4095 });
4096 setDraggedTab(null);
4097 };
4098 const handleDragEnd = () => {
4099 setDraggedTab(null);
4100 setDragOverTab(null);
4101 };
4102 const buildEssentialFieldErrors = () => {
4103 const newErrors = {};
4104 if (!formData.title.trim()) {
4105 newErrors.title = __$1("Title is required", "yatra");
4106 }
4107 if (!formData.slug.trim()) {
4108 newErrors.slug = __$1("Slug is required", "yatra");
4109 } else if (!/^[\p{L}\p{N}-]+$/u.test(formData.slug)) {
4110 newErrors.slug = __$1(
4111 "Slug can only contain letters, numbers, and hyphens",
4112 "yatra"
4113 );
4114 }
4115 return newErrors;
4116 };
4117 const validateForm = () => {
4118 const newErrors = buildEssentialFieldErrors();
4119 setErrors(newErrors);
4120 return Object.keys(newErrors).length === 0;
4121 };
4122 const saveMutation = useMutation({
4123 mutationFn: async (data) => {
4124 const payload = {
4125 title: data.title.trim(),
4126 slug: data.slug.trim(),
4127 description: data.description.trim(),
4128 short_description: data.short_description.trim(),
4129 highlights: data.highlights,
4130 trip_details: data.trip_details.trim(),
4131 what_makes_special: data.what_makes_special.trim(),
4132 trip_story: data.trip_story.trim(),
4133 video_url: data.video_url.trim(),
4134 virtual_tour_url: data.virtual_tour_url.trim(),
4135 testimonial_review_ids: Array.isArray(data.testimonial_review_ids) ? data.testimonial_review_ids.filter(
4136 (id) => id !== null && id !== void 0 && id > 0
4137 ) : [],
4138 destinations: data.destinations || [],
4139 // Array of destination IDs
4140 starting_location: data.starting_location.trim(),
4141 ending_location: data.ending_location.trim(),
4142 countries: data.countries || [],
4143 regions: data.regions || [],
4144 starting_latitude: data.starting_latitude ? parseFloat(data.starting_latitude) : null,
4145 starting_longitude: data.starting_longitude ? parseFloat(data.starting_longitude) : null,
4146 ending_latitude: data.ending_latitude ? parseFloat(data.ending_latitude) : null,
4147 ending_longitude: data.ending_longitude ? parseFloat(data.ending_longitude) : null,
4148 landmarks: data.landmarks || [],
4149 trip_type: data.trip_type,
4150 duration_days: data.duration_days ? parseInt(data.duration_days) : null,
4151 duration_nights: data.duration_nights ? parseInt(data.duration_nights) : null,
4152 // Hour-based day tours. This key was missing from the payload, so the
4153 // Duration (Hours) field could never be saved: the form kept the value,
4154 // the request dropped it, and the field reloaded empty. Send 0 (never
4155 // null) when the field is blank — the validator treats null as "not
4156 // provided" and would leave a stale hours value on a trip switched
4157 // back to multi-day, which the storefront would then show as hours.
4158 duration_hours: data.duration_hours !== "" && data.duration_hours != null && !isNaN(parseInt(data.duration_hours)) ? parseInt(data.duration_hours) : 0,
4159 available_from: data.available_from || null,
4160 available_to: data.available_to || null,
4161 booking_window_days: data.booking_window_days ? parseInt(data.booking_window_days) : null,
4162 seasonal_availability: data.seasonal_availability || "",
4163 best_season: data.best_season.trim(),
4164 peak_season: data.peak_season.trim(),
4165 off_season: data.off_season.trim(),
4166 activity_types: data.activity_types || [],
4167 // Array of activity IDs
4168 difficulty_level: parseInt(data.difficulty_level) || null,
4169 trip_category: (() => {
4170 const rawCategories = data.trip_category || [];
4171 if (tripCategories.length === 0) {
4172 return rawCategories;
4173 }
4174 const validCategories = rawCategories.filter((_catId) => {
4175 return true;
4176 });
4177 return validCategories;
4178 })(),
4179 tags: data.tags || [],
4180 accommodation_type: data.accommodation_type || "",
4181 meal_plan: data.meal_plan || "",
4182 accommodation_details: data.accommodation_details.trim(),
4183 transportation_included: data.transportation_included || false,
4184 pickup_location: data.pickup_location.trim(),
4185 dropoff_location: data.dropoff_location.trim(),
4186 transportation_details: data.transportation_details.trim(),
4187 pricing_type: data.pricing_type,
4188 original_price: data.pricing_type === "regular" ? data.original_price ? parseFloat(data.original_price) : null : null,
4189 discounted_price: data.pricing_type === "regular" ? data.discounted_price ? parseFloat(data.discounted_price) : null : null,
4190 price_types: data.pricing_type === "traveler_based" ? data.price_types.map((pt) => ({
4191 category_id: pt.category_id,
4192 is_default: Boolean(pt.is_default),
4193 original_price: pt.original_price ? parseFloat(pt.original_price) : null,
4194 discounted_price: pt.discounted_price ? parseFloat(pt.discounted_price) : null
4195 })) : [],
4196 deposit_amount: data.deposit_amount ? parseFloat(data.deposit_amount) : null,
4197 deposit_percentage: data.deposit_percentage ? parseFloat(data.deposit_percentage) : null,
4198 payment_terms: data.payment_terms.trim(),
4199 max_travelers: data.max_travelers ? parseInt(data.max_travelers) : null,
4200 min_travelers: data.min_travelers ? parseInt(data.min_travelers) : null,
4201 booking_deadline_hours: data.booking_deadline_hours || null,
4202 cancellation_policy: data.cancellation_policy || "",
4203 custom_fields: { disable_booking: data.disable_booking },
4204 age_min: data.age_min ? parseInt(data.age_min) : null,
4205 age_max: data.age_max ? parseInt(data.age_max) : null,
4206 physical_requirements: data.physical_requirements.trim(),
4207 visa_requirements: data.visa_requirements.trim(),
4208 vaccination_requirements: data.vaccination_requirements.trim(),
4209 has_default_time_slots: data.has_default_time_slots || false,
4210 default_time_slots: JSON.stringify(data.default_time_slots || []),
4211 departure_time: data.departure_time || "09:00",
4212 included_items: (data.included_items || []).map((item) => {
4213 var _a2, _b2;
4214 return {
4215 title: ((_a2 = item.title) == null ? void 0 : _a2.trim()) || "",
4216 description: ((_b2 = item.description) == null ? void 0 : _b2.trim()) || ""
4217 };
4218 }).filter((item) => item.title),
4219 excluded_items: (data.excluded_items || []).map((item) => {
4220 var _a2, _b2;
4221 return {
4222 title: ((_a2 = item.title) == null ? void 0 : _a2.trim()) || "",
4223 description: ((_b2 = item.description) == null ? void 0 : _b2.trim()) || ""
4224 };
4225 }).filter((item) => item.title),
4226 itinerary_days: data.itinerary_days || [],
4227 gallery_images: data.gallery_images || [],
4228 featured_image: data.featured_image ?? null,
4229 faqs: data.faqs || [],
4230 frontend_tabs: data.frontend_tabs.map((tab) => ({
4231 id: tab.id,
4232 label: tab.label,
4233 enabled: tab.enabled,
4234 order: tab.order,
4235 content_type: tab.content_type,
4236 custom_content: tab.custom_content || null,
4237 icon: tab.icon || null
4238 })),
4239 availability_dates: data.availability_dates.map((avail) => ({
4240 id: avail.id,
4241 departure_date: avail.departure_date || null,
4242 arrival_date: avail.arrival_date || null,
4243 seats_remaining: avail.seats_remaining || null,
4244 original_price: avail.original_price ? parseFloat(avail.original_price) : null,
4245 discounted_price: avail.discounted_price ? parseFloat(avail.discounted_price) : null,
4246 discount_percentage: avail.discount_percentage ? parseFloat(avail.discount_percentage) : null,
4247 status: avail.status || "available",
4248 from_location: avail.from_location || null,
4249 to_location: avail.to_location || null,
4250 from_latitude: avail.from_latitude || null,
4251 from_longitude: avail.from_longitude || null,
4252 to_latitude: avail.to_latitude || null,
4253 to_longitude: avail.to_longitude || null
4254 })),
4255 status: data.status === "publish" ? "publish" : "draft",
4256 scheduled_publish_date: data.scheduled_publish_date || null,
4257 scheduled_unpublish_date: data.scheduled_unpublish_date || null,
4258 version: data.version || 1,
4259 seasonal_auto_enable: data.seasonal_auto_enable || false,
4260 seasonal_enable_date: data.seasonal_enable_date || null,
4261 seasonal_disable_date: data.seasonal_disable_date || null,
4262 meta_title: data.meta_title || "",
4263 meta_description: data.meta_description || "",
4264 meta_keywords: data.meta_keywords || "",
4265 attributes: data.attributes || {},
4266 featured_priority: data.featured_priority
4267 };
4268 {
4269 payload.downloadable_items = (data.downloadable_items || []).map((item, idx) => ({
4270 id: item.id ?? null,
4271 title: (item.title || "").trim(),
4272 description: item.description || "",
4273 attachment_id: item.attachment_id ?? null,
4274 visibility: item.visibility || "booked_only",
4275 enabled: item.enabled !== false,
4276 sort_order: item.sort_order != null ? item.sort_order : idx + 1,
4277 attachment_url: item.attachment_url || "",
4278 attachment_title: item.attachment_title || "",
4279 // Prefixed keys (requested)
4280 download_title: (item.title || "").trim(),
4281 download_description: item.description || "",
4282 download_visibility: item.visibility || "booked_only",
4283 download_enabled: item.enabled !== false,
4284 download_file: item.attachment_id ?? null
4285 })).filter((item) => item.title);
4286 }
4287 if (isEditMode && tripId) {
4288 const response = await apiClient.put(`/trips/${tripId}`, payload);
4289 return response.data || response;
4290 } else {
4291 const response = await apiClient.post("/trips", payload);
4292 return response.data || response;
4293 }
4294 },
4295 onSuccess: (data, variables) => {
4296 queryClient.invalidateQueries({ queryKey: ["trips"] });
4297 queryClient.invalidateQueries({ queryKey: ["trip", tripId] });
4298 queryClient.refetchQueries({ queryKey: ["trip", tripId] });
4299 setIsSubmitting(false);
4300 let successMessage;
4301 if (isEditMode) {
4302 successMessage = variables.status === "publish" ? __$1("Trip updated and published successfully", "yatra") : __$1("Trip updated successfully", "yatra");
4303 } else {
4304 successMessage = variables.status === "publish" ? __$1("Trip created and published successfully", "yatra") : __$1("Trip saved as draft successfully", "yatra");
4305 }
4306 showToast(successMessage, "success");
4307 if (!isEditMode && (data == null ? void 0 : data.id)) {
4308 setTimeout(() => {
4309 var _a2;
4310 window.location.href = `${((_a2 = window.yatraAdmin) == null ? void 0 : _a2.siteUrl) || ""}/wp-admin/admin.php?page=yatra&subpage=trips&action=edit&id=${data.id}`;
4311 }, 1e3);
4312 }
4313 },
4314 onError: (error) => {
4315 var _a2, _b2;
4316 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");
4317 showToast(errorMessage, "error");
4318 setErrors({ submit: errorMessage });
4319 setIsSubmitting(false);
4320 }
4321 });
4322 const validateDraft = () => {
4323 const newErrors = buildEssentialFieldErrors();
4324 setErrors(newErrors);
4325 return Object.keys(newErrors).length === 0;
4326 };
4327 const handleSaveDraft = async () => {
4328 if (!validateDraft()) {
4329 showToast(
4330 __$1("Please add a trip title and URL before saving.", "yatra"),
4331 "error"
4332 );
4333 return;
4334 }
4335 setIsSubmitting(true);
4336 saveMutation.mutate({ ...formData, status: "draft" });
4337 };
4338 const handlePublish = async () => {
4339 if (!validateForm()) {
4340 const firstError = Object.keys(errors)[0];
4341 if (firstError) {
4342 showToast(
4343 __$1("Trip title and slug are required before publishing.", "yatra"),
4344 "error"
4345 );
4346 const errorElement = document.querySelector(
4347 `[name="${firstError}"], #${firstError}`
4348 );
4349 if (errorElement) {
4350 errorElement.scrollIntoView({ behavior: "smooth", block: "center" });
4351 }
4352 }
4353 return;
4354 }
4355 setIsSubmitting(true);
4356 saveMutation.mutate({ ...formData, status: "publish" });
4357 };
4358 reactExports.useEffect(() => {
4359 const onKeyDown = (e) => {
4360 if (e.key !== "Enter" || e.shiftKey || e.ctrlKey || e.metaKey || e.altKey)
4361 return;
4362 const target = e.target;
4363 if (!target) return;
4364 const tag = target.tagName.toLowerCase();
4365 const isTextarea = tag === "textarea";
4366 const isButton = tag === "button";
4367 const isLink = tag === "a";
4368 const isContentEditable = target.getAttribute("contenteditable") === "true";
4369 if (isTextarea || isButton || isLink || isContentEditable) return;
4370 const inputType = target.type;
4371 if (["submit", "button", "file"].includes(inputType)) return;
4372 e.preventDefault();
4373 if (!isSubmitting) {
4374 handlePublish();
4375 }
4376 };
4377 window.addEventListener("keydown", onKeyDown);
4378 return () => window.removeEventListener("keydown", onKeyDown);
4379 }, [isSubmitting, handlePublish]);
4380 const revisions = dummyRevisions;
4381 const handlePreview = async () => {
4382 var _a2;
4383 const slug = (formData.slug || "").trim();
4384 if (!slug) {
4385 showToast(
4386 __$1(
4387 "Trip slug is missing. Please add a slug before previewing.",
4388 "yatra"
4389 ),
4390 "error"
4391 );
4392 return;
4393 }
4394 const siteUrl = ((_a2 = window == null ? void 0 : window.yatraAdmin) == null ? void 0 : _a2.siteUrl) || "";
4395 const { plainUrl, prettyUrl } = buildYatraSinglePublicUrls({
4396 entity: "trip",
4397 slug,
4398 siteUrl,
4399 bases: settingsData
4400 });
4401 if (isWordPressPlainPermalink()) {
4402 window.open(plainUrl, "_blank", "noopener,noreferrer");
4403 return;
4404 }
4405 let apiPermalink = (tripData == null ? void 0 : tripData.permalink) || (tripData == null ? void 0 : tripData.url);
4406 if (!apiPermalink && tripId) {
4407 try {
4408 const detail = await apiClient.get(`/trips/${tripId}`);
4409 apiPermalink = (detail == null ? void 0 : detail.permalink) || (detail == null ? void 0 : detail.url) || apiPermalink;
4410 } catch (error) {
4411 }
4412 }
4413 if (apiPermalink) {
4414 window.open(apiPermalink, "_blank", "noopener,noreferrer");
4415 return;
4416 }
4417 window.open(prettyUrl, "_blank", "noopener,noreferrer");
4418 };
4419 const handleRevisionClick = (revisionId) => {
4420 setSelectedRevisionId(revisionId);
4421 setShowRevisionConfirm(true);
4422 };
4423 const handleRevisionConfirm = () => {
4424 if (selectedRevisionId) {
4425 showToast(__$1("Revision feature is coming soon", "yatra"), "info");
4426 }
4427 setShowRevisionConfirm(false);
4428 setShowRevisionsDialog(false);
4429 setSelectedRevisionId(null);
4430 };
4431 if (isEditMode && isLoadingTrip) {
4432 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-h-0 flex flex-col bg-white dark:bg-gray-900 overflow-hidden", children: [
4433 /* @__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: [
4434 /* @__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: [
4435 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-6 w-64 bg-gray-200 dark:bg-gray-700 rounded animate-pulse mb-2" }),
4436 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
4437 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-5 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }),
4438 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-6 w-28 bg-gray-200 dark:bg-gray-700 rounded-full animate-pulse" })
4439 ] })
4440 ] }) }),
4441 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
4442 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-9 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }),
4443 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-9 w-24 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }),
4444 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-9 w-32 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }),
4445 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-9 w-36 bg-blue-200 dark:bg-blue-800 rounded animate-pulse" })
4446 ] })
4447 ] }),
4448 /* @__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: [
4449 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-9 w-24 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }),
4450 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 flex flex-col items-center gap-1 max-w-md mx-4", children: [
4451 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-3 w-24 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }),
4452 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-full h-1.5 bg-gray-200 dark:bg-gray-700 rounded-full animate-pulse" }),
4453 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-2.5 w-32 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" })
4454 ] }),
4455 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-9 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" })
4456 ] }) }),
4457 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 flex overflow-hidden", children: [
4458 /* @__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: [
4459 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
4460 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-3.5 w-24 bg-gray-200 dark:bg-gray-700 rounded animate-pulse mb-3 px-1" }),
4461 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-0.5", children: [...Array(8)].map((_, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
4462 "div",
4463 {
4464 className: "flex items-center gap-2 px-3 py-2.5 rounded-md",
4465 children: [
4466 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-4 h-4 bg-gray-200 dark:bg-gray-700 rounded animate-pulse flex-shrink-0" }),
4467 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 flex-1 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" })
4468 ]
4469 },
4470 `essentials-${i}`
4471 )) })
4472 ] }),
4473 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
4474 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-3.5 w-28 bg-gray-200 dark:bg-gray-700 rounded animate-pulse mb-3 px-1" }),
4475 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-0.5", children: [...Array(9)].map((_, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
4476 "div",
4477 {
4478 className: "flex items-center gap-2 px-3 py-2.5 rounded-md",
4479 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 flex-1 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" })
4482 ]
4483 },
4484 `marketing-${i}`
4485 )) })
4486 ] }),
4487 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 px-3 py-2.5 rounded-md", children: [
4488 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-4 h-4 bg-gray-200 dark:bg-gray-700 rounded animate-pulse flex-shrink-0" }),
4489 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" })
4490 ] }) })
4491 ] }) }),
4492 /* @__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: [
4493 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-4", children: [
4494 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-5 h-5 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }),
4495 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-6 w-56 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" })
4496 ] }),
4497 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 w-96 bg-gray-200 dark:bg-gray-700 rounded animate-pulse mb-6" }),
4498 /* @__PURE__ */ jsxRuntimeExports.jsx(Card, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "p-6 space-y-6", children: [
4499 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
4500 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-3.5 w-12 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }),
4501 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 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-10 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }),
4505 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 w-full bg-gray-200 dark:bg-gray-700 rounded animate-pulse" })
4506 ] }),
4507 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
4508 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-3.5 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }),
4509 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-32 w-full bg-gray-200 dark:bg-gray-700 rounded animate-pulse" })
4510 ] }),
4511 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
4512 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-3.5 w-28 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }),
4513 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-48 w-full bg-gray-200 dark:bg-gray-700 rounded-lg animate-pulse" })
4514 ] }),
4515 /* @__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: [
4516 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-3.5 w-24 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }),
4517 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 w-full bg-gray-200 dark:bg-gray-700 rounded animate-pulse" })
4518 ] }, `grid-${i}`)) })
4519 ] }) })
4520 ] }) })
4521 ] })
4522 ] });
4523 }
4524 if (isEditMode && tripError) {
4525 const requestInfo = tripErrorContext.requestInfo || (tripError == null ? void 0 : tripError.config) || {};
4526 const method = ((_d = (_c = requestInfo.method || "GET").toUpperCase) == null ? void 0 : _d.call(_c)) || "GET";
4527 const url = requestInfo.url || ((_e = tripError == null ? void 0 : tripError.config) == null ? void 0 : _e.url) || "";
4528 const payload = requestInfo.payload || ((_f = tripError == null ? void 0 : tripError.config) == null ? void 0 : _f.data) || "";
4529 const composedErrorText = `Method: ${method}
4530 URL: ${url}
4531 Payload: ${payload || "N/A"}
4532
4533 ${tripErrorContext.details || ""}`;
4534 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: [
4535 /* @__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(
4536 "svg",
4537 {
4538 className: "w-10 h-10 text-red-500",
4539 fill: "none",
4540 stroke: "currentColor",
4541 viewBox: "0 0 24 24",
4542 strokeWidth: "1.8",
4543 children: /* @__PURE__ */ jsxRuntimeExports.jsx(
4544 "path",
4545 {
4546 strokeLinecap: "round",
4547 strokeLinejoin: "round",
4548 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"
4549 }
4550 )
4551 }
4552 ) }),
4553 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-1", children: [
4554 /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-2xl font-semibold text-gray-900", children: __$1("Error Loading Trips", "yatra") }),
4555 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600", children: __$1(
4556 "We couldn’t connect to the trips service. Please refresh or try again shortly.",
4557 "yatra"
4558 ) })
4559 ] }),
4560 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap gap-2 justify-center", children: [
4561 /* @__PURE__ */ jsxRuntimeExports.jsx(
4562 Button,
4563 {
4564 onClick: () => queryClient.invalidateQueries({ queryKey: ["trip", tripId] }),
4565 children: __$1("Try again", "yatra")
4566 }
4567 ),
4568 /* @__PURE__ */ jsxRuntimeExports.jsx(
4569 Button,
4570 {
4571 variant: "outline",
4572 onClick: () => {
4573 if (typeof window !== "undefined") {
4574 window.open(
4575 "https://wordpress.org/support/plugin/yatra",
4576 "_blank"
4577 );
4578 }
4579 },
4580 children: __$1("Visit support center", "yatra")
4581 }
4582 )
4583 ] }),
4584 /* @__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: [
4585 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between px-5 py-3 border-b border-gray-200", children: [
4586 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium text-gray-800", children: __$1("Technical details", "yatra") }),
4587 /* @__PURE__ */ jsxRuntimeExports.jsx(
4588 Button,
4589 {
4590 type: "button",
4591 size: "sm",
4592 variant: "ghost",
4593 className: "flex items-center gap-2 text-gray-600 hover:text-gray-900",
4594 onClick: () => copyErrorDetailsToClipboard(composedErrorText),
4595 children: copiedErrorDetails ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
4596 /* @__PURE__ */ jsxRuntimeExports.jsx(Check, { className: "w-4 h-4" }),
4597 __$1("Copied", "yatra")
4598 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
4599 /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "w-4 h-4" }),
4600 __$1("Copy details", "yatra")
4601 ] })
4602 }
4603 )
4604 ] }),
4605 /* @__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: [
4606 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
4607 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: __$1("Method:", "yatra") }),
4608 " ",
4609 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: method })
4610 ] }),
4611 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "break-all", children: [
4612 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium", children: __$1("URL:", "yatra") }),
4613 " ",
4614 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-mono", children: url || __$1("N/A", "yatra") })
4615 ] }),
4616 payload && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
4617 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium block mb-1", children: __$1("Payload:", "yatra") }),
4618 /* @__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 })
4619 ] })
4620 ] }),
4621 /* @__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(
4622 {
4623 message: tripError instanceof Error ? tripError.message : __$1("Failed to load trip data", "yatra"),
4624 method,
4625 url,
4626 payload
4627 },
4628 null,
4629 2
4630 ) })
4631 ] }) })
4632 ] }) }) });
4633 }
4634 const renderSectionContent = () => {
4635 var _a2;
4636 switch (currentSection) {
4637 case "basic":
4638 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
4639 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-3", children: [
4640 /* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { className: "w-5 h-5 text-blue-600 dark:text-blue-400" }),
4641 /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: __$1("Basic Information", "yatra") }),
4642 /* @__PURE__ */ jsxRuntimeExports.jsx(
4643 Badge,
4644 {
4645 variant: "outline",
4646 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",
4647 children: __$1("Start Here", "yatra")
4648 }
4649 )
4650 ] }),
4651 /* @__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: [
4652 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-blue-900 dark:text-blue-100 font-medium mb-1", children: __$1("💡 Getting Started", "yatra") }),
4653 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-blue-800 dark:text-blue-200", children: __$1(
4654 "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.",
4655 "yatra"
4656 ) })
4657 ] }),
4658 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
4659 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-4", children: [
4660 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-1.5", children: [
4661 /* @__PURE__ */ jsxRuntimeExports.jsxs(
4662 "label",
4663 {
4664 htmlFor: "title",
4665 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 flex items-center gap-1.5",
4666 children: [
4667 __$1("Trip Title", "yatra"),
4668 /* @__PURE__ */ jsxRuntimeExports.jsx(
4669 Badge,
4670 {
4671 variant: "outline",
4672 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",
4673 children: __$1("Required", "yatra")
4674 }
4675 ),
4676 /* @__PURE__ */ jsxRuntimeExports.jsx(
4677 "button",
4678 {
4679 type: "button",
4680 className: "text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 ml-auto",
4681 title: __$1(
4682 "A catchy title that describes your trip. Recommended: 50-60 characters for best SEO results.",
4683 "yatra"
4684 ),
4685 children: /* @__PURE__ */ jsxRuntimeExports.jsx(HelpCircle, { className: "w-3.5 h-3.5" })
4686 }
4687 )
4688 ]
4689 }
4690 ),
4691 /* @__PURE__ */ jsxRuntimeExports.jsxs(
4692 "span",
4693 {
4694 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"}`,
4695 children: [
4696 formData.title.length,
4697 "/60"
4698 ]
4699 }
4700 )
4701 ] }),
4702 /* @__PURE__ */ jsxRuntimeExports.jsx(
4703 HelpText,
4704 {
4705 text: __$1(
4706 '💡 Tip: Include your destination and trip length. Example: "Bali Beach Retreat - 7 Days" or "Paris City Tour - Half Day"',
4707 "yatra"
4708 ),
4709 className: "mb-2"
4710 }
4711 ),
4712 /* @__PURE__ */ jsxRuntimeExports.jsx(
4713 Input,
4714 {
4715 id: "title",
4716 type: "text",
4717 value: formData.title,
4718 onChange: (e) => handleTitleChange(e.target.value),
4719 placeholder: __$1("e.g., Bali Beach Retreat - 7 Days", "yatra"),
4720 maxLength: 100,
4721 className: `${errors.title ? "border-red-500" : formData.title && formData.title.length <= 60 ? "border-green-500" : ""} transition-colors`,
4722 required: true
4723 }
4724 ),
4725 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: [
4726 /* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }),
4727 errors.title
4728 ] }) : 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: [
4729 /* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-3.5 h-3.5" }),
4730 __$1(
4731 "Title is longer than recommended for SEO (60 characters)",
4732 "yatra"
4733 )
4734 ] })
4735 ] }),
4736 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-4", children: [
4737 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-1.5", children: [
4738 /* @__PURE__ */ jsxRuntimeExports.jsxs(
4739 "label",
4740 {
4741 htmlFor: "slug",
4742 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 flex items-center gap-1.5",
4743 children: [
4744 __$1("Trip URL", "yatra"),
4745 /* @__PURE__ */ jsxRuntimeExports.jsx(
4746 Badge,
4747 {
4748 variant: "outline",
4749 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",
4750 children: __$1("Required", "yatra")
4751 }
4752 ),
4753 /* @__PURE__ */ jsxRuntimeExports.jsx(
4754 "button",
4755 {
4756 type: "button",
4757 className: "text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 ml-auto",
4758 title: __$1(
4759 "The web address for your trip page. Auto-generated from your title, but you can customize it.",
4760 "yatra"
4761 ),
4762 children: /* @__PURE__ */ jsxRuntimeExports.jsx(HelpCircle, { className: "w-3.5 h-3.5" })
4763 }
4764 )
4765 ]
4766 }
4767 ),
4768 showSlugPreview && formData.slug && /* @__PURE__ */ jsxRuntimeExports.jsx(
4769 "button",
4770 {
4771 type: "button",
4772 onClick: () => setShowSlugPreview(false),
4773 className: "text-xs text-blue-600 dark:text-blue-400 hover:underline",
4774 children: __$1("Hide", "yatra")
4775 }
4776 )
4777 ] }),
4778 /* @__PURE__ */ jsxRuntimeExports.jsx(
4779 HelpText,
4780 {
4781 text: __$1(
4782 "💡 This is automatically created from your title. You usually don't need to change it unless you want a custom web address.",
4783 "yatra"
4784 ),
4785 className: "mb-2"
4786 }
4787 ),
4788 /* @__PURE__ */ jsxRuntimeExports.jsx(
4789 Input,
4790 {
4791 id: "slug",
4792 type: "text",
4793 value: formData.slug,
4794 onChange: (e) => handleFieldChange("slug", e.target.value),
4795 placeholder: __$1("bali-beach-retreat-7-days", "yatra"),
4796 className: `font-mono text-sm ${errors.slug ? "border-red-500" : ""}`,
4797 required: true
4798 }
4799 ),
4800 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: [
4801 /* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }),
4802 errors.slug
4803 ] }),
4804 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: [
4805 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
4806 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-gray-500 dark:text-gray-400", children: [
4807 __$1("Preview URL:", "yatra"),
4808 " "
4809 ] }),
4810 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-mono text-blue-600 dark:text-blue-400", children: [
4811 ((_a2 = window.yatraAdmin) == null ? void 0 : _a2.siteUrl) || "yoursite.com",
4812 "/",
4813 (settingsData == null ? void 0 : settingsData.trip_base) || "trip",
4814 "/",
4815 formData.slug
4816 ] })
4817 ] }),
4818 /* @__PURE__ */ jsxRuntimeExports.jsx(
4819 "button",
4820 {
4821 type: "button",
4822 onClick: () => {
4823 var _a3;
4824 const tripBase = (settingsData == null ? void 0 : settingsData.trip_base) || "trip";
4825 const url = `${((_a3 = window.yatraAdmin) == null ? void 0 : _a3.siteUrl) || "yoursite.com"}/${tripBase}/${formData.slug}`;
4826 navigator.clipboard.writeText(url);
4827 showToast(
4828 __$1("URL copied to clipboard", "yatra"),
4829 "success"
4830 );
4831 },
4832 className: "ml-2 text-blue-600 dark:text-blue-400 hover:text-blue-700 dark:hover:text-blue-300 flex items-center gap-1",
4833 title: __$1("Copy URL", "yatra"),
4834 children: /* @__PURE__ */ jsxRuntimeExports.jsx(Copy, { className: "w-3.5 h-3.5" })
4835 }
4836 )
4837 ] }),
4838 !showSlugPreview && formData.slug && /* @__PURE__ */ jsxRuntimeExports.jsx(
4839 "button",
4840 {
4841 type: "button",
4842 onClick: () => setShowSlugPreview(true),
4843 className: "mt-2 text-xs text-blue-600 dark:text-blue-400 hover:underline",
4844 children: __$1("Show URL Preview", "yatra")
4845 }
4846 )
4847 ] }),
4848 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-4", children: [
4849 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-1.5", children: [
4850 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-xs font-normal text-gray-500 dark:text-gray-400 flex items-center gap-1.5", children: [
4851 __$1("Short Description", "yatra"),
4852 /* @__PURE__ */ jsxRuntimeExports.jsx(
4853 Badge,
4854 {
4855 variant: "outline",
4856 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",
4857 children: __$1("Recommended", "yatra")
4858 }
4859 ),
4860 /* @__PURE__ */ jsxRuntimeExports.jsx(
4861 "button",
4862 {
4863 type: "button",
4864 className: "text-gray-400 hover:text-gray-600 dark:hover:text-gray-300",
4865 title: __$1(
4866 "A brief summary that appears in listings. Recommended: 100-150 characters for best results.",
4867 "yatra"
4868 ),
4869 children: /* @__PURE__ */ jsxRuntimeExports.jsx(HelpCircle, { className: "w-3.5 h-3.5" })
4870 }
4871 )
4872 ] }),
4873 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
4874 /* @__PURE__ */ jsxRuntimeExports.jsxs(
4875 "span",
4876 {
4877 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"}`,
4878 children: [
4879 formData.short_description.length,
4880 "/200"
4881 ]
4882 }
4883 ),
4884 /* @__PURE__ */ jsxRuntimeExports.jsx(
4885 AiFieldAffordance,
4886 {
4887 task: "trip-short-description",
4888 label: __$1("Short Description", "yatra"),
4889 value: formData.short_description,
4890 onAccept: (v) => handleFieldChange("short_description", v),
4891 buildContext: () => buildTripAiContext(formData)
4892 }
4893 )
4894 ] })
4895 ] }),
4896 /* @__PURE__ */ jsxRuntimeExports.jsx(
4897 HelpText,
4898 {
4899 text: __$1(
4900 '💡 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."',
4901 "yatra"
4902 ),
4903 className: "mb-2"
4904 }
4905 ),
4906 /* @__PURE__ */ jsxRuntimeExports.jsx(
4907 RichTextEditor,
4908 {
4909 value: formData.short_description,
4910 onChange: (value) => handleFieldChange("short_description", value),
4911 placeholder: __$1(
4912 "Escape to paradise with our 7-day Bali beach retreat...",
4913 "yatra"
4914 ),
4915 minHeight: 120
4916 }
4917 ),
4918 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: [
4919 /* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-3.5 h-3.5" }),
4920 __$1(
4921 "Consider adding more details (recommended: 100-150 characters)",
4922 "yatra"
4923 )
4924 ] })
4925 ] }),
4926 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-4", children: [
4927 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-1.5", children: [
4928 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-xs font-normal text-gray-500 dark:text-gray-400 flex items-center gap-1.5", children: [
4929 __$1("Trip Description", "yatra"),
4930 /* @__PURE__ */ jsxRuntimeExports.jsx(
4931 Badge,
4932 {
4933 variant: "outline",
4934 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",
4935 children: __$1("Recommended", "yatra")
4936 }
4937 )
4938 ] }),
4939 /* @__PURE__ */ jsxRuntimeExports.jsx(
4940 AiFieldAffordance,
4941 {
4942 task: "trip-description",
4943 label: __$1("Description", "yatra"),
4944 value: formData.description,
4945 onAccept: (v) => handleFieldChange("description", v),
4946 buildContext: () => buildTripAiContext(formData)
4947 }
4948 )
4949 ] }),
4950 /* @__PURE__ */ jsxRuntimeExports.jsx(
4951 HelpText,
4952 {
4953 text: __$1(
4954 "💡 Tell travelers what makes your trip special! Describe the experience, highlights, and what they'll see. Write 2-4 paragraphs. Be enthusiastic and detailed!",
4955 "💡 Tell travelers what makes your trip special! Describe the experience, highlights, and what they'll see. Write 2-4 paragraphs. Be enthusiastic and detailed!"
4956 ),
4957 className: "mb-2"
4958 }
4959 ),
4960 /* @__PURE__ */ jsxRuntimeExports.jsx(
4961 RichTextEditor,
4962 {
4963 value: formData.description,
4964 onChange: (value) => handleFieldChange("description", value),
4965 placeholder: __$1(
4966 "Escape to paradise with our 7-day Bali beach retreat... Or describe your single day trip experience...",
4967 "yatra"
4968 ),
4969 minHeight: 260
4970 }
4971 ),
4972 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: [
4973 /* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }),
4974 errors.description
4975 ] })
4976 ] }),
4977 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-6", children: [
4978 /* @__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: [
4979 __$1("Featured Image", "yatra"),
4980 /* @__PURE__ */ jsxRuntimeExports.jsx(
4981 Badge,
4982 {
4983 variant: "outline",
4984 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",
4985 children: __$1("Recommended", "yatra")
4986 }
4987 ),
4988 /* @__PURE__ */ jsxRuntimeExports.jsx(
4989 "button",
4990 {
4991 type: "button",
4992 className: "text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 ml-auto",
4993 title: __$1(
4994 "The main image that represents your trip. This appears in listings and as the hero image on the trip page.",
4995 "yatra"
4996 ),
4997 children: /* @__PURE__ */ jsxRuntimeExports.jsx(HelpCircle, { className: "w-3.5 h-3.5" })
4998 }
4999 )
5000 ] }),
5001 /* @__PURE__ */ jsxRuntimeExports.jsx(
5002 HelpText,
5003 {
5004 text: __$1(
5005 "💡 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.",
5006 "yatra"
5007 ),
5008 className: "mb-2"
5009 }
5010 ),
5011 formData.featured_image ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative group", children: [
5012 /* @__PURE__ */ jsxRuntimeExports.jsx(
5013 "div",
5014 {
5015 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"}`,
5016 children: featuredImagePreview ? /* @__PURE__ */ jsxRuntimeExports.jsx(
5017 "img",
5018 {
5019 src: featuredImagePreview,
5020 alt: __$1("Featured Image", "yatra"),
5021 className: "w-full h-full object-cover"
5022 }
5023 ) : /* @__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") })
5024 }
5025 ),
5026 /* @__PURE__ */ jsxRuntimeExports.jsx(
5027 "button",
5028 {
5029 type: "button",
5030 onClick: () => handleFieldChange("featured_image", null),
5031 className: "absolute top-2 right-2 bg-red-600 text-white rounded-full p-1.5 opacity-0 group-hover:opacity-100 transition-opacity",
5032 title: __$1("Remove image", "yatra"),
5033 children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-4 h-4" })
5034 }
5035 )
5036 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
5037 "button",
5038 {
5039 type: "button",
5040 onClick: () => {
5041 if (window.wp && window.wp.media) {
5042 const mediaUploader = window.wp.media({
5043 title: __$1("Select Featured Image", "yatra"),
5044 button: { text: __$1("Use this image", "yatra") },
5045 multiple: false
5046 });
5047 mediaUploader.on("select", () => {
5048 const attachment = mediaUploader.state().get("selection").first().toJSON();
5049 handleFieldChange("featured_image", attachment.id);
5050 });
5051 prepareWordPressMediaFrameOpen();
5052 mediaUploader.open();
5053 }
5054 },
5055 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"}`,
5056 children: [
5057 /* @__PURE__ */ jsxRuntimeExports.jsx(
5058 Upload,
5059 {
5060 className: `w-10 h-10 mb-2 ${errors.featured_image ? "text-red-400" : "text-gray-400"}`
5061 }
5062 ),
5063 /* @__PURE__ */ jsxRuntimeExports.jsx(
5064 "span",
5065 {
5066 className: `text-sm font-medium ${errors.featured_image ? "text-red-600 dark:text-red-400" : "text-gray-600 dark:text-gray-400"}`,
5067 children: __$1("Upload Featured Image", "yatra")
5068 }
5069 ),
5070 /* @__PURE__ */ jsxRuntimeExports.jsx(
5071 "span",
5072 {
5073 className: `text-xs mt-1 ${errors.featured_image ? "text-red-500 dark:text-red-500" : "text-gray-500 dark:text-gray-500"}`,
5074 children: __$1("Recommended: 1200x800px", "yatra")
5075 }
5076 )
5077 ]
5078 }
5079 ),
5080 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: [
5081 /* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }),
5082 errors.featured_image
5083 ] })
5084 ] }),
5085 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { className: "mt-6", children: [
5086 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-2", children: [
5087 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
5088 /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __$1("Trip Highlights", "yatra") }),
5089 /* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: __$1(
5090 "Add key highlights that make your trip special. These will be displayed prominently on your trip page.",
5091 "yatra"
5092 ) })
5093 ] }),
5094 /* @__PURE__ */ jsxRuntimeExports.jsx(
5095 AiFieldAffordance,
5096 {
5097 task: "trip-highlights",
5098 label: __$1("Highlights", "yatra"),
5099 value: (formData.highlights ?? []).join("\n"),
5100 onAccept: (raw) => {
5101 const list = raw.split(/\r?\n/).map((l) => l.replace(/^[\s\-\*•·●]+/, "").trim()).filter((l) => l !== "");
5102 handleFieldChange("highlights", list);
5103 },
5104 buildContext: () => buildTripAiContext(formData)
5105 }
5106 )
5107 ] }) }),
5108 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-3", children: [
5109 formData.highlights.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2", children: formData.highlights.map((highlight, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
5110 "div",
5111 {
5112 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",
5113 children: [
5114 /* @__PURE__ */ jsxRuntimeExports.jsx(CheckCircle2, { className: "w-4 h-4 text-green-600 dark:text-green-400 flex-shrink-0" }),
5115 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 text-sm text-gray-900 dark:text-white", children: highlight }),
5116 /* @__PURE__ */ jsxRuntimeExports.jsx(
5117 Button,
5118 {
5119 type: "button",
5120 variant: "ghost",
5121 size: "sm",
5122 onClick: () => handleHighlightRemove(index),
5123 className: "text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-900/20",
5124 children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-4 h-4" })
5125 }
5126 )
5127 ]
5128 },
5129 index
5130 )) }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-6 border-2 border-dashed border-gray-300 dark:border-gray-700 rounded-lg text-center", children: [
5131 /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "w-8 h-8 text-gray-300 dark:text-gray-600 mx-auto mb-2" }),
5132 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-3", children: __$1("No highlights added yet", "yatra") }),
5133 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-500 mb-4", children: __$1(
5134 'Add key selling points like "Private guide", "All meals included", or "Skip-the-line tickets"',
5135 "yatra"
5136 ) })
5137 ] }),
5138 /* @__PURE__ */ jsxRuntimeExports.jsxs(
5139 Button,
5140 {
5141 type: "button",
5142 variant: "outline",
5143 onClick: handleHighlightAdd,
5144 className: "w-full",
5145 children: [
5146 /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4 mr-2" }),
5147 __$1("Add Highlight", "yatra")
5148 ]
5149 }
5150 )
5151 ] })
5152 ] }),
5153 /* @__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: [
5154 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-sm font-semibold text-gray-900 dark:text-white mb-4", children: __$1("Trip Type & Duration", "yatra") }),
5155 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-4", children: [
5156 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-3", children: __$1("Trip Type", "yatra") }),
5157 /* @__PURE__ */ jsxRuntimeExports.jsxs(
5158 "div",
5159 {
5160 className: `grid grid-cols-1 md:grid-cols-2 gap-4 ${errors.trip_type ? "mb-2" : ""}`,
5161 children: [
5162 /* @__PURE__ */ jsxRuntimeExports.jsxs(
5163 "label",
5164 {
5165 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"}`,
5166 children: [
5167 /* @__PURE__ */ jsxRuntimeExports.jsx(
5168 "input",
5169 {
5170 type: "radio",
5171 name: "trip_type",
5172 value: "single_day",
5173 checked: formData.trip_type === "single_day",
5174 onChange: (e) => {
5175 handleFieldChange("trip_type", e.target.value);
5176 if (e.target.value === "single_day") {
5177 setFormData((prev) => ({
5178 ...prev,
5179 duration_days: "1",
5180 duration_nights: "0"
5181 }));
5182 }
5183 },
5184 className: "sr-only"
5185 }
5186 ),
5187 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-1", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col", children: [
5188 /* @__PURE__ */ jsxRuntimeExports.jsx(
5189 "span",
5190 {
5191 className: `block text-sm font-semibold ${formData.trip_type === "single_day" ? "text-blue-900 dark:text-blue-300" : "text-gray-900 dark:text-white"}`,
5192 children: __$1("Single Day Trip", "yatra")
5193 }
5194 ),
5195 /* @__PURE__ */ jsxRuntimeExports.jsx(
5196 "span",
5197 {
5198 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"}`,
5199 children: __$1(
5200 "Trip completed within one day (no overnight stay)",
5201 "yatra"
5202 )
5203 }
5204 )
5205 ] }) }),
5206 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" }) })
5207 ]
5208 }
5209 ),
5210 /* @__PURE__ */ jsxRuntimeExports.jsxs(
5211 "label",
5212 {
5213 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"}`,
5214 children: [
5215 /* @__PURE__ */ jsxRuntimeExports.jsx(
5216 "input",
5217 {
5218 type: "radio",
5219 name: "trip_type",
5220 value: "multi_day",
5221 checked: formData.trip_type === "multi_day",
5222 onChange: (e) => {
5223 handleFieldChange("trip_type", e.target.value);
5224 setFormData((prev) => ({
5225 ...prev,
5226 duration_hours: ""
5227 }));
5228 },
5229 className: "sr-only"
5230 }
5231 ),
5232 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-1", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col", children: [
5233 /* @__PURE__ */ jsxRuntimeExports.jsx(
5234 "span",
5235 {
5236 className: `block text-sm font-semibold ${formData.trip_type === "multi_day" ? "text-blue-900 dark:text-blue-300" : "text-gray-900 dark:text-white"}`,
5237 children: __$1("Multi-Day Trip", "yatra")
5238 }
5239 ),
5240 /* @__PURE__ */ jsxRuntimeExports.jsx(
5241 "span",
5242 {
5243 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"}`,
5244 children: __$1(
5245 "Trip spans multiple days with overnight stays",
5246 "yatra"
5247 )
5248 }
5249 )
5250 ] }) }),
5251 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" }) })
5252 ]
5253 }
5254 )
5255 ]
5256 }
5257 ),
5258 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: [
5259 /* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }),
5260 errors.trip_type
5261 ] })
5262 ] }),
5263 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
5264 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
5265 /* @__PURE__ */ jsxRuntimeExports.jsx(
5266 "label",
5267 {
5268 htmlFor: "duration_days",
5269 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5",
5270 children: __$1("Duration (Days)", "yatra")
5271 }
5272 ),
5273 /* @__PURE__ */ jsxRuntimeExports.jsx(
5274 Input,
5275 {
5276 id: "duration_days",
5277 type: "number",
5278 min: "1",
5279 value: formData.duration_days,
5280 onChange: (e) => {
5281 const days = e.target.value;
5282 handleFieldChange("duration_days", days);
5283 if (formData.trip_type === "single_day") {
5284 setFormData((prev) => ({
5285 ...prev,
5286 duration_nights: "0"
5287 }));
5288 } else if (days && parseInt(days) > 1) {
5289 const nights = Math.max(
5290 0,
5291 parseInt(days) - 1
5292 ).toString();
5293 setFormData((prev) => ({
5294 ...prev,
5295 duration_nights: nights
5296 }));
5297 }
5298 },
5299 placeholder: formData.trip_type === "single_day" ? "1" : __$1("e.g., 7", "yatra"),
5300 className: errors.duration_days ? "border-red-500" : "",
5301 disabled: formData.trip_type === "single_day"
5302 }
5303 ),
5304 /* @__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(
5305 "Enter the number of days for your trip",
5306 "yatra"
5307 ) }),
5308 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: [
5309 /* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }),
5310 errors.duration_days
5311 ] })
5312 ] }),
5313 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
5314 /* @__PURE__ */ jsxRuntimeExports.jsx(
5315 "label",
5316 {
5317 htmlFor: "duration_nights",
5318 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5",
5319 children: __$1("Duration (Nights)", "yatra")
5320 }
5321 ),
5322 /* @__PURE__ */ jsxRuntimeExports.jsx(
5323 Input,
5324 {
5325 id: "duration_nights",
5326 type: "number",
5327 min: "0",
5328 value: formData.duration_nights,
5329 onChange: (e) => handleFieldChange("duration_nights", e.target.value),
5330 placeholder: formData.trip_type === "single_day" ? "0" : __$1("e.g., 6", "yatra"),
5331 className: errors.duration_nights ? "border-red-500" : "",
5332 disabled: formData.trip_type === "single_day"
5333 }
5334 ),
5335 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1.5 text-xs text-gray-500 dark:text-gray-400", children: formData.trip_type === "single_day" ? __$1(
5336 "Single day trips have 0 nights (no overnight stay)",
5337 "yatra"
5338 ) : __$1(
5339 "Enter the number of nights (typically days - 1)",
5340 "yatra"
5341 ) }),
5342 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: [
5343 /* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }),
5344 errors.duration_nights
5345 ] })
5346 ] })
5347 ] }),
5348 formData.trip_type === "single_day" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-4", children: [
5349 /* @__PURE__ */ jsxRuntimeExports.jsx(
5350 "label",
5351 {
5352 htmlFor: "duration_hours",
5353 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5",
5354 children: __$1("Duration (Hours)", "yatra")
5355 }
5356 ),
5357 /* @__PURE__ */ jsxRuntimeExports.jsx(
5358 Input,
5359 {
5360 id: "duration_hours",
5361 type: "number",
5362 min: "1",
5363 max: "24",
5364 value: formData.duration_hours,
5365 onChange: (e) => handleFieldChange("duration_hours", e.target.value),
5366 placeholder: __$1("e.g., 8", "yatra"),
5367 className: errors.duration_hours ? "border-red-500" : ""
5368 }
5369 ),
5370 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1.5 text-xs text-gray-500 dark:text-gray-400", children: __$1(
5371 "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.",
5372 "yatra"
5373 ) }),
5374 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: [
5375 /* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }),
5376 errors.duration_hours
5377 ] })
5378 ] })
5379 ] }) })
5380 ] })
5381 ] });
5382 case "location":
5383 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
5384 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2 mb-2", children: [
5385 /* @__PURE__ */ jsxRuntimeExports.jsx(MapPin, { className: "w-5 h-5 text-gray-500" }),
5386 /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: __$1("Location & Geography", "yatra") }),
5387 /* @__PURE__ */ jsxRuntimeExports.jsx(
5388 Badge,
5389 {
5390 variant: "outline",
5391 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",
5392 children: __$1("Recommended", "yatra")
5393 }
5394 )
5395 ] }),
5396 /* @__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: [
5397 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm font-medium text-amber-900 dark:text-amber-100 mb-1", children: __$1(
5398 "Specify where your trip takes place, including destinations, coordinates, and key landmarks.",
5399 "yatra"
5400 ) }),
5401 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-amber-800 dark:text-amber-200", children: __$1(
5402 "Optional but highly recommended to help travelers understand the experience.",
5403 "yatra"
5404 ) })
5405 ] }),
5406 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-4", children: [
5407 __$1(
5408 "Optimize how your trip appears in search engines and social shares",
5409 "yatra"
5410 ),
5411 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block text-xs text-gray-500 dark:text-gray-400 mt-1", children: __$1(
5412 "Optional, but completing these fields improves SEO and click-through rates.",
5413 "yatra"
5414 ) })
5415 ] }),
5416 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
5417 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
5418 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: __$1("Destinations", "yatra") }),
5419 destinationsData && destinationsData.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx(
5420 MultiSelect,
5421 {
5422 value: formData.destinations.map((id) => id.toString()),
5423 onChange: (values) => handleFieldChange(
5424 "destinations",
5425 values.map((v) => Number(v))
5426 ),
5427 options: destinationsData.map((destination) => ({
5428 value: destination.id.toString(),
5429 label: destination.name || sprintf(
5430 // translators: %s: numeric destination ID, used as a fallback when the destination has no name.
5431 __$1("Destination #%s", "yatra"),
5432 String(destination.id)
5433 )
5434 })),
5435 placeholder: __$1("Select destinations...", "yatra"),
5436 searchPlaceholder: __$1("Search destinations...", "yatra"),
5437 error: !!errors.destinations
5438 }
5439 ) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-4 border-2 border-dashed border-gray-300 dark:border-gray-700 rounded-lg text-center", children: [
5440 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400 mb-3", children: __$1(
5441 "No destinations available. Please create destinations first.",
5442 "yatra"
5443 ) }),
5444 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
5445 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-400 dark:text-gray-500", children: __$1("To create destinations:", "yatra") }),
5446 /* @__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: [
5447 /* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: __$1(
5448 "Go to Yatra → Destinations in your WordPress admin",
5449 "yatra"
5450 ) }),
5451 /* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: __$1('Click "Add New Destination"', "yatra") }),
5452 /* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: __$1("Enter destination name and details", "yatra") }),
5453 /* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: __$1('Set status to "Published"', "yatra") })
5454 ] }),
5455 /* @__PURE__ */ jsxRuntimeExports.jsxs(
5456 "a",
5457 {
5458 href: "/wp-admin/admin.php?page=yatra&subpage=trips&tab=destinations&action=create",
5459 target: "_blank",
5460 rel: "noopener noreferrer",
5461 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",
5462 children: [
5463 /* @__PURE__ */ jsxRuntimeExports.jsx(
5464 "svg",
5465 {
5466 className: "w-3 h-3 mr-1",
5467 fill: "none",
5468 stroke: "currentColor",
5469 viewBox: "0 0 24 24",
5470 children: /* @__PURE__ */ jsxRuntimeExports.jsx(
5471 "path",
5472 {
5473 strokeLinecap: "round",
5474 strokeLinejoin: "round",
5475 strokeWidth: 2,
5476 d: "M10 6H6a2 2 0 00-2 2v10a2 2 0 002 2h10a2 2 0 002-2v-4M14 4h6m0 0v6m0-6L10 14"
5477 }
5478 )
5479 }
5480 ),
5481 __$1("Create Destinations", "yatra")
5482 ]
5483 }
5484 )
5485 ] })
5486 ] }),
5487 /* @__PURE__ */ jsxRuntimeExports.jsx(
5488 HelpText,
5489 {
5490 text: __$1(
5491 "Select all destinations included in this trip",
5492 "yatra"
5493 ),
5494 className: "mt-2"
5495 }
5496 ),
5497 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: [
5498 /* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }),
5499 errors.destinations
5500 ] })
5501 ] }),
5502 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-8", children: [
5503 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center space-y-2", children: [
5504 /* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-lg font-semibold text-gray-900 dark:text-white flex items-center justify-center gap-2", children: [
5505 /* @__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" }) }),
5506 __$1("Trip Locations", "yatra")
5507 ] }),
5508 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400 max-w-2xl mx-auto", children: __$1(
5509 "Set precise starting and ending points with location names and GPS coordinates. Use manual entry or visual map selection for maximum accuracy.",
5510 "yatra"
5511 ) })
5512 ] }),
5513 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-8", children: [
5514 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
5515 /* @__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: [
5516 /* @__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" }) }),
5517 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
5518 /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-base font-semibold text-blue-900 dark:text-blue-100", children: __$1("Starting Point", "yatra") }),
5519 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-blue-700 dark:text-blue-300", children: __$1("Where the journey begins", "yatra") })
5520 ] }),
5521 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
5522 formData.starting_location && /* @__PURE__ */ jsxRuntimeExports.jsx(
5523 "div",
5524 {
5525 className: "w-2 h-2 bg-green-500 rounded-full animate-pulse",
5526 title: __$1("Location set", "yatra")
5527 }
5528 ),
5529 formData.starting_latitude && formData.starting_longitude && /* @__PURE__ */ jsxRuntimeExports.jsx(
5530 "div",
5531 {
5532 className: "w-2 h-2 bg-blue-500 rounded-full animate-pulse",
5533 title: __$1("Coordinates set", "yatra")
5534 }
5535 )
5536 ] })
5537 ] }),
5538 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
5539 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
5540 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300 flex items-center gap-2", children: [
5541 /* @__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" }) }),
5542 __$1("Starting Location", "yatra")
5543 ] }),
5544 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
5545 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: formData.starting_location ? "✓" : __$1("Required", "yatra") }),
5546 formData.starting_latitude && formData.starting_longitude && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1 text-xs text-green-600", children: [
5547 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-2 h-2 bg-green-500 rounded-full" }),
5548 __$1("Coords Set", "yatra")
5549 ] })
5550 ] })
5551 ] }),
5552 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
5553 LocationPicker,
5554 {
5555 value: {
5556 name: formData.starting_location,
5557 latitude: formData.starting_latitude,
5558 longitude: formData.starting_longitude
5559 },
5560 onChange: (locationData) => {
5561 handleFieldChange(
5562 "starting_location",
5563 locationData.name
5564 );
5565 handleFieldChange(
5566 "starting_latitude",
5567 locationData.latitude
5568 );
5569 handleFieldChange(
5570 "starting_longitude",
5571 locationData.longitude
5572 );
5573 },
5574 label: "",
5575 placeholder: __$1(
5576 "Search for starting location...",
5577 "yatra"
5578 ),
5579 helpText: "",
5580 required: false,
5581 defaultMapCenter: formData.starting_latitude && formData.starting_longitude ? [
5582 parseFloat(formData.starting_latitude),
5583 parseFloat(formData.starting_longitude)
5584 ] : [20, 0],
5585 defaultZoom: formData.starting_latitude && formData.starting_longitude ? 13 : 2,
5586 mapHeight: "300px",
5587 showMapButton: false,
5588 searchLimit: 8,
5589 __: __$1,
5590 className: "",
5591 mapClassName: "rounded-lg"
5592 }
5593 ) })
5594 ] }),
5595 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
5596 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
5597 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300 flex items-center gap-2", children: [
5598 /* @__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" }) }),
5599 __$1("GPS Coordinates", "yatra"),
5600 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: [
5601 "(",
5602 __$1("Manual override", "yatra"),
5603 ")"
5604 ] })
5605 ] }),
5606 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-2", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
5607 "button",
5608 {
5609 type: "button",
5610 onClick: () => {
5611 if (navigator.geolocation) {
5612 navigator.geolocation.getCurrentPosition(
5613 (position) => {
5614 handleFieldChange(
5615 "starting_latitude",
5616 position.coords.latitude.toString()
5617 );
5618 handleFieldChange(
5619 "starting_longitude",
5620 position.coords.longitude.toString()
5621 );
5622 },
5623 (error) => {
5624 let message = __$1(
5625 "Unable to get your location",
5626 "yatra"
5627 );
5628 let showHttpsNotice = false;
5629 switch (error.code) {
5630 case 1:
5631 if (error.message.includes(
5632 "secure origins"
5633 )) {
5634 message = __$1(
5635 "Location access requires HTTPS. This feature will work on your live HTTPS site.",
5636 "yatra"
5637 );
5638 showHttpsNotice = true;
5639 } else {
5640 message = __$1(
5641 "Location access denied. Please allow location access in your browser.",
5642 "yatra"
5643 );
5644 }
5645 break;
5646 case 2:
5647 message = __$1(
5648 "Location information is unavailable. Please try again.",
5649 "yatra"
5650 );
5651 break;
5652 case 3:
5653 message = __$1(
5654 "Location request timed out. Please try again.",
5655 "yatra"
5656 );
5657 break;
5658 }
5659 if (showHttpsNotice) {
5660 alert(
5661 message + "\n\n" + __$1(
5662 "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",
5663 "yatra"
5664 )
5665 );
5666 } else {
5667 alert(message);
5668 }
5669 }
5670 );
5671 } else {
5672 alert(
5673 __$1(
5674 "Geolocation is not supported by your browser",
5675 "yatra"
5676 )
5677 );
5678 }
5679 },
5680 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",
5681 children: [
5682 /* @__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(
5683 "path",
5684 {
5685 fillRule: "evenodd",
5686 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",
5687 clipRule: "evenodd"
5688 }
5689 ) }) }),
5690 __$1("Use Current Location", "yatra")
5691 ]
5692 }
5693 ) })
5694 ] }),
5695 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-3", children: [
5696 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
5697 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-xs font-medium text-gray-600 dark:text-gray-400 flex items-center gap-1", children: [
5698 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-2 h-2 bg-blue-400 rounded-full" }),
5699 __$1("Latitude", "yatra")
5700 ] }),
5701 /* @__PURE__ */ jsxRuntimeExports.jsx(
5702 Input,
5703 {
5704 type: "text",
5705 value: formData.starting_latitude,
5706 onChange: (e) => handleFieldChange(
5707 "starting_latitude",
5708 e.target.value
5709 ),
5710 className: "w-full text-sm"
5711 }
5712 )
5713 ] }),
5714 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
5715 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-xs font-medium text-gray-600 dark:text-gray-400 flex items-center gap-1", children: [
5716 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-2 h-2 bg-blue-400 rounded-full" }),
5717 __$1("Longitude", "yatra")
5718 ] }),
5719 /* @__PURE__ */ jsxRuntimeExports.jsx(
5720 Input,
5721 {
5722 type: "text",
5723 value: formData.starting_longitude,
5724 onChange: (e) => handleFieldChange(
5725 "starting_longitude",
5726 e.target.value
5727 ),
5728 placeholder: __$1("e.g., 115.0920", "yatra"),
5729 className: "w-full text-sm"
5730 }
5731 )
5732 ] })
5733 ] }),
5734 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: __$1(
5735 "Manual coordinate entry. These will be auto-filled when you select a location from the map above.",
5736 "yatra"
5737 ) })
5738 ] })
5739 ] }),
5740 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
5741 /* @__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: [
5742 /* @__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" }) }),
5743 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
5744 /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-base font-semibold text-green-900 dark:text-green-100", children: __$1("Ending Point", "yatra") }),
5745 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-green-700 dark:text-green-300", children: __$1("Where the journey concludes", "yatra") })
5746 ] }),
5747 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-2", children: formData.ending_location && /* @__PURE__ */ jsxRuntimeExports.jsx(
5748 "div",
5749 {
5750 className: "w-2 h-2 bg-green-500 rounded-full animate-pulse",
5751 title: __$1("Location set", "yatra")
5752 }
5753 ) })
5754 ] }),
5755 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
5756 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
5757 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-sm font-medium text-gray-700 dark:text-gray-300 flex items-center gap-2", children: [
5758 /* @__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" }) }),
5759 __$1("Ending Location", "yatra")
5760 ] }),
5761 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
5762 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: formData.ending_location ? "✓" : __$1("Required", "yatra") }),
5763 formData.ending_latitude && formData.ending_longitude && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-1 text-xs text-green-600", children: [
5764 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-2 h-2 bg-green-500 rounded-full" }),
5765 __$1("Coords Set", "yatra")
5766 ] })
5767 ] })
5768 ] }),
5769 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
5770 LocationPicker,
5771 {
5772 value: {
5773 name: formData.ending_location,
5774 latitude: formData.ending_latitude,
5775 longitude: formData.ending_longitude
5776 },
5777 onChange: (locationData) => {
5778 handleFieldChange(
5779 "ending_location",
5780 locationData.name
5781 );
5782 handleFieldChange(
5783 "ending_latitude",
5784 locationData.latitude
5785 );
5786 handleFieldChange(
5787 "ending_longitude",
5788 locationData.longitude
5789 );
5790 },
5791 label: "",
5792 placeholder: __$1(
5793 "Search for ending location...",
5794 "yatra"
5795 ),
5796 helpText: "",
5797 required: false,
5798 defaultMapCenter: formData.ending_latitude && formData.ending_longitude ? [
5799 parseFloat(formData.ending_latitude),
5800 parseFloat(formData.ending_longitude)
5801 ] : formData.starting_latitude && formData.starting_longitude ? [
5802 parseFloat(formData.starting_latitude),
5803 parseFloat(formData.starting_longitude)
5804 ] : [20, 0],
5805 defaultZoom: formData.ending_latitude && formData.ending_longitude ? 13 : formData.starting_latitude && formData.starting_longitude ? 13 : 2,
5806 mapHeight: "300px",
5807 showMapButton: false,
5808 searchLimit: 8,
5809 __: __$1,
5810 className: "",
5811 mapClassName: "rounded-lg"
5812 }
5813 ) })
5814 ] }),
5815 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
5816 /* @__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: [
5817 /* @__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" }) }),
5818 __$1("GPS Coordinates", "yatra"),
5819 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-xs text-gray-500 dark:text-gray-400", children: [
5820 "(",
5821 __$1("Optional", "yatra"),
5822 ")"
5823 ] })
5824 ] }) }),
5825 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-3", children: [
5826 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
5827 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-xs font-medium text-gray-600 dark:text-gray-400 flex items-center gap-1", children: [
5828 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-2 h-2 bg-green-400 rounded-full" }),
5829 __$1("Latitude", "yatra")
5830 ] }),
5831 /* @__PURE__ */ jsxRuntimeExports.jsx(
5832 Input,
5833 {
5834 type: "text",
5835 value: formData.ending_latitude || "",
5836 onChange: (e) => handleFieldChange(
5837 "ending_latitude",
5838 e.target.value
5839 ),
5840 placeholder: __$1("e.g., -8.5069", "yatra"),
5841 className: "w-full text-sm"
5842 }
5843 )
5844 ] }),
5845 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
5846 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "text-xs font-medium text-gray-600 dark:text-gray-400 flex items-center gap-1", children: [
5847 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-2 h-2 bg-green-400 rounded-full" }),
5848 __$1("Longitude", "yatra")
5849 ] }),
5850 /* @__PURE__ */ jsxRuntimeExports.jsx(
5851 Input,
5852 {
5853 type: "text",
5854 value: formData.ending_longitude || "",
5855 onChange: (e) => handleFieldChange(
5856 "ending_longitude",
5857 e.target.value
5858 ),
5859 placeholder: __$1("e.g., 115.2625", "yatra"),
5860 className: "w-full text-sm"
5861 }
5862 )
5863 ] })
5864 ] }),
5865 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: __$1(
5866 "Optional: Manual coordinate entry. Auto-filled when you select a location from the map above.",
5867 "yatra"
5868 ) })
5869 ] })
5870 ] })
5871 ] })
5872 ] }),
5873 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
5874 /* @__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") }),
5875 /* @__PURE__ */ jsxRuntimeExports.jsx(
5876 HelpText,
5877 {
5878 text: __$1(
5879 "Add notable landmarks or points of interest visited during this trip",
5880 "yatra"
5881 ),
5882 className: "mb-2"
5883 }
5884 ),
5885 formData.landmarks.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-2 mb-2", children: formData.landmarks.map((landmark, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
5886 "div",
5887 {
5888 className: "flex items-center gap-2 p-2 bg-gray-50 dark:bg-gray-800 rounded border border-gray-200 dark:border-gray-700",
5889 children: [
5890 /* @__PURE__ */ jsxRuntimeExports.jsx(MapPin, { className: "w-4 h-4 text-gray-400 flex-shrink-0" }),
5891 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 text-sm text-gray-900 dark:text-white", children: landmark }),
5892 /* @__PURE__ */ jsxRuntimeExports.jsx(
5893 Button,
5894 {
5895 type: "button",
5896 variant: "ghost",
5897 size: "sm",
5898 onClick: () => {
5899 const newLandmarks = [...formData.landmarks];
5900 newLandmarks.splice(index, 1);
5901 handleFieldChange("landmarks", newLandmarks);
5902 },
5903 className: "text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-900/20",
5904 children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-4 h-4" })
5905 }
5906 )
5907 ]
5908 },
5909 index
5910 )) }) : /* @__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: [
5911 /* @__PURE__ */ jsxRuntimeExports.jsx(MapPin, { className: "w-6 h-6 text-gray-300 dark:text-gray-600 mx-auto mb-2" }),
5912 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400", children: __$1("No landmarks added yet", "yatra") })
5913 ] }),
5914 /* @__PURE__ */ jsxRuntimeExports.jsxs(
5915 Button,
5916 {
5917 type: "button",
5918 variant: "outline",
5919 onClick: () => {
5920 setShowLandmarkDialog(true);
5921 setLandmarkInput("");
5922 },
5923 className: "w-full",
5924 children: [
5925 /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4 mr-2" }),
5926 __$1("Add Landmark", "yatra")
5927 ]
5928 }
5929 )
5930 ] })
5931 ] })
5932 ] });
5933 case "duration":
5934 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
5935 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2 mb-2", children: [
5936 /* @__PURE__ */ jsxRuntimeExports.jsx(Calendar, { className: "w-5 h-5 text-gray-500" }),
5937 /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: __$1("Availability & Booking", "yatra") }),
5938 /* @__PURE__ */ jsxRuntimeExports.jsx(
5939 Badge,
5940 {
5941 variant: "outline",
5942 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",
5943 children: __$1("Recommended", "yatra")
5944 }
5945 )
5946 ] }),
5947 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-4", children: [
5948 __$1("When is it available & who can book it?", "yatra"),
5949 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block text-xs text-gray-500 dark:text-gray-400 mt-1", children: __$1(
5950 "Set your trip's availability period, capacity limits, and booking requirements. This helps automate bookings and prevent overbooking.",
5951 "yatra"
5952 ) })
5953 ] }),
5954 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
5955 /* @__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: [
5956 /* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-sm font-semibold text-gray-900 dark:text-white mb-4 flex items-center gap-2", children: [
5957 /* @__PURE__ */ jsxRuntimeExports.jsx(Calendar, { className: "w-4 h-4 text-blue-500" }),
5958 __$1("Availability Period", "yatra")
5959 ] }),
5960 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
5961 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
5962 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
5963 /* @__PURE__ */ jsxRuntimeExports.jsx(
5964 "label",
5965 {
5966 htmlFor: "available_from",
5967 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5",
5968 children: __$1("Available From", "yatra")
5969 }
5970 ),
5971 /* @__PURE__ */ jsxRuntimeExports.jsx(
5972 DatePicker,
5973 {
5974 value: formData.available_from,
5975 onChange: (val) => handleFieldChange("available_from", val),
5976 placeholder: __$1("Select date", "yatra")
5977 }
5978 ),
5979 /* @__PURE__ */ jsxRuntimeExports.jsx(
5980 HelpText,
5981 {
5982 text: __$1(
5983 "Earliest date this trip becomes available for booking",
5984 "yatra"
5985 ),
5986 className: "mt-2"
5987 }
5988 )
5989 ] }),
5990 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
5991 /* @__PURE__ */ jsxRuntimeExports.jsx(
5992 "label",
5993 {
5994 htmlFor: "available_to",
5995 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5",
5996 children: __$1("Available To", "yatra")
5997 }
5998 ),
5999 /* @__PURE__ */ jsxRuntimeExports.jsx(
6000 DatePicker,
6001 {
6002 value: formData.available_to,
6003 onChange: (val) => handleFieldChange("available_to", val),
6004 placeholder: __$1("Select date", "yatra")
6005 }
6006 ),
6007 /* @__PURE__ */ jsxRuntimeExports.jsx(
6008 HelpText,
6009 {
6010 text: __$1(
6011 "Latest date this trip is available for booking",
6012 "yatra"
6013 ),
6014 className: "mt-2"
6015 }
6016 )
6017 ] })
6018 ] }),
6019 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
6020 /* @__PURE__ */ jsxRuntimeExports.jsx(
6021 "label",
6022 {
6023 htmlFor: "booking_window_days",
6024 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5",
6025 children: __$1("Booking Window (Days in Advance)", "yatra")
6026 }
6027 ),
6028 /* @__PURE__ */ jsxRuntimeExports.jsx(
6029 Input,
6030 {
6031 id: "booking_window_days",
6032 type: "number",
6033 min: "0",
6034 value: formData.booking_window_days,
6035 onChange: (e) => handleFieldChange("booking_window_days", e.target.value),
6036 placeholder: __$1("e.g., 30", "yatra")
6037 }
6038 ),
6039 /* @__PURE__ */ jsxRuntimeExports.jsx(
6040 HelpText,
6041 {
6042 text: __$1(
6043 "Minimum days in advance customers can book this trip",
6044 "yatra"
6045 ),
6046 className: "mt-2"
6047 }
6048 )
6049 ] }),
6050 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
6051 /* @__PURE__ */ jsxRuntimeExports.jsx(
6052 "label",
6053 {
6054 htmlFor: "seasonal_availability",
6055 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5",
6056 children: __$1("Seasonal Availability Notes", "yatra")
6057 }
6058 ),
6059 /* @__PURE__ */ jsxRuntimeExports.jsx(
6060 Input,
6061 {
6062 id: "seasonal_availability",
6063 type: "text",
6064 value: formData.seasonal_availability,
6065 onChange: (e) => handleFieldChange(
6066 "seasonal_availability",
6067 e.target.value
6068 ),
6069 placeholder: __$1(
6070 "e.g., Available year-round except monsoon season",
6071 "yatra"
6072 )
6073 }
6074 ),
6075 /* @__PURE__ */ jsxRuntimeExports.jsx(
6076 HelpText,
6077 {
6078 text: __$1(
6079 "General notes about when this trip is typically available",
6080 "yatra"
6081 ),
6082 className: "mt-2"
6083 }
6084 )
6085 ] })
6086 ] })
6087 ] }),
6088 /* @__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: [
6089 /* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-sm font-semibold text-gray-900 dark:text-white mb-4 flex items-center gap-2", children: [
6090 /* @__PURE__ */ jsxRuntimeExports.jsx(Users, { className: "w-4 h-4 text-blue-500" }),
6091 __$1("Capacity & Travelers", "yatra")
6092 ] }),
6093 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
6094 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
6095 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
6096 /* @__PURE__ */ jsxRuntimeExports.jsx(
6097 "label",
6098 {
6099 htmlFor: "min_travelers",
6100 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5",
6101 children: __$1("Minimum Travelers", "yatra")
6102 }
6103 ),
6104 /* @__PURE__ */ jsxRuntimeExports.jsx(
6105 Input,
6106 {
6107 id: "min_travelers",
6108 type: "number",
6109 min: "1",
6110 value: formData.min_travelers,
6111 onChange: (e) => handleFieldChange("min_travelers", e.target.value),
6112 className: errors.min_travelers ? "border-red-500" : ""
6113 }
6114 ),
6115 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: [
6116 /* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }),
6117 errors.min_travelers
6118 ] })
6119 ] }),
6120 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
6121 /* @__PURE__ */ jsxRuntimeExports.jsx(
6122 "label",
6123 {
6124 htmlFor: "max_travelers",
6125 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5",
6126 children: __$1("Maximum Travelers", "yatra")
6127 }
6128 ),
6129 /* @__PURE__ */ jsxRuntimeExports.jsx(
6130 Input,
6131 {
6132 id: "max_travelers",
6133 type: "number",
6134 min: "1",
6135 value: formData.max_travelers,
6136 onChange: (e) => handleFieldChange("max_travelers", e.target.value),
6137 className: errors.max_travelers ? "border-red-500" : ""
6138 }
6139 ),
6140 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: [
6141 /* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }),
6142 errors.max_travelers
6143 ] })
6144 ] })
6145 ] }),
6146 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t border-gray-200 dark:border-gray-700 pt-4 mt-4", children: [
6147 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-2 mb-3", children: [
6148 /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-sm font-medium text-gray-900 dark:text-white", children: __$1("Fallback Settings", "yatra") }),
6149 /* @__PURE__ */ jsxRuntimeExports.jsx(
6150 "span",
6151 {
6152 title: __$1(
6153 "These settings are used when the trip has no availability dates or recurring rules set. They provide default values for flexible booking.",
6154 "yatra"
6155 ),
6156 children: /* @__PURE__ */ jsxRuntimeExports.jsx(HelpCircle, { className: "w-4 h-4 text-gray-400 cursor-help" })
6157 }
6158 )
6159 ] }),
6160 /* @__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: [
6161 /* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4 text-amber-600 dark:text-amber-400 mt-0.5 flex-shrink-0" }),
6162 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs text-amber-800 dark:text-amber-200", children: [
6163 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "font-medium mb-1", children: __$1("When are these settings used?", "yatra") }),
6164 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-amber-700 dark:text-amber-300", children: __$1(
6165 "These settings apply ONLY when your trip has ZERO availability dates AND ZERO recurring rules. They provide defaults for flexible booking scenarios.",
6166 "yatra"
6167 ) })
6168 ] })
6169 ] }) }),
6170 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
6171 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: [
6172 /* @__PURE__ */ jsxRuntimeExports.jsxs("h5", { className: "text-sm font-medium text-gray-900 dark:text-white mb-3 flex items-center gap-2", children: [
6173 /* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "w-4 h-4" }),
6174 __$1("Day Tour Time Settings", "yatra")
6175 ] }),
6176 /* @__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: [
6177 /* @__PURE__ */ jsxRuntimeExports.jsx(
6178 "input",
6179 {
6180 type: "checkbox",
6181 id: "has_default_time_slots",
6182 checked: formData.has_default_time_slots,
6183 onChange: (e) => handleFieldChange(
6184 "has_default_time_slots",
6185 e.target.checked
6186 ),
6187 className: "mt-0.5 w-4 h-4 text-blue-600 bg-gray-100 border-gray-300 rounded focus:ring-blue-500"
6188 }
6189 ),
6190 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
6191 /* @__PURE__ */ jsxRuntimeExports.jsx(
6192 "label",
6193 {
6194 htmlFor: "has_default_time_slots",
6195 className: "text-sm font-medium text-gray-900 dark:text-white cursor-pointer",
6196 children: __$1("Enable Multiple Time Slots", "yatra")
6197 }
6198 ),
6199 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-xs text-gray-500 dark:text-gray-400", children: __$1(
6200 "Allow customers to select from multiple departure times (e.g., Morning, Afternoon, Evening tours)",
6201 "yatra"
6202 ) })
6203 ] })
6204 ] }) }),
6205 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: [
6206 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-3", children: [
6207 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
6208 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-gray-900 dark:text-white", children: __$1("Time Slots Configuration", "yatra") }),
6209 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-600 dark:text-gray-400 mt-1", children: __$1(
6210 "Add multiple departure times for customers to choose from.",
6211 "yatra"
6212 ) })
6213 ] }),
6214 /* @__PURE__ */ jsxRuntimeExports.jsxs(
6215 Button,
6216 {
6217 type: "button",
6218 variant: "outline",
6219 size: "sm",
6220 onClick: () => {
6221 const newSlot = {
6222 id: `slot-${Date.now()}`,
6223 time: "09:00",
6224 label: ""
6225 };
6226 handleFieldChange("default_time_slots", [
6227 ...formData.default_time_slots,
6228 newSlot
6229 ]);
6230 },
6231 className: "flex items-center gap-1",
6232 children: [
6233 /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4" }),
6234 __$1("Add Time Slot", "yatra")
6235 ]
6236 }
6237 )
6238 ] }),
6239 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: [
6240 /* @__PURE__ */ jsxRuntimeExports.jsx(Clock, { className: "w-8 h-8 mx-auto text-gray-400 mb-2" }),
6241 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-500 dark:text-gray-400 mb-3", children: __$1("No time slots added yet", "yatra") }),
6242 /* @__PURE__ */ jsxRuntimeExports.jsxs(
6243 Button,
6244 {
6245 type: "button",
6246 variant: "outline",
6247 size: "sm",
6248 onClick: () => {
6249 const newSlot = {
6250 id: `slot-${Date.now()}`,
6251 time: "09:00",
6252 label: __$1("Morning Tour", "yatra")
6253 };
6254 handleFieldChange("default_time_slots", [
6255 newSlot
6256 ]);
6257 },
6258 children: [
6259 /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4 mr-1" }),
6260 __$1("Add First Time Slot", "yatra")
6261 ]
6262 }
6263 )
6264 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: formData.default_time_slots.map(
6265 (slot, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
6266 "div",
6267 {
6268 className: "flex items-start gap-3 p-3 bg-white dark:bg-gray-800 rounded-lg border border-gray-200 dark:border-gray-700",
6269 children: [
6270 /* @__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 }) }),
6271 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 grid grid-cols-1 md:grid-cols-2 gap-3", children: [
6272 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
6273 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1", children: __$1("Time", "yatra") }),
6274 /* @__PURE__ */ jsxRuntimeExports.jsx(
6275 Input,
6276 {
6277 type: "time",
6278 value: slot.time,
6279 onChange: (e) => {
6280 const updated = [
6281 ...formData.default_time_slots
6282 ];
6283 updated[index] = {
6284 ...slot,
6285 time: e.target.value
6286 };
6287 handleFieldChange(
6288 "default_time_slots",
6289 updated
6290 );
6291 },
6292 className: "w-full"
6293 }
6294 )
6295 ] }),
6296 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
6297 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1", children: __$1("Label", "yatra") }),
6298 /* @__PURE__ */ jsxRuntimeExports.jsx(
6299 Input,
6300 {
6301 type: "text",
6302 value: slot.label,
6303 onChange: (e) => {
6304 const updated = [
6305 ...formData.default_time_slots
6306 ];
6307 updated[index] = {
6308 ...slot,
6309 label: e.target.value
6310 };
6311 handleFieldChange(
6312 "default_time_slots",
6313 updated
6314 );
6315 },
6316 placeholder: __$1(
6317 "e.g., Morning Tour, Afternoon Tour",
6318 "yatra"
6319 ),
6320 className: "w-full"
6321 }
6322 )
6323 ] })
6324 ] }),
6325 /* @__PURE__ */ jsxRuntimeExports.jsx(
6326 Button,
6327 {
6328 type: "button",
6329 variant: "ghost",
6330 size: "sm",
6331 onClick: () => {
6332 const updated = formData.default_time_slots.filter(
6333 (_, i) => i !== index
6334 );
6335 handleFieldChange(
6336 "default_time_slots",
6337 updated
6338 );
6339 },
6340 className: "text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-900/20 flex-shrink-0 mt-1",
6341 title: __$1(
6342 "Remove time slot",
6343 "yatra"
6344 ),
6345 children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-4 h-4" })
6346 }
6347 )
6348 ]
6349 },
6350 slot.id
6351 )
6352 ) })
6353 ] }),
6354 !formData.has_default_time_slots && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
6355 /* @__PURE__ */ jsxRuntimeExports.jsx(
6356 "label",
6357 {
6358 htmlFor: "departure_time_single",
6359 className: "block text-sm font-medium text-gray-900 dark:text-white mb-2",
6360 children: __$1("Default Departure Time", "yatra")
6361 }
6362 ),
6363 /* @__PURE__ */ jsxRuntimeExports.jsx(
6364 Input,
6365 {
6366 id: "departure_time_single",
6367 type: "time",
6368 value: formData.departure_time,
6369 onChange: (e) => handleFieldChange(
6370 "departure_time",
6371 e.target.value
6372 ),
6373 className: "max-w-xs"
6374 }
6375 ),
6376 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 text-xs text-gray-500 dark:text-gray-400", children: __$1(
6377 "Single departure time for all bookings when multiple time slots are not enabled.",
6378 "yatra"
6379 ) })
6380 ] })
6381 ] }),
6382 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: [
6383 /* @__PURE__ */ jsxRuntimeExports.jsxs("h5", { className: "text-sm font-medium text-gray-900 dark:text-white mb-3 flex items-center gap-2", children: [
6384 /* @__PURE__ */ jsxRuntimeExports.jsx(Calendar, { className: "w-4 h-4" }),
6385 __$1("Multi-Day Trip Departure Settings", "yatra")
6386 ] }),
6387 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
6388 /* @__PURE__ */ jsxRuntimeExports.jsx(
6389 "label",
6390 {
6391 htmlFor: "departure_time_multiday",
6392 className: "block text-sm font-medium text-gray-900 dark:text-white mb-2",
6393 children: __$1("Default Departure Time", "yatra")
6394 }
6395 ),
6396 /* @__PURE__ */ jsxRuntimeExports.jsx(
6397 Input,
6398 {
6399 id: "departure_time_multiday",
6400 type: "time",
6401 value: formData.departure_time,
6402 onChange: (e) => handleFieldChange(
6403 "departure_time",
6404 e.target.value
6405 ),
6406 className: "max-w-xs"
6407 }
6408 ),
6409 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 text-xs text-gray-500 dark:text-gray-400", children: __$1(
6410 "Default departure time for trips without specific availability dates.",
6411 "yatra"
6412 ) })
6413 ] })
6414 ] }),
6415 !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(
6416 "Please select a trip type (Day Tour or Multi-Day) to configure fallback settings.",
6417 "yatra"
6418 ) }) })
6419 ] })
6420 ] })
6421 ] })
6422 ] }),
6423 /* @__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: [
6424 /* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-sm font-semibold text-gray-900 dark:text-white mb-4 flex items-center gap-2", children: [
6425 /* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { className: "w-4 h-4 text-blue-500" }),
6426 __$1("Booking Policies", "yatra")
6427 ] }),
6428 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
6429 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
6430 /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-sm font-medium text-gray-900 dark:text-white mb-3", children: __$1("Age Restrictions", "yatra") }),
6431 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
6432 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
6433 /* @__PURE__ */ jsxRuntimeExports.jsx(
6434 "label",
6435 {
6436 htmlFor: "age_min",
6437 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5",
6438 children: __$1("Minimum Age", "yatra")
6439 }
6440 ),
6441 /* @__PURE__ */ jsxRuntimeExports.jsx(
6442 Input,
6443 {
6444 id: "age_min",
6445 type: "number",
6446 min: "0",
6447 value: formData.age_min,
6448 onChange: (e) => handleFieldChange("age_min", e.target.value),
6449 placeholder: __$1("e.g., 18", "yatra"),
6450 className: errors.age_min ? "border-red-500" : ""
6451 }
6452 ),
6453 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: [
6454 /* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }),
6455 errors.age_min
6456 ] })
6457 ] }),
6458 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
6459 /* @__PURE__ */ jsxRuntimeExports.jsx(
6460 "label",
6461 {
6462 htmlFor: "age_max",
6463 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5",
6464 children: __$1("Maximum Age", "yatra")
6465 }
6466 ),
6467 /* @__PURE__ */ jsxRuntimeExports.jsx(
6468 Input,
6469 {
6470 id: "age_max",
6471 type: "number",
6472 min: "0",
6473 value: formData.age_max,
6474 onChange: (e) => handleFieldChange("age_max", e.target.value),
6475 placeholder: __$1("e.g., 65", "yatra"),
6476 className: errors.age_max ? "border-red-500" : ""
6477 }
6478 ),
6479 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: [
6480 /* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }),
6481 errors.age_max
6482 ] })
6483 ] })
6484 ] })
6485 ] }),
6486 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
6487 /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-sm font-medium text-gray-900 dark:text-white mb-3", children: __$1("Trip Requirements", "yatra") }),
6488 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
6489 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
6490 /* @__PURE__ */ jsxRuntimeExports.jsx(
6491 "label",
6492 {
6493 htmlFor: "physical_requirements",
6494 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5",
6495 children: __$1("Physical Requirements", "yatra")
6496 }
6497 ),
6498 /* @__PURE__ */ jsxRuntimeExports.jsx(
6499 "textarea",
6500 {
6501 id: "physical_requirements",
6502 value: formData.physical_requirements,
6503 onChange: (e) => handleFieldChange(
6504 "physical_requirements",
6505 e.target.value
6506 ),
6507 placeholder: __$1(
6508 "e.g., Moderate fitness level required. Some walking involved but no strenuous activities.",
6509 "yatra"
6510 ),
6511 rows: 3,
6512 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"
6513 }
6514 )
6515 ] }),
6516 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
6517 /* @__PURE__ */ jsxRuntimeExports.jsx(
6518 "label",
6519 {
6520 htmlFor: "visa_requirements",
6521 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5",
6522 children: __$1("Visa Requirements", "yatra")
6523 }
6524 ),
6525 /* @__PURE__ */ jsxRuntimeExports.jsx(
6526 "textarea",
6527 {
6528 id: "visa_requirements",
6529 value: formData.visa_requirements,
6530 onChange: (e) => handleFieldChange(
6531 "visa_requirements",
6532 e.target.value
6533 ),
6534 placeholder: __$1(
6535 "e.g., Tourist visa required. Can be obtained on arrival or in advance.",
6536 "yatra"
6537 ),
6538 rows: 3,
6539 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"
6540 }
6541 )
6542 ] }),
6543 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
6544 /* @__PURE__ */ jsxRuntimeExports.jsx(
6545 "label",
6546 {
6547 htmlFor: "vaccination_requirements",
6548 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5",
6549 children: __$1("Vaccination Requirements", "yatra")
6550 }
6551 ),
6552 /* @__PURE__ */ jsxRuntimeExports.jsx(
6553 "textarea",
6554 {
6555 id: "vaccination_requirements",
6556 value: formData.vaccination_requirements,
6557 onChange: (e) => handleFieldChange(
6558 "vaccination_requirements",
6559 e.target.value
6560 ),
6561 placeholder: __$1(
6562 "e.g., No mandatory vaccinations. Recommended: Hepatitis A, Typhoid, and routine vaccinations.",
6563 "yatra"
6564 ),
6565 rows: 3,
6566 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"
6567 }
6568 )
6569 ] })
6570 ] })
6571 ] }),
6572 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
6573 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-3", children: [
6574 /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-sm font-medium text-gray-900 dark:text-white", children: __$1("Cancellation Policy", "yatra") }),
6575 /* @__PURE__ */ jsxRuntimeExports.jsx(
6576 AiFieldAffordance,
6577 {
6578 task: "trip-cancellation-policy",
6579 label: __$1("Cancellation Policy", "yatra"),
6580 value: formData.cancellation_policy,
6581 onAccept: (v) => handleFieldChange("cancellation_policy", v),
6582 buildContext: () => buildTripAiContext(formData)
6583 }
6584 )
6585 ] }),
6586 /* @__PURE__ */ jsxRuntimeExports.jsx(
6587 "textarea",
6588 {
6589 id: "cancellation_policy",
6590 value: formData.cancellation_policy,
6591 onChange: (e) => handleFieldChange("cancellation_policy", e.target.value),
6592 placeholder: __$1(
6593 "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.",
6594 "yatra"
6595 ),
6596 rows: 4,
6597 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"
6598 }
6599 )
6600 ] })
6601 ] })
6602 ] }),
6603 /* @__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: [
6604 /* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-sm font-semibold text-gray-900 dark:text-white mb-4 flex items-center gap-2", children: [
6605 /* @__PURE__ */ jsxRuntimeExports.jsx(Calendar, { className: "w-4 h-4 text-blue-500" }),
6606 __$1("Booking Availability", "yatra"),
6607 /* @__PURE__ */ jsxRuntimeExports.jsx(ProBadge, { isProActive: isPro })
6608 ] }),
6609 /* @__PURE__ */ jsxRuntimeExports.jsx(
6610 ProFeature,
6611 {
6612 description: __$1(
6613 "disable the booking calendar and make trips enquiry-only",
6614 "yatra"
6615 ),
6616 moduleName: __$1("Enquiry Only Mode", "yatra"),
6617 pricingUrl: "https://wpyatra.com/pricing",
6618 isProActive: isPro,
6619 isModuleEnabled: isPro,
6620 children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-3", children: [
6621 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center h-5 mt-0.5", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
6622 "input",
6623 {
6624 id: "disable_booking",
6625 type: "checkbox",
6626 checked: formData.disable_booking,
6627 onChange: (e) => handleFieldChange("disable_booking", e.target.checked),
6628 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"
6629 }
6630 ) }),
6631 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
6632 /* @__PURE__ */ jsxRuntimeExports.jsx(
6633 "label",
6634 {
6635 htmlFor: "disable_booking",
6636 className: "block text-sm font-medium text-gray-900 dark:text-white cursor-pointer",
6637 children: __$1("Disable Booking Calendar", "yatra")
6638 }
6639 ),
6640 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-xs text-gray-500 dark:text-gray-400", children: __$1(
6641 "When enabled, the booking form and date picker will be hidden. Visitors can only send an enquiry for this trip.",
6642 "yatra"
6643 ) })
6644 ] })
6645 ] })
6646 }
6647 )
6648 ] }),
6649 /* @__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: [
6650 /* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-sm font-semibold text-gray-900 dark:text-white mb-4 flex items-center gap-2", children: [
6651 /* @__PURE__ */ jsxRuntimeExports.jsx(Home, { className: "w-4 h-4 text-blue-500" }),
6652 __$1("Accommodation", "yatra")
6653 ] }),
6654 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
6655 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
6656 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
6657 /* @__PURE__ */ jsxRuntimeExports.jsx(
6658 "label",
6659 {
6660 htmlFor: "accommodation_type",
6661 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5",
6662 children: __$1("Accommodation Type", "yatra")
6663 }
6664 ),
6665 /* @__PURE__ */ jsxRuntimeExports.jsx(
6666 Input,
6667 {
6668 id: "accommodation_type",
6669 type: "text",
6670 value: formData.accommodation_type,
6671 onChange: (e) => handleFieldChange(
6672 "accommodation_type",
6673 e.target.value
6674 ),
6675 placeholder: __$1(
6676 "e.g., Hotel, Resort, Teahouse, Camping",
6677 "yatra"
6678 )
6679 }
6680 )
6681 ] }),
6682 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
6683 /* @__PURE__ */ jsxRuntimeExports.jsx(
6684 "label",
6685 {
6686 htmlFor: "meal_plan",
6687 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5",
6688 children: __$1("Meal Plan", "yatra")
6689 }
6690 ),
6691 /* @__PURE__ */ jsxRuntimeExports.jsx(
6692 Select,
6693 {
6694 id: "meal_plan",
6695 value: formData.meal_plan,
6696 onChange: (e) => handleFieldChange("meal_plan", e.target.value),
6697 children: MEAL_PLAN_SELECT_OPTIONS.map(({ value, label }) => /* @__PURE__ */ jsxRuntimeExports.jsx(
6698 "option",
6699 {
6700 value,
6701 children: label
6702 },
6703 value || "meal-plan-empty"
6704 ))
6705 }
6706 ),
6707 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1.5 text-xs text-gray-500 dark:text-gray-400", children: __$1(
6708 "Tells travelers which meals are included with lodging (e.g. breakfast only vs full board).",
6709 "yatra"
6710 ) })
6711 ] })
6712 ] }),
6713 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
6714 /* @__PURE__ */ jsxRuntimeExports.jsx(
6715 "label",
6716 {
6717 htmlFor: "accommodation_details",
6718 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5",
6719 children: __$1("Accommodation Details", "yatra")
6720 }
6721 ),
6722 /* @__PURE__ */ jsxRuntimeExports.jsx(
6723 "textarea",
6724 {
6725 id: "accommodation_details",
6726 value: formData.accommodation_details,
6727 onChange: (e) => handleFieldChange(
6728 "accommodation_details",
6729 e.target.value
6730 ),
6731 placeholder: __$1(
6732 "e.g., 4-star beachfront resort with private balconies, infinity pool, and spa facilities",
6733 "yatra"
6734 ),
6735 rows: 3,
6736 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"
6737 }
6738 )
6739 ] })
6740 ] })
6741 ] }),
6742 /* @__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: [
6743 /* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-sm font-semibold text-gray-900 dark:text-white mb-4 flex items-center gap-2", children: [
6744 /* @__PURE__ */ jsxRuntimeExports.jsx(Car, { className: "w-4 h-4 text-blue-500" }),
6745 __$1("Transportation", "yatra")
6746 ] }),
6747 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
6748 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
6749 /* @__PURE__ */ jsxRuntimeExports.jsx(
6750 "input",
6751 {
6752 type: "checkbox",
6753 id: "transportation_included",
6754 checked: formData.transportation_included,
6755 onChange: (e) => handleFieldChange(
6756 "transportation_included",
6757 e.target.checked
6758 ),
6759 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"
6760 }
6761 ),
6762 /* @__PURE__ */ jsxRuntimeExports.jsx(
6763 "label",
6764 {
6765 htmlFor: "transportation_included",
6766 className: "text-sm font-medium text-gray-900 dark:text-white",
6767 children: __$1("Transportation Included", "yatra")
6768 }
6769 )
6770 ] }),
6771 formData.transportation_included && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
6772 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
6773 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
6774 /* @__PURE__ */ jsxRuntimeExports.jsx(
6775 "label",
6776 {
6777 htmlFor: "pickup_location",
6778 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5",
6779 children: __$1("Pickup Location", "yatra")
6780 }
6781 ),
6782 /* @__PURE__ */ jsxRuntimeExports.jsx(
6783 Input,
6784 {
6785 id: "pickup_location",
6786 type: "text",
6787 value: formData.pickup_location,
6788 onChange: (e) => handleFieldChange(
6789 "pickup_location",
6790 e.target.value
6791 ),
6792 placeholder: __$1(
6793 "e.g., Airport, Hotel, City Center",
6794 "yatra"
6795 )
6796 }
6797 )
6798 ] }),
6799 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
6800 /* @__PURE__ */ jsxRuntimeExports.jsx(
6801 "label",
6802 {
6803 htmlFor: "dropoff_location",
6804 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5",
6805 children: __$1("Dropoff Location", "yatra")
6806 }
6807 ),
6808 /* @__PURE__ */ jsxRuntimeExports.jsx(
6809 Input,
6810 {
6811 id: "dropoff_location",
6812 type: "text",
6813 value: formData.dropoff_location,
6814 onChange: (e) => handleFieldChange(
6815 "dropoff_location",
6816 e.target.value
6817 ),
6818 placeholder: __$1(
6819 "e.g., Airport, Hotel, City Center",
6820 "yatra"
6821 )
6822 }
6823 )
6824 ] })
6825 ] }),
6826 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
6827 /* @__PURE__ */ jsxRuntimeExports.jsx(
6828 "label",
6829 {
6830 htmlFor: "transportation_details",
6831 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5",
6832 children: __$1("Transportation Details", "yatra")
6833 }
6834 ),
6835 /* @__PURE__ */ jsxRuntimeExports.jsx(
6836 "textarea",
6837 {
6838 id: "transportation_details",
6839 value: formData.transportation_details,
6840 onChange: (e) => handleFieldChange(
6841 "transportation_details",
6842 e.target.value
6843 ),
6844 placeholder: __$1(
6845 "e.g., Private air-conditioned vehicle with professional driver",
6846 "yatra"
6847 ),
6848 rows: 3,
6849 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"
6850 }
6851 )
6852 ] })
6853 ] })
6854 ] })
6855 ] })
6856 ] })
6857 ] });
6858 case "categorization":
6859 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
6860 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2 mb-2", children: [
6861 /* @__PURE__ */ jsxRuntimeExports.jsx(Tag, { className: "w-5 h-5 text-gray-500" }),
6862 /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: __$1("Categories & Attributes", "yatra") }),
6863 /* @__PURE__ */ jsxRuntimeExports.jsx(
6864 Badge,
6865 {
6866 variant: "outline",
6867 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",
6868 children: __$1("Recommended", "yatra")
6869 }
6870 )
6871 ] }),
6872 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-4", children: [
6873 __$1("How should travelers find this trip?", "yatra"),
6874 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block text-xs text-gray-500 dark:text-gray-400 mt-1", children: __$1(
6875 "Organize your trip with categories, activities, and custom attributes to help travelers discover it through search and filters.",
6876 "yatra"
6877 ) })
6878 ] }),
6879 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
6880 /* @__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: [
6881 /* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-sm font-semibold text-gray-900 dark:text-white mb-4 flex items-center gap-2", children: [
6882 /* @__PURE__ */ jsxRuntimeExports.jsx(Tag, { className: "w-4 h-4 text-blue-500" }),
6883 __$1("Categories & Classification", "yatra")
6884 ] }),
6885 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
6886 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
6887 /* @__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") }),
6888 tripCategories && tripCategories.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx(
6889 MultiSelect,
6890 {
6891 value: formData.trip_category,
6892 onChange: (values) => handleFieldChange(
6893 "trip_category",
6894 values.map((v) => Number(v))
6895 ),
6896 options: (() => {
6897 const flattenCategories = (cats, prefix = "") => {
6898 const result = [];
6899 cats.forEach((cat) => {
6900 result.push({
6901 value: cat.id,
6902 label: prefix + cat.name
6903 });
6904 if (cat.subcategories && cat.subcategories.length > 0) {
6905 result.push(
6906 ...flattenCategories(
6907 cat.subcategories,
6908 prefix + "— "
6909 )
6910 );
6911 }
6912 });
6913 return result;
6914 };
6915 return flattenCategories(tripCategories);
6916 })(),
6917 placeholder: __$1("Select categories...", "yatra"),
6918 searchPlaceholder: __$1("Search categories...", "yatra")
6919 }
6920 ) : /* @__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: [
6921 __$1("No categories available. ", "yatra"),
6922 /* @__PURE__ */ jsxRuntimeExports.jsx(
6923 "a",
6924 {
6925 href: "/wp-admin/admin.php?page=yatra&subpage=trips&tab=categories",
6926 target: "_blank",
6927 rel: "noopener noreferrer",
6928 className: "text-blue-600 hover:text-blue-700 underline",
6929 children: __$1("Create categories here", "yatra")
6930 }
6931 )
6932 ] }) }),
6933 /* @__PURE__ */ jsxRuntimeExports.jsx(
6934 HelpText,
6935 {
6936 text: __$1(
6937 "Select one or more categories for this trip",
6938 "yatra"
6939 ),
6940 className: "mt-2"
6941 }
6942 )
6943 ] }),
6944 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
6945 /* @__PURE__ */ jsxRuntimeExports.jsx(
6946 "label",
6947 {
6948 htmlFor: "difficulty_level",
6949 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5",
6950 children: __$1("Difficulty Level", "yatra")
6951 }
6952 ),
6953 /* @__PURE__ */ jsxRuntimeExports.jsxs(
6954 Select,
6955 {
6956 id: "difficulty_level",
6957 value: formData.difficulty_level,
6958 onChange: (e) => handleFieldChange("difficulty_level", e.target.value),
6959 disabled: isLoadingDifficultyLevels,
6960 children: [
6961 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "", children: __$1("Select difficulty", "yatra") }),
6962 isLoadingDifficultyLevels && /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "", disabled: true, children: __$1("Loading difficulty levels...", "yatra") }),
6963 !isLoadingDifficultyLevels && difficultyLevels.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "", disabled: true, children: __$1(
6964 "No difficulty levels available - Click below to create",
6965 "yatra"
6966 ) }),
6967 !isLoadingDifficultyLevels && difficultyLevels.map((level) => {
6968 var _a3;
6969 return /* @__PURE__ */ jsxRuntimeExports.jsx(
6970 "option",
6971 {
6972 value: ((_a3 = level.id) == null ? void 0 : _a3.toString()) || "",
6973 children: level.name
6974 },
6975 `difficulty-${level.id}`
6976 );
6977 })
6978 ]
6979 }
6980 ),
6981 !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: [
6982 __$1("No difficulty levels available. ", "yatra"),
6983 /* @__PURE__ */ jsxRuntimeExports.jsx(
6984 "a",
6985 {
6986 href: "/wp-admin/admin.php?page=yatra&subpage=trips&tab=difficulty-levels",
6987 target: "_blank",
6988 rel: "noopener noreferrer",
6989 className: "text-amber-800 hover:text-amber-900 underline font-medium",
6990 children: __$1("Create difficulty levels here", "yatra")
6991 }
6992 )
6993 ] }) }),
6994 /* @__PURE__ */ jsxRuntimeExports.jsx(
6995 HelpText,
6996 {
6997 text: __$1(
6998 "Physical difficulty level required for this trip",
6999 "yatra"
7000 ),
7001 className: "mt-2"
7002 }
7003 )
7004 ] }),
7005 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
7006 /* @__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") }),
7007 activitiesData && activitiesData.length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx(
7008 MultiSelect,
7009 {
7010 value: formData.activity_types,
7011 onChange: (values) => handleFieldChange(
7012 "activity_types",
7013 values.map((v) => Number(v))
7014 ),
7015 options: activitiesData.map((activity) => ({
7016 value: activity.id,
7017 label: activity.name
7018 })),
7019 placeholder: __$1("Select activities...", "yatra"),
7020 searchPlaceholder: __$1("Search activities...", "yatra")
7021 }
7022 ) : /* @__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: [
7023 __$1("No activities available. ", "yatra"),
7024 /* @__PURE__ */ jsxRuntimeExports.jsx(
7025 "a",
7026 {
7027 href: "/wp-admin/admin.php?page=yatra&subpage=trips&tab=activities",
7028 target: "_blank",
7029 rel: "noopener noreferrer",
7030 className: "text-blue-600 hover:text-blue-700 underline",
7031 children: __$1("Create activities here", "yatra")
7032 }
7033 )
7034 ] }) }),
7035 /* @__PURE__ */ jsxRuntimeExports.jsx(
7036 HelpText,
7037 {
7038 text: __$1(
7039 "Select all activities included in this trip",
7040 "yatra"
7041 ),
7042 className: "mt-2"
7043 }
7044 )
7045 ] }),
7046 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
7047 /* @__PURE__ */ jsxRuntimeExports.jsx(
7048 "label",
7049 {
7050 htmlFor: "featured_priority",
7051 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5",
7052 children: __$1("Featured Priority", "yatra")
7053 }
7054 ),
7055 /* @__PURE__ */ jsxRuntimeExports.jsxs(
7056 Select,
7057 {
7058 id: "featured_priority",
7059 value: formData.featured_priority,
7060 onChange: (e) => handleFieldChange(
7061 "featured_priority",
7062 e.target.value
7063 ),
7064 children: [
7065 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "none", children: __$1("None", "yatra") }),
7066 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "featured", children: __$1("Featured", "yatra") }),
7067 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "new", children: __$1("New", "yatra") }),
7068 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "limited", children: __$1("Limited Time", "yatra") })
7069 ]
7070 }
7071 ),
7072 /* @__PURE__ */ jsxRuntimeExports.jsx(
7073 HelpText,
7074 {
7075 text: __$1(
7076 "Special designation for frontend display and promotion",
7077 "yatra"
7078 ),
7079 className: "mt-2"
7080 }
7081 )
7082 ] })
7083 ] })
7084 ] }),
7085 /* @__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: [
7086 /* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-sm font-semibold text-gray-900 dark:text-white mb-4 flex items-center gap-2", children: [
7087 /* @__PURE__ */ jsxRuntimeExports.jsx(Settings, { className: "w-4 h-4 text-blue-500" }),
7088 __$1("Custom Attributes", "yatra")
7089 ] }),
7090 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mb-4", children: __$1(
7091 "Add custom attributes for advanced filtering and search capabilities.",
7092 "yatra"
7093 ) }),
7094 /* @__PURE__ */ jsxRuntimeExports.jsx(
7095 TripAttributesSection,
7096 {
7097 formData,
7098 handleFieldChange,
7099 tripId: tripId || void 0,
7100 isEditMode,
7101 tripAttributesData,
7102 tripAttributesReady
7103 }
7104 )
7105 ] })
7106 ] })
7107 ] });
7108 case "media":
7109 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
7110 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2 mb-2", children: [
7111 /* @__PURE__ */ jsxRuntimeExports.jsx(Image, { className: "w-5 h-5 text-gray-500" }),
7112 /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: __$1("Media & Content", "yatra") }),
7113 /* @__PURE__ */ jsxRuntimeExports.jsx(
7114 Badge,
7115 {
7116 variant: "outline",
7117 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",
7118 children: __$1("Recommended", "yatra")
7119 }
7120 )
7121 ] }),
7122 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-6", children: [
7123 __$1(
7124 "Add visual content, videos, stories, and testimonials to showcase your trip",
7125 "yatra"
7126 ),
7127 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block text-xs text-gray-500 dark:text-gray-400 mt-1", children: __$1(
7128 "Optional, but adding rich media greatly increases engagement and conversions.",
7129 "yatra"
7130 ) })
7131 ] }),
7132 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
7133 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
7134 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { children: [
7135 /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __$1("Photo Gallery", "yatra") }),
7136 /* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: __$1(
7137 "Upload images to showcase your trip. These will be displayed on the trip page.",
7138 "yatra"
7139 ) })
7140 ] }),
7141 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { children: [
7142 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 md:grid-cols-3 gap-4 mb-4", children: [
7143 formData.gallery_images.map((image, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative group", children: [
7144 /* @__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(
7145 "img",
7146 {
7147 src: image.thumbnail_url || image.url,
7148 alt: image.alt_text || `Gallery ${index + 1}`,
7149 className: "w-full h-full object-cover"
7150 }
7151 ) }),
7152 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "absolute top-2 left-2 flex gap-1 opacity-0 group-hover:opacity-100 transition-opacity", children: [
7153 index > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
7154 "button",
7155 {
7156 type: "button",
7157 onClick: () => handleGalleryReorder(index, index - 1),
7158 className: "bg-black/60 text-white rounded p-1 hover:bg-black/80",
7159 title: __$1("Move left", "yatra"),
7160 children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronLeft, { className: "w-4 h-4" })
7161 }
7162 ),
7163 index < formData.gallery_images.length - 1 && /* @__PURE__ */ jsxRuntimeExports.jsx(
7164 "button",
7165 {
7166 type: "button",
7167 onClick: () => handleGalleryReorder(index, index + 1),
7168 className: "bg-black/60 text-white rounded p-1 hover:bg-black/80",
7169 title: __$1("Move right", "yatra"),
7170 children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "w-4 h-4" })
7171 }
7172 )
7173 ] }),
7174 /* @__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 }),
7175 /* @__PURE__ */ jsxRuntimeExports.jsx(
7176 "button",
7177 {
7178 type: "button",
7179 onClick: () => handleGalleryRemove(index),
7180 className: "absolute top-2 right-2 bg-red-600 text-white rounded-full p-1 opacity-0 group-hover:opacity-100 transition-opacity",
7181 children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-4 h-4" })
7182 }
7183 )
7184 ] }, index)),
7185 /* @__PURE__ */ jsxRuntimeExports.jsxs(
7186 "button",
7187 {
7188 type: "button",
7189 onClick: handleGalleryAdd,
7190 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"}`,
7191 children: [
7192 /* @__PURE__ */ jsxRuntimeExports.jsx(
7193 Upload,
7194 {
7195 className: `w-8 h-8 mb-2 ${errors.gallery_images ? "text-red-400" : "text-gray-400"}`
7196 }
7197 ),
7198 /* @__PURE__ */ jsxRuntimeExports.jsx(
7199 "span",
7200 {
7201 className: `text-sm ${errors.gallery_images ? "text-red-600 dark:text-red-400" : "text-gray-600 dark:text-gray-400"}`,
7202 children: __$1("Add Image", "yatra")
7203 }
7204 )
7205 ]
7206 }
7207 )
7208 ] }),
7209 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: [
7210 /* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }),
7211 errors.gallery_images
7212 ] })
7213 ] })
7214 ] }),
7215 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
7216 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { children: [
7217 /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __$1("Video & Virtual Tour", "yatra") }),
7218 /* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: __$1(
7219 "Add video content to showcase your trip visually",
7220 "yatra"
7221 ) })
7222 ] }),
7223 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-4", children: [
7224 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
7225 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: [
7226 __$1("Video URL", "yatra"),
7227 " (YouTube/Vimeo)"
7228 ] }),
7229 /* @__PURE__ */ jsxRuntimeExports.jsx(
7230 HelpText,
7231 {
7232 text: __$1(
7233 "Paste the full URL from YouTube or Vimeo. The video will be embedded on your trip page.",
7234 "yatra"
7235 ),
7236 className: "mb-2"
7237 }
7238 ),
7239 /* @__PURE__ */ jsxRuntimeExports.jsx(
7240 Input,
7241 {
7242 type: "url",
7243 value: formData.video_url,
7244 onChange: (e) => handleFieldChange("video_url", e.target.value),
7245 placeholder: "https://www.youtube.com/watch?v=...",
7246 className: `font-mono text-xs ${errors.video_url ? "border-red-500" : ""}`
7247 }
7248 ),
7249 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: [
7250 /* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }),
7251 errors.video_url
7252 ] })
7253 ] }),
7254 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
7255 /* @__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") }),
7256 /* @__PURE__ */ jsxRuntimeExports.jsx(
7257 HelpText,
7258 {
7259 text: __$1(
7260 "Add a link to an interactive 360° virtual tour if available",
7261 "yatra"
7262 ),
7263 className: "mb-2"
7264 }
7265 ),
7266 /* @__PURE__ */ jsxRuntimeExports.jsx(
7267 Input,
7268 {
7269 type: "url",
7270 value: formData.virtual_tour_url,
7271 onChange: (e) => handleFieldChange("virtual_tour_url", e.target.value),
7272 placeholder: "https://...",
7273 className: `font-mono text-xs ${errors.virtual_tour_url ? "border-red-500" : ""}`
7274 }
7275 ),
7276 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: [
7277 /* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }),
7278 errors.virtual_tour_url
7279 ] })
7280 ] })
7281 ] })
7282 ] }),
7283 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
7284 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { children: [
7285 /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __$1("Trip Story & Special Features", "yatra") }),
7286 /* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: __$1(
7287 "Tell an engaging story and highlight what makes this trip unique",
7288 "yatra"
7289 ) })
7290 ] }),
7291 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-4", children: [
7292 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
7293 /* @__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") }),
7294 /* @__PURE__ */ jsxRuntimeExports.jsx(
7295 HelpText,
7296 {
7297 text: __$1(
7298 "Highlight the unique selling points and what sets this trip apart from others",
7299 "yatra"
7300 ),
7301 className: "mb-2"
7302 }
7303 ),
7304 /* @__PURE__ */ jsxRuntimeExports.jsx(
7305 "textarea",
7306 {
7307 value: formData.what_makes_special,
7308 onChange: (e) => handleFieldChange("what_makes_special", e.target.value),
7309 placeholder: __$1(
7310 "Describe what makes this trip unique and special...",
7311 "yatra"
7312 ),
7313 rows: 5,
7314 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"
7315 }
7316 )
7317 ] }),
7318 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
7319 /* @__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") }),
7320 /* @__PURE__ */ jsxRuntimeExports.jsx(
7321 HelpText,
7322 {
7323 text: __$1(
7324 "Tell an engaging story about this trip. Use storytelling to connect with potential travelers emotionally",
7325 "yatra"
7326 ),
7327 className: "mb-2"
7328 }
7329 ),
7330 /* @__PURE__ */ jsxRuntimeExports.jsx(
7331 "textarea",
7332 {
7333 value: formData.trip_story,
7334 onChange: (e) => handleFieldChange("trip_story", e.target.value),
7335 placeholder: __$1(
7336 "Write an engaging narrative about this trip...",
7337 "yatra"
7338 ),
7339 rows: 8,
7340 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"
7341 }
7342 )
7343 ] })
7344 ] })
7345 ] }),
7346 /* @__PURE__ */ jsxRuntimeExports.jsx(
7347 TestimonialsSelector,
7348 {
7349 tripId,
7350 selectedReviewIds: formData.testimonial_review_ids,
7351 onChange: (reviewIds) => handleFieldChange("testimonial_review_ids", reviewIds)
7352 }
7353 )
7354 ] })
7355 ] });
7356 case "downloads":
7357 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
7358 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2 mb-2", children: [
7359 /* @__PURE__ */ jsxRuntimeExports.jsx(Download, { className: "w-5 h-5 text-gray-500" }),
7360 /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: __$1("Downloads", "yatra") })
7361 ] }),
7362 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-6", children: __$1(
7363 "Attach files to this trip and control who can access them.",
7364 "yatra"
7365 ) }),
7366 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
7367 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { children: [
7368 /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __$1("Downloads", "yatra") }),
7369 /* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: __$1(
7370 "Attach files to this trip and control who can access them.",
7371 "yatra"
7372 ) })
7373 ] }),
7374 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-4", children: [
7375 (formData.downloadable_items || []).length > 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: (formData.downloadable_items || []).map((item, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
7376 "div",
7377 {
7378 className: "p-4 border border-gray-200 dark:border-gray-700 rounded-lg space-y-3",
7379 children: [
7380 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between gap-2", children: [
7381 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
7382 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: __$1("Title", "yatra") }),
7383 /* @__PURE__ */ jsxRuntimeExports.jsx(
7384 Input,
7385 {
7386 value: item.title,
7387 onChange: (e) => handleDownloadableItemChange(
7388 index,
7389 "title",
7390 e.target.value
7391 ),
7392 placeholder: __$1(
7393 "E.g. Packing list, itinerary PDF, waiver form...",
7394 "yatra"
7395 )
7396 }
7397 )
7398 ] }),
7399 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-1 pt-7", children: [
7400 index > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx(
7401 Button,
7402 {
7403 type: "button",
7404 variant: "ghost",
7405 size: "sm",
7406 onClick: () => handleDownloadableItemMove(index, index - 1),
7407 title: __$1("Move up", "yatra"),
7408 children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronUp, { className: "w-4 h-4" })
7409 }
7410 ),
7411 index < (formData.downloadable_items || []).length - 1 && /* @__PURE__ */ jsxRuntimeExports.jsx(
7412 Button,
7413 {
7414 type: "button",
7415 variant: "ghost",
7416 size: "sm",
7417 onClick: () => handleDownloadableItemMove(index, index + 1),
7418 title: __$1("Move down", "yatra"),
7419 children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "w-4 h-4" })
7420 }
7421 ),
7422 /* @__PURE__ */ jsxRuntimeExports.jsx(
7423 Button,
7424 {
7425 type: "button",
7426 variant: "ghost",
7427 size: "sm",
7428 onClick: () => handleDownloadableItemRemove(index),
7429 className: "text-red-600 hover:text-red-700",
7430 title: __$1("Remove", "yatra"),
7431 children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-4 h-4" })
7432 }
7433 )
7434 ] })
7435 ] }),
7436 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
7437 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: [
7438 __$1("Description", "yatra"),
7439 " (",
7440 __$1("Optional", "yatra"),
7441 ")"
7442 ] }),
7443 /* @__PURE__ */ jsxRuntimeExports.jsx(
7444 "textarea",
7445 {
7446 value: item.description,
7447 onChange: (e) => handleDownloadableItemChange(
7448 index,
7449 "description",
7450 e.target.value
7451 ),
7452 rows: 3,
7453 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"
7454 }
7455 )
7456 ] }),
7457 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
7458 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
7459 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: __$1("Visibility", "yatra") }),
7460 /* @__PURE__ */ jsxRuntimeExports.jsxs(
7461 Select,
7462 {
7463 value: item.visibility,
7464 onChange: (e) => handleDownloadableItemChange(
7465 index,
7466 "visibility",
7467 e.target.value
7468 ),
7469 children: [
7470 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "public", children: __$1("Public", "yatra") }),
7471 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "logged_in", children: __$1("Private (My Account only)", "yatra") }),
7472 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "booked_only", children: __$1(
7473 "Private (Booking confirmation only)",
7474 "yatra"
7475 ) })
7476 ]
7477 }
7478 )
7479 ] }),
7480 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
7481 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: __$1("File", "yatra") }),
7482 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
7483 item.attachment_url ? /* @__PURE__ */ jsxRuntimeExports.jsx(
7484 "a",
7485 {
7486 href: item.attachment_url,
7487 target: "_blank",
7488 rel: "noreferrer",
7489 className: "flex-shrink-0",
7490 title: __$1("View file", "yatra"),
7491 children: /\.(png|jpe?g|gif|webp|bmp|svg)(\?.*)?$/i.test(
7492 item.attachment_url
7493 ) ? /* @__PURE__ */ jsxRuntimeExports.jsx(
7494 "img",
7495 {
7496 src: item.attachment_url,
7497 alt: item.attachment_title || __$1("Selected file", "yatra"),
7498 className: "w-9 h-9 rounded border border-gray-200 dark:border-gray-700 object-cover bg-white dark:bg-gray-900"
7499 }
7500 ) : /* @__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" }) })
7501 }
7502 ) : /* @__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" }) }),
7503 /* @__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: [
7504 /* @__PURE__ */ jsxRuntimeExports.jsxs(
7505 Button,
7506 {
7507 type: "button",
7508 variant: "outline",
7509 onClick: () => handleDownloadableItemSelectFile(index),
7510 className: "flex items-center gap-2 flex-shrink-0",
7511 children: [
7512 /* @__PURE__ */ jsxRuntimeExports.jsx(Upload, { className: "w-4 h-4" }),
7513 item.attachment_id ? __$1("Change File", "yatra") : __$1("Select File", "yatra")
7514 ]
7515 }
7516 ),
7517 /* @__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")) }),
7518 item.attachment_url && /* @__PURE__ */ jsxRuntimeExports.jsxs(
7519 "a",
7520 {
7521 href: item.attachment_url,
7522 target: "_blank",
7523 rel: "noreferrer",
7524 className: "text-xs text-blue-600 dark:text-blue-400 hover:underline flex items-center gap-1 flex-shrink-0",
7525 children: [
7526 /* @__PURE__ */ jsxRuntimeExports.jsx(Eye, { className: "w-3 h-3" }),
7527 __$1("View", "yatra")
7528 ]
7529 }
7530 )
7531 ] }) })
7532 ] })
7533 ] })
7534 ] }),
7535 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start gap-3", children: [
7536 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 pt-0.5", children: [
7537 /* @__PURE__ */ jsxRuntimeExports.jsx(
7538 "input",
7539 {
7540 type: "checkbox",
7541 checked: item.enabled,
7542 onChange: (e) => handleDownloadableItemChange(
7543 index,
7544 "enabled",
7545 e.target.checked
7546 ),
7547 className: "h-4 w-4"
7548 }
7549 ),
7550 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: __$1("Enabled", "yatra") })
7551 ] }),
7552 /* @__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(
7553 "Controls whether this file appears and is available for download on the trip page. When disabled, the file is completely hidden from users.",
7554 "yatra"
7555 ) }) })
7556 ] })
7557 ]
7558 },
7559 index
7560 )) }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-6 border-2 border-dashed border-gray-300 dark:border-gray-700 rounded-lg text-center", children: [
7561 /* @__PURE__ */ jsxRuntimeExports.jsx(FileText, { className: "w-8 h-8 text-gray-300 dark:text-gray-600 mx-auto mb-2" }),
7562 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-3", children: __$1("No downloads added yet", "yatra") })
7563 ] }),
7564 /* @__PURE__ */ jsxRuntimeExports.jsxs(
7565 Button,
7566 {
7567 type: "button",
7568 variant: "outline",
7569 onClick: handleDownloadableItemAdd,
7570 className: "w-full",
7571 children: [
7572 /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4 mr-2" }),
7573 __$1("Add Download", "yatra")
7574 ]
7575 }
7576 )
7577 ] })
7578 ] })
7579 ] });
7580 case "pricing":
7581 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
7582 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2 mb-2", children: [
7583 /* @__PURE__ */ jsxRuntimeExports.jsx(DollarSign, { className: "w-5 h-5 text-gray-500" }),
7584 /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: __$1("Pricing & Payment", "yatra") }),
7585 /* @__PURE__ */ jsxRuntimeExports.jsx(
7586 Badge,
7587 {
7588 variant: "outline",
7589 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",
7590 children: __$1("Recommended", "yatra")
7591 }
7592 )
7593 ] }),
7594 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-4", children: [
7595 __$1("How much does it cost?", "yatra"),
7596 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block text-xs text-gray-500 dark:text-gray-400 mt-1", children: __$1(
7597 "Set pricing for different traveler types and payment options. Optional for drafts, but adding pricing now makes publishing easier.",
7598 "yatra"
7599 ) })
7600 ] }),
7601 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
7602 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
7603 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-3", children: __$1("Pricing Type", "yatra") }),
7604 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
7605 /* @__PURE__ */ jsxRuntimeExports.jsxs(
7606 "label",
7607 {
7608 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"}`,
7609 children: [
7610 /* @__PURE__ */ jsxRuntimeExports.jsx(
7611 "input",
7612 {
7613 type: "radio",
7614 name: "pricing_type",
7615 value: "regular",
7616 checked: formData.pricing_type === "regular",
7617 onChange: (e) => handleFieldChange("pricing_type", e.target.value),
7618 className: "sr-only"
7619 }
7620 ),
7621 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-1", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col", children: [
7622 /* @__PURE__ */ jsxRuntimeExports.jsx(
7623 "span",
7624 {
7625 className: `block text-sm font-semibold ${formData.pricing_type === "regular" ? "text-blue-900 dark:text-blue-300" : "text-gray-900 dark:text-white"}`,
7626 children: __$1("Regular Pricing", "yatra")
7627 }
7628 ),
7629 /* @__PURE__ */ jsxRuntimeExports.jsx(
7630 "span",
7631 {
7632 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"}`,
7633 children: __$1("Set a single price for all travelers", "yatra")
7634 }
7635 )
7636 ] }) }),
7637 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" }) })
7638 ]
7639 }
7640 ),
7641 /* @__PURE__ */ jsxRuntimeExports.jsxs(
7642 "label",
7643 {
7644 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"}`,
7645 children: [
7646 /* @__PURE__ */ jsxRuntimeExports.jsx(
7647 "input",
7648 {
7649 type: "radio",
7650 name: "pricing_type",
7651 value: "traveler_based",
7652 checked: formData.pricing_type === "traveler_based",
7653 onChange: (e) => handleFieldChange("pricing_type", e.target.value),
7654 className: "sr-only"
7655 }
7656 ),
7657 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex flex-1", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-col", children: [
7658 /* @__PURE__ */ jsxRuntimeExports.jsx(
7659 "span",
7660 {
7661 className: `block text-sm font-semibold ${formData.pricing_type === "traveler_based" ? "text-blue-900 dark:text-blue-300" : "text-gray-900 dark:text-white"}`,
7662 children: __$1("Traveler-Based Pricing", "yatra")
7663 }
7664 ),
7665 /* @__PURE__ */ jsxRuntimeExports.jsx(
7666 "span",
7667 {
7668 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"}`,
7669 children: __$1(
7670 "Set different prices for each traveler category",
7671 "yatra"
7672 )
7673 }
7674 )
7675 ] }) }),
7676 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" }) })
7677 ]
7678 }
7679 )
7680 ] })
7681 ] }),
7682 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: [
7683 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
7684 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: [
7685 __$1("Original Price", "yatra"),
7686 " (",
7687 __$1("Optional", "yatra"),
7688 ")"
7689 ] }),
7690 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
7691 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-500 text-sm", children: getCurrencySymbol(globalCurrency) }),
7692 /* @__PURE__ */ jsxRuntimeExports.jsx(
7693 Input,
7694 {
7695 type: "number",
7696 step: "0.01",
7697 min: "0",
7698 value: formData.original_price,
7699 onChange: (e) => handleFieldChange("original_price", e.target.value),
7700 placeholder: "0.00",
7701 className: `pl-7 ${errors.original_price ? "border-red-500" : ""}`
7702 }
7703 )
7704 ] }),
7705 errors.original_price && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-xs text-red-600", children: errors.original_price })
7706 ] }),
7707 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
7708 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: [
7709 __$1("Discounted Price", "yatra"),
7710 " (",
7711 __$1("Optional", "yatra"),
7712 ")"
7713 ] }),
7714 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
7715 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-500 text-sm", children: getCurrencySymbol(globalCurrency) }),
7716 /* @__PURE__ */ jsxRuntimeExports.jsx(
7717 Input,
7718 {
7719 type: "number",
7720 step: "0.01",
7721 min: "0",
7722 value: formData.discounted_price,
7723 onChange: (e) => handleFieldChange(
7724 "discounted_price",
7725 e.target.value
7726 ),
7727 placeholder: "0.00",
7728 className: `pl-7 ${errors.discounted_price ? "border-red-500" : ""}`
7729 }
7730 )
7731 ] }),
7732 errors.discounted_price && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-1 text-xs text-red-600", children: errors.discounted_price })
7733 ] })
7734 ] }) }),
7735 formData.pricing_type === "traveler_based" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
7736 /* @__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") }) }),
7737 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mb-3", children: __$1(
7738 "Add pricing for traveler categories. Categories are managed in Traveler Categories page.",
7739 "yatra"
7740 ) }),
7741 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: [
7742 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-3", children: __$1("No active traveler categories found.", "yatra") }),
7743 /* @__PURE__ */ jsxRuntimeExports.jsxs(
7744 Button,
7745 {
7746 type: "button",
7747 variant: "outline",
7748 onClick: () => window.location.href = "?page=yatra&subpage=traveler-categories&action=create",
7749 className: "flex items-center gap-2 mx-auto",
7750 children: [
7751 /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4" }),
7752 __$1("Create Category", "yatra")
7753 ]
7754 }
7755 )
7756 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
7757 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
7758 /* @__PURE__ */ jsxRuntimeExports.jsxs(
7759 Button,
7760 {
7761 type: "button",
7762 variant: "outline",
7763 onClick: () => setShowCategorySelector(!showCategorySelector),
7764 className: "flex items-center gap-2",
7765 disabled: activeCategories.filter(
7766 (cat) => !formData.price_types.some(
7767 (pt) => Number(pt.category_id) === Number(cat.id)
7768 )
7769 ).length === 0,
7770 children: [
7771 /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4" }),
7772 __$1("Add Pricing", "yatra")
7773 ]
7774 }
7775 ),
7776 showCategorySelector && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
7777 /* @__PURE__ */ jsxRuntimeExports.jsx(
7778 "div",
7779 {
7780 className: "fixed inset-0 z-10",
7781 onClick: () => setShowCategorySelector(false)
7782 }
7783 ),
7784 /* @__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: [
7785 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs font-medium text-gray-700 dark:text-gray-300 px-3 py-2 mb-1", children: __$1(
7786 "Select a category to add pricing",
7787 "yatra"
7788 ) }),
7789 activeCategories.filter(
7790 (cat) => !formData.price_types.some(
7791 (pt) => Number(pt.category_id) === Number(cat.id)
7792 )
7793 ).length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "px-3 py-4 text-sm text-gray-500 dark:text-gray-400 text-center", children: __$1(
7794 "All categories have pricing added",
7795 "yatra"
7796 ) }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-1", children: activeCategories.filter(
7797 (cat) => !formData.price_types.some(
7798 (pt) => Number(pt.category_id) === Number(cat.id)
7799 )
7800 ).map((category) => {
7801 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;
7802 const pricingMode = category.pricing_mode || "per_person";
7803 const hasMin = category.min_pax !== null && category.min_pax !== void 0;
7804 const hasMax = category.max_pax !== null && category.max_pax !== void 0;
7805 let pricingLabel = "";
7806 if (pricingMode === "per_group") {
7807 if (hasMin && hasMax) {
7808 pricingLabel = `${__$1("Per group", "yatra")} (${category.min_pax}-${category.max_pax})`;
7809 } else if (hasMin) {
7810 pricingLabel = `${__$1("Per group", "yatra")} (${__$1("From", "yatra")} ${category.min_pax})`;
7811 } else if (hasMax) {
7812 pricingLabel = `${__$1("Per group", "yatra")} (${__$1("Up to", "yatra")} ${category.max_pax})`;
7813 } else {
7814 pricingLabel = __$1(
7815 "Per group",
7816 "yatra"
7817 );
7818 }
7819 } else {
7820 pricingLabel = __$1(
7821 "Per person",
7822 "yatra"
7823 );
7824 }
7825 return /* @__PURE__ */ jsxRuntimeExports.jsxs(
7826 "button",
7827 {
7828 type: "button",
7829 onClick: () => {
7830 handlePriceTypeAdd(category.id);
7831 setShowCategorySelector(false);
7832 },
7833 className: "w-full text-left px-3 py-2 rounded-md hover:bg-gray-100 dark:hover:bg-gray-700 transition-colors",
7834 children: [
7835 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "font-medium text-sm text-gray-900 dark:text-white", children: [
7836 category.label,
7837 ageRange && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "ml-2 text-xs font-normal text-gray-500 dark:text-gray-400", children: [
7838 "(",
7839 ageRange,
7840 ")"
7841 ] })
7842 ] }),
7843 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs text-gray-500 dark:text-gray-400 mt-0.5", children: [
7844 category.description,
7845 pricingLabel && /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "ml-1 text-[11px] font-medium text-gray-600 dark:text-gray-300", children: [
7846 "• ",
7847 pricingLabel
7848 ] })
7849 ] })
7850 ]
7851 },
7852 category.id
7853 );
7854 }) })
7855 ] }) })
7856 ] })
7857 ] }),
7858 formData.price_types.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: formData.price_types.map((priceType, index) => {
7859 const category = activeCategories.find(
7860 (cat) => Number(cat.id) === Number(priceType.category_id)
7861 );
7862 if (!category) {
7863 return null;
7864 }
7865 return /* @__PURE__ */ jsxRuntimeExports.jsxs(
7866 "div",
7867 {
7868 className: "p-4 border border-blue-300 dark:border-blue-700 bg-blue-50 dark:bg-blue-900/20 rounded-lg",
7869 children: [
7870 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between mb-3", children: [
7871 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
7872 /* @__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: [
7873 category.label,
7874 (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: [
7875 "(",
7876 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")}` : "",
7877 ")"
7878 ] }),
7879 /* @__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: (() => {
7880 const pricingMode = category.pricing_mode || "per_person";
7881 const hasMin = category.min_pax !== null && category.min_pax !== void 0;
7882 const hasMax = category.max_pax !== null && category.max_pax !== void 0;
7883 if (pricingMode === "per_group") {
7884 if (hasMin && hasMax) {
7885 return `${__$1("Per group", "yatra")} (${category.min_pax}-${category.max_pax})`;
7886 }
7887 if (hasMin) {
7888 return `${__$1("Per group", "yatra")} (${__$1("From", "yatra")} ${category.min_pax})`;
7889 }
7890 if (hasMax) {
7891 return `${__$1("Per group", "yatra")} (${__$1("Up to", "yatra")} ${category.max_pax})`;
7892 }
7893 return __$1("Per group", "yatra");
7894 }
7895 return __$1("Per person", "yatra");
7896 })() })
7897 ] }) }),
7898 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-600 dark:text-gray-400", children: category.description })
7899 ] }),
7900 /* @__PURE__ */ jsxRuntimeExports.jsx(
7901 "button",
7902 {
7903 type: "button",
7904 onClick: () => handlePriceTypeRemove(category.id),
7905 className: "p-1 text-red-600 hover:text-red-700 hover:bg-red-50 dark:hover:bg-red-900/20 rounded transition-colors",
7906 title: __$1("Remove Pricing", "yatra"),
7907 children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-4 h-4" })
7908 }
7909 )
7910 ] }),
7911 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-3", children: [
7912 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
7913 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1.5", children: [
7914 __$1("Original Price", "yatra"),
7915 " (",
7916 __$1("Optional", "yatra"),
7917 ")"
7918 ] }),
7919 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
7920 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-500 text-sm", children: getCurrencySymbol(globalCurrency) }),
7921 /* @__PURE__ */ jsxRuntimeExports.jsx(
7922 Input,
7923 {
7924 type: "number",
7925 step: "0.01",
7926 min: "0",
7927 value: priceType.original_price,
7928 onChange: (e) => handlePriceTypeChange(
7929 category.id,
7930 "original_price",
7931 e.target.value
7932 ),
7933 placeholder: "0.00",
7934 className: `pl-7 ${errors[`price_type_${index}_original`] ? "border-red-500" : ""}`
7935 }
7936 )
7937 ] }),
7938 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`] })
7939 ] }),
7940 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
7941 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-xs font-medium text-gray-700 dark:text-gray-300 mb-1.5", children: [
7942 __$1("Discounted Price", "yatra"),
7943 " (",
7944 __$1("Optional", "yatra"),
7945 ")"
7946 ] }),
7947 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
7948 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-500 text-sm", children: getCurrencySymbol(globalCurrency) }),
7949 /* @__PURE__ */ jsxRuntimeExports.jsx(
7950 Input,
7951 {
7952 type: "number",
7953 step: "0.01",
7954 min: "0",
7955 value: priceType.discounted_price,
7956 onChange: (e) => handlePriceTypeChange(
7957 category.id,
7958 "discounted_price",
7959 e.target.value
7960 ),
7961 placeholder: "0.00",
7962 className: `pl-7 ${errors[`price_type_${index}_discounted`] ? "border-red-500" : ""}`
7963 }
7964 )
7965 ] }),
7966 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`] })
7967 ] })
7968 ] }),
7969 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-3 flex items-center justify-between", children: [
7970 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "inline-flex items-center gap-2 text-xs font-medium text-gray-700 dark:text-gray-300", children: [
7971 /* @__PURE__ */ jsxRuntimeExports.jsx(
7972 "input",
7973 {
7974 type: "checkbox",
7975 checked: Boolean(priceType.is_default),
7976 onChange: (e) => handlePriceTypeDefaultChange(
7977 category.id,
7978 e.target.checked
7979 ),
7980 className: "h-4 w-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500 dark:border-gray-600"
7981 }
7982 ),
7983 __$1(
7984 "Default price (used on page load)",
7985 "yatra"
7986 )
7987 ] }),
7988 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-[11px] text-gray-500 dark:text-gray-400", children: __$1("Traveler-based pricing only", "yatra") })
7989 ] })
7990 ]
7991 },
7992 priceType.category_id
7993 );
7994 }) }),
7995 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: [
7996 /* @__PURE__ */ jsxRuntimeExports.jsx(Tag, { className: "w-8 h-8 text-gray-300 dark:text-gray-600 mx-auto mb-2" }),
7997 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-sm text-gray-600 dark:text-gray-400", children: __$1(
7998 "No pricing added yet. Select a category above to add pricing.",
7999 "yatra"
8000 ) })
8001 ] })
8002 ] }),
8003 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: [
8004 /* @__PURE__ */ jsxRuntimeExports.jsx(AlertCircle, { className: "w-4 h-4" }),
8005 errors.price_types
8006 ] })
8007 ] }),
8008 (() => {
8009 var _a3, _b2;
8010 const flexiblePaymentsEnabled = Boolean(
8011 (_a3 = window == null ? void 0 : window.yatraAdmin) == null ? void 0 : _a3.flexiblePaymentsEnabled
8012 );
8013 const isLocked = !flexiblePaymentsEnabled;
8014 const siteUrl = ((_b2 = window == null ? void 0 : window.yatraAdmin) == null ? void 0 : _b2.siteUrl) || "/wp-admin/admin.php?page=yatra";
8015 const modulesPageUrl = `${siteUrl}/wp-admin/admin.php?page=yatra&subpage=modules`;
8016 const pricingUrl = "https://mantrabrain.com/yatra-pricing/";
8017 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t border-gray-200 dark:border-gray-700 pt-4", children: [
8018 /* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-sm font-semibold text-gray-900 dark:text-white mb-3 flex items-center", children: [
8019 __$1("Deposit & Payment Terms", "yatra"),
8020 isLocked && /* @__PURE__ */ jsxRuntimeExports.jsx(ProBadge, { isProActive: isPro })
8021 ] }),
8022 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: [
8023 /* @__PURE__ */ jsxRuntimeExports.jsx(
8024 "svg",
8025 {
8026 className: "w-4 h-4 mt-0.5 text-purple-500 flex-shrink-0",
8027 fill: "none",
8028 stroke: "currentColor",
8029 viewBox: "0 0 24 24",
8030 "aria-hidden": "true",
8031 children: /* @__PURE__ */ jsxRuntimeExports.jsx(
8032 "path",
8033 {
8034 strokeLinecap: "round",
8035 strokeLinejoin: "round",
8036 strokeWidth: 2,
8037 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"
8038 }
8039 )
8040 }
8041 ),
8042 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex-1", children: isPro ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
8043 __$1(
8044 "Per-trip deposits need the Flexible Payments module.",
8045 "yatra"
8046 ),
8047 " ",
8048 /* @__PURE__ */ jsxRuntimeExports.jsx(
8049 "a",
8050 {
8051 href: modulesPageUrl,
8052 target: "_blank",
8053 rel: "noopener noreferrer",
8054 className: "underline font-medium",
8055 children: __$1("Activate module", "yatra")
8056 }
8057 )
8058 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
8059 __$1(
8060 "Per-trip deposit amount, percentage and custom payment terms are a Yatra Pro feature.",
8061 "yatra"
8062 ),
8063 " ",
8064 /* @__PURE__ */ jsxRuntimeExports.jsx(
8065 "a",
8066 {
8067 href: pricingUrl,
8068 target: "_blank",
8069 rel: "noopener noreferrer",
8070 className: "underline font-medium",
8071 children: __$1("Upgrade to Pro", "yatra")
8072 }
8073 )
8074 ] }) })
8075 ] }),
8076 /* @__PURE__ */ jsxRuntimeExports.jsxs(
8077 "fieldset",
8078 {
8079 disabled: isLocked,
8080 className: isLocked ? "opacity-60 cursor-not-allowed select-none" : "",
8081 "aria-label": isLocked ? __$1(
8082 "Deposit & Payment Terms (Pro feature, disabled)",
8083 "yatra"
8084 ) : void 0,
8085 children: [
8086 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: [
8087 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
8088 /* @__PURE__ */ jsxRuntimeExports.jsx(
8089 "label",
8090 {
8091 htmlFor: "deposit_amount",
8092 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5",
8093 children: __$1("Deposit Amount", "yatra")
8094 }
8095 ),
8096 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
8097 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "absolute left-3 top-1/2 transform -translate-y-1/2 text-gray-500", children: getCurrencySymbol(globalCurrency) }),
8098 /* @__PURE__ */ jsxRuntimeExports.jsx(
8099 Input,
8100 {
8101 id: "deposit_amount",
8102 type: "number",
8103 step: "0.01",
8104 min: "0",
8105 value: formData.deposit_amount,
8106 onChange: (e) => handleFieldChange(
8107 "deposit_amount",
8108 e.target.value
8109 ),
8110 placeholder: "0.00",
8111 className: "pl-7"
8112 }
8113 )
8114 ] })
8115 ] }),
8116 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
8117 /* @__PURE__ */ jsxRuntimeExports.jsx(
8118 "label",
8119 {
8120 htmlFor: "deposit_percentage",
8121 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5",
8122 children: __$1("Deposit Percentage", "yatra")
8123 }
8124 ),
8125 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
8126 /* @__PURE__ */ jsxRuntimeExports.jsx(
8127 Input,
8128 {
8129 id: "deposit_percentage",
8130 type: "number",
8131 step: "0.01",
8132 min: "0",
8133 max: "100",
8134 value: formData.deposit_percentage,
8135 onChange: (e) => handleFieldChange(
8136 "deposit_percentage",
8137 e.target.value
8138 ),
8139 placeholder: "0",
8140 className: "pr-7"
8141 }
8142 ),
8143 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "absolute right-3 top-1/2 transform -translate-y-1/2 text-gray-500", children: "%" })
8144 ] })
8145 ] })
8146 ] }),
8147 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-4", children: [
8148 /* @__PURE__ */ jsxRuntimeExports.jsx(
8149 "label",
8150 {
8151 htmlFor: "payment_terms",
8152 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5",
8153 children: __$1("Payment Terms", "yatra")
8154 }
8155 ),
8156 /* @__PURE__ */ jsxRuntimeExports.jsx(
8157 "textarea",
8158 {
8159 id: "payment_terms",
8160 value: formData.payment_terms,
8161 onChange: (e) => handleFieldChange("payment_terms", e.target.value),
8162 placeholder: __$1(
8163 "e.g., 50% deposit required at booking, balance due 30 days before departure",
8164 "yatra"
8165 ),
8166 rows: 2,
8167 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"
8168 }
8169 )
8170 ] })
8171 ]
8172 }
8173 )
8174 ] });
8175 })()
8176 ] })
8177 ] });
8178 case "attributes":
8179 setCurrentSection("categorization");
8180 return null;
8181 case "itinerary":
8182 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
8183 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2 mb-2", children: [
8184 /* @__PURE__ */ jsxRuntimeExports.jsx(BookOpen, { className: "w-5 h-5 text-gray-500" }),
8185 /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: __$1("Trip Details", "yatra") }),
8186 /* @__PURE__ */ jsxRuntimeExports.jsx(
8187 Badge,
8188 {
8189 variant: "outline",
8190 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",
8191 children: __$1("Recommended", "yatra")
8192 }
8193 )
8194 ] }),
8195 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-4", children: [
8196 __$1("What will travelers experience?", "yatra"),
8197 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block text-xs text-gray-500 dark:text-gray-400 mt-1", children: __$1(
8198 "Build your day-by-day itinerary and list what's included/excluded to set clear expectations.",
8199 "yatra"
8200 ) })
8201 ] }),
8202 /* @__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: [
8203 /* @__PURE__ */ jsxRuntimeExports.jsx(
8204 "button",
8205 {
8206 onClick: () => setTripDetailsTab("itinerary"),
8207 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"}`,
8208 children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
8209 /* @__PURE__ */ jsxRuntimeExports.jsx(Calendar, { className: "w-4 h-4" }),
8210 __$1("Itinerary", "yatra")
8211 ] })
8212 }
8213 ),
8214 /* @__PURE__ */ jsxRuntimeExports.jsx(
8215 "button",
8216 {
8217 onClick: () => setTripDetailsTab("included"),
8218 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"}`,
8219 children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
8220 /* @__PURE__ */ jsxRuntimeExports.jsx(CheckSquare, { className: "w-4 h-4" }),
8221 __$1("Included/Excluded", "yatra")
8222 ] })
8223 }
8224 )
8225 ] }) }),
8226 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-6", children: [
8227 tripDetailsTab === "itinerary" && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
8228 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: [
8229 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs text-blue-900 dark:text-blue-200", children: [
8230 /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "mr-1 inline h-3.5 w-3.5" }),
8231 isEditMode ? __$1(
8232 "Let AI draft a day-by-day plan with real activity blocks — you can edit each day after.",
8233 "yatra"
8234 ) : __$1(
8235 "Save the trip first to enable AI itinerary generation — the agent needs a trip ID to attach days to.",
8236 "yatra"
8237 )
8238 ] }),
8239 /* @__PURE__ */ jsxRuntimeExports.jsxs(
8240 Button,
8241 {
8242 type: "button",
8243 size: "sm",
8244 variant: "outline",
8245 className: "border-blue-300 text-blue-700 hover:bg-blue-100 dark:border-blue-500/60 dark:text-blue-200",
8246 disabled: !isEditMode || !tripId,
8247 onClick: () => {
8248 if (isEditMode && tripId) {
8249 setItineraryBuildOpen(true);
8250 }
8251 },
8252 children: [
8253 /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "mr-1 h-3.5 w-3.5" }),
8254 __$1("Build with AI", "yatra")
8255 ]
8256 }
8257 )
8258 ] }),
8259 /* @__PURE__ */ jsxRuntimeExports.jsx(
8260 ItinerarySection,
8261 {
8262 formData,
8263 isEditMode,
8264 tripId
8265 }
8266 )
8267 ] }),
8268 tripDetailsTab === "included" && /* @__PURE__ */ jsxRuntimeExports.jsx(
8269 IncludedSection,
8270 {
8271 formData,
8272 errors,
8273 handleFieldChange
8274 }
8275 )
8276 ] })
8277 ] });
8278 case "included":
8279 setCurrentSection("itinerary");
8280 setTripDetailsTab("included");
8281 return null;
8282 case "faqs":
8283 setCurrentSection("seo");
8284 return null;
8285 case "seo":
8286 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
8287 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2 mb-2", children: [
8288 /* @__PURE__ */ jsxRuntimeExports.jsx(Search, { className: "w-5 h-5 text-gray-500" }),
8289 /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: __$1("SEO & Marketing", "yatra") }),
8290 /* @__PURE__ */ jsxRuntimeExports.jsx(
8291 Badge,
8292 {
8293 variant: "outline",
8294 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",
8295 children: __$1("Recommended", "yatra")
8296 }
8297 )
8298 ] }),
8299 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-4", children: [
8300 __$1("How will people find & trust this trip?", "yatra"),
8301 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block text-xs text-gray-500 dark:text-gray-400 mt-1", children: __$1(
8302 "Optimize for search engines and answer common questions to build trust and improve discoverability.",
8303 "yatra"
8304 ) })
8305 ] }),
8306 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
8307 /* @__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: [
8308 /* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-sm font-semibold text-gray-900 dark:text-white mb-4 flex items-center gap-2", children: [
8309 /* @__PURE__ */ jsxRuntimeExports.jsx(Search, { className: "w-4 h-4 text-blue-500" }),
8310 __$1("Search Engine Optimization", "yatra")
8311 ] }),
8312 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
8313 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
8314 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-1.5", children: [
8315 /* @__PURE__ */ jsxRuntimeExports.jsx(
8316 "label",
8317 {
8318 htmlFor: "meta_title",
8319 className: "block text-xs font-normal text-gray-500 dark:text-gray-400",
8320 children: __$1("Meta Title", "yatra")
8321 }
8322 ),
8323 /* @__PURE__ */ jsxRuntimeExports.jsx(
8324 AiFieldAffordance,
8325 {
8326 task: "seo-meta-title",
8327 label: __$1("Meta Title", "yatra"),
8328 value: formData.meta_title,
8329 onAccept: (v) => handleFieldChange("meta_title", v.slice(0, 60)),
8330 buildContext: () => buildTripAiContext(formData)
8331 }
8332 )
8333 ] }),
8334 /* @__PURE__ */ jsxRuntimeExports.jsx(
8335 Input,
8336 {
8337 id: "meta_title",
8338 type: "text",
8339 value: formData.meta_title,
8340 onChange: (e) => handleFieldChange("meta_title", e.target.value),
8341 placeholder: formData.title || __$1("Trip Title", "yatra"),
8342 maxLength: 60
8343 }
8344 ),
8345 /* @__PURE__ */ jsxRuntimeExports.jsx(
8346 HelpText,
8347 {
8348 text: __$1(
8349 "Best for search engines: 50-60 characters. Include main keywords.",
8350 "yatra"
8351 ),
8352 className: "mt-1"
8353 }
8354 )
8355 ] }),
8356 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
8357 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-1.5", children: [
8358 /* @__PURE__ */ jsxRuntimeExports.jsx(
8359 "label",
8360 {
8361 htmlFor: "meta_description",
8362 className: "block text-xs font-normal text-gray-500 dark:text-gray-400",
8363 children: __$1("Meta Description", "yatra")
8364 }
8365 ),
8366 /* @__PURE__ */ jsxRuntimeExports.jsx(
8367 AiFieldAffordance,
8368 {
8369 task: "seo-meta-description",
8370 label: __$1("Meta Description", "yatra"),
8371 value: formData.meta_description,
8372 onAccept: (v) => handleFieldChange("meta_description", v.slice(0, 160)),
8373 buildContext: () => buildTripAiContext(formData)
8374 }
8375 )
8376 ] }),
8377 /* @__PURE__ */ jsxRuntimeExports.jsx(
8378 "textarea",
8379 {
8380 id: "meta_description",
8381 value: formData.meta_description,
8382 onChange: (e) => handleFieldChange("meta_description", e.target.value),
8383 rows: 3,
8384 maxLength: 160,
8385 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",
8386 placeholder: __$1(
8387 "Compelling description that includes key travel terms...",
8388 "yatra"
8389 )
8390 }
8391 ),
8392 /* @__PURE__ */ jsxRuntimeExports.jsx(
8393 HelpText,
8394 {
8395 text: __$1(
8396 "160 characters max. Include location, duration, and key features.",
8397 "yatra"
8398 ),
8399 className: "mt-1"
8400 }
8401 )
8402 ] }),
8403 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
8404 /* @__PURE__ */ jsxRuntimeExports.jsx(
8405 "label",
8406 {
8407 htmlFor: "meta_keywords",
8408 className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5",
8409 children: __$1("Meta Keywords", "yatra")
8410 }
8411 ),
8412 /* @__PURE__ */ jsxRuntimeExports.jsx(
8413 Input,
8414 {
8415 id: "meta_keywords",
8416 type: "text",
8417 value: formData.meta_keywords,
8418 onChange: (e) => handleFieldChange("meta_keywords", e.target.value),
8419 placeholder: __$1(
8420 "adventure, travel, tour, guide, experience",
8421 "yatra"
8422 )
8423 }
8424 ),
8425 /* @__PURE__ */ jsxRuntimeExports.jsx(
8426 HelpText,
8427 {
8428 text: __$1(
8429 "Comma-separated keywords. Include location, activities, and travel terms.",
8430 "yatra"
8431 ),
8432 className: "mt-1"
8433 }
8434 )
8435 ] })
8436 ] }),
8437 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
8438 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { children: [
8439 /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __$1("SEO Preview", "yatra") }),
8440 /* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: __$1(
8441 "Preview how your trip appears in search results",
8442 "yatra"
8443 ) })
8444 ] }),
8445 /* @__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: [
8446 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-gray-500 dark:text-gray-400 mb-2", children: __$1("Google Search Result Preview", "yatra") }),
8447 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-2", children: [
8448 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-blue-800 dark:text-blue-400 text-sm font-medium", children: sanitizeTextForSEO(
8449 formData.meta_title || formData.title || "Trip Title",
8450 60
8451 ) }),
8452 /* @__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..." }),
8453 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-gray-600 dark:text-gray-400 text-xs", children: [
8454 window.location.hostname,
8455 "/trip/",
8456 formData.slug || "trip-slug"
8457 ] })
8458 ] })
8459 ] }) })
8460 ] })
8461 ] }),
8462 /* @__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: [
8463 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mb-4 flex items-center justify-between gap-2", children: [
8464 /* @__PURE__ */ jsxRuntimeExports.jsxs("h3", { className: "text-sm font-semibold text-gray-900 dark:text-white flex items-center gap-2", children: [
8465 /* @__PURE__ */ jsxRuntimeExports.jsx(HelpCircle, { className: "w-4 h-4 text-blue-500" }),
8466 __$1("Frequently Asked Questions", "yatra")
8467 ] }),
8468 /* @__PURE__ */ jsxRuntimeExports.jsx(
8469 AiFieldAffordance,
8470 {
8471 task: "trip-faq",
8472 label: __$1("FAQ", "yatra"),
8473 value: (formData.faqs ?? []).map((f) => `Q: ${f.question}
8474 A: ${f.answer}`).join("\n\n"),
8475 onAccept: (raw) => {
8476 const parsed = [];
8477 const blocks = raw.replace(/\r\n?/g, "\n").split(/\n{2,}/);
8478 for (const block of blocks) {
8479 const q = block.match(/^\s*Q[:\.\-]\s*(.+)/im);
8480 const a = block.match(/A[:\.\-]\s*([\s\S]+)/im);
8481 if (q) {
8482 parsed.push({
8483 question: q[1].trim(),
8484 answer: a ? a[1].trim() : ""
8485 });
8486 }
8487 }
8488 if (parsed.length > 0) {
8489 handleFieldChange("faqs", parsed);
8490 }
8491 },
8492 buildContext: () => buildTripAiContext(formData)
8493 }
8494 )
8495 ] }),
8496 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 dark:text-gray-400 mb-4", children: __$1(
8497 "Answer common questions to build trust and reduce support inquiries. FAQs also help with SEO.",
8498 "yatra"
8499 ) }),
8500 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
8501 formData.faqs.map((faq, index) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
8502 "div",
8503 {
8504 className: "border border-gray-200 dark:border-gray-700 rounded-lg p-4 bg-white dark:bg-gray-900",
8505 children: [
8506 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-start justify-between mb-3", children: [
8507 /* @__PURE__ */ jsxRuntimeExports.jsxs("h4", { className: "text-sm font-medium text-gray-900 dark:text-white", children: [
8508 __$1("FAQ", "yatra"),
8509 " ",
8510 index + 1
8511 ] }),
8512 /* @__PURE__ */ jsxRuntimeExports.jsx(
8513 "button",
8514 {
8515 type: "button",
8516 onClick: () => handleFAQRemove(index),
8517 className: "text-red-600 hover:text-red-700",
8518 children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-4 h-4" })
8519 }
8520 )
8521 ] }),
8522 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
8523 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
8524 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: __$1("Question", "yatra") }),
8525 /* @__PURE__ */ jsxRuntimeExports.jsx(
8526 Input,
8527 {
8528 type: "text",
8529 value: faq.question,
8530 onChange: (e) => handleFAQChange(index, "question", e.target.value),
8531 placeholder: __$1("Enter question...", "yatra")
8532 }
8533 )
8534 ] }),
8535 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
8536 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: __$1("Answer", "yatra") }),
8537 /* @__PURE__ */ jsxRuntimeExports.jsx(
8538 "textarea",
8539 {
8540 value: faq.answer,
8541 onChange: (e) => handleFAQChange(index, "answer", e.target.value),
8542 placeholder: __$1("Enter answer...", "yatra"),
8543 rows: 3,
8544 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"
8545 }
8546 )
8547 ] })
8548 ] })
8549 ]
8550 },
8551 index
8552 )),
8553 /* @__PURE__ */ jsxRuntimeExports.jsxs(
8554 Button,
8555 {
8556 type: "button",
8557 variant: "outline",
8558 onClick: handleFAQAdd,
8559 className: "w-full",
8560 children: [
8561 /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4 mr-2" }),
8562 __$1("Add FAQ", "yatra")
8563 ]
8564 }
8565 )
8566 ] })
8567 ] })
8568 ] })
8569 ] });
8570 case "advanced":
8571 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
8572 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-wrap items-center gap-2 mb-2", children: [
8573 /* @__PURE__ */ jsxRuntimeExports.jsx(Settings, { className: "w-5 h-5 text-gray-500" }),
8574 /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: __$1("Lifecycle Management", "yatra") }),
8575 /* @__PURE__ */ jsxRuntimeExports.jsx(
8576 Badge,
8577 {
8578 variant: "outline",
8579 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",
8580 children: __$1("Power Users", "yatra")
8581 }
8582 )
8583 ] }),
8584 /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-gray-600 dark:text-gray-400 mb-4", children: [
8585 __$1("When should this trip be published or archived?", "yatra"),
8586 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "block text-xs text-gray-500 dark:text-gray-400 mt-1", children: __$1(
8587 "Schedule automatic publishing and unpublishing for seasonal trips. Optional but useful for managing trip lifecycles.",
8588 "yatra"
8589 ) })
8590 ] }),
8591 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
8592 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { children: [
8593 /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __$1("Version Control", "yatra") }),
8594 /* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: __$1("Track changes and version history", "yatra") })
8595 ] }),
8596 /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { className: "space-y-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
8597 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-xs font-normal text-gray-500 dark:text-gray-400 mb-1.5", children: __$1("Version", "yatra") }),
8598 /* @__PURE__ */ jsxRuntimeExports.jsx(
8599 Input,
8600 {
8601 type: "number",
8602 value: formData.version,
8603 onChange: (e) => handleFieldChange(
8604 "version",
8605 parseInt(e.target.value) || 1
8606 ),
8607 min: "1",
8608 readOnly: true,
8609 className: "bg-gray-50 dark:bg-gray-800"
8610 }
8611 ),
8612 /* @__PURE__ */ jsxRuntimeExports.jsx(
8613 HelpText,
8614 {
8615 text: __$1(
8616 "Version number is automatically incremented when changes are saved",
8617 "yatra"
8618 ),
8619 className: "mt-2"
8620 }
8621 )
8622 ] }) })
8623 ] }),
8624 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
8625 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { children: [
8626 /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __$1("Scheduled Publishing", "yatra") }),
8627 /* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: __$1(
8628 "Automatically publish or unpublish your trip on specific dates",
8629 "yatra"
8630 ) })
8631 ] }),
8632 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-4", children: [
8633 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
8634 /* @__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") }),
8635 /* @__PURE__ */ jsxRuntimeExports.jsx(
8636 DatePicker,
8637 {
8638 value: formData.scheduled_publish_date,
8639 onChange: (val) => handleFieldChange("scheduled_publish_date", val),
8640 placeholder: __$1("Select date", "yatra")
8641 }
8642 ),
8643 /* @__PURE__ */ jsxRuntimeExports.jsx(
8644 HelpText,
8645 {
8646 text: __$1(
8647 "Trip will be automatically published on this date and time",
8648 "yatra"
8649 ),
8650 className: "mt-2"
8651 }
8652 )
8653 ] }),
8654 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
8655 /* @__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") }),
8656 /* @__PURE__ */ jsxRuntimeExports.jsx(
8657 DatePicker,
8658 {
8659 value: formData.scheduled_unpublish_date,
8660 onChange: (val) => handleFieldChange("scheduled_unpublish_date", val),
8661 placeholder: __$1("Select date", "yatra")
8662 }
8663 ),
8664 /* @__PURE__ */ jsxRuntimeExports.jsx(
8665 HelpText,
8666 {
8667 text: __$1(
8668 "Trip will be automatically unpublished (archived) on this date and time",
8669 "yatra"
8670 ),
8671 className: "mt-2"
8672 }
8673 )
8674 ] })
8675 ] })
8676 ] }),
8677 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
8678 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { children: [
8679 /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __$1("Seasonal Auto-Enable/Disable", "yatra") }),
8680 /* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: __$1(
8681 "Automatically enable or disable trip availability based on seasonal dates",
8682 "yatra"
8683 ) })
8684 ] }),
8685 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-4", children: [
8686 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
8687 /* @__PURE__ */ jsxRuntimeExports.jsx(
8688 "input",
8689 {
8690 type: "checkbox",
8691 id: "seasonal_auto_enable",
8692 checked: formData.seasonal_auto_enable,
8693 onChange: (e) => handleFieldChange(
8694 "seasonal_auto_enable",
8695 e.target.checked
8696 ),
8697 className: "w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500"
8698 }
8699 ),
8700 /* @__PURE__ */ jsxRuntimeExports.jsx(
8701 "label",
8702 {
8703 htmlFor: "seasonal_auto_enable",
8704 className: "text-sm font-medium text-gray-700 dark:text-gray-300",
8705 children: __$1("Enable seasonal auto-management", "yatra")
8706 }
8707 )
8708 ] }),
8709 formData.seasonal_auto_enable && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
8710 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
8711 /* @__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") }),
8712 /* @__PURE__ */ jsxRuntimeExports.jsx(
8713 DatePicker,
8714 {
8715 value: formData.seasonal_enable_date,
8716 onChange: (val) => handleFieldChange("seasonal_enable_date", val),
8717 placeholder: __$1("Select date", "yatra")
8718 }
8719 ),
8720 /* @__PURE__ */ jsxRuntimeExports.jsx(
8721 HelpText,
8722 {
8723 text: __$1(
8724 "Trip will become available for booking on this date",
8725 "yatra"
8726 ),
8727 className: "mt-2"
8728 }
8729 )
8730 ] }),
8731 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
8732 /* @__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") }),
8733 /* @__PURE__ */ jsxRuntimeExports.jsx(
8734 DatePicker,
8735 {
8736 value: formData.seasonal_disable_date,
8737 onChange: (val) => handleFieldChange("seasonal_disable_date", val),
8738 placeholder: __$1("Select date", "yatra")
8739 }
8740 ),
8741 /* @__PURE__ */ jsxRuntimeExports.jsx(
8742 HelpText,
8743 {
8744 text: __$1(
8745 "Trip will become unavailable for booking on this date",
8746 "yatra"
8747 ),
8748 className: "mt-2"
8749 }
8750 )
8751 ] })
8752 ] })
8753 ] })
8754 ] }),
8755 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
8756 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardHeader, { children: [
8757 /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __$1("Frontend Tabs Management", "yatra") }),
8758 /* @__PURE__ */ jsxRuntimeExports.jsx(CardDescription, { children: __$1(
8759 "Manage which tabs appear on the trip single page and in what order. Enable or disable tabs, customize labels, and reorder them.",
8760 "yatra"
8761 ) })
8762 ] }),
8763 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { children: [
8764 /* @__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(
8765 "div",
8766 {
8767 draggable: true,
8768 onDragStart: (e) => handleDragStart(e, tab.id),
8769 onDragOver: handleDragOver,
8770 onDragEnter: () => handleDragEnter(tab.id),
8771 onDragLeave: handleDragLeave,
8772 onDrop: (e) => handleDrop(e, tab.id),
8773 onDragEnd: handleDragEnd,
8774 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" : ""}`,
8775 children: [
8776 tab.content_type === "custom" && /* @__PURE__ */ jsxRuntimeExports.jsx(
8777 Button,
8778 {
8779 type: "button",
8780 variant: "ghost",
8781 size: "sm",
8782 onClick: () => handleTabRemove(tab.id),
8783 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",
8784 title: __$1("Delete tab", "yatra"),
8785 children: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "w-5 h-5" })
8786 }
8787 ),
8788 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3 mb-3", children: [
8789 /* @__PURE__ */ jsxRuntimeExports.jsx(GripVertical, { className: "w-6 h-6 text-gray-400 cursor-grab active:cursor-grabbing" }),
8790 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
8791 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-2", children: [
8792 /* @__PURE__ */ jsxRuntimeExports.jsx(
8793 Input,
8794 {
8795 type: "text",
8796 value: tab.label,
8797 onChange: (e) => handleTabLabelChange(tab.id, e.target.value),
8798 className: "text-sm font-medium flex-1",
8799 disabled: !tab.enabled,
8800 placeholder: __$1("Tab Label", "yatra")
8801 }
8802 ),
8803 /* @__PURE__ */ jsxRuntimeExports.jsx(Badge, { variant: "outline", className: "text-xs", children: tab.content_type })
8804 ] }),
8805 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mb-2", children: tab.enabled ? /* @__PURE__ */ jsxRuntimeExports.jsx(
8806 IconPicker,
8807 {
8808 value: tab.icon || null,
8809 onChange: (value) => handleTabIconChange(tab.id, value),
8810 label: __$1("Tab Icon", "yatra"),
8811 helpText: __$1(
8812 "Select an icon or upload an image for this tab",
8813 "yatra"
8814 ),
8815 size: "sm"
8816 }
8817 ) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "opacity-50", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
8818 IconPicker,
8819 {
8820 value: tab.icon || null,
8821 onChange: () => {
8822 },
8823 label: __$1("Tab Icon", "yatra"),
8824 helpText: __$1(
8825 "Enable this tab to select an icon",
8826 "yatra"
8827 ),
8828 size: "sm"
8829 }
8830 ) }) }),
8831 tab.content_type === "custom" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "mt-2", children: [
8832 /* @__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") }),
8833 /* @__PURE__ */ jsxRuntimeExports.jsx(
8834 "textarea",
8835 {
8836 value: tab.custom_content || "",
8837 onChange: (e) => handleTabCustomContentChange(
8838 tab.id,
8839 e.target.value
8840 ),
8841 rows: 3,
8842 disabled: !tab.enabled,
8843 placeholder: __$1(
8844 "Enter custom content for this tab...",
8845 "yatra"
8846 ),
8847 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"
8848 }
8849 )
8850 ] }),
8851 tab.content_type !== "custom" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-2", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
8852 Select,
8853 {
8854 value: tab.content_type,
8855 onChange: (e) => handleTabContentTypeChange(
8856 tab.id,
8857 e.target.value
8858 ),
8859 disabled: !tab.enabled,
8860 className: "text-xs",
8861 children: [
8862 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "overview", children: __$1("Overview", "yatra") }),
8863 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "itinerary", children: __$1("Itinerary", "yatra") }),
8864 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "included_excluded", children: __$1("Included", "yatra") }),
8865 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "location", children: __$1("Location", "yatra") }),
8866 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "important_info", children: __$1("Important Info", "yatra") }),
8867 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "downloads", children: __$1("Downloads", "yatra") }),
8868 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "faq", children: __$1("FAQ", "yatra") }),
8869 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "trip_story", children: __$1("Story", "yatra") }),
8870 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "what_makes_special", children: __$1("Special", "yatra") }),
8871 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "testimonials", children: __$1("Testimonials", "yatra") }),
8872 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "custom", children: __$1("Custom Content", "yatra") })
8873 ]
8874 }
8875 ) })
8876 ] }),
8877 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2", children: [
8878 /* @__PURE__ */ jsxRuntimeExports.jsx(
8879 Button,
8880 {
8881 type: "button",
8882 variant: "ghost",
8883 size: "sm",
8884 onClick: () => handleTabMove(tab.id, "up"),
8885 disabled: index === 0,
8886 className: "h-10 w-10 p-0",
8887 title: __$1("Move up", "yatra"),
8888 children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronUp, { className: "w-5 h-5" })
8889 }
8890 ),
8891 /* @__PURE__ */ jsxRuntimeExports.jsx(
8892 Button,
8893 {
8894 type: "button",
8895 variant: "ghost",
8896 size: "sm",
8897 onClick: () => handleTabMove(tab.id, "down"),
8898 disabled: index === formData.frontend_tabs.length - 1,
8899 className: "h-10 w-10 p-0",
8900 title: __$1("Move down", "yatra"),
8901 children: /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "w-5 h-5" })
8902 }
8903 ),
8904 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [
8905 /* @__PURE__ */ jsxRuntimeExports.jsx(
8906 "input",
8907 {
8908 type: "checkbox",
8909 checked: tab.enabled,
8910 onChange: () => handleTabToggle(tab.id),
8911 className: "w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500"
8912 }
8913 ),
8914 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: tab.enabled ? __$1("Enabled", "yatra") : __$1("Disabled", "yatra") })
8915 ] })
8916 ] })
8917 ] })
8918 ]
8919 },
8920 tab.id
8921 )) }),
8922 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "mt-4 pt-4 border-t border-gray-200 dark:border-gray-700", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
8923 Button,
8924 {
8925 type: "button",
8926 variant: "outline",
8927 onClick: handleTabAdd,
8928 className: "w-full",
8929 children: [
8930 /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4 mr-2" }),
8931 __$1("Add Custom Tab", "yatra")
8932 ]
8933 }
8934 ) })
8935 ] })
8936 ] })
8937 ] });
8938 default:
8939 return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-center py-8 text-gray-500", children: __$1("Section content coming soon...", "yatra") });
8940 }
8941 };
8942 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1 min-h-0 flex flex-col bg-white dark:bg-gray-900 overflow-hidden", children: [
8943 /* @__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: [
8944 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-4 min-w-0 flex-1", children: [
8945 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "min-w-0", children: [
8946 /* @__PURE__ */ jsxRuntimeExports.jsx("h1", { className: "text-base font-semibold text-gray-900 dark:text-white truncate", children: formData.title || __$1("New Trip", "yatra") }),
8947 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex items-center gap-2 mt-1", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
8948 Badge,
8949 {
8950 variant: "outline",
8951 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"}`,
8952 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")
8953 }
8954 ) })
8955 ] }),
8956 !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(
8957 "button",
8958 {
8959 onClick: () => setSimpleMode(!simpleMode),
8960 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",
8961 title: simpleMode ? __$1("Switch to Advanced Mode", "yatra") : __$1("Switch to Simple Mode", "yatra"),
8962 children: [
8963 /* @__PURE__ */ jsxRuntimeExports.jsx(
8964 Lightbulb,
8965 {
8966 className: `w-3.5 h-3.5 ${simpleMode ? "text-yellow-500" : ""}`
8967 }
8968 ),
8969 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: simpleMode ? __$1("Simple", "yatra") : __$1("Advanced", "yatra") })
8970 ]
8971 }
8972 ) }),
8973 !isEditMode && /* @__PURE__ */ jsxRuntimeExports.jsxs(
8974 Button,
8975 {
8976 variant: "ghost",
8977 size: "sm",
8978 onClick: () => {
8979 showToast(
8980 __$1("Guided tour feature coming soon!", "yatra"),
8981 "info"
8982 );
8983 },
8984 className: "text-xs text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-200 flex-shrink-0",
8985 children: [
8986 /* @__PURE__ */ jsxRuntimeExports.jsx(BookOpen, { className: "w-3.5 h-3.5 mr-1" }),
8987 __$1("Take a Tour", "yatra")
8988 ]
8989 }
8990 ),
8991 !isEditMode && /* @__PURE__ */ jsxRuntimeExports.jsxs(
8992 Button,
8993 {
8994 variant: "ghost",
8995 size: "sm",
8996 onClick: handleFillDummyData,
8997 className: "text-xs text-gray-600 dark:text-gray-400 hover:text-gray-900 dark:hover:text-gray-200 flex-shrink-0",
8998 title: __$1("Fill form with dummy data", "yatra"),
8999 children: [
9000 /* @__PURE__ */ jsxRuntimeExports.jsx(Database, { className: "w-3.5 h-3.5 mr-1" }),
9001 __$1("Fill Dummy Data", "yatra"),
9002 " (",
9003 dummyDataIndex + 1,
9004 "/",
9005 dummyTripsData.length,
9006 ")"
9007 ]
9008 }
9009 )
9010 ] }),
9011 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [
9012 isEditMode && /* @__PURE__ */ jsxRuntimeExports.jsxs(
9013 Button,
9014 {
9015 variant: "outline",
9016 onClick: () => setShowRevisionsDialog(true),
9017 className: "text-gray-700 dark:text-gray-300 border-gray-300 dark:border-gray-600 hover:bg-gray-50 dark:hover:bg-gray-700",
9018 children: [
9019 /* @__PURE__ */ jsxRuntimeExports.jsx(History, { className: "w-4 h-4 mr-2" }),
9020 __$1("Revisions", "yatra")
9021 ]
9022 }
9023 ),
9024 isAiEligible() && isAiModuleEnabled() && /* @__PURE__ */ jsxRuntimeExports.jsxs(
9025 Button,
9026 {
9027 type: "button",
9028 onClick: () => {
9029 setAiModalMode("all");
9030 setAiModalOpen(true);
9031 },
9032 className: "bg-gradient-to-r from-purple-600 to-indigo-600 text-white border-0 hover:from-purple-700 hover:to-indigo-700",
9033 title: __$1(
9034 "Generate description, itinerary, included items, SEO meta, and more — from this trip's facts.",
9035 "yatra"
9036 ),
9037 children: [
9038 /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "w-4 h-4 mr-2" }),
9039 __$1("Auto-fill with AI", "yatra")
9040 ]
9041 }
9042 ),
9043 /* @__PURE__ */ jsxRuntimeExports.jsxs(
9044 Button,
9045 {
9046 variant: "outline",
9047 onClick: handlePreview,
9048 className: "text-gray-700 dark:text-gray-300 border-gray-300 dark:border-gray-600 hover:bg-gray-50 dark:hover:bg-gray-700",
9049 disabled: !formData.slug,
9050 children: [
9051 /* @__PURE__ */ jsxRuntimeExports.jsx(Eye, { className: "w-4 h-4 mr-2" }),
9052 __$1("Preview", "yatra")
9053 ]
9054 }
9055 ),
9056 /* @__PURE__ */ jsxRuntimeExports.jsxs(
9057 Button,
9058 {
9059 variant: "outline",
9060 onClick: handleSaveDraft,
9061 disabled: isSubmitting,
9062 className: "text-gray-700 dark:text-gray-300 border-gray-300 dark:border-gray-600 hover:bg-gray-50 dark:hover:bg-gray-700",
9063 children: [
9064 /* @__PURE__ */ jsxRuntimeExports.jsx(Save, { className: "w-4 h-4 mr-2" }),
9065 isEditMode ? __$1("Update Draft", "yatra") : __$1("Save Draft", "yatra")
9066 ]
9067 }
9068 ),
9069 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative group", children: [
9070 /* @__PURE__ */ jsxRuntimeExports.jsx(
9071 Button,
9072 {
9073 onClick: handlePublish,
9074 disabled: isSubmitting,
9075 className: "bg-blue-600 hover:bg-blue-700 text-white border-0 relative",
9076 children: isSubmitting ? /* @__PURE__ */ jsxRuntimeExports.jsx(Loader2, { className: "w-4 h-4 mr-2 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
9077 /* @__PURE__ */ jsxRuntimeExports.jsx(Send, { className: "w-4 h-4 mr-2" }),
9078 isEditMode ? __$1("Update Trip", "yatra") : __$1("Publish Trip", "yatra"),
9079 /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "w-4 h-4 ml-2" })
9080 ] })
9081 }
9082 ),
9083 !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: [
9084 /* @__PURE__ */ jsxRuntimeExports.jsx(
9085 "button",
9086 {
9087 type: "button",
9088 onClick: () => {
9089 handleFieldChange("status", "draft");
9090 handleSaveDraft();
9091 },
9092 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",
9093 children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: __$1("Save as Draft", "yatra") })
9094 }
9095 ),
9096 /* @__PURE__ */ jsxRuntimeExports.jsx(
9097 "button",
9098 {
9099 type: "button",
9100 onClick: () => {
9101 handleFieldChange("status", "review");
9102 handlePublish();
9103 },
9104 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",
9105 children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: __$1("Save for Review", "yatra") })
9106 }
9107 ),
9108 /* @__PURE__ */ jsxRuntimeExports.jsx(
9109 "button",
9110 {
9111 type: "button",
9112 onClick: () => {
9113 handleFieldChange("status", "approved");
9114 handlePublish();
9115 },
9116 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",
9117 children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: __$1("Mark as Approved", "yatra") })
9118 }
9119 ),
9120 /* @__PURE__ */ jsxRuntimeExports.jsxs(
9121 "button",
9122 {
9123 type: "button",
9124 onClick: handlePublish,
9125 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",
9126 children: [
9127 /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "w-4 h-4" }),
9128 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: isEditMode ? __$1("Update & Publish", "yatra") : __$1("Publish", "yatra") })
9129 ]
9130 }
9131 ),
9132 /* @__PURE__ */ jsxRuntimeExports.jsx(
9133 "button",
9134 {
9135 type: "button",
9136 onClick: () => {
9137 handleFieldChange("status", "suspended");
9138 handlePublish();
9139 },
9140 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",
9141 children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: __$1("Suspend", "yatra") })
9142 }
9143 ),
9144 /* @__PURE__ */ jsxRuntimeExports.jsx(
9145 "button",
9146 {
9147 type: "button",
9148 onClick: () => {
9149 handleFieldChange("status", "archived");
9150 handlePublish();
9151 },
9152 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",
9153 children: /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: __$1("Archive", "yatra") })
9154 }
9155 )
9156 ] }) })
9157 ] })
9158 ] })
9159 ] }),
9160 /* @__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: [
9161 /* @__PURE__ */ jsxRuntimeExports.jsxs(
9162 Button,
9163 {
9164 variant: "outline",
9165 size: "default",
9166 onClick: goToPreviousSection,
9167 disabled: currentStepIndex === 0,
9168 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",
9169 children: [
9170 /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronLeft, { className: "w-4 h-4" }),
9171 __$1("Previous", "yatra")
9172 ]
9173 }
9174 ),
9175 /* @__PURE__ */ jsxRuntimeExports.jsxs(
9176 Button,
9177 {
9178 variant: "outline",
9179 size: "default",
9180 onClick: goToNextSection,
9181 disabled: currentStepIndex >= allSections.length - 1,
9182 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",
9183 children: [
9184 __$1("Next", "yatra"),
9185 /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronRight, { className: "w-4 h-4" })
9186 ]
9187 }
9188 )
9189 ] }) }),
9190 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex flex-1 min-h-0 p-0", children: [
9191 /* @__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: [
9192 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
9193 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-3 px-1", children: [
9194 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 flex-1", children: [
9195 /* @__PURE__ */ jsxRuntimeExports.jsx(Box, { className: "w-3.5 h-3.5 text-red-500 dark:text-red-400 flex-shrink-0" }),
9196 /* @__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") })
9197 ] }),
9198 /* @__PURE__ */ jsxRuntimeExports.jsx(
9199 Badge,
9200 {
9201 variant: "outline",
9202 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",
9203 children: __$1("Must Complete", "yatra")
9204 }
9205 )
9206 ] }),
9207 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-0.5", children: essentialsSections.map((section, index) => {
9208 const Icon = section.icon;
9209 const isActive = currentSection === section.id;
9210 const isNext = !section.completed && essentialsSections.slice(0, index).every((s) => s.completed);
9211 return /* @__PURE__ */ jsxRuntimeExports.jsxs(
9212 "button",
9213 {
9214 type: "button",
9215 onClick: () => setCurrentSection(section.id),
9216 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"}`,
9217 children: [
9218 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [
9219 /* @__PURE__ */ jsxRuntimeExports.jsx(
9220 "span",
9221 {
9222 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"}`,
9223 children: index + 1
9224 }
9225 ),
9226 /* @__PURE__ */ jsxRuntimeExports.jsx(
9227 Icon,
9228 {
9229 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"}`
9230 }
9231 )
9232 ] }),
9233 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "flex-1 min-w-0 break-words leading-snug", children: [
9234 section.label,
9235 section.required && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ml-1 text-[9px] text-red-500", children: "*" })
9236 ] }),
9237 section.hasErrors && /* @__PURE__ */ jsxRuntimeExports.jsx(
9238 "span",
9239 {
9240 className: "flex-shrink-0 w-2 h-2 bg-red-500 rounded-full",
9241 title: __$1("This section has errors", "yatra")
9242 }
9243 )
9244 ]
9245 },
9246 section.id
9247 );
9248 }) })
9249 ] }),
9250 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
9251 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-3 px-1", children: [
9252 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 flex-1", children: [
9253 /* @__PURE__ */ jsxRuntimeExports.jsx(BookOpen, { className: "w-3.5 h-3.5 text-blue-500 dark:text-blue-400 flex-shrink-0" }),
9254 /* @__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") })
9255 ] }),
9256 /* @__PURE__ */ jsxRuntimeExports.jsx(
9257 Badge,
9258 {
9259 variant: "outline",
9260 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",
9261 children: __$1("Recommended", "yatra")
9262 }
9263 )
9264 ] }),
9265 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-0.5", children: detailsSections.map((section, index) => {
9266 const Icon = section.icon;
9267 const isActive = currentSection === section.id;
9268 const sectionNumber = essentialsSections.length + index + 1;
9269 return /* @__PURE__ */ jsxRuntimeExports.jsxs(
9270 "button",
9271 {
9272 type: "button",
9273 onClick: () => setCurrentSection(section.id),
9274 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"}`,
9275 children: [
9276 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [
9277 /* @__PURE__ */ jsxRuntimeExports.jsx(
9278 "span",
9279 {
9280 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"}`,
9281 children: sectionNumber
9282 }
9283 ),
9284 /* @__PURE__ */ jsxRuntimeExports.jsx(
9285 Icon,
9286 {
9287 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"}`
9288 }
9289 )
9290 ] }),
9291 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 min-w-0 break-words leading-snug", children: section.label }),
9292 section.hasErrors && /* @__PURE__ */ jsxRuntimeExports.jsx(
9293 "span",
9294 {
9295 className: "flex-shrink-0 w-2 h-2 bg-red-500 rounded-full",
9296 title: __$1("This section has errors", "yatra")
9297 }
9298 )
9299 ]
9300 },
9301 section.id
9302 );
9303 }) })
9304 ] }),
9305 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
9306 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-3 px-1", children: [
9307 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 flex-1", children: [
9308 /* @__PURE__ */ jsxRuntimeExports.jsx(BarChart3, { className: "w-3.5 h-3.5 text-purple-500 dark:text-purple-400 flex-shrink-0" }),
9309 /* @__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") })
9310 ] }),
9311 /* @__PURE__ */ jsxRuntimeExports.jsx(
9312 Badge,
9313 {
9314 variant: "outline",
9315 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",
9316 children: __$1("Optional", "yatra")
9317 }
9318 )
9319 ] }),
9320 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-0.5", children: optimizationSections.map((section, index) => {
9321 const Icon = section.icon;
9322 const isActive = currentSection === section.id;
9323 const sectionNumber = essentialsSections.length + detailsSections.length + index + 1;
9324 return /* @__PURE__ */ jsxRuntimeExports.jsxs(
9325 "button",
9326 {
9327 type: "button",
9328 onClick: () => setCurrentSection(section.id),
9329 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"}`,
9330 children: [
9331 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [
9332 /* @__PURE__ */ jsxRuntimeExports.jsx(
9333 "span",
9334 {
9335 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"}`,
9336 children: sectionNumber
9337 }
9338 ),
9339 /* @__PURE__ */ jsxRuntimeExports.jsx(
9340 Icon,
9341 {
9342 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"}`
9343 }
9344 )
9345 ] }),
9346 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 min-w-0 break-words leading-snug", children: section.label }),
9347 section.hasErrors && /* @__PURE__ */ jsxRuntimeExports.jsx(
9348 "span",
9349 {
9350 className: "flex-shrink-0 w-2 h-2 bg-red-500 rounded-full",
9351 title: __$1("This section has errors", "yatra")
9352 }
9353 )
9354 ]
9355 },
9356 section.id
9357 );
9358 }) })
9359 ] }),
9360 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "pb-12", children: [
9361 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-3 px-1", children: [
9362 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 flex-1", children: [
9363 /* @__PURE__ */ jsxRuntimeExports.jsx(Settings, { className: "w-3.5 h-3.5 text-gray-400 dark:text-gray-500 flex-shrink-0" }),
9364 /* @__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") })
9365 ] }),
9366 /* @__PURE__ */ jsxRuntimeExports.jsx(
9367 Badge,
9368 {
9369 variant: "outline",
9370 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",
9371 children: __$1("Power Users", "yatra")
9372 }
9373 )
9374 ] }),
9375 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-0.5", children: advancedSections.map((section, index) => {
9376 const Icon = section.icon;
9377 const isActive = currentSection === section.id;
9378 const sectionNumber = essentialsSections.length + detailsSections.length + optimizationSections.length + index + 1;
9379 return /* @__PURE__ */ jsxRuntimeExports.jsxs(
9380 "button",
9381 {
9382 type: "button",
9383 onClick: () => setCurrentSection(section.id),
9384 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"}`,
9385 children: [
9386 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 flex-shrink-0", children: [
9387 /* @__PURE__ */ jsxRuntimeExports.jsx(
9388 "span",
9389 {
9390 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"}`,
9391 children: sectionNumber
9392 }
9393 ),
9394 /* @__PURE__ */ jsxRuntimeExports.jsx(
9395 Icon,
9396 {
9397 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"}`
9398 }
9399 )
9400 ] }),
9401 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 min-w-0 break-words leading-snug", children: section.label })
9402 ]
9403 },
9404 section.id
9405 );
9406 }) })
9407 ] })
9408 ] }) }),
9409 /* @__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: [
9410 errors.submit && /* @__PURE__ */ jsxRuntimeExports.jsx(Alert, { variant: "error", className: "mb-4", children: errors.submit }),
9411 renderSectionContent()
9412 ] }) })
9413 ] }),
9414 showHighlightModal && /* @__PURE__ */ jsxRuntimeExports.jsx(
9415 "div",
9416 {
9417 className: "fixed inset-0 z-50 flex items-center justify-center bg-black/50",
9418 onClick: () => setShowHighlightModal(false),
9419 children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
9420 "div",
9421 {
9422 className: "bg-white dark:bg-gray-800 rounded-lg p-6 max-w-md w-full mx-4 shadow-xl",
9423 onClick: (e) => e.stopPropagation(),
9424 children: [
9425 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-semibold text-gray-900 dark:text-white mb-4", children: __$1("Add Highlight", "yatra") }),
9426 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
9427 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
9428 /* @__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") }),
9429 /* @__PURE__ */ jsxRuntimeExports.jsx(
9430 Input,
9431 {
9432 type: "text",
9433 value: modalInput.text,
9434 onChange: (e) => setModalInput({ ...modalInput, text: e.target.value }),
9435 placeholder: __$1("e.g., Private guide included", "yatra"),
9436 autoFocus: true,
9437 onKeyDown: (e) => {
9438 if (e.key === "Enter") {
9439 e.preventDefault();
9440 handleHighlightSave();
9441 }
9442 }
9443 }
9444 ),
9445 /* @__PURE__ */ jsxRuntimeExports.jsx(
9446 HelpText,
9447 {
9448 text: __$1(
9449 'Keep it short and impactful. Examples: "All meals included", "Skip-the-line tickets", "Free airport transfer"',
9450 "yatra"
9451 ),
9452 className: "mt-2"
9453 }
9454 )
9455 ] }),
9456 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-end gap-2", children: [
9457 /* @__PURE__ */ jsxRuntimeExports.jsx(
9458 Button,
9459 {
9460 variant: "outline",
9461 onClick: () => setShowHighlightModal(false),
9462 children: __$1("Cancel", "yatra")
9463 }
9464 ),
9465 /* @__PURE__ */ jsxRuntimeExports.jsx(
9466 Button,
9467 {
9468 onClick: handleHighlightSave,
9469 disabled: !modalInput.text.trim(),
9470 children: __$1("Add", "yatra")
9471 }
9472 )
9473 ] })
9474 ] })
9475 ]
9476 }
9477 )
9478 }
9479 ),
9480 showRevisionsDialog && /* @__PURE__ */ jsxRuntimeExports.jsx(
9481 "div",
9482 {
9483 className: "fixed inset-0 z-[9998] flex items-center justify-center bg-black/50 backdrop-blur-sm",
9484 onClick: () => setShowRevisionsDialog(false),
9485 children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
9486 Card,
9487 {
9488 className: "w-full max-w-2xl max-h-[80vh] mx-4 shadow-xl overflow-hidden flex flex-col",
9489 onClick: (e) => e.stopPropagation(),
9490 children: [
9491 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { className: "pb-3 flex-shrink-0", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
9492 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardTitle, { className: "text-lg flex items-center gap-2", children: [
9493 /* @__PURE__ */ jsxRuntimeExports.jsx(History, { className: "w-5 h-5" }),
9494 __$1("Trip Revisions", "yatra")
9495 ] }),
9496 /* @__PURE__ */ jsxRuntimeExports.jsx(
9497 "button",
9498 {
9499 onClick: () => setShowRevisionsDialog(false),
9500 className: "text-gray-400 hover:text-gray-600 dark:hover:text-gray-300 transition-colors",
9501 "aria-label": __$1("Close", "yatra"),
9502 children: /* @__PURE__ */ jsxRuntimeExports.jsx(X, { className: "w-5 h-5" })
9503 }
9504 )
9505 ] }) }),
9506 /* @__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(
9507 "div",
9508 {
9509 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",
9510 onClick: () => handleRevisionClick(revision.id),
9511 children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
9512 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex-1", children: [
9513 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-2 mb-1", children: [
9514 /* @__PURE__ */ jsxRuntimeExports.jsxs(Badge, { variant: "outline", children: [
9515 "v",
9516 revision.version
9517 ] }),
9518 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "text-sm font-medium text-gray-900 dark:text-white", children: [
9519 __$1("Revision", "yatra"),
9520 " ",
9521 revision.version
9522 ] })
9523 ] }),
9524 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-xs text-gray-500 dark:text-gray-400", children: [
9525 __$1("Created by", "yatra"),
9526 " ",
9527 revision.created_by_name,
9528 " •",
9529 " ",
9530 new Date(revision.created_at).toLocaleString()
9531 ] })
9532 ] }),
9533 /* @__PURE__ */ jsxRuntimeExports.jsx(
9534 Button,
9535 {
9536 variant: "outline",
9537 size: "sm",
9538 onClick: (e) => {
9539 e.stopPropagation();
9540 handleRevisionClick(revision.id);
9541 },
9542 children: __$1("Use This Revision", "yatra")
9543 }
9544 )
9545 ] })
9546 },
9547 revision.id
9548 )) }) })
9549 ]
9550 }
9551 )
9552 }
9553 ),
9554 /* @__PURE__ */ jsxRuntimeExports.jsx(
9555 ConfirmationDialog,
9556 {
9557 isOpen: showRevisionConfirm,
9558 onClose: () => {
9559 setShowRevisionConfirm(false);
9560 setSelectedRevisionId(null);
9561 },
9562 onConfirm: handleRevisionConfirm,
9563 title: __$1("Use This Revision?", "yatra"),
9564 message: __$1(
9565 "Do you want to use this revision? This will replace all current form data with the revision data.",
9566 "yatra"
9567 ),
9568 confirmText: __$1("Yes, Use This Revision", "yatra"),
9569 cancelText: __$1("Cancel", "yatra"),
9570 variant: "info",
9571 isLoading: false
9572 }
9573 ),
9574 /* @__PURE__ */ jsxRuntimeExports.jsx(
9575 Modal,
9576 {
9577 isOpen: showLandmarkDialog,
9578 onClose: () => {
9579 setShowLandmarkDialog(false);
9580 setLandmarkInput("");
9581 },
9582 title: __$1("Add Landmark", "yatra"),
9583 description: __$1(
9584 "Enter the name of the landmark or point of interest",
9585 "yatra"
9586 ),
9587 size: "sm",
9588 hideFooter: false,
9589 footer: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2 justify-end", children: [
9590 /* @__PURE__ */ jsxRuntimeExports.jsx(
9591 Button,
9592 {
9593 variant: "outline",
9594 onClick: () => {
9595 setShowLandmarkDialog(false);
9596 setLandmarkInput("");
9597 },
9598 children: __$1("Cancel", "yatra")
9599 }
9600 ),
9601 /* @__PURE__ */ jsxRuntimeExports.jsxs(
9602 Button,
9603 {
9604 onClick: () => {
9605 if (landmarkInput.trim()) {
9606 handleFieldChange("landmarks", [
9607 ...formData.landmarks,
9608 landmarkInput.trim()
9609 ]);
9610 setLandmarkInput("");
9611 setShowLandmarkDialog(false);
9612 }
9613 },
9614 disabled: !landmarkInput.trim(),
9615 children: [
9616 /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4 mr-2" }),
9617 __$1("Add Landmark", "yatra")
9618 ]
9619 }
9620 )
9621 ] }),
9622 children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
9623 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
9624 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: __$1("Landmark Name", "yatra") }),
9625 /* @__PURE__ */ jsxRuntimeExports.jsx(
9626 Input,
9627 {
9628 type: "text",
9629 value: landmarkInput,
9630 onChange: (e) => setLandmarkInput(e.target.value),
9631 placeholder: __$1(
9632 "e.g., Eiffel Tower, Central Park, Grand Canyon",
9633 "yatra"
9634 ),
9635 className: "w-full",
9636 autoFocus: true,
9637 onKeyDown: (e) => {
9638 if (e.key === "Enter" && landmarkInput.trim()) {
9639 handleFieldChange("landmarks", [
9640 ...formData.landmarks,
9641 landmarkInput.trim()
9642 ]);
9643 setLandmarkInput("");
9644 setShowLandmarkDialog(false);
9645 }
9646 }
9647 }
9648 )
9649 ] }),
9650 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "text-xs text-gray-500 dark:text-gray-400", children: __$1(
9651 "Examples: Famous monuments, natural landmarks, historical sites, viewpoints, or points of interest that travelers will visit during this trip.",
9652 "yatra"
9653 ) })
9654 ] })
9655 }
9656 ),
9657 /* @__PURE__ */ jsxRuntimeExports.jsx(
9658 AutoFillTripModal,
9659 {
9660 open: aiModalOpen,
9661 onClose: () => setAiModalOpen(false),
9662 buildContext: () => buildTripAiContext(formData),
9663 itineraryOnly: aiModalMode === "itinerary",
9664 onFieldsAccepted: (updates) => {
9665 for (const [key, value] of Object.entries(updates)) {
9666 handleFieldChange(key, value);
9667 }
9668 }
9669 }
9670 ),
9671 isEditMode && tripId && /* @__PURE__ */ jsxRuntimeExports.jsx(
9672 BuildItineraryModal,
9673 {
9674 open: itineraryBuildOpen,
9675 onClose: () => setItineraryBuildOpen(false),
9676 tripId,
9677 tripName: (formData == null ? void 0 : formData.title) || __$1("Trip", "yatra"),
9678 tripDurationDays: Number(formData == null ? void 0 : formData.duration_days) || 0,
9679 onApplied: () => {
9680 setItineraryBuildOpen(false);
9681 }
9682 }
9683 )
9684 ] });
9685 };
9686 export {
9687 TripForm as default
9688 };
9689 //# sourceMappingURL=TripForm-DEQpXvzy.js.map
9690