PluginProbe
Yatra – Travel Booking & Tour Operator Software / 3.0.15
Yatra – Travel Booking & Tour Operator Software v3.0.15
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 2.0.1 2.0.10 All 83 releases
yatra / templates / booking-confirmation.php

booking-confirmation.php in Yatra – Travel Booking & Tour Operator Software 3.0.15, at templates/booking-confirmation.php

1,850 lines 80.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * Booking Confirmation Template
4 *
5 * Displays booking confirmation after successful booking
6 *
7 * @package Yatra
8 *
9 * Global variables available:
10 * - $booking_data or $GLOBALS['yatra_booking']
11 */
12
13 if (!defined('ABSPATH')) {
14 exit;
15 }
16
17 // Get booking data
18 $booking = $GLOBALS['yatra_booking'] ?? null;
19
20 if (!$booking) {
21 wp_safe_redirect(home_url('/'));
22 exit;
23 }
24
25 // Completed booking: ensure checkout session and its transient cannot repopulate the booking form.
26 if (function_exists('yatra_clear_booking_session')) {
27 yatra_clear_booking_session();
28 }
29
30 // Format dates
31 $travel_date_formatted = \Yatra\Helpers\FormatHelper::formatDate((string) ($booking->travel_date ?? ''));
32 $booking_date_formatted = \Yatra\Helpers\FormatHelper::formatDateTime((string) ($booking->created_at ?? ''));
33
34 // "Balance just paid" context detection.
35 // A `?balance=paid` query arg is appended by the remaining-payment flows
36 // (see PaymentGatewayController::create_remaining_balance_intent and
37 // BookingSessionController::process_remaining_payment). We only render the
38 // "balance paid" copy when BOTH the flag is present AND the booking actually
39 // reports a paid status — that way a stale bookmarked URL or a tampered
40 // query string can't show misleading content if a balance is still due.
41 $is_balance_paid_request = isset($_GET['balance']) && sanitize_key((string) $_GET['balance']) === 'paid';
42 $booking_payment_status = (string) ($booking->payment_status ?? '');
43 $booking_amount_due = (float) ($booking->amount_due ?? 0);
44 $booking_is_fully_paid = $booking_payment_status === 'paid' || $booking_amount_due <= 0.01;
45 $show_balance_paid_banner = $is_balance_paid_request && $booking_is_fully_paid;
46
47 // A gateway may redirect back here with `?payment=cancelled` (user aborted the
48 // payment at the provider) or `?payment=failed`. Show an informative notice only
49 // when the booking is not already fully paid, so a genuinely-paid booking that
50 // happens to carry a stale query arg never shows a misleading "cancelled" message.
51 $payment_result_flag = isset($_GET['payment']) ? sanitize_key((string) $_GET['payment']) : '';
52 $show_payment_cancelled_notice = in_array($payment_result_flag, ['cancelled', 'failed'], true) && !$booking_is_fully_paid;
53
54 // Resolve the most recent gateway used on this booking.
55 // `$booking->payment_gateway` is the *initial* method chosen at booking time
56 // (e.g. Pay Later), which is misleading when the customer later settled the
57 // balance via a different gateway (e.g. Stripe). Show the latest payment's
58 // gateway in the Payment Method line; fall back to the booking's stored
59 // gateway when no payment row exists yet.
60 $display_payment_gateway = (string) ($booking->payment_gateway ?? '');
61 if (!empty($booking->id)) {
62 try {
63 $latest_payment = (new \Yatra\Repositories\PaymentRepository())->findLatestByBookingId((int) $booking->id);
64 if ($latest_payment) {
65 $latest_gateway = (string) ($latest_payment->payment_gateway ?? $latest_payment->gateway ?? '');
66 if ($latest_gateway !== '') {
67 $display_payment_gateway = $latest_gateway;
68 }
69 }
70 } catch (\Throwable $e) {
71 // Repository unavailable for some reason — keep the booking's stored gateway.
72 }
73 }
74
75 // Resolved customer account URL (configurable via Settings → Permalink → Account base).
76 $yatra_account_url = home_url('/' . \Yatra\Services\SettingsService::getAccountBase());
77
78 // Get status color
79 $status_colors = [
80 'pending' => ['bg' => '#fef3c7', 'text' => '#d97706', 'label' => 'Pending'],
81 'confirmed' => ['bg' => '#d1fae5', 'text' => '#059669', 'label' => 'Confirmed'],
82 'processing' => ['bg' => '#dbeafe', 'text' => '#2563eb', 'label' => 'Processing'],
83 'completed' => ['bg' => '#d1fae5', 'text' => '#059669', 'label' => 'Completed'],
84 'cancelled' => ['bg' => '#fee2e2', 'text' => '#dc2626', 'label' => 'Cancelled'],
85 'refunded' => ['bg' => '#fce7f3', 'text' => '#db2777', 'label' => 'Refunded'],
86 'on_hold' => ['bg' => '#e5e7eb', 'text' => '#6b7280', 'label' => 'On Hold'],
87 ];
88
89 $status_style = $status_colors[$booking->status] ?? $status_colors['pending'];
90
91 // Ensure Font Awesome CSS is available for icon-picker rendered icons (fa-solid/fa-regular).
92 // This template can be displayed outside normal "trip page" contexts, so we explicitly
93 // register/enqueue the shared stylesheet dependencies before printing the header.
94 if (class_exists(\Yatra\Providers\FrontendAssetsProvider::class)) {
95 \Yatra\Providers\FrontendAssetsProvider::registerCoreFrontendStylesheets();
96 if (wp_style_is('yatra-fontawesome-6', 'registered')) {
97 wp_enqueue_style('yatra-fontawesome-6');
98 }
99 if (wp_style_is('yatra-common', 'registered')) {
100 wp_enqueue_style('yatra-common');
101 }
102 }
103
104 yatra_get_header();
105
106 // Hook for Pro modules to add custom scripts (Facebook Pixel, etc.)
107 do_action('yatra_booking_confirmation_header', $booking);
108 ?>
109
110 <div class="yatra-wrapper yatra-confirmation-wrapper">
111 <div class="yatra-confirmation-container">
112
113 <!-- Success Header -->
114 <div class="yatra-confirmation-header">
115 <div class="yatra-confirmation-icon">
116 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
117 <circle cx="12" cy="12" r="10"></circle>
118 <polyline points="9,12 12,15 16,10"></polyline>
119 </svg>
120 </div>
121 <h1 class="yatra-confirmation-title">
122 <?php
123 if ($show_balance_paid_banner) {
124 esc_html_e('Balance Paid!', 'yatra');
125 } elseif ($booking->status === 'confirmed') {
126 esc_html_e('Booking Confirmed!', 'yatra');
127 } elseif ($booking->status === 'pending') {
128 esc_html_e('Booking Received!', 'yatra');
129 } elseif ($booking->status === 'cancelled') {
130 esc_html_e('Booking Cancelled', 'yatra');
131 } else {
132 esc_html_e('Booking Submitted!', 'yatra');
133 }
134 ?>
135 </h1>
136 <p class="yatra-confirmation-subtitle">
137 <?php
138 if ($show_balance_paid_banner) {
139 esc_html_e('Your remaining balance has been received. This booking is now fully paid.', 'yatra');
140 } elseif ($booking->status === 'confirmed') {
141 esc_html_e('Thank you for your booking. We look forward to hosting you!', 'yatra');
142 } elseif ($booking->status === 'pending') {
143 esc_html_e('Thank you for your booking. Your booking is pending confirmation.', 'yatra');
144 } elseif ($booking->status === 'cancelled') {
145 esc_html_e('This booking has been cancelled.', 'yatra');
146 } else {
147 esc_html_e('Thank you for your booking submission.', 'yatra');
148 }
149 ?>
150 </p>
151 <div class="yatra-confirmation-reference">
152 <span class="yatra-ref-label"><?php esc_html_e('Booking Reference:', 'yatra'); ?></span>
153 <span class="yatra-ref-code"><?php echo esc_html($booking->reference); ?></span>
154 </div>
155 </div>
156
157 <?php if ($show_balance_paid_banner) : ?>
158 <div class="yatra-balance-paid-banner" role="status" aria-live="polite" style="margin: 16px 0; padding: 14px 18px; background: #d1fae5; border: 1px solid #6ee7b7; border-left: 4px solid #059669; border-radius: 8px; color: #065f46; display: flex; gap: 12px; align-items: flex-start;">
159 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="flex: 0 0 22px; width: 22px; height: 22px; margin-top: 1px;">
160 <path stroke-linecap="round" stroke-linejoin="round" d="M9 12l2 2 4-4m6 2a9 9 0 11-18 0 9 9 0 0118 0z"/>
161 </svg>
162 <div style="flex: 1; line-height: 1.45;">
163 <strong style="display: block; margin-bottom: 2px;">
164 <?php esc_html_e('Balance payment received.', 'yatra'); ?>
165 </strong>
166 <span>
167 <?php
168 printf(
169 wp_kses(
170 /* translators: 1: booking reference number (HTML <strong> wrapped), 2: link labelled "payment history" pointing to the customer account page (HTML <a> wrapped). */
171 __('You\'ve completed payment for booking %1$s. A receipt has been emailed to you. View or download your %2$s anytime from your account.', 'yatra'),
172 ['a' => ['href' => true], 'strong' => []]
173 ),
174 '<strong>' . esc_html((string) ($booking->reference ?? '')) . '</strong>',
175 '<a href="' . esc_url(add_query_arg('tab', 'payments', $yatra_account_url)) . '">' . esc_html__('payment history', 'yatra') . '</a>'
176 );
177 ?>
178 </span>
179 </div>
180 </div>
181 <?php endif; ?>
182
183 <?php if ($show_payment_cancelled_notice) : ?>
184 <div class="yatra-payment-cancelled-banner" role="status" aria-live="polite" style="margin: 16px 0; padding: 14px 18px; background: #fef3c7; border: 1px solid #fcd34d; border-left: 4px solid #d97706; border-radius: 8px; color: #92400e; display: flex; gap: 12px; align-items: flex-start;">
185 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="flex: 0 0 22px; width: 22px; height: 22px; margin-top: 1px;">
186 <circle cx="12" cy="12" r="10"></circle>
187 <line x1="12" y1="8" x2="12" y2="12"></line>
188 <line x1="12" y1="16" x2="12.01" y2="16"></line>
189 </svg>
190 <div style="flex: 1; line-height: 1.45;">
191 <strong style="display: block; margin-bottom: 2px;">
192 <?php esc_html_e('Payment not completed.', 'yatra'); ?>
193 </strong>
194 <span>
195 <?php esc_html_e('Your payment was cancelled and no charge was made. Your booking has been saved — you can complete payment anytime from your account.', 'yatra'); ?>
196 </span>
197 </div>
198 </div>
199 <?php endif; ?>
200
201 <?php
202 // Resolve featured image URL (handle attachment ID or direct URL).
203 // Falls back to the bundled trip-placeholder.svg so the confirmation
204 // card always renders with a visual on the left — never an empty
205 // text-only block, regardless of whether the operator set a featured
206 // image for the trip.
207 $featured_image_url = '';
208 if (!empty($booking->featured_image)) {
209 if (is_numeric($booking->featured_image)) {
210 $featured_image_url = wp_get_attachment_url((int) $booking->featured_image) ?: '';
211 } else {
212 $featured_image_url = $booking->featured_image;
213 }
214 }
215 if ($featured_image_url === '') {
216 $featured_image_url = YATRA_PLUGIN_URL . 'assets/images/trip-placeholder.svg';
217 $featured_image_is_placeholder = true;
218 } else {
219 $featured_image_is_placeholder = false;
220 }
221 ?>
222
223 <div class="yatra-confirmation-content">
224 <!-- Trip Summary Card -->
225 <div class="yatra-confirmation-card yatra-trip-summary-card">
226 <div class="yatra-trip-summary">
227 <div class="yatra-trip-image<?php echo $featured_image_is_placeholder ? ' yatra-trip-image--placeholder' : ''; ?>">
228 <img src="<?php echo esc_url($featured_image_url); ?>"
229 alt="<?php echo esc_attr($booking->trip_title); ?>"
230 loading="lazy"
231 onerror="this.onerror=null;this.src='<?php echo esc_url(YATRA_PLUGIN_URL . 'assets/images/trip-placeholder.svg'); ?>';this.parentNode.classList.add('yatra-trip-image--placeholder');">
232 </div>
233
234 <div class="yatra-trip-info">
235 <h2 class="yatra-trip-name"><?php echo esc_html($booking->trip_title); ?></h2>
236
237 <?php if (!empty($booking->trip_average_rating) && $booking->trip_review_count >= 0) : ?>
238 <?php
239 // The confirmation page isn't a "booking page" (it has its
240 // own route), so booking.css — which colours the rating
241 // stars amber — is never enqueued here and the filled stars
242 // fell back to the grey base colour. The rest of this page
243 // is inline-styled, so rather than loading the whole
244 // stylesheet (and risk restyling it) the rating rules are
245 // scoped inline here, mirroring assets/css/booking.css.
246 ?>
247 <?php
248 // IMPORTANT: these rules are deliberately scoped to
249 // `.yatra-trip-rating .yatra-rating-stars .yatra-star*`
250 // (specificity 0,3,0 / 0,4,1) and set `fill` directly on
251 // the SVG — NOT just `color` + `fill="currentColor"`.
252 // trip.css / booking.css define `.yatra-rating-stars
253 // .yatra-star { color:#d1d5db }` (0,2,0) and colour the
254 // "filled" state with a `.filled` (dot) class, not the
255 // `-filled` (hyphen) class this markup uses. If either
256 // stylesheet is present on the confirmation page, its
257 // grey base out-specifies a plain `.yatra-star-filled`
258 // and its amber rule never matches — so every star showed
259 // grey even at 4.8. Winning on specificity + an explicit
260 // fill makes the amber stick regardless of what's loaded.
261 ?>
262 <style>
263 .yatra-trip-rating{display:flex;align-items:center;gap:12px;margin-bottom:12px}
264 .yatra-trip-rating .yatra-rating-stars{display:inline-flex;gap:4px}
265 .yatra-trip-rating .yatra-rating-stars .yatra-star{width:20px;height:20px;color:#e2e8f0;font-size:0;line-height:0}
266 .yatra-trip-rating .yatra-rating-stars .yatra-star svg{width:100%;height:100%;display:block;fill:currentColor}
267 .yatra-trip-rating .yatra-rating-stars .yatra-star-filled{color:#f59e0b}
268 .yatra-trip-rating .yatra-rating-stars .yatra-star-filled svg{fill:#f59e0b}
269 .yatra-trip-rating .yatra-rating-stars .yatra-star-half{position:relative;color:#e2e8f0}
270 .yatra-trip-rating .yatra-rating-stars .yatra-star-half svg{fill:#e2e8f0}
271 .yatra-trip-rating .yatra-rating-stars .yatra-star-half::after{content:"";position:absolute;top:0;left:0;bottom:0;width:50%;overflow:hidden;background:#f59e0b;-webkit-mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpolygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26'/%3E%3C/svg%3E") no-repeat left center / 200% 100%;mask:url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpolygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26'/%3E%3C/svg%3E") no-repeat left center / 200% 100%}
272 .yatra-trip-rating .yatra-rating-meta strong{color:#0f172a;margin-right:6px}
273 .yatra-trip-rating .yatra-rating-meta span{color:#64748b;font-size:14px}
274 </style>
275 <div class="yatra-trip-rating">
276 <div class="yatra-rating-stars">
277 <?php
278 // Shared with the reviews block and listing cards so every
279 // surface draws the same rating. Rounds to the nearest half:
280 // flooring drew 4.9 as four-and-a-half stars, which looked
281 // wrong beside the printed "4.9".
282 $star_parts = yatra_rating_star_parts($booking->trip_average_rating);
283 $filled_stars = $star_parts['full'];
284 $has_half = $star_parts['half'];
285 for ($i = 1; $i <= 5; $i++) :
286 $class = $i <= $filled_stars ? 'yatra-star-filled' : ($has_half && $i === $filled_stars + 1 ? 'yatra-star-half' : '');
287 ?>
288 <span class="yatra-star <?php echo esc_attr($class); ?>">
289 <svg viewBox="0 0 24 24" fill="currentColor"><polygon points="12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26"></polygon></svg>
290 </span>
291 <?php endfor; ?>
292 </div>
293 <div class="yatra-rating-meta">
294 <strong><?php echo esc_html(number_format($booking->trip_average_rating, 1)); ?></strong>
295 <span>
296 <?php
297 printf(
298 esc_html(
299 /* translators: %d: number of reviews. */
300 _n('%d Review', '%d Reviews', (int) $booking->trip_review_count, 'yatra')
301 ),
302 (int) $booking->trip_review_count
303 );
304 ?>
305 </span>
306 </div>
307 </div>
308 <?php endif; ?>
309
310 <div class="yatra-trip-meta">
311 <?php if (!empty($booking->duration_days) || !empty($booking->duration_hours)) : ?>
312 <span class="yatra-meta-item">
313 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
314 <circle cx="12" cy="12" r="10"></circle>
315 <polyline points="12 6 12 12 16 14"></polyline>
316 </svg>
317 <?php
318 $days = (int) ($booking->duration_days ?? 0);
319 $nights = (int) ($booking->duration_nights ?? 0);
320 $hours = (int) ($booking->duration_hours ?? 0);
321
322 if ($hours > 0) {
323 // Hour-based day tour: "8 Hours", not "1 Day".
324 printf(
325 esc_html(
326 /* translators: %d: number of hours. */
327 _n('%d Hour', '%d Hours', $hours, 'yatra')
328 ),
329 $hours
330 );
331 } elseif ($days > 0 && $nights > 0) {
332 printf(
333 /* translators: 1: number of days, 2: number of nights. */
334 esc_html__('%1$d Days / %2$d Nights', 'yatra'),
335 $days,
336 $nights
337 );
338 } elseif ($days > 0) {
339 printf(
340 esc_html(
341 /* translators: %d: number of days. */
342 _n('%d Day', '%d Days', $days, 'yatra')
343 ),
344 $days
345 );
346 } elseif ($nights > 0) {
347 printf(
348 esc_html(
349 /* translators: %d: number of nights. */
350 _n('%d Night', '%d Nights', $nights, 'yatra')
351 ),
352 $nights
353 );
354 }
355 ?>
356 </span>
357 <?php endif; ?>
358
359 <?php if (!empty($booking->difficulty_level)) : ?>
360 <span class="yatra-meta-item">
361 <?php
362 $difficulty = \Yatra\Models\Trip::resolveDifficultyDisplay(
363 (string) $booking->difficulty_level
364 );
365
366 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
367 echo yatra_stored_picker_icon_markup(
368 $difficulty['icon_picker'] ?? null,
369 '',
370 'yatra-icon-sm'
371 );
372
373 echo esc_html($difficulty['level'] ?? (string) $booking->difficulty_level);
374 ?>
375 </span>
376 <?php endif; ?>
377 </div>
378
379 <?php if (!empty($booking->starting_location)) : ?>
380 <p class="yatra-trip-location">
381 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
382 <path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"></path>
383 <circle cx="12" cy="10" r="3"></circle>
384 </svg>
385 <?php echo esc_html($booking->starting_location); ?>
386 <?php if (!empty($booking->ending_location) && $booking->ending_location !== $booking->starting_location) : ?>
387 <?php echo esc_html($booking->ending_location); ?>
388 <?php endif; ?>
389 </p>
390 <?php endif; ?>
391
392 <?php if (!empty($booking->trip_destinations_list)) : ?>
393 <div class="yatra-trip-tags">
394 <span class="yatra-tag-label"><?php esc_html_e('Destinations:', 'yatra'); ?></span>
395 <div class="yatra-tag-group">
396 <?php foreach ($booking->trip_destinations_list as $destination) : ?>
397 <span class="yatra-tag-item"><?php echo esc_html($destination); ?></span>
398 <?php endforeach; ?>
399 </div>
400 </div>
401 <?php endif; ?>
402
403 <?php if (!empty($booking->trip_activities_list)) : ?>
404 <div class="yatra-trip-tags">
405 <span class="yatra-tag-label"><?php esc_html_e('Activities:', 'yatra'); ?></span>
406 <div class="yatra-tag-group">
407 <?php foreach ($booking->trip_activities_list as $activity) : ?>
408 <span class="yatra-tag-item"><?php echo esc_html($activity); ?></span>
409 <?php endforeach; ?>
410 </div>
411 </div>
412 <?php endif; ?>
413
414 <?php if (!empty($booking->trip_categories_list)) : ?>
415 <div class="yatra-trip-tags">
416 <span class="yatra-tag-label"><?php esc_html_e('Trip Type:', 'yatra'); ?></span>
417 <div class="yatra-tag-group">
418 <?php foreach ($booking->trip_categories_list as $category) : ?>
419 <span class="yatra-tag-item"><?php echo esc_html($category); ?></span>
420 <?php endforeach; ?>
421 </div>
422 </div>
423 <?php endif; ?>
424
425 </div>
426 </div>
427 </div>
428
429 <!-- Booking Details -->
430 <div class="yatra-confirmation-grid">
431 <!-- Left Column -->
432 <div class="yatra-confirmation-column">
433 <!-- Booking Info Card -->
434 <div class="yatra-confirmation-card">
435 <h3 class="yatra-card-title">
436 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
437 <rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect>
438 <line x1="16" y1="2" x2="16" y2="6"></line>
439 <line x1="8" y1="2" x2="8" y2="6"></line>
440 <line x1="3" y1="10" x2="21" y2="10"></line>
441 </svg>
442 <?php esc_html_e('Booking Information', 'yatra'); ?>
443 </h3>
444
445 <div class="yatra-info-grid">
446 <div class="yatra-info-item">
447 <span class="yatra-info-label"><?php esc_html_e('Status', 'yatra'); ?></span>
448 <span class="yatra-info-value">
449 <span class="yatra-status-badge" style="background: <?php echo esc_attr($status_style['bg']); ?>; color: <?php echo esc_attr($status_style['text']); ?>;">
450 <?php echo esc_html($status_style['label']); ?>
451 </span>
452 </span>
453 </div>
454 <div class="yatra-info-item">
455 <span class="yatra-info-label"><?php esc_html_e('Travel Date', 'yatra'); ?></span>
456 <span class="yatra-info-value"><?php echo esc_html($travel_date_formatted); ?></span>
457 </div>
458 <div class="yatra-info-item">
459 <span class="yatra-info-label"><?php esc_html_e('Number of Travelers', 'yatra'); ?></span>
460 <span class="yatra-info-value"><?php echo esc_html($booking->travelers_count); ?></span>
461 </div>
462 <div class="yatra-info-item">
463 <span class="yatra-info-label"><?php esc_html_e('Booked On', 'yatra'); ?></span>
464 <span class="yatra-info-value"><?php echo esc_html($booking_date_formatted); ?></span>
465 </div>
466 </div>
467 </div>
468
469 <!-- Travelers Card -->
470 <?php if (!empty($booking->travelers)) : ?>
471 <div class="yatra-confirmation-card">
472 <h3 class="yatra-card-title">
473 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
474 <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>
475 <circle cx="9" cy="7" r="4"></circle>
476 <path d="M23 21v-2a4 4 0 0 0-3-3.87"></path>
477 <path d="M16 3.13a4 4 0 0 1 0 7.75"></path>
478 </svg>
479 <?php esc_html_e('Travelers', 'yatra'); ?>
480 </h3>
481
482 <div class="yatra-travelers-list">
483 <?php foreach ($booking->travelers as $index => $traveler) :
484 $traveler_name = trim(($traveler['first_name'] ?? '') . ' ' . ($traveler['last_name'] ?? ''));
485 ?>
486 <div class="yatra-traveler-item">
487 <span class="yatra-traveler-number"><?php echo esc_html($index + 1); ?></span>
488 <div class="yatra-traveler-details">
489 <span class="yatra-traveler-name">
490 <?php echo esc_html($traveler_name ?: __('Traveler', 'yatra') . ' ' . ($index + 1)); ?>
491 </span>
492 <?php if (!empty($traveler['date_of_birth'])) : ?>
493 <span class="yatra-traveler-dob">
494 <?php echo esc_html(\Yatra\Helpers\FormatHelper::formatDate((string) $traveler['date_of_birth'])); ?>
495 </span>
496 <?php endif; ?>
497 </div>
498 </div>
499 <?php endforeach; ?>
500 </div>
501 </div>
502 <?php endif; ?>
503
504 <?php
505 // Allow gateways to inject cards (e.g., Bank Transfer instructions)
506 do_action('yatra_booking_confirmation_after_details', $booking);
507 ?>
508 </div>
509
510 <!-- Right Column -->
511 <div class="yatra-confirmation-column">
512 <!-- Payment Summary Card -->
513 <div class="yatra-confirmation-card yatra-payment-card">
514 <h3 class="yatra-card-title">
515 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
516 <rect x="1" y="4" width="22" height="16" rx="2" ry="2"></rect>
517 <line x1="1" y1="10" x2="23" y2="10"></line>
518 </svg>
519 <?php esc_html_e('Payment Summary', 'yatra'); ?>
520 </h3>
521
522 <div class="yatra-payment-rows">
523 <?php
524 // ── Raw figures from DB ───────────────────────────────────
525 $db_subtotal = (float) ($booking->subtotal ?? $booking->total_amount);
526 $discount_amount = (float) ($booking->discount_amount ?? 0);
527 $itinerary_costs_total = (float) ($booking->itinerary_costs_total ?? 0);
528 $tax_amount = (float) ($booking->tax_amount ?? 0);
529 $tax_inclusive = !empty($booking->tax_inclusive);
530 $total_amount = (float) $booking->total_amount;
531 $amount_paid = (float) ($booking->amount_paid ?? 0);
532 $amount_due = (float) ($booking->amount_due ?? 0);
533
534 // ── Tax breakdown (built first so it can gate later rows) ─
535 $tax_breakdown = [];
536 if (!empty($booking->tax_details)) {
537 $taxes = json_decode($booking->tax_details, true) ?: [];
538 foreach ($taxes as $tax) {
539 $tax_breakdown[] = [
540 'name' => $tax['name'] ?? __('Tax', 'yatra'),
541 'rate' => (float) ($tax['rate'] ?? 0),
542 'amount' => (float) ($tax['amount'] ?? 0),
543 ];
544 }
545 } elseif ($tax_amount > 0) {
546 $tax_breakdown[] = [
547 'name' => __('Tax', 'yatra'),
548 'rate' => (float) ($booking->tax_rate ?? 0),
549 'amount' => $tax_amount,
550 ];
551 }
552
553 // ── Itinerary costs ───────────────────────────────────────
554 $itinerary_costs = [];
555 if (!empty($booking->itinerary_costs)) {
556 $itinerary_costs = json_decode($booking->itinerary_costs, true) ?: [];
557 }
558
559 // ── Additional services ───────────────────────────────────
560 $raw_services = apply_filters('yatra_booking_get_services', [], (int) ($booking->id ?? 0));
561 $selected_services = [];
562 if (!empty($raw_services) && is_array($raw_services)) {
563 foreach ($raw_services as $s) {
564 $arr = is_array($s) ? $s : (array) $s;
565 if (!isset($arr['selected']) || !empty($arr['selected'])) {
566 $selected_services[] = $arr;
567 }
568 }
569 }
570 $services_total = 0.0;
571 foreach ($selected_services as $s) {
572 $services_total += (float) ($s['total_price'] ?? $s['calculated_price'] ?? $s['total_cost'] ?? $s['amount'] ?? $s['unit_price'] ?? $s['price'] ?? 0);
573 }
574
575 // ── Derived amounts ───────────────────────────────────────
576 // base_trip_cost: the trip price without services (services are embedded in db_subtotal by Pro)
577 $base_trip_cost = $db_subtotal - $services_total;
578 // taxable_amount: what tax is calculated on
579 $taxable_amount = max(0.0, $db_subtotal - $discount_amount) + $itinerary_costs_total;
580
581 $has_services = !empty($selected_services);
582 $has_discount = $discount_amount > 0;
583 $has_itinerary = !empty($itinerary_costs) && $itinerary_costs_total > 0;
584 $has_tax = !empty($tax_breakdown);
585 $show_taxable_row = $has_tax && ($has_discount || $has_itinerary);
586 ?>
587
588 <!-- Trip Base Price (always the first line) -->
589 <div class="yatra-payment-row">
590 <span>
591 <?php esc_html_e('Trip Base Price', 'yatra'); ?>
592 <?php if ($tax_inclusive): ?>
593 <span style="display:inline-flex;align-items:center;padding:1px 6px;border-radius:4px;font-size:0.72em;font-weight:600;background:#eff6ff;color:#1d4ed8;margin-left:5px;letter-spacing:0;">
594 <?php esc_html_e('Tax Incl.', 'yatra'); ?>
595 </span>
596 <?php endif; ?>
597 </span>
598 <span><?php echo esc_html(yatra_format_price($base_trip_cost, $booking->currency)); ?></span>
599 </div>
600
601 <?php if ($has_services): ?>
602 <!-- Additional Services section header -->
603 <div class="yatra-payment-row" style="margin-top: 4px;">
604 <span style="font-size: 0.75em; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: #6b7280;">
605 + <?php esc_html_e('Additional Services', 'yatra'); ?>
606 </span>
607 <span></span>
608 </div>
609 <!-- Service line items -->
610 <?php foreach ($selected_services as $svc): ?>
611 <?php
612 $svc_name = $svc['service_name'] ?? $svc['name'] ?? $svc['title'] ?? $svc['label'] ?? __('Service', 'yatra');
613 $svc_amount = (float) ($svc['total_price'] ?? $svc['calculated_price'] ?? $svc['total_cost'] ?? $svc['amount'] ?? $svc['unit_price'] ?? $svc['price'] ?? 0);
614 ?>
615 <div class="yatra-payment-row" style="margin-left: 16px;">
616 <span><?php echo esc_html($svc_name); ?></span>
617 <span><?php echo esc_html(yatra_format_price($svc_amount, $booking->currency, false)); ?></span>
618 </div>
619 <?php endforeach; ?>
620 <!-- Gross Total = Trip Base Price + Services -->
621 <div class="yatra-payment-row" style="border-top: 1px solid #e5e7eb; margin-top: 6px; padding-top: 6px;">
622 <span><strong><?php esc_html_e('Gross Total', 'yatra'); ?></strong></span>
623 <span><strong><?php echo esc_html(yatra_format_price($db_subtotal, $booking->currency)); ?></strong></span>
624 </div>
625 <?php endif; ?>
626
627 <?php if ($has_discount): ?>
628 <!-- Discount -->
629 <div class="yatra-payment-row">
630 <span><?php esc_html_e('Discount', 'yatra'); ?></span>
631 <span style="color: #059669; font-weight: 500;">-<?php echo esc_html(yatra_format_price($discount_amount, $booking->currency)); ?></span>
632 </div>
633 <?php endif; ?>
634
635 <?php if ($has_itinerary): ?>
636 <!-- Itinerary costs header -->
637 <div class="yatra-payment-row" style="margin-top: 4px;">
638 <span><strong><?php esc_html_e('Itinerary Costs', 'yatra'); ?></strong></span>
639 <span></span>
640 </div>
641 <?php foreach ($itinerary_costs as $cost): ?>
642 <div class="yatra-payment-row" style="margin-left: 20px;">
643 <span>
644 <?php echo esc_html($cost['name']); ?>
645 <?php if (!empty($cost['price_per'])): ?>
646 <small style="opacity: 0.65;">
647 <?php
648 if ($cost['price_per'] === 'person') {
649 esc_html_e('(per person)', 'yatra');
650 } elseif ($cost['price_per'] === 'group') {
651 esc_html_e('(per booking)', 'yatra');
652 } else {
653 esc_html_e('(flat rate)', 'yatra');
654 }
655 ?>
656 </small>
657 <?php endif; ?>
658 </span>
659 <span><?php echo esc_html(yatra_format_price($cost['total_cost'] ?? $cost['price'], $booking->currency)); ?></span>
660 </div>
661 <?php endforeach; ?>
662 <?php endif; ?>
663
664 <?php if (!$tax_inclusive && $show_taxable_row): ?>
665 <!-- Taxable Amount (only for exclusive tax when there are deductions above it) -->
666 <div class="yatra-payment-row" style="border-top: 1px dashed #e5e7eb; margin-top: 8px; padding-top: 8px;">
667 <span><strong><?php esc_html_e('Taxable Amount', 'yatra'); ?></strong></span>
668 <span><strong><?php echo esc_html(yatra_format_price($taxable_amount, $booking->currency)); ?></strong></span>
669 </div>
670 <?php endif; ?>
671
672 <?php if ($has_tax && !$tax_inclusive): ?>
673 <!-- Exclusive tax: shown as an addition before Net Amount -->
674 <div class="yatra-payment-row" style="margin-top: 4px;">
675 <span style="font-size: 0.75em; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: #6b7280;">
676 + <?php esc_html_e('Tax', 'yatra'); ?>
677 </span>
678 <span></span>
679 </div>
680 <?php foreach ($tax_breakdown as $tax): ?>
681 <div class="yatra-payment-row" style="margin-left: 16px;">
682 <span>
683 <?php echo esc_html($tax['name']); ?>
684 <?php if ($tax['rate'] > 0): ?>
685 (<?php echo esc_html($tax['rate']); ?>%)
686 <?php endif; ?>
687 </span>
688 <span>+<?php echo esc_html(yatra_format_price($tax['amount'], $booking->currency)); ?></span>
689 </div>
690 <?php endforeach; ?>
691 <?php endif; ?>
692
693 <!-- Net Amount -->
694 <div class="yatra-payment-row" style="border-top: 2px solid #111827; margin-top: 10px; padding-top: 10px;">
695 <span style="font-size: 1.05em;"><strong><?php esc_html_e('Net Amount', 'yatra'); ?></strong></span>
696 <span style="font-size: 1.05em;"><strong><?php echo esc_html(yatra_format_price($total_amount, $booking->currency)); ?></strong></span>
697 </div>
698
699 <?php if ($has_tax && $tax_inclusive): ?>
700 <!-- Inclusive tax: shown as an informational footnote after Net Amount -->
701 <?php foreach ($tax_breakdown as $tax): ?>
702 <div class="yatra-payment-row" style="margin-top: 4px; opacity: 0.7;">
703 <span style="font-size: 0.85em; font-style: italic;">
704 <?php
705 printf(
706 /* translators: %1$s = tax name, %2$s = rate, %3$s = amount */
707 esc_html__('Incl. %1$s%2$s: %3$s', 'yatra'),
708 esc_html($tax['name']),
709 $tax['rate'] > 0 ? ' (' . esc_html($tax['rate']) . '%)' : '',
710 esc_html(yatra_format_price($tax['amount'], $booking->currency))
711 );
712 ?>
713 </span>
714 <span></span>
715 </div>
716 <?php endforeach; ?>
717 <?php endif; ?>
718
719 <?php if ($amount_paid > 0): ?>
720 <div class="yatra-payment-row" style="margin-top: 6px;">
721 <span><?php esc_html_e('Amount Paid', 'yatra'); ?></span>
722 <span style="color: #059669;"><?php echo esc_html(yatra_format_price($amount_paid, $booking->currency)); ?></span>
723 </div>
724 <?php endif; ?>
725
726 <?php if ($amount_due > 0): ?>
727 <?php
728 // Label the "due now" amount by payment type so a
729 // deposit/partial reads clearly instead of just "Due Now".
730 $payment_method_type = (string) ($booking->payment_method ?? 'full');
731 $remaining_balance = max(0.0, $total_amount - $amount_paid - $amount_due);
732 if ($payment_method_type === 'deposit') {
733 $due_now_label = __('Deposit Due Now', 'yatra');
734 } elseif ($payment_method_type === 'partial') {
735 $due_now_label = __('Partial Payment Due Now', 'yatra');
736 } else {
737 $due_now_label = __('Due Now', 'yatra');
738 }
739 ?>
740 <div class="yatra-payment-row yatra-due-row">
741 <span><strong><?php echo esc_html($due_now_label); ?></strong></span>
742 <span><strong><?php echo esc_html(yatra_format_price($amount_due, $booking->currency)); ?></strong></span>
743 </div>
744 <?php if ($payment_method_type !== 'full' && $remaining_balance > 0.01): ?>
745 <div class="yatra-payment-row" style="margin-top: 6px;">
746 <span><?php esc_html_e('Remaining Balance', 'yatra'); ?></span>
747 <span><?php echo esc_html(yatra_format_price($remaining_balance, $booking->currency)); ?></span>
748 </div>
749 <?php endif; ?>
750 <?php endif; ?>
751 </div>
752
753 <div class="yatra-payment-method">
754 <span class="yatra-pm-label"><?php esc_html_e('Payment Method:', 'yatra'); ?></span>
755 <span class="yatra-pm-value"><?php echo esc_html(ucwords(str_replace('_', ' ', (string) $display_payment_gateway))); ?></span>
756 </div>
757 </div>
758
759 <!-- Contact Info Card -->
760 <div class="yatra-confirmation-card">
761 <h3 class="yatra-card-title">
762 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
763 <path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path>
764 <polyline points="22,6 12,13 2,6"></polyline>
765 </svg>
766 <?php esc_html_e('Contact Information', 'yatra'); ?>
767 </h3>
768
769 <div class="yatra-contact-info">
770 <?php
771 // Try to get contact data from multiple sources
772 $contact_data = [];
773 if (!empty($booking->contact_data)) {
774 $contact_data = json_decode($booking->contact_data, true) ?: [];
775 }
776
777 $contact_name = trim((
778 $contact_data['first_name'] ??
779 $booking->contact_first_name ??
780 ($booking->contact['first_name'] ?? '')
781 ) . ' ' . (
782 $contact_data['last_name'] ??
783 $booking->contact_last_name ??
784 ($booking->contact['last_name'] ?? '')
785 ));
786
787 $contact_email = $contact_data['email'] ?? $booking->contact_email ?? ($booking->contact['email'] ?? '');
788 $contact_phone = $contact_data['phone'] ?? $booking->contact_phone ?? ($booking->contact['phone'] ?? '');
789 ?>
790
791 <?php if ($contact_name) : ?>
792 <p class="yatra-contact-item">
793 <strong><?php esc_html_e('Name:', 'yatra'); ?></strong>
794 <?php echo esc_html($contact_name); ?>
795 </p>
796 <?php endif; ?>
797
798 <?php if ($contact_email) : ?>
799 <p class="yatra-contact-item">
800 <strong><?php esc_html_e('Email:', 'yatra'); ?></strong>
801 <?php echo esc_html($contact_email); ?>
802 </p>
803 <?php endif; ?>
804
805 <?php if ($contact_phone) : ?>
806 <p class="yatra-contact-item">
807 <strong><?php esc_html_e('Phone:', 'yatra'); ?></strong>
808 <?php echo esc_html($contact_phone); ?>
809 </p>
810 <?php endif; ?>
811
812 <?php if (!$contact_name && !$contact_email && !$contact_phone) : ?>
813 <p class="yatra-contact-item">
814 <em><?php esc_html_e('Contact information not available', 'yatra'); ?></em>
815 </p>
816 <?php endif; ?>
817 </div>
818 </div>
819 </div>
820 </div>
821
822 <!-- What's Next Section -->
823 <div class="yatra-confirmation-card yatra-whats-next">
824 <h3 class="yatra-card-title">
825 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
826 <circle cx="12" cy="12" r="10"></circle>
827 <polyline points="12 16 16 12 12 8"></polyline>
828 <line x1="8" y1="12" x2="16" y2="12"></line>
829 </svg>
830 <?php esc_html_e("What's Next?", 'yatra'); ?>
831 </h3>
832
833 <div class="yatra-next-steps">
834 <div class="yatra-step">
835 <span class="yatra-step-number">1</span>
836 <div class="yatra-step-content">
837 <h4><?php esc_html_e('Check Your Email', 'yatra'); ?></h4>
838 <p><?php esc_html_e('We\'ve sent a confirmation email with all the details to your registered email address.', 'yatra'); ?></p>
839 </div>
840 </div>
841
842 <div class="yatra-step">
843 <span class="yatra-step-number">2</span>
844 <div class="yatra-step-content">
845 <h4><?php esc_html_e('Detailed Itinerary', 'yatra'); ?></h4>
846 <p><?php esc_html_e('You\'ll receive a detailed itinerary and preparation guide within 24-48 hours.', 'yatra'); ?></p>
847 </div>
848 </div>
849
850 <div class="yatra-step">
851 <span class="yatra-step-number">3</span>
852 <div class="yatra-step-content">
853 <h4><?php esc_html_e('Prepare for Adventure', 'yatra'); ?></h4>
854 <p><?php esc_html_e('Ensure all travelers have valid ID or travel documents and any required visas for your destination.', 'yatra'); ?></p>
855 </div>
856 </div>
857 </div>
858 </div>
859
860 <!-- Action Buttons -->
861 <div class="yatra-confirmation-actions">
862 <a href="<?php echo esc_url(home_url('/')); ?>" class="yatra-btn yatra-btn-secondary">
863 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
864 <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path>
865 <polyline points="9 22 9 12 15 12 15 22"></polyline>
866 </svg>
867 <?php esc_html_e('Return to Home', 'yatra'); ?>
868 </a>
869
870 <?php
871 // Get latest payment for this booking to enable invoice download.
872 // The invoice endpoint authorises via: admin → owner → signed invoice_token → guest booking_token.
873 // We always issue a signed invoice_token here so the link works for guests
874 // (no session required) AND for logged-in users who don't own the booking
875 // (e.g. site admins viewing the page) — without re-checking login on the client.
876 $paymentRepository = new \Yatra\Repositories\PaymentRepository();
877 $latestPayment = $paymentRepository->findLatestByBookingId((int) $booking->id);
878 if ($latestPayment && in_array($latestPayment->status, ['completed', 'paid'], true)) :
879 $invoiceToken = \Yatra\Controllers\PaymentGatewayController::issueInvoiceToken(
880 (int) $latestPayment->id,
881 (int) ($latestPayment->booking_id ?? $booking->id)
882 );
883 $invoiceUrl = add_query_arg(
884 [
885 'download' => '1',
886 'invoice_token' => $invoiceToken,
887 ],
888 rest_url('yatra/v1/payment/' . (int) $latestPayment->id . '/invoice')
889 );
890 ?>
891 <a href="<?php echo esc_url($invoiceUrl); ?>"
892 target="_blank"
893 rel="noopener"
894 class="yatra-btn yatra-btn-primary">
895 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
896 <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
897 <polyline points="7 10 12 15 17 10"></polyline>
898 <line x1="12" y1="15" x2="12" y2="3"></line>
899 </svg>
900 <?php esc_html_e('Download Invoice', 'yatra'); ?>
901 </a>
902 <?php
903 // No completed payment yet (e.g. Bank Transfer / offline): offer a
904 // pro-forma invoice that carries the payment instructions so the
905 // customer knows how to pay. Uses a booking-scoped invoice token.
906 elseif ((float) ($booking->amount_due ?? $booking->total_amount ?? 0) > 0) :
907 $proformaToken = \Yatra\Controllers\PaymentGatewayController::issueInvoiceToken(0, (int) $booking->id);
908 $proformaUrl = add_query_arg(
909 [
910 'download' => '1',
911 'invoice_token' => $proformaToken,
912 ],
913 rest_url('yatra/v1/booking/' . (int) $booking->id . '/invoice')
914 );
915 ?>
916 <a href="<?php echo esc_url($proformaUrl); ?>"
917 target="_blank"
918 rel="noopener"
919 class="yatra-btn yatra-btn-primary">
920 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
921 <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
922 <polyline points="7 10 12 15 17 10"></polyline>
923 <line x1="12" y1="15" x2="12" y2="3"></line>
924 </svg>
925 <?php esc_html_e('Download Invoice', 'yatra'); ?>
926 </a>
927 <?php endif; ?>
928
929 <button type="button" data-yatra-print="confirmation" class="yatra-btn yatra-btn-outline">
930 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
931 <polyline points="6 9 6 2 18 2 18 9"></polyline>
932 <path d="M6 18H4a2 2 0 0 1-2-2v-5a2 2 0 0 1 2-2h16a2 2 0 0 1 2 2v5a2 2 0 0 1-2 2h-2"></path>
933 <rect x="6" y="14" width="12" height="8"></rect>
934 </svg>
935 <?php esc_html_e('Print Confirmation', 'yatra'); ?>
936 </button>
937 </div>
938
939 </div>
940 </div>
941 </div>
942
943 <style>
944 /* Confirmation Page Styles */
945 .yatra-confirmation-wrapper {
946 max-width: 1300px;
947 margin: 0 auto;
948 padding: 40px 20px;
949 }
950
951 .yatra-confirmation-container {
952 max-width: 900px;
953 margin: 0 auto;
954 }
955
956 .yatra-confirmation-header {
957 text-align: center;
958 margin-bottom: 40px;
959 }
960
961 .yatra-confirmation-icon {
962 width: 100px;
963 height: 100px;
964 margin: 0 auto 24px;
965 background: linear-gradient(135deg, #22c55e 0%, #16a34a 100%);
966 border-radius: 50%;
967 display: flex;
968 align-items: center;
969 justify-content: center;
970 animation: scaleIn 0.5s ease-out;
971 }
972
973 .yatra-confirmation-icon svg {
974 width: 50px;
975 height: 50px;
976 color: white;
977 }
978
979 @keyframes scaleIn {
980 0% { transform: scale(0); opacity: 0; }
981 50% { transform: scale(1.1); }
982 100% { transform: scale(1); opacity: 1; }
983 }
984
985 .yatra-confirmation-title {
986 font-size: 36px;
987 font-weight: 700;
988 color: #111827;
989 margin: 0 0 12px;
990 }
991
992 .yatra-confirmation-subtitle {
993 font-size: 18px;
994 color: #6b7280;
995 margin: 0 0 24px;
996 }
997
998 .yatra-confirmation-reference {
999 display: inline-flex;
1000 align-items: center;
1001 gap: 12px;
1002 background: #f3f4f6;
1003 padding: 12px 24px;
1004 border-radius: 100px;
1005 }
1006
1007 .yatra-ref-label {
1008 color: #6b7280;
1009 font-size: 14px;
1010 }
1011
1012 .yatra-ref-code {
1013 font-size: 18px;
1014 font-weight: 700;
1015 color: #111827;
1016 font-family: monospace;
1017 letter-spacing: 1px;
1018 }
1019
1020 .yatra-confirmation-card {
1021 background: #fff;
1022 border: 1px solid #e5e7eb;
1023 border-radius: 16px;
1024 padding: 24px;
1025 margin-bottom: 24px;
1026 }
1027
1028 .yatra-card-title {
1029 display: flex;
1030 align-items: center;
1031 gap: 12px;
1032 font-size: 18px;
1033 font-weight: 600;
1034 color: #111827;
1035 margin: 0 0 20px;
1036 padding-bottom: 16px;
1037 border-bottom: 1px solid #e5e7eb;
1038 }
1039
1040 .yatra-card-title svg {
1041 width: 22px;
1042 height: 22px;
1043 color: #3b82f6;
1044 }
1045
1046 .yatra-trip-summary-card {
1047 background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
1048 border-color: #bfdbfe;
1049 }
1050
1051 .yatra-trip-summary {
1052 display: flex;
1053 gap: 24px;
1054 align-items: center;
1055 }
1056
1057 .yatra-trip-image {
1058 width: 120px;
1059 height: 120px;
1060 border-radius: 12px;
1061 overflow: hidden;
1062 flex-shrink: 0;
1063 }
1064
1065 .yatra-trip-image img {
1066 width: 100%;
1067 height: 100%;
1068 object-fit: cover;
1069 }
1070
1071 .yatra-trip-name {
1072 font-size: 22px;
1073 font-weight: 700;
1074 color: #111827;
1075 margin: 0 0 12px;
1076 }
1077
1078 /* Star rating. This confirmation page only enqueues yatra-common + fontawesome,
1079 not booking.css/trip.css where these live, so without them the inline SVG
1080 stars render with no size or colour (invisible). Mirrors booking.css. */
1081 .yatra-trip-rating {
1082 display: flex;
1083 align-items: center;
1084 gap: 12px;
1085 margin-bottom: 12px;
1086 }
1087
1088 .yatra-rating-stars {
1089 display: inline-flex;
1090 gap: 4px;
1091 }
1092
1093 .yatra-star {
1094 width: 20px;
1095 height: 20px;
1096 color: #e2e8f0;
1097 }
1098
1099 .yatra-star svg {
1100 width: 100%;
1101 height: 100%;
1102 }
1103
1104 .yatra-star-filled {
1105 color: #f59e0b;
1106 }
1107
1108 /* Half star: base star stays grey; overlay the left half in amber via an
1109 SVG mask (size-independent, so it tracks the star's dimensions). */
1110 .yatra-star-half {
1111 position: relative;
1112 color: #e2e8f0;
1113 }
1114
1115 .yatra-star-half::after {
1116 content: "";
1117 position: absolute;
1118 top: 0;
1119 left: 0;
1120 bottom: 0;
1121 width: 50%;
1122 overflow: hidden;
1123 background: #f59e0b;
1124 -webkit-mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpolygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26'/%3E%3C/svg%3E") no-repeat left center / 200% 100%;
1125 mask: url("data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24'%3E%3Cpolygon points='12 2 15.09 8.26 22 9.27 17 14.14 18.18 21.02 12 17.77 5.82 21.02 7 14.14 2 9.27 8.91 8.26'/%3E%3C/svg%3E") no-repeat left center / 200% 100%;
1126 }
1127
1128 .yatra-rating-meta strong {
1129 color: #0f172a;
1130 margin-right: 6px;
1131 }
1132
1133 .yatra-rating-meta span {
1134 color: #64748b;
1135 font-size: 14px;
1136 }
1137
1138 .yatra-trip-meta {
1139 display: flex;
1140 gap: 20px;
1141 flex-wrap: wrap;
1142 margin-bottom: 8px;
1143 }
1144
1145 .yatra-meta-item {
1146 display: flex;
1147 align-items: center;
1148 gap: 6px;
1149 font-size: 14px;
1150 color: #4b5563;
1151 }
1152
1153 .yatra-meta-item svg {
1154 width: 16px;
1155 height: 16px;
1156 }
1157
1158 .yatra-trip-location {
1159 display: flex;
1160 align-items: center;
1161 gap: 6px;
1162 font-size: 14px;
1163 color: #6b7280;
1164 margin: 0;
1165 }
1166
1167 .yatra-trip-location svg {
1168 width: 16px;
1169 height: 16px;
1170 }
1171
1172 .yatra-confirmation-grid {
1173 display: grid;
1174 grid-template-columns: 1fr 1fr;
1175 gap: 24px;
1176 }
1177
1178 @media (max-width: 768px) {
1179 .yatra-confirmation-grid {
1180 grid-template-columns: 1fr;
1181 }
1182
1183 .yatra-trip-summary {
1184 flex-direction: column;
1185 text-align: center;
1186 }
1187
1188 .yatra-info-grid {
1189 grid-template-columns: 1fr;
1190 gap: 12px;
1191 }
1192 }
1193
1194 .yatra-info-grid {
1195 display: grid;
1196 grid-template-columns: 1fr 1fr;
1197 gap: 16px;
1198 }
1199
1200 .yatra-info-item {
1201 display: flex;
1202 flex-direction: column;
1203 gap: 4px;
1204 padding: 12px 14px;
1205 background: #f9fafb;
1206 border: 1px solid #eef2f7;
1207 border-radius: 12px;
1208 }
1209
1210 .yatra-info-label {
1211 font-size: 13px;
1212 color: #6b7280;
1213 line-height: 1.2;
1214 }
1215
1216 .yatra-info-value {
1217 font-size: 15px;
1218 font-weight: 600;
1219 color: #111827;
1220 line-height: 1.25;
1221 text-align: left;
1222 }
1223
1224 .yatra-status-badge {
1225 display: inline-block;
1226 padding: 4px 12px;
1227 border-radius: 100px;
1228 font-size: 13px;
1229 font-weight: 600;
1230 }
1231
1232 .yatra-travelers-list {
1233 display: flex;
1234 flex-direction: column;
1235 gap: 12px;
1236 }
1237
1238 .yatra-traveler-item {
1239 display: flex;
1240 align-items: center;
1241 gap: 12px;
1242 padding: 12px;
1243 background: #f9fafb;
1244 border-radius: 8px;
1245 }
1246
1247 .yatra-traveler-number {
1248 width: 28px;
1249 height: 28px;
1250 display: flex;
1251 align-items: center;
1252 justify-content: center;
1253 background: #3b82f6;
1254 color: white;
1255 border-radius: 50%;
1256 font-size: 13px;
1257 font-weight: 600;
1258 }
1259
1260 .yatra-traveler-name {
1261 font-weight: 600;
1262 color: #111827;
1263 }
1264
1265 .yatra-traveler-dob {
1266 font-size: 13px;
1267 color: #6b7280;
1268 }
1269
1270 .yatra-payment-card {
1271 background: #fafafa;
1272 }
1273
1274 .yatra-payment-rows {
1275 border: 1px solid #e5e7eb;
1276 border-radius: 8px;
1277 overflow: hidden;
1278 }
1279
1280 .yatra-payment-row {
1281 display: flex;
1282 justify-content: space-between;
1283 padding: 12px 16px;
1284 border-bottom: 1px solid #e5e7eb;
1285 }
1286
1287 .yatra-payment-row:last-child {
1288 border-bottom: none;
1289 background: #111827;
1290 color: white;
1291 font-weight: 600;
1292 }
1293
1294 .yatra-discount-row span:last-child {
1295 color: #22c55e;
1296 }
1297
1298 /* Bank-transfer details (markup injected by Yatra Pro's Bank Transfer gateway
1299 into this page). The card reuses this page's .yatra-confirmation-card /
1300 .yatra-card-title classes, but its rows had no styling at all, so the values
1301 sat immediately after their label while every other row on the page is
1302 flex/space-between — the bank values were the only ones not flush right.
1303 Styling lives here because this template owns the confirmation page's CSS
1304 and Pro enqueues no stylesheet on this page. */
1305 .yatra-bank-info-grid {
1306 border: 1px solid #e5e7eb;
1307 border-radius: 8px;
1308 overflow: hidden;
1309 }
1310
1311 .yatra-bank-info-item {
1312 display: flex;
1313 justify-content: space-between;
1314 align-items: baseline;
1315 gap: 12px;
1316 padding: 12px 16px;
1317 border-bottom: 1px solid #e5e7eb;
1318 }
1319
1320 .yatra-bank-info-item:last-child {
1321 border-bottom: none;
1322 }
1323
1324 .yatra-bank-label {
1325 color: #6b7280;
1326 flex-shrink: 0;
1327 }
1328
1329 .yatra-bank-value {
1330 text-align: right;
1331 word-break: break-word;
1332 }
1333
1334 .yatra-payment-method {
1335 margin-top: 16px;
1336 padding: 12px;
1337 background: white;
1338 border-radius: 8px;
1339 display: flex;
1340 justify-content: space-between;
1341 }
1342
1343 .yatra-pm-label {
1344 color: #6b7280;
1345 }
1346
1347 .yatra-pm-value {
1348 font-weight: 600;
1349 color: #111827;
1350 }
1351
1352 .yatra-contact-info p {
1353 margin: 0 0 8px;
1354 }
1355
1356 .yatra-whats-next {
1357 background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%);
1358 border-color: #bbf7d0;
1359 }
1360
1361 .yatra-next-steps {
1362 display: flex;
1363 flex-direction: column;
1364 gap: 20px;
1365 }
1366
1367 .yatra-step {
1368 display: flex;
1369 gap: 16px;
1370 }
1371
1372 .yatra-step-number {
1373 width: 32px;
1374 height: 32px;
1375 display: flex;
1376 align-items: center;
1377 justify-content: center;
1378 background: #22c55e;
1379 color: white;
1380 border-radius: 50%;
1381 font-weight: 600;
1382 flex-shrink: 0;
1383 }
1384
1385 .yatra-step-content h4 {
1386 margin: 0 0 4px;
1387 font-size: 16px;
1388 color: #111827;
1389 }
1390
1391 .yatra-step-content p {
1392 margin: 0;
1393 font-size: 14px;
1394 color: #6b7280;
1395 }
1396
1397 .yatra-confirmation-actions {
1398 display: flex;
1399 gap: 16px;
1400 justify-content: center;
1401 margin-top: 32px;
1402 }
1403
1404 .yatra-btn {
1405 display: inline-flex;
1406 align-items: center;
1407 gap: 8px;
1408 padding: 14px 28px;
1409 border-radius: 8px;
1410 font-size: 15px;
1411 font-weight: 600;
1412 text-decoration: none;
1413 cursor: pointer;
1414 transition: all 0.2s;
1415 border: none;
1416 }
1417
1418 .yatra-btn svg {
1419 width: 18px;
1420 height: 18px;
1421 }
1422
1423 .yatra-btn-secondary {
1424 background: #3b82f6;
1425 color: white;
1426 }
1427
1428 .yatra-btn-secondary:hover {
1429 background: #2563eb;
1430 }
1431
1432 .yatra-btn-outline {
1433 background: white;
1434 color: #374151;
1435 border: 2px solid #e5e7eb;
1436 }
1437
1438 .yatra-btn-outline:hover {
1439 border-color: #3b82f6;
1440 color: #3b82f6;
1441 }
1442
1443 /* =====================================================================
1444 Print Styles — produce a clean, single-page-friendly receipt.
1445 Triggered by the print button (adds .yatra-printing-confirmation
1446 to <body> + clones the confirmation card into .yatra-print-root).
1447 ===================================================================== */
1448 @media print {
1449 @page {
1450 size: A4;
1451 margin: 9mm 10mm;
1452 }
1453
1454 /* Force browsers to print our colors / borders */
1455 body.yatra-printing-confirmation,
1456 body.yatra-printing-confirmation * {
1457 -webkit-print-color-adjust: exact !important;
1458 print-color-adjust: exact !important;
1459 color-adjust: exact !important;
1460 }
1461
1462 /* Reset body, kill animations & transitions */
1463 body.yatra-printing-confirmation {
1464 background: #fff !important;
1465 color: #111827 !important;
1466 font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
1467 Helvetica, Arial, sans-serif !important;
1468 font-size: 10pt !important;
1469 line-height: 1.45 !important;
1470 }
1471 body.yatra-printing-confirmation *,
1472 body.yatra-printing-confirmation *::before,
1473 body.yatra-printing-confirmation *::after {
1474 animation: none !important;
1475 transition: none !important;
1476 box-shadow: none !important;
1477 text-shadow: none !important;
1478 }
1479
1480 /* Hide everything except our cloned print root */
1481 body.yatra-printing-confirmation > *:not(.yatra-print-root) {
1482 display: none !important;
1483 }
1484 body.yatra-printing-confirmation .yatra-print-root,
1485 body.yatra-printing-confirmation .yatra-print-root * {
1486 visibility: visible;
1487 }
1488 body.yatra-printing-confirmation .yatra-print-root {
1489 position: static !important;
1490 left: auto;
1491 top: auto;
1492 width: 100%;
1493 margin: 0;
1494 padding: 0;
1495 }
1496
1497 /* Wrappers — remove screen padding/widths */
1498 body.yatra-printing-confirmation .yatra-confirmation-wrapper,
1499 body.yatra-printing-confirmation .yatra-confirmation-container {
1500 max-width: none !important;
1501 margin: 0 !important;
1502 padding: 0 !important;
1503 }
1504
1505 /* Hide things that don't belong on paper */
1506 body.yatra-printing-confirmation .yatra-confirmation-actions,
1507 body.yatra-printing-confirmation .yatra-no-print,
1508 body.yatra-printing-confirmation .yatra-whats-next,
1509 body.yatra-printing-confirmation .yatra-trip-rating {
1510 display: none !important;
1511 }
1512
1513 /* Confirmation header — compact, two-column with status icon left & ref right */
1514 body.yatra-printing-confirmation .yatra-confirmation-header {
1515 display: flex !important;
1516 align-items: center !important;
1517 justify-content: space-between !important;
1518 gap: 16pt !important;
1519 text-align: left !important;
1520 margin: 0 0 8pt !important;
1521 padding: 0 0 6pt !important;
1522 border-bottom: 1pt solid #111827 !important;
1523 }
1524 body.yatra-printing-confirmation .yatra-confirmation-icon {
1525 width: 28pt !important;
1526 height: 28pt !important;
1527 margin: 0 !important;
1528 background: #16a34a !important;
1529 flex-shrink: 0 !important;
1530 }
1531 body.yatra-printing-confirmation .yatra-confirmation-icon svg {
1532 width: 16pt !important;
1533 height: 16pt !important;
1534 }
1535 body.yatra-printing-confirmation .yatra-confirmation-title {
1536 font-size: 14pt !important;
1537 font-weight: 700 !important;
1538 margin: 0 !important;
1539 flex: 1 !important;
1540 color: #111827 !important;
1541 }
1542 body.yatra-printing-confirmation .yatra-confirmation-subtitle {
1543 display: none !important;
1544 }
1545 body.yatra-printing-confirmation .yatra-confirmation-reference {
1546 display: inline-flex !important;
1547 flex-direction: column !important;
1548 align-items: flex-end !important;
1549 gap: 2pt !important;
1550 background: transparent !important;
1551 padding: 0 !important;
1552 border: none !important;
1553 border-radius: 0 !important;
1554 }
1555 body.yatra-printing-confirmation .yatra-ref-label {
1556 font-size: 8pt !important;
1557 text-transform: uppercase !important;
1558 letter-spacing: 0.4pt !important;
1559 color: #6b7280 !important;
1560 }
1561 body.yatra-printing-confirmation .yatra-ref-code {
1562 font-size: 11pt !important;
1563 font-weight: 700 !important;
1564 color: #111827 !important;
1565 letter-spacing: 0.6pt !important;
1566 }
1567
1568 /* Cards — flat, thin border, never split across pages */
1569 body.yatra-printing-confirmation .yatra-confirmation-card {
1570 background: #fff !important;
1571 border: 0.75pt solid #d1d5db !important;
1572 border-radius: 3pt !important;
1573 padding: 8pt 10pt !important;
1574 margin: 0 0 6pt !important;
1575 page-break-inside: avoid !important;
1576 break-inside: avoid !important;
1577 }
1578 body.yatra-printing-confirmation .yatra-trip-summary-card {
1579 background: #f9fafb !important;
1580 border-color: #d1d5db !important;
1581 }
1582 body.yatra-printing-confirmation .yatra-card-title {
1583 font-size: 10.5pt !important;
1584 font-weight: 700 !important;
1585 gap: 6pt !important;
1586 margin: 0 0 8pt !important;
1587 padding: 0 0 5pt !important;
1588 border-bottom: 0.5pt solid #e5e7eb !important;
1589 color: #111827 !important;
1590 }
1591 body.yatra-printing-confirmation .yatra-card-title svg {
1592 width: 12pt !important;
1593 height: 12pt !important;
1594 color: #111827 !important;
1595 }
1596
1597 /* Trip summary — small image, tight spacing */
1598 body.yatra-printing-confirmation .yatra-trip-summary {
1599 gap: 10pt !important;
1600 align-items: flex-start !important;
1601 }
1602 /* Images often render as empty placeholders in print preview; hide for a cleaner receipt. */
1603 body.yatra-printing-confirmation .yatra-trip-image {
1604 display: none !important;
1605 }
1606 body.yatra-printing-confirmation .yatra-trip-name {
1607 font-size: 12pt !important;
1608 font-weight: 700 !important;
1609 margin: 0 0 4pt !important;
1610 color: #111827 !important;
1611 }
1612 body.yatra-printing-confirmation .yatra-trip-meta {
1613 font-size: 9pt !important;
1614 gap: 10pt !important;
1615 margin-bottom: 4pt !important;
1616 color: #374151 !important;
1617 }
1618 body.yatra-printing-confirmation .yatra-trip-meta svg,
1619 body.yatra-printing-confirmation .yatra-trip-location svg {
1620 width: 9pt !important;
1621 height: 9pt !important;
1622 }
1623 body.yatra-printing-confirmation .yatra-trip-location {
1624 font-size: 9pt !important;
1625 margin: 0 0 4pt !important;
1626 color: #374151 !important;
1627 }
1628
1629 /* Tags — outline pills, no fills */
1630 body.yatra-printing-confirmation .yatra-trip-tags {
1631 font-size: 9pt !important;
1632 margin-top: 4pt !important;
1633 }
1634 body.yatra-printing-confirmation .yatra-tag-label {
1635 font-weight: 700 !important;
1636 color: #374151 !important;
1637 margin-right: 4pt !important;
1638 }
1639 body.yatra-printing-confirmation .yatra-tag-item {
1640 display: inline-block !important;
1641 background: #fff !important;
1642 border: 0.5pt solid #d1d5db !important;
1643 padding: 1pt 5pt !important;
1644 border-radius: 2pt !important;
1645 font-size: 8.5pt !important;
1646 color: #374151 !important;
1647 margin: 1pt 2pt 1pt 0 !important;
1648 }
1649
1650 /* Two-column grid stays two columns on paper */
1651 body.yatra-printing-confirmation .yatra-confirmation-grid {
1652 display: grid !important;
1653 grid-template-columns: 1.15fr 0.85fr !important;
1654 gap: 6pt !important;
1655 align-items: start !important;
1656 }
1657 body.yatra-printing-confirmation .yatra-confirmation-column {
1658 min-width: 0 !important;
1659 }
1660
1661 /* Booking info grid */
1662 body.yatra-printing-confirmation .yatra-info-grid {
1663 display: grid !important;
1664 grid-template-columns: 1fr 1fr !important;
1665 gap: 5pt 9pt !important;
1666 }
1667 body.yatra-printing-confirmation .yatra-info-item {
1668 display: flex !important;
1669 flex-direction: column !important;
1670 gap: 1pt !important;
1671 }
1672 body.yatra-printing-confirmation .yatra-info-label {
1673 font-size: 7.5pt !important;
1674 text-transform: uppercase !important;
1675 letter-spacing: 0.3pt !important;
1676 color: #6b7280 !important;
1677 }
1678 body.yatra-printing-confirmation .yatra-info-value {
1679 font-size: 10pt !important;
1680 font-weight: 600 !important;
1681 color: #111827 !important;
1682 }
1683 body.yatra-printing-confirmation .yatra-status-badge {
1684 display: inline-block !important;
1685 padding: 1pt 6pt !important;
1686 border: 0.75pt solid currentColor !important;
1687 border-radius: 2pt !important;
1688 font-size: 8.5pt !important;
1689 font-weight: 700 !important;
1690 }
1691
1692 /* Travelers */
1693 body.yatra-printing-confirmation .yatra-travelers-list {
1694 margin: 0 !important;
1695 }
1696 body.yatra-printing-confirmation .yatra-traveler-item {
1697 display: flex !important;
1698 align-items: center !important;
1699 gap: 8pt !important;
1700 padding: 4pt 0 !important;
1701 border-bottom: 0.5pt solid #e5e7eb !important;
1702 }
1703 body.yatra-printing-confirmation .yatra-traveler-item:last-child {
1704 border-bottom: none !important;
1705 }
1706 body.yatra-printing-confirmation .yatra-traveler-number {
1707 display: inline-flex !important;
1708 align-items: center !important;
1709 justify-content: center !important;
1710 width: 16pt !important;
1711 height: 16pt !important;
1712 background: #111827 !important;
1713 color: #fff !important;
1714 border-radius: 50% !important;
1715 font-size: 8.5pt !important;
1716 font-weight: 700 !important;
1717 flex-shrink: 0 !important;
1718 }
1719 body.yatra-printing-confirmation .yatra-traveler-name {
1720 font-size: 10pt !important;
1721 font-weight: 600 !important;
1722 color: #111827 !important;
1723 }
1724 body.yatra-printing-confirmation .yatra-traveler-dob {
1725 font-size: 8.5pt !important;
1726 color: #6b7280 !important;
1727 }
1728
1729 /* Payment summary rows */
1730 body.yatra-printing-confirmation .yatra-payment-rows {
1731 margin: 0 !important;
1732 }
1733 body.yatra-printing-confirmation .yatra-payment-row,
1734 body.yatra-printing-confirmation .yatra-bank-info-item {
1735 display: flex !important;
1736 justify-content: space-between !important;
1737 align-items: baseline !important;
1738 gap: 12pt !important;
1739 font-size: 9.25pt !important;
1740 padding: 1.5pt 0 !important;
1741 color: #111827 !important;
1742 }
1743 body.yatra-printing-confirmation .yatra-due-row {
1744 background: #fef3c7 !important;
1745 padding: 4pt 6pt !important;
1746 margin-top: 5pt !important;
1747 border-radius: 2pt !important;
1748 border: 0.5pt solid #fbbf24 !important;
1749 }
1750 body.yatra-printing-confirmation .yatra-payment-method {
1751 margin-top: 6pt !important;
1752 padding-top: 5pt !important;
1753 font-size: 9pt !important;
1754 border-top: 0.5pt solid #e5e7eb !important;
1755 color: #374151 !important;
1756 }
1757
1758 /* Contact info */
1759 body.yatra-printing-confirmation .yatra-contact-info {
1760 margin: 0 !important;
1761 }
1762 body.yatra-printing-confirmation .yatra-contact-item {
1763 font-size: 9.5pt !important;
1764 margin: 0 0 3pt !important;
1765 color: #111827 !important;
1766 }
1767 body.yatra-printing-confirmation .yatra-contact-item strong {
1768 color: #6b7280 !important;
1769 font-weight: 600 !important;
1770 margin-right: 4pt !important;
1771 }
1772
1773 /* Links — print as plain text, no underline (URL is still in browser footer) */
1774 body.yatra-printing-confirmation a,
1775 body.yatra-printing-confirmation a:visited {
1776 color: inherit !important;
1777 text-decoration: none !important;
1778 }
1779
1780 /* Avoid orphan headings */
1781 body.yatra-printing-confirmation h1,
1782 body.yatra-printing-confirmation h2,
1783 body.yatra-printing-confirmation h3,
1784 body.yatra-printing-confirmation h4 {
1785 page-break-after: avoid !important;
1786 break-after: avoid !important;
1787 }
1788 }
1789 </style>
1790
1791 <script>
1792 (function () {
1793 document.addEventListener('click', function (e) {
1794 var btn = e.target.closest('[data-yatra-print="confirmation"]');
1795 if (!btn) {
1796 return;
1797 }
1798 e.preventDefault();
1799
1800 var card = document.querySelector('.yatra-confirmation-container');
1801 if (!card) {
1802 window.print();
1803 return;
1804 }
1805
1806 // Wrap (or reuse) a print-only root so the @media print rules can target a single
1807 // direct child of <body>. Reused on the account page if the same data attribute
1808 // and CSS rules are added there.
1809 var root = document.querySelector('.yatra-print-root');
1810 var addedWrapper = false;
1811 if (!root) {
1812 root = document.createElement('div');
1813 root.className = 'yatra-print-root';
1814 document.body.appendChild(root);
1815 addedWrapper = true;
1816 }
1817 var clone = card.cloneNode(true);
1818 // Drop the action buttons from the clone so they don't appear on paper.
1819 clone.querySelectorAll('.yatra-confirmation-actions').forEach(function (n) { n.remove(); });
1820 root.innerHTML = '';
1821 root.appendChild(clone);
1822
1823 document.body.classList.add('yatra-printing-confirmation');
1824
1825 var cleanup = function () {
1826 document.body.classList.remove('yatra-printing-confirmation');
1827 if (addedWrapper && root && root.parentNode) {
1828 root.parentNode.removeChild(root);
1829 } else if (root) {
1830 root.innerHTML = '';
1831 }
1832 window.removeEventListener('afterprint', cleanup);
1833 };
1834
1835 window.addEventListener('afterprint', cleanup);
1836 // Safety net for browsers that don't fire afterprint reliably.
1837 window.setTimeout(function () {
1838 if (document.body.classList.contains('yatra-printing-confirmation')) {
1839 cleanup();
1840 }
1841 }, 5000);
1842
1843 window.print();
1844 });
1845 })();
1846 </script>
1847
1848 <?php yatra_get_footer(); ?>
1849
1850