@almatar/smart-booking-dashboard 0.0.2-alpha.7 → 0.0.2-alpha.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/lib/components/booking-input/booking-input.component.mjs +17 -4
- package/esm2022/lib/components/flight-itinerary-card/flight-itinerary-card.component.mjs +3 -3
- package/esm2022/lib/components/hotel-cancel/components/almatar-hotel-auto-cancellation-select-rooms/components/almatar-hotel-auto-cancellation-non-refundable-room/almatar-hotel-auto-cancellation-non-refundable-room.component.mjs +4 -3
- package/esm2022/lib/components/reissue-dialog/reissue-dialog.component.mjs +3 -3
- package/esm2022/lib/components/reissue-dialog/steps/reissue-date-step/reissue-date-step.component.mjs +2 -2
- package/esm2022/lib/components/reissue-dialog/steps/reissue-legs-step/reissue-legs-step.component.mjs +3 -3
- package/esm2022/lib/components/reissue-dialog/steps/reissue-notice/reissue-notice.component.mjs +2 -2
- package/esm2022/lib/components/reissue-dialog/steps/reissue-route-step/reissue-route-step.component.mjs +3 -3
- package/esm2022/lib/components/reissue-dialog/steps/reissue-service-step/reissue-service-step.component.mjs +2 -2
- package/esm2022/lib/components/reissue-dialog/steps/reissue-upgrade-confirm-step/reissue-upgrade-confirm-step.component.mjs +3 -3
- package/esm2022/lib/components/reissue-dialog/steps/reissue-upgrade-step/reissue-upgrade-step.component.mjs +3 -5
- package/esm2022/lib/components/train-details/train-details.component.mjs +89 -0
- package/esm2022/lib/config/dashboard.config.mjs +6 -1
- package/esm2022/lib/models/booking.types.mjs +1 -1
- package/esm2022/lib/models/train.types.mjs +2 -0
- package/esm2022/lib/pages/smart-booking-dashboard/smart-booking-dashboard.component.mjs +34 -7
- package/esm2022/lib/services/booking.service.mjs +10 -3
- package/esm2022/lib/services/brand.service.mjs +29 -0
- package/esm2022/lib/services/reissue.service.mjs +3 -3
- package/esm2022/lib/shared/services/api.service.mjs +3 -3
- package/esm2022/lib/shared/services/sbd-http.mjs +27 -0
- package/esm2022/public-api.mjs +2 -1
- package/fesm2022/almatar-smart-booking-dashboard.mjs +219 -35
- package/fesm2022/almatar-smart-booking-dashboard.mjs.map +1 -1
- package/lib/components/booking-input/booking-input.component.d.ts +10 -4
- package/lib/components/cancel-dialog/cancel-dialog.component.d.ts +2 -2
- package/lib/components/train-details/train-details.component.d.ts +28 -0
- package/lib/config/dashboard.config.d.ts +17 -0
- package/lib/models/booking.types.d.ts +2 -0
- package/lib/models/train.types.d.ts +61 -0
- package/lib/pages/smart-booking-dashboard/smart-booking-dashboard.component.d.ts +6 -2
- package/lib/services/booking.service.d.ts +3 -0
- package/lib/services/brand.service.d.ts +14 -0
- package/lib/shared/services/sbd-http.d.ts +8 -0
- package/package.json +1 -1
- package/public-api.d.ts +2 -1
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { InjectionToken, makeEnvironmentProviders, inject, Injectable, input, model, output, Component, computed,
|
|
2
|
+
import { InjectionToken, makeEnvironmentProviders, inject, signal, Injectable, input, model, output, Component, computed, effect, EventEmitter, Inject, Optional, Input, Output, NgModule, ChangeDetectionStrategy, DestroyRef, Pipe, untracked, Injector, runInInjectionContext, HostListener } from '@angular/core';
|
|
3
3
|
import * as i1$2 from '@angular/common';
|
|
4
4
|
import { NgTemplateOutlet, NgClass, DOCUMENT, CommonModule, LowerCasePipe, UpperCasePipe, NgIf } from '@angular/common';
|
|
5
5
|
import * as i2$1 from 'primeng/button';
|
|
6
6
|
import { ButtonModule } from 'primeng/button';
|
|
7
|
-
import { HttpClient, HttpRequest, HttpEventType } from '@angular/common/http';
|
|
8
7
|
import { map, catchError as catchError$1, switchMap, debounceTime, distinctUntilChanged, tap, finalize } from 'rxjs/operators';
|
|
8
|
+
import { HttpHandler, HttpClient, HttpRequest, HttpEventType } from '@angular/common/http';
|
|
9
9
|
import { ToastrService } from 'ngx-toastr';
|
|
10
10
|
import * as i1 from '@angular/forms';
|
|
11
11
|
import { FormsModule } from '@angular/forms';
|
|
@@ -36,6 +36,11 @@ const SBD_DEFAULT_CONFIG = {
|
|
|
36
36
|
platform: 'BO',
|
|
37
37
|
webBaseUrl: '',
|
|
38
38
|
reissueEnabled: false,
|
|
39
|
+
brands: [
|
|
40
|
+
{ value: 'almatar', label: 'Almatar' },
|
|
41
|
+
{ value: 'nusuk', label: 'Nusuk' },
|
|
42
|
+
],
|
|
43
|
+
defaultBrand: 'almatar',
|
|
39
44
|
};
|
|
40
45
|
const SBD_CONFIG = new InjectionToken('SBD_CONFIG', {
|
|
41
46
|
providedIn: 'root',
|
|
@@ -48,9 +53,59 @@ function provideSmartBookingDashboard(config = {}) {
|
|
|
48
53
|
]);
|
|
49
54
|
}
|
|
50
55
|
|
|
56
|
+
/** The brand the agent is working on. It is sent as the `x-brand` header of every request of the dashboard. */
|
|
57
|
+
class SbdBrandService {
|
|
58
|
+
constructor() {
|
|
59
|
+
this.config = inject(SBD_CONFIG);
|
|
60
|
+
this.brands = this.config.brands;
|
|
61
|
+
/** The `value` of the selected brand. Starts on the default of the config (Almatar). */
|
|
62
|
+
this.brand = signal(this.start());
|
|
63
|
+
}
|
|
64
|
+
/** Ignores a value that is not one of the brands, so a wrong header can never be sent. */
|
|
65
|
+
setBrand(value) {
|
|
66
|
+
if (this.brands.some((b) => b.value === value)) {
|
|
67
|
+
this.brand.set(value);
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
start() {
|
|
71
|
+
const wanted = this.config.defaultBrand;
|
|
72
|
+
return this.brands.some((b) => b.value === wanted) ? wanted : (this.brands[0]?.value ?? 'almatar');
|
|
73
|
+
}
|
|
74
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SbdBrandService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
75
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SbdBrandService, providedIn: 'root' }); }
|
|
76
|
+
}
|
|
77
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SbdBrandService, decorators: [{
|
|
78
|
+
type: Injectable,
|
|
79
|
+
args: [{ providedIn: 'root' }]
|
|
80
|
+
}] });
|
|
81
|
+
|
|
82
|
+
/**
|
|
83
|
+
* Adds the `x-brand` header (the brand selected in the dashboard) to a request, then hands it to the host's own
|
|
84
|
+
* handler, so the host's interceptors (token, language...) still run after it.
|
|
85
|
+
*/
|
|
86
|
+
class SbdBrandHandler extends HttpHandler {
|
|
87
|
+
constructor(next, brand) {
|
|
88
|
+
super();
|
|
89
|
+
this.next = next;
|
|
90
|
+
this.brand = brand;
|
|
91
|
+
}
|
|
92
|
+
handle(req) {
|
|
93
|
+
return this.next.handle(req.clone({ setHeaders: { 'x-brand': this.brand.brand() } }));
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* The HttpClient of the package. The services of the package are provided in root, so they use the host's HttpClient
|
|
98
|
+
* and an interceptor registered inside the package would never see their requests. Every call of the package goes
|
|
99
|
+
* through this client instead, which adds `x-brand` without any change in the host app.
|
|
100
|
+
*/
|
|
101
|
+
const SBD_HTTP = new InjectionToken('SBD_HTTP', {
|
|
102
|
+
providedIn: 'root',
|
|
103
|
+
factory: () => new HttpClient(new SbdBrandHandler(inject(HttpHandler), inject(SbdBrandService))),
|
|
104
|
+
});
|
|
105
|
+
|
|
51
106
|
class SbdBookingService {
|
|
52
107
|
constructor() {
|
|
53
|
-
this.http = inject(
|
|
108
|
+
this.http = inject(SBD_HTTP);
|
|
54
109
|
this.config = inject(SBD_CONFIG);
|
|
55
110
|
this.base = this.config.apiBase;
|
|
56
111
|
}
|
|
@@ -70,6 +125,13 @@ class SbdBookingService {
|
|
|
70
125
|
})
|
|
71
126
|
.pipe(map(data => ({ data, elapsedMs: performance.now() - start })));
|
|
72
127
|
}
|
|
128
|
+
/** Train booking details: bilingual sections + summary, ready to show (same API Helix uses). */
|
|
129
|
+
getTrainDetails(id) {
|
|
130
|
+
const base = (this.config.trainApiBase ?? this.base).replace(/\/+$/, '');
|
|
131
|
+
return this.http.get(`${base}/crm/fcr/booking/${encodeURIComponent(id)}/details`, {
|
|
132
|
+
params: { product: 'trains' },
|
|
133
|
+
});
|
|
134
|
+
}
|
|
73
135
|
resendTicket(id) {
|
|
74
136
|
return this.http.post(`${this.base}/v1/fcr/booking/${id}/resend`, {});
|
|
75
137
|
}
|
|
@@ -1201,15 +1263,27 @@ class SbdBookingInputComponent {
|
|
|
1201
1263
|
this.product = model('flight');
|
|
1202
1264
|
this.bookingId = model('');
|
|
1203
1265
|
this.lookup = output();
|
|
1266
|
+
/** The agent picked another brand: the booking on screen belongs to the previous one. */
|
|
1267
|
+
this.brandChanged = output();
|
|
1268
|
+
this.brandService = inject(SbdBrandService);
|
|
1269
|
+
this.brands = this.brandService.brands;
|
|
1270
|
+
this.brand = this.brandService.brand;
|
|
1204
1271
|
this.productOptions = [
|
|
1205
1272
|
{ label: '✈ Flight', value: 'flight' },
|
|
1206
1273
|
{ label: '🏨 Hotel', value: 'hotel' },
|
|
1274
|
+
{ label: '🚆 Train', value: 'train' },
|
|
1207
1275
|
];
|
|
1208
1276
|
this.demoIds = [
|
|
1209
1277
|
{ label: 'Demo Flight: ALM-20481', value: 'ALM-20481' },
|
|
1210
1278
|
{ label: 'Demo Hotel: ALM-HTL-9921', value: 'ALM-HTL-9921' },
|
|
1211
1279
|
];
|
|
1212
1280
|
}
|
|
1281
|
+
onBrand(value) {
|
|
1282
|
+
if (value === this.brand())
|
|
1283
|
+
return;
|
|
1284
|
+
this.brandService.setBrand(value);
|
|
1285
|
+
this.brandChanged.emit(value);
|
|
1286
|
+
}
|
|
1213
1287
|
fillDemo(id) {
|
|
1214
1288
|
const product = id.includes('HTL') ? 'hotel' : 'flight';
|
|
1215
1289
|
this.product.set(product);
|
|
@@ -1220,11 +1294,11 @@ class SbdBookingInputComponent {
|
|
|
1220
1294
|
this.lookup.emit();
|
|
1221
1295
|
}
|
|
1222
1296
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SbdBookingInputComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
1223
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.
|
|
1297
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SbdBookingInputComponent, isStandalone: true, selector: "app-sbd-booking-input", inputs: { loading: { classPropertyName: "loading", publicName: "loading", isSignal: true, isRequired: false, transformFunction: null }, product: { classPropertyName: "product", publicName: "product", isSignal: true, isRequired: false, transformFunction: null }, bookingId: { classPropertyName: "bookingId", publicName: "bookingId", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { product: "productChange", bookingId: "bookingIdChange", lookup: "lookup", brandChanged: "brandChanged" }, ngImport: i0, template: "<div class=\"sbd-booking-input\">\n <div class=\"sbd-booking-input__top\">\n <p-selectButton\n [(ngModel)]=\"product\"\n [options]=\"productOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n optionDisabled=\"disabled\">\n <ng-template pTemplate=\"item\" let-item>\n <span\n [pTooltip]=\"item.disabled ? 'Coming soon' : null\"\n tooltipPosition=\"bottom\"\n style=\"pointer-events: auto; display: inline-block;\">\n {{ item.label }}\n </span>\n </ng-template>\n </p-selectButton>\n </div>\n <div class=\"sbd-booking-input__row\">\n <div class=\"sbd-booking-input__field-wrap\">\n <i class=\"pi pi-search sbd-booking-input__icon\"></i>\n <input pInputText class=\"sbd-booking-input__field\" placeholder=\"Enter Booking ID\"\n [(ngModel)]=\"bookingId\" (keydown)=\"onKeydown($event)\" autocomplete=\"off\" spellcheck=\"false\" />\n </div>\n <!-- Brand: one radio per configured brand, between the Booking ID field and the Lookup button. -->\n <div class=\"sbd-booking-input__brands\" role=\"radiogroup\" aria-label=\"Brand\">\n @for (b of brands; track b.value) {\n <label class=\"sbd-booking-input__brand-option\">\n <input type=\"radio\" name=\"sbd-brand\" [value]=\"b.value\" [checked]=\"brand() === b.value\"\n (change)=\"onBrand(b.value)\" />\n <span>{{ b.label }}</span>\n </label>\n }\n </div>\n <button pButton label=\"Lookup \u2192\" [disabled]=\"!bookingId().trim()\" (click)=\"lookup.emit()\" class=\"sbd-booking-input__btn\"></button>\n </div>\n</div>\n", styles: [".sbd-booking-input{background:#fff;border-radius:12px;border:1px solid #e2e8f0;padding:20px;display:flex;flex-direction:column;gap:14px}.sbd-booking-input__top{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}.sbd-booking-input__brands{display:flex;flex-direction:column;align-items:flex-start;gap:6px;flex-shrink:0}.sbd-booking-input__brand-option{display:inline-flex;align-items:center;gap:6px;margin:0;cursor:pointer;font-size:13.5px;font-weight:500;color:#1e2e4a}.sbd-booking-input__brand-option input{accent-color:var(--sbd-primary, #007ad9);width:16px;height:16px;margin:0;cursor:pointer}.sbd-booking-input__row{display:flex;gap:10px;align-items:center;flex-wrap:wrap}.sbd-booking-input__field-wrap{flex:1 1 220px;position:relative;display:flex;align-items:center}.sbd-booking-input__icon{position:absolute;left:12px;color:#94a3b8;font-size:14px;pointer-events:none;z-index:1}.sbd-booking-input__field{width:100%!important;padding-left:36px!important;height:44px;font-size:14px!important}.sbd-booking-input__field:enabled:focus{border-color:var(--sbd-primary, #007ad9);box-shadow:0 0 0 .2em color-mix(in srgb,var(--sbd-primary, #007ad9) 45%,#fff)}.sbd-booking-input__btn{height:44px;white-space:nowrap;background:var(--sbd-primary, #007ad9);border-color:var(--sbd-primary, #007ad9)}.sbd-booking-input__btn:enabled:hover{background:color-mix(in srgb,var(--sbd-primary, #007ad9) 88%,#000);border-color:color-mix(in srgb,var(--sbd-primary, #007ad9) 88%,#000)}.sbd-booking-input__btn:enabled:focus{box-shadow:0 0 0 .2em color-mix(in srgb,var(--sbd-primary, #007ad9) 45%,#fff)}.sbd-booking-input__demos{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.sbd-booking-input__demos-label{font-size:11.5px;color:#94a3b8}.sbd-booking-input__chip{padding:4px 10px;border-radius:20px;border:1px solid #e2e8f0;background:#f8fafc;color:#1e2e4a;font-size:11.5px;font-weight:500;cursor:pointer;transition:border-color .15s,background .15s}.sbd-booking-input__chip:hover{border-color:var(--sbd-primary, #3b82f6);background:var(--sbd-primary-soft, #eff6ff);color:var(--sbd-primary, #3b82f6)}:host ::ng-deep .p-selectbutton .p-button.p-highlight{background:var(--sbd-primary, #007ad9);border-color:var(--sbd-primary, #007ad9)}:host ::ng-deep .p-selectbutton .p-button.p-highlight:hover{background:color-mix(in srgb,var(--sbd-primary, #007ad9) 88%,#000);border-color:color-mix(in srgb,var(--sbd-primary, #007ad9) 88%,#000)}:host ::ng-deep .p-selectbutton .p-button.p-highlight:focus{box-shadow:0 0 0 .2em color-mix(in srgb,var(--sbd-primary, #007ad9) 45%,#fff)}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: SelectButtonModule }, { kind: "component", type: i2.SelectButton, selector: "p-selectButton", inputs: ["options", "optionLabel", "optionValue", "optionDisabled", "tabindex", "multiple", "style", "styleClass", "ariaLabelledBy", "disabled", "dataKey"], outputs: ["onOptionClick", "onChange"] }, { kind: "ngmodule", type: InputTextModule }, { kind: "directive", type: i3.InputText, selector: "[pInputText]" }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2$1.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading"] }, { kind: "ngmodule", type: TooltipModule }, { kind: "directive", type: i5.Tooltip, selector: "[pTooltip]", inputs: ["tooltipPosition", "tooltipEvent", "appendTo", "positionStyle", "tooltipStyleClass", "tooltipZIndex", "escape", "showDelay", "hideDelay", "life", "positionTop", "positionLeft", "fitContent", "pTooltip", "tooltipDisabled", "tooltipOptions"] }] }); }
|
|
1224
1298
|
}
|
|
1225
1299
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SbdBookingInputComponent, decorators: [{
|
|
1226
1300
|
type: Component,
|
|
1227
|
-
args: [{ selector: 'app-sbd-booking-input', standalone: true, imports: [FormsModule, SelectButtonModule, InputTextModule, ButtonModule, TooltipModule], template: "<div class=\"sbd-booking-input\">\n <p-selectButton\n [(ngModel)]=\"product\"\n [options]=\"productOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n optionDisabled=\"disabled\">\n <ng-template pTemplate=\"item\" let-item>\n <span\n [pTooltip]=\"item.disabled ? 'Coming soon' : null\"\n tooltipPosition=\"bottom\"\n style=\"pointer-events: auto; display: inline-block;\">\n {{ item.label }}\n </span>\n </ng-template>\n </p-selectButton>\n <div class=\"sbd-booking-input__row\">\n <div class=\"sbd-booking-input__field-wrap\">\n <i class=\"pi pi-search sbd-booking-input__icon\"></i>\n <input pInputText class=\"sbd-booking-input__field\" placeholder=\"Enter Booking ID\"\n [(ngModel)]=\"bookingId\" (keydown)=\"onKeydown($event)\" autocomplete=\"off\" spellcheck=\"false\" />\n </div>\n <button pButton label=\"Lookup \u2192\" [disabled]=\"!bookingId().trim()\" (click)=\"lookup.emit()\" class=\"sbd-booking-input__btn\"></button>\n </div>\n</div>\n", styles: [".sbd-booking-input{background:#fff;border-radius:12px;border:1px solid #e2e8f0;padding:20px;display:flex;flex-direction:column;gap:14px}.sbd-booking-input__row{display:flex;gap:10px;align-items:center}.sbd-booking-input__field-wrap{flex:1;position:relative;display:flex;align-items:center}.sbd-booking-input__icon{position:absolute;left:12px;color:#94a3b8;font-size:14px;pointer-events:none;z-index:1}.sbd-booking-input__field{width:100%!important;padding-left:36px!important;height:44px;font-size:14px!important}.sbd-booking-input__field:enabled:focus{border-color:var(--sbd-primary, #007ad9);box-shadow:0 0 0 .2em color-mix(in srgb,var(--sbd-primary, #007ad9) 45%,#fff)}.sbd-booking-input__btn{height:44px;white-space:nowrap;background:var(--sbd-primary, #007ad9);border-color:var(--sbd-primary, #007ad9)}.sbd-booking-input__btn:enabled:hover{background:color-mix(in srgb,var(--sbd-primary, #007ad9) 88%,#000);border-color:color-mix(in srgb,var(--sbd-primary, #007ad9) 88%,#000)}.sbd-booking-input__btn:enabled:focus{box-shadow:0 0 0 .2em color-mix(in srgb,var(--sbd-primary, #007ad9) 45%,#fff)}.sbd-booking-input__demos{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.sbd-booking-input__demos-label{font-size:11.5px;color:#94a3b8}.sbd-booking-input__chip{padding:4px 10px;border-radius:20px;border:1px solid #e2e8f0;background:#f8fafc;color:#1e2e4a;font-size:11.5px;font-weight:500;cursor:pointer;transition:border-color .15s,background .15s}.sbd-booking-input__chip:hover{border-color:var(--sbd-primary, #3b82f6);background:var(--sbd-primary-soft, #eff6ff);color:var(--sbd-primary, #3b82f6)}:host ::ng-deep .p-selectbutton .p-button.p-highlight{background:var(--sbd-primary, #007ad9);border-color:var(--sbd-primary, #007ad9)}:host ::ng-deep .p-selectbutton .p-button.p-highlight:hover{background:color-mix(in srgb,var(--sbd-primary, #007ad9) 88%,#000);border-color:color-mix(in srgb,var(--sbd-primary, #007ad9) 88%,#000)}:host ::ng-deep .p-selectbutton .p-button.p-highlight:focus{box-shadow:0 0 0 .2em color-mix(in srgb,var(--sbd-primary, #007ad9) 45%,#fff)}\n"] }]
|
|
1301
|
+
args: [{ selector: 'app-sbd-booking-input', standalone: true, imports: [FormsModule, SelectButtonModule, InputTextModule, ButtonModule, TooltipModule], template: "<div class=\"sbd-booking-input\">\n <div class=\"sbd-booking-input__top\">\n <p-selectButton\n [(ngModel)]=\"product\"\n [options]=\"productOptions\"\n optionLabel=\"label\"\n optionValue=\"value\"\n optionDisabled=\"disabled\">\n <ng-template pTemplate=\"item\" let-item>\n <span\n [pTooltip]=\"item.disabled ? 'Coming soon' : null\"\n tooltipPosition=\"bottom\"\n style=\"pointer-events: auto; display: inline-block;\">\n {{ item.label }}\n </span>\n </ng-template>\n </p-selectButton>\n </div>\n <div class=\"sbd-booking-input__row\">\n <div class=\"sbd-booking-input__field-wrap\">\n <i class=\"pi pi-search sbd-booking-input__icon\"></i>\n <input pInputText class=\"sbd-booking-input__field\" placeholder=\"Enter Booking ID\"\n [(ngModel)]=\"bookingId\" (keydown)=\"onKeydown($event)\" autocomplete=\"off\" spellcheck=\"false\" />\n </div>\n <!-- Brand: one radio per configured brand, between the Booking ID field and the Lookup button. -->\n <div class=\"sbd-booking-input__brands\" role=\"radiogroup\" aria-label=\"Brand\">\n @for (b of brands; track b.value) {\n <label class=\"sbd-booking-input__brand-option\">\n <input type=\"radio\" name=\"sbd-brand\" [value]=\"b.value\" [checked]=\"brand() === b.value\"\n (change)=\"onBrand(b.value)\" />\n <span>{{ b.label }}</span>\n </label>\n }\n </div>\n <button pButton label=\"Lookup \u2192\" [disabled]=\"!bookingId().trim()\" (click)=\"lookup.emit()\" class=\"sbd-booking-input__btn\"></button>\n </div>\n</div>\n", styles: [".sbd-booking-input{background:#fff;border-radius:12px;border:1px solid #e2e8f0;padding:20px;display:flex;flex-direction:column;gap:14px}.sbd-booking-input__top{display:flex;align-items:center;justify-content:space-between;gap:12px;flex-wrap:wrap}.sbd-booking-input__brands{display:flex;flex-direction:column;align-items:flex-start;gap:6px;flex-shrink:0}.sbd-booking-input__brand-option{display:inline-flex;align-items:center;gap:6px;margin:0;cursor:pointer;font-size:13.5px;font-weight:500;color:#1e2e4a}.sbd-booking-input__brand-option input{accent-color:var(--sbd-primary, #007ad9);width:16px;height:16px;margin:0;cursor:pointer}.sbd-booking-input__row{display:flex;gap:10px;align-items:center;flex-wrap:wrap}.sbd-booking-input__field-wrap{flex:1 1 220px;position:relative;display:flex;align-items:center}.sbd-booking-input__icon{position:absolute;left:12px;color:#94a3b8;font-size:14px;pointer-events:none;z-index:1}.sbd-booking-input__field{width:100%!important;padding-left:36px!important;height:44px;font-size:14px!important}.sbd-booking-input__field:enabled:focus{border-color:var(--sbd-primary, #007ad9);box-shadow:0 0 0 .2em color-mix(in srgb,var(--sbd-primary, #007ad9) 45%,#fff)}.sbd-booking-input__btn{height:44px;white-space:nowrap;background:var(--sbd-primary, #007ad9);border-color:var(--sbd-primary, #007ad9)}.sbd-booking-input__btn:enabled:hover{background:color-mix(in srgb,var(--sbd-primary, #007ad9) 88%,#000);border-color:color-mix(in srgb,var(--sbd-primary, #007ad9) 88%,#000)}.sbd-booking-input__btn:enabled:focus{box-shadow:0 0 0 .2em color-mix(in srgb,var(--sbd-primary, #007ad9) 45%,#fff)}.sbd-booking-input__demos{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.sbd-booking-input__demos-label{font-size:11.5px;color:#94a3b8}.sbd-booking-input__chip{padding:4px 10px;border-radius:20px;border:1px solid #e2e8f0;background:#f8fafc;color:#1e2e4a;font-size:11.5px;font-weight:500;cursor:pointer;transition:border-color .15s,background .15s}.sbd-booking-input__chip:hover{border-color:var(--sbd-primary, #3b82f6);background:var(--sbd-primary-soft, #eff6ff);color:var(--sbd-primary, #3b82f6)}:host ::ng-deep .p-selectbutton .p-button.p-highlight{background:var(--sbd-primary, #007ad9);border-color:var(--sbd-primary, #007ad9)}:host ::ng-deep .p-selectbutton .p-button.p-highlight:hover{background:color-mix(in srgb,var(--sbd-primary, #007ad9) 88%,#000);border-color:color-mix(in srgb,var(--sbd-primary, #007ad9) 88%,#000)}:host ::ng-deep .p-selectbutton .p-button.p-highlight:focus{box-shadow:0 0 0 .2em color-mix(in srgb,var(--sbd-primary, #007ad9) 45%,#fff)}\n"] }]
|
|
1228
1302
|
}] });
|
|
1229
1303
|
|
|
1230
1304
|
class SbdWorkflowActionsComponent {
|
|
@@ -3096,7 +3170,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
3096
3170
|
|
|
3097
3171
|
class ApiService {
|
|
3098
3172
|
constructor() {
|
|
3099
|
-
this.http = inject(
|
|
3173
|
+
this.http = inject(SBD_HTTP);
|
|
3100
3174
|
}
|
|
3101
3175
|
get(url, options) {
|
|
3102
3176
|
const requestUrl = typeof url === 'string' ? url : (url.url || url.endpoint);
|
|
@@ -3810,7 +3884,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
3810
3884
|
|
|
3811
3885
|
class AlmatarHotelAutoCancellationNonRefundableRoomComponent {
|
|
3812
3886
|
constructor() {
|
|
3813
|
-
this.http = inject(
|
|
3887
|
+
this.http = inject(SBD_HTTP);
|
|
3814
3888
|
this.destroyRef = inject(DestroyRef);
|
|
3815
3889
|
this.endpointsService = inject(AlmatarHotelAutoCancellationEndpointsService);
|
|
3816
3890
|
this.translateService = inject(TranslationService);
|
|
@@ -5771,11 +5845,97 @@ class SbdFlightItineraryCardComponent {
|
|
|
5771
5845
|
return `${Math.floor(mins / 60)}h ${mins % 60}m`;
|
|
5772
5846
|
}
|
|
5773
5847
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SbdFlightItineraryCardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5774
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SbdFlightItineraryCardComponent, isStandalone: true, selector: "app-sbd-flight-itinerary-card", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, product: { classPropertyName: "product", publicName: "product", isSignal: true, isRequired: true, transformFunction: null }, verified: { classPropertyName: "verified", publicName: "verified", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"fic\">\n @if (product() === 'flight') {\n\n <!-- \u2500\u2500 Verified pill \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (verified()) {\n <div class=\"fic__verified-bar\">\n <span class=\"fic__verified-pill\">\n <i class=\"pi pi-verified\"></i> Verified with Airlines\n </span>\n </div>\n }\n\n <!-- \u2500\u2500 Legs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @for (leg of legs(); track leg.direction + $index; let li = $index) {\n <div class=\"fic__leg\" [class.fic__leg--return]=\"leg.direction === 'Return'\">\n\n <!-- Leg header -->\n <div class=\"fic__leg-header\">\n <div class=\"fic__leg-direction\">\n <i class=\"pi\" [class.pi-arrow-right]=\"leg.direction !== 'Return'\" [class.pi-arrow-left]=\"leg.direction === 'Return'\"></i>\n <span>{{ leg.direction }}</span>\n </div>\n <div class=\"fic__leg-chips\">\n @if (leg.cabin) {\n <span class=\"fic__chip fic__chip--cabin\">{{ leg.cabin }}</span>\n }\n @if (leg.fareBrand) {\n <span class=\"fic__chip fic__chip--fare\">{{ leg.fareBrand }}</span>\n }\n </div>\n </div>\n\n <!-- Airline row -->\n @if (leg.airlineName) {\n <div class=\"fic__airline\">\n <i class=\"pi pi-send\"></i>\n <span>{{ leg.airlineName }}</span>\n </div>\n }\n\n <!-- Route timeline -->\n <div class=\"fic__route\">\n\n <!-- Origin -->\n <div class=\"fic__airport\">\n <div class=\"fic__airport-code\">{{ leg.from }}</div>\n <div class=\"fic__airport-time\">{{ fmtTime(leg.depTime) }}</div>\n <div class=\"fic__airport-date\">{{ fmtShortDate(leg.depTime) }}</div>\n </div>\n\n <!-- Segments + stops -->\n <div class=\"fic__timeline\">\n\n <!-- Top row: all labels -->\n <div class=\"fic__tl-top\">\n @for (seg of leg.durationSegments; track seg.DepartureAirportCode; let si = $index) {\n <div class=\"fic__tl-seg\">\n <span class=\"fic__tl-flt\">{{ leg.segments[si]?.AirlineCode }}{{ leg.segments[si]?.FlightNumber }}</span>\n <span class=\"fic__tl-dur\">{{ fmtMins(seg.SegmentElapsedTimeMinutes) }}</span>\n </div>\n @if (si < leg.stops.length) {\n <div class=\"fic__tl-stop\">\n <span class=\"fic__stop-dot\"></span>\n <span class=\"fic__stop-code\">{{ leg.stops[si].StopAirport }}</span>\n <span class=\"fic__stop-sep\">\u00B7</span>\n <span class=\"fic__stop-dur\">{{ fmtMins(leg.stops[si].LayoverDuration) }}</span>\n </div>\n }\n }\n </div>\n\n <!-- Bottom row: single continuous line + one arrow -->\n <div class=\"fic__tl-track\">\n <div class=\"fic__tl-line\"></div>\n <i class=\"pi pi-send fic__tl-plane\"></i>\n </div>\n\n </div>\n\n <!-- Destination -->\n <div class=\"fic__airport fic__airport--right\">\n <div class=\"fic__airport-code\">{{ leg.to }}</div>\n <div class=\"fic__airport-time\">{{ fmtTime(leg.arrTime) }}</div>\n <div class=\"fic__airport-date\">{{ fmtShortDate(leg.arrTime) }}</div>\n </div>\n\n </div>\n </div>\n }\n\n <!-- \u2500\u2500 Passengers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (passengers().length > 0) {\n <div class=\"fic__section\">\n <div class=\"fic__section-label\">\n <i class=\"pi pi-users\"></i> Passengers\n <span class=\"fic__section-count\">{{ passengers().length }}</span>\n </div>\n <div class=\"fic__pax-list\">\n @for (p of passengers(); track p.passengerId) {\n <div class=\"fic__pax\">\n <div class=\"fic__pax-top\">\n <span class=\"fic__pax-badge fic__pax-badge--{{ p.type | lowercase }}\">{{ typeLabel[p.type] ?? p.type }}</span>\n <span class=\"fic__pax-name\">{{ p.name?.prefix }} {{ p.name?.givenName }} {{ p.name?.surName }}</span>\n </div>\n <div class=\"fic__pax-bottom\">\n @if (p.identity?.number) {\n <span class=\"fic__pax-doc\"><i class=\"pi pi-id-card\"></i> {{ p.identity?.number }}</span>\n }\n @if (p.email) {\n <span class=\"fic__pax-email\">{{ p.email }}</span>\n }\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- \u2500\u2500 Payment \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (payment()) {\n <div class=\"fic__payment\">\n <div class=\"fic__payment-main\">\n <i class=\"pi pi-credit-card fic__payment-icon\"></i>\n <span class=\"fic__payment-amount\">{{ payment()?.amount }} {{ payment()?.currency }}</span>\n <span class=\"fic__payment-status\" [class.fic__payment-status--ok]=\"payment()?.status?.key === 'SUCCESS'\">\n <i class=\"pi\" [class.pi-check-circle]=\"payment()?.status?.key === 'SUCCESS'\" [class.pi-clock]=\"payment()?.status?.key !== 'SUCCESS'\"></i>\n {{ payment()?.status?.name }}\n </span>\n </div>\n @if (payment()?.method || payment()?.date) {\n <div class=\"fic__payment-sub\">\n @if (payment()?.method) { <span>{{ payment()?.method }}</span> }\n @if (payment()?.method && payment()?.date) { <span class=\"fic__dot\">\u00B7</span> }\n @if (payment()?.date) { <span>{{ payment()?.date }}</span> }\n </div>\n }\n </div>\n }\n\n\n }\n</div>\n", styles: [".fic{background:#fff;border:1px solid #e2e8f0;border-radius:12px;overflow:hidden;font-family:inherit}.fic__leg{padding:16px 16px 18px;border-bottom:1px solid #e2e8f0}.fic__leg--return{background:#fafbff}.fic__leg-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}.fic__leg-direction{display:flex;align-items:center;gap:6px;font-size:11px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:#1e2e4a}.fic__leg-direction .pi{font-size:10px;color:#475569}.fic__leg-chips{display:flex;gap:5px}.fic__chip{font-size:10.5px;font-weight:600;padding:2px 8px;border-radius:12px;letter-spacing:.02em}.fic__chip--cabin{background:#eff6ff;color:#1d4ed8}.fic__chip--fare{background:#fef9c3;color:#854d0e}.fic__airline{display:flex;align-items:center;gap:5px;font-size:12px;color:#64748b;margin-bottom:14px}.fic__airline .pi{font-size:11px;color:#94a3b8;transform:rotate(45deg)}.fic__route{display:flex;align-items:flex-start;gap:0}.fic__airport{display:flex;flex-direction:column;align-items:flex-start;flex-shrink:0}.fic__airport--right{align-items:flex-end}.fic__airport-code{font-size:26px;font-weight:800;color:#1e2e4a;line-height:1}.fic__airport-time{font-size:13px;font-weight:600;color:#334155;margin-top:3px}.fic__airport-date{font-size:10.5px;color:#94a3b8;margin-top:1px}.fic__timeline{flex:1;display:flex;flex-direction:column;gap:4px;margin:0 4px}.fic__tl-top{display:flex;align-items:flex-end;gap:0}.fic__tl-seg{flex:1;display:flex;flex-direction:column;align-items:center;gap:1px}.fic__tl-flt{font-size:10px;font-weight:700;color:#1e2e4a;background:#f1f5f9;padding:1px 5px;border-radius:4px;white-space:nowrap}.fic__tl-dur{font-size:9.5px;color:#94a3b8;white-space:nowrap}.fic__tl-stop{flex-shrink:0;display:inline-flex;align-items:center;gap:4px;padding:0 8px 1px}.fic__tl-track{display:flex;align-items:center;height:22px}.fic__tl-line{flex:1;height:2px;background:#cbd5e1}.fic__tl-plane{font-size:13px;color:#475569;transform:rotate(45deg);flex-shrink:0;margin-left:-2px}.fic__stop-dot{width:7px;height:7px;border-radius:50%;background:#94a3b8;flex-shrink:0}.fic__stop-code{font-size:11px;font-weight:700;color:#334155}.fic__stop-sep{font-size:11px;color:#cbd5e1}.fic__stop-dur{font-size:11px;font-weight:600;color:#f59e0b}.fic__section{padding:14px 16px;border-bottom:1px solid #e2e8f0}.fic__section-label{display:flex;align-items:center;gap:5px;font-size:10.5px;font-weight:800;letter-spacing:.07em;text-transform:uppercase;color:#64748b;margin-bottom:10px}.fic__section-label .pi{font-size:11px}.fic__section-count{margin-left:auto;background:#f1f5f9;color:#475569;font-size:10px;font-weight:700;padding:1px 6px;border-radius:10px}.fic__pax-list{display:flex;flex-direction:column;gap:8px}.fic__pax{background:#f8fafc;border-radius:8px;padding:8px 10px;display:flex;flex-direction:column;gap:5px}.fic__pax-top{display:flex;align-items:center;gap:7px}.fic__pax-badge{font-size:9.5px;font-weight:700;letter-spacing:.04em;padding:2px 7px;border-radius:10px;flex-shrink:0;text-transform:uppercase}.fic__pax-badge--adt{background:#dbeafe;color:#1d4ed8}.fic__pax-badge--cnn{background:#dcfce7;color:#15803d}.fic__pax-badge--inf{background:#fce7f3;color:#9d174d}.fic__pax-name{font-size:12.5px;font-weight:600;color:#1e2e4a;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.fic__pax-bottom{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.fic__pax-doc{display:inline-flex;align-items:center;gap:3px;font-size:11px;font-family:monospace;color:#475569;background:#f1f5f9;padding:1px 6px;border-radius:4px}.fic__pax-doc .pi{font-size:10px}.fic__pax-email{font-size:11px;color:#94a3b8;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:180px}.fic__payment{padding:12px 16px;background:#f8fafc;display:flex;flex-direction:column;gap:4px}.fic__payment-main{display:flex;align-items:center;gap:8px}.fic__payment-icon{font-size:14px;color:#64748b}.fic__payment-amount{font-size:14px;font-weight:700;color:#1e2e4a}.fic__payment-status{display:flex;align-items:center;gap:4px;font-size:12px;font-weight:600;color:#64748b;margin-left:auto}.fic__payment-status .pi{font-size:12px}.fic__payment-status--ok{color:#16a34a}.fic__payment-sub{display:flex;align-items:center;gap:6px;font-size:11.5px;color:#94a3b8;padding-left:22px}.fic__dot{color:#cbd5e1}.fic__verified-bar{display:flex;align-items:center;padding:8px 12px;background:#f0fdf4;border-bottom:1px solid #bbf7d0}.fic__verified-pill{display:inline-flex;align-items:center;gap:5px;padding:3px 10px 3px 7px;background:#16a34a;color:#fff;font-size:11px;font-weight:700;border-radius:20px;letter-spacing:.02em}.fic__verified-pill .pi{font-size:12px}\n"], dependencies: [{ kind: "ngmodule", type: TagModule }, { kind: "pipe", type: LowerCasePipe, name: "lowercase" }] }); }
|
|
5848
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SbdFlightItineraryCardComponent, isStandalone: true, selector: "app-sbd-flight-itinerary-card", inputs: { data: { classPropertyName: "data", publicName: "data", isSignal: true, isRequired: false, transformFunction: null }, product: { classPropertyName: "product", publicName: "product", isSignal: true, isRequired: true, transformFunction: null }, verified: { classPropertyName: "verified", publicName: "verified", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<div class=\"fic\">\n @if (product() === 'flight') {\n\n <!-- \u2500\u2500 Verified pill \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (verified()) {\n <div class=\"fic__verified-bar\">\n <span class=\"fic__verified-pill\">\n <i class=\"pi pi-verified\"></i> Verified with Airlines\n </span>\n </div>\n }\n\n <!-- \u2500\u2500 Legs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @for (leg of legs(); track leg.direction + $index; let li = $index) {\n <div class=\"fic__leg\" [class.fic__leg--return]=\"leg.direction === 'Return'\">\n\n <!-- Leg header -->\n <div class=\"fic__leg-header\">\n <div class=\"fic__leg-direction\">\n <i class=\"pi\" [class.pi-arrow-right]=\"leg.direction !== 'Return'\" [class.pi-arrow-left]=\"leg.direction === 'Return'\"></i>\n <span>{{ leg.direction }}</span>\n </div>\n <div class=\"fic__leg-chips\">\n @if (leg.cabin) {\n <span class=\"fic__chip fic__chip--cabin\">{{ leg.cabin }}</span>\n }\n @if (leg.fareBrand) {\n <span class=\"fic__chip fic__chip--fare\">{{ leg.fareBrand }}</span>\n }\n </div>\n </div>\n\n <!-- Airline row -->\n @if (leg.airlineName) {\n <div class=\"fic__airline\">\n <i class=\"pi pi-send\"></i>\n <span>{{ leg.airlineName }}</span>\n </div>\n }\n\n <!-- Route timeline -->\n <div class=\"fic__route\">\n\n <!-- Origin -->\n <div class=\"fic__airport\">\n <div class=\"fic__airport-code\">{{ leg.from }}</div>\n <div class=\"fic__airport-time\">{{ fmtTime(leg.depTime) }}</div>\n <div class=\"fic__airport-date\">{{ fmtShortDate(leg.depTime) }}</div>\n </div>\n\n <!-- Segments + stops -->\n <div class=\"fic__timeline\">\n\n <!-- Top row: all labels -->\n <div class=\"fic__tl-top\">\n @for (seg of leg.durationSegments; track seg.DepartureAirportCode; let si = $index) {\n <div class=\"fic__tl-seg\">\n <span class=\"fic__tl-flt\">{{ leg.segments[si]?.AirlineCode }}{{ leg.segments[si]?.FlightNumber }}</span>\n <span class=\"fic__tl-dur\">{{ fmtMins(seg.SegmentElapsedTimeMinutes) }}</span>\n </div>\n @if (si < leg.stops.length) {\n <div class=\"fic__tl-stop\">\n <span class=\"fic__stop-head\">\n <span class=\"fic__stop-dot\"></span>\n <span class=\"fic__stop-code\">{{ leg.stops[si].StopAirport }}</span>\n </span>\n <span class=\"fic__stop-dur\">{{ fmtMins(leg.stops[si].LayoverDuration) }}</span>\n </div>\n }\n }\n </div>\n\n <!-- Bottom row: single continuous line + one arrow -->\n <div class=\"fic__tl-track\">\n <div class=\"fic__tl-line\"></div>\n <i class=\"pi pi-send fic__tl-plane\"></i>\n </div>\n\n </div>\n\n <!-- Destination -->\n <div class=\"fic__airport fic__airport--right\">\n <div class=\"fic__airport-code\">{{ leg.to }}</div>\n <div class=\"fic__airport-time\">{{ fmtTime(leg.arrTime) }}</div>\n <div class=\"fic__airport-date\">{{ fmtShortDate(leg.arrTime) }}</div>\n </div>\n\n </div>\n </div>\n }\n\n <!-- \u2500\u2500 Passengers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (passengers().length > 0) {\n <div class=\"fic__section\">\n <div class=\"fic__section-label\">\n <i class=\"pi pi-users\"></i> Passengers\n <span class=\"fic__section-count\">{{ passengers().length }}</span>\n </div>\n <div class=\"fic__pax-list\">\n @for (p of passengers(); track p.passengerId) {\n <div class=\"fic__pax\">\n <div class=\"fic__pax-top\">\n <span class=\"fic__pax-badge fic__pax-badge--{{ p.type | lowercase }}\">{{ typeLabel[p.type] ?? p.type }}</span>\n <span class=\"fic__pax-name\">{{ p.name?.prefix }} {{ p.name?.givenName }} {{ p.name?.surName }}</span>\n </div>\n <div class=\"fic__pax-bottom\">\n @if (p.identity?.number) {\n <span class=\"fic__pax-doc\"><i class=\"pi pi-id-card\"></i> {{ p.identity?.number }}</span>\n }\n @if (p.email) {\n <span class=\"fic__pax-email\">{{ p.email }}</span>\n }\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- \u2500\u2500 Payment \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (payment()) {\n <div class=\"fic__payment\">\n <div class=\"fic__payment-main\">\n <i class=\"pi pi-credit-card fic__payment-icon\"></i>\n <span class=\"fic__payment-amount\">{{ payment()?.amount }} {{ payment()?.currency }}</span>\n <span class=\"fic__payment-status\" [class.fic__payment-status--ok]=\"payment()?.status?.key === 'SUCCESS'\">\n <i class=\"pi\" [class.pi-check-circle]=\"payment()?.status?.key === 'SUCCESS'\" [class.pi-clock]=\"payment()?.status?.key !== 'SUCCESS'\"></i>\n {{ payment()?.status?.name }}\n </span>\n </div>\n @if (payment()?.method || payment()?.date) {\n <div class=\"fic__payment-sub\">\n @if (payment()?.method) { <span>{{ payment()?.method }}</span> }\n @if (payment()?.method && payment()?.date) { <span class=\"fic__dot\">\u00B7</span> }\n @if (payment()?.date) { <span>{{ payment()?.date }}</span> }\n </div>\n }\n </div>\n }\n\n\n }\n</div>\n", styles: [".fic{background:#fff;border:1px solid #e2e8f0;border-radius:12px;overflow:hidden;font-family:inherit}.fic__leg{padding:16px 16px 18px;border-bottom:1px solid #e2e8f0}.fic__leg--return{background:#fafbff}.fic__leg-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}.fic__leg-direction{display:flex;align-items:center;gap:6px;font-size:11px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:#1e2e4a}.fic__leg-direction .pi{font-size:10px;color:#475569}.fic__leg-chips{display:flex;gap:5px}.fic__chip{font-size:10.5px;font-weight:600;padding:2px 8px;border-radius:12px;letter-spacing:.02em}.fic__chip--cabin{background:#eff6ff;color:#1d4ed8}.fic__chip--fare{background:#fef9c3;color:#854d0e}.fic__airline{display:flex;align-items:center;gap:5px;font-size:12px;color:#64748b;margin-bottom:14px}.fic__airline .pi{font-size:11px;color:#94a3b8;transform:rotate(45deg)}.fic__route{display:flex;align-items:flex-start;gap:0}.fic__airport{display:flex;flex-direction:column;align-items:flex-start;flex-shrink:0}.fic__airport--right{align-items:flex-end}.fic__airport-code{font-size:26px;font-weight:800;color:#1e2e4a;line-height:1}.fic__airport-time{font-size:13px;font-weight:600;color:#334155;margin-top:3px}.fic__airport-date{font-size:10.5px;color:#94a3b8;margin-top:1px}.fic__timeline{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px;margin:0 4px}.fic__tl-top{display:flex;align-items:flex-end;gap:0}.fic__tl-seg{flex:1 1 0;min-width:0;display:flex;flex-direction:column;align-items:center;gap:1px}.fic__tl-flt{font-size:10px;font-weight:700;color:#1e2e4a;background:#f1f5f9;padding:1px 5px;border-radius:4px;white-space:nowrap}.fic__tl-dur{font-size:9.5px;color:#94a3b8;white-space:nowrap}.fic__tl-stop{flex:0 0 auto;display:flex;flex-direction:column;align-items:center;gap:1px;padding:0 6px}.fic__stop-head{display:inline-flex;align-items:center;gap:4px}.fic__tl-track{display:flex;align-items:center;height:22px}.fic__tl-line{flex:1;height:2px;background:#cbd5e1}.fic__tl-plane{font-size:13px;color:#475569;transform:rotate(45deg);flex-shrink:0;margin-left:-2px}.fic__stop-dot{width:7px;height:7px;border-radius:50%;background:#94a3b8;flex-shrink:0}.fic__stop-code{font-size:11px;font-weight:700;color:#334155}.fic__stop-dur{font-size:10.5px;font-weight:600;color:#f59e0b;white-space:nowrap}.fic__section{padding:14px 16px;border-bottom:1px solid #e2e8f0}.fic__section-label{display:flex;align-items:center;gap:5px;font-size:10.5px;font-weight:800;letter-spacing:.07em;text-transform:uppercase;color:#64748b;margin-bottom:10px}.fic__section-label .pi{font-size:11px}.fic__section-count{margin-left:auto;background:#f1f5f9;color:#475569;font-size:10px;font-weight:700;padding:1px 6px;border-radius:10px}.fic__pax-list{display:flex;flex-direction:column;gap:8px}.fic__pax{background:#f8fafc;border-radius:8px;padding:8px 10px;display:flex;flex-direction:column;gap:5px}.fic__pax-top{display:flex;align-items:center;gap:7px}.fic__pax-badge{font-size:9.5px;font-weight:700;letter-spacing:.04em;padding:2px 7px;border-radius:10px;flex-shrink:0;text-transform:uppercase}.fic__pax-badge--adt{background:#dbeafe;color:#1d4ed8}.fic__pax-badge--cnn{background:#dcfce7;color:#15803d}.fic__pax-badge--inf{background:#fce7f3;color:#9d174d}.fic__pax-name{font-size:12.5px;font-weight:600;color:#1e2e4a;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.fic__pax-bottom{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.fic__pax-doc{display:inline-flex;align-items:center;gap:3px;font-size:11px;font-family:monospace;color:#475569;background:#f1f5f9;padding:1px 6px;border-radius:4px}.fic__pax-doc .pi{font-size:10px}.fic__pax-email{font-size:11px;color:#94a3b8;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:180px}.fic__payment{padding:12px 16px;background:#f8fafc;display:flex;flex-direction:column;gap:4px}.fic__payment-main{display:flex;align-items:center;gap:8px}.fic__payment-icon{font-size:14px;color:#64748b}.fic__payment-amount{font-size:14px;font-weight:700;color:#1e2e4a}.fic__payment-status{display:flex;align-items:center;gap:4px;font-size:12px;font-weight:600;color:#64748b;margin-left:auto}.fic__payment-status .pi{font-size:12px}.fic__payment-status--ok{color:#16a34a}.fic__payment-sub{display:flex;align-items:center;gap:6px;font-size:11.5px;color:#94a3b8;padding-left:22px}.fic__dot{color:#cbd5e1}.fic__verified-bar{display:flex;align-items:center;padding:8px 12px;background:#f0fdf4;border-bottom:1px solid #bbf7d0}.fic__verified-pill{display:inline-flex;align-items:center;gap:5px;padding:3px 10px 3px 7px;background:#16a34a;color:#fff;font-size:11px;font-weight:700;border-radius:20px;letter-spacing:.02em}.fic__verified-pill .pi{font-size:12px}\n"], dependencies: [{ kind: "ngmodule", type: TagModule }, { kind: "pipe", type: LowerCasePipe, name: "lowercase" }] }); }
|
|
5775
5849
|
}
|
|
5776
5850
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SbdFlightItineraryCardComponent, decorators: [{
|
|
5777
5851
|
type: Component,
|
|
5778
|
-
args: [{ selector: 'app-sbd-flight-itinerary-card', standalone: true, imports: [TagModule, UpperCasePipe, LowerCasePipe], template: "<div class=\"fic\">\n @if (product() === 'flight') {\n\n <!-- \u2500\u2500 Verified pill \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (verified()) {\n <div class=\"fic__verified-bar\">\n <span class=\"fic__verified-pill\">\n <i class=\"pi pi-verified\"></i> Verified with Airlines\n </span>\n </div>\n }\n\n <!-- \u2500\u2500 Legs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @for (leg of legs(); track leg.direction + $index; let li = $index) {\n <div class=\"fic__leg\" [class.fic__leg--return]=\"leg.direction === 'Return'\">\n\n <!-- Leg header -->\n <div class=\"fic__leg-header\">\n <div class=\"fic__leg-direction\">\n <i class=\"pi\" [class.pi-arrow-right]=\"leg.direction !== 'Return'\" [class.pi-arrow-left]=\"leg.direction === 'Return'\"></i>\n <span>{{ leg.direction }}</span>\n </div>\n <div class=\"fic__leg-chips\">\n @if (leg.cabin) {\n <span class=\"fic__chip fic__chip--cabin\">{{ leg.cabin }}</span>\n }\n @if (leg.fareBrand) {\n <span class=\"fic__chip fic__chip--fare\">{{ leg.fareBrand }}</span>\n }\n </div>\n </div>\n\n <!-- Airline row -->\n @if (leg.airlineName) {\n <div class=\"fic__airline\">\n <i class=\"pi pi-send\"></i>\n <span>{{ leg.airlineName }}</span>\n </div>\n }\n\n <!-- Route timeline -->\n <div class=\"fic__route\">\n\n <!-- Origin -->\n <div class=\"fic__airport\">\n <div class=\"fic__airport-code\">{{ leg.from }}</div>\n <div class=\"fic__airport-time\">{{ fmtTime(leg.depTime) }}</div>\n <div class=\"fic__airport-date\">{{ fmtShortDate(leg.depTime) }}</div>\n </div>\n\n <!-- Segments + stops -->\n <div class=\"fic__timeline\">\n\n <!-- Top row: all labels -->\n <div class=\"fic__tl-top\">\n @for (seg of leg.durationSegments; track seg.DepartureAirportCode; let si = $index) {\n <div class=\"fic__tl-seg\">\n <span class=\"fic__tl-flt\">{{ leg.segments[si]?.AirlineCode }}{{ leg.segments[si]?.FlightNumber }}</span>\n <span class=\"fic__tl-dur\">{{ fmtMins(seg.SegmentElapsedTimeMinutes) }}</span>\n </div>\n @if (si < leg.stops.length) {\n <div class=\"fic__tl-stop\">\n <span class=\"fic__stop-dot\"></span>\n <span class=\"fic__stop-code\">{{ leg.stops[si].StopAirport }}</span>\n <span class=\"fic__stop-sep\">\u00B7</span>\n <span class=\"fic__stop-dur\">{{ fmtMins(leg.stops[si].LayoverDuration) }}</span>\n </div>\n }\n }\n </div>\n\n <!-- Bottom row: single continuous line + one arrow -->\n <div class=\"fic__tl-track\">\n <div class=\"fic__tl-line\"></div>\n <i class=\"pi pi-send fic__tl-plane\"></i>\n </div>\n\n </div>\n\n <!-- Destination -->\n <div class=\"fic__airport fic__airport--right\">\n <div class=\"fic__airport-code\">{{ leg.to }}</div>\n <div class=\"fic__airport-time\">{{ fmtTime(leg.arrTime) }}</div>\n <div class=\"fic__airport-date\">{{ fmtShortDate(leg.arrTime) }}</div>\n </div>\n\n </div>\n </div>\n }\n\n <!-- \u2500\u2500 Passengers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (passengers().length > 0) {\n <div class=\"fic__section\">\n <div class=\"fic__section-label\">\n <i class=\"pi pi-users\"></i> Passengers\n <span class=\"fic__section-count\">{{ passengers().length }}</span>\n </div>\n <div class=\"fic__pax-list\">\n @for (p of passengers(); track p.passengerId) {\n <div class=\"fic__pax\">\n <div class=\"fic__pax-top\">\n <span class=\"fic__pax-badge fic__pax-badge--{{ p.type | lowercase }}\">{{ typeLabel[p.type] ?? p.type }}</span>\n <span class=\"fic__pax-name\">{{ p.name?.prefix }} {{ p.name?.givenName }} {{ p.name?.surName }}</span>\n </div>\n <div class=\"fic__pax-bottom\">\n @if (p.identity?.number) {\n <span class=\"fic__pax-doc\"><i class=\"pi pi-id-card\"></i> {{ p.identity?.number }}</span>\n }\n @if (p.email) {\n <span class=\"fic__pax-email\">{{ p.email }}</span>\n }\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- \u2500\u2500 Payment \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (payment()) {\n <div class=\"fic__payment\">\n <div class=\"fic__payment-main\">\n <i class=\"pi pi-credit-card fic__payment-icon\"></i>\n <span class=\"fic__payment-amount\">{{ payment()?.amount }} {{ payment()?.currency }}</span>\n <span class=\"fic__payment-status\" [class.fic__payment-status--ok]=\"payment()?.status?.key === 'SUCCESS'\">\n <i class=\"pi\" [class.pi-check-circle]=\"payment()?.status?.key === 'SUCCESS'\" [class.pi-clock]=\"payment()?.status?.key !== 'SUCCESS'\"></i>\n {{ payment()?.status?.name }}\n </span>\n </div>\n @if (payment()?.method || payment()?.date) {\n <div class=\"fic__payment-sub\">\n @if (payment()?.method) { <span>{{ payment()?.method }}</span> }\n @if (payment()?.method && payment()?.date) { <span class=\"fic__dot\">\u00B7</span> }\n @if (payment()?.date) { <span>{{ payment()?.date }}</span> }\n </div>\n }\n </div>\n }\n\n\n }\n</div>\n", styles: [".fic{background:#fff;border:1px solid #e2e8f0;border-radius:12px;overflow:hidden;font-family:inherit}.fic__leg{padding:16px 16px 18px;border-bottom:1px solid #e2e8f0}.fic__leg--return{background:#fafbff}.fic__leg-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}.fic__leg-direction{display:flex;align-items:center;gap:6px;font-size:11px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:#1e2e4a}.fic__leg-direction .pi{font-size:10px;color:#475569}.fic__leg-chips{display:flex;gap:5px}.fic__chip{font-size:10.5px;font-weight:600;padding:2px 8px;border-radius:12px;letter-spacing:.02em}.fic__chip--cabin{background:#eff6ff;color:#1d4ed8}.fic__chip--fare{background:#fef9c3;color:#854d0e}.fic__airline{display:flex;align-items:center;gap:5px;font-size:12px;color:#64748b;margin-bottom:14px}.fic__airline .pi{font-size:11px;color:#94a3b8;transform:rotate(45deg)}.fic__route{display:flex;align-items:flex-start;gap:0}.fic__airport{display:flex;flex-direction:column;align-items:flex-start;flex-shrink:0}.fic__airport--right{align-items:flex-end}.fic__airport-code{font-size:26px;font-weight:800;color:#1e2e4a;line-height:1}.fic__airport-time{font-size:13px;font-weight:600;color:#334155;margin-top:3px}.fic__airport-date{font-size:10.5px;color:#94a3b8;margin-top:1px}.fic__timeline{flex:1;display:flex;flex-direction:column;gap:4px;margin:0 4px}.fic__tl-top{display:flex;align-items:flex-end;gap:0}.fic__tl-seg{flex:1;display:flex;flex-direction:column;align-items:center;gap:1px}.fic__tl-flt{font-size:10px;font-weight:700;color:#1e2e4a;background:#f1f5f9;padding:1px 5px;border-radius:4px;white-space:nowrap}.fic__tl-dur{font-size:9.5px;color:#94a3b8;white-space:nowrap}.fic__tl-stop{flex-shrink:0;display:inline-flex;align-items:center;gap:4px;padding:0 8px 1px}.fic__tl-track{display:flex;align-items:center;height:22px}.fic__tl-line{flex:1;height:2px;background:#cbd5e1}.fic__tl-plane{font-size:13px;color:#475569;transform:rotate(45deg);flex-shrink:0;margin-left:-2px}.fic__stop-dot{width:7px;height:7px;border-radius:50%;background:#94a3b8;flex-shrink:0}.fic__stop-code{font-size:11px;font-weight:700;color:#334155}.fic__stop-sep{font-size:11px;color:#cbd5e1}.fic__stop-dur{font-size:11px;font-weight:600;color:#f59e0b}.fic__section{padding:14px 16px;border-bottom:1px solid #e2e8f0}.fic__section-label{display:flex;align-items:center;gap:5px;font-size:10.5px;font-weight:800;letter-spacing:.07em;text-transform:uppercase;color:#64748b;margin-bottom:10px}.fic__section-label .pi{font-size:11px}.fic__section-count{margin-left:auto;background:#f1f5f9;color:#475569;font-size:10px;font-weight:700;padding:1px 6px;border-radius:10px}.fic__pax-list{display:flex;flex-direction:column;gap:8px}.fic__pax{background:#f8fafc;border-radius:8px;padding:8px 10px;display:flex;flex-direction:column;gap:5px}.fic__pax-top{display:flex;align-items:center;gap:7px}.fic__pax-badge{font-size:9.5px;font-weight:700;letter-spacing:.04em;padding:2px 7px;border-radius:10px;flex-shrink:0;text-transform:uppercase}.fic__pax-badge--adt{background:#dbeafe;color:#1d4ed8}.fic__pax-badge--cnn{background:#dcfce7;color:#15803d}.fic__pax-badge--inf{background:#fce7f3;color:#9d174d}.fic__pax-name{font-size:12.5px;font-weight:600;color:#1e2e4a;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.fic__pax-bottom{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.fic__pax-doc{display:inline-flex;align-items:center;gap:3px;font-size:11px;font-family:monospace;color:#475569;background:#f1f5f9;padding:1px 6px;border-radius:4px}.fic__pax-doc .pi{font-size:10px}.fic__pax-email{font-size:11px;color:#94a3b8;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:180px}.fic__payment{padding:12px 16px;background:#f8fafc;display:flex;flex-direction:column;gap:4px}.fic__payment-main{display:flex;align-items:center;gap:8px}.fic__payment-icon{font-size:14px;color:#64748b}.fic__payment-amount{font-size:14px;font-weight:700;color:#1e2e4a}.fic__payment-status{display:flex;align-items:center;gap:4px;font-size:12px;font-weight:600;color:#64748b;margin-left:auto}.fic__payment-status .pi{font-size:12px}.fic__payment-status--ok{color:#16a34a}.fic__payment-sub{display:flex;align-items:center;gap:6px;font-size:11.5px;color:#94a3b8;padding-left:22px}.fic__dot{color:#cbd5e1}.fic__verified-bar{display:flex;align-items:center;padding:8px 12px;background:#f0fdf4;border-bottom:1px solid #bbf7d0}.fic__verified-pill{display:inline-flex;align-items:center;gap:5px;padding:3px 10px 3px 7px;background:#16a34a;color:#fff;font-size:11px;font-weight:700;border-radius:20px;letter-spacing:.02em}.fic__verified-pill .pi{font-size:12px}\n"] }]
|
|
5852
|
+
args: [{ selector: 'app-sbd-flight-itinerary-card', standalone: true, imports: [TagModule, UpperCasePipe, LowerCasePipe], template: "<div class=\"fic\">\n @if (product() === 'flight') {\n\n <!-- \u2500\u2500 Verified pill \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (verified()) {\n <div class=\"fic__verified-bar\">\n <span class=\"fic__verified-pill\">\n <i class=\"pi pi-verified\"></i> Verified with Airlines\n </span>\n </div>\n }\n\n <!-- \u2500\u2500 Legs \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @for (leg of legs(); track leg.direction + $index; let li = $index) {\n <div class=\"fic__leg\" [class.fic__leg--return]=\"leg.direction === 'Return'\">\n\n <!-- Leg header -->\n <div class=\"fic__leg-header\">\n <div class=\"fic__leg-direction\">\n <i class=\"pi\" [class.pi-arrow-right]=\"leg.direction !== 'Return'\" [class.pi-arrow-left]=\"leg.direction === 'Return'\"></i>\n <span>{{ leg.direction }}</span>\n </div>\n <div class=\"fic__leg-chips\">\n @if (leg.cabin) {\n <span class=\"fic__chip fic__chip--cabin\">{{ leg.cabin }}</span>\n }\n @if (leg.fareBrand) {\n <span class=\"fic__chip fic__chip--fare\">{{ leg.fareBrand }}</span>\n }\n </div>\n </div>\n\n <!-- Airline row -->\n @if (leg.airlineName) {\n <div class=\"fic__airline\">\n <i class=\"pi pi-send\"></i>\n <span>{{ leg.airlineName }}</span>\n </div>\n }\n\n <!-- Route timeline -->\n <div class=\"fic__route\">\n\n <!-- Origin -->\n <div class=\"fic__airport\">\n <div class=\"fic__airport-code\">{{ leg.from }}</div>\n <div class=\"fic__airport-time\">{{ fmtTime(leg.depTime) }}</div>\n <div class=\"fic__airport-date\">{{ fmtShortDate(leg.depTime) }}</div>\n </div>\n\n <!-- Segments + stops -->\n <div class=\"fic__timeline\">\n\n <!-- Top row: all labels -->\n <div class=\"fic__tl-top\">\n @for (seg of leg.durationSegments; track seg.DepartureAirportCode; let si = $index) {\n <div class=\"fic__tl-seg\">\n <span class=\"fic__tl-flt\">{{ leg.segments[si]?.AirlineCode }}{{ leg.segments[si]?.FlightNumber }}</span>\n <span class=\"fic__tl-dur\">{{ fmtMins(seg.SegmentElapsedTimeMinutes) }}</span>\n </div>\n @if (si < leg.stops.length) {\n <div class=\"fic__tl-stop\">\n <span class=\"fic__stop-head\">\n <span class=\"fic__stop-dot\"></span>\n <span class=\"fic__stop-code\">{{ leg.stops[si].StopAirport }}</span>\n </span>\n <span class=\"fic__stop-dur\">{{ fmtMins(leg.stops[si].LayoverDuration) }}</span>\n </div>\n }\n }\n </div>\n\n <!-- Bottom row: single continuous line + one arrow -->\n <div class=\"fic__tl-track\">\n <div class=\"fic__tl-line\"></div>\n <i class=\"pi pi-send fic__tl-plane\"></i>\n </div>\n\n </div>\n\n <!-- Destination -->\n <div class=\"fic__airport fic__airport--right\">\n <div class=\"fic__airport-code\">{{ leg.to }}</div>\n <div class=\"fic__airport-time\">{{ fmtTime(leg.arrTime) }}</div>\n <div class=\"fic__airport-date\">{{ fmtShortDate(leg.arrTime) }}</div>\n </div>\n\n </div>\n </div>\n }\n\n <!-- \u2500\u2500 Passengers \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (passengers().length > 0) {\n <div class=\"fic__section\">\n <div class=\"fic__section-label\">\n <i class=\"pi pi-users\"></i> Passengers\n <span class=\"fic__section-count\">{{ passengers().length }}</span>\n </div>\n <div class=\"fic__pax-list\">\n @for (p of passengers(); track p.passengerId) {\n <div class=\"fic__pax\">\n <div class=\"fic__pax-top\">\n <span class=\"fic__pax-badge fic__pax-badge--{{ p.type | lowercase }}\">{{ typeLabel[p.type] ?? p.type }}</span>\n <span class=\"fic__pax-name\">{{ p.name?.prefix }} {{ p.name?.givenName }} {{ p.name?.surName }}</span>\n </div>\n <div class=\"fic__pax-bottom\">\n @if (p.identity?.number) {\n <span class=\"fic__pax-doc\"><i class=\"pi pi-id-card\"></i> {{ p.identity?.number }}</span>\n }\n @if (p.email) {\n <span class=\"fic__pax-email\">{{ p.email }}</span>\n }\n </div>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- \u2500\u2500 Payment \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500 -->\n @if (payment()) {\n <div class=\"fic__payment\">\n <div class=\"fic__payment-main\">\n <i class=\"pi pi-credit-card fic__payment-icon\"></i>\n <span class=\"fic__payment-amount\">{{ payment()?.amount }} {{ payment()?.currency }}</span>\n <span class=\"fic__payment-status\" [class.fic__payment-status--ok]=\"payment()?.status?.key === 'SUCCESS'\">\n <i class=\"pi\" [class.pi-check-circle]=\"payment()?.status?.key === 'SUCCESS'\" [class.pi-clock]=\"payment()?.status?.key !== 'SUCCESS'\"></i>\n {{ payment()?.status?.name }}\n </span>\n </div>\n @if (payment()?.method || payment()?.date) {\n <div class=\"fic__payment-sub\">\n @if (payment()?.method) { <span>{{ payment()?.method }}</span> }\n @if (payment()?.method && payment()?.date) { <span class=\"fic__dot\">\u00B7</span> }\n @if (payment()?.date) { <span>{{ payment()?.date }}</span> }\n </div>\n }\n </div>\n }\n\n\n }\n</div>\n", styles: [".fic{background:#fff;border:1px solid #e2e8f0;border-radius:12px;overflow:hidden;font-family:inherit}.fic__leg{padding:16px 16px 18px;border-bottom:1px solid #e2e8f0}.fic__leg--return{background:#fafbff}.fic__leg-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}.fic__leg-direction{display:flex;align-items:center;gap:6px;font-size:11px;font-weight:800;letter-spacing:.08em;text-transform:uppercase;color:#1e2e4a}.fic__leg-direction .pi{font-size:10px;color:#475569}.fic__leg-chips{display:flex;gap:5px}.fic__chip{font-size:10.5px;font-weight:600;padding:2px 8px;border-radius:12px;letter-spacing:.02em}.fic__chip--cabin{background:#eff6ff;color:#1d4ed8}.fic__chip--fare{background:#fef9c3;color:#854d0e}.fic__airline{display:flex;align-items:center;gap:5px;font-size:12px;color:#64748b;margin-bottom:14px}.fic__airline .pi{font-size:11px;color:#94a3b8;transform:rotate(45deg)}.fic__route{display:flex;align-items:flex-start;gap:0}.fic__airport{display:flex;flex-direction:column;align-items:flex-start;flex-shrink:0}.fic__airport--right{align-items:flex-end}.fic__airport-code{font-size:26px;font-weight:800;color:#1e2e4a;line-height:1}.fic__airport-time{font-size:13px;font-weight:600;color:#334155;margin-top:3px}.fic__airport-date{font-size:10.5px;color:#94a3b8;margin-top:1px}.fic__timeline{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px;margin:0 4px}.fic__tl-top{display:flex;align-items:flex-end;gap:0}.fic__tl-seg{flex:1 1 0;min-width:0;display:flex;flex-direction:column;align-items:center;gap:1px}.fic__tl-flt{font-size:10px;font-weight:700;color:#1e2e4a;background:#f1f5f9;padding:1px 5px;border-radius:4px;white-space:nowrap}.fic__tl-dur{font-size:9.5px;color:#94a3b8;white-space:nowrap}.fic__tl-stop{flex:0 0 auto;display:flex;flex-direction:column;align-items:center;gap:1px;padding:0 6px}.fic__stop-head{display:inline-flex;align-items:center;gap:4px}.fic__tl-track{display:flex;align-items:center;height:22px}.fic__tl-line{flex:1;height:2px;background:#cbd5e1}.fic__tl-plane{font-size:13px;color:#475569;transform:rotate(45deg);flex-shrink:0;margin-left:-2px}.fic__stop-dot{width:7px;height:7px;border-radius:50%;background:#94a3b8;flex-shrink:0}.fic__stop-code{font-size:11px;font-weight:700;color:#334155}.fic__stop-dur{font-size:10.5px;font-weight:600;color:#f59e0b;white-space:nowrap}.fic__section{padding:14px 16px;border-bottom:1px solid #e2e8f0}.fic__section-label{display:flex;align-items:center;gap:5px;font-size:10.5px;font-weight:800;letter-spacing:.07em;text-transform:uppercase;color:#64748b;margin-bottom:10px}.fic__section-label .pi{font-size:11px}.fic__section-count{margin-left:auto;background:#f1f5f9;color:#475569;font-size:10px;font-weight:700;padding:1px 6px;border-radius:10px}.fic__pax-list{display:flex;flex-direction:column;gap:8px}.fic__pax{background:#f8fafc;border-radius:8px;padding:8px 10px;display:flex;flex-direction:column;gap:5px}.fic__pax-top{display:flex;align-items:center;gap:7px}.fic__pax-badge{font-size:9.5px;font-weight:700;letter-spacing:.04em;padding:2px 7px;border-radius:10px;flex-shrink:0;text-transform:uppercase}.fic__pax-badge--adt{background:#dbeafe;color:#1d4ed8}.fic__pax-badge--cnn{background:#dcfce7;color:#15803d}.fic__pax-badge--inf{background:#fce7f3;color:#9d174d}.fic__pax-name{font-size:12.5px;font-weight:600;color:#1e2e4a;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.fic__pax-bottom{display:flex;align-items:center;gap:8px;flex-wrap:wrap}.fic__pax-doc{display:inline-flex;align-items:center;gap:3px;font-size:11px;font-family:monospace;color:#475569;background:#f1f5f9;padding:1px 6px;border-radius:4px}.fic__pax-doc .pi{font-size:10px}.fic__pax-email{font-size:11px;color:#94a3b8;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:180px}.fic__payment{padding:12px 16px;background:#f8fafc;display:flex;flex-direction:column;gap:4px}.fic__payment-main{display:flex;align-items:center;gap:8px}.fic__payment-icon{font-size:14px;color:#64748b}.fic__payment-amount{font-size:14px;font-weight:700;color:#1e2e4a}.fic__payment-status{display:flex;align-items:center;gap:4px;font-size:12px;font-weight:600;color:#64748b;margin-left:auto}.fic__payment-status .pi{font-size:12px}.fic__payment-status--ok{color:#16a34a}.fic__payment-sub{display:flex;align-items:center;gap:6px;font-size:11.5px;color:#94a3b8;padding-left:22px}.fic__dot{color:#cbd5e1}.fic__verified-bar{display:flex;align-items:center;padding:8px 12px;background:#f0fdf4;border-bottom:1px solid #bbf7d0}.fic__verified-pill{display:inline-flex;align-items:center;gap:5px;padding:3px 10px 3px 7px;background:#16a34a;color:#fff;font-size:11px;font-weight:700;border-radius:20px;letter-spacing:.02em}.fic__verified-pill .pi{font-size:12px}\n"] }]
|
|
5853
|
+
}] });
|
|
5854
|
+
|
|
5855
|
+
/** Icon and subtitle of each section card. Keys may carry an index (journey_0, fare_1): the base key covers them all. */
|
|
5856
|
+
const SECTION_META = {
|
|
5857
|
+
journey: { icon: 'pi-arrow-right', sub: 'Operator · Stations · Times' },
|
|
5858
|
+
pnr: { icon: 'pi-tag', sub: 'PNR · Booking ref' },
|
|
5859
|
+
seat: { icon: 'pi-ticket', sub: 'Coach · Seat · Class' },
|
|
5860
|
+
fare: { icon: 'pi-list', sub: 'Fare rules · Conditions' },
|
|
5861
|
+
refund: { icon: 'pi-undo', sub: 'Refund · Penalty' },
|
|
5862
|
+
payment: { icon: 'pi-credit-card', sub: 'Amount · Taxes' },
|
|
5863
|
+
};
|
|
5864
|
+
/** Train booking details (read only): journey summary, passengers, payment and the bilingual sections to copy. */
|
|
5865
|
+
class SbdTrainDetailsComponent {
|
|
5866
|
+
constructor() {
|
|
5867
|
+
this.detail = input.required();
|
|
5868
|
+
this.bookingId = input.required();
|
|
5869
|
+
/** Same as Helix for a train booking: read only, only the non-mutating "coming soon" actions. */
|
|
5870
|
+
this.quickActions = [
|
|
5871
|
+
{ icon: 'pi-send', label: 'Send Ticket' },
|
|
5872
|
+
{ icon: 'pi-plus-circle', label: 'Add Service' },
|
|
5873
|
+
];
|
|
5874
|
+
this.picked = signal('');
|
|
5875
|
+
this.copied = signal(false);
|
|
5876
|
+
this.summary = computed(() => this.detail().summary);
|
|
5877
|
+
this.sections = computed(() => this.detail().sections ?? []);
|
|
5878
|
+
this.current = computed(() => this.sections().find((s) => s.key === this.picked()) ?? this.sections()[0]);
|
|
5879
|
+
}
|
|
5880
|
+
select(key) {
|
|
5881
|
+
this.picked.set(key);
|
|
5882
|
+
}
|
|
5883
|
+
meta(key) {
|
|
5884
|
+
return SECTION_META[key] ?? SECTION_META[key.replace(/_\d+$/, '')] ?? { icon: 'pi-info-circle', sub: '' };
|
|
5885
|
+
}
|
|
5886
|
+
isReturn(leg) {
|
|
5887
|
+
return /return/i.test(leg.direction || '');
|
|
5888
|
+
}
|
|
5889
|
+
format(section, lang) {
|
|
5890
|
+
const lines = [`*${lang === 'ar' ? section.titleAr : section.title}*`];
|
|
5891
|
+
for (const r of section.rows) {
|
|
5892
|
+
const label = lang === 'ar' ? r.labelAr : r.label;
|
|
5893
|
+
const value = (lang === 'ar' ? r.ar : r.en) || '';
|
|
5894
|
+
if (value.includes('\n'))
|
|
5895
|
+
lines.push(`${label}:`, ...value.split('\n').map((l) => ` ${l}`));
|
|
5896
|
+
else
|
|
5897
|
+
lines.push(`${label}: ${value}`);
|
|
5898
|
+
}
|
|
5899
|
+
return lines.join('\n');
|
|
5900
|
+
}
|
|
5901
|
+
copy(mode) {
|
|
5902
|
+
const s = this.current();
|
|
5903
|
+
if (!s)
|
|
5904
|
+
return;
|
|
5905
|
+
const text = mode === 'both' ? `${this.format(s, 'en')}\n\n${this.format(s, 'ar')}` : this.format(s, mode);
|
|
5906
|
+
const done = () => {
|
|
5907
|
+
this.copied.set(true);
|
|
5908
|
+
setTimeout(() => this.copied.set(false), 1600);
|
|
5909
|
+
};
|
|
5910
|
+
if (navigator.clipboard?.writeText) {
|
|
5911
|
+
navigator.clipboard.writeText(text).then(done, () => this.fallbackCopy(text, done));
|
|
5912
|
+
}
|
|
5913
|
+
else {
|
|
5914
|
+
this.fallbackCopy(text, done);
|
|
5915
|
+
}
|
|
5916
|
+
}
|
|
5917
|
+
fallbackCopy(text, done) {
|
|
5918
|
+
const ta = document.createElement('textarea');
|
|
5919
|
+
ta.value = text;
|
|
5920
|
+
ta.style.position = 'fixed';
|
|
5921
|
+
ta.style.opacity = '0';
|
|
5922
|
+
document.body.appendChild(ta);
|
|
5923
|
+
ta.select();
|
|
5924
|
+
try {
|
|
5925
|
+
document.execCommand('copy');
|
|
5926
|
+
done();
|
|
5927
|
+
}
|
|
5928
|
+
catch {
|
|
5929
|
+
/* ignore: the browser blocked the copy */
|
|
5930
|
+
}
|
|
5931
|
+
document.body.removeChild(ta);
|
|
5932
|
+
}
|
|
5933
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SbdTrainDetailsComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
5934
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SbdTrainDetailsComponent, isStandalone: true, selector: "app-sbd-train-details", inputs: { detail: { classPropertyName: "detail", publicName: "detail", isSignal: true, isRequired: true, transformFunction: null }, bookingId: { classPropertyName: "bookingId", publicName: "bookingId", isSignal: true, isRequired: true, transformFunction: null } }, ngImport: i0, template: "<div class=\"std\">\n <div class=\"std__head\">\n <span class=\"std__ico\"><i class=\"pi pi-bookmark\"></i></span>\n <div>\n <h3 class=\"std__title\">Booking details</h3>\n <div class=\"std__sub\">\n <b>{{ bookingId() }}</b>\n @if (detail().headline) { <span>\u00B7 {{ detail().headline }}</span> }\n </div>\n </div>\n </div>\n\n @if (!detail().configured) {\n <div class=\"std__state std__state--warn\">Train booking details are not available on this server.</div>\n } @else if (!sections().length && !summary()) {\n <div class=\"std__state std__state--warn\">No details found for this train booking.</div>\n } @else {\n <div class=\"std__grid\">\n\n <!-- Left: journey, passengers, payment -->\n <aside class=\"std__rail\">\n @if (summary()?.verified) {\n <div class=\"std__verified\"><i class=\"pi pi-check-circle\"></i> Verified with the operator</div>\n }\n\n @for (t of summary()?.trainLegs ?? []; track $index) {\n <div class=\"std__leg\">\n <div class=\"std__leg-top\">\n <span class=\"std__dir\">\n <i class=\"pi\" [ngClass]=\"isReturn(t) ? 'pi-arrow-left' : 'pi-arrow-right'\"></i>\n {{ t.direction || (isReturn(t) ? 'Return' : 'Onward') }}\n </span>\n <span class=\"std__badges\">\n @if (t.fareClass) { <span class=\"std__badge std__badge--fare\">{{ t.fareClass }}</span> }\n @if (t.status) { <span class=\"std__badge\">{{ t.status }}</span> }\n </span>\n </div>\n @if (t.operator || t.trainNumber) {\n <div class=\"std__operator\">{{ t.operator }}@if (t.trainNumber) { <span> \u00B7 {{ t.trainNumber }}</span> }</div>\n }\n <div class=\"std__itin\">\n <div class=\"std__stop\">\n <div class=\"std__node\"></div>\n <div class=\"std__city\">{{ t.fromCity || t.fromStation }}</div>\n @if (t.fromCity && t.fromStation) { <div class=\"std__station\">{{ t.fromStation }}</div> }\n <div class=\"std__time\">{{ t.depTime }}</div>\n <div class=\"std__date\">{{ t.depDate }}</div>\n </div>\n <div class=\"std__seg\">\n <div class=\"std__bar\"><i class=\"pi pi-arrow-right\"></i></div>\n @if (t.duration) { <span class=\"std__dur\">{{ t.duration }}</span> }\n </div>\n <div class=\"std__stop std__stop--end\">\n <div class=\"std__node\"></div>\n <div class=\"std__city\">{{ t.toCity || t.toStation }}</div>\n @if (t.toCity && t.toStation) { <div class=\"std__station\">{{ t.toStation }}</div> }\n <div class=\"std__time\">{{ t.arrTime }}</div>\n <div class=\"std__date\">{{ t.arrDate }}</div>\n </div>\n </div>\n </div>\n }\n\n @if ((summary()?.passengers ?? []).length) {\n <div class=\"std__box\">\n <div class=\"std__box-h\"><i class=\"pi pi-users\"></i> Passengers <span class=\"std__n\">{{ summary()?.passengers?.length }}</span></div>\n @for (p of summary()?.passengers ?? []; track $index) {\n <div class=\"std__pax\">\n <span class=\"std__ptag\">{{ p.typeLabel }}</span>\n <div class=\"std__pinfo\">\n <div class=\"std__pname\">{{ p.name }}</div>\n <div class=\"std__pdoc\">\n {{ p.doc }}@if (p.email) { <span>{{ p.doc ? ' \u00B7 ' : '' }}{{ p.email }}</span> }\n </div>\n </div>\n </div>\n }\n </div>\n }\n\n @if (summary()?.payment; as pay) {\n <div class=\"std__pay\">\n <div class=\"std__pay-l\">\n <i class=\"pi pi-credit-card\"></i>\n <div>\n <div class=\"std__amt\">{{ pay.amount }} {{ pay.currency }}</div>\n <div class=\"std__pmeta\">{{ pay.method }}@if (pay.date) { <span> \u00B7 {{ pay.date }}</span> }</div>\n </div>\n </div>\n @if (pay.status) { <span class=\"std__pok\"><i class=\"pi pi-check-circle\"></i> {{ pay.status }}</span> }\n </div>\n }\n </aside>\n\n <!-- Right: section cards and the selected section -->\n <section class=\"std__main\">\n <div class=\"std__qa\">\n <div class=\"std__qa-h\">Quick actions</div>\n <div class=\"std__qa-row\">\n @for (a of quickActions; track a.label) {\n <button type=\"button\" class=\"std__qa-btn\" disabled title=\"Coming soon\">\n <i class=\"pi\" [ngClass]=\"a.icon\"></i> {{ a.label }}\n </button>\n }\n </div>\n </div>\n\n <div class=\"std__main-h\">Booking sections</div>\n <div class=\"std__cards\">\n @for (s of sections(); track s.key) {\n <button type=\"button\" class=\"std__card\" [class.std__card--on]=\"current()?.key === s.key\" (click)=\"select(s.key)\">\n <span class=\"std__card-ico\"><i class=\"pi\" [ngClass]=\"meta(s.key).icon\"></i></span>\n <span class=\"std__card-t\">{{ s.title }}</span>\n <span class=\"std__card-s\">{{ meta(s.key).sub }}</span>\n </button>\n }\n </div>\n\n @if (current(); as cur) {\n <div class=\"std__panel\">\n <div class=\"std__panel-h\">\n <i class=\"pi\" [ngClass]=\"meta(cur.key).icon\"></i> {{ cur.title }}\n <small dir=\"rtl\">{{ cur.titleAr }}</small>\n </div>\n <div class=\"std__rows\">\n @for (r of cur.rows; track $index) {\n <div class=\"std__row\">\n <div class=\"std__label\">{{ r.label }}<small dir=\"rtl\">{{ r.labelAr }}</small></div>\n <div class=\"std__val\">\n <div class=\"std__en\">{{ r.en }}</div>\n @if (r.ar && r.ar !== r.en) { <div class=\"std__ar\" dir=\"rtl\">{{ r.ar }}</div> }\n </div>\n </div>\n }\n </div>\n <div class=\"std__copybar\">\n @if (copied()) {\n <span class=\"std__copied\"><i class=\"pi pi-check\"></i> Copied</span>\n } @else {\n <span class=\"std__hint\">Copy this section to paste in the chat</span>\n }\n <span class=\"std__spacer\"></span>\n <button type=\"button\" class=\"std__btn\" (click)=\"copy('en')\"><i class=\"pi pi-copy\"></i> EN</button>\n <button type=\"button\" class=\"std__btn\" (click)=\"copy('ar')\"><i class=\"pi pi-copy\"></i> AR</button>\n <button type=\"button\" class=\"std__btn std__btn--primary\" (click)=\"copy('both')\"><i class=\"pi pi-copy\"></i> Both</button>\n </div>\n </div>\n }\n </section>\n </div>\n }\n</div>\n", styles: [".std{background:var(--sbd-r-surface, #fff);border:1px solid var(--sbd-r-line, #e2e8f0);border-radius:12px;overflow:hidden;font-family:inherit;color:var(--sbd-r-ink, #1e2e4a)}.std__head{display:flex;align-items:center;gap:12px;padding:16px 20px;border-bottom:1px solid var(--sbd-r-line, #e2e8f0)}.std__ico{width:38px;height:38px;border-radius:10px;background:var(--std-accent-soft, #eff6ff);color:#007ad9;display:grid;place-items:center;flex:none}.std__title{margin:0;font-size:16px;font-weight:700}.std__sub{color:var(--sbd-r-muted, #64748b);font-size:12.5px;display:flex;gap:6px}.std__sub b{color:var(--sbd-r-ink, #1e2e4a)}.std__state{padding:40px;text-align:center;color:var(--sbd-r-muted, #64748b);font-size:14px}.std__state--warn{color:var(--sbd-r-warn-text, #b26a00)}.std__grid{display:grid;grid-template-columns:342px minmax(0,1fr)}.std__rail{border-right:1px solid var(--sbd-r-line, #e2e8f0);background:var(--sbd-r-soft, #f8fafc);padding:16px}.std__main{padding:18px 20px;min-width:0}.std__verified{display:inline-flex;align-items:center;gap:8px;margin-bottom:14px;padding:8px 14px;border-radius:10px;background:var(--sbd-r-success-bg, #e7f7ec);color:var(--sbd-r-success-text, #1a7f37);border:1px solid var(--sbd-r-success-line, #b7e6c4);font-weight:700;font-size:12.5px}.std__leg{background:var(--sbd-r-surface, #fff);border:1px solid var(--sbd-r-line, #e2e8f0);border-radius:14px;padding:14px;margin-bottom:12px}.std__leg-top{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}.std__dir{font-size:11.5px;font-weight:800;letter-spacing:.5px;text-transform:uppercase;display:inline-flex;align-items:center;gap:6px}.std__badges{display:flex;gap:5px}.std__badge{font-size:10.5px;font-weight:700;padding:3px 8px;border-radius:999px;background:var(--std-accent-soft, #eff6ff);color:#007ad9}.std__badge--fare{background:var(--sbd-r-warn-bg, #fff3d6);color:var(--sbd-r-warn-text, #a56a00)}.std__operator{font-size:12.5px;color:var(--sbd-r-muted, #64748b);margin-bottom:12px}.std__itin{display:flex;align-items:flex-start}.std__stop{display:flex;flex-direction:column;flex:none;align-items:flex-start}.std__stop--end{align-items:flex-end;text-align:right}.std__node{width:10px;height:10px;border-radius:50%;background:#007ad9;margin-bottom:8px}.std__city{font-size:15px;font-weight:800;line-height:1.15;max-width:130px}.std__station{font-size:10.5px;color:var(--sbd-r-faint, #94a3b8);margin-top:2px;line-height:1.2;max-width:130px}.std__time{font-size:13.5px;font-weight:700;margin-top:4px}.std__date{font-size:11px;color:var(--sbd-r-faint, #94a3b8);margin-top:1px}.std__seg{flex:1;min-width:26px;display:flex;flex-direction:column;align-items:center}.std__bar{position:relative;width:100%;height:2px;background:var(--sbd-r-line, #e2e8f0);margin-top:4px}.std__bar .pi{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:9px;color:#007ad9;background:var(--sbd-r-surface, #fff);padding:0 3px}.std__dur{font-size:9.5px;font-weight:700;background:var(--sbd-r-soft, #f8fafc);border:1px solid var(--sbd-r-line, #e2e8f0);color:var(--sbd-r-muted, #64748b);padding:1px 6px;border-radius:6px;margin-top:7px;white-space:nowrap}.std__box{background:var(--sbd-r-surface, #fff);border:1px solid var(--sbd-r-line, #e2e8f0);border-radius:14px;padding:12px 14px;margin-bottom:12px}.std__box-h{font-size:11.5px;font-weight:800;letter-spacing:.4px;text-transform:uppercase;color:var(--sbd-r-muted, #64748b);display:flex;align-items:center;gap:7px;margin-bottom:10px}.std__n{margin-left:auto;background:var(--sbd-r-sunk, #f1f5f9);color:var(--sbd-r-muted, #64748b);border-radius:999px;padding:1px 8px;font-size:11px}.std__pax{display:flex;align-items:center;gap:10px;padding:7px 0;border-top:1px dashed var(--sbd-r-line, #e2e8f0)}.std__pax:first-of-type{border-top:none}.std__ptag{flex:none;font-size:10px;font-weight:800;text-transform:uppercase;padding:3px 8px;border-radius:6px;background:var(--std-accent-soft, #eff6ff);color:#007ad9}.std__pinfo{min-width:0}.std__pname{font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.std__pdoc{font-size:11px;color:var(--sbd-r-faint, #94a3b8);word-break:break-all}.std__pay{display:flex;align-items:center;justify-content:space-between;gap:8px;background:var(--sbd-r-surface, #fff);border:1px solid var(--sbd-r-line, #e2e8f0);border-radius:14px;padding:12px 14px}.std__pay-l{display:flex;gap:10px;align-items:center}.std__pay-l>.pi{color:#007ad9;font-size:15px}.std__amt{font-size:15px;font-weight:800}.std__pmeta{font-size:11px;color:var(--sbd-r-faint, #94a3b8)}.std__pok{flex:none;font-size:11.5px;font-weight:700;color:var(--sbd-r-success-text, #1a7f37);display:inline-flex;align-items:center;gap:5px}.std__main-h{font-size:15px;font-weight:700;margin-bottom:12px}.std__cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px;margin-bottom:16px}.std__card{text-align:left;border:1.5px solid var(--sbd-r-line, #e2e8f0);background:var(--sbd-r-surface, #fff);border-radius:13px;padding:12px;cursor:pointer;display:flex;flex-direction:column;gap:3px;font-family:inherit;transition:border-color .12s,box-shadow .12s}.std__card:hover{border-color:var(--std-hover-line, #bfdbfe)}.std__card--on{border-color:#007ad9;box-shadow:0 0 0 3px var(--std-accent-soft, #eff6ff)}.std__card-ico{width:30px;height:30px;border-radius:8px;background:var(--sbd-r-sunk, #f1f5f9);color:var(--sbd-r-muted, #64748b);display:grid;place-items:center;margin-bottom:5px}.std__card--on .std__card-ico{background:var(--std-accent-soft, #eff6ff);color:#007ad9}.std__card-t{font-size:13px;font-weight:700}.std__card--on .std__card-t{color:#007ad9}.std__card-s{font-size:11px;color:var(--sbd-r-faint, #94a3b8)}.std__panel{border:1px solid var(--sbd-r-line, #e2e8f0);border-radius:14px;overflow:hidden}.std__panel-h{padding:12px 16px;border-bottom:1px solid var(--sbd-r-line, #e2e8f0);font-size:13.5px;font-weight:700;background:var(--sbd-r-soft, #f8fafc);display:flex;align-items:center;gap:8px}.std__panel-h .pi{color:#007ad9}.std__panel-h small{font-weight:500;color:var(--sbd-r-faint, #94a3b8)}.std__rows{padding:4px 16px;max-height:40vh;overflow-y:auto}.std__row{display:grid;grid-template-columns:160px 1fr;gap:12px;padding:9px 0;border-bottom:1px dashed var(--sbd-r-line, #e2e8f0)}.std__row:last-child{border-bottom:none}.std__label{font-size:12.5px;font-weight:600;color:var(--sbd-r-muted, #64748b);display:flex;flex-direction:column;gap:2px}.std__label small{font-weight:500;color:var(--sbd-r-faint, #94a3b8)}.std__val{font-size:13.5px;min-width:0}.std__en{white-space:pre-line;word-break:break-word}.std__ar{white-space:pre-line;word-break:break-word;color:var(--sbd-r-muted, #64748b);margin-top:3px}.std__copybar{display:flex;align-items:center;gap:10px;padding:12px 16px;border-top:1px solid var(--sbd-r-line, #e2e8f0);background:var(--sbd-r-soft, #f8fafc)}.std__hint{font-size:12px;color:var(--sbd-r-faint, #94a3b8)}.std__copied{color:var(--sbd-r-success-text, #1a7f37);font-size:12.5px;font-weight:700}.std__spacer{flex:1}.std__btn{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--sbd-r-line, #e2e8f0);background:var(--sbd-r-surface, #fff);color:var(--sbd-r-ink, #1e2e4a);border-radius:9px;padding:8px 13px;font-size:12.5px;font-weight:600;cursor:pointer;font-family:inherit}.std__btn--primary{background:#007ad9;border-color:#007ad9;color:#fff}@media (max-width: 820px){.std__grid{grid-template-columns:minmax(0,1fr)}.std__rail{border-right:none;border-bottom:1px solid var(--sbd-r-line, #e2e8f0)}}.std__qa{margin-bottom:18px}.std__qa-h{font-size:11.5px;font-weight:800;letter-spacing:.5px;text-transform:uppercase;color:var(--sbd-r-muted, #64748b);margin-bottom:10px}.std__qa-row{display:flex;flex-wrap:wrap;gap:8px}.std__qa-btn{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--sbd-r-line, #e2e8f0);background:var(--sbd-r-surface, #fff);color:var(--sbd-r-muted, #64748b);border-radius:9px;padding:8px 13px;font-size:12.5px;font-weight:600;font-family:inherit;cursor:not-allowed;opacity:.6}:host-context(.dark) .std,:host-context([data-theme=dark]) .std{--sbd-r-bg: #18181b;--sbd-r-surface: #1f1f23;--sbd-r-soft: #27272a;--sbd-r-sunk: #2f2f34;--sbd-r-ink: #f4f4f5;--sbd-r-muted: #a1a1aa;--sbd-r-faint: #8b8b94;--sbd-r-line: #3f3f46;--sbd-r-line-strong: #52525b;--sbd-r-label: #d4d4d8;--sbd-r-input-text: #e4e4e7;--sbd-r-info-bg: #172554;--sbd-r-info-line: #1e3a8a;--sbd-r-info-text: #93c5fd;--sbd-r-warn-bg: #3a2a0e;--sbd-r-warn-line: #6b4a16;--sbd-r-warn-text: #fcd34d;--sbd-r-warn-icon: #f59e0b;--sbd-r-error-bg: #3a1517;--sbd-r-error-line: #7f1d1d;--sbd-r-error-text: #fca5a5;--sbd-r-success-bg: #0f2a1a;--sbd-r-success-line: #166534;--sbd-r-success-text: #86efac;--sbd-r-state-bg: #3a2410;--sbd-r-state-line: #7c3a10;--sbd-r-state-warn-bg: #3a1517;--sbd-r-state-warn-line: #7f1d1d;--sbd-r-green: #4ade80;--sbd-r-expiry-soon: #fbbf24;--sbd-r-accent-soft: color-mix(in srgb, var(--sbd-accent, #6d4aff) 28%, transparent);--std-accent-soft: #1e2a52;--std-hover-line: #3b5ea8}\n"], dependencies: [{ kind: "directive", type: NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }] }); }
|
|
5935
|
+
}
|
|
5936
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SbdTrainDetailsComponent, decorators: [{
|
|
5937
|
+
type: Component,
|
|
5938
|
+
args: [{ selector: 'app-sbd-train-details', standalone: true, imports: [NgClass], template: "<div class=\"std\">\n <div class=\"std__head\">\n <span class=\"std__ico\"><i class=\"pi pi-bookmark\"></i></span>\n <div>\n <h3 class=\"std__title\">Booking details</h3>\n <div class=\"std__sub\">\n <b>{{ bookingId() }}</b>\n @if (detail().headline) { <span>\u00B7 {{ detail().headline }}</span> }\n </div>\n </div>\n </div>\n\n @if (!detail().configured) {\n <div class=\"std__state std__state--warn\">Train booking details are not available on this server.</div>\n } @else if (!sections().length && !summary()) {\n <div class=\"std__state std__state--warn\">No details found for this train booking.</div>\n } @else {\n <div class=\"std__grid\">\n\n <!-- Left: journey, passengers, payment -->\n <aside class=\"std__rail\">\n @if (summary()?.verified) {\n <div class=\"std__verified\"><i class=\"pi pi-check-circle\"></i> Verified with the operator</div>\n }\n\n @for (t of summary()?.trainLegs ?? []; track $index) {\n <div class=\"std__leg\">\n <div class=\"std__leg-top\">\n <span class=\"std__dir\">\n <i class=\"pi\" [ngClass]=\"isReturn(t) ? 'pi-arrow-left' : 'pi-arrow-right'\"></i>\n {{ t.direction || (isReturn(t) ? 'Return' : 'Onward') }}\n </span>\n <span class=\"std__badges\">\n @if (t.fareClass) { <span class=\"std__badge std__badge--fare\">{{ t.fareClass }}</span> }\n @if (t.status) { <span class=\"std__badge\">{{ t.status }}</span> }\n </span>\n </div>\n @if (t.operator || t.trainNumber) {\n <div class=\"std__operator\">{{ t.operator }}@if (t.trainNumber) { <span> \u00B7 {{ t.trainNumber }}</span> }</div>\n }\n <div class=\"std__itin\">\n <div class=\"std__stop\">\n <div class=\"std__node\"></div>\n <div class=\"std__city\">{{ t.fromCity || t.fromStation }}</div>\n @if (t.fromCity && t.fromStation) { <div class=\"std__station\">{{ t.fromStation }}</div> }\n <div class=\"std__time\">{{ t.depTime }}</div>\n <div class=\"std__date\">{{ t.depDate }}</div>\n </div>\n <div class=\"std__seg\">\n <div class=\"std__bar\"><i class=\"pi pi-arrow-right\"></i></div>\n @if (t.duration) { <span class=\"std__dur\">{{ t.duration }}</span> }\n </div>\n <div class=\"std__stop std__stop--end\">\n <div class=\"std__node\"></div>\n <div class=\"std__city\">{{ t.toCity || t.toStation }}</div>\n @if (t.toCity && t.toStation) { <div class=\"std__station\">{{ t.toStation }}</div> }\n <div class=\"std__time\">{{ t.arrTime }}</div>\n <div class=\"std__date\">{{ t.arrDate }}</div>\n </div>\n </div>\n </div>\n }\n\n @if ((summary()?.passengers ?? []).length) {\n <div class=\"std__box\">\n <div class=\"std__box-h\"><i class=\"pi pi-users\"></i> Passengers <span class=\"std__n\">{{ summary()?.passengers?.length }}</span></div>\n @for (p of summary()?.passengers ?? []; track $index) {\n <div class=\"std__pax\">\n <span class=\"std__ptag\">{{ p.typeLabel }}</span>\n <div class=\"std__pinfo\">\n <div class=\"std__pname\">{{ p.name }}</div>\n <div class=\"std__pdoc\">\n {{ p.doc }}@if (p.email) { <span>{{ p.doc ? ' \u00B7 ' : '' }}{{ p.email }}</span> }\n </div>\n </div>\n </div>\n }\n </div>\n }\n\n @if (summary()?.payment; as pay) {\n <div class=\"std__pay\">\n <div class=\"std__pay-l\">\n <i class=\"pi pi-credit-card\"></i>\n <div>\n <div class=\"std__amt\">{{ pay.amount }} {{ pay.currency }}</div>\n <div class=\"std__pmeta\">{{ pay.method }}@if (pay.date) { <span> \u00B7 {{ pay.date }}</span> }</div>\n </div>\n </div>\n @if (pay.status) { <span class=\"std__pok\"><i class=\"pi pi-check-circle\"></i> {{ pay.status }}</span> }\n </div>\n }\n </aside>\n\n <!-- Right: section cards and the selected section -->\n <section class=\"std__main\">\n <div class=\"std__qa\">\n <div class=\"std__qa-h\">Quick actions</div>\n <div class=\"std__qa-row\">\n @for (a of quickActions; track a.label) {\n <button type=\"button\" class=\"std__qa-btn\" disabled title=\"Coming soon\">\n <i class=\"pi\" [ngClass]=\"a.icon\"></i> {{ a.label }}\n </button>\n }\n </div>\n </div>\n\n <div class=\"std__main-h\">Booking sections</div>\n <div class=\"std__cards\">\n @for (s of sections(); track s.key) {\n <button type=\"button\" class=\"std__card\" [class.std__card--on]=\"current()?.key === s.key\" (click)=\"select(s.key)\">\n <span class=\"std__card-ico\"><i class=\"pi\" [ngClass]=\"meta(s.key).icon\"></i></span>\n <span class=\"std__card-t\">{{ s.title }}</span>\n <span class=\"std__card-s\">{{ meta(s.key).sub }}</span>\n </button>\n }\n </div>\n\n @if (current(); as cur) {\n <div class=\"std__panel\">\n <div class=\"std__panel-h\">\n <i class=\"pi\" [ngClass]=\"meta(cur.key).icon\"></i> {{ cur.title }}\n <small dir=\"rtl\">{{ cur.titleAr }}</small>\n </div>\n <div class=\"std__rows\">\n @for (r of cur.rows; track $index) {\n <div class=\"std__row\">\n <div class=\"std__label\">{{ r.label }}<small dir=\"rtl\">{{ r.labelAr }}</small></div>\n <div class=\"std__val\">\n <div class=\"std__en\">{{ r.en }}</div>\n @if (r.ar && r.ar !== r.en) { <div class=\"std__ar\" dir=\"rtl\">{{ r.ar }}</div> }\n </div>\n </div>\n }\n </div>\n <div class=\"std__copybar\">\n @if (copied()) {\n <span class=\"std__copied\"><i class=\"pi pi-check\"></i> Copied</span>\n } @else {\n <span class=\"std__hint\">Copy this section to paste in the chat</span>\n }\n <span class=\"std__spacer\"></span>\n <button type=\"button\" class=\"std__btn\" (click)=\"copy('en')\"><i class=\"pi pi-copy\"></i> EN</button>\n <button type=\"button\" class=\"std__btn\" (click)=\"copy('ar')\"><i class=\"pi pi-copy\"></i> AR</button>\n <button type=\"button\" class=\"std__btn std__btn--primary\" (click)=\"copy('both')\"><i class=\"pi pi-copy\"></i> Both</button>\n </div>\n </div>\n }\n </section>\n </div>\n }\n</div>\n", styles: [".std{background:var(--sbd-r-surface, #fff);border:1px solid var(--sbd-r-line, #e2e8f0);border-radius:12px;overflow:hidden;font-family:inherit;color:var(--sbd-r-ink, #1e2e4a)}.std__head{display:flex;align-items:center;gap:12px;padding:16px 20px;border-bottom:1px solid var(--sbd-r-line, #e2e8f0)}.std__ico{width:38px;height:38px;border-radius:10px;background:var(--std-accent-soft, #eff6ff);color:#007ad9;display:grid;place-items:center;flex:none}.std__title{margin:0;font-size:16px;font-weight:700}.std__sub{color:var(--sbd-r-muted, #64748b);font-size:12.5px;display:flex;gap:6px}.std__sub b{color:var(--sbd-r-ink, #1e2e4a)}.std__state{padding:40px;text-align:center;color:var(--sbd-r-muted, #64748b);font-size:14px}.std__state--warn{color:var(--sbd-r-warn-text, #b26a00)}.std__grid{display:grid;grid-template-columns:342px minmax(0,1fr)}.std__rail{border-right:1px solid var(--sbd-r-line, #e2e8f0);background:var(--sbd-r-soft, #f8fafc);padding:16px}.std__main{padding:18px 20px;min-width:0}.std__verified{display:inline-flex;align-items:center;gap:8px;margin-bottom:14px;padding:8px 14px;border-radius:10px;background:var(--sbd-r-success-bg, #e7f7ec);color:var(--sbd-r-success-text, #1a7f37);border:1px solid var(--sbd-r-success-line, #b7e6c4);font-weight:700;font-size:12.5px}.std__leg{background:var(--sbd-r-surface, #fff);border:1px solid var(--sbd-r-line, #e2e8f0);border-radius:14px;padding:14px;margin-bottom:12px}.std__leg-top{display:flex;align-items:center;justify-content:space-between;margin-bottom:8px}.std__dir{font-size:11.5px;font-weight:800;letter-spacing:.5px;text-transform:uppercase;display:inline-flex;align-items:center;gap:6px}.std__badges{display:flex;gap:5px}.std__badge{font-size:10.5px;font-weight:700;padding:3px 8px;border-radius:999px;background:var(--std-accent-soft, #eff6ff);color:#007ad9}.std__badge--fare{background:var(--sbd-r-warn-bg, #fff3d6);color:var(--sbd-r-warn-text, #a56a00)}.std__operator{font-size:12.5px;color:var(--sbd-r-muted, #64748b);margin-bottom:12px}.std__itin{display:flex;align-items:flex-start}.std__stop{display:flex;flex-direction:column;flex:none;align-items:flex-start}.std__stop--end{align-items:flex-end;text-align:right}.std__node{width:10px;height:10px;border-radius:50%;background:#007ad9;margin-bottom:8px}.std__city{font-size:15px;font-weight:800;line-height:1.15;max-width:130px}.std__station{font-size:10.5px;color:var(--sbd-r-faint, #94a3b8);margin-top:2px;line-height:1.2;max-width:130px}.std__time{font-size:13.5px;font-weight:700;margin-top:4px}.std__date{font-size:11px;color:var(--sbd-r-faint, #94a3b8);margin-top:1px}.std__seg{flex:1;min-width:26px;display:flex;flex-direction:column;align-items:center}.std__bar{position:relative;width:100%;height:2px;background:var(--sbd-r-line, #e2e8f0);margin-top:4px}.std__bar .pi{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);font-size:9px;color:#007ad9;background:var(--sbd-r-surface, #fff);padding:0 3px}.std__dur{font-size:9.5px;font-weight:700;background:var(--sbd-r-soft, #f8fafc);border:1px solid var(--sbd-r-line, #e2e8f0);color:var(--sbd-r-muted, #64748b);padding:1px 6px;border-radius:6px;margin-top:7px;white-space:nowrap}.std__box{background:var(--sbd-r-surface, #fff);border:1px solid var(--sbd-r-line, #e2e8f0);border-radius:14px;padding:12px 14px;margin-bottom:12px}.std__box-h{font-size:11.5px;font-weight:800;letter-spacing:.4px;text-transform:uppercase;color:var(--sbd-r-muted, #64748b);display:flex;align-items:center;gap:7px;margin-bottom:10px}.std__n{margin-left:auto;background:var(--sbd-r-sunk, #f1f5f9);color:var(--sbd-r-muted, #64748b);border-radius:999px;padding:1px 8px;font-size:11px}.std__pax{display:flex;align-items:center;gap:10px;padding:7px 0;border-top:1px dashed var(--sbd-r-line, #e2e8f0)}.std__pax:first-of-type{border-top:none}.std__ptag{flex:none;font-size:10px;font-weight:800;text-transform:uppercase;padding:3px 8px;border-radius:6px;background:var(--std-accent-soft, #eff6ff);color:#007ad9}.std__pinfo{min-width:0}.std__pname{font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.std__pdoc{font-size:11px;color:var(--sbd-r-faint, #94a3b8);word-break:break-all}.std__pay{display:flex;align-items:center;justify-content:space-between;gap:8px;background:var(--sbd-r-surface, #fff);border:1px solid var(--sbd-r-line, #e2e8f0);border-radius:14px;padding:12px 14px}.std__pay-l{display:flex;gap:10px;align-items:center}.std__pay-l>.pi{color:#007ad9;font-size:15px}.std__amt{font-size:15px;font-weight:800}.std__pmeta{font-size:11px;color:var(--sbd-r-faint, #94a3b8)}.std__pok{flex:none;font-size:11.5px;font-weight:700;color:var(--sbd-r-success-text, #1a7f37);display:inline-flex;align-items:center;gap:5px}.std__main-h{font-size:15px;font-weight:700;margin-bottom:12px}.std__cards{display:grid;grid-template-columns:repeat(auto-fill,minmax(150px,1fr));gap:10px;margin-bottom:16px}.std__card{text-align:left;border:1.5px solid var(--sbd-r-line, #e2e8f0);background:var(--sbd-r-surface, #fff);border-radius:13px;padding:12px;cursor:pointer;display:flex;flex-direction:column;gap:3px;font-family:inherit;transition:border-color .12s,box-shadow .12s}.std__card:hover{border-color:var(--std-hover-line, #bfdbfe)}.std__card--on{border-color:#007ad9;box-shadow:0 0 0 3px var(--std-accent-soft, #eff6ff)}.std__card-ico{width:30px;height:30px;border-radius:8px;background:var(--sbd-r-sunk, #f1f5f9);color:var(--sbd-r-muted, #64748b);display:grid;place-items:center;margin-bottom:5px}.std__card--on .std__card-ico{background:var(--std-accent-soft, #eff6ff);color:#007ad9}.std__card-t{font-size:13px;font-weight:700}.std__card--on .std__card-t{color:#007ad9}.std__card-s{font-size:11px;color:var(--sbd-r-faint, #94a3b8)}.std__panel{border:1px solid var(--sbd-r-line, #e2e8f0);border-radius:14px;overflow:hidden}.std__panel-h{padding:12px 16px;border-bottom:1px solid var(--sbd-r-line, #e2e8f0);font-size:13.5px;font-weight:700;background:var(--sbd-r-soft, #f8fafc);display:flex;align-items:center;gap:8px}.std__panel-h .pi{color:#007ad9}.std__panel-h small{font-weight:500;color:var(--sbd-r-faint, #94a3b8)}.std__rows{padding:4px 16px;max-height:40vh;overflow-y:auto}.std__row{display:grid;grid-template-columns:160px 1fr;gap:12px;padding:9px 0;border-bottom:1px dashed var(--sbd-r-line, #e2e8f0)}.std__row:last-child{border-bottom:none}.std__label{font-size:12.5px;font-weight:600;color:var(--sbd-r-muted, #64748b);display:flex;flex-direction:column;gap:2px}.std__label small{font-weight:500;color:var(--sbd-r-faint, #94a3b8)}.std__val{font-size:13.5px;min-width:0}.std__en{white-space:pre-line;word-break:break-word}.std__ar{white-space:pre-line;word-break:break-word;color:var(--sbd-r-muted, #64748b);margin-top:3px}.std__copybar{display:flex;align-items:center;gap:10px;padding:12px 16px;border-top:1px solid var(--sbd-r-line, #e2e8f0);background:var(--sbd-r-soft, #f8fafc)}.std__hint{font-size:12px;color:var(--sbd-r-faint, #94a3b8)}.std__copied{color:var(--sbd-r-success-text, #1a7f37);font-size:12.5px;font-weight:700}.std__spacer{flex:1}.std__btn{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--sbd-r-line, #e2e8f0);background:var(--sbd-r-surface, #fff);color:var(--sbd-r-ink, #1e2e4a);border-radius:9px;padding:8px 13px;font-size:12.5px;font-weight:600;cursor:pointer;font-family:inherit}.std__btn--primary{background:#007ad9;border-color:#007ad9;color:#fff}@media (max-width: 820px){.std__grid{grid-template-columns:minmax(0,1fr)}.std__rail{border-right:none;border-bottom:1px solid var(--sbd-r-line, #e2e8f0)}}.std__qa{margin-bottom:18px}.std__qa-h{font-size:11.5px;font-weight:800;letter-spacing:.5px;text-transform:uppercase;color:var(--sbd-r-muted, #64748b);margin-bottom:10px}.std__qa-row{display:flex;flex-wrap:wrap;gap:8px}.std__qa-btn{display:inline-flex;align-items:center;gap:7px;border:1px solid var(--sbd-r-line, #e2e8f0);background:var(--sbd-r-surface, #fff);color:var(--sbd-r-muted, #64748b);border-radius:9px;padding:8px 13px;font-size:12.5px;font-weight:600;font-family:inherit;cursor:not-allowed;opacity:.6}:host-context(.dark) .std,:host-context([data-theme=dark]) .std{--sbd-r-bg: #18181b;--sbd-r-surface: #1f1f23;--sbd-r-soft: #27272a;--sbd-r-sunk: #2f2f34;--sbd-r-ink: #f4f4f5;--sbd-r-muted: #a1a1aa;--sbd-r-faint: #8b8b94;--sbd-r-line: #3f3f46;--sbd-r-line-strong: #52525b;--sbd-r-label: #d4d4d8;--sbd-r-input-text: #e4e4e7;--sbd-r-info-bg: #172554;--sbd-r-info-line: #1e3a8a;--sbd-r-info-text: #93c5fd;--sbd-r-warn-bg: #3a2a0e;--sbd-r-warn-line: #6b4a16;--sbd-r-warn-text: #fcd34d;--sbd-r-warn-icon: #f59e0b;--sbd-r-error-bg: #3a1517;--sbd-r-error-line: #7f1d1d;--sbd-r-error-text: #fca5a5;--sbd-r-success-bg: #0f2a1a;--sbd-r-success-line: #166534;--sbd-r-success-text: #86efac;--sbd-r-state-bg: #3a2410;--sbd-r-state-line: #7c3a10;--sbd-r-state-warn-bg: #3a1517;--sbd-r-state-warn-line: #7f1d1d;--sbd-r-green: #4ade80;--sbd-r-expiry-soon: #fbbf24;--sbd-r-accent-soft: color-mix(in srgb, var(--sbd-accent, #6d4aff) 28%, transparent);--std-accent-soft: #1e2a52;--std-hover-line: #3b5ea8}\n"] }]
|
|
5779
5939
|
}] });
|
|
5780
5940
|
|
|
5781
5941
|
class SbdHotelItineraryCardComponent {
|
|
@@ -6589,7 +6749,7 @@ const POST_BOOKING_PARAMS = { entrySource: 'navigation bar', device: 'web' };
|
|
|
6589
6749
|
*/
|
|
6590
6750
|
class SbdReissueService {
|
|
6591
6751
|
constructor() {
|
|
6592
|
-
this.http = inject(
|
|
6752
|
+
this.http = inject(SBD_HTTP);
|
|
6593
6753
|
this.config = inject(SBD_CONFIG);
|
|
6594
6754
|
this.base = this.config.apiBase;
|
|
6595
6755
|
}
|
|
@@ -7424,11 +7584,11 @@ class SbdReissueNoticeComponent {
|
|
|
7424
7584
|
this.tone = input('info');
|
|
7425
7585
|
}
|
|
7426
7586
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SbdReissueNoticeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
7427
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.14", type: SbdReissueNoticeComponent, isStandalone: true, selector: "app-sbd-reissue-notice", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "\"sbd-notice sbd-notice--\" + tone()" } }, ngImport: i0, template: `<i [class]="icon()"></i><span class="sbd-notice__text"><ng-content /></span><ng-content select="[action]" />`, isInline: true, styles: [":host{display:flex;align-items:flex-start;gap:10px;padding:12px 14px;border-radius:12px;font-size:13px;line-height:1.5}:host i{flex-shrink:0;margin-top:1px}:host .sbd-notice__text{flex:1}:host(.sbd-notice--info){background
|
|
7587
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "18.2.14", type: SbdReissueNoticeComponent, isStandalone: true, selector: "app-sbd-reissue-notice", inputs: { icon: { classPropertyName: "icon", publicName: "icon", isSignal: true, isRequired: false, transformFunction: null }, tone: { classPropertyName: "tone", publicName: "tone", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "\"sbd-notice sbd-notice--\" + tone()" } }, ngImport: i0, template: `<i [class]="icon()"></i><span class="sbd-notice__text"><ng-content /></span><ng-content select="[action]" />`, isInline: true, styles: [":host{display:flex;align-items:flex-start;gap:10px;padding:12px 14px;border-radius:12px;font-size:13px;line-height:1.5}:host i{flex-shrink:0;margin-top:1px}:host .sbd-notice__text{flex:1}:host(.sbd-notice--info){background:var(--sbd-r-info-bg, #eaf2ff);border:1px solid var(--sbd-r-info-line, #b9d6ff);color:var(--sbd-r-info-text, #1a5fd6)}:host(.sbd-notice--warn){background:var(--sbd-r-warn-bg, #fdf3e3);border:1px solid var(--sbd-r-warn-line, #f3d9a4);color:var(--sbd-r-warn-text, #8a5a1e)}:host(.sbd-notice--warn) i{color:var(--sbd-r-warn-icon, #b98a3e)}:host(.sbd-notice--error){background:var(--sbd-r-error-bg, #fef2f2);border:1px solid var(--sbd-r-error-line, #fecaca);color:var(--sbd-r-error-text, #b91c1c)}:host(.sbd-notice--success){background:var(--sbd-r-success-bg, #f0fdf4);border:1px solid var(--sbd-r-success-line, #bbf7d0);color:var(--sbd-r-success-text, #166534)}:host(.sbd-notice--muted){align-items:center;color:var(--sbd-r-muted, #64748b)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
7428
7588
|
}
|
|
7429
7589
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SbdReissueNoticeComponent, decorators: [{
|
|
7430
7590
|
type: Component,
|
|
7431
|
-
args: [{ selector: 'app-sbd-reissue-notice', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: { '[class]': '"sbd-notice sbd-notice--" + tone()' }, template: `<i [class]="icon()"></i><span class="sbd-notice__text"><ng-content /></span><ng-content select="[action]" />`, styles: [":host{display:flex;align-items:flex-start;gap:10px;padding:12px 14px;border-radius:12px;font-size:13px;line-height:1.5}:host i{flex-shrink:0;margin-top:1px}:host .sbd-notice__text{flex:1}:host(.sbd-notice--info){background
|
|
7591
|
+
args: [{ selector: 'app-sbd-reissue-notice', standalone: true, changeDetection: ChangeDetectionStrategy.OnPush, host: { '[class]': '"sbd-notice sbd-notice--" + tone()' }, template: `<i [class]="icon()"></i><span class="sbd-notice__text"><ng-content /></span><ng-content select="[action]" />`, styles: [":host{display:flex;align-items:flex-start;gap:10px;padding:12px 14px;border-radius:12px;font-size:13px;line-height:1.5}:host i{flex-shrink:0;margin-top:1px}:host .sbd-notice__text{flex:1}:host(.sbd-notice--info){background:var(--sbd-r-info-bg, #eaf2ff);border:1px solid var(--sbd-r-info-line, #b9d6ff);color:var(--sbd-r-info-text, #1a5fd6)}:host(.sbd-notice--warn){background:var(--sbd-r-warn-bg, #fdf3e3);border:1px solid var(--sbd-r-warn-line, #f3d9a4);color:var(--sbd-r-warn-text, #8a5a1e)}:host(.sbd-notice--warn) i{color:var(--sbd-r-warn-icon, #b98a3e)}:host(.sbd-notice--error){background:var(--sbd-r-error-bg, #fef2f2);border:1px solid var(--sbd-r-error-line, #fecaca);color:var(--sbd-r-error-text, #b91c1c)}:host(.sbd-notice--success){background:var(--sbd-r-success-bg, #f0fdf4);border:1px solid var(--sbd-r-success-line, #bbf7d0);color:var(--sbd-r-success-text, #166534)}:host(.sbd-notice--muted){align-items:center;color:var(--sbd-r-muted, #64748b)}\n"] }]
|
|
7432
7592
|
}] });
|
|
7433
7593
|
|
|
7434
7594
|
/** New-class options as radio cards, in the look of the cancel dialog's refund-method options. */
|
|
@@ -7463,7 +7623,6 @@ class SbdReissueUpgradeStepComponent {
|
|
|
7463
7623
|
<span class="sbd-rup__radio" [class.sbd-rup__radio--on]="option.selected"></span>
|
|
7464
7624
|
<span class="sbd-rup__text">
|
|
7465
7625
|
<strong>{{ option.name }}</strong>
|
|
7466
|
-
<small>{{ option.code }}</small>
|
|
7467
7626
|
</span>
|
|
7468
7627
|
@if (option.unavailable) {
|
|
7469
7628
|
<span class="sbd-rup__unavailable">Not available</span>
|
|
@@ -7474,7 +7633,7 @@ class SbdReissueUpgradeStepComponent {
|
|
|
7474
7633
|
}
|
|
7475
7634
|
</section>
|
|
7476
7635
|
}
|
|
7477
|
-
`, isInline: true, styles: [":host{display:flex;flex-direction:column;gap:14px}.sbd-rup__section{display:flex;flex-direction:column;gap:10px}.sbd-rup__head{display:flex;flex-direction:column;gap:2px}.sbd-rup__route{font-size:15px;font-weight:700;color
|
|
7636
|
+
`, isInline: true, styles: [":host{display:flex;flex-direction:column;gap:14px}.sbd-rup__section{display:flex;flex-direction:column;gap:10px}.sbd-rup__head{display:flex;flex-direction:column;gap:2px}.sbd-rup__route{font-size:15px;font-weight:700;color:var(--sbd-r-ink, #1e2e4a)}.sbd-rup__current,.sbd-rup__empty{font-size:13px;color:var(--sbd-r-muted, #64748b)}.sbd-rup__option{border:1.5px solid var(--sbd-r-line, #e2e8f0);border-radius:16px;background:var(--sbd-r-surface, #fff);transition:border-color .15s,box-shadow .15s;display:flex;align-items:center;gap:12px;width:100%;padding:16px;text-align:left;font-family:inherit;cursor:pointer}.sbd-rup__option--active{border-color:var(--sbd-accent, #6d4aff);box-shadow:0 0 0 1px var(--sbd-accent, #6d4aff)}.sbd-rup__option:disabled{opacity:.5;cursor:not-allowed}.sbd-rup__option:hover:not(:disabled):not(.sbd-rup__option--active){border-color:var(--sbd-r-line-strong, #cbd5e1)}.sbd-rup__radio{flex-shrink:0;width:20px;height:20px;border-radius:50%;border:2px solid var(--sbd-r-line-strong, #cbd5e1);background:var(--sbd-r-surface, #fff)}.sbd-rup__radio--on{border-color:var(--sbd-accent, #6d4aff);box-shadow:inset 0 0 0 4px var(--sbd-r-surface, #fff);background:var(--sbd-accent, #6d4aff)}.sbd-rup__text{flex:1;display:flex;flex-direction:column;gap:2px}.sbd-rup__text strong{font-size:14px;font-weight:700;color:var(--sbd-r-ink, #1e2e4a)}.sbd-rup__text small{font-size:12.5px;color:var(--sbd-r-muted, #64748b)}.sbd-rup__price{font-size:14px;font-weight:800;color:var(--sbd-r-ink, #1e2e4a);white-space:nowrap;font-variant-numeric:tabular-nums}.sbd-rup__unavailable{font-size:11.5px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;color:var(--sbd-r-muted, #64748b);background:var(--sbd-r-soft, #f8fafc);box-shadow:inset 0 0 0 1px var(--sbd-r-line, #e2e8f0);border-radius:20px;padding:3px 12px;white-space:nowrap}\n"], dependencies: [{ kind: "component", type: SbdReissueNoticeComponent, selector: "app-sbd-reissue-notice", inputs: ["icon", "tone"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
7478
7637
|
}
|
|
7479
7638
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SbdReissueUpgradeStepComponent, decorators: [{
|
|
7480
7639
|
type: Component,
|
|
@@ -7502,7 +7661,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
7502
7661
|
<span class="sbd-rup__radio" [class.sbd-rup__radio--on]="option.selected"></span>
|
|
7503
7662
|
<span class="sbd-rup__text">
|
|
7504
7663
|
<strong>{{ option.name }}</strong>
|
|
7505
|
-
<small>{{ option.code }}</small>
|
|
7506
7664
|
</span>
|
|
7507
7665
|
@if (option.unavailable) {
|
|
7508
7666
|
<span class="sbd-rup__unavailable">Not available</span>
|
|
@@ -7513,7 +7671,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
7513
7671
|
}
|
|
7514
7672
|
</section>
|
|
7515
7673
|
}
|
|
7516
|
-
`, host: { class: 'sbd-rup' }, styles: [":host{display:flex;flex-direction:column;gap:14px}.sbd-rup__section{display:flex;flex-direction:column;gap:10px}.sbd-rup__head{display:flex;flex-direction:column;gap:2px}.sbd-rup__route{font-size:15px;font-weight:700;color
|
|
7674
|
+
`, host: { class: 'sbd-rup' }, styles: [":host{display:flex;flex-direction:column;gap:14px}.sbd-rup__section{display:flex;flex-direction:column;gap:10px}.sbd-rup__head{display:flex;flex-direction:column;gap:2px}.sbd-rup__route{font-size:15px;font-weight:700;color:var(--sbd-r-ink, #1e2e4a)}.sbd-rup__current,.sbd-rup__empty{font-size:13px;color:var(--sbd-r-muted, #64748b)}.sbd-rup__option{border:1.5px solid var(--sbd-r-line, #e2e8f0);border-radius:16px;background:var(--sbd-r-surface, #fff);transition:border-color .15s,box-shadow .15s;display:flex;align-items:center;gap:12px;width:100%;padding:16px;text-align:left;font-family:inherit;cursor:pointer}.sbd-rup__option--active{border-color:var(--sbd-accent, #6d4aff);box-shadow:0 0 0 1px var(--sbd-accent, #6d4aff)}.sbd-rup__option:disabled{opacity:.5;cursor:not-allowed}.sbd-rup__option:hover:not(:disabled):not(.sbd-rup__option--active){border-color:var(--sbd-r-line-strong, #cbd5e1)}.sbd-rup__radio{flex-shrink:0;width:20px;height:20px;border-radius:50%;border:2px solid var(--sbd-r-line-strong, #cbd5e1);background:var(--sbd-r-surface, #fff)}.sbd-rup__radio--on{border-color:var(--sbd-accent, #6d4aff);box-shadow:inset 0 0 0 4px var(--sbd-r-surface, #fff);background:var(--sbd-accent, #6d4aff)}.sbd-rup__text{flex:1;display:flex;flex-direction:column;gap:2px}.sbd-rup__text strong{font-size:14px;font-weight:700;color:var(--sbd-r-ink, #1e2e4a)}.sbd-rup__text small{font-size:12.5px;color:var(--sbd-r-muted, #64748b)}.sbd-rup__price{font-size:14px;font-weight:800;color:var(--sbd-r-ink, #1e2e4a);white-space:nowrap;font-variant-numeric:tabular-nums}.sbd-rup__unavailable{font-size:11.5px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;color:var(--sbd-r-muted, #64748b);background:var(--sbd-r-soft, #f8fafc);box-shadow:inset 0 0 0 1px var(--sbd-r-line, #e2e8f0);border-radius:20px;padding:3px 12px;white-space:nowrap}\n"] }]
|
|
7517
7675
|
}] });
|
|
7518
7676
|
|
|
7519
7677
|
class SbdReissueUpgradeConfirmStepComponent {
|
|
@@ -7628,7 +7786,7 @@ class SbdReissueUpgradeConfirmStepComponent {
|
|
|
7628
7786
|
: 'Nothing to pay: confirming places the upgrade straight away.' }}
|
|
7629
7787
|
</app-sbd-reissue-notice>
|
|
7630
7788
|
}
|
|
7631
|
-
`, isInline: true, styles: [":host{display:flex;flex-direction:column;gap:14px}.sbd-rconf__summary{background
|
|
7789
|
+
`, isInline: true, styles: [":host{display:flex;flex-direction:column;gap:14px}.sbd-rconf__summary{background:var(--sbd-r-soft, #f8fafc);border:1px solid var(--sbd-r-line, #e2e8f0);border-radius:12px;padding:14px 16px;display:flex;flex-direction:column;gap:12px}.sbd-rconf__row{display:flex;align-items:center;justify-content:space-between;gap:12px;font-size:13.5px}.sbd-rconf__row strong{font-size:14px;font-weight:800;color:var(--sbd-r-ink, #1e2e4a);font-variant-numeric:tabular-nums;white-space:nowrap}.sbd-rconf__row-main{display:flex;flex-direction:column;gap:2px;min-width:0}.sbd-rconf__row-main b{font-weight:700;color:var(--sbd-r-ink, #1e2e4a)}.sbd-rconf__row-main small{font-size:12.5px;color:var(--sbd-r-muted, #64748b)}.sbd-rconf__total{display:flex;align-items:center;justify-content:space-between;border-top:1px solid var(--sbd-r-line, #e2e8f0);padding-top:12px}.sbd-rconf__total span{font-size:14.5px;font-weight:700;color:var(--sbd-r-ink, #1e2e4a)}.sbd-rconf__total strong{font-size:17px;font-weight:800;color:var(--sbd-r-ink, #1e2e4a);font-variant-numeric:tabular-nums}.sbd-rconf__link{border:1.5px solid var(--sbd-r-line, #e2e8f0);border-radius:16px;background:var(--sbd-r-surface, #fff);transition:border-color .15s,box-shadow .15s;padding:16px;display:flex;flex-direction:column;gap:10px}.sbd-rconf__link-head{display:flex;justify-content:space-between;align-items:center;font-size:14px;color:var(--sbd-r-ink, #1e2e4a)}.sbd-rconf__link-head small{color:var(--sbd-r-faint, #94a3b8);font-size:12.5px}.sbd-rconf__link-row{display:flex;gap:8px}.sbd-rconf__link-input{height:40px;padding:0 12px;border:1.5px solid var(--sbd-r-line, #e2e8f0);border-radius:10px;background:var(--sbd-r-surface, #fff);font-size:13px;font-family:inherit;color:var(--sbd-r-ink, #1e2e4a);color-scheme:inherit}.sbd-rconf__link-input:focus{outline:none;border-color:var(--sbd-accent, #6d4aff)}.sbd-rconf__link-input{flex:1;min-width:0;height:36px;font-size:12px;color:var(--sbd-r-input-text, #334155)}.sbd-rconf__expiry{color:var(--sbd-r-faint, #94a3b8);font-size:12.5px;font-variant-numeric:tabular-nums}.sbd-rconf__expiry--soon{color:var(--sbd-r-expiry-soon, #b45309);font-weight:600}\n"], dependencies: [{ kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2$1.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading"] }, { kind: "component", type: SbdReissueNoticeComponent, selector: "app-sbd-reissue-notice", inputs: ["icon", "tone"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
7632
7790
|
}
|
|
7633
7791
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SbdReissueUpgradeConfirmStepComponent, decorators: [{
|
|
7634
7792
|
type: Component,
|
|
@@ -7700,7 +7858,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
7700
7858
|
: 'Nothing to pay: confirming places the upgrade straight away.' }}
|
|
7701
7859
|
</app-sbd-reissue-notice>
|
|
7702
7860
|
}
|
|
7703
|
-
`, host: { class: 'sbd-rconf' }, styles: [":host{display:flex;flex-direction:column;gap:14px}.sbd-rconf__summary{background
|
|
7861
|
+
`, host: { class: 'sbd-rconf' }, styles: [":host{display:flex;flex-direction:column;gap:14px}.sbd-rconf__summary{background:var(--sbd-r-soft, #f8fafc);border:1px solid var(--sbd-r-line, #e2e8f0);border-radius:12px;padding:14px 16px;display:flex;flex-direction:column;gap:12px}.sbd-rconf__row{display:flex;align-items:center;justify-content:space-between;gap:12px;font-size:13.5px}.sbd-rconf__row strong{font-size:14px;font-weight:800;color:var(--sbd-r-ink, #1e2e4a);font-variant-numeric:tabular-nums;white-space:nowrap}.sbd-rconf__row-main{display:flex;flex-direction:column;gap:2px;min-width:0}.sbd-rconf__row-main b{font-weight:700;color:var(--sbd-r-ink, #1e2e4a)}.sbd-rconf__row-main small{font-size:12.5px;color:var(--sbd-r-muted, #64748b)}.sbd-rconf__total{display:flex;align-items:center;justify-content:space-between;border-top:1px solid var(--sbd-r-line, #e2e8f0);padding-top:12px}.sbd-rconf__total span{font-size:14.5px;font-weight:700;color:var(--sbd-r-ink, #1e2e4a)}.sbd-rconf__total strong{font-size:17px;font-weight:800;color:var(--sbd-r-ink, #1e2e4a);font-variant-numeric:tabular-nums}.sbd-rconf__link{border:1.5px solid var(--sbd-r-line, #e2e8f0);border-radius:16px;background:var(--sbd-r-surface, #fff);transition:border-color .15s,box-shadow .15s;padding:16px;display:flex;flex-direction:column;gap:10px}.sbd-rconf__link-head{display:flex;justify-content:space-between;align-items:center;font-size:14px;color:var(--sbd-r-ink, #1e2e4a)}.sbd-rconf__link-head small{color:var(--sbd-r-faint, #94a3b8);font-size:12.5px}.sbd-rconf__link-row{display:flex;gap:8px}.sbd-rconf__link-input{height:40px;padding:0 12px;border:1.5px solid var(--sbd-r-line, #e2e8f0);border-radius:10px;background:var(--sbd-r-surface, #fff);font-size:13px;font-family:inherit;color:var(--sbd-r-ink, #1e2e4a);color-scheme:inherit}.sbd-rconf__link-input:focus{outline:none;border-color:var(--sbd-accent, #6d4aff)}.sbd-rconf__link-input{flex:1;min-width:0;height:36px;font-size:12px;color:var(--sbd-r-input-text, #334155)}.sbd-rconf__expiry{color:var(--sbd-r-faint, #94a3b8);font-size:12.5px;font-variant-numeric:tabular-nums}.sbd-rconf__expiry--soon{color:var(--sbd-r-expiry-soon, #b45309);font-weight:600}\n"] }]
|
|
7704
7862
|
}], ctorParameters: () => [] });
|
|
7705
7863
|
|
|
7706
7864
|
const OPTIONS = [
|
|
@@ -7727,7 +7885,7 @@ class SbdReissueServiceStepComponent {
|
|
|
7727
7885
|
<i class="pi pi-chevron-right sbd-rsvc__arrow"></i>
|
|
7728
7886
|
</button>
|
|
7729
7887
|
}
|
|
7730
|
-
`, isInline: true, styles: [":host{display:flex;flex-direction:column;gap:12px}.sbd-rsvc__option{border:1.5px solid #e2e8f0;border-radius:16px;background
|
|
7888
|
+
`, isInline: true, styles: [":host{display:flex;flex-direction:column;gap:12px}.sbd-rsvc__option{border:1.5px solid var(--sbd-r-line, #e2e8f0);border-radius:16px;background:var(--sbd-r-surface, #fff);transition:border-color .15s,box-shadow .15s;display:flex;align-items:center;gap:12px;width:100%;padding:16px;text-align:left;font-family:inherit;cursor:pointer}.sbd-rsvc__option:hover{border-color:var(--sbd-accent, #6d4aff)}.sbd-rsvc__icon{flex-shrink:0;width:44px;height:44px;border-radius:10px;border:1px solid var(--sbd-r-line, #e2e8f0);color:var(--sbd-r-ink, #1e2e4a);display:flex;align-items:center;justify-content:center}.sbd-rsvc__icon .pi{font-size:16px}.sbd-rsvc__text{flex:1;display:flex;flex-direction:column;gap:2px}.sbd-rsvc__text strong{font-size:15px;font-weight:700;color:var(--sbd-r-ink, #1e2e4a)}.sbd-rsvc__text small{font-size:12.5px;color:var(--sbd-r-muted, #64748b)}.sbd-rsvc__arrow{color:var(--sbd-r-faint, #94a3b8);font-size:12px}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
7731
7889
|
}
|
|
7732
7890
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SbdReissueServiceStepComponent, decorators: [{
|
|
7733
7891
|
type: Component,
|
|
@@ -7742,7 +7900,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
7742
7900
|
<i class="pi pi-chevron-right sbd-rsvc__arrow"></i>
|
|
7743
7901
|
</button>
|
|
7744
7902
|
}
|
|
7745
|
-
`, host: { class: 'sbd-rsvc' }, styles: [":host{display:flex;flex-direction:column;gap:12px}.sbd-rsvc__option{border:1.5px solid #e2e8f0;border-radius:16px;background
|
|
7903
|
+
`, host: { class: 'sbd-rsvc' }, styles: [":host{display:flex;flex-direction:column;gap:12px}.sbd-rsvc__option{border:1.5px solid var(--sbd-r-line, #e2e8f0);border-radius:16px;background:var(--sbd-r-surface, #fff);transition:border-color .15s,box-shadow .15s;display:flex;align-items:center;gap:12px;width:100%;padding:16px;text-align:left;font-family:inherit;cursor:pointer}.sbd-rsvc__option:hover{border-color:var(--sbd-accent, #6d4aff)}.sbd-rsvc__icon{flex-shrink:0;width:44px;height:44px;border-radius:10px;border:1px solid var(--sbd-r-line, #e2e8f0);color:var(--sbd-r-ink, #1e2e4a);display:flex;align-items:center;justify-content:center}.sbd-rsvc__icon .pi{font-size:16px}.sbd-rsvc__text{flex:1;display:flex;flex-direction:column;gap:2px}.sbd-rsvc__text strong{font-size:15px;font-weight:700;color:var(--sbd-r-ink, #1e2e4a)}.sbd-rsvc__text small{font-size:12.5px;color:var(--sbd-r-muted, #64748b)}.sbd-rsvc__arrow{color:var(--sbd-r-faint, #94a3b8);font-size:12px}\n"] }]
|
|
7746
7904
|
}] });
|
|
7747
7905
|
|
|
7748
7906
|
/** Leg cards in the cancel dialog's "Select Leg" design: checkbox overlay, outline badge, times row. */
|
|
@@ -7820,7 +7978,7 @@ class SbdReissueLegsStepComponent {
|
|
|
7820
7978
|
</div>
|
|
7821
7979
|
</div>
|
|
7822
7980
|
}
|
|
7823
|
-
`, isInline: true, styles: [":host{display:flex;flex-direction:column;gap:12px}.sbd-rlegs__card{border:1.5px solid #e2e8f0;border-radius:16px;background
|
|
7981
|
+
`, isInline: true, styles: [":host{display:flex;flex-direction:column;gap:12px}.sbd-rlegs__card{border:1.5px solid var(--sbd-r-line, #e2e8f0);border-radius:16px;background:var(--sbd-r-surface, #fff);transition:border-color .15s,box-shadow .15s;position:relative;padding:16px 16px 16px 48px;cursor:pointer}.sbd-rlegs__card:focus-visible{outline:2px solid var(--sbd-accent, #6d4aff);outline-offset:2px}.sbd-rlegs__card--selected{border-color:var(--sbd-accent, #6d4aff)}.sbd-rlegs__card--disabled{opacity:.7;cursor:not-allowed}.sbd-rlegs__checkbox{position:absolute;top:16px;left:16px;width:22px;height:22px;border-radius:6px;border:1.5px solid var(--sbd-r-line-strong, #cbd5e1);background:var(--sbd-r-surface, #fff);color:#fff;font-size:12px;display:flex;align-items:center;justify-content:center}.sbd-rlegs__checkbox--on{background:var(--sbd-accent, #6d4aff);border-color:var(--sbd-accent, #6d4aff)}.sbd-rlegs__checkbox--off{background:var(--sbd-r-sunk, #f1f5f9);border-color:var(--sbd-r-line, #e2e8f0)}.sbd-rlegs__content{display:flex;flex-direction:column;gap:8px}.sbd-rlegs__top{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}.sbd-rlegs__name{font-size:15px;font-weight:700;color:var(--sbd-r-ink, #1e2e4a)}.sbd-rlegs__date{font-size:13px;color:var(--sbd-r-muted, #64748b);margin-top:2px}.sbd-rlegs__badge{font-size:11.5px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;border-radius:20px;padding:4px 14px;width:max-content;background:var(--sbd-r-soft, #f8fafc);color:var(--sbd-r-muted, #64748b);box-shadow:inset 0 0 0 1px var(--sbd-r-line, #e2e8f0)}.sbd-rlegs__badge--green{background:transparent;color:var(--sbd-r-green, #16a34a);box-shadow:inset 0 0 0 1.5px currentColor}.sbd-rlegs__times{display:flex;align-items:center;gap:8px}.sbd-rlegs__time{font-size:18px;font-weight:700;color:var(--sbd-r-ink, #1e2e4a);font-variant-numeric:tabular-nums}.sbd-rlegs__line{flex:1;position:relative;display:flex;flex-direction:column;align-items:center;gap:2px;padding:0 16px 0 8px}.sbd-rlegs__line:before{content:\"\";position:absolute;left:0;right:14px;top:50%;height:2px;background:var(--sbd-r-line-strong, #cbd5e1);z-index:1}.sbd-rlegs__stops{font-size:12px;color:var(--sbd-r-muted, #64748b);background:var(--sbd-r-surface, #fff);padding:0 6px;z-index:2}.sbd-rlegs__arrow{position:absolute;right:4px;top:51%;transform:translateY(-50%);font-size:11px;color:var(--sbd-r-muted, #64748b)}.sbd-rlegs__airline{font-size:12.5px;color:var(--sbd-r-muted, #64748b)}.sbd-rlegs__notice{display:flex;align-items:flex-start;gap:8px;padding:10px 12px;border-radius:10px;background:var(--sbd-r-warn-bg, #fdf1e0);color:var(--sbd-r-warn-text, #6b4a16);font-size:12.5px;line-height:1.4}.sbd-rlegs__notice i{flex-shrink:0;margin-top:1px;color:var(--sbd-r-warn-icon, #b98a3e)}\n"], dependencies: [{ kind: "component", type: SbdReissueNoticeComponent, selector: "app-sbd-reissue-notice", inputs: ["icon", "tone"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
7824
7982
|
}
|
|
7825
7983
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SbdReissueLegsStepComponent, decorators: [{
|
|
7826
7984
|
type: Component,
|
|
@@ -7879,7 +8037,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
7879
8037
|
</div>
|
|
7880
8038
|
</div>
|
|
7881
8039
|
}
|
|
7882
|
-
`, host: { class: 'sbd-rlegs' }, styles: [":host{display:flex;flex-direction:column;gap:12px}.sbd-rlegs__card{border:1.5px solid #e2e8f0;border-radius:16px;background
|
|
8040
|
+
`, host: { class: 'sbd-rlegs' }, styles: [":host{display:flex;flex-direction:column;gap:12px}.sbd-rlegs__card{border:1.5px solid var(--sbd-r-line, #e2e8f0);border-radius:16px;background:var(--sbd-r-surface, #fff);transition:border-color .15s,box-shadow .15s;position:relative;padding:16px 16px 16px 48px;cursor:pointer}.sbd-rlegs__card:focus-visible{outline:2px solid var(--sbd-accent, #6d4aff);outline-offset:2px}.sbd-rlegs__card--selected{border-color:var(--sbd-accent, #6d4aff)}.sbd-rlegs__card--disabled{opacity:.7;cursor:not-allowed}.sbd-rlegs__checkbox{position:absolute;top:16px;left:16px;width:22px;height:22px;border-radius:6px;border:1.5px solid var(--sbd-r-line-strong, #cbd5e1);background:var(--sbd-r-surface, #fff);color:#fff;font-size:12px;display:flex;align-items:center;justify-content:center}.sbd-rlegs__checkbox--on{background:var(--sbd-accent, #6d4aff);border-color:var(--sbd-accent, #6d4aff)}.sbd-rlegs__checkbox--off{background:var(--sbd-r-sunk, #f1f5f9);border-color:var(--sbd-r-line, #e2e8f0)}.sbd-rlegs__content{display:flex;flex-direction:column;gap:8px}.sbd-rlegs__top{display:flex;align-items:flex-start;justify-content:space-between;gap:8px}.sbd-rlegs__name{font-size:15px;font-weight:700;color:var(--sbd-r-ink, #1e2e4a)}.sbd-rlegs__date{font-size:13px;color:var(--sbd-r-muted, #64748b);margin-top:2px}.sbd-rlegs__badge{font-size:11.5px;font-weight:700;letter-spacing:.03em;text-transform:uppercase;border-radius:20px;padding:4px 14px;width:max-content;background:var(--sbd-r-soft, #f8fafc);color:var(--sbd-r-muted, #64748b);box-shadow:inset 0 0 0 1px var(--sbd-r-line, #e2e8f0)}.sbd-rlegs__badge--green{background:transparent;color:var(--sbd-r-green, #16a34a);box-shadow:inset 0 0 0 1.5px currentColor}.sbd-rlegs__times{display:flex;align-items:center;gap:8px}.sbd-rlegs__time{font-size:18px;font-weight:700;color:var(--sbd-r-ink, #1e2e4a);font-variant-numeric:tabular-nums}.sbd-rlegs__line{flex:1;position:relative;display:flex;flex-direction:column;align-items:center;gap:2px;padding:0 16px 0 8px}.sbd-rlegs__line:before{content:\"\";position:absolute;left:0;right:14px;top:50%;height:2px;background:var(--sbd-r-line-strong, #cbd5e1);z-index:1}.sbd-rlegs__stops{font-size:12px;color:var(--sbd-r-muted, #64748b);background:var(--sbd-r-surface, #fff);padding:0 6px;z-index:2}.sbd-rlegs__arrow{position:absolute;right:4px;top:51%;transform:translateY(-50%);font-size:11px;color:var(--sbd-r-muted, #64748b)}.sbd-rlegs__airline{font-size:12.5px;color:var(--sbd-r-muted, #64748b)}.sbd-rlegs__notice{display:flex;align-items:flex-start;gap:8px;padding:10px 12px;border-radius:10px;background:var(--sbd-r-warn-bg, #fdf1e0);color:var(--sbd-r-warn-text, #6b4a16);font-size:12.5px;line-height:1.4}.sbd-rlegs__notice i{flex-shrink:0;margin-top:1px;color:var(--sbd-r-warn-icon, #b98a3e)}\n"] }]
|
|
7883
8041
|
}] });
|
|
7884
8042
|
|
|
7885
8043
|
class SbdReissueDateStepComponent {
|
|
@@ -7903,7 +8061,7 @@ class SbdReissueDateStepComponent {
|
|
|
7903
8061
|
</label>
|
|
7904
8062
|
</div>
|
|
7905
8063
|
}
|
|
7906
|
-
`, isInline: true, styles: [":host{display:flex;flex-direction:column;gap:12px}.sbd-rdate__card{border:1.5px solid #e2e8f0;border-radius:16px;background
|
|
8064
|
+
`, isInline: true, styles: [":host{display:flex;flex-direction:column;gap:12px}.sbd-rdate__card{border:1.5px solid var(--sbd-r-line, #e2e8f0);border-radius:16px;background:var(--sbd-r-surface, #fff);transition:border-color .15s,box-shadow .15s;padding:16px;display:flex;flex-direction:column;gap:14px}.sbd-rdate__head{display:flex;flex-direction:column;gap:2px}.sbd-rdate__name{font-size:15px;font-weight:700;color:var(--sbd-r-ink, #1e2e4a)}.sbd-rdate__current{font-size:13px;color:var(--sbd-r-muted, #64748b)}.sbd-rdate__field{display:flex;flex-direction:column;gap:6px;min-width:0;font-size:12.5px;font-weight:600;color:var(--sbd-r-label, #475569)}.sbd-rdate__input{height:40px;padding:0 12px;border:1.5px solid var(--sbd-r-line, #e2e8f0);border-radius:10px;background:var(--sbd-r-surface, #fff);font-size:13px;font-family:inherit;color:var(--sbd-r-ink, #1e2e4a);color-scheme:inherit}.sbd-rdate__input:focus{outline:none;border-color:var(--sbd-accent, #6d4aff)}\n"], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
7907
8065
|
}
|
|
7908
8066
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SbdReissueDateStepComponent, decorators: [{
|
|
7909
8067
|
type: Component,
|
|
@@ -7922,7 +8080,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
7922
8080
|
</label>
|
|
7923
8081
|
</div>
|
|
7924
8082
|
}
|
|
7925
|
-
`, host: { class: 'sbd-rdate' }, styles: [":host{display:flex;flex-direction:column;gap:12px}.sbd-rdate__card{border:1.5px solid #e2e8f0;border-radius:16px;background
|
|
8083
|
+
`, host: { class: 'sbd-rdate' }, styles: [":host{display:flex;flex-direction:column;gap:12px}.sbd-rdate__card{border:1.5px solid var(--sbd-r-line, #e2e8f0);border-radius:16px;background:var(--sbd-r-surface, #fff);transition:border-color .15s,box-shadow .15s;padding:16px;display:flex;flex-direction:column;gap:14px}.sbd-rdate__head{display:flex;flex-direction:column;gap:2px}.sbd-rdate__name{font-size:15px;font-weight:700;color:var(--sbd-r-ink, #1e2e4a)}.sbd-rdate__current{font-size:13px;color:var(--sbd-r-muted, #64748b)}.sbd-rdate__field{display:flex;flex-direction:column;gap:6px;min-width:0;font-size:12.5px;font-weight:600;color:var(--sbd-r-label, #475569)}.sbd-rdate__input{height:40px;padding:0 12px;border:1.5px solid var(--sbd-r-line, #e2e8f0);border-radius:10px;background:var(--sbd-r-surface, #fff);font-size:13px;font-family:inherit;color:var(--sbd-r-ink, #1e2e4a);color-scheme:inherit}.sbd-rdate__input:focus{outline:none;border-color:var(--sbd-accent, #6d4aff)}\n"] }]
|
|
7926
8084
|
}] });
|
|
7927
8085
|
|
|
7928
8086
|
class SbdReissueRouteStepComponent {
|
|
@@ -7977,7 +8135,7 @@ class SbdReissueRouteStepComponent {
|
|
|
7977
8135
|
</div>
|
|
7978
8136
|
</div>
|
|
7979
8137
|
}
|
|
7980
|
-
`, isInline: true, styles: [":host{display:flex;flex-direction:column;gap:12px}.sbd-rroute__card{border:1.5px solid #e2e8f0;border-radius:16px;background
|
|
8138
|
+
`, isInline: true, styles: [":host{display:flex;flex-direction:column;gap:12px}.sbd-rroute__card{border:1.5px solid var(--sbd-r-line, #e2e8f0);border-radius:16px;background:var(--sbd-r-surface, #fff);transition:border-color .15s,box-shadow .15s;padding:16px;display:flex;flex-direction:column;gap:14px}.sbd-rroute__head{display:flex;flex-direction:column;gap:2px}.sbd-rroute__name{font-size:15px;font-weight:700;color:var(--sbd-r-ink, #1e2e4a)}.sbd-rroute__current{font-size:13px;color:var(--sbd-r-muted, #64748b)}.sbd-rroute__field{display:flex;flex-direction:column;gap:6px;min-width:0;font-size:12.5px;font-weight:600;color:var(--sbd-r-label, #475569)}.sbd-rroute__pair{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);gap:8px;align-items:end}.sbd-rroute__swap{width:32px;height:32px;margin-bottom:4px;border-radius:50%;border:1.5px solid var(--sbd-r-line, #e2e8f0);background:var(--sbd-r-surface, #fff);color:var(--sbd-r-ink, #1e2e4a);display:flex;align-items:center;justify-content:center;cursor:pointer;transition:background .15s,border-color .15s}.sbd-rroute__swap .pi{font-size:13px}.sbd-rroute__swap:hover{background:var(--sbd-r-soft, #f8fafc);border-color:var(--sbd-accent, #6d4aff)}.sbd-rroute__opt{display:flex;flex-direction:column;line-height:1.3;min-width:0}.sbd-rroute__opt b{font-size:13px;font-weight:600;color:var(--sbd-r-ink, #1e2e4a)}.sbd-rroute__opt small{font-size:11px;color:var(--sbd-r-muted, #64748b);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host ::ng-deep .sbd-rroute__select{font-size:13px;font-weight:400;color:var(--sbd-r-ink, #1e2e4a)}:host ::ng-deep .sbd-rroute__select .ng-select-container{min-height:40px;border-radius:10px;border:1.5px solid var(--sbd-r-line, #e2e8f0);background:var(--sbd-r-surface, #fff);color:var(--sbd-r-ink, #1e2e4a)}:host ::ng-deep .sbd-rroute__select .ng-value-container .ng-input>input{color:var(--sbd-r-ink, #1e2e4a)}:host ::ng-deep .sbd-rroute__select .ng-arrow-wrapper .ng-arrow{border-top-color:var(--sbd-r-muted, #64748b)}:host ::ng-deep .sbd-rroute__select.ng-select-focused:not(.ng-select-opened)>.ng-select-container{border-color:var(--sbd-accent, #6d4aff);box-shadow:none}:host ::ng-deep .sbd-rroute__select .ng-value-container .ng-value{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}:host ::ng-deep .sbd-rroute__select .ng-dropdown-panel{min-width:100%;z-index:1100;border-radius:10px;background:var(--sbd-r-surface, #fff);border-color:var(--sbd-r-line, #e2e8f0)}:host ::ng-deep .sbd-rroute__select .ng-dropdown-panel .ng-dropdown-panel-items{max-height:220px}:host ::ng-deep .sbd-rroute__select .ng-dropdown-panel .ng-option{padding:8px 12px;font-size:13px;white-space:normal;background:transparent;color:var(--sbd-r-ink, #1e2e4a)}:host ::ng-deep .sbd-rroute__select .ng-dropdown-panel .ng-option.ng-option-selected,:host ::ng-deep .sbd-rroute__select .ng-dropdown-panel .ng-option.ng-option-marked{background:var(--sbd-r-accent-soft, var(--sbd-accent-soft, #ede9fe))}\n"], dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: NgSelectModule }, { kind: "component", type: i5$1.NgSelectComponent, selector: "ng-select", inputs: ["bindLabel", "bindValue", "ariaLabel", "markFirst", "placeholder", "fixedPlaceholder", "notFoundText", "typeToSearchText", "preventToggleOnRightClick", "addTagText", "loadingText", "clearAllText", "appearance", "dropdownPosition", "appendTo", "loading", "closeOnSelect", "hideSelected", "selectOnTab", "openOnEnter", "maxSelectedItems", "groupBy", "groupValue", "bufferAmount", "virtualScroll", "selectableGroup", "selectableGroupAsModel", "searchFn", "trackByFn", "clearOnBackspace", "labelForId", "inputAttrs", "tabIndex", "readonly", "searchWhileComposing", "minTermLength", "editableSearchTerm", "ngClass", "typeahead", "multiple", "addTag", "searchable", "clearable", "isOpen", "items", "compareWith", "clearSearchOnAdd", "deselectOnClick", "keyDownFn"], outputs: ["blur", "focus", "change", "open", "close", "search", "clear", "add", "remove", "scroll", "scrollToEnd"] }, { kind: "directive", type: i5$1.NgOptionTemplateDirective, selector: "[ng-option-tmp]" }, { kind: "directive", type: i5$1.NgLabelTemplateDirective, selector: "[ng-label-tmp]" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
7981
8139
|
}
|
|
7982
8140
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SbdReissueRouteStepComponent, decorators: [{
|
|
7983
8141
|
type: Component,
|
|
@@ -8019,7 +8177,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
8019
8177
|
</div>
|
|
8020
8178
|
</div>
|
|
8021
8179
|
}
|
|
8022
|
-
`, host: { class: 'sbd-rroute' }, styles: [":host{display:flex;flex-direction:column;gap:12px}.sbd-rroute__card{border:1.5px solid #e2e8f0;border-radius:16px;background
|
|
8180
|
+
`, host: { class: 'sbd-rroute' }, styles: [":host{display:flex;flex-direction:column;gap:12px}.sbd-rroute__card{border:1.5px solid var(--sbd-r-line, #e2e8f0);border-radius:16px;background:var(--sbd-r-surface, #fff);transition:border-color .15s,box-shadow .15s;padding:16px;display:flex;flex-direction:column;gap:14px}.sbd-rroute__head{display:flex;flex-direction:column;gap:2px}.sbd-rroute__name{font-size:15px;font-weight:700;color:var(--sbd-r-ink, #1e2e4a)}.sbd-rroute__current{font-size:13px;color:var(--sbd-r-muted, #64748b)}.sbd-rroute__field{display:flex;flex-direction:column;gap:6px;min-width:0;font-size:12.5px;font-weight:600;color:var(--sbd-r-label, #475569)}.sbd-rroute__pair{display:grid;grid-template-columns:minmax(0,1fr) auto minmax(0,1fr);gap:8px;align-items:end}.sbd-rroute__swap{width:32px;height:32px;margin-bottom:4px;border-radius:50%;border:1.5px solid var(--sbd-r-line, #e2e8f0);background:var(--sbd-r-surface, #fff);color:var(--sbd-r-ink, #1e2e4a);display:flex;align-items:center;justify-content:center;cursor:pointer;transition:background .15s,border-color .15s}.sbd-rroute__swap .pi{font-size:13px}.sbd-rroute__swap:hover{background:var(--sbd-r-soft, #f8fafc);border-color:var(--sbd-accent, #6d4aff)}.sbd-rroute__opt{display:flex;flex-direction:column;line-height:1.3;min-width:0}.sbd-rroute__opt b{font-size:13px;font-weight:600;color:var(--sbd-r-ink, #1e2e4a)}.sbd-rroute__opt small{font-size:11px;color:var(--sbd-r-muted, #64748b);overflow:hidden;text-overflow:ellipsis;white-space:nowrap}:host ::ng-deep .sbd-rroute__select{font-size:13px;font-weight:400;color:var(--sbd-r-ink, #1e2e4a)}:host ::ng-deep .sbd-rroute__select .ng-select-container{min-height:40px;border-radius:10px;border:1.5px solid var(--sbd-r-line, #e2e8f0);background:var(--sbd-r-surface, #fff);color:var(--sbd-r-ink, #1e2e4a)}:host ::ng-deep .sbd-rroute__select .ng-value-container .ng-input>input{color:var(--sbd-r-ink, #1e2e4a)}:host ::ng-deep .sbd-rroute__select .ng-arrow-wrapper .ng-arrow{border-top-color:var(--sbd-r-muted, #64748b)}:host ::ng-deep .sbd-rroute__select.ng-select-focused:not(.ng-select-opened)>.ng-select-container{border-color:var(--sbd-accent, #6d4aff);box-shadow:none}:host ::ng-deep .sbd-rroute__select .ng-value-container .ng-value{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:100%}:host ::ng-deep .sbd-rroute__select .ng-dropdown-panel{min-width:100%;z-index:1100;border-radius:10px;background:var(--sbd-r-surface, #fff);border-color:var(--sbd-r-line, #e2e8f0)}:host ::ng-deep .sbd-rroute__select .ng-dropdown-panel .ng-dropdown-panel-items{max-height:220px}:host ::ng-deep .sbd-rroute__select .ng-dropdown-panel .ng-option{padding:8px 12px;font-size:13px;white-space:normal;background:transparent;color:var(--sbd-r-ink, #1e2e4a)}:host ::ng-deep .sbd-rroute__select .ng-dropdown-panel .ng-option.ng-option-selected,:host ::ng-deep .sbd-rroute__select .ng-dropdown-panel .ng-option.ng-option-marked{background:var(--sbd-r-accent-soft, var(--sbd-accent-soft, #ede9fe))}\n"] }]
|
|
8023
8181
|
}] });
|
|
8024
8182
|
|
|
8025
8183
|
/**
|
|
@@ -8122,7 +8280,7 @@ class SbdReissueDialogComponent {
|
|
|
8122
8280
|
}
|
|
8123
8281
|
}
|
|
8124
8282
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SbdReissueDialogComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8125
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SbdReissueDialogComponent, isStandalone: true, selector: "app-sbd-reissue-dialog", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, bookingId: { classPropertyName: "bookingId", publicName: "bookingId", isSignal: true, isRequired: false, transformFunction: null }, bookingData: { classPropertyName: "bookingData", publicName: "bookingData", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, providers: [SbdReissueStore, SbdReissueUpgradeStore], ngImport: i0, template: "<p-dialog [visible]=\"visible()\" (visibleChange)=\"$event ? null : closed.emit()\"\n [modal]=\"true\" [blockScroll]=\"true\" [draggable]=\"false\" [resizable]=\"false\"\n [showHeader]=\"false\" [style]=\"{ width: '560px', padding: '0' }\" styleClass=\"sbd-reissue-dialog-wrapper\">\n\n <div class=\"sbd-reissue\">\n\n <!-- Header: same layout as the cancel dialog (round close button, centered title + booking id) -->\n <div class=\"sbd-reissue__header\">\n <button type=\"button\" class=\"sbd-reissue__close\" (click)=\"closed.emit()\" aria-label=\"Close\">\n <i class=\"pi pi-times\"></i>\n </button>\n <div class=\"sbd-reissue__header-text\">\n <h3 class=\"sbd-reissue__title\">{{ title() }}</h3>\n <span class=\"sbd-reissue__sub\">Booking ID #{{ bookingId() }}</span>\n </div>\n </div>\n\n @if (store.loading()) {\n <div class=\"sbd-reissue__state\">\n <div class=\"sbd-reissue__state-icon\"><i class=\"pi pi-spin pi-spinner\"></i></div>\n <div class=\"sbd-reissue__state-text\">Checking availability\u2026</div>\n <div class=\"sbd-reissue__dots\"><span></span><span></span><span></span></div>\n </div>\n } @else if (store.error()) {\n <div class=\"sbd-reissue__state\">\n <div class=\"sbd-reissue__state-icon sbd-reissue__state-icon--warn\"><i class=\"pi pi-exclamation-triangle\"></i></div>\n <div class=\"sbd-reissue__state-text\">{{ store.error() }}</div>\n <button pButton type=\"button\" label=\"Retry\" class=\"p-button-outlined p-button-secondary\" (click)=\"store.load()\"></button>\n </div>\n } @else if (store.blocked()) {\n <!-- No leg can be reissued online: same idea as the cancel dialog's \"not eligible, escalate\" notice. -->\n <div class=\"sbd-reissue__body\">\n <app-sbd-reissue-notice tone=\"warn\" icon=\"pi pi-exclamation-triangle\">\n <strong>{{ store.blocked()?.title }}</strong><br>{{ store.blocked()?.text }}\n </app-sbd-reissue-notice>\n </div>\n <div class=\"sbd-reissue__footer\">\n <button pButton type=\"button\" label=\"Close\" class=\"p-button-outlined p-button-secondary sbd-reissue__btn\"\n (click)=\"closed.emit()\"></button>\n </div>\n } @else {\n <div class=\"sbd-reissue__body\">\n @switch (store.step()) {\n @case ('service') {\n <app-sbd-reissue-notice>Change requests are subject to availability from the airline.</app-sbd-reissue-notice>\n <app-sbd-reissue-service-step\n [upgradeAvailable]=\"store.upgradeAvailable()\"\n (chosen)=\"onServiceChosen($event)\" />\n }\n @case ('legs') {\n <app-sbd-reissue-legs-step\n [rows]=\"store.legRows()\"\n [anyAvailable]=\"store.anyAvailable()\"\n (toggled)=\"store.toggleLeg($event)\" />\n }\n @case ('edit') {\n @if (store.service() === 'change_date') {\n <app-sbd-reissue-date-step\n [rows]=\"store.dateRows()\"\n (changed)=\"store.setDate($event.legId, $event.date)\" />\n } @else {\n <app-sbd-reissue-route-step\n [rows]=\"store.routeRows()\"\n [options]=\"store.airportOptions()\"\n (airportChanged)=\"store.setAirport($event.legId, $event.side, $event.airport)\"\n (searched)=\"store.searchAirports($event)\"\n (swapped)=\"store.swapAirports($event)\" />\n }\n }\n @case ('upgrade-legs') {\n <app-sbd-reissue-legs-step\n unavailableText=\"None of these flights can be upgraded online. Handle this booking manually.\"\n [rows]=\"upgrade.legRows()\"\n [anyAvailable]=\"upgrade.anyLegUpgradable()\"\n [note]=\"store.allowSingleLegSelection() ? null : 'These flights must be upgraded together.'\"\n [error]=\"upgrade.error()\"\n (toggled)=\"upgrade.toggleLeg($event)\" />\n }\n @case ('upgrade') {\n <app-sbd-reissue-upgrade-step\n [sections]=\"upgrade.sections()\"\n [error]=\"upgrade.error()\"\n (picked)=\"upgrade.select($event.sectionId, $event.key)\" />\n }\n @case ('confirm') {\n <app-sbd-reissue-upgrade-confirm-step\n [rows]=\"upgrade.summary()\"\n [total]=\"upgrade.total()\"\n [totalLabel]=\"upgrade.totalLabel()\"\n [priceChanged]=\"upgrade.priceChanged()\"\n [booked]=\"upgrade.booked()\"\n [link]=\"upgrade.paymentLink()\"\n [error]=\"upgrade.error()\"\n (restart)=\"restartFlow()\" />\n }\n }\n </div>\n\n @if (hint(); as text) {\n <div class=\"sbd-reissue__hint\">{{ text }}</div>\n }\n\n @if (store.step() !== 'service') {\n <div class=\"sbd-reissue__footer\">\n <button pButton type=\"button\" label=\"Back\" class=\"p-button-outlined p-button-secondary sbd-reissue__btn\"\n [disabled]=\"store.step() === 'confirm' && upgrade.locked()\" (click)=\"onBack()\"></button>\n\n @switch (store.step()) {\n @case ('legs') {\n <button pButton type=\"button\" label=\"Continue\" class=\"sbd-reissue__btn\"\n [disabled]=\"!store.canContinue()\" (click)=\"store.goToEdit()\"></button>\n }\n @case ('edit') {\n <button pButton type=\"button\" icon=\"pi pi-search\" label=\"Search flights\" class=\"sbd-reissue__btn\"\n [disabled]=\"!!store.validationError()\" (click)=\"searchFlights()\"></button>\n }\n @case ('upgrade-legs') {\n <button pButton type=\"button\" label=\"Continue\" class=\"sbd-reissue__btn\" [loading]=\"upgrade.submitting()\"\n [disabled]=\"!upgrade.canContinueFromLegs()\" (click)=\"upgrade.continueFromLegs()\"></button>\n }\n @case ('upgrade') {\n <button pButton type=\"button\" label=\"Continue\" class=\"sbd-reissue__btn\" [loading]=\"upgrade.submitting()\"\n [disabled]=\"!upgrade.canContinue()\" (click)=\"upgrade.continue()\"></button>\n }\n @case ('confirm') {\n @switch (upgrade.action()) {\n @case ('done') {\n <button pButton type=\"button\" label=\"Close\" class=\"sbd-reissue__btn\" (click)=\"closed.emit()\"></button>\n }\n @case ('book') {\n <button pButton type=\"button\" label=\"Confirm upgrade\" class=\"sbd-reissue__btn\"\n [loading]=\"upgrade.submitting()\" (click)=\"upgrade.confirm()\"></button>\n }\n @case ('link') {\n <button pButton type=\"button\" icon=\"pi pi-link\" label=\"Generate payment link\" class=\"sbd-reissue__btn\"\n [loading]=\"upgrade.submitting()\" (click)=\"upgrade.confirm()\"></button>\n }\n }\n }\n }\n </div>\n }\n }\n </div>\n</p-dialog>\n", styles: [":host ::ng-deep .sbd-reissue-dialog-wrapper{border-radius:16px;box-shadow:0 24px 60px #0f172a38}:host ::ng-deep .sbd-reissue-dialog-wrapper .p-dialog-content{padding:0;border-radius:16px;overflow:visible}.sbd-reissue{font-family:inherit;position:relative}.sbd-reissue__header{display:flex;align-items:flex-start;gap:12px;padding:20px 20px 0}.sbd-reissue__close{flex-shrink:0;width:32px;height:32px;border-radius:50%;background:#f8fafc;border:none;color:#1e2e4a;display:flex;align-items:center;justify-content:center;cursor:pointer}.sbd-reissue__close .pi{font-size:13px}.sbd-reissue__close:hover{background:#e2e8f0}.sbd-reissue__header-text{flex:1;display:flex;flex-direction:column;align-items:center;gap:4px;text-align:center;margin-right:32px}.sbd-reissue__title{font-size:19px;font-weight:800;color:#1e2e4a;margin:0}.sbd-reissue__sub{font-size:12.5px;color:#94a3b8}.sbd-reissue__body{padding:16px 20px 20px;display:flex;flex-direction:column;gap:12px}.sbd-reissue__hint{text-align:center;padding:0 20px 12px;font-size:13px;color:#94a3b8}.sbd-reissue__footer{display:flex;justify-content:flex-end;gap:10px;align-items:stretch;padding:14px 20px;border-top:1px solid #e2e8f0;background:#fff;border-radius:0 0 16px 16px}.sbd-reissue__btn{flex:1 1 0;justify-content:center}.sbd-reissue__state{padding:36px 24px 28px;display:flex;flex-direction:column;align-items:center;gap:14px;text-align:center}.sbd-reissue__state-icon{width:56px;height:56px;border-radius:50%;background:#fff7ed;border:2px solid #fed7aa;display:flex;align-items:center;justify-content:center}.sbd-reissue__state-icon .pi{font-size:24px;color:#f97316}.sbd-reissue__state-icon--warn{background:#fef2f2;border-color:#fecaca}.sbd-reissue__state-icon--warn .pi{color:#ef4444}.sbd-reissue__state-text{font-size:13px;color:#64748b;min-height:20px}.sbd-reissue__dots{display:flex;gap:6px}.sbd-reissue__dots span{width:7px;height:7px;border-radius:50%;background:#f97316;opacity:.3;animation:sbd-reissue-dot 1.2s ease-in-out infinite}.sbd-reissue__dots span:nth-child(2){animation-delay:.2s}.sbd-reissue__dots span:nth-child(3){animation-delay:.4s}@keyframes sbd-reissue-dot{0%,to{opacity:.3;transform:scale(1)}50%{opacity:1;transform:scale(1.4)}}\n"], dependencies: [{ kind: "ngmodule", type: DialogModule }, { kind: "component", type: i1$1.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "visible", "style", "position"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2$1.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading"] }, { kind: "component", type: SbdReissueNoticeComponent, selector: "app-sbd-reissue-notice", inputs: ["icon", "tone"] }, { kind: "component", type: SbdReissueServiceStepComponent, selector: "app-sbd-reissue-service-step", inputs: ["upgradeAvailable"], outputs: ["chosen"] }, { kind: "component", type: SbdReissueLegsStepComponent, selector: "app-sbd-reissue-legs-step", inputs: ["rows", "anyAvailable", "unavailableText", "note", "error"], outputs: ["toggled"] }, { kind: "component", type: SbdReissueDateStepComponent, selector: "app-sbd-reissue-date-step", inputs: ["rows"], outputs: ["changed"] }, { kind: "component", type: SbdReissueRouteStepComponent, selector: "app-sbd-reissue-route-step", inputs: ["rows", "options"], outputs: ["airportChanged", "searched", "swapped"] }, { kind: "component", type: SbdReissueUpgradeStepComponent, selector: "app-sbd-reissue-upgrade-step", inputs: ["sections", "error"], outputs: ["picked"] }, { kind: "component", type: SbdReissueUpgradeConfirmStepComponent, selector: "app-sbd-reissue-upgrade-confirm-step", inputs: ["rows", "total", "totalLabel", "priceChanged", "booked", "link", "error"], outputs: ["restart"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
8283
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SbdReissueDialogComponent, isStandalone: true, selector: "app-sbd-reissue-dialog", inputs: { visible: { classPropertyName: "visible", publicName: "visible", isSignal: true, isRequired: false, transformFunction: null }, bookingId: { classPropertyName: "bookingId", publicName: "bookingId", isSignal: true, isRequired: false, transformFunction: null }, bookingData: { classPropertyName: "bookingData", publicName: "bookingData", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { closed: "closed" }, providers: [SbdReissueStore, SbdReissueUpgradeStore], ngImport: i0, template: "<p-dialog [visible]=\"visible()\" (visibleChange)=\"$event ? null : closed.emit()\"\n [modal]=\"true\" [blockScroll]=\"true\" [draggable]=\"false\" [resizable]=\"false\"\n [showHeader]=\"false\" [style]=\"{ width: '560px', padding: '0' }\" styleClass=\"sbd-reissue-dialog-wrapper\">\n\n <div class=\"sbd-reissue\">\n\n <!-- Header: same layout as the cancel dialog (round close button, centered title + booking id) -->\n <div class=\"sbd-reissue__header\">\n <button type=\"button\" class=\"sbd-reissue__close\" (click)=\"closed.emit()\" aria-label=\"Close\">\n <i class=\"pi pi-times\"></i>\n </button>\n <div class=\"sbd-reissue__header-text\">\n <h3 class=\"sbd-reissue__title\">{{ title() }}</h3>\n <span class=\"sbd-reissue__sub\">Booking ID #{{ bookingId() }}</span>\n </div>\n </div>\n\n @if (store.loading()) {\n <div class=\"sbd-reissue__state\">\n <div class=\"sbd-reissue__state-icon\"><i class=\"pi pi-spin pi-spinner\"></i></div>\n <div class=\"sbd-reissue__state-text\">Checking availability\u2026</div>\n <div class=\"sbd-reissue__dots\"><span></span><span></span><span></span></div>\n </div>\n } @else if (store.error()) {\n <div class=\"sbd-reissue__state\">\n <div class=\"sbd-reissue__state-icon sbd-reissue__state-icon--warn\"><i class=\"pi pi-exclamation-triangle\"></i></div>\n <div class=\"sbd-reissue__state-text\">{{ store.error() }}</div>\n <button pButton type=\"button\" label=\"Retry\" class=\"p-button-outlined p-button-secondary\" (click)=\"store.load()\"></button>\n </div>\n } @else if (store.blocked()) {\n <!-- No leg can be reissued online: same idea as the cancel dialog's \"not eligible, escalate\" notice. -->\n <div class=\"sbd-reissue__body\">\n <app-sbd-reissue-notice tone=\"warn\" icon=\"pi pi-exclamation-triangle\">\n <strong>{{ store.blocked()?.title }}</strong><br>{{ store.blocked()?.text }}\n </app-sbd-reissue-notice>\n </div>\n <div class=\"sbd-reissue__footer\">\n <button pButton type=\"button\" label=\"Close\" class=\"p-button-outlined p-button-secondary sbd-reissue__btn\"\n (click)=\"closed.emit()\"></button>\n </div>\n } @else {\n <div class=\"sbd-reissue__body\">\n @switch (store.step()) {\n @case ('service') {\n <app-sbd-reissue-notice>Change requests are subject to availability from the airline.</app-sbd-reissue-notice>\n <app-sbd-reissue-service-step\n [upgradeAvailable]=\"store.upgradeAvailable()\"\n (chosen)=\"onServiceChosen($event)\" />\n }\n @case ('legs') {\n <app-sbd-reissue-legs-step\n [rows]=\"store.legRows()\"\n [anyAvailable]=\"store.anyAvailable()\"\n (toggled)=\"store.toggleLeg($event)\" />\n }\n @case ('edit') {\n @if (store.service() === 'change_date') {\n <app-sbd-reissue-date-step\n [rows]=\"store.dateRows()\"\n (changed)=\"store.setDate($event.legId, $event.date)\" />\n } @else {\n <app-sbd-reissue-route-step\n [rows]=\"store.routeRows()\"\n [options]=\"store.airportOptions()\"\n (airportChanged)=\"store.setAirport($event.legId, $event.side, $event.airport)\"\n (searched)=\"store.searchAirports($event)\"\n (swapped)=\"store.swapAirports($event)\" />\n }\n }\n @case ('upgrade-legs') {\n <app-sbd-reissue-legs-step\n unavailableText=\"None of these flights can be upgraded online. Handle this booking manually.\"\n [rows]=\"upgrade.legRows()\"\n [anyAvailable]=\"upgrade.anyLegUpgradable()\"\n [note]=\"store.allowSingleLegSelection() ? null : 'These flights must be upgraded together.'\"\n [error]=\"upgrade.error()\"\n (toggled)=\"upgrade.toggleLeg($event)\" />\n }\n @case ('upgrade') {\n <app-sbd-reissue-upgrade-step\n [sections]=\"upgrade.sections()\"\n [error]=\"upgrade.error()\"\n (picked)=\"upgrade.select($event.sectionId, $event.key)\" />\n }\n @case ('confirm') {\n <app-sbd-reissue-upgrade-confirm-step\n [rows]=\"upgrade.summary()\"\n [total]=\"upgrade.total()\"\n [totalLabel]=\"upgrade.totalLabel()\"\n [priceChanged]=\"upgrade.priceChanged()\"\n [booked]=\"upgrade.booked()\"\n [link]=\"upgrade.paymentLink()\"\n [error]=\"upgrade.error()\"\n (restart)=\"restartFlow()\" />\n }\n }\n </div>\n\n @if (hint(); as text) {\n <div class=\"sbd-reissue__hint\">{{ text }}</div>\n }\n\n @if (store.step() !== 'service') {\n <div class=\"sbd-reissue__footer\">\n <button pButton type=\"button\" label=\"Back\" class=\"p-button-outlined p-button-secondary sbd-reissue__btn\"\n [disabled]=\"store.step() === 'confirm' && upgrade.locked()\" (click)=\"onBack()\"></button>\n\n @switch (store.step()) {\n @case ('legs') {\n <button pButton type=\"button\" label=\"Continue\" class=\"sbd-reissue__btn\"\n [disabled]=\"!store.canContinue()\" (click)=\"store.goToEdit()\"></button>\n }\n @case ('edit') {\n <button pButton type=\"button\" icon=\"pi pi-search\" label=\"Search flights\" class=\"sbd-reissue__btn\"\n [disabled]=\"!!store.validationError()\" (click)=\"searchFlights()\"></button>\n }\n @case ('upgrade-legs') {\n <button pButton type=\"button\" label=\"Continue\" class=\"sbd-reissue__btn\" [loading]=\"upgrade.submitting()\"\n [disabled]=\"!upgrade.canContinueFromLegs()\" (click)=\"upgrade.continueFromLegs()\"></button>\n }\n @case ('upgrade') {\n <button pButton type=\"button\" label=\"Continue\" class=\"sbd-reissue__btn\" [loading]=\"upgrade.submitting()\"\n [disabled]=\"!upgrade.canContinue()\" (click)=\"upgrade.continue()\"></button>\n }\n @case ('confirm') {\n @switch (upgrade.action()) {\n @case ('done') {\n <button pButton type=\"button\" label=\"Close\" class=\"sbd-reissue__btn\" (click)=\"closed.emit()\"></button>\n }\n @case ('book') {\n <button pButton type=\"button\" label=\"Confirm upgrade\" class=\"sbd-reissue__btn\"\n [loading]=\"upgrade.submitting()\" (click)=\"upgrade.confirm()\"></button>\n }\n @case ('link') {\n <button pButton type=\"button\" icon=\"pi pi-link\" label=\"Generate payment link\" class=\"sbd-reissue__btn\"\n [loading]=\"upgrade.submitting()\" (click)=\"upgrade.confirm()\"></button>\n }\n }\n }\n }\n </div>\n }\n }\n </div>\n</p-dialog>\n", styles: [":host ::ng-deep .sbd-reissue-dialog-wrapper{border-radius:16px;box-shadow:0 24px 60px #0f172a38}:host ::ng-deep .sbd-reissue-dialog-wrapper .p-dialog-content{padding:0;border-radius:16px;overflow:visible}.sbd-reissue{font-family:inherit;background:var(--sbd-r-bg, transparent);border-radius:16px;color-scheme:light;position:relative}.sbd-reissue__header{display:flex;align-items:flex-start;gap:12px;padding:20px 20px 0}.sbd-reissue__close{flex-shrink:0;width:32px;height:32px;border-radius:50%;background:var(--sbd-r-soft, #f8fafc);border:none;color:var(--sbd-r-ink, #1e2e4a);display:flex;align-items:center;justify-content:center;cursor:pointer}.sbd-reissue__close .pi{font-size:13px}.sbd-reissue__close:hover{background:var(--sbd-r-line, #e2e8f0)}.sbd-reissue__header-text{flex:1;display:flex;flex-direction:column;align-items:center;gap:4px;text-align:center;margin-right:32px}.sbd-reissue__title{font-size:19px;font-weight:800;color:var(--sbd-r-ink, #1e2e4a);margin:0}.sbd-reissue__sub{font-size:12.5px;color:var(--sbd-r-faint, #94a3b8)}.sbd-reissue__body{padding:16px 20px 20px;display:flex;flex-direction:column;gap:12px}.sbd-reissue__hint{text-align:center;padding:0 20px 12px;font-size:13px;color:var(--sbd-r-faint, #94a3b8)}.sbd-reissue__footer{display:flex;justify-content:flex-end;gap:10px;align-items:stretch;padding:14px 20px;border-top:1px solid var(--sbd-r-line, #e2e8f0);background:var(--sbd-r-surface, #fff);border-radius:0 0 16px 16px}.sbd-reissue__btn{flex:1 1 0;justify-content:center}.sbd-reissue__state{padding:36px 24px 28px;display:flex;flex-direction:column;align-items:center;gap:14px;text-align:center}.sbd-reissue__state-icon{width:56px;height:56px;border-radius:50%;background:var(--sbd-r-state-bg, #fff7ed);border:2px solid var(--sbd-r-state-line, #fed7aa);display:flex;align-items:center;justify-content:center}.sbd-reissue__state-icon .pi{font-size:24px;color:#f97316}.sbd-reissue__state-icon--warn{background:var(--sbd-r-state-warn-bg, #fef2f2);border-color:var(--sbd-r-state-warn-line, #fecaca)}.sbd-reissue__state-icon--warn .pi{color:#ef4444}.sbd-reissue__state-text{font-size:13px;color:var(--sbd-r-muted, #64748b);min-height:20px}.sbd-reissue__dots{display:flex;gap:6px}.sbd-reissue__dots span{width:7px;height:7px;border-radius:50%;background:#f97316;opacity:.3;animation:sbd-reissue-dot 1.2s ease-in-out infinite}.sbd-reissue__dots span:nth-child(2){animation-delay:.2s}.sbd-reissue__dots span:nth-child(3){animation-delay:.4s}@keyframes sbd-reissue-dot{0%,to{opacity:.3;transform:scale(1)}50%{opacity:1;transform:scale(1.4)}}:host-context(.dark) .sbd-reissue,:host-context([data-theme=dark]) .sbd-reissue{--sbd-r-bg: #18181b;--sbd-r-surface: #1f1f23;--sbd-r-soft: #27272a;--sbd-r-sunk: #2f2f34;--sbd-r-ink: #f4f4f5;--sbd-r-muted: #a1a1aa;--sbd-r-faint: #8b8b94;--sbd-r-line: #3f3f46;--sbd-r-line-strong: #52525b;--sbd-r-label: #d4d4d8;--sbd-r-input-text: #e4e4e7;--sbd-r-info-bg: #172554;--sbd-r-info-line: #1e3a8a;--sbd-r-info-text: #93c5fd;--sbd-r-warn-bg: #3a2a0e;--sbd-r-warn-line: #6b4a16;--sbd-r-warn-text: #fcd34d;--sbd-r-warn-icon: #f59e0b;--sbd-r-error-bg: #3a1517;--sbd-r-error-line: #7f1d1d;--sbd-r-error-text: #fca5a5;--sbd-r-success-bg: #0f2a1a;--sbd-r-success-line: #166534;--sbd-r-success-text: #86efac;--sbd-r-state-bg: #3a2410;--sbd-r-state-line: #7c3a10;--sbd-r-state-warn-bg: #3a1517;--sbd-r-state-warn-line: #7f1d1d;--sbd-r-green: #4ade80;--sbd-r-expiry-soon: #fbbf24;--sbd-r-accent-soft: color-mix(in srgb, var(--sbd-accent, #6d4aff) 28%, transparent);color-scheme:dark}\n"], dependencies: [{ kind: "ngmodule", type: DialogModule }, { kind: "component", type: i1$1.Dialog, selector: "p-dialog", inputs: ["header", "draggable", "resizable", "positionLeft", "positionTop", "contentStyle", "contentStyleClass", "modal", "closeOnEscape", "dismissableMask", "rtl", "closable", "responsive", "appendTo", "breakpoints", "styleClass", "maskStyleClass", "showHeader", "breakpoint", "blockScroll", "autoZIndex", "baseZIndex", "minX", "minY", "focusOnShow", "maximizable", "keepInViewport", "focusTrap", "transitionOptions", "closeIcon", "closeAriaLabel", "closeTabindex", "minimizeIcon", "maximizeIcon", "visible", "style", "position"], outputs: ["onShow", "onHide", "visibleChange", "onResizeInit", "onResizeEnd", "onDragEnd", "onMaximize"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2$1.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading"] }, { kind: "component", type: SbdReissueNoticeComponent, selector: "app-sbd-reissue-notice", inputs: ["icon", "tone"] }, { kind: "component", type: SbdReissueServiceStepComponent, selector: "app-sbd-reissue-service-step", inputs: ["upgradeAvailable"], outputs: ["chosen"] }, { kind: "component", type: SbdReissueLegsStepComponent, selector: "app-sbd-reissue-legs-step", inputs: ["rows", "anyAvailable", "unavailableText", "note", "error"], outputs: ["toggled"] }, { kind: "component", type: SbdReissueDateStepComponent, selector: "app-sbd-reissue-date-step", inputs: ["rows"], outputs: ["changed"] }, { kind: "component", type: SbdReissueRouteStepComponent, selector: "app-sbd-reissue-route-step", inputs: ["rows", "options"], outputs: ["airportChanged", "searched", "swapped"] }, { kind: "component", type: SbdReissueUpgradeStepComponent, selector: "app-sbd-reissue-upgrade-step", inputs: ["sections", "error"], outputs: ["picked"] }, { kind: "component", type: SbdReissueUpgradeConfirmStepComponent, selector: "app-sbd-reissue-upgrade-confirm-step", inputs: ["rows", "total", "totalLabel", "priceChanged", "booked", "link", "error"], outputs: ["restart"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
8126
8284
|
}
|
|
8127
8285
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SbdReissueDialogComponent, decorators: [{
|
|
8128
8286
|
type: Component,
|
|
@@ -8136,7 +8294,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
8136
8294
|
SbdReissueRouteStepComponent,
|
|
8137
8295
|
SbdReissueUpgradeStepComponent,
|
|
8138
8296
|
SbdReissueUpgradeConfirmStepComponent,
|
|
8139
|
-
], providers: [SbdReissueStore, SbdReissueUpgradeStore], changeDetection: ChangeDetectionStrategy.OnPush, template: "<p-dialog [visible]=\"visible()\" (visibleChange)=\"$event ? null : closed.emit()\"\n [modal]=\"true\" [blockScroll]=\"true\" [draggable]=\"false\" [resizable]=\"false\"\n [showHeader]=\"false\" [style]=\"{ width: '560px', padding: '0' }\" styleClass=\"sbd-reissue-dialog-wrapper\">\n\n <div class=\"sbd-reissue\">\n\n <!-- Header: same layout as the cancel dialog (round close button, centered title + booking id) -->\n <div class=\"sbd-reissue__header\">\n <button type=\"button\" class=\"sbd-reissue__close\" (click)=\"closed.emit()\" aria-label=\"Close\">\n <i class=\"pi pi-times\"></i>\n </button>\n <div class=\"sbd-reissue__header-text\">\n <h3 class=\"sbd-reissue__title\">{{ title() }}</h3>\n <span class=\"sbd-reissue__sub\">Booking ID #{{ bookingId() }}</span>\n </div>\n </div>\n\n @if (store.loading()) {\n <div class=\"sbd-reissue__state\">\n <div class=\"sbd-reissue__state-icon\"><i class=\"pi pi-spin pi-spinner\"></i></div>\n <div class=\"sbd-reissue__state-text\">Checking availability\u2026</div>\n <div class=\"sbd-reissue__dots\"><span></span><span></span><span></span></div>\n </div>\n } @else if (store.error()) {\n <div class=\"sbd-reissue__state\">\n <div class=\"sbd-reissue__state-icon sbd-reissue__state-icon--warn\"><i class=\"pi pi-exclamation-triangle\"></i></div>\n <div class=\"sbd-reissue__state-text\">{{ store.error() }}</div>\n <button pButton type=\"button\" label=\"Retry\" class=\"p-button-outlined p-button-secondary\" (click)=\"store.load()\"></button>\n </div>\n } @else if (store.blocked()) {\n <!-- No leg can be reissued online: same idea as the cancel dialog's \"not eligible, escalate\" notice. -->\n <div class=\"sbd-reissue__body\">\n <app-sbd-reissue-notice tone=\"warn\" icon=\"pi pi-exclamation-triangle\">\n <strong>{{ store.blocked()?.title }}</strong><br>{{ store.blocked()?.text }}\n </app-sbd-reissue-notice>\n </div>\n <div class=\"sbd-reissue__footer\">\n <button pButton type=\"button\" label=\"Close\" class=\"p-button-outlined p-button-secondary sbd-reissue__btn\"\n (click)=\"closed.emit()\"></button>\n </div>\n } @else {\n <div class=\"sbd-reissue__body\">\n @switch (store.step()) {\n @case ('service') {\n <app-sbd-reissue-notice>Change requests are subject to availability from the airline.</app-sbd-reissue-notice>\n <app-sbd-reissue-service-step\n [upgradeAvailable]=\"store.upgradeAvailable()\"\n (chosen)=\"onServiceChosen($event)\" />\n }\n @case ('legs') {\n <app-sbd-reissue-legs-step\n [rows]=\"store.legRows()\"\n [anyAvailable]=\"store.anyAvailable()\"\n (toggled)=\"store.toggleLeg($event)\" />\n }\n @case ('edit') {\n @if (store.service() === 'change_date') {\n <app-sbd-reissue-date-step\n [rows]=\"store.dateRows()\"\n (changed)=\"store.setDate($event.legId, $event.date)\" />\n } @else {\n <app-sbd-reissue-route-step\n [rows]=\"store.routeRows()\"\n [options]=\"store.airportOptions()\"\n (airportChanged)=\"store.setAirport($event.legId, $event.side, $event.airport)\"\n (searched)=\"store.searchAirports($event)\"\n (swapped)=\"store.swapAirports($event)\" />\n }\n }\n @case ('upgrade-legs') {\n <app-sbd-reissue-legs-step\n unavailableText=\"None of these flights can be upgraded online. Handle this booking manually.\"\n [rows]=\"upgrade.legRows()\"\n [anyAvailable]=\"upgrade.anyLegUpgradable()\"\n [note]=\"store.allowSingleLegSelection() ? null : 'These flights must be upgraded together.'\"\n [error]=\"upgrade.error()\"\n (toggled)=\"upgrade.toggleLeg($event)\" />\n }\n @case ('upgrade') {\n <app-sbd-reissue-upgrade-step\n [sections]=\"upgrade.sections()\"\n [error]=\"upgrade.error()\"\n (picked)=\"upgrade.select($event.sectionId, $event.key)\" />\n }\n @case ('confirm') {\n <app-sbd-reissue-upgrade-confirm-step\n [rows]=\"upgrade.summary()\"\n [total]=\"upgrade.total()\"\n [totalLabel]=\"upgrade.totalLabel()\"\n [priceChanged]=\"upgrade.priceChanged()\"\n [booked]=\"upgrade.booked()\"\n [link]=\"upgrade.paymentLink()\"\n [error]=\"upgrade.error()\"\n (restart)=\"restartFlow()\" />\n }\n }\n </div>\n\n @if (hint(); as text) {\n <div class=\"sbd-reissue__hint\">{{ text }}</div>\n }\n\n @if (store.step() !== 'service') {\n <div class=\"sbd-reissue__footer\">\n <button pButton type=\"button\" label=\"Back\" class=\"p-button-outlined p-button-secondary sbd-reissue__btn\"\n [disabled]=\"store.step() === 'confirm' && upgrade.locked()\" (click)=\"onBack()\"></button>\n\n @switch (store.step()) {\n @case ('legs') {\n <button pButton type=\"button\" label=\"Continue\" class=\"sbd-reissue__btn\"\n [disabled]=\"!store.canContinue()\" (click)=\"store.goToEdit()\"></button>\n }\n @case ('edit') {\n <button pButton type=\"button\" icon=\"pi pi-search\" label=\"Search flights\" class=\"sbd-reissue__btn\"\n [disabled]=\"!!store.validationError()\" (click)=\"searchFlights()\"></button>\n }\n @case ('upgrade-legs') {\n <button pButton type=\"button\" label=\"Continue\" class=\"sbd-reissue__btn\" [loading]=\"upgrade.submitting()\"\n [disabled]=\"!upgrade.canContinueFromLegs()\" (click)=\"upgrade.continueFromLegs()\"></button>\n }\n @case ('upgrade') {\n <button pButton type=\"button\" label=\"Continue\" class=\"sbd-reissue__btn\" [loading]=\"upgrade.submitting()\"\n [disabled]=\"!upgrade.canContinue()\" (click)=\"upgrade.continue()\"></button>\n }\n @case ('confirm') {\n @switch (upgrade.action()) {\n @case ('done') {\n <button pButton type=\"button\" label=\"Close\" class=\"sbd-reissue__btn\" (click)=\"closed.emit()\"></button>\n }\n @case ('book') {\n <button pButton type=\"button\" label=\"Confirm upgrade\" class=\"sbd-reissue__btn\"\n [loading]=\"upgrade.submitting()\" (click)=\"upgrade.confirm()\"></button>\n }\n @case ('link') {\n <button pButton type=\"button\" icon=\"pi pi-link\" label=\"Generate payment link\" class=\"sbd-reissue__btn\"\n [loading]=\"upgrade.submitting()\" (click)=\"upgrade.confirm()\"></button>\n }\n }\n }\n }\n </div>\n }\n }\n </div>\n</p-dialog>\n", styles: [":host ::ng-deep .sbd-reissue-dialog-wrapper{border-radius:16px;box-shadow:0 24px 60px #0f172a38}:host ::ng-deep .sbd-reissue-dialog-wrapper .p-dialog-content{padding:0;border-radius:16px;overflow:visible}.sbd-reissue{font-family:inherit;position:relative}.sbd-reissue__header{display:flex;align-items:flex-start;gap:12px;padding:20px 20px 0}.sbd-reissue__close{flex-shrink:0;width:32px;height:32px;border-radius:50%;background:#f8fafc;border:none;color:#1e2e4a;display:flex;align-items:center;justify-content:center;cursor:pointer}.sbd-reissue__close .pi{font-size:13px}.sbd-reissue__close:hover{background:#e2e8f0}.sbd-reissue__header-text{flex:1;display:flex;flex-direction:column;align-items:center;gap:4px;text-align:center;margin-right:32px}.sbd-reissue__title{font-size:19px;font-weight:800;color:#1e2e4a;margin:0}.sbd-reissue__sub{font-size:12.5px;color:#94a3b8}.sbd-reissue__body{padding:16px 20px 20px;display:flex;flex-direction:column;gap:12px}.sbd-reissue__hint{text-align:center;padding:0 20px 12px;font-size:13px;color:#94a3b8}.sbd-reissue__footer{display:flex;justify-content:flex-end;gap:10px;align-items:stretch;padding:14px 20px;border-top:1px solid #e2e8f0;background:#fff;border-radius:0 0 16px 16px}.sbd-reissue__btn{flex:1 1 0;justify-content:center}.sbd-reissue__state{padding:36px 24px 28px;display:flex;flex-direction:column;align-items:center;gap:14px;text-align:center}.sbd-reissue__state-icon{width:56px;height:56px;border-radius:50%;background:#fff7ed;border:2px solid #fed7aa;display:flex;align-items:center;justify-content:center}.sbd-reissue__state-icon .pi{font-size:24px;color:#f97316}.sbd-reissue__state-icon--warn{background:#fef2f2;border-color:#fecaca}.sbd-reissue__state-icon--warn .pi{color:#ef4444}.sbd-reissue__state-text{font-size:13px;color:#64748b;min-height:20px}.sbd-reissue__dots{display:flex;gap:6px}.sbd-reissue__dots span{width:7px;height:7px;border-radius:50%;background:#f97316;opacity:.3;animation:sbd-reissue-dot 1.2s ease-in-out infinite}.sbd-reissue__dots span:nth-child(2){animation-delay:.2s}.sbd-reissue__dots span:nth-child(3){animation-delay:.4s}@keyframes sbd-reissue-dot{0%,to{opacity:.3;transform:scale(1)}50%{opacity:1;transform:scale(1.4)}}\n"] }]
|
|
8297
|
+
], providers: [SbdReissueStore, SbdReissueUpgradeStore], changeDetection: ChangeDetectionStrategy.OnPush, template: "<p-dialog [visible]=\"visible()\" (visibleChange)=\"$event ? null : closed.emit()\"\n [modal]=\"true\" [blockScroll]=\"true\" [draggable]=\"false\" [resizable]=\"false\"\n [showHeader]=\"false\" [style]=\"{ width: '560px', padding: '0' }\" styleClass=\"sbd-reissue-dialog-wrapper\">\n\n <div class=\"sbd-reissue\">\n\n <!-- Header: same layout as the cancel dialog (round close button, centered title + booking id) -->\n <div class=\"sbd-reissue__header\">\n <button type=\"button\" class=\"sbd-reissue__close\" (click)=\"closed.emit()\" aria-label=\"Close\">\n <i class=\"pi pi-times\"></i>\n </button>\n <div class=\"sbd-reissue__header-text\">\n <h3 class=\"sbd-reissue__title\">{{ title() }}</h3>\n <span class=\"sbd-reissue__sub\">Booking ID #{{ bookingId() }}</span>\n </div>\n </div>\n\n @if (store.loading()) {\n <div class=\"sbd-reissue__state\">\n <div class=\"sbd-reissue__state-icon\"><i class=\"pi pi-spin pi-spinner\"></i></div>\n <div class=\"sbd-reissue__state-text\">Checking availability\u2026</div>\n <div class=\"sbd-reissue__dots\"><span></span><span></span><span></span></div>\n </div>\n } @else if (store.error()) {\n <div class=\"sbd-reissue__state\">\n <div class=\"sbd-reissue__state-icon sbd-reissue__state-icon--warn\"><i class=\"pi pi-exclamation-triangle\"></i></div>\n <div class=\"sbd-reissue__state-text\">{{ store.error() }}</div>\n <button pButton type=\"button\" label=\"Retry\" class=\"p-button-outlined p-button-secondary\" (click)=\"store.load()\"></button>\n </div>\n } @else if (store.blocked()) {\n <!-- No leg can be reissued online: same idea as the cancel dialog's \"not eligible, escalate\" notice. -->\n <div class=\"sbd-reissue__body\">\n <app-sbd-reissue-notice tone=\"warn\" icon=\"pi pi-exclamation-triangle\">\n <strong>{{ store.blocked()?.title }}</strong><br>{{ store.blocked()?.text }}\n </app-sbd-reissue-notice>\n </div>\n <div class=\"sbd-reissue__footer\">\n <button pButton type=\"button\" label=\"Close\" class=\"p-button-outlined p-button-secondary sbd-reissue__btn\"\n (click)=\"closed.emit()\"></button>\n </div>\n } @else {\n <div class=\"sbd-reissue__body\">\n @switch (store.step()) {\n @case ('service') {\n <app-sbd-reissue-notice>Change requests are subject to availability from the airline.</app-sbd-reissue-notice>\n <app-sbd-reissue-service-step\n [upgradeAvailable]=\"store.upgradeAvailable()\"\n (chosen)=\"onServiceChosen($event)\" />\n }\n @case ('legs') {\n <app-sbd-reissue-legs-step\n [rows]=\"store.legRows()\"\n [anyAvailable]=\"store.anyAvailable()\"\n (toggled)=\"store.toggleLeg($event)\" />\n }\n @case ('edit') {\n @if (store.service() === 'change_date') {\n <app-sbd-reissue-date-step\n [rows]=\"store.dateRows()\"\n (changed)=\"store.setDate($event.legId, $event.date)\" />\n } @else {\n <app-sbd-reissue-route-step\n [rows]=\"store.routeRows()\"\n [options]=\"store.airportOptions()\"\n (airportChanged)=\"store.setAirport($event.legId, $event.side, $event.airport)\"\n (searched)=\"store.searchAirports($event)\"\n (swapped)=\"store.swapAirports($event)\" />\n }\n }\n @case ('upgrade-legs') {\n <app-sbd-reissue-legs-step\n unavailableText=\"None of these flights can be upgraded online. Handle this booking manually.\"\n [rows]=\"upgrade.legRows()\"\n [anyAvailable]=\"upgrade.anyLegUpgradable()\"\n [note]=\"store.allowSingleLegSelection() ? null : 'These flights must be upgraded together.'\"\n [error]=\"upgrade.error()\"\n (toggled)=\"upgrade.toggleLeg($event)\" />\n }\n @case ('upgrade') {\n <app-sbd-reissue-upgrade-step\n [sections]=\"upgrade.sections()\"\n [error]=\"upgrade.error()\"\n (picked)=\"upgrade.select($event.sectionId, $event.key)\" />\n }\n @case ('confirm') {\n <app-sbd-reissue-upgrade-confirm-step\n [rows]=\"upgrade.summary()\"\n [total]=\"upgrade.total()\"\n [totalLabel]=\"upgrade.totalLabel()\"\n [priceChanged]=\"upgrade.priceChanged()\"\n [booked]=\"upgrade.booked()\"\n [link]=\"upgrade.paymentLink()\"\n [error]=\"upgrade.error()\"\n (restart)=\"restartFlow()\" />\n }\n }\n </div>\n\n @if (hint(); as text) {\n <div class=\"sbd-reissue__hint\">{{ text }}</div>\n }\n\n @if (store.step() !== 'service') {\n <div class=\"sbd-reissue__footer\">\n <button pButton type=\"button\" label=\"Back\" class=\"p-button-outlined p-button-secondary sbd-reissue__btn\"\n [disabled]=\"store.step() === 'confirm' && upgrade.locked()\" (click)=\"onBack()\"></button>\n\n @switch (store.step()) {\n @case ('legs') {\n <button pButton type=\"button\" label=\"Continue\" class=\"sbd-reissue__btn\"\n [disabled]=\"!store.canContinue()\" (click)=\"store.goToEdit()\"></button>\n }\n @case ('edit') {\n <button pButton type=\"button\" icon=\"pi pi-search\" label=\"Search flights\" class=\"sbd-reissue__btn\"\n [disabled]=\"!!store.validationError()\" (click)=\"searchFlights()\"></button>\n }\n @case ('upgrade-legs') {\n <button pButton type=\"button\" label=\"Continue\" class=\"sbd-reissue__btn\" [loading]=\"upgrade.submitting()\"\n [disabled]=\"!upgrade.canContinueFromLegs()\" (click)=\"upgrade.continueFromLegs()\"></button>\n }\n @case ('upgrade') {\n <button pButton type=\"button\" label=\"Continue\" class=\"sbd-reissue__btn\" [loading]=\"upgrade.submitting()\"\n [disabled]=\"!upgrade.canContinue()\" (click)=\"upgrade.continue()\"></button>\n }\n @case ('confirm') {\n @switch (upgrade.action()) {\n @case ('done') {\n <button pButton type=\"button\" label=\"Close\" class=\"sbd-reissue__btn\" (click)=\"closed.emit()\"></button>\n }\n @case ('book') {\n <button pButton type=\"button\" label=\"Confirm upgrade\" class=\"sbd-reissue__btn\"\n [loading]=\"upgrade.submitting()\" (click)=\"upgrade.confirm()\"></button>\n }\n @case ('link') {\n <button pButton type=\"button\" icon=\"pi pi-link\" label=\"Generate payment link\" class=\"sbd-reissue__btn\"\n [loading]=\"upgrade.submitting()\" (click)=\"upgrade.confirm()\"></button>\n }\n }\n }\n }\n </div>\n }\n }\n </div>\n</p-dialog>\n", styles: [":host ::ng-deep .sbd-reissue-dialog-wrapper{border-radius:16px;box-shadow:0 24px 60px #0f172a38}:host ::ng-deep .sbd-reissue-dialog-wrapper .p-dialog-content{padding:0;border-radius:16px;overflow:visible}.sbd-reissue{font-family:inherit;background:var(--sbd-r-bg, transparent);border-radius:16px;color-scheme:light;position:relative}.sbd-reissue__header{display:flex;align-items:flex-start;gap:12px;padding:20px 20px 0}.sbd-reissue__close{flex-shrink:0;width:32px;height:32px;border-radius:50%;background:var(--sbd-r-soft, #f8fafc);border:none;color:var(--sbd-r-ink, #1e2e4a);display:flex;align-items:center;justify-content:center;cursor:pointer}.sbd-reissue__close .pi{font-size:13px}.sbd-reissue__close:hover{background:var(--sbd-r-line, #e2e8f0)}.sbd-reissue__header-text{flex:1;display:flex;flex-direction:column;align-items:center;gap:4px;text-align:center;margin-right:32px}.sbd-reissue__title{font-size:19px;font-weight:800;color:var(--sbd-r-ink, #1e2e4a);margin:0}.sbd-reissue__sub{font-size:12.5px;color:var(--sbd-r-faint, #94a3b8)}.sbd-reissue__body{padding:16px 20px 20px;display:flex;flex-direction:column;gap:12px}.sbd-reissue__hint{text-align:center;padding:0 20px 12px;font-size:13px;color:var(--sbd-r-faint, #94a3b8)}.sbd-reissue__footer{display:flex;justify-content:flex-end;gap:10px;align-items:stretch;padding:14px 20px;border-top:1px solid var(--sbd-r-line, #e2e8f0);background:var(--sbd-r-surface, #fff);border-radius:0 0 16px 16px}.sbd-reissue__btn{flex:1 1 0;justify-content:center}.sbd-reissue__state{padding:36px 24px 28px;display:flex;flex-direction:column;align-items:center;gap:14px;text-align:center}.sbd-reissue__state-icon{width:56px;height:56px;border-radius:50%;background:var(--sbd-r-state-bg, #fff7ed);border:2px solid var(--sbd-r-state-line, #fed7aa);display:flex;align-items:center;justify-content:center}.sbd-reissue__state-icon .pi{font-size:24px;color:#f97316}.sbd-reissue__state-icon--warn{background:var(--sbd-r-state-warn-bg, #fef2f2);border-color:var(--sbd-r-state-warn-line, #fecaca)}.sbd-reissue__state-icon--warn .pi{color:#ef4444}.sbd-reissue__state-text{font-size:13px;color:var(--sbd-r-muted, #64748b);min-height:20px}.sbd-reissue__dots{display:flex;gap:6px}.sbd-reissue__dots span{width:7px;height:7px;border-radius:50%;background:#f97316;opacity:.3;animation:sbd-reissue-dot 1.2s ease-in-out infinite}.sbd-reissue__dots span:nth-child(2){animation-delay:.2s}.sbd-reissue__dots span:nth-child(3){animation-delay:.4s}@keyframes sbd-reissue-dot{0%,to{opacity:.3;transform:scale(1)}50%{opacity:1;transform:scale(1.4)}}:host-context(.dark) .sbd-reissue,:host-context([data-theme=dark]) .sbd-reissue{--sbd-r-bg: #18181b;--sbd-r-surface: #1f1f23;--sbd-r-soft: #27272a;--sbd-r-sunk: #2f2f34;--sbd-r-ink: #f4f4f5;--sbd-r-muted: #a1a1aa;--sbd-r-faint: #8b8b94;--sbd-r-line: #3f3f46;--sbd-r-line-strong: #52525b;--sbd-r-label: #d4d4d8;--sbd-r-input-text: #e4e4e7;--sbd-r-info-bg: #172554;--sbd-r-info-line: #1e3a8a;--sbd-r-info-text: #93c5fd;--sbd-r-warn-bg: #3a2a0e;--sbd-r-warn-line: #6b4a16;--sbd-r-warn-text: #fcd34d;--sbd-r-warn-icon: #f59e0b;--sbd-r-error-bg: #3a1517;--sbd-r-error-line: #7f1d1d;--sbd-r-error-text: #fca5a5;--sbd-r-success-bg: #0f2a1a;--sbd-r-success-line: #166534;--sbd-r-success-text: #86efac;--sbd-r-state-bg: #3a2410;--sbd-r-state-line: #7c3a10;--sbd-r-state-warn-bg: #3a1517;--sbd-r-state-warn-line: #7f1d1d;--sbd-r-green: #4ade80;--sbd-r-expiry-soon: #fbbf24;--sbd-r-accent-soft: color-mix(in srgb, var(--sbd-accent, #6d4aff) 28%, transparent);color-scheme:dark}\n"] }]
|
|
8140
8298
|
}], ctorParameters: () => [] });
|
|
8141
8299
|
|
|
8142
8300
|
class SbdHotelContentComponent {
|
|
@@ -8273,6 +8431,8 @@ class SmartBookingDashboardComponent {
|
|
|
8273
8431
|
/** The Reissue button is shown for flights only, and only when the host enabled the feature. */
|
|
8274
8432
|
this.reissueEnabled = inject(SBD_CONFIG).reissueEnabled;
|
|
8275
8433
|
this.product = signal('flight');
|
|
8434
|
+
/** The product the FCR based parts (cancel, notes, actions) work on. Trains have none of them. */
|
|
8435
|
+
this.fcrProduct = computed(() => (this.product() === 'hotel' ? 'hotel' : 'flight'));
|
|
8276
8436
|
this.bookingId = signal('');
|
|
8277
8437
|
this.bookingStatus = signal('idle');
|
|
8278
8438
|
this.bookingData = signal(null);
|
|
@@ -8283,7 +8443,7 @@ class SmartBookingDashboardComponent {
|
|
|
8283
8443
|
this.reissueDialogOpen = signal(false);
|
|
8284
8444
|
this.selectedActionKey = signal(null);
|
|
8285
8445
|
this.activeContextTab = signal('changes');
|
|
8286
|
-
this.availableActions = computed(() => (this.product() === 'flight' ? FLIGHT_ACTIONS : HOTEL_ACTIONS).filter(a => !a.hidden));
|
|
8446
|
+
this.availableActions = computed(() => (this.product() === 'flight' ? FLIGHT_ACTIONS : this.product() === 'hotel' ? HOTEL_ACTIONS : []).filter(a => !a.hidden));
|
|
8287
8447
|
// Handle both correct spelling (dataVerified) and BE typo (dataVerfied)
|
|
8288
8448
|
this.dataVerified = computed(() => {
|
|
8289
8449
|
const bi = this.bookingData()?.data?.booking_info;
|
|
@@ -8358,18 +8518,41 @@ class SmartBookingDashboardComponent {
|
|
|
8358
8518
|
document.querySelector('.sbd-booking-input__field')?.focus();
|
|
8359
8519
|
}
|
|
8360
8520
|
}
|
|
8521
|
+
/** The booking on screen was found under the previous brand: clear it, the agent looks it up again on the new one. */
|
|
8522
|
+
onBrandChanged() {
|
|
8523
|
+
this.bookingStatus.set('idle');
|
|
8524
|
+
this.bookingData.set(null);
|
|
8525
|
+
}
|
|
8361
8526
|
lookupBooking() {
|
|
8362
8527
|
const id = this.bookingId().trim();
|
|
8363
8528
|
if (!id)
|
|
8364
8529
|
return;
|
|
8365
8530
|
this.bookingStatus.set('loading');
|
|
8366
|
-
const
|
|
8531
|
+
const product = this.product();
|
|
8532
|
+
if (product === 'train') {
|
|
8533
|
+
this.bookingService.getTrainDetails(id).subscribe({
|
|
8534
|
+
next: (detail) => {
|
|
8535
|
+
const found = detail.configured && (detail.found || !!detail.summary || detail.sections?.length > 0);
|
|
8536
|
+
this.bookingData.set(found ? detail : null);
|
|
8537
|
+
this.bookingStatus.set(found ? 'success' : 'error');
|
|
8538
|
+
if (!found)
|
|
8539
|
+
this.toast.error('Train booking not found. Check the ID and try again.');
|
|
8540
|
+
},
|
|
8541
|
+
error: () => {
|
|
8542
|
+
this.bookingStatus.set('error');
|
|
8543
|
+
this.bookingData.set(null);
|
|
8544
|
+
this.toast.error('Train booking not found. Check the ID and try again.');
|
|
8545
|
+
},
|
|
8546
|
+
});
|
|
8547
|
+
return;
|
|
8548
|
+
}
|
|
8549
|
+
const fields = product === 'hotel'
|
|
8367
8550
|
? ['booking_info', 'hotel_information', 'checkin_checkout', 'room_information']
|
|
8368
8551
|
: 'booking_info';
|
|
8369
|
-
this.bookingService.getBooking(id,
|
|
8552
|
+
this.bookingService.getBooking(id, product, fields).subscribe({
|
|
8370
8553
|
next: ({ data }) => {
|
|
8371
8554
|
// console.log('Booking data received:', data);
|
|
8372
|
-
if (
|
|
8555
|
+
if (product === 'hotel') {
|
|
8373
8556
|
const mappedData = mapToHotelBookingData(data);
|
|
8374
8557
|
this.bookingData.set(mappedData);
|
|
8375
8558
|
}
|
|
@@ -8386,7 +8569,7 @@ class SmartBookingDashboardComponent {
|
|
|
8386
8569
|
});
|
|
8387
8570
|
}
|
|
8388
8571
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SmartBookingDashboardComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8389
|
-
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SmartBookingDashboardComponent, isStandalone: true, selector: "app-smart-booking-dashboard", host: { listeners: { "document:keydown": "onKeydown($event)" } }, ngImport: i0, template: "<div class=\"sbd-page\">\n\n <!-- Search bar full-width at top -->\n <div class=\"sbd-page__search\">\n <app-sbd-booking-input\n [(product)]=\"product\"\n [(bookingId)]=\"bookingId\"\n [loading]=\"bookingStatus() === 'loading'\"\n (lookup)=\"lookupBooking()\"\n />\n </div>\n\n <!-- Hotel: Use dedicated component -->\n @if (product() === 'hotel') {\n <app-sbd-hotel-content\n [bookingData]=\"bookingData()\"\n [bookingStatus]=\"bookingStatus()\"\n [bookingId]=\"bookingId()\"\n [dataVerified]=\"dataVerified()\"\n [bookingNotes]=\"bookingNotes()\"\n [bookingHistory]=\"bookingHistory()\"\n [historyGroups]=\"historyGroups()\"\n [activeContextTab]=\"activeContextTab()\"\n (cancelBooking)=\"cancelDialogOpen.set(true)\"\n (addNoteRequested)=\"addNoteDialogOpen.set(true)\"\n (contextTabChanged)=\"activeContextTab.set($event)\"\n />\n }\n\n <!-- Flight: Keep original 2-column layout -->\n @if (product() === 'flight') {\n <div class=\"sbd-page__content\">\n\n <!-- Left: booking context -->\n <aside class=\"sbd-page__aside\">\n\n <!-- Data search at the top of the sidebar -->\n @if (bookingStatus() === 'success') {\n <app-sbd-data-search [data]=\"bookingData()\" />\n <app-sbd-flight-itinerary-card [product]=\"product()\" [data]=\"bookingData()\" [verified]=\"dataVerified()\" />\n }\n\n <!-- Loading skeleton for aside -->\n @if (bookingStatus() === 'loading') {\n <div class=\"sbd-page__skeleton-card\">\n <div class=\"sbd-page__skeleton-row\" style=\"width:60%\"></div>\n <div class=\"sbd-page__skeleton-row\" style=\"width:40%\"></div>\n <div class=\"sbd-page__skeleton-row\" style=\"width:80%\"></div>\n <div class=\"sbd-page__skeleton-row\" style=\"width:50%\"></div>\n </div>\n }\n\n </aside>\n\n <!-- Right: agent workspace -->\n <main class=\"sbd-page__main\">\n\n <!-- Error state -->\n @if (bookingStatus() === 'error') {\n <div class=\"sbd-page__error\">\n <i class=\"pi pi-exclamation-circle\"></i>\n <span>Booking not found. Double-check the ID and product type, then try again.</span>\n </div>\n }\n\n <!-- Content once loaded -->\n @if (bookingStatus() === 'success') {\n\n <!-- Quick actions -->\n <div class=\"sbd-page__quick-actions\">\n <span class=\"sbd-page__quick-label\">Quick actions</span>\n <app-sbd-workflow-actions\n [bookingId]=\"bookingId()\"\n [showReissue]=\"reissueEnabled && product() === 'flight'\"\n (cancelBooking)=\"cancelDialogOpen.set(true)\"\n (reissue)=\"reissueDialogOpen.set(true)\"\n />\n </div>\n\n <!-- Action grid -->\n <app-sbd-action-grid\n [actions]=\"availableActions()\"\n [activeKey]=\"selectedActionKey()\"\n (actionSelected)=\"openAction($event)\"\n />\n\n <!-- Context: Notes + Changes tabbed -->\n <div class=\"sbd-page__context\">\n\n <!-- Tab bar -->\n <div class=\"sbd-page__context-tabs\">\n <button class=\"sbd-page__context-tab\"\n [class.sbd-page__context-tab--active]=\"activeContextTab() === 'changes'\"\n (click)=\"activeContextTab.set('changes')\">\n <i class=\"pi pi-history\"></i>\n Changes\n @if (bookingHistory().length > 0) {\n <span class=\"sbd-page__context-pill sbd-page__context-pill--changes\">{{ bookingHistory().length }}</span>\n }\n </button>\n <button class=\"sbd-page__context-tab\"\n [class.sbd-page__context-tab--active]=\"activeContextTab() === 'notes'\"\n (click)=\"activeContextTab.set('notes')\">\n <i class=\"pi pi-comments\"></i>\n Notes\n <span class=\"sbd-page__context-pill sbd-page__context-pill--notes\">{{ bookingNotes().length }}</span>\n </button>\n @if (activeContextTab() === 'notes') {\n <button pButton label=\"Add Note\" icon=\"pi pi-plus\" class=\"p-button-sm p-button-outlined sbd-page__context-add\"\n (click)=\"addNoteDialogOpen.set(true)\">\n </button>\n }\n </div>\n\n <!-- Notes tab -->\n @if (activeContextTab() === 'notes') {\n <div class=\"sbd-page__notes-list\">\n @if (bookingNotes().length === 0) {\n <div class=\"sbd-page__context-empty\">\n <i class=\"pi pi-inbox\"></i> No notes yet\n </div>\n }\n @for (note of bookingNotes(); track $index) {\n <div class=\"sbd-page__note\">\n <div class=\"sbd-page__note-top\">\n <span class=\"sbd-page__note-badge sbd-page__note-badge--{{ note.action | lowercase }}\">\n {{ note.action }}\n </span>\n <span class=\"sbd-page__note-author\">\n {{ note.writtenBy?.firstName }} {{ note.writtenBy?.lastName }}\n </span>\n <span class=\"sbd-page__note-date\">{{ fmtNoteDate(note.date) }}</span>\n </div>\n <p class=\"sbd-page__note-msg\">{{ note.message }}</p>\n </div>\n }\n </div>\n }\n\n <!-- Changes tab -->\n @if (activeContextTab() === 'changes') {\n <div class=\"sbd-page__changes-groups\">\n @if (historyGroups().length === 0) {\n <div class=\"sbd-page__context-empty\">\n <i class=\"pi pi-check\"></i> No changes recorded\n </div>\n }\n @for (group of historyGroups(); track group.changedAt) {\n <div class=\"sbd-page__changes-group\">\n <div class=\"sbd-page__changes-meta\">\n <i class=\"pi pi-user\"></i>\n <strong>{{ group.changedBy }}</strong>\n <span class=\"sbd-page__changes-sep\">\u00B7</span>\n <span>{{ fmtDate(group.changedAt) }}</span>\n </div>\n <table class=\"sbd-page__changes-table\">\n <thead>\n <tr>\n <th>Field</th>\n <th><i class=\"pi pi-times-circle\"></i> Before</th>\n <th><i class=\"pi pi-check-circle\"></i> After</th>\n </tr>\n </thead>\n <tbody>\n @for (entry of group.entries; track entry.field) {\n <tr>\n <td class=\"sbd-page__changes-field\">{{ formatField(entry.field) }}</td>\n <td class=\"sbd-page__changes-old\">{{ entry.from }}</td>\n <td class=\"sbd-page__changes-new\">{{ entry.to }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </div>\n }\n\n </div>\n\n }\n\n <!-- Loading skeleton for main -->\n @if (bookingStatus() === 'loading') {\n <div class=\"sbd-page__skeleton-card\">\n <div class=\"sbd-page__skeleton-row\" style=\"width:40%\"></div>\n <div class=\"sbd-page__skeleton-row\" style=\"width:25%\"></div>\n </div>\n }\n\n </main>\n\n </div>\n }\n\n</div>\n\n<app-sbd-cancel-dialog\n [visible]=\"cancelDialogOpen() && product() === 'flight'\"\n [bookingId]=\"bookingId()\"\n [product]=\"product()\"\n [pnrInfo]=\"cancelPnrInfo()\"\n [bookingInfo]=\"bookingData()\"\n (closed)=\"cancelDialogOpen.set(false)\"\n (confirmed)=\"bookingStatus.set('idle'); bookingData.set(null)\"\n/>\n\n<almatar-hotel-auto-cancellation\n *ngIf=\"cancelDialogOpen() && product() === 'hotel'\"\n [selectedHotelBooking]=\"bookingData()\"\n (closed)=\"cancelDialogOpen.set(false)\"\n (cancellationSuccess)=\"bookingStatus.set('idle'); bookingData.set(null)\"\n/>\n\n<app-sbd-action-dialog\n [visible]=\"actionDialogOpen()\"\n [bookingId]=\"bookingId()\"\n [product]=\"product()\"\n [actions]=\"availableActions()\"\n [initialKey]=\"selectedActionKey()\"\n [preloadedData]=\"bookingData()\"\n (closed)=\"actionDialogOpen.set(false)\"\n/>\n\n<app-sbd-add-note-dialog\n [visible]=\"addNoteDialogOpen()\"\n [bookingId]=\"bookingId()\"\n [product]=\"product()\"\n (closed)=\"addNoteDialogOpen.set(false)\"\n/>\n\n<app-sbd-reissue-dialog\n [visible]=\"reissueDialogOpen()\"\n [bookingId]=\"bookingId()\"\n [bookingData]=\"bookingData()\"\n (closed)=\"reissueDialogOpen.set(false)\"\n/>\n", styles: [".sbd-page{display:flex;flex-direction:column;gap:20px;padding:24px;max-width:1400px;min-height:100%}.sbd-page__search{width:100%}.sbd-page__error{display:flex;align-items:center;gap:10px;padding:16px 20px;background:#fef2f2;border:1px solid rgba(239,68,68,.2);border-radius:10px;color:#ef4444;font-size:13.5px;font-weight:500}.sbd-page__error i{font-size:18px}.sbd-page__content{display:grid;grid-template-columns:320px 1fr;gap:20px;align-items:start}@media (max-width: 960px){.sbd-page__content{grid-template-columns:1fr}}.sbd-page__aside{display:flex;flex-direction:column;gap:16px;position:sticky;top:20px}.sbd-page__main{display:flex;flex-direction:column;gap:16px}.sbd-page__quick-actions{display:flex;align-items:center;gap:12px;padding:12px 16px;background:#fff;border:1px solid #e2e8f0;border-radius:10px;flex-wrap:wrap}.sbd-page__quick-label{font-size:11.5px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:#94a3b8;flex-shrink:0}.sbd-page__context{background:#fff;border:1px solid #e2e8f0;border-radius:12px;overflow:hidden}.sbd-page__context-tabs{display:flex;align-items:center;border-bottom:1px solid #e2e8f0;background:#f8fafc}.sbd-page__context-add{margin-left:auto;margin-right:10px}.sbd-page__context-tab{display:flex;align-items:center;gap:7px;padding:11px 20px;font-size:13px;font-weight:600;color:#64748b;background:transparent;border:none;cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1px;transition:color .15s,border-color .15s}.sbd-page__context-tab .pi{font-size:13px}.sbd-page__context-tab:hover{color:#334155}.sbd-page__context-tab--active{color:#1e2e4a;border-bottom-color:var(--sbd-primary, #3b82f6);background:#fff}.sbd-page__context-pill{font-size:10.5px;font-weight:700;padding:1px 7px;border-radius:10px}.sbd-page__context-pill--notes{background:#e0e7ff;color:#4338ca}.sbd-page__context-pill--changes{background:#fef3c7;color:#b45309}.sbd-page__context-empty{display:flex;align-items:center;gap:8px;padding:24px 20px;font-size:13px;color:#94a3b8}.sbd-page__context-empty .pi{font-size:16px}.sbd-page__notes-list{display:flex;flex-direction:column}.sbd-page__note{padding:12px 16px;border-bottom:1px solid #f1f5f9;display:flex;flex-direction:column;gap:6px}.sbd-page__note:last-child{border-bottom:none}.sbd-page__note-top{display:flex;align-items:center;gap:8px}.sbd-page__note-badge{font-size:10px;font-weight:800;letter-spacing:.05em;padding:2px 8px;border-radius:10px;text-transform:uppercase;flex-shrink:0}.sbd-page__note-badge--general{background:#dbeafe;color:#1d4ed8}.sbd-page__note-badge--remark{background:#fef3c7;color:#b45309}.sbd-page__note-badge--feedback{background:#f3e8ff;color:#7e22ce}.sbd-page__note-author{font-size:12px;font-weight:700;color:#1e2e4a}.sbd-page__note-date{margin-left:auto;font-size:11px;color:#94a3b8;white-space:nowrap}.sbd-page__note-msg{margin:0;font-size:13px;color:#334155;line-height:1.55}.sbd-page__changes-groups{display:flex;flex-direction:column}.sbd-page__changes-group{border-bottom:1px solid #f1f5f9}.sbd-page__changes-group:last-child{border-bottom:none}.sbd-page__changes-meta{display:flex;align-items:center;gap:6px;padding:8px 16px;background:#fafafa;border-bottom:1px solid #f1f5f9;font-size:11.5px;color:#64748b}.sbd-page__changes-meta strong{font-weight:700;color:#334155}.sbd-page__changes-meta .pi{font-size:11px;color:#94a3b8}.sbd-page__changes-sep{color:#cbd5e1}.sbd-page__changes-table{width:100%;border-collapse:collapse;font-size:12.5px}.sbd-page__changes-table thead tr{background:#f8fafc;border-bottom:1px solid #e2e8f0}.sbd-page__changes-table thead th{padding:7px 14px;text-align:left;font-size:10.5px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:#64748b;white-space:nowrap}.sbd-page__changes-table thead th .pi{margin-right:4px;font-size:10px}.sbd-page__changes-table thead th:nth-child(2){color:#dc2626}.sbd-page__changes-table thead th:nth-child(3){color:#16a34a}.sbd-page__changes-table tbody tr{border-bottom:1px solid #f1f5f9}.sbd-page__changes-table tbody tr:last-child{border-bottom:none}.sbd-page__changes-table tbody tr:hover{background:#f8fafc}.sbd-page__changes-table tbody td{padding:8px 14px;vertical-align:top;word-break:break-word}.sbd-page__changes-field{font-size:12px;font-weight:600;color:#475569;width:28%}.sbd-page__changes-old{color:#dc2626;font-weight:500;text-decoration:line-through;opacity:.8;width:36%}.sbd-page__changes-new{color:#16a34a;font-weight:700;width:36%}.sbd-page__content--loading{opacity:.6;pointer-events:none}.sbd-page__skeleton-card{background:#fff;border:1px solid #e2e8f0;border-radius:12px;padding:20px;display:flex;flex-direction:column;gap:12px}.sbd-page__skeleton-row{height:13px;background:#f1f5f9;border-radius:6px;animation:sbd-shimmer 1.4s ease-in-out infinite}.sbd-page__skeleton-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:10px;margin-top:8px}.sbd-page__skeleton-chip{height:56px;background:#f1f5f9;border-radius:8px;animation:sbd-shimmer 1.4s ease-in-out infinite}@keyframes sbd-shimmer{0%,to{opacity:1}50%{opacity:.45}}@keyframes sbd-fadein{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "component", type: SbdBookingInputComponent, selector: "app-sbd-booking-input", inputs: ["loading", "product", "bookingId"], outputs: ["productChange", "bookingIdChange", "lookup"] }, { kind: "component", type: SbdWorkflowActionsComponent, selector: "app-sbd-workflow-actions", inputs: ["bookingId", "showReissue"], outputs: ["cancelBooking", "reissue"] }, { kind: "component", type: SbdActionGridComponent, selector: "app-sbd-action-grid", inputs: ["actions", "activeKey", "loadingKey"], outputs: ["actionSelected"] }, { kind: "component", type: SbdCancelDialogComponent, selector: "app-sbd-cancel-dialog", inputs: ["visible", "bookingId", "product", "pnrInfo", "bookingInfo"], outputs: ["closed", "confirmed"] }, { kind: "component", type: AlmatarHotelAutoCancellationComponent, selector: "almatar-hotel-auto-cancellation", inputs: ["selectedHotelBooking"], outputs: ["closed", "cancellationSuccess", "nonRefundableSubmitSuccess", "chatWithAgent"] }, { kind: "component", type: SbdFlightItineraryCardComponent, selector: "app-sbd-flight-itinerary-card", inputs: ["data", "product", "verified"] }, { kind: "component", type: SbdDataSearchComponent, selector: "app-sbd-data-search", inputs: ["data"] }, { kind: "component", type: SbdActionDialogComponent, selector: "app-sbd-action-dialog", inputs: ["visible", "bookingId", "product", "actions", "initialKey", "preloadedData"], outputs: ["closed"] }, { kind: "component", type: SbdAddNoteDialogComponent, selector: "app-sbd-add-note-dialog", inputs: ["visible", "bookingId", "product"], outputs: ["closed"] }, { kind: "component", type: SbdReissueDialogComponent, selector: "app-sbd-reissue-dialog", inputs: ["visible", "bookingId", "bookingData"], outputs: ["closed"] }, { kind: "component", type: SbdHotelContentComponent, selector: "app-sbd-hotel-content", inputs: ["bookingData", "bookingStatus", "bookingId", "dataVerified", "bookingNotes", "bookingHistory", "historyGroups", "activeContextTab"], outputs: ["cancelBooking", "addNoteRequested", "contextTabChanged"] }, { kind: "pipe", type: LowerCasePipe, name: "lowercase" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2$1.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading"] }] }); }
|
|
8572
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.14", type: SmartBookingDashboardComponent, isStandalone: true, selector: "app-smart-booking-dashboard", host: { listeners: { "document:keydown": "onKeydown($event)" } }, ngImport: i0, template: "<div class=\"sbd-page\">\n\n <!-- Search bar full-width at top -->\n <div class=\"sbd-page__search\">\n <app-sbd-booking-input\n [(product)]=\"product\"\n [(bookingId)]=\"bookingId\"\n [loading]=\"bookingStatus() === 'loading'\"\n (lookup)=\"lookupBooking()\"\n (brandChanged)=\"onBrandChanged()\"\n />\n </div>\n\n <!-- Hotel: Use dedicated component -->\n @if (product() === 'hotel') {\n <app-sbd-hotel-content\n [bookingData]=\"bookingData()\"\n [bookingStatus]=\"bookingStatus()\"\n [bookingId]=\"bookingId()\"\n [dataVerified]=\"dataVerified()\"\n [bookingNotes]=\"bookingNotes()\"\n [bookingHistory]=\"bookingHistory()\"\n [historyGroups]=\"historyGroups()\"\n [activeContextTab]=\"activeContextTab()\"\n (cancelBooking)=\"cancelDialogOpen.set(true)\"\n (addNoteRequested)=\"addNoteDialogOpen.set(true)\"\n (contextTabChanged)=\"activeContextTab.set($event)\"\n />\n }\n\n <!-- Train: read-only booking details -->\n @if (product() === 'train') {\n @if (bookingStatus() === 'loading') {\n <div class=\"sbd-page__skeleton-card\">\n <div class=\"sbd-page__skeleton-row\" style=\"width:60%\"></div>\n <div class=\"sbd-page__skeleton-row\" style=\"width:40%\"></div>\n <div class=\"sbd-page__skeleton-row\" style=\"width:80%\"></div>\n </div>\n }\n @if (bookingStatus() === 'error') {\n <div class=\"sbd-page__error\">\n <i class=\"pi pi-exclamation-circle\"></i>\n <span>Train booking not found. Double-check the ID, then try again.</span>\n </div>\n }\n @if (bookingStatus() === 'success' && bookingData()) {\n <app-sbd-train-details [detail]=\"bookingData()\" [bookingId]=\"bookingId()\" />\n }\n }\n\n <!-- Flight: Keep original 2-column layout -->\n @if (product() === 'flight') {\n <div class=\"sbd-page__content\">\n\n <!-- Left: booking context -->\n <aside class=\"sbd-page__aside\">\n\n <!-- Data search at the top of the sidebar -->\n @if (bookingStatus() === 'success') {\n <app-sbd-data-search [data]=\"bookingData()\" />\n <app-sbd-flight-itinerary-card [product]=\"fcrProduct()\" [data]=\"bookingData()\" [verified]=\"dataVerified()\" />\n }\n\n <!-- Loading skeleton for aside -->\n @if (bookingStatus() === 'loading') {\n <div class=\"sbd-page__skeleton-card\">\n <div class=\"sbd-page__skeleton-row\" style=\"width:60%\"></div>\n <div class=\"sbd-page__skeleton-row\" style=\"width:40%\"></div>\n <div class=\"sbd-page__skeleton-row\" style=\"width:80%\"></div>\n <div class=\"sbd-page__skeleton-row\" style=\"width:50%\"></div>\n </div>\n }\n\n </aside>\n\n <!-- Right: agent workspace -->\n <main class=\"sbd-page__main\">\n\n <!-- Error state -->\n @if (bookingStatus() === 'error') {\n <div class=\"sbd-page__error\">\n <i class=\"pi pi-exclamation-circle\"></i>\n <span>Booking not found. Double-check the ID and product type, then try again.</span>\n </div>\n }\n\n <!-- Content once loaded -->\n @if (bookingStatus() === 'success') {\n\n <!-- Quick actions -->\n <div class=\"sbd-page__quick-actions\">\n <span class=\"sbd-page__quick-label\">Quick actions</span>\n <app-sbd-workflow-actions\n [bookingId]=\"bookingId()\"\n [showReissue]=\"reissueEnabled && product() === 'flight'\"\n (cancelBooking)=\"cancelDialogOpen.set(true)\"\n (reissue)=\"reissueDialogOpen.set(true)\"\n />\n </div>\n\n <!-- Action grid -->\n <app-sbd-action-grid\n [actions]=\"availableActions()\"\n [activeKey]=\"selectedActionKey()\"\n (actionSelected)=\"openAction($event)\"\n />\n\n <!-- Context: Notes + Changes tabbed -->\n <div class=\"sbd-page__context\">\n\n <!-- Tab bar -->\n <div class=\"sbd-page__context-tabs\">\n <button class=\"sbd-page__context-tab\"\n [class.sbd-page__context-tab--active]=\"activeContextTab() === 'changes'\"\n (click)=\"activeContextTab.set('changes')\">\n <i class=\"pi pi-history\"></i>\n Changes\n @if (bookingHistory().length > 0) {\n <span class=\"sbd-page__context-pill sbd-page__context-pill--changes\">{{ bookingHistory().length }}</span>\n }\n </button>\n <button class=\"sbd-page__context-tab\"\n [class.sbd-page__context-tab--active]=\"activeContextTab() === 'notes'\"\n (click)=\"activeContextTab.set('notes')\">\n <i class=\"pi pi-comments\"></i>\n Notes\n <span class=\"sbd-page__context-pill sbd-page__context-pill--notes\">{{ bookingNotes().length }}</span>\n </button>\n @if (activeContextTab() === 'notes') {\n <button pButton label=\"Add Note\" icon=\"pi pi-plus\" class=\"p-button-sm p-button-outlined sbd-page__context-add\"\n (click)=\"addNoteDialogOpen.set(true)\">\n </button>\n }\n </div>\n\n <!-- Notes tab -->\n @if (activeContextTab() === 'notes') {\n <div class=\"sbd-page__notes-list\">\n @if (bookingNotes().length === 0) {\n <div class=\"sbd-page__context-empty\">\n <i class=\"pi pi-inbox\"></i> No notes yet\n </div>\n }\n @for (note of bookingNotes(); track $index) {\n <div class=\"sbd-page__note\">\n <div class=\"sbd-page__note-top\">\n <span class=\"sbd-page__note-badge sbd-page__note-badge--{{ note.action | lowercase }}\">\n {{ note.action }}\n </span>\n <span class=\"sbd-page__note-author\">\n {{ note.writtenBy?.firstName }} {{ note.writtenBy?.lastName }}\n </span>\n <span class=\"sbd-page__note-date\">{{ fmtNoteDate(note.date) }}</span>\n </div>\n <p class=\"sbd-page__note-msg\">{{ note.message }}</p>\n </div>\n }\n </div>\n }\n\n <!-- Changes tab -->\n @if (activeContextTab() === 'changes') {\n <div class=\"sbd-page__changes-groups\">\n @if (historyGroups().length === 0) {\n <div class=\"sbd-page__context-empty\">\n <i class=\"pi pi-check\"></i> No changes recorded\n </div>\n }\n @for (group of historyGroups(); track group.changedAt) {\n <div class=\"sbd-page__changes-group\">\n <div class=\"sbd-page__changes-meta\">\n <i class=\"pi pi-user\"></i>\n <strong>{{ group.changedBy }}</strong>\n <span class=\"sbd-page__changes-sep\">\u00B7</span>\n <span>{{ fmtDate(group.changedAt) }}</span>\n </div>\n <table class=\"sbd-page__changes-table\">\n <thead>\n <tr>\n <th>Field</th>\n <th><i class=\"pi pi-times-circle\"></i> Before</th>\n <th><i class=\"pi pi-check-circle\"></i> After</th>\n </tr>\n </thead>\n <tbody>\n @for (entry of group.entries; track entry.field) {\n <tr>\n <td class=\"sbd-page__changes-field\">{{ formatField(entry.field) }}</td>\n <td class=\"sbd-page__changes-old\">{{ entry.from }}</td>\n <td class=\"sbd-page__changes-new\">{{ entry.to }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </div>\n }\n\n </div>\n\n }\n\n <!-- Loading skeleton for main -->\n @if (bookingStatus() === 'loading') {\n <div class=\"sbd-page__skeleton-card\">\n <div class=\"sbd-page__skeleton-row\" style=\"width:40%\"></div>\n <div class=\"sbd-page__skeleton-row\" style=\"width:25%\"></div>\n </div>\n }\n\n </main>\n\n </div>\n }\n\n</div>\n\n<app-sbd-cancel-dialog\n [visible]=\"cancelDialogOpen() && product() === 'flight'\"\n [bookingId]=\"bookingId()\"\n [product]=\"fcrProduct()\"\n [pnrInfo]=\"cancelPnrInfo()\"\n [bookingInfo]=\"bookingData()\"\n (closed)=\"cancelDialogOpen.set(false)\"\n (confirmed)=\"bookingStatus.set('idle'); bookingData.set(null)\"\n/>\n\n<almatar-hotel-auto-cancellation\n *ngIf=\"cancelDialogOpen() && product() === 'hotel'\"\n [selectedHotelBooking]=\"bookingData()\"\n (closed)=\"cancelDialogOpen.set(false)\"\n (cancellationSuccess)=\"bookingStatus.set('idle'); bookingData.set(null)\"\n/>\n\n<app-sbd-action-dialog\n [visible]=\"actionDialogOpen()\"\n [bookingId]=\"bookingId()\"\n [product]=\"fcrProduct()\"\n [actions]=\"availableActions()\"\n [initialKey]=\"selectedActionKey()\"\n [preloadedData]=\"bookingData()\"\n (closed)=\"actionDialogOpen.set(false)\"\n/>\n\n<app-sbd-add-note-dialog\n [visible]=\"addNoteDialogOpen()\"\n [bookingId]=\"bookingId()\"\n [product]=\"fcrProduct()\"\n (closed)=\"addNoteDialogOpen.set(false)\"\n/>\n\n<app-sbd-reissue-dialog\n [visible]=\"reissueDialogOpen()\"\n [bookingId]=\"bookingId()\"\n [bookingData]=\"bookingData()\"\n (closed)=\"reissueDialogOpen.set(false)\"\n/>\n", styles: [".sbd-page{display:flex;flex-direction:column;gap:20px;padding:24px;max-width:1400px;min-height:100%}.sbd-page__search{width:100%}.sbd-page__error{display:flex;align-items:center;gap:10px;padding:16px 20px;background:#fef2f2;border:1px solid rgba(239,68,68,.2);border-radius:10px;color:#ef4444;font-size:13.5px;font-weight:500}.sbd-page__error i{font-size:18px}.sbd-page__content{display:grid;grid-template-columns:320px 1fr;gap:20px;align-items:start}@media (max-width: 960px){.sbd-page__content{grid-template-columns:1fr}}.sbd-page__aside{display:flex;flex-direction:column;gap:16px;position:sticky;top:20px}.sbd-page__main{display:flex;flex-direction:column;gap:16px}.sbd-page__quick-actions{display:flex;align-items:center;gap:12px;padding:12px 16px;background:#fff;border:1px solid #e2e8f0;border-radius:10px;flex-wrap:wrap}.sbd-page__quick-label{font-size:11.5px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:#94a3b8;flex-shrink:0}.sbd-page__context{background:#fff;border:1px solid #e2e8f0;border-radius:12px;overflow:hidden}.sbd-page__context-tabs{display:flex;align-items:center;border-bottom:1px solid #e2e8f0;background:#f8fafc}.sbd-page__context-add{margin-left:auto;margin-right:10px}.sbd-page__context-tab{display:flex;align-items:center;gap:7px;padding:11px 20px;font-size:13px;font-weight:600;color:#64748b;background:transparent;border:none;cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1px;transition:color .15s,border-color .15s}.sbd-page__context-tab .pi{font-size:13px}.sbd-page__context-tab:hover{color:#334155}.sbd-page__context-tab--active{color:#1e2e4a;border-bottom-color:var(--sbd-primary, #3b82f6);background:#fff}.sbd-page__context-pill{font-size:10.5px;font-weight:700;padding:1px 7px;border-radius:10px}.sbd-page__context-pill--notes{background:#e0e7ff;color:#4338ca}.sbd-page__context-pill--changes{background:#fef3c7;color:#b45309}.sbd-page__context-empty{display:flex;align-items:center;gap:8px;padding:24px 20px;font-size:13px;color:#94a3b8}.sbd-page__context-empty .pi{font-size:16px}.sbd-page__notes-list{display:flex;flex-direction:column}.sbd-page__note{padding:12px 16px;border-bottom:1px solid #f1f5f9;display:flex;flex-direction:column;gap:6px}.sbd-page__note:last-child{border-bottom:none}.sbd-page__note-top{display:flex;align-items:center;gap:8px}.sbd-page__note-badge{font-size:10px;font-weight:800;letter-spacing:.05em;padding:2px 8px;border-radius:10px;text-transform:uppercase;flex-shrink:0}.sbd-page__note-badge--general{background:#dbeafe;color:#1d4ed8}.sbd-page__note-badge--remark{background:#fef3c7;color:#b45309}.sbd-page__note-badge--feedback{background:#f3e8ff;color:#7e22ce}.sbd-page__note-author{font-size:12px;font-weight:700;color:#1e2e4a}.sbd-page__note-date{margin-left:auto;font-size:11px;color:#94a3b8;white-space:nowrap}.sbd-page__note-msg{margin:0;font-size:13px;color:#334155;line-height:1.55}.sbd-page__changes-groups{display:flex;flex-direction:column}.sbd-page__changes-group{border-bottom:1px solid #f1f5f9}.sbd-page__changes-group:last-child{border-bottom:none}.sbd-page__changes-meta{display:flex;align-items:center;gap:6px;padding:8px 16px;background:#fafafa;border-bottom:1px solid #f1f5f9;font-size:11.5px;color:#64748b}.sbd-page__changes-meta strong{font-weight:700;color:#334155}.sbd-page__changes-meta .pi{font-size:11px;color:#94a3b8}.sbd-page__changes-sep{color:#cbd5e1}.sbd-page__changes-table{width:100%;border-collapse:collapse;font-size:12.5px}.sbd-page__changes-table thead tr{background:#f8fafc;border-bottom:1px solid #e2e8f0}.sbd-page__changes-table thead th{padding:7px 14px;text-align:left;font-size:10.5px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:#64748b;white-space:nowrap}.sbd-page__changes-table thead th .pi{margin-right:4px;font-size:10px}.sbd-page__changes-table thead th:nth-child(2){color:#dc2626}.sbd-page__changes-table thead th:nth-child(3){color:#16a34a}.sbd-page__changes-table tbody tr{border-bottom:1px solid #f1f5f9}.sbd-page__changes-table tbody tr:last-child{border-bottom:none}.sbd-page__changes-table tbody tr:hover{background:#f8fafc}.sbd-page__changes-table tbody td{padding:8px 14px;vertical-align:top;word-break:break-word}.sbd-page__changes-field{font-size:12px;font-weight:600;color:#475569;width:28%}.sbd-page__changes-old{color:#dc2626;font-weight:500;text-decoration:line-through;opacity:.8;width:36%}.sbd-page__changes-new{color:#16a34a;font-weight:700;width:36%}.sbd-page__content--loading{opacity:.6;pointer-events:none}.sbd-page__skeleton-card{background:#fff;border:1px solid #e2e8f0;border-radius:12px;padding:20px;display:flex;flex-direction:column;gap:12px}.sbd-page__skeleton-row{height:13px;background:#f1f5f9;border-radius:6px;animation:sbd-shimmer 1.4s ease-in-out infinite}.sbd-page__skeleton-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:10px;margin-top:8px}.sbd-page__skeleton-chip{height:56px;background:#f1f5f9;border-radius:8px;animation:sbd-shimmer 1.4s ease-in-out infinite}@keyframes sbd-shimmer{0%,to{opacity:1}50%{opacity:.45}}@keyframes sbd-fadein{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "component", type: SbdBookingInputComponent, selector: "app-sbd-booking-input", inputs: ["loading", "product", "bookingId"], outputs: ["productChange", "bookingIdChange", "lookup", "brandChanged"] }, { kind: "component", type: SbdWorkflowActionsComponent, selector: "app-sbd-workflow-actions", inputs: ["bookingId", "showReissue"], outputs: ["cancelBooking", "reissue"] }, { kind: "component", type: SbdActionGridComponent, selector: "app-sbd-action-grid", inputs: ["actions", "activeKey", "loadingKey"], outputs: ["actionSelected"] }, { kind: "component", type: SbdCancelDialogComponent, selector: "app-sbd-cancel-dialog", inputs: ["visible", "bookingId", "product", "pnrInfo", "bookingInfo"], outputs: ["closed", "confirmed"] }, { kind: "component", type: AlmatarHotelAutoCancellationComponent, selector: "almatar-hotel-auto-cancellation", inputs: ["selectedHotelBooking"], outputs: ["closed", "cancellationSuccess", "nonRefundableSubmitSuccess", "chatWithAgent"] }, { kind: "component", type: SbdFlightItineraryCardComponent, selector: "app-sbd-flight-itinerary-card", inputs: ["data", "product", "verified"] }, { kind: "component", type: SbdDataSearchComponent, selector: "app-sbd-data-search", inputs: ["data"] }, { kind: "component", type: SbdActionDialogComponent, selector: "app-sbd-action-dialog", inputs: ["visible", "bookingId", "product", "actions", "initialKey", "preloadedData"], outputs: ["closed"] }, { kind: "component", type: SbdAddNoteDialogComponent, selector: "app-sbd-add-note-dialog", inputs: ["visible", "bookingId", "product"], outputs: ["closed"] }, { kind: "component", type: SbdReissueDialogComponent, selector: "app-sbd-reissue-dialog", inputs: ["visible", "bookingId", "bookingData"], outputs: ["closed"] }, { kind: "component", type: SbdHotelContentComponent, selector: "app-sbd-hotel-content", inputs: ["bookingData", "bookingStatus", "bookingId", "dataVerified", "bookingNotes", "bookingHistory", "historyGroups", "activeContextTab"], outputs: ["cancelBooking", "addNoteRequested", "contextTabChanged"] }, { kind: "component", type: SbdTrainDetailsComponent, selector: "app-sbd-train-details", inputs: ["detail", "bookingId"] }, { kind: "pipe", type: LowerCasePipe, name: "lowercase" }, { kind: "directive", type: NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "ngmodule", type: ButtonModule }, { kind: "directive", type: i2$1.ButtonDirective, selector: "[pButton]", inputs: ["iconPos", "loadingIcon", "label", "icon", "loading"] }] }); }
|
|
8390
8573
|
}
|
|
8391
8574
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImport: i0, type: SmartBookingDashboardComponent, decorators: [{
|
|
8392
8575
|
type: Component,
|
|
@@ -8403,10 +8586,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
8403
8586
|
SbdAddNoteDialogComponent,
|
|
8404
8587
|
SbdReissueDialogComponent,
|
|
8405
8588
|
SbdHotelContentComponent,
|
|
8589
|
+
SbdTrainDetailsComponent,
|
|
8406
8590
|
LowerCasePipe,
|
|
8407
8591
|
NgIf,
|
|
8408
8592
|
ButtonModule,
|
|
8409
|
-
], template: "<div class=\"sbd-page\">\n\n <!-- Search bar full-width at top -->\n <div class=\"sbd-page__search\">\n <app-sbd-booking-input\n [(product)]=\"product\"\n [(bookingId)]=\"bookingId\"\n [loading]=\"bookingStatus() === 'loading'\"\n (lookup)=\"lookupBooking()\"\n />\n </div>\n\n <!-- Hotel: Use dedicated component -->\n @if (product() === 'hotel') {\n <app-sbd-hotel-content\n [bookingData]=\"bookingData()\"\n [bookingStatus]=\"bookingStatus()\"\n [bookingId]=\"bookingId()\"\n [dataVerified]=\"dataVerified()\"\n [bookingNotes]=\"bookingNotes()\"\n [bookingHistory]=\"bookingHistory()\"\n [historyGroups]=\"historyGroups()\"\n [activeContextTab]=\"activeContextTab()\"\n (cancelBooking)=\"cancelDialogOpen.set(true)\"\n (addNoteRequested)=\"addNoteDialogOpen.set(true)\"\n (contextTabChanged)=\"activeContextTab.set($event)\"\n />\n }\n\n <!-- Flight: Keep original 2-column layout -->\n @if (product() === 'flight') {\n <div class=\"sbd-page__content\">\n\n <!-- Left: booking context -->\n <aside class=\"sbd-page__aside\">\n\n <!-- Data search at the top of the sidebar -->\n @if (bookingStatus() === 'success') {\n <app-sbd-data-search [data]=\"bookingData()\" />\n <app-sbd-flight-itinerary-card [product]=\"product()\" [data]=\"bookingData()\" [verified]=\"dataVerified()\" />\n }\n\n <!-- Loading skeleton for aside -->\n @if (bookingStatus() === 'loading') {\n <div class=\"sbd-page__skeleton-card\">\n <div class=\"sbd-page__skeleton-row\" style=\"width:60%\"></div>\n <div class=\"sbd-page__skeleton-row\" style=\"width:40%\"></div>\n <div class=\"sbd-page__skeleton-row\" style=\"width:80%\"></div>\n <div class=\"sbd-page__skeleton-row\" style=\"width:50%\"></div>\n </div>\n }\n\n </aside>\n\n <!-- Right: agent workspace -->\n <main class=\"sbd-page__main\">\n\n <!-- Error state -->\n @if (bookingStatus() === 'error') {\n <div class=\"sbd-page__error\">\n <i class=\"pi pi-exclamation-circle\"></i>\n <span>Booking not found. Double-check the ID and product type, then try again.</span>\n </div>\n }\n\n <!-- Content once loaded -->\n @if (bookingStatus() === 'success') {\n\n <!-- Quick actions -->\n <div class=\"sbd-page__quick-actions\">\n <span class=\"sbd-page__quick-label\">Quick actions</span>\n <app-sbd-workflow-actions\n [bookingId]=\"bookingId()\"\n [showReissue]=\"reissueEnabled && product() === 'flight'\"\n (cancelBooking)=\"cancelDialogOpen.set(true)\"\n (reissue)=\"reissueDialogOpen.set(true)\"\n />\n </div>\n\n <!-- Action grid -->\n <app-sbd-action-grid\n [actions]=\"availableActions()\"\n [activeKey]=\"selectedActionKey()\"\n (actionSelected)=\"openAction($event)\"\n />\n\n <!-- Context: Notes + Changes tabbed -->\n <div class=\"sbd-page__context\">\n\n <!-- Tab bar -->\n <div class=\"sbd-page__context-tabs\">\n <button class=\"sbd-page__context-tab\"\n [class.sbd-page__context-tab--active]=\"activeContextTab() === 'changes'\"\n (click)=\"activeContextTab.set('changes')\">\n <i class=\"pi pi-history\"></i>\n Changes\n @if (bookingHistory().length > 0) {\n <span class=\"sbd-page__context-pill sbd-page__context-pill--changes\">{{ bookingHistory().length }}</span>\n }\n </button>\n <button class=\"sbd-page__context-tab\"\n [class.sbd-page__context-tab--active]=\"activeContextTab() === 'notes'\"\n (click)=\"activeContextTab.set('notes')\">\n <i class=\"pi pi-comments\"></i>\n Notes\n <span class=\"sbd-page__context-pill sbd-page__context-pill--notes\">{{ bookingNotes().length }}</span>\n </button>\n @if (activeContextTab() === 'notes') {\n <button pButton label=\"Add Note\" icon=\"pi pi-plus\" class=\"p-button-sm p-button-outlined sbd-page__context-add\"\n (click)=\"addNoteDialogOpen.set(true)\">\n </button>\n }\n </div>\n\n <!-- Notes tab -->\n @if (activeContextTab() === 'notes') {\n <div class=\"sbd-page__notes-list\">\n @if (bookingNotes().length === 0) {\n <div class=\"sbd-page__context-empty\">\n <i class=\"pi pi-inbox\"></i> No notes yet\n </div>\n }\n @for (note of bookingNotes(); track $index) {\n <div class=\"sbd-page__note\">\n <div class=\"sbd-page__note-top\">\n <span class=\"sbd-page__note-badge sbd-page__note-badge--{{ note.action | lowercase }}\">\n {{ note.action }}\n </span>\n <span class=\"sbd-page__note-author\">\n {{ note.writtenBy?.firstName }} {{ note.writtenBy?.lastName }}\n </span>\n <span class=\"sbd-page__note-date\">{{ fmtNoteDate(note.date) }}</span>\n </div>\n <p class=\"sbd-page__note-msg\">{{ note.message }}</p>\n </div>\n }\n </div>\n }\n\n <!-- Changes tab -->\n @if (activeContextTab() === 'changes') {\n <div class=\"sbd-page__changes-groups\">\n @if (historyGroups().length === 0) {\n <div class=\"sbd-page__context-empty\">\n <i class=\"pi pi-check\"></i> No changes recorded\n </div>\n }\n @for (group of historyGroups(); track group.changedAt) {\n <div class=\"sbd-page__changes-group\">\n <div class=\"sbd-page__changes-meta\">\n <i class=\"pi pi-user\"></i>\n <strong>{{ group.changedBy }}</strong>\n <span class=\"sbd-page__changes-sep\">\u00B7</span>\n <span>{{ fmtDate(group.changedAt) }}</span>\n </div>\n <table class=\"sbd-page__changes-table\">\n <thead>\n <tr>\n <th>Field</th>\n <th><i class=\"pi pi-times-circle\"></i> Before</th>\n <th><i class=\"pi pi-check-circle\"></i> After</th>\n </tr>\n </thead>\n <tbody>\n @for (entry of group.entries; track entry.field) {\n <tr>\n <td class=\"sbd-page__changes-field\">{{ formatField(entry.field) }}</td>\n <td class=\"sbd-page__changes-old\">{{ entry.from }}</td>\n <td class=\"sbd-page__changes-new\">{{ entry.to }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </div>\n }\n\n </div>\n\n }\n\n <!-- Loading skeleton for main -->\n @if (bookingStatus() === 'loading') {\n <div class=\"sbd-page__skeleton-card\">\n <div class=\"sbd-page__skeleton-row\" style=\"width:40%\"></div>\n <div class=\"sbd-page__skeleton-row\" style=\"width:25%\"></div>\n </div>\n }\n\n </main>\n\n </div>\n }\n\n</div>\n\n<app-sbd-cancel-dialog\n [visible]=\"cancelDialogOpen() && product() === 'flight'\"\n [bookingId]=\"bookingId()\"\n [product]=\"product()\"\n [pnrInfo]=\"cancelPnrInfo()\"\n [bookingInfo]=\"bookingData()\"\n (closed)=\"cancelDialogOpen.set(false)\"\n (confirmed)=\"bookingStatus.set('idle'); bookingData.set(null)\"\n/>\n\n<almatar-hotel-auto-cancellation\n *ngIf=\"cancelDialogOpen() && product() === 'hotel'\"\n [selectedHotelBooking]=\"bookingData()\"\n (closed)=\"cancelDialogOpen.set(false)\"\n (cancellationSuccess)=\"bookingStatus.set('idle'); bookingData.set(null)\"\n/>\n\n<app-sbd-action-dialog\n [visible]=\"actionDialogOpen()\"\n [bookingId]=\"bookingId()\"\n [product]=\"product()\"\n [actions]=\"availableActions()\"\n [initialKey]=\"selectedActionKey()\"\n [preloadedData]=\"bookingData()\"\n (closed)=\"actionDialogOpen.set(false)\"\n/>\n\n<app-sbd-add-note-dialog\n [visible]=\"addNoteDialogOpen()\"\n [bookingId]=\"bookingId()\"\n [product]=\"product()\"\n (closed)=\"addNoteDialogOpen.set(false)\"\n/>\n\n<app-sbd-reissue-dialog\n [visible]=\"reissueDialogOpen()\"\n [bookingId]=\"bookingId()\"\n [bookingData]=\"bookingData()\"\n (closed)=\"reissueDialogOpen.set(false)\"\n/>\n", styles: [".sbd-page{display:flex;flex-direction:column;gap:20px;padding:24px;max-width:1400px;min-height:100%}.sbd-page__search{width:100%}.sbd-page__error{display:flex;align-items:center;gap:10px;padding:16px 20px;background:#fef2f2;border:1px solid rgba(239,68,68,.2);border-radius:10px;color:#ef4444;font-size:13.5px;font-weight:500}.sbd-page__error i{font-size:18px}.sbd-page__content{display:grid;grid-template-columns:320px 1fr;gap:20px;align-items:start}@media (max-width: 960px){.sbd-page__content{grid-template-columns:1fr}}.sbd-page__aside{display:flex;flex-direction:column;gap:16px;position:sticky;top:20px}.sbd-page__main{display:flex;flex-direction:column;gap:16px}.sbd-page__quick-actions{display:flex;align-items:center;gap:12px;padding:12px 16px;background:#fff;border:1px solid #e2e8f0;border-radius:10px;flex-wrap:wrap}.sbd-page__quick-label{font-size:11.5px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:#94a3b8;flex-shrink:0}.sbd-page__context{background:#fff;border:1px solid #e2e8f0;border-radius:12px;overflow:hidden}.sbd-page__context-tabs{display:flex;align-items:center;border-bottom:1px solid #e2e8f0;background:#f8fafc}.sbd-page__context-add{margin-left:auto;margin-right:10px}.sbd-page__context-tab{display:flex;align-items:center;gap:7px;padding:11px 20px;font-size:13px;font-weight:600;color:#64748b;background:transparent;border:none;cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1px;transition:color .15s,border-color .15s}.sbd-page__context-tab .pi{font-size:13px}.sbd-page__context-tab:hover{color:#334155}.sbd-page__context-tab--active{color:#1e2e4a;border-bottom-color:var(--sbd-primary, #3b82f6);background:#fff}.sbd-page__context-pill{font-size:10.5px;font-weight:700;padding:1px 7px;border-radius:10px}.sbd-page__context-pill--notes{background:#e0e7ff;color:#4338ca}.sbd-page__context-pill--changes{background:#fef3c7;color:#b45309}.sbd-page__context-empty{display:flex;align-items:center;gap:8px;padding:24px 20px;font-size:13px;color:#94a3b8}.sbd-page__context-empty .pi{font-size:16px}.sbd-page__notes-list{display:flex;flex-direction:column}.sbd-page__note{padding:12px 16px;border-bottom:1px solid #f1f5f9;display:flex;flex-direction:column;gap:6px}.sbd-page__note:last-child{border-bottom:none}.sbd-page__note-top{display:flex;align-items:center;gap:8px}.sbd-page__note-badge{font-size:10px;font-weight:800;letter-spacing:.05em;padding:2px 8px;border-radius:10px;text-transform:uppercase;flex-shrink:0}.sbd-page__note-badge--general{background:#dbeafe;color:#1d4ed8}.sbd-page__note-badge--remark{background:#fef3c7;color:#b45309}.sbd-page__note-badge--feedback{background:#f3e8ff;color:#7e22ce}.sbd-page__note-author{font-size:12px;font-weight:700;color:#1e2e4a}.sbd-page__note-date{margin-left:auto;font-size:11px;color:#94a3b8;white-space:nowrap}.sbd-page__note-msg{margin:0;font-size:13px;color:#334155;line-height:1.55}.sbd-page__changes-groups{display:flex;flex-direction:column}.sbd-page__changes-group{border-bottom:1px solid #f1f5f9}.sbd-page__changes-group:last-child{border-bottom:none}.sbd-page__changes-meta{display:flex;align-items:center;gap:6px;padding:8px 16px;background:#fafafa;border-bottom:1px solid #f1f5f9;font-size:11.5px;color:#64748b}.sbd-page__changes-meta strong{font-weight:700;color:#334155}.sbd-page__changes-meta .pi{font-size:11px;color:#94a3b8}.sbd-page__changes-sep{color:#cbd5e1}.sbd-page__changes-table{width:100%;border-collapse:collapse;font-size:12.5px}.sbd-page__changes-table thead tr{background:#f8fafc;border-bottom:1px solid #e2e8f0}.sbd-page__changes-table thead th{padding:7px 14px;text-align:left;font-size:10.5px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:#64748b;white-space:nowrap}.sbd-page__changes-table thead th .pi{margin-right:4px;font-size:10px}.sbd-page__changes-table thead th:nth-child(2){color:#dc2626}.sbd-page__changes-table thead th:nth-child(3){color:#16a34a}.sbd-page__changes-table tbody tr{border-bottom:1px solid #f1f5f9}.sbd-page__changes-table tbody tr:last-child{border-bottom:none}.sbd-page__changes-table tbody tr:hover{background:#f8fafc}.sbd-page__changes-table tbody td{padding:8px 14px;vertical-align:top;word-break:break-word}.sbd-page__changes-field{font-size:12px;font-weight:600;color:#475569;width:28%}.sbd-page__changes-old{color:#dc2626;font-weight:500;text-decoration:line-through;opacity:.8;width:36%}.sbd-page__changes-new{color:#16a34a;font-weight:700;width:36%}.sbd-page__content--loading{opacity:.6;pointer-events:none}.sbd-page__skeleton-card{background:#fff;border:1px solid #e2e8f0;border-radius:12px;padding:20px;display:flex;flex-direction:column;gap:12px}.sbd-page__skeleton-row{height:13px;background:#f1f5f9;border-radius:6px;animation:sbd-shimmer 1.4s ease-in-out infinite}.sbd-page__skeleton-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:10px;margin-top:8px}.sbd-page__skeleton-chip{height:56px;background:#f1f5f9;border-radius:8px;animation:sbd-shimmer 1.4s ease-in-out infinite}@keyframes sbd-shimmer{0%,to{opacity:1}50%{opacity:.45}}@keyframes sbd-fadein{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}\n"] }]
|
|
8593
|
+
], template: "<div class=\"sbd-page\">\n\n <!-- Search bar full-width at top -->\n <div class=\"sbd-page__search\">\n <app-sbd-booking-input\n [(product)]=\"product\"\n [(bookingId)]=\"bookingId\"\n [loading]=\"bookingStatus() === 'loading'\"\n (lookup)=\"lookupBooking()\"\n (brandChanged)=\"onBrandChanged()\"\n />\n </div>\n\n <!-- Hotel: Use dedicated component -->\n @if (product() === 'hotel') {\n <app-sbd-hotel-content\n [bookingData]=\"bookingData()\"\n [bookingStatus]=\"bookingStatus()\"\n [bookingId]=\"bookingId()\"\n [dataVerified]=\"dataVerified()\"\n [bookingNotes]=\"bookingNotes()\"\n [bookingHistory]=\"bookingHistory()\"\n [historyGroups]=\"historyGroups()\"\n [activeContextTab]=\"activeContextTab()\"\n (cancelBooking)=\"cancelDialogOpen.set(true)\"\n (addNoteRequested)=\"addNoteDialogOpen.set(true)\"\n (contextTabChanged)=\"activeContextTab.set($event)\"\n />\n }\n\n <!-- Train: read-only booking details -->\n @if (product() === 'train') {\n @if (bookingStatus() === 'loading') {\n <div class=\"sbd-page__skeleton-card\">\n <div class=\"sbd-page__skeleton-row\" style=\"width:60%\"></div>\n <div class=\"sbd-page__skeleton-row\" style=\"width:40%\"></div>\n <div class=\"sbd-page__skeleton-row\" style=\"width:80%\"></div>\n </div>\n }\n @if (bookingStatus() === 'error') {\n <div class=\"sbd-page__error\">\n <i class=\"pi pi-exclamation-circle\"></i>\n <span>Train booking not found. Double-check the ID, then try again.</span>\n </div>\n }\n @if (bookingStatus() === 'success' && bookingData()) {\n <app-sbd-train-details [detail]=\"bookingData()\" [bookingId]=\"bookingId()\" />\n }\n }\n\n <!-- Flight: Keep original 2-column layout -->\n @if (product() === 'flight') {\n <div class=\"sbd-page__content\">\n\n <!-- Left: booking context -->\n <aside class=\"sbd-page__aside\">\n\n <!-- Data search at the top of the sidebar -->\n @if (bookingStatus() === 'success') {\n <app-sbd-data-search [data]=\"bookingData()\" />\n <app-sbd-flight-itinerary-card [product]=\"fcrProduct()\" [data]=\"bookingData()\" [verified]=\"dataVerified()\" />\n }\n\n <!-- Loading skeleton for aside -->\n @if (bookingStatus() === 'loading') {\n <div class=\"sbd-page__skeleton-card\">\n <div class=\"sbd-page__skeleton-row\" style=\"width:60%\"></div>\n <div class=\"sbd-page__skeleton-row\" style=\"width:40%\"></div>\n <div class=\"sbd-page__skeleton-row\" style=\"width:80%\"></div>\n <div class=\"sbd-page__skeleton-row\" style=\"width:50%\"></div>\n </div>\n }\n\n </aside>\n\n <!-- Right: agent workspace -->\n <main class=\"sbd-page__main\">\n\n <!-- Error state -->\n @if (bookingStatus() === 'error') {\n <div class=\"sbd-page__error\">\n <i class=\"pi pi-exclamation-circle\"></i>\n <span>Booking not found. Double-check the ID and product type, then try again.</span>\n </div>\n }\n\n <!-- Content once loaded -->\n @if (bookingStatus() === 'success') {\n\n <!-- Quick actions -->\n <div class=\"sbd-page__quick-actions\">\n <span class=\"sbd-page__quick-label\">Quick actions</span>\n <app-sbd-workflow-actions\n [bookingId]=\"bookingId()\"\n [showReissue]=\"reissueEnabled && product() === 'flight'\"\n (cancelBooking)=\"cancelDialogOpen.set(true)\"\n (reissue)=\"reissueDialogOpen.set(true)\"\n />\n </div>\n\n <!-- Action grid -->\n <app-sbd-action-grid\n [actions]=\"availableActions()\"\n [activeKey]=\"selectedActionKey()\"\n (actionSelected)=\"openAction($event)\"\n />\n\n <!-- Context: Notes + Changes tabbed -->\n <div class=\"sbd-page__context\">\n\n <!-- Tab bar -->\n <div class=\"sbd-page__context-tabs\">\n <button class=\"sbd-page__context-tab\"\n [class.sbd-page__context-tab--active]=\"activeContextTab() === 'changes'\"\n (click)=\"activeContextTab.set('changes')\">\n <i class=\"pi pi-history\"></i>\n Changes\n @if (bookingHistory().length > 0) {\n <span class=\"sbd-page__context-pill sbd-page__context-pill--changes\">{{ bookingHistory().length }}</span>\n }\n </button>\n <button class=\"sbd-page__context-tab\"\n [class.sbd-page__context-tab--active]=\"activeContextTab() === 'notes'\"\n (click)=\"activeContextTab.set('notes')\">\n <i class=\"pi pi-comments\"></i>\n Notes\n <span class=\"sbd-page__context-pill sbd-page__context-pill--notes\">{{ bookingNotes().length }}</span>\n </button>\n @if (activeContextTab() === 'notes') {\n <button pButton label=\"Add Note\" icon=\"pi pi-plus\" class=\"p-button-sm p-button-outlined sbd-page__context-add\"\n (click)=\"addNoteDialogOpen.set(true)\">\n </button>\n }\n </div>\n\n <!-- Notes tab -->\n @if (activeContextTab() === 'notes') {\n <div class=\"sbd-page__notes-list\">\n @if (bookingNotes().length === 0) {\n <div class=\"sbd-page__context-empty\">\n <i class=\"pi pi-inbox\"></i> No notes yet\n </div>\n }\n @for (note of bookingNotes(); track $index) {\n <div class=\"sbd-page__note\">\n <div class=\"sbd-page__note-top\">\n <span class=\"sbd-page__note-badge sbd-page__note-badge--{{ note.action | lowercase }}\">\n {{ note.action }}\n </span>\n <span class=\"sbd-page__note-author\">\n {{ note.writtenBy?.firstName }} {{ note.writtenBy?.lastName }}\n </span>\n <span class=\"sbd-page__note-date\">{{ fmtNoteDate(note.date) }}</span>\n </div>\n <p class=\"sbd-page__note-msg\">{{ note.message }}</p>\n </div>\n }\n </div>\n }\n\n <!-- Changes tab -->\n @if (activeContextTab() === 'changes') {\n <div class=\"sbd-page__changes-groups\">\n @if (historyGroups().length === 0) {\n <div class=\"sbd-page__context-empty\">\n <i class=\"pi pi-check\"></i> No changes recorded\n </div>\n }\n @for (group of historyGroups(); track group.changedAt) {\n <div class=\"sbd-page__changes-group\">\n <div class=\"sbd-page__changes-meta\">\n <i class=\"pi pi-user\"></i>\n <strong>{{ group.changedBy }}</strong>\n <span class=\"sbd-page__changes-sep\">\u00B7</span>\n <span>{{ fmtDate(group.changedAt) }}</span>\n </div>\n <table class=\"sbd-page__changes-table\">\n <thead>\n <tr>\n <th>Field</th>\n <th><i class=\"pi pi-times-circle\"></i> Before</th>\n <th><i class=\"pi pi-check-circle\"></i> After</th>\n </tr>\n </thead>\n <tbody>\n @for (entry of group.entries; track entry.field) {\n <tr>\n <td class=\"sbd-page__changes-field\">{{ formatField(entry.field) }}</td>\n <td class=\"sbd-page__changes-old\">{{ entry.from }}</td>\n <td class=\"sbd-page__changes-new\">{{ entry.to }}</td>\n </tr>\n }\n </tbody>\n </table>\n </div>\n }\n </div>\n }\n\n </div>\n\n }\n\n <!-- Loading skeleton for main -->\n @if (bookingStatus() === 'loading') {\n <div class=\"sbd-page__skeleton-card\">\n <div class=\"sbd-page__skeleton-row\" style=\"width:40%\"></div>\n <div class=\"sbd-page__skeleton-row\" style=\"width:25%\"></div>\n </div>\n }\n\n </main>\n\n </div>\n }\n\n</div>\n\n<app-sbd-cancel-dialog\n [visible]=\"cancelDialogOpen() && product() === 'flight'\"\n [bookingId]=\"bookingId()\"\n [product]=\"fcrProduct()\"\n [pnrInfo]=\"cancelPnrInfo()\"\n [bookingInfo]=\"bookingData()\"\n (closed)=\"cancelDialogOpen.set(false)\"\n (confirmed)=\"bookingStatus.set('idle'); bookingData.set(null)\"\n/>\n\n<almatar-hotel-auto-cancellation\n *ngIf=\"cancelDialogOpen() && product() === 'hotel'\"\n [selectedHotelBooking]=\"bookingData()\"\n (closed)=\"cancelDialogOpen.set(false)\"\n (cancellationSuccess)=\"bookingStatus.set('idle'); bookingData.set(null)\"\n/>\n\n<app-sbd-action-dialog\n [visible]=\"actionDialogOpen()\"\n [bookingId]=\"bookingId()\"\n [product]=\"fcrProduct()\"\n [actions]=\"availableActions()\"\n [initialKey]=\"selectedActionKey()\"\n [preloadedData]=\"bookingData()\"\n (closed)=\"actionDialogOpen.set(false)\"\n/>\n\n<app-sbd-add-note-dialog\n [visible]=\"addNoteDialogOpen()\"\n [bookingId]=\"bookingId()\"\n [product]=\"fcrProduct()\"\n (closed)=\"addNoteDialogOpen.set(false)\"\n/>\n\n<app-sbd-reissue-dialog\n [visible]=\"reissueDialogOpen()\"\n [bookingId]=\"bookingId()\"\n [bookingData]=\"bookingData()\"\n (closed)=\"reissueDialogOpen.set(false)\"\n/>\n", styles: [".sbd-page{display:flex;flex-direction:column;gap:20px;padding:24px;max-width:1400px;min-height:100%}.sbd-page__search{width:100%}.sbd-page__error{display:flex;align-items:center;gap:10px;padding:16px 20px;background:#fef2f2;border:1px solid rgba(239,68,68,.2);border-radius:10px;color:#ef4444;font-size:13.5px;font-weight:500}.sbd-page__error i{font-size:18px}.sbd-page__content{display:grid;grid-template-columns:320px 1fr;gap:20px;align-items:start}@media (max-width: 960px){.sbd-page__content{grid-template-columns:1fr}}.sbd-page__aside{display:flex;flex-direction:column;gap:16px;position:sticky;top:20px}.sbd-page__main{display:flex;flex-direction:column;gap:16px}.sbd-page__quick-actions{display:flex;align-items:center;gap:12px;padding:12px 16px;background:#fff;border:1px solid #e2e8f0;border-radius:10px;flex-wrap:wrap}.sbd-page__quick-label{font-size:11.5px;font-weight:700;text-transform:uppercase;letter-spacing:.05em;color:#94a3b8;flex-shrink:0}.sbd-page__context{background:#fff;border:1px solid #e2e8f0;border-radius:12px;overflow:hidden}.sbd-page__context-tabs{display:flex;align-items:center;border-bottom:1px solid #e2e8f0;background:#f8fafc}.sbd-page__context-add{margin-left:auto;margin-right:10px}.sbd-page__context-tab{display:flex;align-items:center;gap:7px;padding:11px 20px;font-size:13px;font-weight:600;color:#64748b;background:transparent;border:none;cursor:pointer;border-bottom:2px solid transparent;margin-bottom:-1px;transition:color .15s,border-color .15s}.sbd-page__context-tab .pi{font-size:13px}.sbd-page__context-tab:hover{color:#334155}.sbd-page__context-tab--active{color:#1e2e4a;border-bottom-color:var(--sbd-primary, #3b82f6);background:#fff}.sbd-page__context-pill{font-size:10.5px;font-weight:700;padding:1px 7px;border-radius:10px}.sbd-page__context-pill--notes{background:#e0e7ff;color:#4338ca}.sbd-page__context-pill--changes{background:#fef3c7;color:#b45309}.sbd-page__context-empty{display:flex;align-items:center;gap:8px;padding:24px 20px;font-size:13px;color:#94a3b8}.sbd-page__context-empty .pi{font-size:16px}.sbd-page__notes-list{display:flex;flex-direction:column}.sbd-page__note{padding:12px 16px;border-bottom:1px solid #f1f5f9;display:flex;flex-direction:column;gap:6px}.sbd-page__note:last-child{border-bottom:none}.sbd-page__note-top{display:flex;align-items:center;gap:8px}.sbd-page__note-badge{font-size:10px;font-weight:800;letter-spacing:.05em;padding:2px 8px;border-radius:10px;text-transform:uppercase;flex-shrink:0}.sbd-page__note-badge--general{background:#dbeafe;color:#1d4ed8}.sbd-page__note-badge--remark{background:#fef3c7;color:#b45309}.sbd-page__note-badge--feedback{background:#f3e8ff;color:#7e22ce}.sbd-page__note-author{font-size:12px;font-weight:700;color:#1e2e4a}.sbd-page__note-date{margin-left:auto;font-size:11px;color:#94a3b8;white-space:nowrap}.sbd-page__note-msg{margin:0;font-size:13px;color:#334155;line-height:1.55}.sbd-page__changes-groups{display:flex;flex-direction:column}.sbd-page__changes-group{border-bottom:1px solid #f1f5f9}.sbd-page__changes-group:last-child{border-bottom:none}.sbd-page__changes-meta{display:flex;align-items:center;gap:6px;padding:8px 16px;background:#fafafa;border-bottom:1px solid #f1f5f9;font-size:11.5px;color:#64748b}.sbd-page__changes-meta strong{font-weight:700;color:#334155}.sbd-page__changes-meta .pi{font-size:11px;color:#94a3b8}.sbd-page__changes-sep{color:#cbd5e1}.sbd-page__changes-table{width:100%;border-collapse:collapse;font-size:12.5px}.sbd-page__changes-table thead tr{background:#f8fafc;border-bottom:1px solid #e2e8f0}.sbd-page__changes-table thead th{padding:7px 14px;text-align:left;font-size:10.5px;font-weight:800;text-transform:uppercase;letter-spacing:.06em;color:#64748b;white-space:nowrap}.sbd-page__changes-table thead th .pi{margin-right:4px;font-size:10px}.sbd-page__changes-table thead th:nth-child(2){color:#dc2626}.sbd-page__changes-table thead th:nth-child(3){color:#16a34a}.sbd-page__changes-table tbody tr{border-bottom:1px solid #f1f5f9}.sbd-page__changes-table tbody tr:last-child{border-bottom:none}.sbd-page__changes-table tbody tr:hover{background:#f8fafc}.sbd-page__changes-table tbody td{padding:8px 14px;vertical-align:top;word-break:break-word}.sbd-page__changes-field{font-size:12px;font-weight:600;color:#475569;width:28%}.sbd-page__changes-old{color:#dc2626;font-weight:500;text-decoration:line-through;opacity:.8;width:36%}.sbd-page__changes-new{color:#16a34a;font-weight:700;width:36%}.sbd-page__content--loading{opacity:.6;pointer-events:none}.sbd-page__skeleton-card{background:#fff;border:1px solid #e2e8f0;border-radius:12px;padding:20px;display:flex;flex-direction:column;gap:12px}.sbd-page__skeleton-row{height:13px;background:#f1f5f9;border-radius:6px;animation:sbd-shimmer 1.4s ease-in-out infinite}.sbd-page__skeleton-grid{display:grid;grid-template-columns:repeat(5,1fr);gap:10px;margin-top:8px}.sbd-page__skeleton-chip{height:56px;background:#f1f5f9;border-radius:8px;animation:sbd-shimmer 1.4s ease-in-out infinite}@keyframes sbd-shimmer{0%,to{opacity:1}50%{opacity:.45}}@keyframes sbd-fadein{0%{opacity:0;transform:translateY(-4px)}to{opacity:1;transform:translateY(0)}}\n"] }]
|
|
8410
8594
|
}], propDecorators: { onKeydown: [{
|
|
8411
8595
|
type: HostListener,
|
|
8412
8596
|
args: ['document:keydown', ['$event']]
|
|
@@ -8445,5 +8629,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.14", ngImpo
|
|
|
8445
8629
|
* Generated bundle index. Do not edit.
|
|
8446
8630
|
*/
|
|
8447
8631
|
|
|
8448
|
-
export { SBD_CONFIG, SBD_DEFAULT_CONFIG, SBD_TOAST_HANDLER, SmartBookingDashboardComponent, SmartBookingDashboardModule, appendAuthParams, buildReissueBookingContext, buildReissueSearchParams, buildReissueSearchUrl, provideSmartBookingDashboard, smartBookingDashboardRoutes };
|
|
8632
|
+
export { SBD_CONFIG, SBD_DEFAULT_CONFIG, SBD_TOAST_HANDLER, SbdBrandService, SmartBookingDashboardComponent, SmartBookingDashboardModule, appendAuthParams, buildReissueBookingContext, buildReissueSearchParams, buildReissueSearchUrl, provideSmartBookingDashboard, smartBookingDashboardRoutes };
|
|
8449
8633
|
//# sourceMappingURL=almatar-smart-booking-dashboard.mjs.map
|