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 / TripConsentForm-C4az7Muo.js

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

1,658 lines 78.1 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 import { r as reactExports, v as useQueryClient, u as useQuery, w as useMutation, j as jsxRuntimeExports, F as FileSignature, D as ArrowLeft, S as Sparkles, E as Loader2, aW as Save, c5 as Hash, a_ as Phone, d as Mail, q as Calendar, L as List, bH as CheckSquare, c6 as AlignLeft, c7 as Type, bc as GripVertical, bd as ChevronUp, y as ChevronDown, aO as Trash2, ax as Plus, a6 as React } from "./react-vendor-CithbthY.js";
2 import { B as Button, C as Card, f as CardHeader, d as CardContent, P as PageHeader, g as CardTitle, S as Select } from "../../admin/dist/js/app.js";
3 import { u as useToast, _ as __, I as Input, a as apiClient } from "./index-Dec_weLB.js";
4 import { A as ApplicableTripSelector } from "./ApplicableTripSelector-BZ25j59n.js";
5 const defaultFormData = {
6 name: "",
7 description: "",
8 status: "publish",
9 require_signature: true,
10 require_initials: false,
11 applicable_to: "all",
12 send_to: "all_travelers",
13 trip_ids: [],
14 send_before_days: 7,
15 reminder_days: "3,1",
16 expiry_hours: null,
17 fields: [],
18 content_blocks: []
19 };
20 const fieldTypeIcons = {
21 text: Type,
22 textarea: AlignLeft,
23 checkbox: CheckSquare,
24 select: List,
25 date: Calendar,
26 email: Mail,
27 phone: Phone,
28 number: Hash
29 };
30 const isModuleAvailable = () => {
31 const yatraAdmin = window == null ? void 0 : window.yatraAdmin;
32 return Boolean((yatraAdmin == null ? void 0 : yatraAdmin.isPro) && (yatraAdmin == null ? void 0 : yatraAdmin.tripConsentEnabled));
33 };
34 const generateId = () => `field_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
35 const SignaturePadPreview = ({
36 id,
37 placeholder,
38 onContentChange,
39 canvasRef: externalCanvasRef
40 }) => {
41 const internalCanvasRef = React.useRef(null);
42 const canvasRef = externalCanvasRef || internalCanvasRef;
43 const [isDrawing, setIsDrawing] = React.useState(false);
44 const [hasContent, setHasContent] = React.useState(false);
45 const updateContent = (value) => {
46 setHasContent(value);
47 onContentChange == null ? void 0 : onContentChange(value);
48 };
49 const getCoordinates = (e) => {
50 const canvas = canvasRef.current;
51 if (!canvas) return { x: 0, y: 0 };
52 const rect = canvas.getBoundingClientRect();
53 if ("touches" in e) {
54 return {
55 x: e.touches[0].clientX - rect.left,
56 y: e.touches[0].clientY - rect.top
57 };
58 }
59 return {
60 x: e.clientX - rect.left,
61 y: e.clientY - rect.top
62 };
63 };
64 const startDrawing = (e) => {
65 const canvas = canvasRef.current;
66 const ctx = canvas == null ? void 0 : canvas.getContext("2d");
67 if (!ctx) return;
68 setIsDrawing(true);
69 updateContent(true);
70 const { x, y } = getCoordinates(e);
71 ctx.beginPath();
72 ctx.moveTo(x, y);
73 };
74 const draw = (e) => {
75 if (!isDrawing) return;
76 const canvas = canvasRef.current;
77 const ctx = canvas == null ? void 0 : canvas.getContext("2d");
78 if (!ctx) return;
79 const { x, y } = getCoordinates(e);
80 ctx.lineTo(x, y);
81 ctx.strokeStyle = "#1f2937";
82 ctx.lineWidth = 2;
83 ctx.lineCap = "round";
84 ctx.lineJoin = "round";
85 ctx.stroke();
86 };
87 const stopDrawing = () => {
88 setIsDrawing(false);
89 };
90 const clearCanvas = () => {
91 const canvas = canvasRef.current;
92 const ctx = canvas == null ? void 0 : canvas.getContext("2d");
93 if (!ctx || !canvas) return;
94 ctx.clearRect(0, 0, canvas.width, canvas.height);
95 updateContent(false);
96 };
97 React.useEffect(() => {
98 const canvas = canvasRef.current;
99 if (canvas) {
100 const rect = canvas.getBoundingClientRect();
101 canvas.width = rect.width;
102 canvas.height = rect.height;
103 }
104 }, []);
105 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "relative", children: [
106 /* @__PURE__ */ jsxRuntimeExports.jsx(
107 "canvas",
108 {
109 ref: canvasRef,
110 id,
111 className: "w-full h-32 border-2 border-gray-300 dark:border-gray-600 rounded-lg bg-white cursor-crosshair touch-none",
112 onMouseDown: startDrawing,
113 onMouseMove: draw,
114 onMouseUp: stopDrawing,
115 onMouseLeave: stopDrawing,
116 onTouchStart: startDrawing,
117 onTouchMove: draw,
118 onTouchEnd: stopDrawing
119 }
120 ),
121 !hasContent && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "absolute inset-0 flex items-center justify-center pointer-events-none", children: /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-400 text-sm", children: placeholder }) }),
122 hasContent && /* @__PURE__ */ jsxRuntimeExports.jsx(
123 "button",
124 {
125 type: "button",
126 onClick: clearCanvas,
127 className: "absolute top-2 right-2 px-2 py-1 text-xs bg-gray-100 hover:bg-gray-200 dark:bg-gray-700 dark:hover:bg-gray-600 text-gray-600 dark:text-gray-300 rounded",
128 children: __("Clear")
129 }
130 )
131 ] });
132 };
133 const TripConsentForm = () => {
134 const [formData, setFormData] = reactExports.useState(defaultFormData);
135 const [errors, setErrors] = reactExports.useState({});
136 const [activeTab, setActiveTab] = reactExports.useState("general");
137 const [expandedField, setExpandedField] = reactExports.useState(null);
138 const [testEmail, setTestEmail] = reactExports.useState("");
139 const { showToast } = useToast();
140 const queryClient = useQueryClient();
141 const urlParams = new URLSearchParams(window.location.search);
142 const formId = urlParams.get("id");
143 const isEditMode = !!formId;
144 const { data: existingFormResponse, isLoading: isLoadingForm } = useQuery({
145 queryKey: ["consent-form", formId],
146 queryFn: async () => {
147 const response = await apiClient.get(`/consent-forms/${formId}`);
148 return response;
149 },
150 enabled: isEditMode && isModuleAvailable()
151 });
152 reactExports.useEffect(() => {
153 var _a, _b;
154 const existingForm = (existingFormResponse == null ? void 0 : existingFormResponse.data) || existingFormResponse;
155 if (existingForm && existingForm.id) {
156 const fields = ((_a = existingForm.form_config) == null ? void 0 : _a.fields) || [];
157 const sortedFields = [...fields].sort(
158 (a, b) => (a.order ?? 0) - (b.order ?? 0)
159 );
160 const contentBlocks = ((_b = existingForm.form_config) == null ? void 0 : _b.content_blocks) || [];
161 const sortedContentBlocks = [...contentBlocks].sort(
162 (a, b) => (a.order ?? 0) - (b.order ?? 0)
163 );
164 setFormData({
165 ...defaultFormData,
166 id: existingForm.id,
167 name: existingForm.name || "",
168 description: existingForm.description || "",
169 status: existingForm.status || "publish",
170 require_signature: existingForm.require_signature ?? true,
171 require_initials: existingForm.require_initials ?? false,
172 applicable_to: existingForm.applicable_to || "all",
173 send_to: existingForm.send_to || "all_travelers",
174 trip_ids: existingForm.trip_ids || [],
175 send_before_days: existingForm.send_before_days || 7,
176 reminder_days: existingForm.reminder_days || "3,1",
177 expiry_hours: existingForm.expiry_hours || null,
178 fields: sortedFields,
179 content_blocks: sortedContentBlocks
180 });
181 }
182 }, [existingFormResponse]);
183 const saveMutation = useMutation({
184 mutationFn: async (data) => {
185 const fieldsWithOrder = data.fields.map((field, index) => ({
186 id: field.id,
187 type: field.type,
188 label: field.label || "",
189 placeholder: field.placeholder || "",
190 required: field.required ?? false,
191 enabled: field.enabled ?? true,
192 order: index,
193 width: field.width || "full",
194 options: field.options || void 0
195 }));
196 const contentBlocksWithOrder = data.content_blocks.map(
197 (block, index) => ({
198 id: block.id,
199 type: block.type,
200 title: block.title || "",
201 content: block.content || "",
202 order: index
203 })
204 );
205 const payload = {
206 name: data.name,
207 description: data.description,
208 status: data.status,
209 require_signature: data.require_signature,
210 require_initials: data.require_initials,
211 applicable_to: data.applicable_to,
212 send_to: data.send_to,
213 trip_ids: data.trip_ids,
214 send_before_days: data.send_before_days,
215 reminder_days: data.reminder_days,
216 expiry_hours: data.expiry_hours,
217 form_config: {
218 fields: fieldsWithOrder,
219 content_blocks: contentBlocksWithOrder
220 }
221 };
222 if (isEditMode) {
223 return await apiClient.put(`/consent-forms/${formId}`, payload);
224 }
225 return await apiClient.post("/consent-forms", payload);
226 },
227 onSuccess: (response) => {
228 var _a, _b;
229 queryClient.invalidateQueries({ queryKey: ["consent-forms"] });
230 showToast(
231 isEditMode ? __("Consent form updated successfully") : __("Consent form created successfully"),
232 "success"
233 );
234 if (isEditMode) {
235 return;
236 }
237 const newId = ((_a = response == null ? void 0 : response.data) == null ? void 0 : _a.id) ?? (response == null ? void 0 : response.id) ?? ((_b = response == null ? void 0 : response.form) == null ? void 0 : _b.id);
238 if (!newId) {
239 navigateBack();
240 return;
241 }
242 const params = new URLSearchParams(window.location.search);
243 params.set("action", "edit");
244 params.set("id", String(newId));
245 params.set("subpage", "trips");
246 params.set("tab", "trip-consent");
247 window.history.pushState(
248 {},
249 "",
250 `${window.location.pathname}?${params.toString()}`
251 );
252 window.dispatchEvent(new PopStateEvent("popstate"));
253 },
254 onError: (error) => {
255 showToast((error == null ? void 0 : error.message) || __("Failed to save consent form"), "error");
256 }
257 });
258 const sendTestEmailMutation = useMutation({
259 mutationFn: async (email) => {
260 const payload = {
261 email,
262 form_data: {
263 ...formData,
264 fields: formData.fields.map((field, index) => ({
265 ...field,
266 order: index
267 })),
268 content_blocks: formData.content_blocks.map((block, index) => ({
269 ...block,
270 order: index
271 }))
272 }
273 };
274 return await apiClient.post("/consent-forms/send-test-email", payload);
275 },
276 onSuccess: () => {
277 showToast(__("Test email sent successfully"), "success");
278 setTestEmail("");
279 },
280 onError: (error) => {
281 showToast((error == null ? void 0 : error.message) || __("Failed to send test email"), "error");
282 }
283 });
284 const handleSendTestEmail = () => {
285 if (!testEmail) {
286 showToast(__("Please enter an email address"), "warning");
287 return;
288 }
289 sendTestEmailMutation.mutate(testEmail);
290 };
291 const navigateBack = () => {
292 const params = new URLSearchParams(window.location.search);
293 params.delete("action");
294 params.delete("id");
295 params.set("subpage", "trips");
296 params.set("tab", "trip-consent");
297 window.history.pushState({}, "", `${window.location.pathname}?${params}`);
298 window.dispatchEvent(new PopStateEvent("popstate"));
299 };
300 const handleSubmit = (e) => {
301 e.preventDefault();
302 const newErrors = {};
303 if (!formData.name.trim()) {
304 newErrors.name = __("Form name is required");
305 }
306 if (Object.keys(newErrors).length > 0) {
307 setErrors(newErrors);
308 return;
309 }
310 saveMutation.mutate(formData);
311 };
312 const addField = (type) => {
313 const newField = {
314 id: generateId(),
315 type,
316 label: "",
317 placeholder: "",
318 required: false,
319 enabled: true,
320 order: formData.fields.length,
321 width: "full",
322 options: type === "select" ? [{ value: "", label: "" }] : void 0
323 };
324 setFormData({ ...formData, fields: [...formData.fields, newField] });
325 setExpandedField(newField.id);
326 };
327 const updateField = (fieldId, updates) => {
328 setFormData({
329 ...formData,
330 fields: formData.fields.map(
331 (f) => f.id === fieldId ? { ...f, ...updates } : f
332 )
333 });
334 };
335 const removeField = (fieldId) => {
336 setFormData({
337 ...formData,
338 fields: formData.fields.filter((f) => f.id !== fieldId)
339 });
340 };
341 const moveField = (fromIndex, toIndex) => {
342 const newFields = [...formData.fields];
343 const [movedField] = newFields.splice(fromIndex, 1);
344 newFields.splice(toIndex, 0, movedField);
345 const reorderedFields = newFields.map((field, index) => ({
346 ...field,
347 order: index
348 }));
349 setFormData({ ...formData, fields: reorderedFields });
350 };
351 const [draggedFieldIndex, setDraggedFieldIndex] = reactExports.useState(
352 null
353 );
354 const [dragOverFieldIndex, setDragOverFieldIndex] = reactExports.useState(
355 null
356 );
357 const handleDragStart = (e, index) => {
358 setDraggedFieldIndex(index);
359 e.dataTransfer.effectAllowed = "move";
360 e.dataTransfer.setData("text/plain", index.toString());
361 };
362 const handleDragOver = (e, index) => {
363 e.preventDefault();
364 e.dataTransfer.dropEffect = "move";
365 if (draggedFieldIndex !== null && draggedFieldIndex !== index) {
366 setDragOverFieldIndex(index);
367 }
368 };
369 const handleDragLeave = () => {
370 setDragOverFieldIndex(null);
371 };
372 const handleDrop = (e, toIndex) => {
373 e.preventDefault();
374 if (draggedFieldIndex !== null && draggedFieldIndex !== toIndex) {
375 moveField(draggedFieldIndex, toIndex);
376 }
377 setDraggedFieldIndex(null);
378 setDragOverFieldIndex(null);
379 };
380 const handleDragEnd = () => {
381 setDraggedFieldIndex(null);
382 setDragOverFieldIndex(null);
383 };
384 const addContentBlock = (type) => {
385 const newBlock = {
386 id: generateId(),
387 type,
388 title: "",
389 content: "",
390 order: formData.content_blocks.length
391 };
392 setFormData({
393 ...formData,
394 content_blocks: [...formData.content_blocks, newBlock]
395 });
396 };
397 const updateContentBlock = (blockId, updates) => {
398 setFormData({
399 ...formData,
400 content_blocks: formData.content_blocks.map(
401 (b) => b.id === blockId ? { ...b, ...updates } : b
402 )
403 });
404 };
405 const removeContentBlock = (blockId) => {
406 setFormData({
407 ...formData,
408 content_blocks: formData.content_blocks.filter((b) => b.id !== blockId)
409 });
410 };
411 const generateSimpleForm = () => {
412 const simpleFields = [
413 {
414 id: generateId(),
415 type: "text",
416 label: __("Full Name"),
417 placeholder: __("Enter your full legal name"),
418 required: true,
419 enabled: true,
420 order: 0,
421 width: "half"
422 },
423 {
424 id: generateId(),
425 type: "email",
426 label: __("Email Address"),
427 placeholder: __("Enter your email address"),
428 required: true,
429 enabled: true,
430 order: 1,
431 width: "half"
432 },
433 {
434 id: generateId(),
435 type: "phone",
436 label: __("Phone Number"),
437 placeholder: __("Enter your phone number"),
438 required: true,
439 enabled: true,
440 order: 2,
441 width: "half"
442 },
443 {
444 id: generateId(),
445 type: "date",
446 label: __("Date of Birth"),
447 placeholder: "",
448 required: true,
449 enabled: true,
450 order: 3,
451 width: "half"
452 },
453 {
454 id: generateId(),
455 type: "text",
456 label: __("Emergency Contact Name"),
457 placeholder: __("Name of emergency contact"),
458 required: true,
459 enabled: true,
460 order: 4,
461 width: "half"
462 },
463 {
464 id: generateId(),
465 type: "phone",
466 label: __("Emergency Contact Phone"),
467 placeholder: __("Emergency contact phone number"),
468 required: true,
469 enabled: true,
470 order: 5,
471 width: "half"
472 },
473 {
474 id: generateId(),
475 type: "textarea",
476 label: __("Medical Conditions or Allergies"),
477 placeholder: __(
478 "Please list any medical conditions, allergies, or dietary restrictions we should be aware of"
479 ),
480 required: false,
481 enabled: true,
482 order: 6,
483 width: "full"
484 },
485 {
486 id: generateId(),
487 type: "checkbox",
488 label: __(
489 "I confirm that I am physically fit to participate in this trip"
490 ),
491 placeholder: "",
492 required: true,
493 enabled: true,
494 order: 7,
495 width: "full"
496 }
497 ];
498 const simpleContentBlocks = [
499 {
500 id: generateId(),
501 type: "heading",
502 title: __("Trip Participation Agreement"),
503 content: "",
504 order: 0
505 },
506 {
507 id: generateId(),
508 type: "paragraph",
509 title: __("Introduction"),
510 content: __(
511 "By signing this consent form, you acknowledge that you have read, understood, and agree to the terms and conditions outlined below for your participation in the trip."
512 ),
513 order: 1
514 },
515 {
516 id: generateId(),
517 type: "terms",
518 title: __("Assumption of Risk"),
519 content: __(
520 "I understand that participation in this trip involves inherent risks, including but not limited to physical injury, illness, property damage, and other hazards. I voluntarily assume all risks associated with my participation and agree to hold harmless the trip organizers, guides, and affiliated parties from any liability arising from my participation."
521 ),
522 order: 2
523 },
524 {
525 id: generateId(),
526 type: "terms",
527 title: __("Medical Authorization"),
528 content: __(
529 "In the event of a medical emergency, I authorize the trip organizers to seek and consent to medical treatment on my behalf. I understand that I am responsible for any medical expenses incurred during the trip."
530 ),
531 order: 3
532 },
533 {
534 id: generateId(),
535 type: "terms",
536 title: __("Photo/Video Release"),
537 content: __(
538 "I grant permission to the trip organizers to use photographs and videos taken during the trip for promotional and marketing purposes without compensation."
539 ),
540 order: 4
541 },
542 {
543 id: generateId(),
544 type: "paragraph",
545 title: __("Agreement"),
546 content: __(
547 "By signing below, I confirm that I have read and understood this consent form, that I am at least 18 years of age (or have parental/guardian consent), and that I agree to abide by all rules and instructions provided by the trip organizers."
548 ),
549 order: 5
550 }
551 ];
552 setFormData({
553 ...formData,
554 name: formData.name || __("Trip Liability Waiver"),
555 description: formData.description || __("Standard liability waiver and consent form for trip participants"),
556 require_signature: true,
557 require_initials: true,
558 fields: simpleFields,
559 content_blocks: simpleContentBlocks
560 });
561 showToast(
562 __("Simple consent form generated! Review and customize as needed."),
563 "success"
564 );
565 };
566 if (!isModuleAvailable()) {
567 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-8 text-center", children: [
568 /* @__PURE__ */ jsxRuntimeExports.jsx(FileSignature, { className: "w-16 h-16 mx-auto text-gray-400 mb-4" }),
569 /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-xl font-semibold text-gray-900 dark:text-white mb-2", children: __("Trip Consent is a Premium Feature") }),
570 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-600 dark:text-gray-400 mb-4", children: __("Upgrade to Yatra Pro to create and manage consent forms.") }),
571 /* @__PURE__ */ jsxRuntimeExports.jsx(
572 Button,
573 {
574 onClick: () => window.open(
575 "https://wpyatra.com/pricing?module=trip-consent",
576 "_blank"
577 ),
578 children: __("Upgrade to Pro")
579 }
580 )
581 ] });
582 }
583 if (isLoadingForm) {
584 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
585 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between", children: [
586 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
587 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-8 w-48 bg-gray-200 dark:bg-gray-700 rounded animate-pulse mb-2" }),
588 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 w-72 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" })
589 ] }),
590 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
591 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 w-24 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }),
592 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 w-32 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" })
593 ] })
594 ] }),
595 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex gap-2 border-b border-gray-200 dark:border-gray-700 pb-2", children: [1, 2, 3, 4, 5].map((i) => /* @__PURE__ */ jsxRuntimeExports.jsx(
596 "div",
597 {
598 className: "h-10 w-24 bg-gray-200 dark:bg-gray-700 rounded animate-pulse"
599 },
600 i
601 )) }),
602 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-6", children: [
603 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "lg:col-span-2 space-y-6", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
604 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-6 w-32 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }) }),
605 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-4", children: [
606 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
607 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 w-24 bg-gray-200 dark:bg-gray-700 rounded animate-pulse mb-2" }),
608 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 w-full bg-gray-200 dark:bg-gray-700 rounded animate-pulse" })
609 ] }),
610 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
611 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 w-28 bg-gray-200 dark:bg-gray-700 rounded animate-pulse mb-2" }),
612 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-24 w-full bg-gray-200 dark:bg-gray-700 rounded animate-pulse" })
613 ] })
614 ] })
615 ] }) }),
616 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
617 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
618 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-6 w-20 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }) }),
619 /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 w-full bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }) })
620 ] }),
621 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
622 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-6 w-40 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }) }),
623 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-3", children: [
624 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
625 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 w-4 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }),
626 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 w-32 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" })
627 ] }),
628 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
629 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 w-4 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }),
630 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-4 w-28 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" })
631 ] })
632 ] })
633 ] }),
634 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
635 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-6 w-40 bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }) }),
636 /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { className: "space-y-3", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "h-10 w-full bg-gray-200 dark:bg-gray-700 rounded animate-pulse" }) })
637 ] })
638 ] })
639 ] })
640 ] });
641 }
642 return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
643 /* @__PURE__ */ jsxRuntimeExports.jsx(
644 PageHeader,
645 {
646 title: isEditMode ? __("Edit Consent Form") : __("Create Consent Form"),
647 description: isEditMode ? __("Update your consent form settings and fields.") : __("Create a new consent form for your trips."),
648 actions: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-3", children: [
649 /* @__PURE__ */ jsxRuntimeExports.jsxs(Button, { variant: "outline", onClick: navigateBack, children: [
650 /* @__PURE__ */ jsxRuntimeExports.jsx(ArrowLeft, { className: "w-4 h-4 mr-2" }),
651 __("Back")
652 ] }),
653 !isEditMode && formData.fields.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs(
654 Button,
655 {
656 type: "button",
657 variant: "outline",
658 onClick: generateSimpleForm,
659 className: "border-blue-300 text-blue-600 hover:bg-blue-50 dark:border-blue-700 dark:hover:bg-blue-900/20",
660 children: [
661 /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "w-4 h-4 mr-2" }),
662 __("Generate Simple Form")
663 ]
664 }
665 ),
666 /* @__PURE__ */ jsxRuntimeExports.jsxs(
667 Button,
668 {
669 onClick: handleSubmit,
670 disabled: saveMutation.isPending,
671 className: "bg-blue-600 hover:bg-blue-700",
672 children: [
673 saveMutation.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsx(Loader2, { className: "w-4 h-4 mr-2 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Save, { className: "w-4 h-4 mr-2" }),
674 isEditMode ? __("Update Form") : __("Create Form")
675 ]
676 }
677 )
678 ] })
679 }
680 ),
681 /* @__PURE__ */ jsxRuntimeExports.jsxs("form", { onSubmit: handleSubmit, children: [
682 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "border-b border-gray-200 dark:border-gray-700 mb-6", children: /* @__PURE__ */ jsxRuntimeExports.jsx("nav", { className: "flex gap-6", children: ["general", "fields", "content", "settings", "preview"].map((tab) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
683 "button",
684 {
685 type: "button",
686 onClick: () => setActiveTab(tab),
687 className: `pb-3 text-sm font-medium border-b-2 transition-colors ${activeTab === tab ? "border-blue-600 text-blue-600" : "border-transparent text-gray-500 hover:text-gray-700 dark:text-gray-400 dark:hover:text-gray-300"}`,
688 children: [
689 tab === "general" && __("General"),
690 tab === "fields" && __("Form Fields"),
691 tab === "content" && __("Content Blocks"),
692 tab === "settings" && __("Settings"),
693 tab === "preview" && __("Preview")
694 ]
695 },
696 tab
697 )) }) }),
698 activeTab === "general" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-3 gap-6", children: [
699 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "lg:col-span-2 space-y-6", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
700 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __("Form Details") }) }),
701 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-4", children: [
702 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
703 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", children: [
704 __("Form Name"),
705 " ",
706 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-500", children: "*" })
707 ] }),
708 /* @__PURE__ */ jsxRuntimeExports.jsx(
709 Input,
710 {
711 value: formData.name,
712 onChange: (e) => setFormData({ ...formData, name: e.target.value }),
713 placeholder: __("e.g., Liability Waiver"),
714 className: errors.name ? "border-red-500" : ""
715 }
716 ),
717 errors.name && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-red-500 text-sm mt-1", children: errors.name })
718 ] }),
719 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
720 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", children: __("Description") }),
721 /* @__PURE__ */ jsxRuntimeExports.jsx(
722 "textarea",
723 {
724 value: formData.description,
725 onChange: (e) => setFormData({
726 ...formData,
727 description: e.target.value
728 }),
729 placeholder: __(
730 "Brief description of this consent form..."
731 ),
732 rows: 3,
733 className: "w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white"
734 }
735 )
736 ] })
737 ] })
738 ] }) }),
739 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6", children: [
740 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
741 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __("Status") }) }),
742 /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
743 Select,
744 {
745 value: formData.status,
746 onChange: (e) => setFormData({
747 ...formData,
748 status: e.target.value
749 }),
750 children: [
751 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "publish", children: __("Published") }),
752 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "draft", children: __("Draft") }),
753 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "archived", children: __("Archived") }),
754 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "trash", children: __("Trash") })
755 ]
756 }
757 ) })
758 ] }),
759 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
760 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __("Signature Requirements") }) }),
761 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-3", children: [
762 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex items-center gap-3 cursor-pointer", children: [
763 /* @__PURE__ */ jsxRuntimeExports.jsx(
764 "input",
765 {
766 type: "checkbox",
767 checked: formData.require_signature,
768 onChange: (e) => setFormData({
769 ...formData,
770 require_signature: e.target.checked
771 }),
772 className: "w-4 h-4 rounded border-gray-300"
773 }
774 ),
775 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: __("Require signature") })
776 ] }),
777 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex items-center gap-3 cursor-pointer", children: [
778 /* @__PURE__ */ jsxRuntimeExports.jsx(
779 "input",
780 {
781 type: "checkbox",
782 checked: formData.require_initials,
783 onChange: (e) => setFormData({
784 ...formData,
785 require_initials: e.target.checked
786 }),
787 className: "w-4 h-4 rounded border-gray-300"
788 }
789 ),
790 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm text-gray-700 dark:text-gray-300", children: __("Require initials") })
791 ] })
792 ] })
793 ] }),
794 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
795 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { className: "pb-2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { className: "text-base", children: __("Applicable To", "yatra") }) }),
796 /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(
797 ApplicableTripSelector,
798 {
799 value: formData.applicable_to,
800 onValueChange: (val) => setFormData({ ...formData, applicable_to: val }),
801 selectedTripIds: formData.trip_ids,
802 onTripIdsChange: (ids) => setFormData({ ...formData, trip_ids: ids }),
803 description: __(
804 "Choose whether this consent form applies to all trips or specific ones."
805 ),
806 helperText: __(
807 "Trips shown with ID for quick identification."
808 )
809 }
810 ) })
811 ] })
812 ] })
813 ] }),
814 activeTab === "fields" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-6", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
815 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardTitle, { className: "flex items-center justify-between", children: [
816 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: __("Form Fields") }),
817 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex gap-2", children: Object.entries(fieldTypeIcons).map(([type, Icon]) => /* @__PURE__ */ jsxRuntimeExports.jsx(
818 Button,
819 {
820 type: "button",
821 variant: "outline",
822 size: "sm",
823 onClick: () => addField(type),
824 title: type,
825 children: /* @__PURE__ */ jsxRuntimeExports.jsx(Icon, { className: "w-4 h-4" })
826 },
827 type
828 )) })
829 ] }) }),
830 /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { children: formData.fields.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center py-8 text-gray-500", children: [
831 /* @__PURE__ */ jsxRuntimeExports.jsx(Type, { className: "w-12 h-12 mx-auto mb-3 opacity-50" }),
832 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: __(
833 "No fields added yet. Click the buttons above to add fields."
834 ) })
835 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-3", children: formData.fields.map((field, index) => {
836 var _a;
837 const FieldIcon = fieldTypeIcons[field.type] || Type;
838 const isExpanded = expandedField === field.id;
839 const isDragging = draggedFieldIndex === index;
840 const isDragOver = dragOverFieldIndex === index;
841 return /* @__PURE__ */ jsxRuntimeExports.jsxs(
842 "div",
843 {
844 draggable: true,
845 onDragStart: (e) => handleDragStart(e, index),
846 onDragOver: (e) => handleDragOver(e, index),
847 onDragLeave: handleDragLeave,
848 onDrop: (e) => handleDrop(e, index),
849 onDragEnd: handleDragEnd,
850 className: `border rounded-lg transition-all ${isDragging ? "opacity-50 border-blue-400 bg-blue-50 dark:bg-blue-900/20" : isDragOver ? "border-blue-500 border-2 bg-blue-50 dark:bg-blue-900/10" : "border-gray-200 dark:border-gray-700"}`,
851 children: [
852 /* @__PURE__ */ jsxRuntimeExports.jsxs(
853 "div",
854 {
855 className: "flex items-center gap-3 p-3 cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800",
856 onClick: () => setExpandedField(isExpanded ? null : field.id),
857 children: [
858 /* @__PURE__ */ jsxRuntimeExports.jsx(GripVertical, { className: "w-4 h-4 text-gray-400 cursor-grab active:cursor-grabbing" }),
859 /* @__PURE__ */ jsxRuntimeExports.jsx(FieldIcon, { className: "w-4 h-4 text-blue-600" }),
860 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "flex-1 text-sm font-medium", children: field.label || __("Untitled Field") }),
861 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-xs text-gray-500 capitalize", children: field.type }),
862 isExpanded ? /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronUp, { className: "w-4 h-4" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ChevronDown, { className: "w-4 h-4" })
863 ]
864 }
865 ),
866 isExpanded && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "p-4 border-t border-gray-200 dark:border-gray-700 space-y-4", children: [
867 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-2 gap-4", children: [
868 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
869 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium mb-1", children: __("Label") }),
870 /* @__PURE__ */ jsxRuntimeExports.jsx(
871 Input,
872 {
873 value: field.label,
874 onChange: (e) => updateField(field.id, {
875 label: e.target.value
876 }),
877 placeholder: __("Field label")
878 }
879 )
880 ] }),
881 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
882 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium mb-1", children: __("Placeholder") }),
883 /* @__PURE__ */ jsxRuntimeExports.jsx(
884 Input,
885 {
886 value: field.placeholder || "",
887 onChange: (e) => updateField(field.id, {
888 placeholder: e.target.value
889 }),
890 placeholder: __("Placeholder text")
891 }
892 )
893 ] })
894 ] }),
895 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center gap-6", children: [
896 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [
897 /* @__PURE__ */ jsxRuntimeExports.jsx(
898 "input",
899 {
900 type: "checkbox",
901 checked: field.required,
902 onChange: (e) => updateField(field.id, {
903 required: e.target.checked
904 }),
905 className: "w-4 h-4 rounded"
906 }
907 ),
908 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm", children: __("Required") })
909 ] }),
910 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex items-center gap-2 cursor-pointer", children: [
911 /* @__PURE__ */ jsxRuntimeExports.jsx(
912 "input",
913 {
914 type: "checkbox",
915 checked: field.enabled,
916 onChange: (e) => updateField(field.id, {
917 enabled: e.target.checked
918 }),
919 className: "w-4 h-4 rounded"
920 }
921 ),
922 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm", children: __("Enabled") })
923 ] }),
924 /* @__PURE__ */ jsxRuntimeExports.jsxs(
925 Select,
926 {
927 value: field.width,
928 onChange: (e) => updateField(field.id, {
929 width: e.target.value
930 }),
931 className: "w-32",
932 children: [
933 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "full", children: __("Full Width") }),
934 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "half", children: __("Half Width") })
935 ]
936 }
937 )
938 ] }),
939 field.type === "select" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
940 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium mb-2", children: __("Options") }),
941 (_a = field.options) == null ? void 0 : _a.map((opt, idx) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2 mb-2", children: [
942 /* @__PURE__ */ jsxRuntimeExports.jsx(
943 Input,
944 {
945 value: opt.value,
946 onChange: (e) => {
947 const newOptions = [
948 ...field.options || []
949 ];
950 newOptions[idx] = {
951 ...newOptions[idx],
952 value: e.target.value
953 };
954 updateField(field.id, {
955 options: newOptions
956 });
957 },
958 placeholder: __("Value"),
959 className: "flex-1"
960 }
961 ),
962 /* @__PURE__ */ jsxRuntimeExports.jsx(
963 Input,
964 {
965 value: opt.label,
966 onChange: (e) => {
967 const newOptions = [
968 ...field.options || []
969 ];
970 newOptions[idx] = {
971 ...newOptions[idx],
972 label: e.target.value
973 };
974 updateField(field.id, {
975 options: newOptions
976 });
977 },
978 placeholder: __("Label"),
979 className: "flex-1"
980 }
981 ),
982 /* @__PURE__ */ jsxRuntimeExports.jsx(
983 Button,
984 {
985 type: "button",
986 variant: "ghost",
987 size: "sm",
988 onClick: () => {
989 var _a2;
990 const newOptions = (_a2 = field.options) == null ? void 0 : _a2.filter(
991 (_, i) => i !== idx
992 );
993 updateField(field.id, {
994 options: newOptions
995 });
996 },
997 children: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "w-4 h-4 text-red-500" })
998 }
999 )
1000 ] }, idx)),
1001 /* @__PURE__ */ jsxRuntimeExports.jsxs(
1002 Button,
1003 {
1004 type: "button",
1005 variant: "outline",
1006 size: "sm",
1007 onClick: () => {
1008 const newOptions = [
1009 ...field.options || [],
1010 { value: "", label: "" }
1011 ];
1012 updateField(field.id, {
1013 options: newOptions
1014 });
1015 },
1016 children: [
1017 /* @__PURE__ */ jsxRuntimeExports.jsx(Plus, { className: "w-4 h-4 mr-1" }),
1018 __("Add Option")
1019 ]
1020 }
1021 )
1022 ] }),
1023 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "flex justify-end", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
1024 Button,
1025 {
1026 type: "button",
1027 variant: "ghost",
1028 size: "sm",
1029 onClick: () => removeField(field.id),
1030 className: "text-red-600 hover:text-red-700 hover:bg-red-50",
1031 children: [
1032 /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "w-4 h-4 mr-1" }),
1033 __("Remove Field")
1034 ]
1035 }
1036 ) })
1037 ] })
1038 ]
1039 },
1040 field.id
1041 );
1042 }) }) })
1043 ] }) }),
1044 activeTab === "content" && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-6", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
1045 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardTitle, { className: "flex items-center justify-between", children: [
1046 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: __("Content Blocks") }),
1047 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
1048 /* @__PURE__ */ jsxRuntimeExports.jsx(
1049 Button,
1050 {
1051 type: "button",
1052 variant: "outline",
1053 size: "sm",
1054 onClick: () => addContentBlock("heading"),
1055 children: __("Add Heading")
1056 }
1057 ),
1058 /* @__PURE__ */ jsxRuntimeExports.jsx(
1059 Button,
1060 {
1061 type: "button",
1062 variant: "outline",
1063 size: "sm",
1064 onClick: () => addContentBlock("paragraph"),
1065 children: __("Add Paragraph")
1066 }
1067 ),
1068 /* @__PURE__ */ jsxRuntimeExports.jsx(
1069 Button,
1070 {
1071 type: "button",
1072 variant: "outline",
1073 size: "sm",
1074 onClick: () => addContentBlock("terms"),
1075 children: __("Add Terms")
1076 }
1077 )
1078 ] })
1079 ] }) }),
1080 /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { children: formData.content_blocks.length === 0 ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center py-8 text-gray-500", children: [
1081 /* @__PURE__ */ jsxRuntimeExports.jsx(AlignLeft, { className: "w-12 h-12 mx-auto mb-3 opacity-50" }),
1082 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { children: __(
1083 "No content blocks added yet. Add headings, paragraphs, or terms sections."
1084 ) })
1085 ] }) : /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-4", children: formData.content_blocks.map((block) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
1086 "div",
1087 {
1088 className: "border border-gray-200 dark:border-gray-700 rounded-lg p-4",
1089 children: [
1090 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex items-center justify-between mb-3", children: [
1091 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm font-medium text-blue-600 capitalize", children: block.type }),
1092 /* @__PURE__ */ jsxRuntimeExports.jsx(
1093 Button,
1094 {
1095 type: "button",
1096 variant: "ghost",
1097 size: "sm",
1098 onClick: () => removeContentBlock(block.id),
1099 className: "text-red-600",
1100 children: /* @__PURE__ */ jsxRuntimeExports.jsx(Trash2, { className: "w-4 h-4" })
1101 }
1102 )
1103 ] }),
1104 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
1105 /* @__PURE__ */ jsxRuntimeExports.jsx(
1106 Input,
1107 {
1108 value: block.title,
1109 onChange: (e) => updateContentBlock(block.id, {
1110 title: e.target.value
1111 }),
1112 placeholder: __("Title")
1113 }
1114 ),
1115 /* @__PURE__ */ jsxRuntimeExports.jsx(
1116 "textarea",
1117 {
1118 value: block.content,
1119 onChange: (e) => updateContentBlock(block.id, {
1120 content: e.target.value
1121 }),
1122 placeholder: __("Content..."),
1123 rows: 4,
1124 className: "w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white"
1125 }
1126 )
1127 ] })
1128 ]
1129 },
1130 block.id
1131 )) }) })
1132 ] }) }),
1133 activeTab === "settings" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 lg:grid-cols-2 gap-6", children: [
1134 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
1135 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __("Recipient Settings") }) }),
1136 /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { className: "space-y-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1137 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: __("Send consent form to") }),
1138 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-3", children: [
1139 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex items-start gap-3 p-3 border border-gray-200 dark:border-gray-700 rounded-lg cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800", children: [
1140 /* @__PURE__ */ jsxRuntimeExports.jsx(
1141 "input",
1142 {
1143 type: "radio",
1144 name: "send_to",
1145 value: "all_travelers",
1146 checked: formData.send_to === "all_travelers",
1147 onChange: (e) => setFormData({
1148 ...formData,
1149 send_to: e.target.value
1150 }),
1151 className: "mt-1"
1152 }
1153 ),
1154 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1155 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium text-gray-900 dark:text-white", children: __("All Travelers") }),
1156 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 mt-0.5", children: __(
1157 "Each traveler in the booking will receive their own consent form to sign individually."
1158 ) })
1159 ] })
1160 ] }),
1161 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex items-start gap-3 p-3 border border-gray-200 dark:border-gray-700 rounded-lg cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800", children: [
1162 /* @__PURE__ */ jsxRuntimeExports.jsx(
1163 "input",
1164 {
1165 type: "radio",
1166 name: "send_to",
1167 value: "lead_traveler",
1168 checked: formData.send_to === "lead_traveler",
1169 onChange: (e) => setFormData({
1170 ...formData,
1171 send_to: e.target.value
1172 }),
1173 className: "mt-1"
1174 }
1175 ),
1176 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1177 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium text-gray-900 dark:text-white", children: __("Lead Traveler Only") }),
1178 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 mt-0.5", children: __(
1179 "Only the first/lead traveler will receive the consent form."
1180 ) })
1181 ] })
1182 ] }),
1183 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex items-start gap-3 p-3 border border-gray-200 dark:border-gray-700 rounded-lg cursor-pointer hover:bg-gray-50 dark:hover:bg-gray-800", children: [
1184 /* @__PURE__ */ jsxRuntimeExports.jsx(
1185 "input",
1186 {
1187 type: "radio",
1188 name: "send_to",
1189 value: "primary_contact",
1190 checked: formData.send_to === "primary_contact",
1191 onChange: (e) => setFormData({
1192 ...formData,
1193 send_to: e.target.value
1194 }),
1195 className: "mt-1"
1196 }
1197 ),
1198 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1199 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "font-medium text-gray-900 dark:text-white", children: __("Primary Contact Only") }),
1200 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 mt-0.5", children: __(
1201 "Only the person who made the booking (primary contact) will receive the consent form."
1202 ) })
1203 ] })
1204 ] })
1205 ] })
1206 ] }) })
1207 ] }),
1208 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
1209 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __("Delivery Settings") }) }),
1210 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "space-y-4", children: [
1211 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1212 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", children: __("Send before trip (days)") }),
1213 /* @__PURE__ */ jsxRuntimeExports.jsx(
1214 Input,
1215 {
1216 type: "number",
1217 value: formData.send_before_days,
1218 onChange: (e) => setFormData({
1219 ...formData,
1220 send_before_days: parseInt(e.target.value) || 7
1221 }),
1222 min: 1,
1223 max: 90
1224 }
1225 ),
1226 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 mt-1", children: __(
1227 "Number of days before the trip to send the consent request."
1228 ) })
1229 ] }),
1230 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1231 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", children: __("Reminder days") }),
1232 /* @__PURE__ */ jsxRuntimeExports.jsx(
1233 Input,
1234 {
1235 value: formData.reminder_days,
1236 onChange: (e) => setFormData({
1237 ...formData,
1238 reminder_days: e.target.value
1239 }),
1240 placeholder: "3,1"
1241 }
1242 ),
1243 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 mt-1", children: __(
1244 "Comma-separated days before trip to send reminders (e.g., 3,1 for 3 days and 1 day before)."
1245 ) })
1246 ] }),
1247 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "border-t pt-4", children: [
1248 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", children: __("Test Email") }),
1249 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-2", children: [
1250 /* @__PURE__ */ jsxRuntimeExports.jsx(
1251 Input,
1252 {
1253 type: "email",
1254 value: testEmail || "",
1255 onChange: (e) => setTestEmail(e.target.value),
1256 placeholder: __(
1257 "Enter email address to test consent email"
1258 ),
1259 className: "flex-1"
1260 }
1261 ),
1262 /* @__PURE__ */ jsxRuntimeExports.jsxs(
1263 Button,
1264 {
1265 type: "button",
1266 variant: "outline",
1267 size: "sm",
1268 onClick: handleSendTestEmail,
1269 disabled: !testEmail || sendTestEmailMutation.isPending,
1270 className: "flex items-center gap-2",
1271 children: [
1272 sendTestEmailMutation.isPending ? /* @__PURE__ */ jsxRuntimeExports.jsx(Loader2, { className: "w-4 h-4 animate-spin" }) : /* @__PURE__ */ jsxRuntimeExports.jsx(Mail, { className: "w-4 h-4" }),
1273 __("Send Test")
1274 ]
1275 }
1276 )
1277 ] }),
1278 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 mt-1", children: __(
1279 "Send a test consent email to preview how it will appear to customers."
1280 ) })
1281 ] })
1282 ] })
1283 ] }),
1284 /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { children: [
1285 /* @__PURE__ */ jsxRuntimeExports.jsx(CardHeader, { children: /* @__PURE__ */ jsxRuntimeExports.jsx(CardTitle, { children: __("Expiry Settings") }) }),
1286 /* @__PURE__ */ jsxRuntimeExports.jsx(CardContent, { className: "space-y-4", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1287 /* @__PURE__ */ jsxRuntimeExports.jsx("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", children: __("Link expiry (hours)") }),
1288 /* @__PURE__ */ jsxRuntimeExports.jsx(
1289 Input,
1290 {
1291 type: "number",
1292 value: formData.expiry_hours || "",
1293 onChange: (e) => setFormData({
1294 ...formData,
1295 expiry_hours: e.target.value ? parseInt(e.target.value) : null
1296 }),
1297 placeholder: __("No expiry"),
1298 min: 1
1299 }
1300 ),
1301 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-gray-500 mt-1", children: __(
1302 "Leave empty for no expiry. The consent link will expire after this many hours."
1303 ) })
1304 ] }) })
1305 ] })
1306 ] }),
1307 activeTab === "preview" && /* @__PURE__ */ jsxRuntimeExports.jsx(
1308 PreviewForm,
1309 {
1310 formData,
1311 showToast,
1312 generateSimpleForm,
1313 setActiveTab
1314 }
1315 )
1316 ] })
1317 ] });
1318 };
1319 const PreviewForm = ({
1320 formData,
1321 showToast,
1322 generateSimpleForm,
1323 setActiveTab
1324 }) => {
1325 const [previewValues, setPreviewValues] = React.useState({});
1326 const [previewChecked, setPreviewChecked] = React.useState({});
1327 const [hasSignature, setHasSignature] = React.useState(false);
1328 const [hasInitials, setHasInitials] = React.useState(false);
1329 const [validationErrors, setValidationErrors] = React.useState([]);
1330 const [isSubmitting, setIsSubmitting] = React.useState(false);
1331 const [isSubmitted, setIsSubmitted] = React.useState(false);
1332 const [savedConsentId, setSavedConsentId] = React.useState(
1333 null
1334 );
1335 const signatureCanvasRef = React.useRef(null);
1336 const initialsCanvasRef = React.useRef(null);
1337 const handlePreviewSubmit = async () => {
1338 var _a, _b, _c;
1339 const errors = [];
1340 formData.fields.filter((f) => f.enabled && f.required).forEach((field) => {
1341 var _a2;
1342 if (field.type === "checkbox") {
1343 if (!previewChecked[field.id]) {
1344 errors.push(`"${field.label}" ${__("is required")}`);
1345 }
1346 } else {
1347 if (!((_a2 = previewValues[field.id]) == null ? void 0 : _a2.trim())) {
1348 errors.push(`"${field.label}" ${__("is required")}`);
1349 }
1350 }
1351 });
1352 if (formData.require_signature && !hasSignature) {
1353 errors.push(__("Signature is required"));
1354 }
1355 if (formData.require_initials && !hasInitials) {
1356 errors.push(__("Initials are required"));
1357 }
1358 setValidationErrors(errors);
1359 if (errors.length > 0) {
1360 showToast(__("Please fill in all required fields"), "error");
1361 return;
1362 }
1363 const signatureData = ((_a = signatureCanvasRef.current) == null ? void 0 : _a.toDataURL("image/png")) || "";
1364 const initialsData = ((_b = initialsCanvasRef.current) == null ? void 0 : _b.toDataURL("image/png")) || "";
1365 const submittedFormData = {};
1366 formData.fields.filter((f) => f.enabled).forEach((field) => {
1367 if (field.type === "checkbox") {
1368 submittedFormData[field.label] = previewChecked[field.id] || false;
1369 } else {
1370 submittedFormData[field.label] = previewValues[field.id] || "";
1371 }
1372 });
1373 setIsSubmitting(true);
1374 try {
1375 const response = await apiClient.post("/signed-consents/preview", {
1376 form_id: formData.id || 0,
1377 form_version: 1,
1378 signer_name: previewValues["full_name"] || previewValues["name"] || __("Preview User", "yatra"),
1379 signer_email: previewValues["email"] || "[email protected]",
1380 form_data: submittedFormData,
1381 signature_data: formData.require_signature ? signatureData : null,
1382 initials_data: formData.require_initials ? initialsData : null,
1383 is_preview: true
1384 });
1385 if (response == null ? void 0 : response.success) {
1386 setSavedConsentId(((_c = response.data) == null ? void 0 : _c.id) || null);
1387 setIsSubmitted(true);
1388 showToast(__("Consent form saved successfully!"), "success");
1389 } else {
1390 throw new Error((response == null ? void 0 : response.message) || __("Failed to save", "yatra"));
1391 }
1392 } catch (error) {
1393 console.error("Failed to save consent:", error);
1394 showToast((error == null ? void 0 : error.message) || __("Failed to save consent form"), "error");
1395 } finally {
1396 setIsSubmitting(false);
1397 }
1398 };
1399 if (isSubmitted) {
1400 return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "max-w-3xl mx-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsx(Card, { className: "overflow-hidden", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "p-12 text-center", children: [
1401 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "w-20 h-20 bg-blue-100 dark:bg-blue-900/30 rounded-full flex items-center justify-center mx-auto mb-6", children: /* @__PURE__ */ jsxRuntimeExports.jsx(CheckSquare, { className: "w-10 h-10 text-blue-600" }) }),
1402 /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-2xl font-bold text-gray-900 dark:text-white mb-3", children: __("Consent Form Saved!") }),
1403 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-600 dark:text-gray-400 mb-2", children: __(
1404 "Your consent form submission has been saved to the database."
1405 ) }),
1406 savedConsentId && /* @__PURE__ */ jsxRuntimeExports.jsxs("p", { className: "text-sm text-blue-600 dark:text-blue-400 mb-6", children: [
1407 __("Consent ID"),
1408 ": #",
1409 savedConsentId
1410 ] }),
1411 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-gray-50 dark:bg-gray-800 rounded-lg p-4 text-left mb-6", children: [
1412 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "font-medium text-gray-900 dark:text-white mb-2", children: __("Saved Data:") }),
1413 /* @__PURE__ */ jsxRuntimeExports.jsxs("ul", { className: "text-sm text-gray-600 dark:text-gray-400 space-y-1", children: [
1414 formData.fields.filter((f) => f.enabled).map((field) => /* @__PURE__ */ jsxRuntimeExports.jsxs("li", { children: [
1415 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-medium", children: [
1416 field.label,
1417 ":"
1418 ] }),
1419 " ",
1420 field.type === "checkbox" ? previewChecked[field.id] ? __("✓ Checked", "yatra") : __("✗ Not checked", "yatra") : previewValues[field.id] || "-"
1421 ] }, field.id)),
1422 formData.require_signature && /* @__PURE__ */ jsxRuntimeExports.jsxs("li", { children: [
1423 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-medium", children: [
1424 __("Signature"),
1425 ":"
1426 ] }),
1427 " ✓",
1428 " ",
1429 __("Saved")
1430 ] }),
1431 formData.require_initials && /* @__PURE__ */ jsxRuntimeExports.jsxs("li", { children: [
1432 /* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "font-medium", children: [
1433 __("Initials"),
1434 ":"
1435 ] }),
1436 " ✓",
1437 " ",
1438 __("Saved")
1439 ] })
1440 ] })
1441 ] }),
1442 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "flex gap-3 justify-center", children: [
1443 /* @__PURE__ */ jsxRuntimeExports.jsx(
1444 Button,
1445 {
1446 type: "button",
1447 variant: "outline",
1448 onClick: () => {
1449 setIsSubmitted(false);
1450 setSavedConsentId(null);
1451 setPreviewValues({});
1452 setPreviewChecked({});
1453 setHasSignature(false);
1454 setHasInitials(false);
1455 },
1456 children: __("Submit Another")
1457 }
1458 ),
1459 /* @__PURE__ */ jsxRuntimeExports.jsx(
1460 Button,
1461 {
1462 type: "button",
1463 onClick: () => {
1464 var _a;
1465 window.location.href = `${((_a = window.yatraAdmin) == null ? void 0 : _a.siteUrl) || ""}/wp-admin/admin.php?page=yatra&subpage=trips&tab=trip-consent`;
1466 },
1467 children: __("View Signed Consents")
1468 }
1469 )
1470 ] })
1471 ] }) }) });
1472 }
1473 return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "max-w-3xl mx-auto", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(Card, { className: "overflow-hidden", children: [
1474 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-gradient-to-r from-blue-600 to-blue-800 p-6 text-white", children: [
1475 /* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "text-2xl font-bold", children: formData.name || __("Consent Form") }),
1476 formData.description && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "mt-2 text-blue-100", children: formData.description })
1477 ] }),
1478 /* @__PURE__ */ jsxRuntimeExports.jsxs(CardContent, { className: "p-6 space-y-8", children: [
1479 validationErrors.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-red-50 dark:bg-red-900/20 border border-red-200 dark:border-red-800 rounded-lg p-4", children: [
1480 /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-red-800 dark:text-red-300 font-medium mb-2", children: __("Please fix the following errors:") }),
1481 /* @__PURE__ */ jsxRuntimeExports.jsx("ul", { className: "list-disc list-inside text-sm text-red-600 dark:text-red-400 space-y-1", children: validationErrors.map((error, idx) => /* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: error }, idx)) })
1482 ] }),
1483 formData.content_blocks.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "space-y-6", children: formData.content_blocks.sort((a, b) => a.order - b.order).map((block) => /* @__PURE__ */ jsxRuntimeExports.jsxs(
1484 "div",
1485 {
1486 className: "prose dark:prose-invert max-w-none",
1487 children: [
1488 block.type === "heading" && /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-xl font-semibold text-gray-900 dark:text-white border-b border-gray-200 dark:border-gray-700 pb-2", children: block.title }),
1489 block.type === "paragraph" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1490 block.title && /* @__PURE__ */ jsxRuntimeExports.jsx("h4", { className: "text-lg font-medium text-gray-800 dark:text-gray-200 mb-2", children: block.title }),
1491 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-600 dark:text-gray-400 leading-relaxed", children: block.content })
1492 ] }),
1493 block.type === "terms" && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "bg-gray-50 dark:bg-gray-800/50 border border-gray-200 dark:border-gray-700 rounded-lg p-4", children: [
1494 /* @__PURE__ */ jsxRuntimeExports.jsxs("h4", { className: "text-lg font-medium text-gray-800 dark:text-gray-200 mb-2 flex items-center gap-2", children: [
1495 /* @__PURE__ */ jsxRuntimeExports.jsx(CheckSquare, { className: "w-5 h-5 text-blue-600" }),
1496 block.title
1497 ] }),
1498 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-600 dark:text-gray-400 text-sm leading-relaxed", children: block.content })
1499 ] })
1500 ]
1501 },
1502 block.id
1503 )) }),
1504 formData.fields.length > 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-4", children: [
1505 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-semibold text-gray-900 dark:text-white border-b border-gray-200 dark:border-gray-700 pb-2", children: __("Participant Information") }),
1506 /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-4", children: formData.fields.filter((f) => f.enabled).sort((a, b) => a.order - b.order).map((field) => {
1507 var _a;
1508 return /* @__PURE__ */ jsxRuntimeExports.jsxs(
1509 "div",
1510 {
1511 className: field.width === "full" ? "md:col-span-2" : "",
1512 children: [
1513 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-1", children: [
1514 field.label || __("Untitled Field"),
1515 field.required && /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-500 ml-1", children: "*" })
1516 ] }),
1517 field.type === "textarea" ? /* @__PURE__ */ jsxRuntimeExports.jsx(
1518 "textarea",
1519 {
1520 placeholder: field.placeholder,
1521 value: previewValues[field.id] || "",
1522 onChange: (e) => setPreviewValues({
1523 ...previewValues,
1524 [field.id]: e.target.value
1525 }),
1526 rows: 3,
1527 className: "w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
1528 }
1529 ) : field.type === "checkbox" ? /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "flex items-start gap-3 cursor-pointer", children: [
1530 /* @__PURE__ */ jsxRuntimeExports.jsx(
1531 "input",
1532 {
1533 type: "checkbox",
1534 checked: previewChecked[field.id] || false,
1535 onChange: (e) => setPreviewChecked({
1536 ...previewChecked,
1537 [field.id]: e.target.checked
1538 }),
1539 className: "mt-1 w-4 h-4 rounded border-gray-300 text-blue-600 focus:ring-blue-500"
1540 }
1541 ),
1542 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-sm text-gray-600 dark:text-gray-400", children: field.label })
1543 ] }) : field.type === "select" ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
1544 "select",
1545 {
1546 value: previewValues[field.id] || "",
1547 onChange: (e) => setPreviewValues({
1548 ...previewValues,
1549 [field.id]: e.target.value
1550 }),
1551 className: "w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-blue-500",
1552 children: [
1553 /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: "", children: field.placeholder || __("Select an option") }),
1554 (_a = field.options) == null ? void 0 : _a.map((opt, idx) => /* @__PURE__ */ jsxRuntimeExports.jsx("option", { value: opt.value, children: opt.label }, idx))
1555 ]
1556 }
1557 ) : /* @__PURE__ */ jsxRuntimeExports.jsx(
1558 "input",
1559 {
1560 type: field.type,
1561 placeholder: field.placeholder,
1562 value: previewValues[field.id] || "",
1563 onChange: (e) => setPreviewValues({
1564 ...previewValues,
1565 [field.id]: e.target.value
1566 }),
1567 className: "w-full px-3 py-2 border border-gray-300 dark:border-gray-600 rounded-lg bg-white dark:bg-gray-800 text-gray-900 dark:text-white focus:ring-2 focus:ring-blue-500 focus:border-blue-500"
1568 }
1569 )
1570 ]
1571 },
1572 field.id
1573 );
1574 }) })
1575 ] }),
1576 (formData.require_signature || formData.require_initials) && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "space-y-6 border-t border-gray-200 dark:border-gray-700 pt-6", children: [
1577 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-semibold text-gray-900 dark:text-white", children: __("Signature") }),
1578 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "grid grid-cols-1 md:grid-cols-2 gap-6", children: [
1579 formData.require_signature && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1580 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: [
1581 __("Your Signature"),
1582 " ",
1583 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-500", children: "*" })
1584 ] }),
1585 /* @__PURE__ */ jsxRuntimeExports.jsx(
1586 SignaturePadPreview,
1587 {
1588 id: "signature-preview",
1589 placeholder: __("Draw your signature here"),
1590 onContentChange: setHasSignature,
1591 canvasRef: signatureCanvasRef
1592 }
1593 )
1594 ] }),
1595 formData.require_initials && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
1596 /* @__PURE__ */ jsxRuntimeExports.jsxs("label", { className: "block text-sm font-medium text-gray-700 dark:text-gray-300 mb-2", children: [
1597 __("Initials"),
1598 " ",
1599 /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "text-red-500", children: "*" })
1600 ] }),
1601 /* @__PURE__ */ jsxRuntimeExports.jsx(
1602 SignaturePadPreview,
1603 {
1604 id: "initials-preview",
1605 placeholder: __("Draw initials here"),
1606 onContentChange: setHasInitials,
1607 canvasRef: initialsCanvasRef
1608 }
1609 )
1610 ] })
1611 ] })
1612 ] }),
1613 /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "pt-4", children: [
1614 /* @__PURE__ */ jsxRuntimeExports.jsx(
1615 Button,
1616 {
1617 type: "button",
1618 onClick: handlePreviewSubmit,
1619 disabled: isSubmitting,
1620 className: "w-full bg-blue-600 hover:bg-blue-700 text-white py-3",
1621 children: isSubmitting ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
1622 /* @__PURE__ */ jsxRuntimeExports.jsx(Loader2, { className: "w-4 h-4 mr-2 animate-spin" }),
1623 __("Submitting...")
1624 ] }) : __("Submit Consent Form")
1625 }
1626 ),
1627 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-xs text-center text-gray-500 mt-2", children: __(
1628 "This is an interactive preview. Test the form submission behavior."
1629 ) })
1630 ] }),
1631 formData.fields.length === 0 && formData.content_blocks.length === 0 && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "text-center py-12", children: [
1632 /* @__PURE__ */ jsxRuntimeExports.jsx(FileSignature, { className: "w-16 h-16 mx-auto text-gray-300 mb-4" }),
1633 /* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "text-lg font-medium text-gray-900 dark:text-white mb-2", children: __("No content yet") }),
1634 /* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "text-gray-500 dark:text-gray-400 mb-4", children: __("Add form fields and content blocks to see the preview.") }),
1635 /* @__PURE__ */ jsxRuntimeExports.jsxs(
1636 Button,
1637 {
1638 type: "button",
1639 variant: "outline",
1640 onClick: () => {
1641 generateSimpleForm();
1642 setActiveTab("preview");
1643 },
1644 children: [
1645 /* @__PURE__ */ jsxRuntimeExports.jsx(Sparkles, { className: "w-4 h-4 mr-2" }),
1646 __("Generate Simple Form")
1647 ]
1648 }
1649 )
1650 ] })
1651 ] })
1652 ] }) });
1653 };
1654 export {
1655 TripConsentForm as default
1656 };
1657 //# sourceMappingURL=TripConsentForm-C4az7Muo.js.map
1658