| 1 |
<?php |
| 2 |
/** |
| 3 |
* Booking Content Partial |
| 4 |
* |
| 5 |
* Main booking form and sidebar content - used by both: |
| 6 |
* - booking.php (with header/footer) |
| 7 |
* - shortcode (without header/footer) |
| 8 |
* |
| 9 |
* @package Yatra |
| 10 |
* |
| 11 |
* Expected variables from parent: |
| 12 |
* - $booking (global object) |
| 13 |
* - $trip |
| 14 |
* - $travel_date |
| 15 |
* - $total_travelers |
| 16 |
* - $deposit_required |
| 17 |
* - $deposit_percentage |
| 18 |
* - $partial_payment |
| 19 |
* - $partial_payment_percentage |
| 20 |
* - $enabled_gateways |
| 21 |
* - $is_remaining_payment |
| 22 |
* - $remaining_amount |
| 23 |
* - $existing_booking_id |
| 24 |
* - $booking_reference |
| 25 |
*/ |
| 26 |
|
| 27 |
if (!defined('ABSPATH')) { |
| 28 |
exit; |
| 29 |
} |
| 30 |
|
| 31 |
// Prepare variables for form fields partial |
| 32 |
$trip_id = $trip->id; |
| 33 |
$trip_slug = $trip->slug ?? ''; |
| 34 |
$is_remaining_payment = !empty($booking->is_remaining_payment); |
| 35 |
$remaining_amount = isset($booking->remaining_amount) ? (float) $booking->remaining_amount : null; |
| 36 |
$existing_booking_id = $booking->existing_booking_id ?? 0; |
| 37 |
$booking_reference = $booking->booking_reference ?? ''; |
| 38 |
$amount_paid = isset($booking->amount_paid) ? (float) $booking->amount_paid : null; |
| 39 |
$total_amount = isset($booking->total_amount) ? (float) $booking->total_amount : null; |
| 40 |
|
| 41 |
// Check if login is required |
| 42 |
$require_login = \Yatra\Services\SettingsService::get('require_login', false); |
| 43 |
$allow_guest_checkout = \Yatra\Services\SettingsService::get('allow_guest_checkout', true); |
| 44 |
$needs_authentication = !is_user_logged_in() && ($require_login || !$allow_guest_checkout); |
| 45 |
|
| 46 |
// Get group discount from booking object (calculated in AppServiceProvider) |
| 47 |
$group_discount = $booking->group_discount ?? null; |
| 48 |
$group_discount_amount = $group_discount['amount'] ?? 0; |
| 49 |
$group_discount_code = $group_discount['code'] ?? null; |
| 50 |
$group_discount_label = $group_discount['label'] ?? __('Group Discount', 'yatra'); |
| 51 |
|
| 52 |
// Get pre-calculated pricing from booking object (calculated in BookingPageHandler) |
| 53 |
$pricing_calculation = $booking->pricing_calculation ?? [ |
| 54 |
'base_amount' => 0, |
| 55 |
'gross_total' => 0, |
| 56 |
'final_total' => 0, |
| 57 |
'amount_due' => 0, |
| 58 |
'tax_calculation' => ['tax_breakdown' => [], 'total_tax_amount' => 0], |
| 59 |
]; |
| 60 |
|
| 61 |
$tax_calculation = $pricing_calculation['tax_calculation'] ?? ['tax_breakdown' => [], 'total_tax_amount' => 0]; |
| 62 |
|
| 63 |
// Use pre-calculated amounts |
| 64 |
$summary_total_amount = $is_remaining_payment && !empty($total_amount) |
| 65 |
? (float) $total_amount |
| 66 |
: ($pricing_calculation['final_total'] ?? 0); |
| 67 |
$summary_due_amount = $is_remaining_payment && $remaining_amount !== null |
| 68 |
? (float) $remaining_amount |
| 69 |
: ($pricing_calculation['amount_due'] ?? $pricing_calculation['final_total'] ?? 0); |
| 70 |
?> |
| 71 |
|
| 72 |
<div class="yatra-booking-page"> |
| 73 |
<div class="yatra-booking-container"> |
| 74 |
<div class="yatra-booking-layout"> |
| 75 |
<!-- Left Side: Auth Form or Booking Form --> |
| 76 |
<div class="yatra-booking-main"> |
| 77 |
<?php if ($needs_authentication) : ?> |
| 78 |
<!-- Show Login/Registration Form --> |
| 79 |
<div class="yatra-booking-header"> |
| 80 |
<h1><?php esc_html_e('Login Required', 'yatra'); ?></h1> |
| 81 |
<p class="yatra-booking-subtitle"><?php esc_html_e('Please login or create an account to continue with your booking', 'yatra'); ?></p> |
| 82 |
</div> |
| 83 |
|
| 84 |
<?php |
| 85 |
// Include the authentication form partial |
| 86 |
include YATRA_PLUGIN_PATH . 'templates/partials/booking-auth.php'; |
| 87 |
?> |
| 88 |
<?php else : ?> |
| 89 |
<!-- Show Booking Form --> |
| 90 |
<div class="yatra-booking-header"> |
| 91 |
<h1> |
| 92 |
<?php |
| 93 |
if (!empty($booking->is_remaining_payment)) { |
| 94 |
esc_html_e('Pay Remaining Balance', 'yatra'); |
| 95 |
} else { |
| 96 |
esc_html_e('Complete Your Booking', 'yatra'); |
| 97 |
} |
| 98 |
?> |
| 99 |
</h1> |
| 100 |
<p class="yatra-booking-subtitle"> |
| 101 |
<?php |
| 102 |
$reference_label = $booking_reference ? '#' . $booking_reference : ''; |
| 103 |
|
| 104 |
if ($is_remaining_payment) { |
| 105 |
echo esc_html( |
| 106 |
sprintf( |
| 107 |
/* translators: %s booking reference */ |
| 108 |
__('You are paying the remaining balance for Booking %s.', 'yatra'), |
| 109 |
$reference_label ?: __('(unknown reference)', 'yatra') |
| 110 |
) |
| 111 |
); |
| 112 |
} else { |
| 113 |
esc_html_e('Please fill in your details to complete the booking', 'yatra'); |
| 114 |
} |
| 115 |
?> |
| 116 |
</p> |
| 117 |
<?php if ($is_remaining_payment && !empty($remaining_amount)) : ?> |
| 118 |
<div class="yatra-remaining-banner"> |
| 119 |
<strong><?php esc_html_e('Amount Due Now', 'yatra'); ?>:</strong> |
| 120 |
<span><?php echo esc_html(yatra_format_price((float) $remaining_amount, null, false)); ?></span> |
| 121 |
<?php if ($amount_paid !== null) : ?> |
| 122 |
<small> |
| 123 |
<?php |
| 124 |
printf( |
| 125 |
/* translators: %s formatted amount */ |
| 126 |
esc_html__('Amount already paid: %s', 'yatra'), |
| 127 |
yatra_format_price((float) $amount_paid, null, false) |
| 128 |
); |
| 129 |
?> |
| 130 |
</small> |
| 131 |
<?php endif; ?> |
| 132 |
</div> |
| 133 |
<?php endif; ?> |
| 134 |
</div> |
| 135 |
|
| 136 |
<!-- Booking Form --> |
| 137 |
<form |
| 138 |
class="yatra-booking-form" |
| 139 |
id="yatra-booking-form" |
| 140 |
data-payment-due="<?php echo esc_attr($summary_due_amount); ?>" |
| 141 |
data-is-remaining-payment="<?php echo esc_attr($is_remaining_payment ? 'yes' : 'no'); ?>" |
| 142 |
> |
| 143 |
<?php |
| 144 |
// Pass pricing type info to form fields partial |
| 145 |
// Prefer booking pricing data, fallback to trip definition |
| 146 |
$trip_pricing_mode = \Yatra\Services\TripPricingService::resolvePricingType($trip); |
| 147 |
$pricing_type = !empty($booking->pricing_type) ? $booking->pricing_type : ($trip->pricing_type ?? 'regular'); |
| 148 |
$price_types = !empty($booking->price_types) ? $booking->price_types : ($trip->price_types ?? []); |
| 149 |
if ($trip_pricing_mode === 'regular' && empty($booking->price_types)) { |
| 150 |
$pricing_type = 'regular'; |
| 151 |
$price_types = []; |
| 152 |
} |
| 153 |
if (empty($pricing_type) && !empty($price_types)) { |
| 154 |
$pricing_type = 'traveler_based'; |
| 155 |
} |
| 156 |
// Do not override explicit regular trip pricing with orphan trip_price_types rows |
| 157 |
if (empty($price_types) && !empty($trip->price_types) && $trip_pricing_mode === 'traveler_based') { |
| 158 |
$price_types = $trip->price_types; |
| 159 |
if (empty($pricing_type) || $pricing_type === 'regular') { |
| 160 |
$pricing_type = 'traveler_based'; |
| 161 |
} |
| 162 |
} |
| 163 |
$traveler_counts = $booking->traveler_counts ?? []; |
| 164 |
|
| 165 |
// Include shared booking form fields |
| 166 |
include YATRA_PLUGIN_PATH . 'templates/partials/booking-form-fields.php'; |
| 167 |
?> |
| 168 |
|
| 169 |
<!-- Submit Button --> |
| 170 |
<div class="yatra-booking-actions"> |
| 171 |
<button type="submit" class="yatra-booking-pay-btn" id="yatra-submit-booking"> |
| 172 |
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="CurrentColor" stroke-width="2"> |
| 173 |
<rect x="1" y="4" width="22" height="16" rx="2" ry="2"></rect> |
| 174 |
<line x1="1" y1="10" x2="23" y2="10"></line> |
| 175 |
</svg> |
| 176 |
<span id="pay-button-text"><?php esc_html_e('Complete Booking', 'yatra'); ?></span> |
| 177 |
<span id="pay-amount"><?php echo esc_html(yatra_format_price((float) ($summary_due_amount ?? 0), null, false)); ?></span> |
| 178 |
</button> |
| 179 |
<a href="<?php echo esc_url(yatra_get_trip_permalink($trip)); ?>" class="yatra-booking-cancel-btn"> |
| 180 |
<?php esc_html_e('Cancel', 'yatra'); ?> |
| 181 |
</a> |
| 182 |
</div> |
| 183 |
<div class="yatra-booking-form-errors" id="yatra-booking-form-errors" aria-live="polite"></div> |
| 184 |
|
| 185 |
<input type="hidden" name="trip_price" value="<?php echo esc_attr($trip->price); ?>"> |
| 186 |
<input type="hidden" name="currency" value="<?php echo esc_attr(\Yatra\Services\SettingsService::getCurrency()); ?>"> |
| 187 |
<?php wp_nonce_field('yatra_booking_nonce', 'yatra_booking_nonce'); ?> |
| 188 |
</form> |
| 189 |
<?php endif; ?> |
| 190 |
</div> |
| 191 |
|
| 192 |
<!-- Right Side: Booking Summary --> |
| 193 |
<div class="yatra-booking-sidebar"> |
| 194 |
|
| 195 |
<?php if ($is_remaining_payment) : ?> |
| 196 |
<!-- Simplified Remaining Payment Sidebar --> |
| 197 |
<div class="yatra-booking-summary yatra-remaining-summary" data-summary-total="<?php echo esc_attr($summary_total_amount); ?>" data-summary-due="<?php echo esc_attr($summary_due_amount); ?>" data-is-remaining="yes"> |
| 198 |
<h3><?php esc_html_e('Payment Summary', 'yatra'); ?></h3> |
| 199 |
|
| 200 |
<!-- Booking Reference --> |
| 201 |
<div class="yatra-remaining-reference"> |
| 202 |
<div class="yatra-reference-badge"> |
| 203 |
<svg width="18" height="18" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 204 |
<path d="M14 2H6a2 2 0 0 0-2 2v16a2 2 0 0 0 2 2h12a2 2 0 0 0 2-2V8z"></path> |
| 205 |
<polyline points="14 2 14 8 20 8"></polyline> |
| 206 |
<line x1="16" y1="13" x2="8" y2="13"></line> |
| 207 |
<line x1="16" y1="17" x2="8" y2="17"></line> |
| 208 |
</svg> |
| 209 |
<span><?php esc_html_e('Booking Reference', 'yatra'); ?></span> |
| 210 |
</div> |
| 211 |
<strong class="yatra-reference-value">#<?php echo esc_html($booking_reference); ?></strong> |
| 212 |
</div> |
| 213 |
|
| 214 |
<!-- Trip Info Card --> |
| 215 |
<div class="yatra-remaining-trip-card"> |
| 216 |
<div class="yatra-remaining-trip-image"> |
| 217 |
<img src="<?php echo esc_url($trip->featured_image ?? ''); ?>" alt="<?php echo esc_attr($trip->title ?? ''); ?>"> |
| 218 |
</div> |
| 219 |
<div class="yatra-remaining-trip-info"> |
| 220 |
<h4><?php echo esc_html($trip->title); ?></h4> |
| 221 |
<div class="yatra-remaining-trip-meta"> |
| 222 |
<span> |
| 223 |
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 224 |
<rect x="3" y="4" width="18" height="18" rx="2" ry="2"></rect> |
| 225 |
<line x1="16" y1="2" x2="16" y2="6"></line> |
| 226 |
<line x1="8" y1="2" x2="8" y2="6"></line> |
| 227 |
<line x1="3" y1="10" x2="21" y2="10"></line> |
| 228 |
</svg> |
| 229 |
<?php echo esc_html(date_i18n(get_option('date_format'), strtotime($travel_date))); ?> |
| 230 |
</span> |
| 231 |
<span> |
| 232 |
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 233 |
<path d="M17 21v-2a4 4 0 0 0-4-4H5a4 4 0 0 0-4 4v2"></path> |
| 234 |
<circle cx="9" cy="7" r="4"></circle> |
| 235 |
</svg> |
| 236 |
<?php echo esc_html($total_travelers . ' ' . _n('traveler', 'travelers', $total_travelers, 'yatra')); ?> |
| 237 |
</span> |
| 238 |
</div> |
| 239 |
</div> |
| 240 |
</div> |
| 241 |
|
| 242 |
<!-- Payment Breakdown --> |
| 243 |
<div class="yatra-remaining-breakdown"> |
| 244 |
<div class="yatra-remaining-row"> |
| 245 |
<span><?php esc_html_e('Original Booking Total', 'yatra'); ?></span> |
| 246 |
<span><?php echo esc_html(yatra_format_price((float) ($total_amount ?? 0), null, false)); ?></span> |
| 247 |
</div> |
| 248 |
<div class="yatra-remaining-row yatra-remaining-paid"> |
| 249 |
<span> |
| 250 |
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 251 |
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path> |
| 252 |
<polyline points="22 4 12 14.01 9 11.01"></polyline> |
| 253 |
</svg> |
| 254 |
<?php esc_html_e('Amount Already Paid', 'yatra'); ?> |
| 255 |
</span> |
| 256 |
<span class="yatra-paid-amount"><?php echo esc_html(yatra_format_price((float) ($amount_paid ?? 0), null, false)); ?></span> |
| 257 |
</div> |
| 258 |
<div class="yatra-remaining-row yatra-remaining-due"> |
| 259 |
<span><strong><?php esc_html_e('Remaining Balance', 'yatra'); ?></strong></span> |
| 260 |
<span class="yatra-due-amount"><strong><?php echo esc_html(yatra_format_price((float) ($remaining_amount ?? 0), null, false)); ?></strong></span> |
| 261 |
</div> |
| 262 |
</div> |
| 263 |
|
| 264 |
<!-- Due Now Highlight --> |
| 265 |
<div class="yatra-remaining-due-now"> |
| 266 |
<div class="yatra-due-now-label"> |
| 267 |
<svg width="20" height="20" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 268 |
<rect x="1" y="4" width="22" height="16" rx="2" ry="2"></rect> |
| 269 |
<line x1="1" y1="10" x2="23" y2="10"></line> |
| 270 |
</svg> |
| 271 |
<?php esc_html_e('Amount Due Now', 'yatra'); ?> |
| 272 |
</div> |
| 273 |
<div class="yatra-due-now-amount" id="summary-due"> |
| 274 |
<?php echo esc_html(yatra_format_price((float) ($remaining_amount ?? 0), null, false)); ?> |
| 275 |
</div> |
| 276 |
</div> |
| 277 |
|
| 278 |
<!-- Secure Payment Badge --> |
| 279 |
<div class="yatra-remaining-secure"> |
| 280 |
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 281 |
<rect x="3" y="11" width="18" height="11" rx="2" ry="2"></rect> |
| 282 |
<path d="M7 11V7a5 5 0 0 1 10 0v4"></path> |
| 283 |
</svg> |
| 284 |
<span><?php esc_html_e('Secure SSL encrypted payment', 'yatra'); ?></span> |
| 285 |
</div> |
| 286 |
</div> |
| 287 |
<?php else : ?> |
| 288 |
<!-- Regular Booking Summary --> |
| 289 |
<div class="yatra-booking-summary" data-summary-total="<?php echo esc_attr($summary_total_amount); ?>" data-summary-due="<?php echo esc_attr($summary_due_amount); ?>" data-is-remaining="no"> |
| 290 |
<h3><?php esc_html_e('Booking Summary', 'yatra'); ?></h3> |
| 291 |
|
| 292 |
<!-- Travel Details --> |
| 293 |
<div class="yatra-summary-travel-details"> |
| 294 |
<?php |
| 295 |
$departure_time = $booking->departure_time ?? ''; |
| 296 |
$is_day_trip = $booking->is_day_trip ?? false; |
| 297 |
$pricing_type = $booking->pricing_type ?? 'regular'; |
| 298 |
$price_types = $booking->price_types ?? []; |
| 299 |
$traveler_counts = $booking->traveler_counts ?? []; |
| 300 |
?> |
| 301 |
|
| 302 |
<div class="yatra-summary-form-group"> |
| 303 |
<label for="travel-date"><?php esc_html_e('Travel Date', 'yatra'); ?></label> |
| 304 |
<div class="yatra-summary-readonly-field"> |
| 305 |
<?php if ($is_day_trip && !empty($departure_time)): ?> |
| 306 |
<span class="yatra-date-display"><?php echo esc_html(\Yatra\Helpers\FormatHelper::formatDate((string) $travel_date)); ?></span> |
| 307 |
<span class="yatra-time-display"><?php echo esc_html(\Yatra\Helpers\FormatHelper::formatTimeForDisplay($departure_time)); ?></span> |
| 308 |
<?php else: ?> |
| 309 |
<?php echo esc_html(\Yatra\Helpers\FormatHelper::formatDate((string) $travel_date)); ?> |
| 310 |
<?php endif; ?> |
| 311 |
</div> |
| 312 |
<input type="hidden" id="travel-date" name="travel_date" form="yatra-booking-form" value="<?php echo esc_attr($travel_date); ?>"> |
| 313 |
<?php if (!empty($departure_time)): ?> |
| 314 |
<input type="hidden" name="departure_time" form="yatra-booking-form" value="<?php echo esc_attr($departure_time); ?>"> |
| 315 |
<?php endif; ?> |
| 316 |
</div> |
| 317 |
|
| 318 |
<?php if ($pricing_type === 'traveler_based' && !empty($price_types)): ?> |
| 319 |
<!-- Traveler-based pricing: use shared traveler selector partial --> |
| 320 |
<div class="yatra-summary-form-group yatra-traveler-categories"> |
| 321 |
<label><?php esc_html_e('Travelers', 'yatra'); ?></label> |
| 322 |
<?php |
| 323 |
$traveler_rows = []; |
| 324 |
foreach ($price_types as $index => $pt) { |
| 325 |
$pt = (object) $pt; |
| 326 |
$category_id = $pt->category_id ?? $index; |
| 327 |
$category_label = $pt->category_label ?? __('Traveler', 'yatra'); |
| 328 |
$count = isset($traveler_counts[$category_id]) ? (int) $traveler_counts[$category_id] : ($index === 0 ? 1 : 0); |
| 329 |
$category_price = isset($pt->effective_price) ? (float) $pt->effective_price : ($pt->sale_price ?? $pt->discounted_price ?? $pt->original_price ?? 0); |
| 330 |
$pricing_mode = (!empty($pt->pricing_mode) && $pt->pricing_mode === 'per_group') ? 'per_group' : 'per_person'; |
| 331 |
$age_info = ''; |
| 332 |
if (isset($pt->age_min) || isset($pt->age_max)) { |
| 333 |
if (isset($pt->age_min) && isset($pt->age_max)) { |
| 334 |
/* translators: 1: minimum age, 2: maximum age. */ |
| 335 |
$age_info = sprintf(__('(Age %1$d-%2$d)', 'yatra'), $pt->age_min, $pt->age_max); |
| 336 |
} elseif (isset($pt->age_min)) { |
| 337 |
/* translators: %d: minimum age. */ |
| 338 |
$age_info = sprintf(__('(Age %d+)', 'yatra'), $pt->age_min); |
| 339 |
} else { |
| 340 |
/* translators: %d: maximum age. */ |
| 341 |
$age_info = sprintf(__('(Up to age %d)', 'yatra'), $pt->age_max); |
| 342 |
} |
| 343 |
} |
| 344 |
$input_id = 'traveler_' . $category_id; |
| 345 |
$traveler_rows[] = [ |
| 346 |
'label' => $category_label, |
| 347 |
'subtitle' => $age_info, |
| 348 |
'price_html' => $category_price > 0 ? '<span class="yatra-quantity-price">' . yatra_format_price($category_price) . '</span>' : '', |
| 349 |
'row_attrs' => [ |
| 350 |
'data-category-id' => $category_id, |
| 351 |
'data-price' => $category_price, |
| 352 |
'data-pricing-mode' => $pricing_mode, |
| 353 |
'data-group-overflow' => $pt->group_overflow ?? 'block', |
| 354 |
'data-max-pax' => $pt->max_pax ?? '', |
| 355 |
], |
| 356 |
'minus_disabled' => ($index !== 0 && $count <= 0), |
| 357 |
'plus_disabled' => false, |
| 358 |
'minus_attrs' => [ |
| 359 |
'data-target' => $input_id, |
| 360 |
/* translators: %s: traveler category label (e.g. "Adult", "Child"). */ |
| 361 |
'aria-label' => sprintf(__('Decrease %s', 'yatra'), $category_label), |
| 362 |
], |
| 363 |
'plus_attrs' => [ |
| 364 |
'data-target' => $input_id, |
| 365 |
/* translators: %s: traveler category label (e.g. "Adult", "Child"). */ |
| 366 |
'aria-label' => sprintf(__('Increase %s', 'yatra'), $category_label), |
| 367 |
], |
| 368 |
'input_attrs' => [ |
| 369 |
'id' => $input_id, |
| 370 |
'name' => 'travelers[' . $category_id . ']', |
| 371 |
'value' => $count, |
| 372 |
'min' => 0, |
| 373 |
'max' => $trip->max_travelers ?: 20, |
| 374 |
'data-category-label' => $category_label, |
| 375 |
'data-price' => $category_price, |
| 376 |
'data-pricing-mode' => $pricing_mode, |
| 377 |
'data-group-overflow' => $pt->group_overflow ?? 'block', |
| 378 |
'data-max-pax' => $pt->max_pax ?? '', |
| 379 |
], |
| 380 |
]; |
| 381 |
} |
| 382 |
$traveler_display_text = !empty($traveler_rows) ? ($traveler_rows[0]['label'] . ' x ' . max(1, (int) $traveler_rows[0]['input_attrs']['value'])) : __('Traveler x 1', 'yatra'); |
| 383 |
$root_id = ''; |
| 384 |
$root_class = 'yatra-booking-field-select yatra-participants-select'; |
| 385 |
$container_attrs = []; |
| 386 |
$display_id = 'participants-display'; |
| 387 |
$display_class = 'yatra-participants-display'; |
| 388 |
$display_attrs = []; |
| 389 |
$dropdown_id = 'quantity-selector'; |
| 390 |
$dropdown_class = 'yatra-booking-quantity-selector'; |
| 391 |
$dropdown_attrs = []; |
| 392 |
$icon_html = yatra_svg_icon('users', 'yatra-icon-sm'); |
| 393 |
$rows = $traveler_rows; |
| 394 |
include YATRA_PLUGIN_PATH . 'templates/partials/traveler-selector.php'; |
| 395 |
?> |
| 396 |
</div> |
| 397 |
<?php else: ?> |
| 398 |
<!-- Regular pricing: Read-only display --> |
| 399 |
<div class="yatra-summary-form-group"> |
| 400 |
<label for="number-of-travelers"><?php esc_html_e('Travelers', 'yatra'); ?></label> |
| 401 |
<div class="yatra-summary-readonly-field"> |
| 402 |
<?php echo esc_html($total_travelers . ' ' . _n('traveler', 'travelers', $total_travelers, 'yatra')); ?> |
| 403 |
</div> |
| 404 |
<input type="hidden" id="number-of-travelers" name="number_of_travelers" form="yatra-booking-form" value="<?php echo esc_attr($total_travelers); ?>"> |
| 405 |
</div> |
| 406 |
<?php endif; ?> |
| 407 |
</div> |
| 408 |
|
| 409 |
<!-- Trip Info --> |
| 410 |
<div class="yatra-summary-trip"> |
| 411 |
<?php $trip_permalink = function_exists('yatra_get_trip_permalink') ? yatra_get_trip_permalink($trip) : ''; ?> |
| 412 |
<div class="yatra-summary-image"> |
| 413 |
<?php if (!empty($trip_permalink)) : ?> |
| 414 |
<a href="<?php echo esc_url($trip_permalink ?? ''); ?>"> |
| 415 |
<?php endif; ?> |
| 416 |
<img src="<?php echo esc_url($trip->featured_image ?? ''); ?>" alt="<?php echo esc_attr($trip->title ?? ''); ?>"> |
| 417 |
<?php if (!empty($trip_permalink)) : ?> |
| 418 |
</a> |
| 419 |
<?php endif; ?> |
| 420 |
</div> |
| 421 |
<div class="yatra-summary-details"> |
| 422 |
<?php if (!empty($trip_permalink)) : ?> |
| 423 |
<h4><a href="<?php echo esc_url($trip_permalink ?? ''); ?>"><?php echo esc_html($trip->title ?? ''); ?></a></h4> |
| 424 |
<?php else : ?> |
| 425 |
<h4><?php echo esc_html($trip->title); ?></h4> |
| 426 |
<?php endif; ?> |
| 427 |
<div class="yatra-summary-meta"> |
| 428 |
<?php |
| 429 |
$duration_days = (int) ($trip->duration_days ?? 0); |
| 430 |
$duration_nights = isset($trip->duration_nights) ? (int) $trip->duration_nights : null; |
| 431 |
$duration_hours = (int) ($trip->duration_hours ?? 0); |
| 432 |
?> |
| 433 |
<?php if ($duration_hours > 0) : ?> |
| 434 |
<span><?php echo esc_html(yatra_format_duration(0, null, $duration_hours)); ?></span> |
| 435 |
<?php elseif ($duration_days > 0) : ?> |
| 436 |
<?php if ($duration_days <= 1) : ?> |
| 437 |
<span><?php esc_html_e('Day Trip', 'yatra'); ?></span> |
| 438 |
<?php else : ?> |
| 439 |
<span><?php echo esc_html(yatra_format_duration($duration_days, $duration_nights)); ?></span> |
| 440 |
<?php endif; ?> |
| 441 |
<?php endif; ?> |
| 442 |
<?php |
| 443 |
// Resolve difficulty_level to a human label. |
| 444 |
// The trip row stores difficulty_level as the |
| 445 |
// classification FK id (e.g. 32), and that's |
| 446 |
// what we'd otherwise render — "32" on the |
| 447 |
// sidebar. Prefer the joined `difficulty_name` |
| 448 |
// when present; fall back to a one-row lookup |
| 449 |
// in wp_yatra_classifications when only the |
| 450 |
// id arrived; finally fall back to the raw |
| 451 |
// string (legacy trips that stored |
| 452 |
// 'easy'/'moderate' before the FK migration). |
| 453 |
$difficulty_label = ''; |
| 454 |
$difficulty_raw = $trip->difficulty_level ?? null; |
| 455 |
if (!empty($trip->difficulty_name)) { |
| 456 |
$difficulty_label = (string) $trip->difficulty_name; |
| 457 |
} elseif (is_numeric($difficulty_raw) && (int) $difficulty_raw > 0) { |
| 458 |
global $wpdb; |
| 459 |
$classifications_table = \Yatra\Database\Tables\ClassificationsTable::getTableName(); |
| 460 |
$difficulty_label = (string) $wpdb->get_var($wpdb->prepare( |
| 461 |
"SELECT name FROM {$classifications_table} WHERE id = %d LIMIT 1", |
| 462 |
(int) $difficulty_raw |
| 463 |
)); |
| 464 |
} elseif (is_string($difficulty_raw) && $difficulty_raw !== '') { |
| 465 |
$difficulty_label = ucfirst($difficulty_raw); |
| 466 |
} |
| 467 |
?> |
| 468 |
<?php if ($difficulty_label !== '') : ?> |
| 469 |
<span>•</span> |
| 470 |
<span><?php echo esc_html($difficulty_label); ?></span> |
| 471 |
<?php endif; ?> |
| 472 |
</div> |
| 473 |
</div> |
| 474 |
</div> |
| 475 |
|
| 476 |
|
| 477 |
<!-- Trip Attributes --> |
| 478 |
<?php if (!empty($trip->attributes)): ?> |
| 479 |
<div class="yatra-booking-attributes"> |
| 480 |
<h5><?php esc_html_e('Trip Features', 'yatra'); ?></h5> |
| 481 |
<div class="yatra-booking-attributes-list"> |
| 482 |
<?php foreach ($trip->attributes as $attribute): ?> |
| 483 |
<div class="yatra-booking-attribute-item"> |
| 484 |
<div class="yatra-booking-attribute-name"> |
| 485 |
<?php echo esc_html($attribute['name']); ?> |
| 486 |
</div> |
| 487 |
<div class="yatra-booking-attribute-value"> |
| 488 |
<?php |
| 489 |
// Display value based on field type (simplified for booking sidebar) |
| 490 |
switch ($attribute['field_type']) { |
| 491 |
case 'checkbox': |
| 492 |
$cb_val = $attribute['value'] ?? null; |
| 493 |
$cb_options = json_decode($attribute['field_options'] ?? '[]', true); |
| 494 |
if (!is_array($cb_options)) { |
| 495 |
$cb_options = []; |
| 496 |
} |
| 497 |
if (is_array($cb_val)) { |
| 498 |
$labels = []; |
| 499 |
foreach ($cb_options as $opt) { |
| 500 |
if (!isset($opt['value'], $opt['label'])) { |
| 501 |
continue; |
| 502 |
} |
| 503 |
foreach ($cb_val as $v) { |
| 504 |
if ((string) $v === (string) $opt['value']) { |
| 505 |
$labels[] = $opt['label']; |
| 506 |
break; |
| 507 |
} |
| 508 |
} |
| 509 |
} |
| 510 |
echo esc_html($labels !== [] ? implode(', ', $labels) : '—'); |
| 511 |
} else { |
| 512 |
echo $cb_val ? esc_html__('Yes', 'yatra') : esc_html__('No', 'yatra'); |
| 513 |
} |
| 514 |
break; |
| 515 |
case 'select': |
| 516 |
case 'radio': |
| 517 |
$options = json_decode($attribute['field_options'] ?? '[]', true); |
| 518 |
if (!is_array($options)) { |
| 519 |
$options = []; |
| 520 |
} |
| 521 |
$selected_value = is_array($attribute['value']) ? ($attribute['value'][0] ?? null) : ($attribute['value'] ?? null); |
| 522 |
$matched_label = null; |
| 523 |
foreach ($options as $option) { |
| 524 |
if (!is_array($option) || !isset($option['value'], $option['label'])) { |
| 525 |
continue; |
| 526 |
} |
| 527 |
if ((string) $option['value'] === (string) $selected_value) { |
| 528 |
$matched_label = (string) $option['label']; |
| 529 |
break; |
| 530 |
} |
| 531 |
} |
| 532 |
if ($matched_label !== null) { |
| 533 |
echo esc_html($matched_label); |
| 534 |
} elseif ($selected_value !== null && $selected_value !== '') { |
| 535 |
echo esc_html((string) $selected_value); |
| 536 |
} else { |
| 537 |
echo esc_html('—'); |
| 538 |
} |
| 539 |
break; |
| 540 |
case 'date': |
| 541 |
echo esc_html(date_i18n(get_option('date_format'), strtotime($attribute['value']))); |
| 542 |
break; |
| 543 |
case 'color': |
| 544 |
echo '<span class="yatra-booking-color-swatch" style="background-color: ' . esc_attr($attribute['value']) . ';" title="' . esc_attr($attribute['value']) . '"></span>'; |
| 545 |
break; |
| 546 |
case 'textarea': |
| 547 |
// Truncate long text for sidebar |
| 548 |
$text = wp_strip_all_tags($attribute['value']); |
| 549 |
echo esc_html(substr($text, 0, 25) . (strlen($text) > 25 ? '...' : '')); |
| 550 |
break; |
| 551 |
case 'number': |
| 552 |
echo esc_html(number_format($attribute['value'], 0)); |
| 553 |
break; |
| 554 |
default: |
| 555 |
// Truncate long text for sidebar |
| 556 |
echo esc_html(substr($attribute['value'], 0, 20) . (strlen($attribute['value']) > 20 ? '...' : '')); |
| 557 |
break; |
| 558 |
} |
| 559 |
?> |
| 560 |
</div> |
| 561 |
</div> |
| 562 |
<?php endforeach; ?> |
| 563 |
</div> |
| 564 |
</div> |
| 565 |
<?php endif; ?> |
| 566 |
|
| 567 |
<!-- Coupon Code Section |
| 568 |
Server-side checks whether a coupon is already |
| 569 |
applied to this booking session so the correct UI |
| 570 |
(toggle-to-enter vs applied-with-remove) is rendered |
| 571 |
on the FIRST byte. Without this, the page always |
| 572 |
shipped with the applied-coupon block `display:none` |
| 573 |
and relied on the JS `loadCouponFromSession()` GET |
| 574 |
to flip the visibility — which fails on page refresh |
| 575 |
in REST contexts where PHPSESSID doesn't propagate, |
| 576 |
leaving the user without a remove button. --> |
| 577 |
<?php |
| 578 |
$applied_coupon = null; |
| 579 |
if (!empty($booking) && is_object($booking)) { |
| 580 |
$session_for_coupon = yatra_get_booking_session(); |
| 581 |
if (is_array($session_for_coupon) && !empty($session_for_coupon['coupon']['code'])) { |
| 582 |
$applied_coupon = $session_for_coupon['coupon']; |
| 583 |
} |
| 584 |
} |
| 585 |
$coupon_is_applied = !empty($applied_coupon); |
| 586 |
$coupon_discount_amount_for_display = $coupon_is_applied |
| 587 |
? (float) ($applied_coupon['discount_amount'] ?? $applied_coupon['calculated_amount'] ?? 0) |
| 588 |
: 0.0; |
| 589 |
?> |
| 590 |
<div class="yatra-coupon-section"> |
| 591 |
<div class="yatra-coupon-toggle" <?php echo $coupon_is_applied ? 'style="display: none;"' : ''; ?>> |
| 592 |
<button type="button" id="yatra-coupon-toggle-btn" class="yatra-coupon-toggle-btn"> |
| 593 |
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 594 |
<path d="M20 12v6a2 2 0 0 1-2 2H6a2 2 0 0 1-2-2v-6"></path> |
| 595 |
<path d="M12 2v10"></path> |
| 596 |
<path d="m4.93 10.93 1.41 1.41"></path> |
| 597 |
<path d="m17.66 10.93-1.41 1.41"></path> |
| 598 |
<circle cx="12" cy="2" r="2"></circle> |
| 599 |
</svg> |
| 600 |
<?php esc_html_e('Have a coupon code?', 'yatra'); ?> |
| 601 |
<svg class="yatra-coupon-chevron" width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 602 |
<polyline points="6 9 12 15 18 9"></polyline> |
| 603 |
</svg> |
| 604 |
</button> |
| 605 |
</div> |
| 606 |
<div class="yatra-coupon-form" id="yatra-coupon-form" style="display: none;"> |
| 607 |
<div class="yatra-coupon-input-group"> |
| 608 |
<input type="text" id="yatra-coupon-code" name="coupon_code" placeholder="<?php esc_attr_e('Enter coupon code', 'yatra'); ?>" class="yatra-coupon-input" autocomplete="off"> |
| 609 |
<button type="button" id="yatra-apply-coupon" class="yatra-apply-coupon-btn"> |
| 610 |
<?php esc_html_e('Apply', 'yatra'); ?> |
| 611 |
</button> |
| 612 |
</div> |
| 613 |
<div id="yatra-coupon-message" class="yatra-coupon-message" style="display: none;"></div> |
| 614 |
</div> |
| 615 |
<!-- Applied Coupon Display — rendered visible on first paint when the |
| 616 |
session already has a coupon, so the remove button is reachable |
| 617 |
even before any JS runs. --> |
| 618 |
<div class="yatra-applied-coupon" id="yatra-applied-coupon" <?php echo $coupon_is_applied ? '' : 'style="display: none;"'; ?>> |
| 619 |
<div class="yatra-applied-coupon-info"> |
| 620 |
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 621 |
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path> |
| 622 |
<polyline points="22 4 12 14.01 9 11.01"></polyline> |
| 623 |
</svg> |
| 624 |
<span class="yatra-coupon-code-display"><?php echo $coupon_is_applied ? esc_html($applied_coupon['code']) : ''; ?></span> |
| 625 |
<span class="yatra-coupon-discount"><?php echo $coupon_is_applied && $coupon_discount_amount_for_display > 0 ? '-' . esc_html(yatra_format_price($coupon_discount_amount_for_display)) : ''; ?></span> |
| 626 |
</div> |
| 627 |
<button type="button" id="yatra-remove-coupon" class="yatra-remove-coupon-btn" title="<?php esc_attr_e('Remove coupon', 'yatra'); ?>"> |
| 628 |
<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"> |
| 629 |
<line x1="18" y1="6" x2="6" y2="18"></line> |
| 630 |
<line x1="6" y1="6" x2="18" y2="18"></line> |
| 631 |
</svg> |
| 632 |
</button> |
| 633 |
</div> |
| 634 |
</div> |
| 635 |
|
| 636 |
<!-- Additional Services Section (Premium Feature) |
| 637 |
Renders as its own card BEFORE the Pricing Summary |
| 638 |
(after the coupon code section). Checkbox toggles fire |
| 639 |
the change handler in booking.js → updateServicesInSession() |
| 640 |
→ /booking/session POST → schedulePricingSummaryRefresh() |
| 641 |
→ /booking/summary GET → re-render the pricing-summary |
| 642 |
partial below, which then shows the selected services |
| 643 |
as compact line items in the price breakdown. --> |
| 644 |
<?php |
| 645 |
/** |
| 646 |
* Filter: Get additional services for this trip |
| 647 |
* Allows premium modules to add extra services to the booking |
| 648 |
*/ |
| 649 |
$additional_services = apply_filters('yatra_booking_additional_services', [], $trip_id, $total_travelers, $traveler_counts ?? [], $travel_date); |
| 650 |
|
| 651 |
// Get selected services from session (set from popup) |
| 652 |
$session = yatra_get_booking_session(); |
| 653 |
$selected_service_ids = isset($session['additional_services']) && is_array($session['additional_services']) |
| 654 |
? array_map('intval', $session['additional_services']) |
| 655 |
: []; |
| 656 |
|
| 657 |
if (!empty($additional_services)) : |
| 658 |
?> |
| 659 |
<div class="yatra-additional-services-section"> |
| 660 |
<div class="yatra-services-header"> |
| 661 |
<h4><?php esc_html_e('Additional Services', 'yatra'); ?></h4> |
| 662 |
<p class="yatra-services-subtitle"><?php esc_html_e('Enhance your trip with these optional add-ons', 'yatra'); ?></p> |
| 663 |
</div> |
| 664 |
<div class="yatra-services-list" id="yatra-additional-services"> |
| 665 |
<?php foreach ($additional_services as $service) : |
| 666 |
$service_id = (int) $service['id']; |
| 667 |
$service_name = $service['name']; |
| 668 |
$service_description = (string) ($service['description'] ?? ''); |
| 669 |
$service_price = (float) $service['price']; |
| 670 |
$service_price_per = $service['price_per'] ?? 'person'; |
| 671 |
$service_price_type = $service['price_type'] ?? 'fixed'; |
| 672 |
$is_required = isset($service['is_required']) && ($service['is_required'] === true || $service['is_required'] === 1 || $service['is_required'] === '1'); |
| 673 |
$is_included = isset($service['is_included']) && ($service['is_included'] === true || $service['is_included'] === 1 || $service['is_included'] === '1'); |
| 674 |
$is_selected = in_array($service_id, $selected_service_ids, false); |
| 675 |
|
| 676 |
// Percentage services show "X% of trip price" (the actual |
| 677 |
// dollar amount is rendered in the price-breakdown summary). |
| 678 |
// Price Per does NOT apply to percentage (it's a % of the |
| 679 |
// whole trip), so no per-person/day/booking suffix is added. |
| 680 |
// Fixed services show the formatted amount plus the suffix. |
| 681 |
if ($service_price_type === 'percentage') { |
| 682 |
$pct_display = rtrim(rtrim(number_format($service_price, 2), '0'), '.'); |
| 683 |
/* translators: %s: percentage value, e.g. "17" */ |
| 684 |
$price_label = sprintf(__('%s%% of trip price', 'yatra'), $pct_display); |
| 685 |
} else { |
| 686 |
$price_label = yatra_format_price($service_price); |
| 687 |
if ($service_price_per === 'person') { |
| 688 |
$price_label .= ' ' . __('per person', 'yatra'); |
| 689 |
} elseif ($service_price_per === 'day') { |
| 690 |
$price_label .= ' ' . __('per day', 'yatra'); |
| 691 |
} else { |
| 692 |
$price_label .= ' ' . __('per booking', 'yatra'); |
| 693 |
} |
| 694 |
} |
| 695 |
if ($is_included) { |
| 696 |
$price_label = __('Included', 'yatra'); |
| 697 |
} |
| 698 |
|
| 699 |
$is_checked = $is_required || $is_included || $is_selected; |
| 700 |
$is_disabled = $is_required || $is_included; |
| 701 |
?> |
| 702 |
<?php |
| 703 |
// Description shown as a hover tooltip on the |
| 704 |
// whole row (no separate ⓘ icon). `title` lives |
| 705 |
// on the outer .yatra-service-item so hovering |
| 706 |
// anywhere in the block reveals the tooltip — |
| 707 |
// the small icon variant was easy to miss. |
| 708 |
$plain_description = $service_description !== '' ? wp_strip_all_tags($service_description) : ''; |
| 709 |
?> |
| 710 |
<div class="yatra-service-item <?php echo $is_required ? 'yatra-service-required' : ''; ?> <?php echo $is_checked ? 'yatra-service-selected' : ''; ?>" |
| 711 |
data-service-id="<?php echo esc_attr((string) $service_id); ?>" |
| 712 |
data-service-price="<?php echo esc_attr((string) $service_price); ?>" |
| 713 |
data-service-price-per="<?php echo esc_attr($service_price_per); ?>" |
| 714 |
data-is-required="<?php echo $is_required ? '1' : '0'; ?>" |
| 715 |
<?php if ($plain_description !== '') : ?> |
| 716 |
data-tooltip="<?php echo esc_attr($plain_description); ?>" |
| 717 |
aria-label="<?php echo esc_attr($plain_description); ?>" |
| 718 |
<?php endif; ?>> |
| 719 |
<label class="yatra-service-label"> |
| 720 |
<input type="checkbox" |
| 721 |
name="additional_services[]" |
| 722 |
value="<?php echo esc_attr((string) $service_id); ?>" |
| 723 |
<?php echo $is_checked ? 'checked' : ''; ?> |
| 724 |
<?php echo $is_disabled ? 'disabled' : ''; ?> |
| 725 |
form="yatra-booking-form"> |
| 726 |
<div class="yatra-service-info"> |
| 727 |
<span class="yatra-service-name"><?php echo esc_html($service_name); ?></span> |
| 728 |
</div> |
| 729 |
<span class="yatra-service-price"><?php echo esc_html($price_label); ?></span> |
| 730 |
</label> |
| 731 |
</div> |
| 732 |
<?php endforeach; ?> |
| 733 |
</div> |
| 734 |
</div> |
| 735 |
<?php endif; ?> |
| 736 |
|
| 737 |
<!-- Price Breakdown — services + dynamic-pricing summary + totals all live |
| 738 |
in one card so the sidebar reads as a single "Pricing Summary" panel. --> |
| 739 |
<div class="yatra-summary-pricing" id="yatra-summary-pricing" data-pricing-type="<?php echo esc_attr($pricing_type); ?>" data-is-remaining="<?php echo esc_attr($is_remaining_payment ? 'yes' : 'no'); ?>"> |
| 740 |
<?php |
| 741 |
// Get checkout model from booking object |
| 742 |
$checkout = $booking->checkout ?? null; |
| 743 |
|
| 744 |
// Surface the dynamic-pricing breakdown as a template |
| 745 |
// variable so the partial can render the DP line items. |
| 746 |
// CalculationService stuffs the breakdown into |
| 747 |
// `pricing_calculation.dynamic_pricing` via the |
| 748 |
// `yatra_price_breakdown` filter; without exposing it |
| 749 |
// here the partial's DP block stays dark on first load. |
| 750 |
$dynamic_pricing = $pricing_calculation['dynamic_pricing'] ?? null; |
| 751 |
$currency = $pricing_calculation['currency'] ?? null; |
| 752 |
|
| 753 |
// The pricing-summary partial calls $render_additional_services() |
| 754 |
// at the right spot — right after the traveler/per-person rows |
| 755 |
// and before the Trip Subtotal — so the services row shares the |
| 756 |
// same compact "label … price" layout as the traveler row. |
| 757 |
|
| 758 |
// Include pricing summary template (uses $checkout model) |
| 759 |
include YATRA_PLUGIN_PATH . 'templates/partials/pricing-summary.php'; |
| 760 |
?> |
| 761 |
</div> |
| 762 |
|
| 763 |
<!-- Cancellation Policy --> |
| 764 |
<?php if (!empty($trip->cancellation_policy)): ?> |
| 765 |
<div class="yatra-summary-info yatra-cancellation-policy"> |
| 766 |
<h4><?php esc_html_e('Cancellation Policy', 'yatra'); ?></h4> |
| 767 |
<div class="yatra-cancellation-policy-content"> |
| 768 |
<?php |
| 769 |
// Process and display the cancellation policy as a paragraph |
| 770 |
$policy_text = wp_strip_all_tags($trip->cancellation_policy); |
| 771 |
|
| 772 |
// Truncate if too long for booking summary |
| 773 |
$max_length = 200; |
| 774 |
if (strlen($policy_text) > $max_length) { |
| 775 |
$truncated_text = substr($policy_text, 0, $max_length); |
| 776 |
// Find last complete sentence within truncation |
| 777 |
$last_period = strrpos($truncated_text, '.'); |
| 778 |
$last_exclamation = strrpos($truncated_text, '!'); |
| 779 |
$last_question = strrpos($truncated_text, '?'); |
| 780 |
|
| 781 |
$last_sentence_end = max($last_period, $last_exclamation, $last_question); |
| 782 |
|
| 783 |
if ($last_sentence_end > $max_length * 0.7) { |
| 784 |
// If we have a complete sentence, end there |
| 785 |
$display_text = substr($truncated_text, 0, $last_sentence_end + 1); |
| 786 |
} else { |
| 787 |
// Otherwise, truncate at word boundary |
| 788 |
$display_text = substr($truncated_text, 0, strrpos($truncated_text, ' ')) . '...'; |
| 789 |
} |
| 790 |
} else { |
| 791 |
$display_text = $policy_text; |
| 792 |
} |
| 793 |
|
| 794 |
echo '<p>' . esc_html($display_text) . '</p>'; |
| 795 |
|
| 796 |
// Show "more" indicator if truncated |
| 797 |
if (strlen($policy_text) > $max_length) { |
| 798 |
echo '<p class="yatra-policy-more">'; |
| 799 |
echo esc_html__('Full policy available on trip details page', 'yatra'); |
| 800 |
echo '</p>'; |
| 801 |
} |
| 802 |
?> |
| 803 |
</div> |
| 804 |
</div> |
| 805 |
<?php endif; ?> |
| 806 |
|
| 807 |
<!-- Booking Assurance --> |
| 808 |
<div class="yatra-summary-info"> |
| 809 |
<h4><?php esc_html_e('Booking Assurance', 'yatra'); ?></h4> |
| 810 |
<ul> |
| 811 |
<li> |
| 812 |
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="display: inline-block; vertical-align: middle; margin-right: 6px;"> |
| 813 |
<path d="M22 11.08V12a10 10 0 1 1-5.93-9.14"></path> |
| 814 |
<polyline points="22 4 12 14.01 9 11.01"></polyline> |
| 815 |
</svg> |
| 816 |
<?php esc_html_e('Instant confirmation', 'yatra'); ?> |
| 817 |
</li> |
| 818 |
<li> |
| 819 |
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="display: inline-block; vertical-align: middle; margin-right: 6px;"> |
| 820 |
<path d="M22 16.92v3a2 2 0 0 1-2.18 2 19.79 19.79 0 0 1-8.63-3.07 19.5 19.5 0 0 1-6-6 19.79 19.79 0 0 1-3.07-8.67A2 2 0 0 1 4.11 2h3a2 2 0 0 1 2 1.72 12.84 12.84 0 0 0 .7 2.81 2 2 0 0 1-.45 2.11L8.09 9.91a16 16 0 0 0 6 6l1.27-1.27a2 2 0 0 1 2.11-.45 12.84 12.84 0 0 0 2.81.7A2 2 0 0 1 22 16.92z"></path> |
| 821 |
</svg> |
| 822 |
<?php esc_html_e('24/7 customer support', 'yatra'); ?> |
| 823 |
</li> |
| 824 |
<li> |
| 825 |
<svg width="16" height="16" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" style="display: inline-block; vertical-align: middle; margin-right: 6px;"> |
| 826 |
<rect x="1" y="4" width="22" height="16" rx="2" ry="2"></rect> |
| 827 |
<line x1="1" y1="10" x2="23" y2="10"></line> |
| 828 |
</svg> |
| 829 |
<?php esc_html_e('Secure payment processing', 'yatra'); ?> |
| 830 |
</li> |
| 831 |
</ul> |
| 832 |
</div> |
| 833 |
|
| 834 |
<!-- Selected Gateway Info --> |
| 835 |
<div class="yatra-gateway-info" id="yatra-gateway-info" style="display: none;"> |
| 836 |
<h4><?php esc_html_e('Payment Information', 'yatra'); ?></h4> |
| 837 |
<div id="yatra-gateway-details"></div> |
| 838 |
</div> |
| 839 |
</div> |
| 840 |
<?php endif; ?> |
| 841 |
</div> |
| 842 |
</div> |
| 843 |
</div> |
| 844 |
</div> |
| 845 |
|
| 846 |
|