@propbinder/mobile-design 0.3.37 → 0.3.39

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.
@@ -1,5 +1,5 @@
1
1
  import * as i0 from '@angular/core';
2
- import { signal, computed, effect, Injectable, inject, Input, Component, input, output, Directive, EventEmitter, HostListener, Output, PLATFORM_ID, ElementRef, CUSTOM_ELEMENTS_SCHEMA, TemplateRef, ContentChild, forwardRef, ViewChild, afterNextRender, ViewEncapsulation, model, createComponent, ChangeDetectionStrategy, NgZone, Pipe, HostBinding, InjectionToken } from '@angular/core';
2
+ import { signal, computed, effect, Injectable, inject, Input, Component, input, output, Directive, EventEmitter, HostListener, Output, PLATFORM_ID, ElementRef, CUSTOM_ELEMENTS_SCHEMA, TemplateRef, ContentChild, forwardRef, ViewChild, afterNextRender, ViewEncapsulation, model, createComponent, ChangeDetectionStrategy, NgZone, HostBinding, Pipe, InjectionToken } from '@angular/core';
3
3
  import * as i1$1 from '@angular/common';
4
4
  import { CommonModule, isPlatformBrowser } from '@angular/common';
5
5
  import * as i1$3 from '@angular/router';
@@ -6186,7 +6186,7 @@ class DsMobilePageMainComponent extends MobilePageBase {
6186
6186
 
6187
6187
  <!-- Pull to refresh (only on native iOS/Android) -->
6188
6188
  @if (showRefresh() && isNativePlatform()) {
6189
- <ion-refresher slot="fixed" (ionRefresh)="handleRefresh($event)" [pullFactor]="0.4" [pullMin]="80" [pullMax]="240" closeDuration="600ms">
6189
+ <ion-refresher slot="fixed" (ionRefresh)="handleRefresh($event)" [pullFactor]="0.5" [pullMin]="80" [pullMax]="240" [snapbackDuration]="'280ms'" closeDuration="280ms">
6190
6190
  <ion-refresher-content pullingIcon="remixArrowDownS" refreshingSpinner="crescent"> </ion-refresher-content>
6191
6191
  </ion-refresher>
6192
6192
  }
@@ -6275,7 +6275,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
6275
6275
 
6276
6276
  <!-- Pull to refresh (only on native iOS/Android) -->
6277
6277
  @if (showRefresh() && isNativePlatform()) {
6278
- <ion-refresher slot="fixed" (ionRefresh)="handleRefresh($event)" [pullFactor]="0.4" [pullMin]="80" [pullMax]="240" closeDuration="600ms">
6278
+ <ion-refresher slot="fixed" (ionRefresh)="handleRefresh($event)" [pullFactor]="0.5" [pullMin]="80" [pullMax]="240" [snapbackDuration]="'280ms'" closeDuration="280ms">
6279
6279
  <ion-refresher-content pullingIcon="remixArrowDownS" refreshingSpinner="crescent"> </ion-refresher-content>
6280
6280
  </ion-refresher>
6281
6281
  }
@@ -6727,10 +6727,11 @@ class DsMobilePageDetailsComponent extends MobilePageBase {
6727
6727
  <ion-refresher
6728
6728
  slot="fixed"
6729
6729
  (ionRefresh)="handleRefresh($event)"
6730
- [pullFactor]="0.4"
6730
+ [pullFactor]="0.5"
6731
6731
  [pullMin]="80"
6732
6732
  [pullMax]="240"
6733
- closeDuration="600ms">
6733
+ [snapbackDuration]="'280ms'"
6734
+ closeDuration="280ms">
6734
6735
  <ion-refresher-content
6735
6736
  pullingIcon="remixArrowDownS"
6736
6737
  refreshingSpinner="crescent">
@@ -6819,10 +6820,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
6819
6820
  <ion-refresher
6820
6821
  slot="fixed"
6821
6822
  (ionRefresh)="handleRefresh($event)"
6822
- [pullFactor]="0.4"
6823
+ [pullFactor]="0.5"
6823
6824
  [pullMin]="80"
6824
6825
  [pullMax]="240"
6825
- closeDuration="600ms">
6826
+ [snapbackDuration]="'280ms'"
6827
+ closeDuration="280ms">
6826
6828
  <ion-refresher-content
6827
6829
  pullingIcon="remixArrowDownS"
6828
6830
  refreshingSpinner="crescent">
@@ -22211,6 +22213,7 @@ class DsMobilePostDetailModalComponent {
22211
22213
  */
22212
22214
  cancelEdit() {
22213
22215
  this.editingComment.set(null);
22216
+ this.replyingTo.set(null);
22214
22217
  this.commentText.set('');
22215
22218
  }
22216
22219
  /**
@@ -22219,6 +22222,17 @@ class DsMobilePostDetailModalComponent {
22219
22222
  handleEditComment(comment) {
22220
22223
  // Clear reply state if active
22221
22224
  this.replyingTo.set(null);
22225
+ let contentToEdit = comment.content;
22226
+ const possibleNames = [this.post().authorName, ...(this.post().comments?.map((c) => c.authorName) || [])];
22227
+ const uniqueNames = Array.from(new Set(possibleNames)).sort((a, b) => b.length - a.length);
22228
+ for (const author of uniqueNames) {
22229
+ const tagPrefix = `@${author} `;
22230
+ if (contentToEdit.startsWith(tagPrefix)) {
22231
+ this.replyingTo.set({ authorName: author, content: '' });
22232
+ contentToEdit = contentToEdit.substring(tagPrefix.length);
22233
+ break;
22234
+ }
22235
+ }
22222
22236
  // Set edit state
22223
22237
  this.editingComment.set({
22224
22238
  id: comment.id,
@@ -22227,7 +22241,7 @@ class DsMobilePostDetailModalComponent {
22227
22241
  timestamp: comment.timestamp,
22228
22242
  });
22229
22243
  // Populate the input with existing content
22230
- this.commentText.set(comment.content);
22244
+ this.commentText.set(contentToEdit);
22231
22245
  // Focus the input, show keyboard, and auto-resize
22232
22246
  setTimeout(() => {
22233
22247
  if (this.commentInput?.nativeElement) {
@@ -22297,10 +22311,12 @@ class DsMobilePostDetailModalComponent {
22297
22311
  // console.log('[PostDetailModal] Updating comment:', text);
22298
22312
  const editing = this.editingComment();
22299
22313
  const updatedComments = currentPost.comments?.map((comment) => {
22300
- if (comment.id && editing.id && comment.id === editing.id) {
22314
+ const matchesId = comment.id && editing.id && comment.id === editing.id;
22315
+ const matchesContent = !comment.id && !editing.id && comment.authorName === editing.authorName && comment.content === editing.originalContent;
22316
+ if (matchesId || matchesContent) {
22301
22317
  return {
22302
22318
  ...comment,
22303
- content: text,
22319
+ content: finalText,
22304
22320
  timestamp: `${this.textJustNow} (${this.textEdited})`,
22305
22321
  };
22306
22322
  }
@@ -22318,6 +22334,7 @@ class DsMobilePostDetailModalComponent {
22318
22334
  });
22319
22335
  }
22320
22336
  this.editingComment.set(null);
22337
+ this.replyingTo.set(null);
22321
22338
  }
22322
22339
  else {
22323
22340
  // console.log('[PostDetailModal] Submitting comment:', finalText);
@@ -22552,8 +22569,10 @@ class DsMobilePostDetailModalComponent {
22552
22569
  <ds-icon name="remixCloseLine" size="16px" />
22553
22570
  </button>
22554
22571
  </div>
22555
- } @else if (replyingTo()) {
22572
+ }
22573
+
22556
22574
  <!-- Reply indicator -->
22575
+ @if (replyingTo()) {
22557
22576
  <div class="reply-indicator">
22558
22577
  <div class="reply-indicator-content">
22559
22578
  <ds-icon name="remixReplyLine" size="16px" />
@@ -22698,8 +22717,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
22698
22717
  <ds-icon name="remixCloseLine" size="16px" />
22699
22718
  </button>
22700
22719
  </div>
22701
- } @else if (replyingTo()) {
22720
+ }
22721
+
22702
22722
  <!-- Reply indicator -->
22723
+ @if (replyingTo()) {
22703
22724
  <div class="reply-indicator">
22704
22725
  <div class="reply-indicator-content">
22705
22726
  <ds-icon name="remixReplyLine" size="16px" />
@@ -24210,7 +24231,7 @@ class DsMobileBookingModalComponent {
24210
24231
  </ds-button>
24211
24232
  </div>
24212
24233
  </ds-mobile-modal-base>
24213
- `, isInline: true, styles: [".date-item{display:flex;flex-direction:column;align-items:center;justify-content:center;width:80px;padding:12px 8px;border-radius:12px;border:1px solid var(--color-border, #e5e5e5);background:var(--color-surface-primary, #ffffff);cursor:pointer;transition:all .2s ease;-webkit-tap-highlight-color:transparent;gap:4px}.date-item .day-name{font-family:Brockmann,sans-serif;font-size:var(--font-size-xs, 12px);font-weight:400;color:var(--text-color-default-secondary, #71727a);text-transform:uppercase}.date-item .date-number{font-family:Brockmann,sans-serif;font-size:var(--font-size-xl, 20px);font-weight:600;color:var(--text-color-default-primary, #202227)}.date-item .month-name{font-family:Brockmann,sans-serif;font-size:var(--font-size-xs, 12px);font-weight:400;color:var(--text-color-default-secondary, #71727a);text-transform:capitalize}.date-item.selected{background:var(--color-accent, #5d5fef);border-color:var(--color-accent, #5d5fef)}.date-item.selected .day-name,.date-item.selected .date-number,.date-item.selected .month-name{color:#fff}.date-item.disabled{background:var(--color-background-neutral-secondary, #f5f5f5);border-color:var(--color-border, #e5e5e5);cursor:not-allowed;opacity:.6}.date-item.disabled .day-name,.date-item.disabled .date-number,.date-item.disabled .month-name{color:var(--text-color-default-tertiary, #9a9aa2)}.date-item:not(.disabled):not(.selected):hover{border-color:var(--color-accent, #5d5fef);background:var(--color-background-neutral-secondary, #f5f5f5)}.time-slots-list{display:flex;flex-direction:column;gap:8px}.time-slot-item{display:flex;align-items:center;justify-content:space-between;width:100%;padding:16px 20px;border-radius:12px;border:1px solid var(--color-border, #e5e5e5);background:var(--color-surface-primary, #ffffff);cursor:pointer;transition:all .2s ease;-webkit-tap-highlight-color:transparent}.time-slot-item span{font-family:Brockmann,sans-serif;font-size:var(--font-size-base, 16px);font-weight:400;color:var(--text-color-default-primary, #202227)}.time-slot-item.selected{background:var(--color-accent, #5d5fef);border-color:var(--color-accent, #5d5fef)}.time-slot-item.selected span{color:#fff;font-weight:500}.time-slot-item.disabled{background:var(--color-background-neutral-secondary, #f5f5f5);border-color:var(--color-border, #e5e5e5);cursor:not-allowed;opacity:.6}.time-slot-item.disabled span{color:var(--text-color-default-tertiary, #9a9aa2)}.time-slot-item:not(.disabled):not(.selected):hover{border-color:var(--color-accent, #5d5fef);background:var(--color-background-neutral-secondary, #f5f5f5)}.booking-confirm-action{width:100%;padding:16px 20px;background:var(--color-surface-primary, #ffffff);border-top:1px solid var(--color-border, #e5e5e5);box-sizing:border-box}.booking-confirm-action ::ng-deep ds-button{display:block;width:100%}.booking-confirm-action ::ng-deep ds-button button{width:100%;border-radius:100px;height:40px}::ng-deep .date-swiper .swiper-slide{width:auto!important}.calendar-link{display:flex;align-items:center;gap:2px;font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;color:var(--color-accent, #5d5fef);cursor:pointer;white-space:nowrap;-webkit-user-select:none;user-select:none;line-height:1}::ng-deep .cdk-overlay-container,::ng-deep .floating-container,::ng-deep [data-floating-ui],::ng-deep .ds-select__dropdown{z-index:20005!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsMobileModalBaseComponent, selector: "ds-mobile-modal-base", inputs: ["headerTitleInteractive", "textLoading", "textErrorTitle", "showHeader"], outputs: ["titleClick"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileSwiperComponent, selector: "ds-mobile-swiper", inputs: ["slideWidth", "gap", "pagination", "autoHeight", "progressiveOpacity", "progressiveScale"] }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsButtonComponent, selector: "ds-button", inputs: ["variant", "size", "disabled", "loading", "pressed", "expanded", "leadingIcon", "trailingIcon", "ariaLabel", "iconOnly"], outputs: ["clicked", "focused", "blurred"] }, { kind: "component", type: DsDatepickerComponent, selector: "ds-datepicker", inputs: ["variant", "disabled", "placeholder", "ariaLabel", "ariaDescribedBy", "disableFutureDates", "disablePastDates", "isDateDisabled", "locale"], outputs: ["dateChange", "opened", "closed"] }] });
24234
+ `, isInline: true, styles: [".date-item{display:flex;flex-direction:column;align-items:center;justify-content:center;width:80px;padding:12px 8px;border-radius:12px;border:1px solid var(--color-border, #e5e5e5);background:var(--color-surface-primary, #ffffff);cursor:pointer;transition:all .2s ease;-webkit-tap-highlight-color:transparent;gap:4px}.date-item .day-name{font-family:Brockmann,sans-serif;font-size:var(--font-size-xs, 12px);font-weight:400;color:var(--text-color-default-secondary, #71727a);text-transform:uppercase}.date-item .date-number{font-family:Brockmann,sans-serif;font-size:var(--font-size-xl, 20px);font-weight:600;color:var(--text-color-default-primary, #202227)}.date-item .month-name{font-family:Brockmann,sans-serif;font-size:var(--font-size-xs, 12px);font-weight:400;color:var(--text-color-default-secondary, #71727a);text-transform:capitalize}.date-item.selected{background:var(--color-accent, #5d5fef);border-color:var(--color-accent, #5d5fef)}.date-item.selected .day-name,.date-item.selected .date-number,.date-item.selected .month-name{color:#fff}.date-item.disabled{background:var(--color-background-neutral-secondary, #f5f5f5);border-color:var(--color-border, #e5e5e5);cursor:not-allowed;opacity:.6}.date-item.disabled .day-name,.date-item.disabled .date-number,.date-item.disabled .month-name{color:var(--text-color-default-tertiary, #9a9aa2)}.date-item:not(.disabled):not(.selected):hover{border-color:var(--color-accent, #5d5fef);background:var(--color-background-neutral-secondary, #f5f5f5)}.time-slots-list{display:flex;flex-direction:column;gap:8px}.time-slot-item{display:flex;align-items:center;justify-content:space-between;width:100%;padding:16px 20px;border-radius:12px;border:1px solid var(--color-border, #e5e5e5);background:var(--color-surface-primary, #ffffff);cursor:pointer;transition:all .2s ease;-webkit-tap-highlight-color:transparent}.time-slot-item span{font-family:Brockmann,sans-serif;font-size:var(--font-size-base, 16px);font-weight:400;color:var(--text-color-default-primary, #202227)}.time-slot-item.selected{background:var(--color-accent, #5d5fef);border-color:var(--color-accent, #5d5fef)}.time-slot-item.selected span{color:#fff;font-weight:500}.time-slot-item.disabled{background:var(--color-background-neutral-secondary, #f5f5f5);border-color:var(--color-border, #e5e5e5);cursor:not-allowed;opacity:.6}.time-slot-item.disabled span{color:var(--text-color-default-tertiary, #9a9aa2)}.time-slot-item:not(.disabled):not(.selected):hover{border-color:var(--color-accent, #5d5fef);background:var(--color-background-neutral-secondary, #f5f5f5)}.booking-confirm-action{width:100%;padding:16px 20px;background:var(--color-surface-primary, #ffffff);border-top:1px solid var(--color-border, #e5e5e5);box-sizing:border-box}.booking-confirm-action ::ng-deep ds-button{display:block;width:100%}.booking-confirm-action ::ng-deep ds-button button{width:100%;border-radius:100px;height:40px}::ng-deep .date-swiper .swiper-slide{width:auto!important}.calendar-link{display:flex;align-items:center;gap:2px;font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;color:var(--color-accent, #5d5fef);cursor:pointer;white-space:nowrap;-webkit-user-select:none;user-select:none;line-height:1}::ng-deep .cdk-overlay-container,::ng-deep .floating-container,::ng-deep [data-floating-ui]{z-index:20005!important}::ng-deep .ds-select_dropdown,::ng-deep .ds-select__dropdown,::ng-deep [ngpselectdropdown]{z-index:20010!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsMobileModalBaseComponent, selector: "ds-mobile-modal-base", inputs: ["headerTitleInteractive", "textLoading", "textErrorTitle", "showHeader"], outputs: ["titleClick"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileSwiperComponent, selector: "ds-mobile-swiper", inputs: ["slideWidth", "gap", "pagination", "autoHeight", "progressiveOpacity", "progressiveScale"] }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsButtonComponent, selector: "ds-button", inputs: ["variant", "size", "disabled", "loading", "pressed", "expanded", "leadingIcon", "trailingIcon", "ariaLabel", "iconOnly"], outputs: ["clicked", "focused", "blurred"] }, { kind: "component", type: DsDatepickerComponent, selector: "ds-datepicker", inputs: ["variant", "disabled", "placeholder", "ariaLabel", "ariaDescribedBy", "disableFutureDates", "disablePastDates", "isDateDisabled", "locale"], outputs: ["dateChange", "opened", "closed"] }] });
24214
24235
  }
24215
24236
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingModalComponent, decorators: [{
24216
24237
  type: Component,
@@ -24294,7 +24315,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
24294
24315
  </ds-button>
24295
24316
  </div>
24296
24317
  </ds-mobile-modal-base>
24297
- `, styles: [".date-item{display:flex;flex-direction:column;align-items:center;justify-content:center;width:80px;padding:12px 8px;border-radius:12px;border:1px solid var(--color-border, #e5e5e5);background:var(--color-surface-primary, #ffffff);cursor:pointer;transition:all .2s ease;-webkit-tap-highlight-color:transparent;gap:4px}.date-item .day-name{font-family:Brockmann,sans-serif;font-size:var(--font-size-xs, 12px);font-weight:400;color:var(--text-color-default-secondary, #71727a);text-transform:uppercase}.date-item .date-number{font-family:Brockmann,sans-serif;font-size:var(--font-size-xl, 20px);font-weight:600;color:var(--text-color-default-primary, #202227)}.date-item .month-name{font-family:Brockmann,sans-serif;font-size:var(--font-size-xs, 12px);font-weight:400;color:var(--text-color-default-secondary, #71727a);text-transform:capitalize}.date-item.selected{background:var(--color-accent, #5d5fef);border-color:var(--color-accent, #5d5fef)}.date-item.selected .day-name,.date-item.selected .date-number,.date-item.selected .month-name{color:#fff}.date-item.disabled{background:var(--color-background-neutral-secondary, #f5f5f5);border-color:var(--color-border, #e5e5e5);cursor:not-allowed;opacity:.6}.date-item.disabled .day-name,.date-item.disabled .date-number,.date-item.disabled .month-name{color:var(--text-color-default-tertiary, #9a9aa2)}.date-item:not(.disabled):not(.selected):hover{border-color:var(--color-accent, #5d5fef);background:var(--color-background-neutral-secondary, #f5f5f5)}.time-slots-list{display:flex;flex-direction:column;gap:8px}.time-slot-item{display:flex;align-items:center;justify-content:space-between;width:100%;padding:16px 20px;border-radius:12px;border:1px solid var(--color-border, #e5e5e5);background:var(--color-surface-primary, #ffffff);cursor:pointer;transition:all .2s ease;-webkit-tap-highlight-color:transparent}.time-slot-item span{font-family:Brockmann,sans-serif;font-size:var(--font-size-base, 16px);font-weight:400;color:var(--text-color-default-primary, #202227)}.time-slot-item.selected{background:var(--color-accent, #5d5fef);border-color:var(--color-accent, #5d5fef)}.time-slot-item.selected span{color:#fff;font-weight:500}.time-slot-item.disabled{background:var(--color-background-neutral-secondary, #f5f5f5);border-color:var(--color-border, #e5e5e5);cursor:not-allowed;opacity:.6}.time-slot-item.disabled span{color:var(--text-color-default-tertiary, #9a9aa2)}.time-slot-item:not(.disabled):not(.selected):hover{border-color:var(--color-accent, #5d5fef);background:var(--color-background-neutral-secondary, #f5f5f5)}.booking-confirm-action{width:100%;padding:16px 20px;background:var(--color-surface-primary, #ffffff);border-top:1px solid var(--color-border, #e5e5e5);box-sizing:border-box}.booking-confirm-action ::ng-deep ds-button{display:block;width:100%}.booking-confirm-action ::ng-deep ds-button button{width:100%;border-radius:100px;height:40px}::ng-deep .date-swiper .swiper-slide{width:auto!important}.calendar-link{display:flex;align-items:center;gap:2px;font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;color:var(--color-accent, #5d5fef);cursor:pointer;white-space:nowrap;-webkit-user-select:none;user-select:none;line-height:1}::ng-deep .cdk-overlay-container,::ng-deep .floating-container,::ng-deep [data-floating-ui],::ng-deep .ds-select__dropdown{z-index:20005!important}\n"] }]
24318
+ `, styles: [".date-item{display:flex;flex-direction:column;align-items:center;justify-content:center;width:80px;padding:12px 8px;border-radius:12px;border:1px solid var(--color-border, #e5e5e5);background:var(--color-surface-primary, #ffffff);cursor:pointer;transition:all .2s ease;-webkit-tap-highlight-color:transparent;gap:4px}.date-item .day-name{font-family:Brockmann,sans-serif;font-size:var(--font-size-xs, 12px);font-weight:400;color:var(--text-color-default-secondary, #71727a);text-transform:uppercase}.date-item .date-number{font-family:Brockmann,sans-serif;font-size:var(--font-size-xl, 20px);font-weight:600;color:var(--text-color-default-primary, #202227)}.date-item .month-name{font-family:Brockmann,sans-serif;font-size:var(--font-size-xs, 12px);font-weight:400;color:var(--text-color-default-secondary, #71727a);text-transform:capitalize}.date-item.selected{background:var(--color-accent, #5d5fef);border-color:var(--color-accent, #5d5fef)}.date-item.selected .day-name,.date-item.selected .date-number,.date-item.selected .month-name{color:#fff}.date-item.disabled{background:var(--color-background-neutral-secondary, #f5f5f5);border-color:var(--color-border, #e5e5e5);cursor:not-allowed;opacity:.6}.date-item.disabled .day-name,.date-item.disabled .date-number,.date-item.disabled .month-name{color:var(--text-color-default-tertiary, #9a9aa2)}.date-item:not(.disabled):not(.selected):hover{border-color:var(--color-accent, #5d5fef);background:var(--color-background-neutral-secondary, #f5f5f5)}.time-slots-list{display:flex;flex-direction:column;gap:8px}.time-slot-item{display:flex;align-items:center;justify-content:space-between;width:100%;padding:16px 20px;border-radius:12px;border:1px solid var(--color-border, #e5e5e5);background:var(--color-surface-primary, #ffffff);cursor:pointer;transition:all .2s ease;-webkit-tap-highlight-color:transparent}.time-slot-item span{font-family:Brockmann,sans-serif;font-size:var(--font-size-base, 16px);font-weight:400;color:var(--text-color-default-primary, #202227)}.time-slot-item.selected{background:var(--color-accent, #5d5fef);border-color:var(--color-accent, #5d5fef)}.time-slot-item.selected span{color:#fff;font-weight:500}.time-slot-item.disabled{background:var(--color-background-neutral-secondary, #f5f5f5);border-color:var(--color-border, #e5e5e5);cursor:not-allowed;opacity:.6}.time-slot-item.disabled span{color:var(--text-color-default-tertiary, #9a9aa2)}.time-slot-item:not(.disabled):not(.selected):hover{border-color:var(--color-accent, #5d5fef);background:var(--color-background-neutral-secondary, #f5f5f5)}.booking-confirm-action{width:100%;padding:16px 20px;background:var(--color-surface-primary, #ffffff);border-top:1px solid var(--color-border, #e5e5e5);box-sizing:border-box}.booking-confirm-action ::ng-deep ds-button{display:block;width:100%}.booking-confirm-action ::ng-deep ds-button button{width:100%;border-radius:100px;height:40px}::ng-deep .date-swiper .swiper-slide{width:auto!important}.calendar-link{display:flex;align-items:center;gap:2px;font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;color:var(--color-accent, #5d5fef);cursor:pointer;white-space:nowrap;-webkit-user-select:none;user-select:none;line-height:1}::ng-deep .cdk-overlay-container,::ng-deep .floating-container,::ng-deep [data-floating-ui]{z-index:20005!important}::ng-deep .ds-select_dropdown,::ng-deep .ds-select__dropdown,::ng-deep [ngpselectdropdown]{z-index:20010!important}\n"] }]
24298
24319
  }], ctorParameters: () => [{ type: i1.ModalController }], propDecorators: { facilityId: [{
24299
24320
  type: Input
24300
24321
  }], facilityTitle: [{
@@ -24674,6 +24695,465 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
24674
24695
  args: [{ providedIn: 'root' }]
24675
24696
  }], ctorParameters: () => [{ type: i1.ModalController }] });
24676
24697
 
24698
+ class DsMobileBookingDetailSheetComponent {
24699
+ modalController;
24700
+ /** `sheet` = bottom sheet. `modal` = `ds-modal-base` shell (active + history bookings). */
24701
+ presentation = 'sheet';
24702
+ data;
24703
+ /** When true the modal sizes to its content instead of filling the screen. */
24704
+ autoHeight = false;
24705
+ get isModalPresentation() {
24706
+ return this.presentation === 'modal';
24707
+ }
24708
+ constructor(modalController) {
24709
+ this.modalController = modalController;
24710
+ }
24711
+ close() {
24712
+ this.modalController.dismiss(null, 'backdrop');
24713
+ }
24714
+ cancelBooking() {
24715
+ this.modalController.dismiss(null, 'cancel');
24716
+ }
24717
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetComponent, deps: [{ token: i1.ModalController }], target: i0.ɵɵFactoryTarget.Component });
24718
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DsMobileBookingDetailSheetComponent, isStandalone: true, selector: "ds-mobile-booking-detail-sheet", inputs: { presentation: "presentation", data: "data", autoHeight: "autoHeight" }, host: { properties: { "class.presentation-modal": "this.isModalPresentation" } }, ngImport: i0, template: `
24719
+ @if (presentation === 'modal') {
24720
+ <ds-mobile-modal-base
24721
+ [headerTitle]="data.facilityTitle"
24722
+ [closeButtonLabel]="'Luk'"
24723
+ [isAutoHeight]="autoHeight"
24724
+ [keyboardContentBehavior]="'follow'">
24725
+
24726
+ <ds-mobile-section
24727
+ [showBorder]="false"
24728
+ padding="20px 20px 0 20px">
24729
+ <div class="hero-image-container">
24730
+ @if (data.heroImage) {
24731
+ <img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
24732
+ } @else {
24733
+ <div class="hero-image-placeholder">
24734
+ <ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
24735
+ </div>
24736
+ }
24737
+ </div>
24738
+ </ds-mobile-section>
24739
+
24740
+ <ds-mobile-section padding="20px 20px 20px 20px">
24741
+ <div class="booking-summary-card">
24742
+ <div class="details-section">
24743
+ <h3 class="details-heading">Booking detaljer</h3>
24744
+ <div class="info-rows">
24745
+ @if (data.bookingDate) {
24746
+ <div class="info-row">
24747
+ <ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
24748
+ <span>{{ data.bookingDate }}</span>
24749
+ </div>
24750
+ }
24751
+ @if (data.bookingTime) {
24752
+ <div class="info-row">
24753
+ <ds-icon name="remixTimeLine" size="16px" color="tertiary" />
24754
+ <span>{{ data.bookingTime }}</span>
24755
+ </div>
24756
+ }
24757
+ @if (data.price) {
24758
+ <div class="info-row">
24759
+ <ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
24760
+ <span>{{ data.price }}</span>
24761
+ </div>
24762
+ }
24763
+ @if (data.bookingType) {
24764
+ <div class="info-row">
24765
+ <ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
24766
+ <span>{{ data.bookingType }}</span>
24767
+ </div>
24768
+ }
24769
+ @for (req of data.requirements || []; track req) {
24770
+ <div class="info-row">
24771
+ <ds-icon name="remixLockLine" size="16px" color="tertiary" />
24772
+ <span>{{ req }}</span>
24773
+ </div>
24774
+ }
24775
+ </div>
24776
+ </div>
24777
+ </div>
24778
+ </ds-mobile-section>
24779
+
24780
+ @if (data.canCancel) {
24781
+ <div class="booking-action">
24782
+ <div class="booking-actions-row">
24783
+ <ds-button
24784
+ class="cancel-primary"
24785
+ size="md"
24786
+ variant="secondary"
24787
+ (clicked)="cancelBooking()">
24788
+ Annuller booking
24789
+ </ds-button>
24790
+ </div>
24791
+ </div>
24792
+ }
24793
+ </ds-mobile-modal-base>
24794
+ } @else {
24795
+ <ds-mobile-bottom-sheet-wrapper [showDragHandle]="true">
24796
+ <div class="detail-header">
24797
+ <h2 class="detail-title">{{ data.facilityTitle }}</h2>
24798
+ <ds-icon-button
24799
+ icon="remixCloseLine"
24800
+ variant="ghost"
24801
+ size="sm"
24802
+ (clicked)="close()"
24803
+ aria-label="Luk"
24804
+ />
24805
+ </div>
24806
+
24807
+ <div class="detail-content">
24808
+ <div class="hero-image-container">
24809
+ @if (data.heroImage) {
24810
+ <img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
24811
+ } @else {
24812
+ <div class="hero-image-placeholder">
24813
+ <ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
24814
+ </div>
24815
+ }
24816
+ </div>
24817
+
24818
+ <div class="booking-summary-card">
24819
+ <div class="details-section">
24820
+ <h3 class="details-heading">Booking detaljer</h3>
24821
+ <div class="info-rows">
24822
+ @if (data.bookingDate) {
24823
+ <div class="info-row">
24824
+ <ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
24825
+ <span>{{ data.bookingDate }}</span>
24826
+ </div>
24827
+ }
24828
+ @if (data.bookingTime) {
24829
+ <div class="info-row">
24830
+ <ds-icon name="remixTimeLine" size="16px" color="tertiary" />
24831
+ <span>{{ data.bookingTime }}</span>
24832
+ </div>
24833
+ }
24834
+ @if (data.price) {
24835
+ <div class="info-row">
24836
+ <ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
24837
+ <span>{{ data.price }}</span>
24838
+ </div>
24839
+ }
24840
+ @if (data.bookingType) {
24841
+ <div class="info-row">
24842
+ <ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
24843
+ <span>{{ data.bookingType }}</span>
24844
+ </div>
24845
+ }
24846
+ @for (req of data.requirements || []; track req) {
24847
+ <div class="info-row">
24848
+ <ds-icon name="remixLockLine" size="16px" color="tertiary" />
24849
+ <span>{{ req }}</span>
24850
+ </div>
24851
+ }
24852
+ </div>
24853
+ </div>
24854
+ </div>
24855
+
24856
+ @if (data.canCancel) {
24857
+ <div class="footer-button-container">
24858
+ <div class="booking-actions-column">
24859
+ <ds-button
24860
+ size="md"
24861
+ variant="secondary"
24862
+ (clicked)="cancelBooking()">
24863
+ Annuller booking
24864
+ </ds-button>
24865
+ </div>
24866
+ </div>
24867
+ }
24868
+ </div>
24869
+ </ds-mobile-bottom-sheet-wrapper>
24870
+ }
24871
+ `, isInline: true, styles: [":host{display:block;height:auto;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;box-sizing:border-box}.detail-header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px 8px}.detail-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-lg, 18px);font-weight:600;color:var(--text-color-default-primary, #202227);margin:0;flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding-right:12px}.detail-content{padding:8px 20px 24px;display:flex;flex-direction:column;gap:20px}.hero-image-container{width:100%;aspect-ratio:16 / 9;border-radius:12px;overflow:hidden;background:var(--color-surface-secondary, #f5f5f5)}.hero-image{width:100%;height:100%;object-fit:cover;display:block}.hero-image-placeholder{width:100%;height:100%;min-height:0;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,color-mix(in srgb,var(--color-accent, #6B5FF5) 30%,transparent),color-mix(in srgb,var(--color-accent, #6B5FF5) 60%,transparent))}.booking-summary-card{background:var(--color-background-neutral-secondary, #f5f5f5);border-radius:16px;padding:16px}.details-section{display:flex;flex-direction:column;gap:12px}.details-heading{font-family:Brockmann,sans-serif;font-size:var(--font-size-base, 16px);font-weight:600;color:var(--text-color-default-primary, #202227);margin:0}.info-rows{display:flex;flex-direction:column;gap:8px}.info-row{display:flex;align-items:center;gap:10px;font-family:Brockmann,sans-serif;font-size:var(--font-size-sm, 14px);color:var(--text-color-default-secondary, #545B66);line-height:1.4}.info-row ds-icon{flex-shrink:0}.footer-button-container{width:100%;padding:16px 20px 0}.footer-button-container ::ng-deep ds-button{display:block;width:100%}.footer-button-container ::ng-deep ds-button button{width:100%;border-radius:100px;height:44px;min-height:44px;max-height:44px}.booking-action{padding:16px 20px;padding-bottom:calc(16px + max(8px,env(safe-area-inset-bottom,0px) - 24px));background:var(--color-surface-primary, #ffffff)}.booking-actions-row{display:flex;flex-direction:row;align-items:center;gap:12px;width:100%}.booking-action .cancel-primary{flex:1;min-width:0;display:block}.booking-action .cancel-primary ::ng-deep button{width:100%;border-radius:100px;height:44px;min-height:44px;max-height:44px;padding-left:16px;padding-right:16px}:host.presentation-modal{display:block;height:auto;width:100%;min-height:0;overflow:hidden}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsMobileBottomSheetWrapperComponent, selector: "ds-mobile-bottom-sheet-wrapper", inputs: ["showDragHandle"] }, { kind: "component", type: DsMobileModalBaseComponent, selector: "ds-mobile-modal-base", inputs: ["headerTitleInteractive", "textLoading", "textErrorTitle", "showHeader"], outputs: ["titleClick"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsButtonComponent, selector: "ds-button", inputs: ["variant", "size", "disabled", "loading", "pressed", "expanded", "leadingIcon", "trailingIcon", "ariaLabel", "iconOnly"], outputs: ["clicked", "focused", "blurred"] }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsIconButtonComponent, selector: "ds-icon-button", inputs: ["variant", "size", "icon", "disabled", "loading", "pressed", "expanded", "ariaLabel", "tooltip", "tooltipDisabled", "tooltipPlacement"], outputs: ["clicked", "focused", "blurred"] }] });
24872
+ }
24873
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetComponent, decorators: [{
24874
+ type: Component,
24875
+ args: [{ selector: 'ds-mobile-booking-detail-sheet', standalone: true, imports: [
24876
+ CommonModule,
24877
+ DsMobileBottomSheetWrapperComponent,
24878
+ DsMobileModalBaseComponent,
24879
+ DsMobileSectionComponent,
24880
+ DsButtonComponent,
24881
+ DsIconComponent,
24882
+ DsIconButtonComponent,
24883
+ ], template: `
24884
+ @if (presentation === 'modal') {
24885
+ <ds-mobile-modal-base
24886
+ [headerTitle]="data.facilityTitle"
24887
+ [closeButtonLabel]="'Luk'"
24888
+ [isAutoHeight]="autoHeight"
24889
+ [keyboardContentBehavior]="'follow'">
24890
+
24891
+ <ds-mobile-section
24892
+ [showBorder]="false"
24893
+ padding="20px 20px 0 20px">
24894
+ <div class="hero-image-container">
24895
+ @if (data.heroImage) {
24896
+ <img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
24897
+ } @else {
24898
+ <div class="hero-image-placeholder">
24899
+ <ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
24900
+ </div>
24901
+ }
24902
+ </div>
24903
+ </ds-mobile-section>
24904
+
24905
+ <ds-mobile-section padding="20px 20px 20px 20px">
24906
+ <div class="booking-summary-card">
24907
+ <div class="details-section">
24908
+ <h3 class="details-heading">Booking detaljer</h3>
24909
+ <div class="info-rows">
24910
+ @if (data.bookingDate) {
24911
+ <div class="info-row">
24912
+ <ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
24913
+ <span>{{ data.bookingDate }}</span>
24914
+ </div>
24915
+ }
24916
+ @if (data.bookingTime) {
24917
+ <div class="info-row">
24918
+ <ds-icon name="remixTimeLine" size="16px" color="tertiary" />
24919
+ <span>{{ data.bookingTime }}</span>
24920
+ </div>
24921
+ }
24922
+ @if (data.price) {
24923
+ <div class="info-row">
24924
+ <ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
24925
+ <span>{{ data.price }}</span>
24926
+ </div>
24927
+ }
24928
+ @if (data.bookingType) {
24929
+ <div class="info-row">
24930
+ <ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
24931
+ <span>{{ data.bookingType }}</span>
24932
+ </div>
24933
+ }
24934
+ @for (req of data.requirements || []; track req) {
24935
+ <div class="info-row">
24936
+ <ds-icon name="remixLockLine" size="16px" color="tertiary" />
24937
+ <span>{{ req }}</span>
24938
+ </div>
24939
+ }
24940
+ </div>
24941
+ </div>
24942
+ </div>
24943
+ </ds-mobile-section>
24944
+
24945
+ @if (data.canCancel) {
24946
+ <div class="booking-action">
24947
+ <div class="booking-actions-row">
24948
+ <ds-button
24949
+ class="cancel-primary"
24950
+ size="md"
24951
+ variant="secondary"
24952
+ (clicked)="cancelBooking()">
24953
+ Annuller booking
24954
+ </ds-button>
24955
+ </div>
24956
+ </div>
24957
+ }
24958
+ </ds-mobile-modal-base>
24959
+ } @else {
24960
+ <ds-mobile-bottom-sheet-wrapper [showDragHandle]="true">
24961
+ <div class="detail-header">
24962
+ <h2 class="detail-title">{{ data.facilityTitle }}</h2>
24963
+ <ds-icon-button
24964
+ icon="remixCloseLine"
24965
+ variant="ghost"
24966
+ size="sm"
24967
+ (clicked)="close()"
24968
+ aria-label="Luk"
24969
+ />
24970
+ </div>
24971
+
24972
+ <div class="detail-content">
24973
+ <div class="hero-image-container">
24974
+ @if (data.heroImage) {
24975
+ <img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
24976
+ } @else {
24977
+ <div class="hero-image-placeholder">
24978
+ <ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
24979
+ </div>
24980
+ }
24981
+ </div>
24982
+
24983
+ <div class="booking-summary-card">
24984
+ <div class="details-section">
24985
+ <h3 class="details-heading">Booking detaljer</h3>
24986
+ <div class="info-rows">
24987
+ @if (data.bookingDate) {
24988
+ <div class="info-row">
24989
+ <ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
24990
+ <span>{{ data.bookingDate }}</span>
24991
+ </div>
24992
+ }
24993
+ @if (data.bookingTime) {
24994
+ <div class="info-row">
24995
+ <ds-icon name="remixTimeLine" size="16px" color="tertiary" />
24996
+ <span>{{ data.bookingTime }}</span>
24997
+ </div>
24998
+ }
24999
+ @if (data.price) {
25000
+ <div class="info-row">
25001
+ <ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
25002
+ <span>{{ data.price }}</span>
25003
+ </div>
25004
+ }
25005
+ @if (data.bookingType) {
25006
+ <div class="info-row">
25007
+ <ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
25008
+ <span>{{ data.bookingType }}</span>
25009
+ </div>
25010
+ }
25011
+ @for (req of data.requirements || []; track req) {
25012
+ <div class="info-row">
25013
+ <ds-icon name="remixLockLine" size="16px" color="tertiary" />
25014
+ <span>{{ req }}</span>
25015
+ </div>
25016
+ }
25017
+ </div>
25018
+ </div>
25019
+ </div>
25020
+
25021
+ @if (data.canCancel) {
25022
+ <div class="footer-button-container">
25023
+ <div class="booking-actions-column">
25024
+ <ds-button
25025
+ size="md"
25026
+ variant="secondary"
25027
+ (clicked)="cancelBooking()">
25028
+ Annuller booking
25029
+ </ds-button>
25030
+ </div>
25031
+ </div>
25032
+ }
25033
+ </div>
25034
+ </ds-mobile-bottom-sheet-wrapper>
25035
+ }
25036
+ `, styles: [":host{display:block;height:auto;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;box-sizing:border-box}.detail-header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px 8px}.detail-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-lg, 18px);font-weight:600;color:var(--text-color-default-primary, #202227);margin:0;flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding-right:12px}.detail-content{padding:8px 20px 24px;display:flex;flex-direction:column;gap:20px}.hero-image-container{width:100%;aspect-ratio:16 / 9;border-radius:12px;overflow:hidden;background:var(--color-surface-secondary, #f5f5f5)}.hero-image{width:100%;height:100%;object-fit:cover;display:block}.hero-image-placeholder{width:100%;height:100%;min-height:0;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,color-mix(in srgb,var(--color-accent, #6B5FF5) 30%,transparent),color-mix(in srgb,var(--color-accent, #6B5FF5) 60%,transparent))}.booking-summary-card{background:var(--color-background-neutral-secondary, #f5f5f5);border-radius:16px;padding:16px}.details-section{display:flex;flex-direction:column;gap:12px}.details-heading{font-family:Brockmann,sans-serif;font-size:var(--font-size-base, 16px);font-weight:600;color:var(--text-color-default-primary, #202227);margin:0}.info-rows{display:flex;flex-direction:column;gap:8px}.info-row{display:flex;align-items:center;gap:10px;font-family:Brockmann,sans-serif;font-size:var(--font-size-sm, 14px);color:var(--text-color-default-secondary, #545B66);line-height:1.4}.info-row ds-icon{flex-shrink:0}.footer-button-container{width:100%;padding:16px 20px 0}.footer-button-container ::ng-deep ds-button{display:block;width:100%}.footer-button-container ::ng-deep ds-button button{width:100%;border-radius:100px;height:44px;min-height:44px;max-height:44px}.booking-action{padding:16px 20px;padding-bottom:calc(16px + max(8px,env(safe-area-inset-bottom,0px) - 24px));background:var(--color-surface-primary, #ffffff)}.booking-actions-row{display:flex;flex-direction:row;align-items:center;gap:12px;width:100%}.booking-action .cancel-primary{flex:1;min-width:0;display:block}.booking-action .cancel-primary ::ng-deep button{width:100%;border-radius:100px;height:44px;min-height:44px;max-height:44px;padding-left:16px;padding-right:16px}:host.presentation-modal{display:block;height:auto;width:100%;min-height:0;overflow:hidden}\n"] }]
25037
+ }], ctorParameters: () => [{ type: i1.ModalController }], propDecorators: { presentation: [{
25038
+ type: Input
25039
+ }], data: [{
25040
+ type: Input
25041
+ }], autoHeight: [{
25042
+ type: Input
25043
+ }], isModalPresentation: [{
25044
+ type: HostBinding,
25045
+ args: ['class.presentation-modal']
25046
+ }] } });
25047
+
25048
+ class DsMobileBookingDetailSheetService extends BaseModalService {
25049
+ bottomSheet;
25050
+ constructor(modalController, bottomSheet) {
25051
+ super(modalController);
25052
+ this.bottomSheet = bottomSheet;
25053
+ }
25054
+ /**
25055
+ * Bottom-sheet presentation (draggable breakpoints). Prefer `openAsModal` for booking lists.
25056
+ */
25057
+ async open(data) {
25058
+ const modal = await this.bottomSheet.create({
25059
+ component: DsMobileBookingDetailSheetComponent,
25060
+ componentProps: { data },
25061
+ autoHeight: true,
25062
+ backdropDismiss: true,
25063
+ backdropBlur: true,
25064
+ });
25065
+ const result = await modal.onWillDismiss();
25066
+ return { role: result.role, data: result.data ?? undefined };
25067
+ }
25068
+ /** `ds-modal-base` shell — used for active and past bookings. Auto-heights to content. */
25069
+ async openAsModal(data) {
25070
+ const modal = await this.createModal(DsMobileBookingDetailSheetComponent, { data, presentation: 'modal', autoHeight: true }, { keyboardClose: true, autoHeight: true });
25071
+ await modal.present();
25072
+ const result = await modal.onWillDismiss();
25073
+ return { role: result.role, data: result.data ?? undefined };
25074
+ }
25075
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetService, deps: [{ token: i1.ModalController }, { token: DsMobileBottomSheetService }], target: i0.ɵɵFactoryTarget.Injectable });
25076
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetService, providedIn: 'root' });
25077
+ }
25078
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetService, decorators: [{
25079
+ type: Injectable,
25080
+ args: [{
25081
+ providedIn: 'root',
25082
+ }]
25083
+ }], ctorParameters: () => [{ type: i1.ModalController }, { type: DsMobileBottomSheetService }] });
25084
+
25085
+ class DsMobileBookingCancelConfirmationComponent {
25086
+ facilityTitle;
25087
+ facilityThumbnail;
25088
+ bookingDate;
25089
+ bookingTime;
25090
+ get confirmationMessage() {
25091
+ const datePart = this.bookingDate ? ` den ${this.bookingDate}` : '';
25092
+ return `Er du sikker på, at du vil annullere din booking af ${this.facilityTitle}${datePart}?`;
25093
+ }
25094
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingCancelConfirmationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
25095
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: DsMobileBookingCancelConfirmationComponent, isStandalone: true, selector: "ds-mobile-booking-cancel-confirmation", inputs: { facilityTitle: "facilityTitle", facilityThumbnail: "facilityThumbnail", bookingDate: "bookingDate", bookingTime: "bookingTime" }, ngImport: i0, template: `
25096
+ <ds-mobile-confirmation-sheet
25097
+ [title]="'Annuller booking?'"
25098
+ [message]="confirmationMessage"
25099
+ [buttonText]="'Ja, annuller booking'"
25100
+ [destructive]="true"
25101
+ [secondaryButtonText]="'Luk'"
25102
+ [secondaryButtonVariant]="'secondary'"
25103
+ [illustrationVariant]="'delete-warning'"
25104
+ [illustrationSize]="'140px'">
25105
+ <ng-template #summary>
25106
+ <ds-mobile-booking-summary
25107
+ [facilityTitle]="facilityTitle"
25108
+ [facilityThumbnail]="facilityThumbnail"
25109
+ [date]="bookingDate"
25110
+ [time]="bookingTime"
25111
+ />
25112
+ </ng-template>
25113
+ </ds-mobile-confirmation-sheet>
25114
+ `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsMobileConfirmationSheetComponent, selector: "ds-mobile-confirmation-sheet", inputs: ["title", "message", "buttonText", "destructive", "showCancelButton", "cancelButtonText", "showIllustration", "illustrationVariant", "illustrationSize", "secondaryButtonText", "secondaryButtonVariant"] }, { kind: "component", type: DsMobileBookingSummaryComponent, selector: "ds-mobile-booking-summary", inputs: ["facilityTitle", "facilityThumbnail", "date", "time", "bookingCount"] }] });
25115
+ }
25116
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingCancelConfirmationComponent, decorators: [{
25117
+ type: Component,
25118
+ args: [{
25119
+ selector: 'ds-mobile-booking-cancel-confirmation',
25120
+ standalone: true,
25121
+ imports: [
25122
+ CommonModule,
25123
+ DsMobileConfirmationSheetComponent,
25124
+ DsMobileBookingSummaryComponent
25125
+ ],
25126
+ template: `
25127
+ <ds-mobile-confirmation-sheet
25128
+ [title]="'Annuller booking?'"
25129
+ [message]="confirmationMessage"
25130
+ [buttonText]="'Ja, annuller booking'"
25131
+ [destructive]="true"
25132
+ [secondaryButtonText]="'Luk'"
25133
+ [secondaryButtonVariant]="'secondary'"
25134
+ [illustrationVariant]="'delete-warning'"
25135
+ [illustrationSize]="'140px'">
25136
+ <ng-template #summary>
25137
+ <ds-mobile-booking-summary
25138
+ [facilityTitle]="facilityTitle"
25139
+ [facilityThumbnail]="facilityThumbnail"
25140
+ [date]="bookingDate"
25141
+ [time]="bookingTime"
25142
+ />
25143
+ </ng-template>
25144
+ </ds-mobile-confirmation-sheet>
25145
+ `
25146
+ }]
25147
+ }], propDecorators: { facilityTitle: [{
25148
+ type: Input
25149
+ }], facilityThumbnail: [{
25150
+ type: Input
25151
+ }], bookingDate: [{
25152
+ type: Input
25153
+ }], bookingTime: [{
25154
+ type: Input
25155
+ }] } });
25156
+
24677
25157
  /**
24678
25158
  * DsMobileFacilityCreationModalComponent
24679
25159
  *
@@ -30301,393 +30781,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
30301
30781
  }]
30302
30782
  }], ctorParameters: () => [] });
30303
30783
 
30304
- class DsMobileBookingDetailSheetComponent {
30305
- modalController;
30306
- /** `sheet` = bottom sheet. `modal` = `ds-modal-base` shell (active + history bookings). */
30307
- presentation = 'sheet';
30308
- data;
30309
- /** When true the modal sizes to its content instead of filling the screen. */
30310
- autoHeight = false;
30311
- get isModalPresentation() {
30312
- return this.presentation === 'modal';
30313
- }
30314
- constructor(modalController) {
30315
- this.modalController = modalController;
30316
- }
30317
- close() {
30318
- this.modalController.dismiss(null, 'backdrop');
30319
- }
30320
- cancelBooking() {
30321
- this.modalController.dismiss(null, 'cancel');
30322
- }
30323
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetComponent, deps: [{ token: i1.ModalController }], target: i0.ɵɵFactoryTarget.Component });
30324
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DsMobileBookingDetailSheetComponent, isStandalone: true, selector: "ds-mobile-booking-detail-sheet", inputs: { presentation: "presentation", data: "data", autoHeight: "autoHeight" }, host: { properties: { "class.presentation-modal": "this.isModalPresentation" } }, ngImport: i0, template: `
30325
- @if (presentation === 'modal') {
30326
- <ds-mobile-modal-base
30327
- [headerTitle]="data.facilityTitle"
30328
- [closeButtonLabel]="'Luk'"
30329
- [isAutoHeight]="autoHeight"
30330
- [keyboardContentBehavior]="'follow'">
30331
-
30332
- <ds-mobile-section
30333
- [showBorder]="false"
30334
- padding="20px 20px 0 20px">
30335
- <div class="hero-image-container">
30336
- @if (data.heroImage) {
30337
- <img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
30338
- } @else {
30339
- <div class="hero-image-placeholder">
30340
- <ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
30341
- </div>
30342
- }
30343
- </div>
30344
- </ds-mobile-section>
30345
-
30346
- <ds-mobile-section padding="20px 20px 20px 20px">
30347
- <div class="booking-summary-card">
30348
- <div class="details-section">
30349
- <h3 class="details-heading">Booking detaljer</h3>
30350
- <div class="info-rows">
30351
- @if (data.bookingDate) {
30352
- <div class="info-row">
30353
- <ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
30354
- <span>{{ data.bookingDate }}</span>
30355
- </div>
30356
- }
30357
- @if (data.bookingTime) {
30358
- <div class="info-row">
30359
- <ds-icon name="remixTimeLine" size="16px" color="tertiary" />
30360
- <span>{{ data.bookingTime }}</span>
30361
- </div>
30362
- }
30363
- @if (data.price) {
30364
- <div class="info-row">
30365
- <ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
30366
- <span>{{ data.price }}</span>
30367
- </div>
30368
- }
30369
- @if (data.bookingType) {
30370
- <div class="info-row">
30371
- <ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
30372
- <span>{{ data.bookingType }}</span>
30373
- </div>
30374
- }
30375
- @for (req of data.requirements || []; track req) {
30376
- <div class="info-row">
30377
- <ds-icon name="remixLockLine" size="16px" color="tertiary" />
30378
- <span>{{ req }}</span>
30379
- </div>
30380
- }
30381
- </div>
30382
- </div>
30383
- </div>
30384
- </ds-mobile-section>
30385
-
30386
- @if (data.canCancel) {
30387
- <div class="booking-action">
30388
- <div class="booking-actions-row">
30389
- <ds-button
30390
- class="cancel-primary"
30391
- size="md"
30392
- variant="secondary"
30393
- (clicked)="cancelBooking()">
30394
- Annuller booking
30395
- </ds-button>
30396
- </div>
30397
- </div>
30398
- }
30399
- </ds-mobile-modal-base>
30400
- } @else {
30401
- <ds-mobile-bottom-sheet-wrapper [showDragHandle]="true">
30402
- <div class="detail-header">
30403
- <h2 class="detail-title">{{ data.facilityTitle }}</h2>
30404
- <ds-icon-button
30405
- icon="remixCloseLine"
30406
- variant="ghost"
30407
- size="sm"
30408
- (clicked)="close()"
30409
- aria-label="Luk"
30410
- />
30411
- </div>
30412
-
30413
- <div class="detail-content">
30414
- <div class="hero-image-container">
30415
- @if (data.heroImage) {
30416
- <img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
30417
- } @else {
30418
- <div class="hero-image-placeholder">
30419
- <ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
30420
- </div>
30421
- }
30422
- </div>
30423
-
30424
- <div class="booking-summary-card">
30425
- <div class="details-section">
30426
- <h3 class="details-heading">Booking detaljer</h3>
30427
- <div class="info-rows">
30428
- @if (data.bookingDate) {
30429
- <div class="info-row">
30430
- <ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
30431
- <span>{{ data.bookingDate }}</span>
30432
- </div>
30433
- }
30434
- @if (data.bookingTime) {
30435
- <div class="info-row">
30436
- <ds-icon name="remixTimeLine" size="16px" color="tertiary" />
30437
- <span>{{ data.bookingTime }}</span>
30438
- </div>
30439
- }
30440
- @if (data.price) {
30441
- <div class="info-row">
30442
- <ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
30443
- <span>{{ data.price }}</span>
30444
- </div>
30445
- }
30446
- @if (data.bookingType) {
30447
- <div class="info-row">
30448
- <ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
30449
- <span>{{ data.bookingType }}</span>
30450
- </div>
30451
- }
30452
- @for (req of data.requirements || []; track req) {
30453
- <div class="info-row">
30454
- <ds-icon name="remixLockLine" size="16px" color="tertiary" />
30455
- <span>{{ req }}</span>
30456
- </div>
30457
- }
30458
- </div>
30459
- </div>
30460
- </div>
30461
-
30462
- @if (data.canCancel) {
30463
- <div class="footer-button-container">
30464
- <div class="booking-actions-column">
30465
- <ds-button
30466
- size="md"
30467
- variant="secondary"
30468
- (clicked)="cancelBooking()">
30469
- Annuller booking
30470
- </ds-button>
30471
- </div>
30472
- </div>
30473
- }
30474
- </div>
30475
- </ds-mobile-bottom-sheet-wrapper>
30476
- }
30477
- `, isInline: true, styles: [":host{display:block;height:auto;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;box-sizing:border-box}.detail-header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px 8px}.detail-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-lg, 18px);font-weight:600;color:var(--text-color-default-primary, #202227);margin:0;flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding-right:12px}.detail-content{padding:8px 20px 24px;display:flex;flex-direction:column;gap:20px}.hero-image-container{width:100%;aspect-ratio:16 / 9;border-radius:12px;overflow:hidden;background:var(--color-surface-secondary, #f5f5f5)}.hero-image{width:100%;height:100%;object-fit:cover;display:block}.hero-image-placeholder{width:100%;height:100%;min-height:0;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,color-mix(in srgb,var(--color-accent, #6B5FF5) 30%,transparent),color-mix(in srgb,var(--color-accent, #6B5FF5) 60%,transparent))}.booking-summary-card{background:var(--color-background-neutral-secondary, #f5f5f5);border-radius:16px;padding:16px}.details-section{display:flex;flex-direction:column;gap:12px}.details-heading{font-family:Brockmann,sans-serif;font-size:var(--font-size-base, 16px);font-weight:600;color:var(--text-color-default-primary, #202227);margin:0}.info-rows{display:flex;flex-direction:column;gap:8px}.info-row{display:flex;align-items:center;gap:10px;font-family:Brockmann,sans-serif;font-size:var(--font-size-sm, 14px);color:var(--text-color-default-secondary, #545B66);line-height:1.4}.info-row ds-icon{flex-shrink:0}.footer-button-container{width:100%;padding:16px 20px 0}.footer-button-container ::ng-deep ds-button{display:block;width:100%}.footer-button-container ::ng-deep ds-button button{width:100%;border-radius:100px;height:44px;min-height:44px;max-height:44px}.booking-action{padding:16px 20px;padding-bottom:calc(16px + max(8px,env(safe-area-inset-bottom,0px) - 24px));background:var(--color-surface-primary, #ffffff)}.booking-actions-row{display:flex;flex-direction:row;align-items:center;gap:12px;width:100%}.booking-action .cancel-primary{flex:1;min-width:0;display:block}.booking-action .cancel-primary ::ng-deep button{width:100%;border-radius:100px;height:44px;min-height:44px;max-height:44px;padding-left:16px;padding-right:16px}:host.presentation-modal{display:block;height:auto;width:100%;min-height:0;overflow:hidden}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsMobileBottomSheetWrapperComponent, selector: "ds-mobile-bottom-sheet-wrapper", inputs: ["showDragHandle"] }, { kind: "component", type: DsMobileModalBaseComponent, selector: "ds-mobile-modal-base", inputs: ["headerTitleInteractive", "textLoading", "textErrorTitle", "showHeader"], outputs: ["titleClick"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsButtonComponent, selector: "ds-button", inputs: ["variant", "size", "disabled", "loading", "pressed", "expanded", "leadingIcon", "trailingIcon", "ariaLabel", "iconOnly"], outputs: ["clicked", "focused", "blurred"] }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsIconButtonComponent, selector: "ds-icon-button", inputs: ["variant", "size", "icon", "disabled", "loading", "pressed", "expanded", "ariaLabel", "tooltip", "tooltipDisabled", "tooltipPlacement"], outputs: ["clicked", "focused", "blurred"] }] });
30478
- }
30479
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetComponent, decorators: [{
30480
- type: Component,
30481
- args: [{ selector: 'ds-mobile-booking-detail-sheet', standalone: true, imports: [
30482
- CommonModule,
30483
- DsMobileBottomSheetWrapperComponent,
30484
- DsMobileModalBaseComponent,
30485
- DsMobileSectionComponent,
30486
- DsButtonComponent,
30487
- DsIconComponent,
30488
- DsIconButtonComponent,
30489
- ], template: `
30490
- @if (presentation === 'modal') {
30491
- <ds-mobile-modal-base
30492
- [headerTitle]="data.facilityTitle"
30493
- [closeButtonLabel]="'Luk'"
30494
- [isAutoHeight]="autoHeight"
30495
- [keyboardContentBehavior]="'follow'">
30496
-
30497
- <ds-mobile-section
30498
- [showBorder]="false"
30499
- padding="20px 20px 0 20px">
30500
- <div class="hero-image-container">
30501
- @if (data.heroImage) {
30502
- <img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
30503
- } @else {
30504
- <div class="hero-image-placeholder">
30505
- <ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
30506
- </div>
30507
- }
30508
- </div>
30509
- </ds-mobile-section>
30510
-
30511
- <ds-mobile-section padding="20px 20px 20px 20px">
30512
- <div class="booking-summary-card">
30513
- <div class="details-section">
30514
- <h3 class="details-heading">Booking detaljer</h3>
30515
- <div class="info-rows">
30516
- @if (data.bookingDate) {
30517
- <div class="info-row">
30518
- <ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
30519
- <span>{{ data.bookingDate }}</span>
30520
- </div>
30521
- }
30522
- @if (data.bookingTime) {
30523
- <div class="info-row">
30524
- <ds-icon name="remixTimeLine" size="16px" color="tertiary" />
30525
- <span>{{ data.bookingTime }}</span>
30526
- </div>
30527
- }
30528
- @if (data.price) {
30529
- <div class="info-row">
30530
- <ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
30531
- <span>{{ data.price }}</span>
30532
- </div>
30533
- }
30534
- @if (data.bookingType) {
30535
- <div class="info-row">
30536
- <ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
30537
- <span>{{ data.bookingType }}</span>
30538
- </div>
30539
- }
30540
- @for (req of data.requirements || []; track req) {
30541
- <div class="info-row">
30542
- <ds-icon name="remixLockLine" size="16px" color="tertiary" />
30543
- <span>{{ req }}</span>
30544
- </div>
30545
- }
30546
- </div>
30547
- </div>
30548
- </div>
30549
- </ds-mobile-section>
30550
-
30551
- @if (data.canCancel) {
30552
- <div class="booking-action">
30553
- <div class="booking-actions-row">
30554
- <ds-button
30555
- class="cancel-primary"
30556
- size="md"
30557
- variant="secondary"
30558
- (clicked)="cancelBooking()">
30559
- Annuller booking
30560
- </ds-button>
30561
- </div>
30562
- </div>
30563
- }
30564
- </ds-mobile-modal-base>
30565
- } @else {
30566
- <ds-mobile-bottom-sheet-wrapper [showDragHandle]="true">
30567
- <div class="detail-header">
30568
- <h2 class="detail-title">{{ data.facilityTitle }}</h2>
30569
- <ds-icon-button
30570
- icon="remixCloseLine"
30571
- variant="ghost"
30572
- size="sm"
30573
- (clicked)="close()"
30574
- aria-label="Luk"
30575
- />
30576
- </div>
30577
-
30578
- <div class="detail-content">
30579
- <div class="hero-image-container">
30580
- @if (data.heroImage) {
30581
- <img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
30582
- } @else {
30583
- <div class="hero-image-placeholder">
30584
- <ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
30585
- </div>
30586
- }
30587
- </div>
30588
-
30589
- <div class="booking-summary-card">
30590
- <div class="details-section">
30591
- <h3 class="details-heading">Booking detaljer</h3>
30592
- <div class="info-rows">
30593
- @if (data.bookingDate) {
30594
- <div class="info-row">
30595
- <ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
30596
- <span>{{ data.bookingDate }}</span>
30597
- </div>
30598
- }
30599
- @if (data.bookingTime) {
30600
- <div class="info-row">
30601
- <ds-icon name="remixTimeLine" size="16px" color="tertiary" />
30602
- <span>{{ data.bookingTime }}</span>
30603
- </div>
30604
- }
30605
- @if (data.price) {
30606
- <div class="info-row">
30607
- <ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
30608
- <span>{{ data.price }}</span>
30609
- </div>
30610
- }
30611
- @if (data.bookingType) {
30612
- <div class="info-row">
30613
- <ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
30614
- <span>{{ data.bookingType }}</span>
30615
- </div>
30616
- }
30617
- @for (req of data.requirements || []; track req) {
30618
- <div class="info-row">
30619
- <ds-icon name="remixLockLine" size="16px" color="tertiary" />
30620
- <span>{{ req }}</span>
30621
- </div>
30622
- }
30623
- </div>
30624
- </div>
30625
- </div>
30626
-
30627
- @if (data.canCancel) {
30628
- <div class="footer-button-container">
30629
- <div class="booking-actions-column">
30630
- <ds-button
30631
- size="md"
30632
- variant="secondary"
30633
- (clicked)="cancelBooking()">
30634
- Annuller booking
30635
- </ds-button>
30636
- </div>
30637
- </div>
30638
- }
30639
- </div>
30640
- </ds-mobile-bottom-sheet-wrapper>
30641
- }
30642
- `, styles: [":host{display:block;height:auto;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;box-sizing:border-box}.detail-header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px 8px}.detail-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-lg, 18px);font-weight:600;color:var(--text-color-default-primary, #202227);margin:0;flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding-right:12px}.detail-content{padding:8px 20px 24px;display:flex;flex-direction:column;gap:20px}.hero-image-container{width:100%;aspect-ratio:16 / 9;border-radius:12px;overflow:hidden;background:var(--color-surface-secondary, #f5f5f5)}.hero-image{width:100%;height:100%;object-fit:cover;display:block}.hero-image-placeholder{width:100%;height:100%;min-height:0;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,color-mix(in srgb,var(--color-accent, #6B5FF5) 30%,transparent),color-mix(in srgb,var(--color-accent, #6B5FF5) 60%,transparent))}.booking-summary-card{background:var(--color-background-neutral-secondary, #f5f5f5);border-radius:16px;padding:16px}.details-section{display:flex;flex-direction:column;gap:12px}.details-heading{font-family:Brockmann,sans-serif;font-size:var(--font-size-base, 16px);font-weight:600;color:var(--text-color-default-primary, #202227);margin:0}.info-rows{display:flex;flex-direction:column;gap:8px}.info-row{display:flex;align-items:center;gap:10px;font-family:Brockmann,sans-serif;font-size:var(--font-size-sm, 14px);color:var(--text-color-default-secondary, #545B66);line-height:1.4}.info-row ds-icon{flex-shrink:0}.footer-button-container{width:100%;padding:16px 20px 0}.footer-button-container ::ng-deep ds-button{display:block;width:100%}.footer-button-container ::ng-deep ds-button button{width:100%;border-radius:100px;height:44px;min-height:44px;max-height:44px}.booking-action{padding:16px 20px;padding-bottom:calc(16px + max(8px,env(safe-area-inset-bottom,0px) - 24px));background:var(--color-surface-primary, #ffffff)}.booking-actions-row{display:flex;flex-direction:row;align-items:center;gap:12px;width:100%}.booking-action .cancel-primary{flex:1;min-width:0;display:block}.booking-action .cancel-primary ::ng-deep button{width:100%;border-radius:100px;height:44px;min-height:44px;max-height:44px;padding-left:16px;padding-right:16px}:host.presentation-modal{display:block;height:auto;width:100%;min-height:0;overflow:hidden}\n"] }]
30643
- }], ctorParameters: () => [{ type: i1.ModalController }], propDecorators: { presentation: [{
30644
- type: Input
30645
- }], data: [{
30646
- type: Input
30647
- }], autoHeight: [{
30648
- type: Input
30649
- }], isModalPresentation: [{
30650
- type: HostBinding,
30651
- args: ['class.presentation-modal']
30652
- }] } });
30653
-
30654
- class DsMobileBookingDetailSheetService extends BaseModalService {
30655
- bottomSheet;
30656
- constructor(modalController, bottomSheet) {
30657
- super(modalController);
30658
- this.bottomSheet = bottomSheet;
30659
- }
30660
- /**
30661
- * Bottom-sheet presentation (draggable breakpoints). Prefer `openAsModal` for booking lists.
30662
- */
30663
- async open(data) {
30664
- const modal = await this.bottomSheet.create({
30665
- component: DsMobileBookingDetailSheetComponent,
30666
- componentProps: { data },
30667
- autoHeight: true,
30668
- backdropDismiss: true,
30669
- backdropBlur: true,
30670
- });
30671
- const result = await modal.onWillDismiss();
30672
- return { role: result.role, data: result.data ?? undefined };
30673
- }
30674
- /** `ds-modal-base` shell — used for active and past bookings. Auto-heights to content. */
30675
- async openAsModal(data) {
30676
- const modal = await this.createModal(DsMobileBookingDetailSheetComponent, { data, presentation: 'modal', autoHeight: true }, { keyboardClose: true, autoHeight: true });
30677
- await modal.present();
30678
- const result = await modal.onWillDismiss();
30679
- return { role: result.role, data: result.data ?? undefined };
30680
- }
30681
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetService, deps: [{ token: i1.ModalController }, { token: DsMobileBottomSheetService }], target: i0.ɵɵFactoryTarget.Injectable });
30682
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetService, providedIn: 'root' });
30683
- }
30684
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetService, decorators: [{
30685
- type: Injectable,
30686
- args: [{
30687
- providedIn: 'root',
30688
- }]
30689
- }], ctorParameters: () => [{ type: i1.ModalController }, { type: DsMobileBottomSheetService }] });
30690
-
30691
30784
  const VENDOR_MODAL_SERVICE = new InjectionToken('VendorModalService');
30692
30785
  const BOOKING_DETAIL_MAP = {
30693
30786
  'booking-1': {
@@ -35691,78 +35784,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
35691
35784
  `, styles: [":host{display:block;height:100dvh;width:100vw;position:relative}.app-error{position:fixed;inset:0;z-index:9999;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;padding:40px 32px;background:var(--color-header-surface, #2D2356)}.app-error__title{font-family:Brockmann,sans-serif;font-size:var(--font-size-lg, 18px);font-weight:600;color:var(--color-header-content, #fff);text-align:center;margin:0}.app-error__description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);color:#ffffffa6;text-align:center;margin:0 0 8px}.app-error ds-button::ng-deep .btn{border-radius:9999px}\n"] }]
35692
35785
  }], ctorParameters: () => [{ type: UserService }, { type: i1$3.Router }, { type: i1.NavController }] });
35693
35786
 
35694
- class DsMobileBookingCancelConfirmationComponent {
35695
- facilityTitle;
35696
- facilityThumbnail;
35697
- bookingDate;
35698
- bookingTime;
35699
- get confirmationMessage() {
35700
- const datePart = this.bookingDate ? ` den ${this.bookingDate}` : '';
35701
- return `Er du sikker på, at du vil annullere din booking af ${this.facilityTitle}${datePart}?`;
35702
- }
35703
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingCancelConfirmationComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
35704
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: DsMobileBookingCancelConfirmationComponent, isStandalone: true, selector: "ds-mobile-booking-cancel-confirmation", inputs: { facilityTitle: "facilityTitle", facilityThumbnail: "facilityThumbnail", bookingDate: "bookingDate", bookingTime: "bookingTime" }, ngImport: i0, template: `
35705
- <ds-mobile-confirmation-sheet
35706
- [title]="'Annuller booking?'"
35707
- [message]="confirmationMessage"
35708
- [buttonText]="'Ja, annuller booking'"
35709
- [destructive]="true"
35710
- [secondaryButtonText]="'Luk'"
35711
- [secondaryButtonVariant]="'secondary'"
35712
- [illustrationVariant]="'delete-warning'"
35713
- [illustrationSize]="'140px'">
35714
- <ng-template #summary>
35715
- <ds-mobile-booking-summary
35716
- [facilityTitle]="facilityTitle"
35717
- [facilityThumbnail]="facilityThumbnail"
35718
- [date]="bookingDate"
35719
- [time]="bookingTime"
35720
- />
35721
- </ng-template>
35722
- </ds-mobile-confirmation-sheet>
35723
- `, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsMobileConfirmationSheetComponent, selector: "ds-mobile-confirmation-sheet", inputs: ["title", "message", "buttonText", "destructive", "showCancelButton", "cancelButtonText", "showIllustration", "illustrationVariant", "illustrationSize", "secondaryButtonText", "secondaryButtonVariant"] }, { kind: "component", type: DsMobileBookingSummaryComponent, selector: "ds-mobile-booking-summary", inputs: ["facilityTitle", "facilityThumbnail", "date", "time", "bookingCount"] }] });
35724
- }
35725
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingCancelConfirmationComponent, decorators: [{
35726
- type: Component,
35727
- args: [{
35728
- selector: 'ds-mobile-booking-cancel-confirmation',
35729
- standalone: true,
35730
- imports: [
35731
- CommonModule,
35732
- DsMobileConfirmationSheetComponent,
35733
- DsMobileBookingSummaryComponent
35734
- ],
35735
- template: `
35736
- <ds-mobile-confirmation-sheet
35737
- [title]="'Annuller booking?'"
35738
- [message]="confirmationMessage"
35739
- [buttonText]="'Ja, annuller booking'"
35740
- [destructive]="true"
35741
- [secondaryButtonText]="'Luk'"
35742
- [secondaryButtonVariant]="'secondary'"
35743
- [illustrationVariant]="'delete-warning'"
35744
- [illustrationSize]="'140px'">
35745
- <ng-template #summary>
35746
- <ds-mobile-booking-summary
35747
- [facilityTitle]="facilityTitle"
35748
- [facilityThumbnail]="facilityThumbnail"
35749
- [date]="bookingDate"
35750
- [time]="bookingTime"
35751
- />
35752
- </ng-template>
35753
- </ds-mobile-confirmation-sheet>
35754
- `
35755
- }]
35756
- }], propDecorators: { facilityTitle: [{
35757
- type: Input
35758
- }], facilityThumbnail: [{
35759
- type: Input
35760
- }], bookingDate: [{
35761
- type: Input
35762
- }], bookingTime: [{
35763
- type: Input
35764
- }] } });
35765
-
35766
35787
  const HISTORY_LINK = {
35767
35788
  da: 'Historik',
35768
35789
  en: 'History',
@@ -38860,5 +38881,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
38860
38881
  * Generated bundle index. Do not edit.
38861
38882
  */
38862
38883
 
38863
- export { AcceptInvitePageComponent, ActionCommentComponent, ActionLikeComponent, AvatarUploadPageComponent, BaseModalService, ContentRowComponent, CreateAccountPageComponent, DEFAULT_SERVICE_PAGE_LABELS, DsAppIconComponent, DsAvatarWithBadgeComponent, DsLogoComponent, DsMobileAccessSheetComponent, DsMobileActionListItemComponent, DsMobileActionsBottomSheetComponent, DsMobileAddGroupTenantsModalComponent, DsMobileAppLoadingComponent, DsMobileAttachmentPreviewComponent, DsMobileBookingConfirmationWrapperComponent, DsMobileBookingModalComponent, DsMobileBookingModalService, DsMobileBookingSummaryComponent, DsMobileBottomSheetHeaderComponent, DsMobileBottomSheetService, DsMobileBottomSheetWrapperComponent, DsMobileCapacitySheetComponent, DsMobileCardInlineBannerComponent, DsMobileCardInlineComponent, DsMobileCardInlineContactComponent, DsMobileCardInlineFileComponent, DsMobileChatModalComponent, DsMobileChatModalService, DsMobileActionsBottomSheetComponent as DsMobileCommentActionsBottomSheetComponent, DsMobileCommentComponent, DsMobileCommunityAdminPickerComponent, DsMobileCommunityAdminsModalComponent, DsMobileConfirmationSheetComponent, DsMobileContactListItemComponent, DsMobileContentComponent, DsMobileCountBadgeComponent, DsMobileCreateGroupModalComponent, DsMobileDropdownComponent, DsMobileEditGroupModalComponent, DsMobileEmptyStateComponent, DsMobileFabComponent, DsMobileFacilityArchiveConfirmationComponent, DsMobileFacilityCreationConfirmationWrapperComponent, DsMobileFacilityCreationModalComponent, DsMobileFacilityCreationModalService, DsMobileFacilityDeleteConfirmationComponent, DsMobileFacilityDetailModalComponent, DsMobileFacilityDetailModalService, DsMobileFileAttachmentComponent, DsMobileGlassSpinnerComponent, DsMobileGroupAvatarStackComponent, DsMobileGroupMembersModalComponent, DsMobileHandbookDetailModalComponent, DsMobileHandbookDetailModalService, DsMobileHandbookFolderComponent, DsMobileHandbookFolderMiniComponent, DsMobileHeaderContentComponent, DsMobileHeaderContentTileComponent, DsMobileIllustrationComponent, DsMobileImagePlaceholderComponent, DsMobileInlinePhotoComponent, DsMobileInlineTabsComponent, DsMobileInteractiveListItemBookingComponent, DsMobileInteractiveListItemInquiryComponent, DsMobileInteractiveListItemMessageComponent, DsMobileInteractiveListItemPostComponent, DsMobileLightboxImageComponent as DsMobileLightboxComponent, DsMobileLightboxFooterComponent, DsMobileLightboxHeaderComponent, DsMobileLightboxImageComponent, DsMobileLightboxImageWithDescriptionComponent, DsMobileLightboxPdfComponent, DsMobileLightboxService, DsMobileListItemComponent, DsMobileListItemStaticComponent, DsMobileListSearchComponent, DsMobileLoaderOverlayComponent, DsMobileLongPressDirective, DsMobileMediaActionsPanelComponent, DsMobileMessageBubbleComponent, DsMobileMessageComposerComponent, DsMobileModalBaseComponent, DsMobileModalService, DsMobileNewInquiryModalComponent, DsMobileNewInquiryModalService, DsMobileNotificationButtonComponent, DsMobileNotificationModalComponent, DsMobileNotificationModalService, DsMobileNotificationPromptComponent, DsMobileOfflineBannerComponent, DsMobilePageDetailsComponent, DsMobilePageMainComponent, DsMobilePillComponent, DsMobileActionsBottomSheetComponent as DsMobilePostActionsBottomSheetComponent, DsMobilePostComposerComponent, DsMobilePostCreateBottomSheetComponent, DsMobilePostDetailModalComponent, DsMobilePostDetailModalService, DsMobilePriceSheetComponent, DsMobileProfileActionsSheetComponent, DsMobilePromptBottomSheetComponent, DsMobilePropertyBannerComponent, DsMobileRichTextEditorComponent, DsMobileSectionComponent, DsMobileServiceVendorModalService, DsMobileServiceVendorSheetComponent, DsMobileSwiperComponent, DsMobileSwiperWithNavComponent, DsMobileSystemMessageBannerComponent, DsMobileTabBarComponent, DsMobileTabsComponent, DsMobileTenantPickerModalComponent, DsMobileToggleComponent, DsMobileWhenCanBookSheetComponent, DsMobileWhoCanBookSheetComponent, DsTextInputComponent, FamilyAccessPageComponent, FamilyAccessService, InquiriesService, InviteSuccessPageComponent, MediaPickerService, MobileBookingPageComponent, MobileCommunityPageComponent, MobileHandbookPageComponent, MobileHomePageComponent, MobileInquiriesPageComponent, MobileInquiryDetailPageComponent, MobileModalBase, MobilePageBase, MobilePostDetailPageComponent, MobileTabsExampleComponent, NOTIFICATION_ICON_MAP, NotificationPromptService, NotificationService, PageLoadingService, PostActionsComponent, PostAttachmentsComponent, PostContentComponent, PostCreatePageComponent, PostMediaComponent, PostPdfAttachmentComponent, PostTextComponent, PostsService, RelativeTimePipe, SAMPLE_NOTIFICATIONS, SectionHeaderComponent, ServicesPageComponent, SettingsModalService, SignInPageComponent, SignInToAcceptPageComponent, TenantChatPageComponent, TileContentComponent, TileIconComponent, TileLabelComponent, TileValueComponent, TrackingPermissionService, UserService, VENDOR_MODAL_SERVICE, WhitelabelDemoModalComponent, WhitelabelDemoModalService, WhitelabelService, customBackTransition, customPageTransition, dateBucket };
38884
+ export { AcceptInvitePageComponent, ActionCommentComponent, ActionLikeComponent, AvatarUploadPageComponent, BaseModalService, ContentRowComponent, CreateAccountPageComponent, DEFAULT_SERVICE_PAGE_LABELS, DsAppIconComponent, DsAvatarWithBadgeComponent, DsLogoComponent, DsMobileAccessSheetComponent, DsMobileActionListItemComponent, DsMobileActionsBottomSheetComponent, DsMobileAddGroupTenantsModalComponent, DsMobileAppLoadingComponent, DsMobileAttachmentPreviewComponent, DsMobileBookingCancelConfirmationComponent, DsMobileBookingConfirmationWrapperComponent, DsMobileBookingDetailSheetComponent, DsMobileBookingDetailSheetService, DsMobileBookingModalComponent, DsMobileBookingModalService, DsMobileBookingSummaryComponent, DsMobileBottomSheetHeaderComponent, DsMobileBottomSheetService, DsMobileBottomSheetWrapperComponent, DsMobileCapacitySheetComponent, DsMobileCardInlineBannerComponent, DsMobileCardInlineComponent, DsMobileCardInlineContactComponent, DsMobileCardInlineFileComponent, DsMobileChatModalComponent, DsMobileChatModalService, DsMobileActionsBottomSheetComponent as DsMobileCommentActionsBottomSheetComponent, DsMobileCommentComponent, DsMobileCommunityAdminPickerComponent, DsMobileCommunityAdminsModalComponent, DsMobileConfirmationSheetComponent, DsMobileContactListItemComponent, DsMobileContentComponent, DsMobileCountBadgeComponent, DsMobileCreateGroupModalComponent, DsMobileDropdownComponent, DsMobileEditGroupModalComponent, DsMobileEmptyStateComponent, DsMobileFabComponent, DsMobileFacilityArchiveConfirmationComponent, DsMobileFacilityCreationConfirmationWrapperComponent, DsMobileFacilityCreationModalComponent, DsMobileFacilityCreationModalService, DsMobileFacilityDeleteConfirmationComponent, DsMobileFacilityDetailModalComponent, DsMobileFacilityDetailModalService, DsMobileFileAttachmentComponent, DsMobileGlassSpinnerComponent, DsMobileGroupAvatarStackComponent, DsMobileGroupMembersModalComponent, DsMobileHandbookDetailModalComponent, DsMobileHandbookDetailModalService, DsMobileHandbookFolderComponent, DsMobileHandbookFolderMiniComponent, DsMobileHeaderContentComponent, DsMobileHeaderContentTileComponent, DsMobileIllustrationComponent, DsMobileImagePlaceholderComponent, DsMobileInlinePhotoComponent, DsMobileInlineTabsComponent, DsMobileInteractiveListItemBookingComponent, DsMobileInteractiveListItemInquiryComponent, DsMobileInteractiveListItemMessageComponent, DsMobileInteractiveListItemPostComponent, DsMobileLightboxImageComponent as DsMobileLightboxComponent, DsMobileLightboxFooterComponent, DsMobileLightboxHeaderComponent, DsMobileLightboxImageComponent, DsMobileLightboxImageWithDescriptionComponent, DsMobileLightboxPdfComponent, DsMobileLightboxService, DsMobileListItemComponent, DsMobileListItemStaticComponent, DsMobileListSearchComponent, DsMobileLoaderOverlayComponent, DsMobileLongPressDirective, DsMobileMediaActionsPanelComponent, DsMobileMessageBubbleComponent, DsMobileMessageComposerComponent, DsMobileModalBaseComponent, DsMobileModalService, DsMobileNewInquiryModalComponent, DsMobileNewInquiryModalService, DsMobileNotificationButtonComponent, DsMobileNotificationModalComponent, DsMobileNotificationModalService, DsMobileNotificationPromptComponent, DsMobileOfflineBannerComponent, DsMobilePageDetailsComponent, DsMobilePageMainComponent, DsMobilePillComponent, DsMobileActionsBottomSheetComponent as DsMobilePostActionsBottomSheetComponent, DsMobilePostComposerComponent, DsMobilePostCreateBottomSheetComponent, DsMobilePostDetailModalComponent, DsMobilePostDetailModalService, DsMobilePriceSheetComponent, DsMobileProfileActionsSheetComponent, DsMobilePromptBottomSheetComponent, DsMobilePropertyBannerComponent, DsMobileRichTextEditorComponent, DsMobileSectionComponent, DsMobileServiceVendorModalService, DsMobileServiceVendorSheetComponent, DsMobileSwiperComponent, DsMobileSwiperWithNavComponent, DsMobileSystemMessageBannerComponent, DsMobileTabBarComponent, DsMobileTabsComponent, DsMobileTenantPickerModalComponent, DsMobileToggleComponent, DsMobileWhenCanBookSheetComponent, DsMobileWhoCanBookSheetComponent, DsTextInputComponent, FamilyAccessPageComponent, FamilyAccessService, InquiriesService, InviteSuccessPageComponent, MediaPickerService, MobileBookingPageComponent, MobileCommunityPageComponent, MobileHandbookPageComponent, MobileHomePageComponent, MobileInquiriesPageComponent, MobileInquiryDetailPageComponent, MobileModalBase, MobilePageBase, MobilePostDetailPageComponent, MobileTabsExampleComponent, NOTIFICATION_ICON_MAP, NotificationPromptService, NotificationService, PageLoadingService, PostActionsComponent, PostAttachmentsComponent, PostContentComponent, PostCreatePageComponent, PostMediaComponent, PostPdfAttachmentComponent, PostTextComponent, PostsService, RelativeTimePipe, SAMPLE_NOTIFICATIONS, SectionHeaderComponent, ServicesPageComponent, SettingsModalService, SignInPageComponent, SignInToAcceptPageComponent, TenantChatPageComponent, TileContentComponent, TileIconComponent, TileLabelComponent, TileValueComponent, TrackingPermissionService, UserService, VENDOR_MODAL_SERVICE, WhitelabelDemoModalComponent, WhitelabelDemoModalService, WhitelabelService, customBackTransition, customPageTransition, dateBucket };
38864
38885
  //# sourceMappingURL=propbinder-mobile-design.mjs.map