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

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

1,840 lines 79.3 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)) : ?>
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
321 if ($days > 0 && $nights > 0) {
322 printf(
323 /* translators: 1: number of days, 2: number of nights. */
324 esc_html__('%1$d Days / %2$d Nights', 'yatra'),
325 $days,
326 $nights
327 );
328 } elseif ($days > 0) {
329 printf(
330 esc_html(
331 /* translators: %d: number of days. */
332 _n('%d Day', '%d Days', $days, 'yatra')
333 ),
334 $days
335 );
336 } elseif ($nights > 0) {
337 printf(
338 esc_html(
339 /* translators: %d: number of nights. */
340 _n('%d Night', '%d Nights', $nights, 'yatra')
341 ),
342 $nights
343 );
344 }
345 ?>
346 </span>
347 <?php endif; ?>
348
349 <?php if (!empty($booking->difficulty_level)) : ?>
350 <span class="yatra-meta-item">
351 <?php
352 $difficulty = \Yatra\Models\Trip::resolveDifficultyDisplay(
353 (string) $booking->difficulty_level
354 );
355
356 // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
357 echo yatra_stored_picker_icon_markup(
358 $difficulty['icon_picker'] ?? null,
359 '',
360 'yatra-icon-sm'
361 );
362
363 echo esc_html($difficulty['level'] ?? (string) $booking->difficulty_level);
364 ?>
365 </span>
366 <?php endif; ?>
367 </div>
368
369 <?php if (!empty($booking->starting_location)) : ?>
370 <p class="yatra-trip-location">
371 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
372 <path d="M21 10c0 7-9 13-9 13s-9-6-9-13a9 9 0 0 1 18 0z"></path>
373 <circle cx="12" cy="10" r="3"></circle>
374 </svg>
375 <?php echo esc_html($booking->starting_location); ?>
376 <?php if (!empty($booking->ending_location) && $booking->ending_location !== $booking->starting_location) : ?>
377 → <?php echo esc_html($booking->ending_location); ?>
378 <?php endif; ?>
379 </p>
380 <?php endif; ?>
381
382 <?php if (!empty($booking->trip_destinations_list)) : ?>
383 <div class="yatra-trip-tags">
384 <span class="yatra-tag-label"><?php esc_html_e('Destinations:', 'yatra'); ?></span>
385 <div class="yatra-tag-group">
386 <?php foreach ($booking->trip_destinations_list as $destination) : ?>
387 <span class="yatra-tag-item"><?php echo esc_html($destination); ?></span>
388 <?php endforeach; ?>
389 </div>
390 </div>
391 <?php endif; ?>
392
393 <?php if (!empty($booking->trip_activities_list)) : ?>
394 <div class="yatra-trip-tags">
395 <span class="yatra-tag-label"><?php esc_html_e('Activities:', 'yatra'); ?></span>
396 <div class="yatra-tag-group">
397 <?php foreach ($booking->trip_activities_list as $activity) : ?>
398 <span class="yatra-tag-item"><?php echo esc_html($activity); ?></span>
399 <?php endforeach; ?>
400 </div>
401 </div>
402 <?php endif; ?>
403
404 <?php if (!empty($booking->trip_categories_list)) : ?>
405 <div class="yatra-trip-tags">
406 <span class="yatra-tag-label"><?php esc_html_e('Trip Type:', 'yatra'); ?></span>
407 <div class="yatra-tag-group">
408 <?php foreach ($booking->trip_categories_list as $category) : ?>
409 <span class="yatra-tag-item"><?php echo esc_html($category); ?></span>
410 <?php endforeach; ?>
411 </div>
412 </div>
413 <?php endif; ?>
414
415 </div>
416 </div>
417 </div>
418
419 <!-- Booking Details -->
420 <div class="yatra-confirmation-grid">
421 <!-- Left Column -->
422 <div class="yatra-confirmation-column">
423 <!-- Booking Info Card -->
424 <div class="yatra-confirmation-card">
425 <h3 class="yatra-card-title">
426 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
427 <rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect>
428 <line x1="16" y1="2" x2="16" y2="6"></line>
429 <line x1="8" y1="2" x2="8" y2="6"></line>
430 <line x1="3" y1="10" x2="21" y2="10"></line>
431 </svg>
432 <?php esc_html_e('Booking Information', 'yatra'); ?>
433 </h3>
434
435 <div class="yatra-info-grid">
436 <div class="yatra-info-item">
437 <span class="yatra-info-label"><?php esc_html_e('Status', 'yatra'); ?></span>
438 <span class="yatra-info-value">
439 <span class="yatra-status-badge" style="background: <?php echo esc_attr($status_style['bg']); ?>; color: <?php echo esc_attr($status_style['text']); ?>;">
440 <?php echo esc_html($status_style['label']); ?>
441 </span>
442 </span>
443 </div>
444 <div class="yatra-info-item">
445 <span class="yatra-info-label"><?php esc_html_e('Travel Date', 'yatra'); ?></span>
446 <span class="yatra-info-value"><?php echo esc_html($travel_date_formatted); ?></span>
447 </div>
448 <div class="yatra-info-item">
449 <span class="yatra-info-label"><?php esc_html_e('Number of Travelers', 'yatra'); ?></span>
450 <span class="yatra-info-value"><?php echo esc_html($booking->travelers_count); ?></span>
451 </div>
452 <div class="yatra-info-item">
453 <span class="yatra-info-label"><?php esc_html_e('Booked On', 'yatra'); ?></span>
454 <span class="yatra-info-value"><?php echo esc_html($booking_date_formatted); ?></span>
455 </div>
456 </div>
457 </div>
458
459 <!-- Travelers Card -->
460 <?php if (!empty($booking->travelers)) : ?>
461 <div class="yatra-confirmation-card">
462 <h3 class="yatra-card-title">
463 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
464 <path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path>
465 <circle cx="9" cy="7" r="4"></circle>
466 <path d="M23 21v-2a4 4 0 0 0-3-3.87"></path>
467 <path d="M16 3.13a4 4 0 0 1 0 7.75"></path>
468 </svg>
469 <?php esc_html_e('Travelers', 'yatra'); ?>
470 </h3>
471
472 <div class="yatra-travelers-list">
473 <?php foreach ($booking->travelers as $index => $traveler) :
474 $traveler_name = trim(($traveler['first_name'] ?? '') . ' ' . ($traveler['last_name'] ?? ''));
475 ?>
476 <div class="yatra-traveler-item">
477 <span class="yatra-traveler-number"><?php echo esc_html($index + 1); ?></span>
478 <div class="yatra-traveler-details">
479 <span class="yatra-traveler-name">
480 <?php echo esc_html($traveler_name ?: __('Traveler', 'yatra') . ' ' . ($index + 1)); ?>
481 </span>
482 <?php if (!empty($traveler['date_of_birth'])) : ?>
483 <span class="yatra-traveler-dob">
484 <?php echo esc_html(\Yatra\Helpers\FormatHelper::formatDate((string) $traveler['date_of_birth'])); ?>
485 </span>
486 <?php endif; ?>
487 </div>
488 </div>
489 <?php endforeach; ?>
490 </div>
491 </div>
492 <?php endif; ?>
493
494 <?php
495 // Allow gateways to inject cards (e.g., Bank Transfer instructions)
496 do_action('yatra_booking_confirmation_after_details', $booking);
497 ?>
498 </div>
499
500 <!-- Right Column -->
501 <div class="yatra-confirmation-column">
502 <!-- Payment Summary Card -->
503 <div class="yatra-confirmation-card yatra-payment-card">
504 <h3 class="yatra-card-title">
505 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
506 <rect x="1" y="4" width="22" height="16" rx="2" ry="2"></rect>
507 <line x1="1" y1="10" x2="23" y2="10"></line>
508 </svg>
509 <?php esc_html_e('Payment Summary', 'yatra'); ?>
510 </h3>
511
512 <div class="yatra-payment-rows">
513 <?php
514 // ── Raw figures from DB ───────────────────────────────────
515 $db_subtotal = (float) ($booking->subtotal ?? $booking->total_amount);
516 $discount_amount = (float) ($booking->discount_amount ?? 0);
517 $itinerary_costs_total = (float) ($booking->itinerary_costs_total ?? 0);
518 $tax_amount = (float) ($booking->tax_amount ?? 0);
519 $tax_inclusive = !empty($booking->tax_inclusive);
520 $total_amount = (float) $booking->total_amount;
521 $amount_paid = (float) ($booking->amount_paid ?? 0);
522 $amount_due = (float) ($booking->amount_due ?? 0);
523
524 // ── Tax breakdown (built first so it can gate later rows) ─
525 $tax_breakdown = [];
526 if (!empty($booking->tax_details)) {
527 $taxes = json_decode($booking->tax_details, true) ?: [];
528 foreach ($taxes as $tax) {
529 $tax_breakdown[] = [
530 'name' => $tax['name'] ?? __('Tax', 'yatra'),
531 'rate' => (float) ($tax['rate'] ?? 0),
532 'amount' => (float) ($tax['amount'] ?? 0),
533 ];
534 }
535 } elseif ($tax_amount > 0) {
536 $tax_breakdown[] = [
537 'name' => __('Tax', 'yatra'),
538 'rate' => (float) ($booking->tax_rate ?? 0),
539 'amount' => $tax_amount,
540 ];
541 }
542
543 // ── Itinerary costs ───────────────────────────────────────
544 $itinerary_costs = [];
545 if (!empty($booking->itinerary_costs)) {
546 $itinerary_costs = json_decode($booking->itinerary_costs, true) ?: [];
547 }
548
549 // ── Additional services ───────────────────────────────────
550 $raw_services = apply_filters('yatra_booking_get_services', [], (int) ($booking->id ?? 0));
551 $selected_services = [];
552 if (!empty($raw_services) && is_array($raw_services)) {
553 foreach ($raw_services as $s) {
554 $arr = is_array($s) ? $s : (array) $s;
555 if (!isset($arr['selected']) || !empty($arr['selected'])) {
556 $selected_services[] = $arr;
557 }
558 }
559 }
560 $services_total = 0.0;
561 foreach ($selected_services as $s) {
562 $services_total += (float) ($s['total_price'] ?? $s['calculated_price'] ?? $s['total_cost'] ?? $s['amount'] ?? $s['unit_price'] ?? $s['price'] ?? 0);
563 }
564
565 // ── Derived amounts ───────────────────────────────────────
566 // base_trip_cost: the trip price without services (services are embedded in db_subtotal by Pro)
567 $base_trip_cost = $db_subtotal - $services_total;
568 // taxable_amount: what tax is calculated on
569 $taxable_amount = max(0.0, $db_subtotal - $discount_amount) + $itinerary_costs_total;
570
571 $has_services = !empty($selected_services);
572 $has_discount = $discount_amount > 0;
573 $has_itinerary = !empty($itinerary_costs) && $itinerary_costs_total > 0;
574 $has_tax = !empty($tax_breakdown);
575 $show_taxable_row = $has_tax && ($has_discount || $has_itinerary);
576 ?>
577
578 <!-- Trip Base Price (always the first line) -->
579 <div class="yatra-payment-row">
580 <span>
581 <?php esc_html_e('Trip Base Price', 'yatra'); ?>
582 <?php if ($tax_inclusive): ?>
583 <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;">
584 <?php esc_html_e('Tax Incl.', 'yatra'); ?>
585 </span>
586 <?php endif; ?>
587 </span>
588 <span><?php echo esc_html(yatra_format_price($base_trip_cost, $booking->currency)); ?></span>
589 </div>
590
591 <?php if ($has_services): ?>
592 <!-- Additional Services section header -->
593 <div class="yatra-payment-row" style="margin-top: 4px;">
594 <span style="font-size: 0.75em; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: #6b7280;">
595 + <?php esc_html_e('Additional Services', 'yatra'); ?>
596 </span>
597 <span></span>
598 </div>
599 <!-- Service line items -->
600 <?php foreach ($selected_services as $svc): ?>
601 <?php
602 $svc_name = $svc['service_name'] ?? $svc['name'] ?? $svc['title'] ?? $svc['label'] ?? __('Service', 'yatra');
603 $svc_amount = (float) ($svc['total_price'] ?? $svc['calculated_price'] ?? $svc['total_cost'] ?? $svc['amount'] ?? $svc['unit_price'] ?? $svc['price'] ?? 0);
604 ?>
605 <div class="yatra-payment-row" style="margin-left: 16px;">
606 <span><?php echo esc_html($svc_name); ?></span>
607 <span><?php echo esc_html(yatra_format_price($svc_amount, $booking->currency, false)); ?></span>
608 </div>
609 <?php endforeach; ?>
610 <!-- Gross Total = Trip Base Price + Services -->
611 <div class="yatra-payment-row" style="border-top: 1px solid #e5e7eb; margin-top: 6px; padding-top: 6px;">
612 <span><strong><?php esc_html_e('Gross Total', 'yatra'); ?></strong></span>
613 <span><strong><?php echo esc_html(yatra_format_price($db_subtotal, $booking->currency)); ?></strong></span>
614 </div>
615 <?php endif; ?>
616
617 <?php if ($has_discount): ?>
618 <!-- Discount -->
619 <div class="yatra-payment-row">
620 <span><?php esc_html_e('Discount', 'yatra'); ?></span>
621 <span style="color: #059669; font-weight: 500;">-<?php echo esc_html(yatra_format_price($discount_amount, $booking->currency)); ?></span>
622 </div>
623 <?php endif; ?>
624
625 <?php if ($has_itinerary): ?>
626 <!-- Itinerary costs header -->
627 <div class="yatra-payment-row" style="margin-top: 4px;">
628 <span><strong><?php esc_html_e('Itinerary Costs', 'yatra'); ?></strong></span>
629 <span></span>
630 </div>
631 <?php foreach ($itinerary_costs as $cost): ?>
632 <div class="yatra-payment-row" style="margin-left: 20px;">
633 <span>
634 <?php echo esc_html($cost['name']); ?>
635 <?php if (!empty($cost['price_per'])): ?>
636 <small style="opacity: 0.65;">
637 <?php
638 if ($cost['price_per'] === 'person') {
639 esc_html_e('(per person)', 'yatra');
640 } elseif ($cost['price_per'] === 'group') {
641 esc_html_e('(per booking)', 'yatra');
642 } else {
643 esc_html_e('(flat rate)', 'yatra');
644 }
645 ?>
646 </small>
647 <?php endif; ?>
648 </span>
649 <span><?php echo esc_html(yatra_format_price($cost['total_cost'] ?? $cost['price'], $booking->currency)); ?></span>
650 </div>
651 <?php endforeach; ?>
652 <?php endif; ?>
653
654 <?php if (!$tax_inclusive && $show_taxable_row): ?>
655 <!-- Taxable Amount (only for exclusive tax when there are deductions above it) -->
656 <div class="yatra-payment-row" style="border-top: 1px dashed #e5e7eb; margin-top: 8px; padding-top: 8px;">
657 <span><strong><?php esc_html_e('Taxable Amount', 'yatra'); ?></strong></span>
658 <span><strong><?php echo esc_html(yatra_format_price($taxable_amount, $booking->currency)); ?></strong></span>
659 </div>
660 <?php endif; ?>
661
662 <?php if ($has_tax && !$tax_inclusive): ?>
663 <!-- Exclusive tax: shown as an addition before Net Amount -->
664 <div class="yatra-payment-row" style="margin-top: 4px;">
665 <span style="font-size: 0.75em; font-weight: 600; text-transform: uppercase; letter-spacing: 0.05em; color: #6b7280;">
666 + <?php esc_html_e('Tax', 'yatra'); ?>
667 </span>
668 <span></span>
669 </div>
670 <?php foreach ($tax_breakdown as $tax): ?>
671 <div class="yatra-payment-row" style="margin-left: 16px;">
672 <span>
673 <?php echo esc_html($tax['name']); ?>
674 <?php if ($tax['rate'] > 0): ?>
675 (<?php echo esc_html($tax['rate']); ?>%)
676 <?php endif; ?>
677 </span>
678 <span>+<?php echo esc_html(yatra_format_price($tax['amount'], $booking->currency)); ?></span>
679 </div>
680 <?php endforeach; ?>
681 <?php endif; ?>
682
683 <!-- Net Amount -->
684 <div class="yatra-payment-row" style="border-top: 2px solid #111827; margin-top: 10px; padding-top: 10px;">
685 <span style="font-size: 1.05em;"><strong><?php esc_html_e('Net Amount', 'yatra'); ?></strong></span>
686 <span style="font-size: 1.05em;"><strong><?php echo esc_html(yatra_format_price($total_amount, $booking->currency)); ?></strong></span>
687 </div>
688
689 <?php if ($has_tax && $tax_inclusive): ?>
690 <!-- Inclusive tax: shown as an informational footnote after Net Amount -->
691 <?php foreach ($tax_breakdown as $tax): ?>
692 <div class="yatra-payment-row" style="margin-top: 4px; opacity: 0.7;">
693 <span style="font-size: 0.85em; font-style: italic;">
694 <?php
695 printf(
696 /* translators: %1$s = tax name, %2$s = rate, %3$s = amount */
697 esc_html__('Incl. %1$s%2$s: %3$s', 'yatra'),
698 esc_html($tax['name']),
699 $tax['rate'] > 0 ? ' (' . esc_html($tax['rate']) . '%)' : '',
700 esc_html(yatra_format_price($tax['amount'], $booking->currency))
701 );
702 ?>
703 </span>
704 <span></span>
705 </div>
706 <?php endforeach; ?>
707 <?php endif; ?>
708
709 <?php if ($amount_paid > 0): ?>
710 <div class="yatra-payment-row" style="margin-top: 6px;">
711 <span><?php esc_html_e('Amount Paid', 'yatra'); ?></span>
712 <span style="color: #059669;"><?php echo esc_html(yatra_format_price($amount_paid, $booking->currency)); ?></span>
713 </div>
714 <?php endif; ?>
715
716 <?php if ($amount_due > 0): ?>
717 <?php
718 // Label the "due now" amount by payment type so a
719 // deposit/partial reads clearly instead of just "Due Now".
720 $payment_method_type = (string) ($booking->payment_method ?? 'full');
721 $remaining_balance = max(0.0, $total_amount - $amount_paid - $amount_due);
722 if ($payment_method_type === 'deposit') {
723 $due_now_label = __('Deposit Due Now', 'yatra');
724 } elseif ($payment_method_type === 'partial') {
725 $due_now_label = __('Partial Payment Due Now', 'yatra');
726 } else {
727 $due_now_label = __('Due Now', 'yatra');
728 }
729 ?>
730 <div class="yatra-payment-row yatra-due-row">
731 <span><strong><?php echo esc_html($due_now_label); ?></strong></span>
732 <span><strong><?php echo esc_html(yatra_format_price($amount_due, $booking->currency)); ?></strong></span>
733 </div>
734 <?php if ($payment_method_type !== 'full' && $remaining_balance > 0.01): ?>
735 <div class="yatra-payment-row" style="margin-top: 6px;">
736 <span><?php esc_html_e('Remaining Balance', 'yatra'); ?></span>
737 <span><?php echo esc_html(yatra_format_price($remaining_balance, $booking->currency)); ?></span>
738 </div>
739 <?php endif; ?>
740 <?php endif; ?>
741 </div>
742
743 <div class="yatra-payment-method">
744 <span class="yatra-pm-label"><?php esc_html_e('Payment Method:', 'yatra'); ?></span>
745 <span class="yatra-pm-value"><?php echo esc_html(ucwords(str_replace('_', ' ', (string) $display_payment_gateway))); ?></span>
746 </div>
747 </div>
748
749 <!-- Contact Info Card -->
750 <div class="yatra-confirmation-card">
751 <h3 class="yatra-card-title">
752 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
753 <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>
754 <polyline points="22,6 12,13 2,6"></polyline>
755 </svg>
756 <?php esc_html_e('Contact Information', 'yatra'); ?>
757 </h3>
758
759 <div class="yatra-contact-info">
760 <?php
761 // Try to get contact data from multiple sources
762 $contact_data = [];
763 if (!empty($booking->contact_data)) {
764 $contact_data = json_decode($booking->contact_data, true) ?: [];
765 }
766
767 $contact_name = trim((
768 $contact_data['first_name'] ??
769 $booking->contact_first_name ??
770 ($booking->contact['first_name'] ?? '')
771 ) . ' ' . (
772 $contact_data['last_name'] ??
773 $booking->contact_last_name ??
774 ($booking->contact['last_name'] ?? '')
775 ));
776
777 $contact_email = $contact_data['email'] ?? $booking->contact_email ?? ($booking->contact['email'] ?? '');
778 $contact_phone = $contact_data['phone'] ?? $booking->contact_phone ?? ($booking->contact['phone'] ?? '');
779 ?>
780
781 <?php if ($contact_name) : ?>
782 <p class="yatra-contact-item">
783 <strong><?php esc_html_e('Name:', 'yatra'); ?></strong>
784 <?php echo esc_html($contact_name); ?>
785 </p>
786 <?php endif; ?>
787
788 <?php if ($contact_email) : ?>
789 <p class="yatra-contact-item">
790 <strong><?php esc_html_e('Email:', 'yatra'); ?></strong>
791 <?php echo esc_html($contact_email); ?>
792 </p>
793 <?php endif; ?>
794
795 <?php if ($contact_phone) : ?>
796 <p class="yatra-contact-item">
797 <strong><?php esc_html_e('Phone:', 'yatra'); ?></strong>
798 <?php echo esc_html($contact_phone); ?>
799 </p>
800 <?php endif; ?>
801
802 <?php if (!$contact_name && !$contact_email && !$contact_phone) : ?>
803 <p class="yatra-contact-item">
804 <em><?php esc_html_e('Contact information not available', 'yatra'); ?></em>
805 </p>
806 <?php endif; ?>
807 </div>
808 </div>
809 </div>
810 </div>
811
812 <!-- What's Next Section -->
813 <div class="yatra-confirmation-card yatra-whats-next">
814 <h3 class="yatra-card-title">
815 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
816 <circle cx="12" cy="12" r="10"></circle>
817 <polyline points="12 16 16 12 12 8"></polyline>
818 <line x1="8" y1="12" x2="16" y2="12"></line>
819 </svg>
820 <?php esc_html_e("What's Next?", 'yatra'); ?>
821 </h3>
822
823 <div class="yatra-next-steps">
824 <div class="yatra-step">
825 <span class="yatra-step-number">1</span>
826 <div class="yatra-step-content">
827 <h4><?php esc_html_e('Check Your Email', 'yatra'); ?></h4>
828 <p><?php esc_html_e('We\'ve sent a confirmation email with all the details to your registered email address.', 'yatra'); ?></p>
829 </div>
830 </div>
831
832 <div class="yatra-step">
833 <span class="yatra-step-number">2</span>
834 <div class="yatra-step-content">
835 <h4><?php esc_html_e('Detailed Itinerary', 'yatra'); ?></h4>
836 <p><?php esc_html_e('You\'ll receive a detailed itinerary and preparation guide within 24-48 hours.', 'yatra'); ?></p>
837 </div>
838 </div>
839
840 <div class="yatra-step">
841 <span class="yatra-step-number">3</span>
842 <div class="yatra-step-content">
843 <h4><?php esc_html_e('Prepare for Adventure', 'yatra'); ?></h4>
844 <p><?php esc_html_e('Ensure all travelers have valid ID or travel documents and any required visas for your destination.', 'yatra'); ?></p>
845 </div>
846 </div>
847 </div>
848 </div>
849
850 <!-- Action Buttons -->
851 <div class="yatra-confirmation-actions">
852 <a href="<?php echo esc_url(home_url('/')); ?>" class="yatra-btn yatra-btn-secondary">
853 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
854 <path d="M3 9l9-7 9 7v11a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2z"></path>
855 <polyline points="9 22 9 12 15 12 15 22"></polyline>
856 </svg>
857 <?php esc_html_e('Return to Home', 'yatra'); ?>
858 </a>
859
860 <?php
861 // Get latest payment for this booking to enable invoice download.
862 // The invoice endpoint authorises via: admin → owner → signed invoice_token → guest booking_token.
863 // We always issue a signed invoice_token here so the link works for guests
864 // (no session required) AND for logged-in users who don't own the booking
865 // (e.g. site admins viewing the page) — without re-checking login on the client.
866 $paymentRepository = new \Yatra\Repositories\PaymentRepository();
867 $latestPayment = $paymentRepository->findLatestByBookingId((int) $booking->id);
868 if ($latestPayment && in_array($latestPayment->status, ['completed', 'paid'], true)) :
869 $invoiceToken = \Yatra\Controllers\PaymentGatewayController::issueInvoiceToken(
870 (int) $latestPayment->id,
871 (int) ($latestPayment->booking_id ?? $booking->id)
872 );
873 $invoiceUrl = add_query_arg(
874 [
875 'download' => '1',
876 'invoice_token' => $invoiceToken,
877 ],
878 rest_url('yatra/v1/payment/' . (int) $latestPayment->id . '/invoice')
879 );
880 ?>
881 <a href="<?php echo esc_url($invoiceUrl); ?>"
882 target="_blank"
883 rel="noopener"
884 class="yatra-btn yatra-btn-primary">
885 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
886 <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
887 <polyline points="7 10 12 15 17 10"></polyline>
888 <line x1="12" y1="15" x2="12" y2="3"></line>
889 </svg>
890 <?php esc_html_e('Download Invoice', 'yatra'); ?>
891 </a>
892 <?php
893 // No completed payment yet (e.g. Bank Transfer / offline): offer a
894 // pro-forma invoice that carries the payment instructions so the
895 // customer knows how to pay. Uses a booking-scoped invoice token.
896 elseif ((float) ($booking->amount_due ?? $booking->total_amount ?? 0) > 0) :
897 $proformaToken = \Yatra\Controllers\PaymentGatewayController::issueInvoiceToken(0, (int) $booking->id);
898 $proformaUrl = add_query_arg(
899 [
900 'download' => '1',
901 'invoice_token' => $proformaToken,
902 ],
903 rest_url('yatra/v1/booking/' . (int) $booking->id . '/invoice')
904 );
905 ?>
906 <a href="<?php echo esc_url($proformaUrl); ?>"
907 target="_blank"
908 rel="noopener"
909 class="yatra-btn yatra-btn-primary">
910 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
911 <path d="M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4"></path>
912 <polyline points="7 10 12 15 17 10"></polyline>
913 <line x1="12" y1="15" x2="12" y2="3"></line>
914 </svg>
915 <?php esc_html_e('Download Invoice', 'yatra'); ?>
916 </a>
917 <?php endif; ?>
918
919 <button type="button" data-yatra-print="confirmation" class="yatra-btn yatra-btn-outline">
920 <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
921 <polyline points="6 9 6 2 18 2 18 9"></polyline>
922 <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>
923 <rect x="6" y="14" width="12" height="8"></rect>
924 </svg>
925 <?php esc_html_e('Print Confirmation', 'yatra'); ?>
926 </button>
927 </div>
928
929 </div>
930 </div>
931 </div>
932
933 <style>
934 /* Confirmation Page Styles */
935 .yatra-confirmation-wrapper {
936 max-width: 1300px;
937 margin: 0 auto;
938 padding: 40px 20px;
939 }
940
941 .yatra-confirmation-container {
942 max-width: 900px;
943 margin: 0 auto;
944 }
945
946 .yatra-confirmation-header {
947 text-align: center;
948 margin-bottom: 40px;
949 }
950
951 .yatra-confirmation-icon {
952 width: 100px;
953 height: 100px;
954 margin: 0 auto 24px;
955 background: linear-gradient(135deg, #22c55e 0%, #16a34a 100%);
956 border-radius: 50%;
957 display: flex;
958 align-items: center;
959 justify-content: center;
960 animation: scaleIn 0.5s ease-out;
961 }
962
963 .yatra-confirmation-icon svg {
964 width: 50px;
965 height: 50px;
966 color: white;
967 }
968
969 @keyframes scaleIn {
970 0% { transform: scale(0); opacity: 0; }
971 50% { transform: scale(1.1); }
972 100% { transform: scale(1); opacity: 1; }
973 }
974
975 .yatra-confirmation-title {
976 font-size: 36px;
977 font-weight: 700;
978 color: #111827;
979 margin: 0 0 12px;
980 }
981
982 .yatra-confirmation-subtitle {
983 font-size: 18px;
984 color: #6b7280;
985 margin: 0 0 24px;
986 }
987
988 .yatra-confirmation-reference {
989 display: inline-flex;
990 align-items: center;
991 gap: 12px;
992 background: #f3f4f6;
993 padding: 12px 24px;
994 border-radius: 100px;
995 }
996
997 .yatra-ref-label {
998 color: #6b7280;
999 font-size: 14px;
1000 }
1001
1002 .yatra-ref-code {
1003 font-size: 18px;
1004 font-weight: 700;
1005 color: #111827;
1006 font-family: monospace;
1007 letter-spacing: 1px;
1008 }
1009
1010 .yatra-confirmation-card {
1011 background: #fff;
1012 border: 1px solid #e5e7eb;
1013 border-radius: 16px;
1014 padding: 24px;
1015 margin-bottom: 24px;
1016 }
1017
1018 .yatra-card-title {
1019 display: flex;
1020 align-items: center;
1021 gap: 12px;
1022 font-size: 18px;
1023 font-weight: 600;
1024 color: #111827;
1025 margin: 0 0 20px;
1026 padding-bottom: 16px;
1027 border-bottom: 1px solid #e5e7eb;
1028 }
1029
1030 .yatra-card-title svg {
1031 width: 22px;
1032 height: 22px;
1033 color: #3b82f6;
1034 }
1035
1036 .yatra-trip-summary-card {
1037 background: linear-gradient(135deg, #eff6ff 0%, #dbeafe 100%);
1038 border-color: #bfdbfe;
1039 }
1040
1041 .yatra-trip-summary {
1042 display: flex;
1043 gap: 24px;
1044 align-items: center;
1045 }
1046
1047 .yatra-trip-image {
1048 width: 120px;
1049 height: 120px;
1050 border-radius: 12px;
1051 overflow: hidden;
1052 flex-shrink: 0;
1053 }
1054
1055 .yatra-trip-image img {
1056 width: 100%;
1057 height: 100%;
1058 object-fit: cover;
1059 }
1060
1061 .yatra-trip-name {
1062 font-size: 22px;
1063 font-weight: 700;
1064 color: #111827;
1065 margin: 0 0 12px;
1066 }
1067
1068 /* Star rating. This confirmation page only enqueues yatra-common + fontawesome,
1069 not booking.css/trip.css where these live, so without them the inline SVG
1070 stars render with no size or colour (invisible). Mirrors booking.css. */
1071 .yatra-trip-rating {
1072 display: flex;
1073 align-items: center;
1074 gap: 12px;
1075 margin-bottom: 12px;
1076 }
1077
1078 .yatra-rating-stars {
1079 display: inline-flex;
1080 gap: 4px;
1081 }
1082
1083 .yatra-star {
1084 width: 20px;
1085 height: 20px;
1086 color: #e2e8f0;
1087 }
1088
1089 .yatra-star svg {
1090 width: 100%;
1091 height: 100%;
1092 }
1093
1094 .yatra-star-filled {
1095 color: #f59e0b;
1096 }
1097
1098 /* Half star: base star stays grey; overlay the left half in amber via an
1099 SVG mask (size-independent, so it tracks the star's dimensions). */
1100 .yatra-star-half {
1101 position: relative;
1102 color: #e2e8f0;
1103 }
1104
1105 .yatra-star-half::after {
1106 content: "";
1107 position: absolute;
1108 top: 0;
1109 left: 0;
1110 bottom: 0;
1111 width: 50%;
1112 overflow: hidden;
1113 background: #f59e0b;
1114 -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%;
1115 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%;
1116 }
1117
1118 .yatra-rating-meta strong {
1119 color: #0f172a;
1120 margin-right: 6px;
1121 }
1122
1123 .yatra-rating-meta span {
1124 color: #64748b;
1125 font-size: 14px;
1126 }
1127
1128 .yatra-trip-meta {
1129 display: flex;
1130 gap: 20px;
1131 flex-wrap: wrap;
1132 margin-bottom: 8px;
1133 }
1134
1135 .yatra-meta-item {
1136 display: flex;
1137 align-items: center;
1138 gap: 6px;
1139 font-size: 14px;
1140 color: #4b5563;
1141 }
1142
1143 .yatra-meta-item svg {
1144 width: 16px;
1145 height: 16px;
1146 }
1147
1148 .yatra-trip-location {
1149 display: flex;
1150 align-items: center;
1151 gap: 6px;
1152 font-size: 14px;
1153 color: #6b7280;
1154 margin: 0;
1155 }
1156
1157 .yatra-trip-location svg {
1158 width: 16px;
1159 height: 16px;
1160 }
1161
1162 .yatra-confirmation-grid {
1163 display: grid;
1164 grid-template-columns: 1fr 1fr;
1165 gap: 24px;
1166 }
1167
1168 @media (max-width: 768px) {
1169 .yatra-confirmation-grid {
1170 grid-template-columns: 1fr;
1171 }
1172
1173 .yatra-trip-summary {
1174 flex-direction: column;
1175 text-align: center;
1176 }
1177
1178 .yatra-info-grid {
1179 grid-template-columns: 1fr;
1180 gap: 12px;
1181 }
1182 }
1183
1184 .yatra-info-grid {
1185 display: grid;
1186 grid-template-columns: 1fr 1fr;
1187 gap: 16px;
1188 }
1189
1190 .yatra-info-item {
1191 display: flex;
1192 flex-direction: column;
1193 gap: 4px;
1194 padding: 12px 14px;
1195 background: #f9fafb;
1196 border: 1px solid #eef2f7;
1197 border-radius: 12px;
1198 }
1199
1200 .yatra-info-label {
1201 font-size: 13px;
1202 color: #6b7280;
1203 line-height: 1.2;
1204 }
1205
1206 .yatra-info-value {
1207 font-size: 15px;
1208 font-weight: 600;
1209 color: #111827;
1210 line-height: 1.25;
1211 text-align: left;
1212 }
1213
1214 .yatra-status-badge {
1215 display: inline-block;
1216 padding: 4px 12px;
1217 border-radius: 100px;
1218 font-size: 13px;
1219 font-weight: 600;
1220 }
1221
1222 .yatra-travelers-list {
1223 display: flex;
1224 flex-direction: column;
1225 gap: 12px;
1226 }
1227
1228 .yatra-traveler-item {
1229 display: flex;
1230 align-items: center;
1231 gap: 12px;
1232 padding: 12px;
1233 background: #f9fafb;
1234 border-radius: 8px;
1235 }
1236
1237 .yatra-traveler-number {
1238 width: 28px;
1239 height: 28px;
1240 display: flex;
1241 align-items: center;
1242 justify-content: center;
1243 background: #3b82f6;
1244 color: white;
1245 border-radius: 50%;
1246 font-size: 13px;
1247 font-weight: 600;
1248 }
1249
1250 .yatra-traveler-name {
1251 font-weight: 600;
1252 color: #111827;
1253 }
1254
1255 .yatra-traveler-dob {
1256 font-size: 13px;
1257 color: #6b7280;
1258 }
1259
1260 .yatra-payment-card {
1261 background: #fafafa;
1262 }
1263
1264 .yatra-payment-rows {
1265 border: 1px solid #e5e7eb;
1266 border-radius: 8px;
1267 overflow: hidden;
1268 }
1269
1270 .yatra-payment-row {
1271 display: flex;
1272 justify-content: space-between;
1273 padding: 12px 16px;
1274 border-bottom: 1px solid #e5e7eb;
1275 }
1276
1277 .yatra-payment-row:last-child {
1278 border-bottom: none;
1279 background: #111827;
1280 color: white;
1281 font-weight: 600;
1282 }
1283
1284 .yatra-discount-row span:last-child {
1285 color: #22c55e;
1286 }
1287
1288 /* Bank-transfer details (markup injected by Yatra Pro's Bank Transfer gateway
1289 into this page). The card reuses this page's .yatra-confirmation-card /
1290 .yatra-card-title classes, but its rows had no styling at all, so the values
1291 sat immediately after their label while every other row on the page is
1292 flex/space-between — the bank values were the only ones not flush right.
1293 Styling lives here because this template owns the confirmation page's CSS
1294 and Pro enqueues no stylesheet on this page. */
1295 .yatra-bank-info-grid {
1296 border: 1px solid #e5e7eb;
1297 border-radius: 8px;
1298 overflow: hidden;
1299 }
1300
1301 .yatra-bank-info-item {
1302 display: flex;
1303 justify-content: space-between;
1304 align-items: baseline;
1305 gap: 12px;
1306 padding: 12px 16px;
1307 border-bottom: 1px solid #e5e7eb;
1308 }
1309
1310 .yatra-bank-info-item:last-child {
1311 border-bottom: none;
1312 }
1313
1314 .yatra-bank-label {
1315 color: #6b7280;
1316 flex-shrink: 0;
1317 }
1318
1319 .yatra-bank-value {
1320 text-align: right;
1321 word-break: break-word;
1322 }
1323
1324 .yatra-payment-method {
1325 margin-top: 16px;
1326 padding: 12px;
1327 background: white;
1328 border-radius: 8px;
1329 display: flex;
1330 justify-content: space-between;
1331 }
1332
1333 .yatra-pm-label {
1334 color: #6b7280;
1335 }
1336
1337 .yatra-pm-value {
1338 font-weight: 600;
1339 color: #111827;
1340 }
1341
1342 .yatra-contact-info p {
1343 margin: 0 0 8px;
1344 }
1345
1346 .yatra-whats-next {
1347 background: linear-gradient(135deg, #f0fdf4 0%, #dcfce7 100%);
1348 border-color: #bbf7d0;
1349 }
1350
1351 .yatra-next-steps {
1352 display: flex;
1353 flex-direction: column;
1354 gap: 20px;
1355 }
1356
1357 .yatra-step {
1358 display: flex;
1359 gap: 16px;
1360 }
1361
1362 .yatra-step-number {
1363 width: 32px;
1364 height: 32px;
1365 display: flex;
1366 align-items: center;
1367 justify-content: center;
1368 background: #22c55e;
1369 color: white;
1370 border-radius: 50%;
1371 font-weight: 600;
1372 flex-shrink: 0;
1373 }
1374
1375 .yatra-step-content h4 {
1376 margin: 0 0 4px;
1377 font-size: 16px;
1378 color: #111827;
1379 }
1380
1381 .yatra-step-content p {
1382 margin: 0;
1383 font-size: 14px;
1384 color: #6b7280;
1385 }
1386
1387 .yatra-confirmation-actions {
1388 display: flex;
1389 gap: 16px;
1390 justify-content: center;
1391 margin-top: 32px;
1392 }
1393
1394 .yatra-btn {
1395 display: inline-flex;
1396 align-items: center;
1397 gap: 8px;
1398 padding: 14px 28px;
1399 border-radius: 8px;
1400 font-size: 15px;
1401 font-weight: 600;
1402 text-decoration: none;
1403 cursor: pointer;
1404 transition: all 0.2s;
1405 border: none;
1406 }
1407
1408 .yatra-btn svg {
1409 width: 18px;
1410 height: 18px;
1411 }
1412
1413 .yatra-btn-secondary {
1414 background: #3b82f6;
1415 color: white;
1416 }
1417
1418 .yatra-btn-secondary:hover {
1419 background: #2563eb;
1420 }
1421
1422 .yatra-btn-outline {
1423 background: white;
1424 color: #374151;
1425 border: 2px solid #e5e7eb;
1426 }
1427
1428 .yatra-btn-outline:hover {
1429 border-color: #3b82f6;
1430 color: #3b82f6;
1431 }
1432
1433 /* =====================================================================
1434 Print Styles — produce a clean, single-page-friendly receipt.
1435 Triggered by the print button (adds .yatra-printing-confirmation
1436 to <body> + clones the confirmation card into .yatra-print-root).
1437 ===================================================================== */
1438 @media print {
1439 @page {
1440 size: A4;
1441 margin: 9mm 10mm;
1442 }
1443
1444 /* Force browsers to print our colors / borders */
1445 body.yatra-printing-confirmation,
1446 body.yatra-printing-confirmation * {
1447 -webkit-print-color-adjust: exact !important;
1448 print-color-adjust: exact !important;
1449 color-adjust: exact !important;
1450 }
1451
1452 /* Reset body, kill animations & transitions */
1453 body.yatra-printing-confirmation {
1454 background: #fff !important;
1455 color: #111827 !important;
1456 font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto,
1457 Helvetica, Arial, sans-serif !important;
1458 font-size: 10pt !important;
1459 line-height: 1.45 !important;
1460 }
1461 body.yatra-printing-confirmation *,
1462 body.yatra-printing-confirmation *::before,
1463 body.yatra-printing-confirmation *::after {
1464 animation: none !important;
1465 transition: none !important;
1466 box-shadow: none !important;
1467 text-shadow: none !important;
1468 }
1469
1470 /* Hide everything except our cloned print root */
1471 body.yatra-printing-confirmation > *:not(.yatra-print-root) {
1472 display: none !important;
1473 }
1474 body.yatra-printing-confirmation .yatra-print-root,
1475 body.yatra-printing-confirmation .yatra-print-root * {
1476 visibility: visible;
1477 }
1478 body.yatra-printing-confirmation .yatra-print-root {
1479 position: static !important;
1480 left: auto;
1481 top: auto;
1482 width: 100%;
1483 margin: 0;
1484 padding: 0;
1485 }
1486
1487 /* Wrappers — remove screen padding/widths */
1488 body.yatra-printing-confirmation .yatra-confirmation-wrapper,
1489 body.yatra-printing-confirmation .yatra-confirmation-container {
1490 max-width: none !important;
1491 margin: 0 !important;
1492 padding: 0 !important;
1493 }
1494
1495 /* Hide things that don't belong on paper */
1496 body.yatra-printing-confirmation .yatra-confirmation-actions,
1497 body.yatra-printing-confirmation .yatra-no-print,
1498 body.yatra-printing-confirmation .yatra-whats-next,
1499 body.yatra-printing-confirmation .yatra-trip-rating {
1500 display: none !important;
1501 }
1502
1503 /* Confirmation header — compact, two-column with status icon left & ref right */
1504 body.yatra-printing-confirmation .yatra-confirmation-header {
1505 display: flex !important;
1506 align-items: center !important;
1507 justify-content: space-between !important;
1508 gap: 16pt !important;
1509 text-align: left !important;
1510 margin: 0 0 8pt !important;
1511 padding: 0 0 6pt !important;
1512 border-bottom: 1pt solid #111827 !important;
1513 }
1514 body.yatra-printing-confirmation .yatra-confirmation-icon {
1515 width: 28pt !important;
1516 height: 28pt !important;
1517 margin: 0 !important;
1518 background: #16a34a !important;
1519 flex-shrink: 0 !important;
1520 }
1521 body.yatra-printing-confirmation .yatra-confirmation-icon svg {
1522 width: 16pt !important;
1523 height: 16pt !important;
1524 }
1525 body.yatra-printing-confirmation .yatra-confirmation-title {
1526 font-size: 14pt !important;
1527 font-weight: 700 !important;
1528 margin: 0 !important;
1529 flex: 1 !important;
1530 color: #111827 !important;
1531 }
1532 body.yatra-printing-confirmation .yatra-confirmation-subtitle {
1533 display: none !important;
1534 }
1535 body.yatra-printing-confirmation .yatra-confirmation-reference {
1536 display: inline-flex !important;
1537 flex-direction: column !important;
1538 align-items: flex-end !important;
1539 gap: 2pt !important;
1540 background: transparent !important;
1541 padding: 0 !important;
1542 border: none !important;
1543 border-radius: 0 !important;
1544 }
1545 body.yatra-printing-confirmation .yatra-ref-label {
1546 font-size: 8pt !important;
1547 text-transform: uppercase !important;
1548 letter-spacing: 0.4pt !important;
1549 color: #6b7280 !important;
1550 }
1551 body.yatra-printing-confirmation .yatra-ref-code {
1552 font-size: 11pt !important;
1553 font-weight: 700 !important;
1554 color: #111827 !important;
1555 letter-spacing: 0.6pt !important;
1556 }
1557
1558 /* Cards — flat, thin border, never split across pages */
1559 body.yatra-printing-confirmation .yatra-confirmation-card {
1560 background: #fff !important;
1561 border: 0.75pt solid #d1d5db !important;
1562 border-radius: 3pt !important;
1563 padding: 8pt 10pt !important;
1564 margin: 0 0 6pt !important;
1565 page-break-inside: avoid !important;
1566 break-inside: avoid !important;
1567 }
1568 body.yatra-printing-confirmation .yatra-trip-summary-card {
1569 background: #f9fafb !important;
1570 border-color: #d1d5db !important;
1571 }
1572 body.yatra-printing-confirmation .yatra-card-title {
1573 font-size: 10.5pt !important;
1574 font-weight: 700 !important;
1575 gap: 6pt !important;
1576 margin: 0 0 8pt !important;
1577 padding: 0 0 5pt !important;
1578 border-bottom: 0.5pt solid #e5e7eb !important;
1579 color: #111827 !important;
1580 }
1581 body.yatra-printing-confirmation .yatra-card-title svg {
1582 width: 12pt !important;
1583 height: 12pt !important;
1584 color: #111827 !important;
1585 }
1586
1587 /* Trip summary — small image, tight spacing */
1588 body.yatra-printing-confirmation .yatra-trip-summary {
1589 gap: 10pt !important;
1590 align-items: flex-start !important;
1591 }
1592 /* Images often render as empty placeholders in print preview; hide for a cleaner receipt. */
1593 body.yatra-printing-confirmation .yatra-trip-image {
1594 display: none !important;
1595 }
1596 body.yatra-printing-confirmation .yatra-trip-name {
1597 font-size: 12pt !important;
1598 font-weight: 700 !important;
1599 margin: 0 0 4pt !important;
1600 color: #111827 !important;
1601 }
1602 body.yatra-printing-confirmation .yatra-trip-meta {
1603 font-size: 9pt !important;
1604 gap: 10pt !important;
1605 margin-bottom: 4pt !important;
1606 color: #374151 !important;
1607 }
1608 body.yatra-printing-confirmation .yatra-trip-meta svg,
1609 body.yatra-printing-confirmation .yatra-trip-location svg {
1610 width: 9pt !important;
1611 height: 9pt !important;
1612 }
1613 body.yatra-printing-confirmation .yatra-trip-location {
1614 font-size: 9pt !important;
1615 margin: 0 0 4pt !important;
1616 color: #374151 !important;
1617 }
1618
1619 /* Tags — outline pills, no fills */
1620 body.yatra-printing-confirmation .yatra-trip-tags {
1621 font-size: 9pt !important;
1622 margin-top: 4pt !important;
1623 }
1624 body.yatra-printing-confirmation .yatra-tag-label {
1625 font-weight: 700 !important;
1626 color: #374151 !important;
1627 margin-right: 4pt !important;
1628 }
1629 body.yatra-printing-confirmation .yatra-tag-item {
1630 display: inline-block !important;
1631 background: #fff !important;
1632 border: 0.5pt solid #d1d5db !important;
1633 padding: 1pt 5pt !important;
1634 border-radius: 2pt !important;
1635 font-size: 8.5pt !important;
1636 color: #374151 !important;
1637 margin: 1pt 2pt 1pt 0 !important;
1638 }
1639
1640 /* Two-column grid stays two columns on paper */
1641 body.yatra-printing-confirmation .yatra-confirmation-grid {
1642 display: grid !important;
1643 grid-template-columns: 1.15fr 0.85fr !important;
1644 gap: 6pt !important;
1645 align-items: start !important;
1646 }
1647 body.yatra-printing-confirmation .yatra-confirmation-column {
1648 min-width: 0 !important;
1649 }
1650
1651 /* Booking info grid */
1652 body.yatra-printing-confirmation .yatra-info-grid {
1653 display: grid !important;
1654 grid-template-columns: 1fr 1fr !important;
1655 gap: 5pt 9pt !important;
1656 }
1657 body.yatra-printing-confirmation .yatra-info-item {
1658 display: flex !important;
1659 flex-direction: column !important;
1660 gap: 1pt !important;
1661 }
1662 body.yatra-printing-confirmation .yatra-info-label {
1663 font-size: 7.5pt !important;
1664 text-transform: uppercase !important;
1665 letter-spacing: 0.3pt !important;
1666 color: #6b7280 !important;
1667 }
1668 body.yatra-printing-confirmation .yatra-info-value {
1669 font-size: 10pt !important;
1670 font-weight: 600 !important;
1671 color: #111827 !important;
1672 }
1673 body.yatra-printing-confirmation .yatra-status-badge {
1674 display: inline-block !important;
1675 padding: 1pt 6pt !important;
1676 border: 0.75pt solid currentColor !important;
1677 border-radius: 2pt !important;
1678 font-size: 8.5pt !important;
1679 font-weight: 700 !important;
1680 }
1681
1682 /* Travelers */
1683 body.yatra-printing-confirmation .yatra-travelers-list {
1684 margin: 0 !important;
1685 }
1686 body.yatra-printing-confirmation .yatra-traveler-item {
1687 display: flex !important;
1688 align-items: center !important;
1689 gap: 8pt !important;
1690 padding: 4pt 0 !important;
1691 border-bottom: 0.5pt solid #e5e7eb !important;
1692 }
1693 body.yatra-printing-confirmation .yatra-traveler-item:last-child {
1694 border-bottom: none !important;
1695 }
1696 body.yatra-printing-confirmation .yatra-traveler-number {
1697 display: inline-flex !important;
1698 align-items: center !important;
1699 justify-content: center !important;
1700 width: 16pt !important;
1701 height: 16pt !important;
1702 background: #111827 !important;
1703 color: #fff !important;
1704 border-radius: 50% !important;
1705 font-size: 8.5pt !important;
1706 font-weight: 700 !important;
1707 flex-shrink: 0 !important;
1708 }
1709 body.yatra-printing-confirmation .yatra-traveler-name {
1710 font-size: 10pt !important;
1711 font-weight: 600 !important;
1712 color: #111827 !important;
1713 }
1714 body.yatra-printing-confirmation .yatra-traveler-dob {
1715 font-size: 8.5pt !important;
1716 color: #6b7280 !important;
1717 }
1718
1719 /* Payment summary rows */
1720 body.yatra-printing-confirmation .yatra-payment-rows {
1721 margin: 0 !important;
1722 }
1723 body.yatra-printing-confirmation .yatra-payment-row,
1724 body.yatra-printing-confirmation .yatra-bank-info-item {
1725 display: flex !important;
1726 justify-content: space-between !important;
1727 align-items: baseline !important;
1728 gap: 12pt !important;
1729 font-size: 9.25pt !important;
1730 padding: 1.5pt 0 !important;
1731 color: #111827 !important;
1732 }
1733 body.yatra-printing-confirmation .yatra-due-row {
1734 background: #fef3c7 !important;
1735 padding: 4pt 6pt !important;
1736 margin-top: 5pt !important;
1737 border-radius: 2pt !important;
1738 border: 0.5pt solid #fbbf24 !important;
1739 }
1740 body.yatra-printing-confirmation .yatra-payment-method {
1741 margin-top: 6pt !important;
1742 padding-top: 5pt !important;
1743 font-size: 9pt !important;
1744 border-top: 0.5pt solid #e5e7eb !important;
1745 color: #374151 !important;
1746 }
1747
1748 /* Contact info */
1749 body.yatra-printing-confirmation .yatra-contact-info {
1750 margin: 0 !important;
1751 }
1752 body.yatra-printing-confirmation .yatra-contact-item {
1753 font-size: 9.5pt !important;
1754 margin: 0 0 3pt !important;
1755 color: #111827 !important;
1756 }
1757 body.yatra-printing-confirmation .yatra-contact-item strong {
1758 color: #6b7280 !important;
1759 font-weight: 600 !important;
1760 margin-right: 4pt !important;
1761 }
1762
1763 /* Links — print as plain text, no underline (URL is still in browser footer) */
1764 body.yatra-printing-confirmation a,
1765 body.yatra-printing-confirmation a:visited {
1766 color: inherit !important;
1767 text-decoration: none !important;
1768 }
1769
1770 /* Avoid orphan headings */
1771 body.yatra-printing-confirmation h1,
1772 body.yatra-printing-confirmation h2,
1773 body.yatra-printing-confirmation h3,
1774 body.yatra-printing-confirmation h4 {
1775 page-break-after: avoid !important;
1776 break-after: avoid !important;
1777 }
1778 }
1779 </style>
1780
1781 <script>
1782 (function () {
1783 document.addEventListener('click', function (e) {
1784 var btn = e.target.closest('[data-yatra-print="confirmation"]');
1785 if (!btn) {
1786 return;
1787 }
1788 e.preventDefault();
1789
1790 var card = document.querySelector('.yatra-confirmation-container');
1791 if (!card) {
1792 window.print();
1793 return;
1794 }
1795
1796 // Wrap (or reuse) a print-only root so the @media print rules can target a single
1797 // direct child of <body>. Reused on the account page if the same data attribute
1798 // and CSS rules are added there.
1799 var root = document.querySelector('.yatra-print-root');
1800 var addedWrapper = false;
1801 if (!root) {
1802 root = document.createElement('div');
1803 root.className = 'yatra-print-root';
1804 document.body.appendChild(root);
1805 addedWrapper = true;
1806 }
1807 var clone = card.cloneNode(true);
1808 // Drop the action buttons from the clone so they don't appear on paper.
1809 clone.querySelectorAll('.yatra-confirmation-actions').forEach(function (n) { n.remove(); });
1810 root.innerHTML = '';
1811 root.appendChild(clone);
1812
1813 document.body.classList.add('yatra-printing-confirmation');
1814
1815 var cleanup = function () {
1816 document.body.classList.remove('yatra-printing-confirmation');
1817 if (addedWrapper && root && root.parentNode) {
1818 root.parentNode.removeChild(root);
1819 } else if (root) {
1820 root.innerHTML = '';
1821 }
1822 window.removeEventListener('afterprint', cleanup);
1823 };
1824
1825 window.addEventListener('afterprint', cleanup);
1826 // Safety net for browsers that don't fire afterprint reliably.
1827 window.setTimeout(function () {
1828 if (document.body.classList.contains('yatra-printing-confirmation')) {
1829 cleanup();
1830 }
1831 }, 5000);
1832
1833 window.print();
1834 });
1835 })();
1836 </script>
1837
1838 <?php yatra_get_footer(); ?>
1839
1840