@propbinder/mobile-design 0.3.34 → 0.3.36

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.
@@ -20,16 +20,16 @@ import { FilePicker } from '@capawesome/capacitor-file-picker';
20
20
  import { Subject, isObservable } from 'rxjs';
21
21
  import { createAnimation } from '@ionic/core';
22
22
  import { Share } from '@capacitor/share';
23
- import Swiper from 'swiper';
24
23
  import { Filesystem, Directory } from '@capacitor/filesystem';
24
+ import Swiper from 'swiper';
25
25
  import { Browser } from '@capacitor/browser';
26
26
  import { filter } from 'rxjs/operators';
27
27
  import { Pagination } from 'swiper/modules';
28
28
  import { AppTrackingTransparency } from 'capacitor-plugin-app-tracking-transparency';
29
29
 
30
30
  const DEFAULT_CONFIG = {
31
- logoUrl: '/Assets/logos/propbinder-logomark.svg',
32
- logoMarkUrl: '/Assets/logos/propbinder-logomark.svg',
31
+ logoUrl: '/assets/logos/propbinder-logomark.svg',
32
+ logoMarkUrl: '/assets/logos/propbinder-logomark.svg',
33
33
  logoAlt: 'Propbinder',
34
34
  logoSize: 'md', // Propbinder default: md (28px mobile, 32px desktop)
35
35
  // App icon (brand identity)
@@ -63,8 +63,8 @@ const DEFAULT_CONFIG = {
63
63
  * Initialize with custom config:
64
64
  * ```typescript
65
65
  * whitelabelService.initialize({
66
- * logoUrl: '/Assets/logos/acme-logo.svg',
67
- * logoMarkUrl: '/Assets/logos/acme-mark.svg',
66
+ * logoUrl: '/assets/logos/acme-logo.svg',
67
+ * logoMarkUrl: '/assets/logos/acme-mark.svg',
68
68
  * accent: '#2563eb',
69
69
  * onAccent: '#ffffff',
70
70
  * headerSurface: '#1e40af',
@@ -202,8 +202,8 @@ class WhitelabelService {
202
202
  // Example: Different configs for different organizations
203
203
  if (organizationId === 'demo-client') {
204
204
  this.initialize({
205
- logoUrl: '/Assets/logos/demo-logo.svg',
206
- logoMarkUrl: '/Assets/logos/demo-mark.svg',
205
+ logoUrl: '/assets/logos/demo-logo.svg',
206
+ logoMarkUrl: '/assets/logos/demo-mark.svg',
207
207
  logoAlt: 'Demo Client',
208
208
  appIconSurface: '#2563eb',
209
209
  appIconContent: '#FFFFFF',
@@ -219,8 +219,8 @@ class WhitelabelService {
219
219
  }
220
220
  else if (organizationId === 'cobblestone') {
221
221
  this.initialize({
222
- logoUrl: '/Assets/logos/cobblestone-logo.svg',
223
- logoMarkUrl: '/Assets/logos/cobblestone-logomark.svg',
222
+ logoUrl: '/assets/logos/cobblestone-logo.svg',
223
+ logoMarkUrl: '/assets/logos/cobblestone-logomark.svg',
224
224
  logoAlt: 'Cobblestone',
225
225
  logoSize: 'sm',
226
226
  appIconSurface: '#2C3E50',
@@ -14611,9 +14611,6 @@ class DsMobileLightboxImageComponent {
14611
14611
  this.onCloseRequested();
14612
14612
  }
14613
14613
  }
14614
- /**
14615
- * Handle share button click
14616
- */
14617
14614
  async onShare() {
14618
14615
  console.log('[Lightbox] Share button clicked');
14619
14616
  const currentImg = this.currentImage();
@@ -14622,20 +14619,78 @@ class DsMobileLightboxImageComponent {
14622
14619
  return;
14623
14620
  }
14624
14621
  try {
14622
+ let shareUrl = currentImg.src;
14623
+ // Handle native platform sharing of remote URLs
14624
+ if (Capacitor.isNativePlatform()) {
14625
+ if (currentImg.src.startsWith('http')) {
14626
+ try {
14627
+ // Fetch image as blob
14628
+ const response = await fetch(currentImg.src);
14629
+ const blob = await response.blob();
14630
+ // Convert to base64
14631
+ const reader = new FileReader();
14632
+ const base64Data = await new Promise((resolve, reject) => {
14633
+ reader.onloadend = () => {
14634
+ if (typeof reader.result === 'string') {
14635
+ const base64 = reader.result.split(',')[1];
14636
+ resolve(base64);
14637
+ }
14638
+ else {
14639
+ reject(new Error('Failed to read blob as base64'));
14640
+ }
14641
+ };
14642
+ reader.onerror = reject;
14643
+ reader.readAsDataURL(blob);
14644
+ });
14645
+ // Write to cache directory
14646
+ const fileName = `shared_image_${Date.now()}.jpg`;
14647
+ const writeResult = await Filesystem.writeFile({
14648
+ path: fileName,
14649
+ data: base64Data,
14650
+ directory: Directory.Cache
14651
+ });
14652
+ shareUrl = writeResult.uri;
14653
+ }
14654
+ catch (e) {
14655
+ console.error('[Lightbox] Failed to prepare native image share:', e);
14656
+ // Fallback to sharing the URL directly
14657
+ }
14658
+ }
14659
+ }
14625
14660
  // Check if Web Share API is available (for browser)
14626
- if (navigator.share) {
14661
+ if (navigator.share && !Capacitor.isNativePlatform()) {
14662
+ try {
14663
+ if (currentImg.src.startsWith('http')) {
14664
+ const response = await fetch(currentImg.src);
14665
+ const blob = await response.blob();
14666
+ const file = new File([blob], 'shared_image.jpg', { type: blob.type || 'image/jpeg' });
14667
+ if (navigator.canShare && navigator.canShare({ files: [file] })) {
14668
+ await navigator.share({
14669
+ title: currentImg.title || 'Shared Image',
14670
+ text: currentImg.description || '',
14671
+ files: [file]
14672
+ });
14673
+ console.log('[Lightbox] Shared file via Web Share API');
14674
+ return;
14675
+ }
14676
+ }
14677
+ }
14678
+ catch (e) {
14679
+ console.error('[Lightbox] Web Share API file share failed:', e);
14680
+ }
14681
+ // Fallback to URL web share
14627
14682
  await navigator.share({
14628
14683
  title: currentImg.title || 'Shared Image',
14629
14684
  text: currentImg.description || '',
14630
14685
  url: currentImg.src,
14631
14686
  });
14632
- console.log('[Lightbox] Shared via Web Share API');
14687
+ console.log('[Lightbox] Shared URL via Web Share API');
14633
14688
  }
14634
14689
  else {
14635
14690
  // Fallback to Capacitor Share API (for native apps)
14636
14691
  await Share.share({
14637
14692
  title: currentImg.title || 'Shared Image',
14638
- url: currentImg.src,
14693
+ url: shareUrl,
14639
14694
  dialogTitle: 'Share Image',
14640
14695
  });
14641
14696
  console.log('[Lightbox] Shared via Capacitor Share API');
@@ -21924,7 +21979,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
21924
21979
  * ```html
21925
21980
  * <!-- With image -->
21926
21981
  * <ds-mobile-empty-state
21927
- * [imageSrc]="'/Assets/empty-state-inquiry.svg'"
21982
+ * [imageSrc]="'/assets/empty-state-inquiry.svg'"
21928
21983
  * [imageAlt]="'No messages'"
21929
21984
  * [title]="'Ingen beskeder endnu'"
21930
21985
  * [description]="'Start samtalen ved at sende en besked'">
@@ -22042,6 +22097,20 @@ class DsMobilePostDetailModalComponent {
22042
22097
  onEditComment;
22043
22098
  // Callback for deleting a comment
22044
22099
  onDeleteComment;
22100
+ // Translations
22101
+ textReplySingle = 'svar';
22102
+ textReplyPlural = 'svar';
22103
+ textNoRepliesTitle = 'Ingen svar endnu';
22104
+ textNoRepliesDesc = 'Vær den første til at svare på dette opslag';
22105
+ textAddReply = 'Tilføj et svar...';
22106
+ textEditComment = 'Rediger din kommentar...';
22107
+ textEditingComment = 'Redigerer kommentar';
22108
+ textReplyingTo = 'Svarer til';
22109
+ textSend = 'Send kommentar';
22110
+ textClosePost = 'Luk opslag';
22111
+ textJustNow = 'Lige nu';
22112
+ textEdited = 'redigeret';
22113
+ textConfirmDelete = 'Er du sikker på, at du vil slette denne kommentar?';
22045
22114
  // ViewChild for comment input
22046
22115
  commentInput;
22047
22116
  // Signal for reactive post data
@@ -22232,7 +22301,7 @@ class DsMobilePostDetailModalComponent {
22232
22301
  return {
22233
22302
  ...comment,
22234
22303
  content: text,
22235
- timestamp: 'Just now (edited)',
22304
+ timestamp: `${this.textJustNow} (${this.textEdited})`,
22236
22305
  };
22237
22306
  }
22238
22307
  return comment;
@@ -22256,7 +22325,7 @@ class DsMobilePostDetailModalComponent {
22256
22325
  const newComment = {
22257
22326
  authorName: this.currentUserName || 'Dig',
22258
22327
  authorRole: 'Dig',
22259
- timestamp: 'Just now',
22328
+ timestamp: this.textJustNow,
22260
22329
  avatarInitials: this.currentUserInitials(),
22261
22330
  content: finalText,
22262
22331
  isLiked: false,
@@ -22272,6 +22341,9 @@ class DsMobilePostDetailModalComponent {
22272
22341
  });
22273
22342
  // Clear reply state
22274
22343
  this.replyingTo.set(null);
22344
+ if (this.onSubmitComment) {
22345
+ this.onSubmitComment({ postId, text: finalText });
22346
+ }
22275
22347
  }
22276
22348
  // Clear the input
22277
22349
  this.commentText.set('');
@@ -22283,11 +22355,6 @@ class DsMobilePostDetailModalComponent {
22283
22355
  }
22284
22356
  // Hide keyboard explicitly
22285
22357
  Keyboard.hide().catch(() => { });
22286
- // In a real app, you would also send this to your backend
22287
- // this.commentService.addComment(currentPost.postId, text);
22288
- if (this.onSubmitComment) {
22289
- this.onSubmitComment({ postId, text: finalText });
22290
- }
22291
22358
  }
22292
22359
  /**
22293
22360
  * Open image in lightbox
@@ -22382,9 +22449,8 @@ class DsMobilePostDetailModalComponent {
22382
22449
  }
22383
22450
  break;
22384
22451
  case 'delete':
22385
- // console.log('Delete comment by', authorName);
22386
22452
  // Show confirmation before deleting
22387
- if (confirm('Are you sure you want to delete this comment?')) {
22453
+ if (confirm(this.textConfirmDelete)) {
22388
22454
  const commentToDelete = currentPost.comments?.find((comment) => comment.authorName === authorName && comment.content === content);
22389
22455
  const updatedCommentsAfterDelete = currentPost.comments?.filter((comment) => !(comment.authorName === authorName && comment.content === content));
22390
22456
  this.post.set({
@@ -22402,7 +22468,7 @@ class DsMobilePostDetailModalComponent {
22402
22468
  }
22403
22469
  }
22404
22470
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobilePostDetailModalComponent, deps: [{ token: DsMobileLightboxService }, { token: DsMobileBottomSheetService }], target: i0.ɵɵFactoryTarget.Component });
22405
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DsMobilePostDetailModalComponent, isStandalone: true, selector: "ds-mobile-post-detail-modal", inputs: { postData: "postData", currentUserName: "currentUserName", currentUserInitialsInput: "currentUserInitialsInput", loading: "loading", error: "error", onTogglePostLike: "onTogglePostLike", onSubmitComment: "onSubmitComment", onToggleCommentLike: "onToggleCommentLike", onEditComment: "onEditComment", onDeleteComment: "onDeleteComment" }, viewQueries: [{ propertyName: "commentInput", first: true, predicate: ["commentInput"], descendants: true }], ngImport: i0, template: `
22471
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DsMobilePostDetailModalComponent, isStandalone: true, selector: "ds-mobile-post-detail-modal", inputs: { postData: "postData", currentUserName: "currentUserName", currentUserInitialsInput: "currentUserInitialsInput", loading: "loading", error: "error", onTogglePostLike: "onTogglePostLike", onSubmitComment: "onSubmitComment", onToggleCommentLike: "onToggleCommentLike", onEditComment: "onEditComment", onDeleteComment: "onDeleteComment", textReplySingle: "textReplySingle", textReplyPlural: "textReplyPlural", textNoRepliesTitle: "textNoRepliesTitle", textNoRepliesDesc: "textNoRepliesDesc", textAddReply: "textAddReply", textEditComment: "textEditComment", textEditingComment: "textEditingComment", textReplyingTo: "textReplyingTo", textSend: "textSend", textClosePost: "textClosePost", textJustNow: "textJustNow", textEdited: "textEdited", textConfirmDelete: "textConfirmDelete" }, viewQueries: [{ propertyName: "commentInput", first: true, predicate: ["commentInput"], descendants: true }], ngImport: i0, template: `
22406
22472
  <ds-mobile-modal-base
22407
22473
  [loading]="loading"
22408
22474
  [error]="error"
@@ -22410,7 +22476,7 @@ class DsMobilePostDetailModalComponent {
22410
22476
  [headerMeta]="post().authorRole + ' · ' + post().timestamp"
22411
22477
  [hasFixedBottom]="true"
22412
22478
  [enableKeyboardHandling]="true"
22413
- closeButtonLabel="Luk opslag"
22479
+ [closeButtonLabel]="textClosePost"
22414
22480
  >
22415
22481
  <!-- Header Avatar -->
22416
22482
  <ds-avatar header-leading [initials]="post().avatarInitials || ''" [type]="post().avatarType || 'initials'" [src]="post().avatarSrc || ''" size="md" />
@@ -22441,7 +22507,7 @@ class DsMobilePostDetailModalComponent {
22441
22507
 
22442
22508
  <!-- Comments Section -->
22443
22509
  <ds-mobile-section
22444
- [headline]="post().comments && post().comments!.length > 0 ? (post().comments!.length + ' ' + (post().comments!.length === 1 ? 'reply' : 'replies')) : ''">
22510
+ [headline]="post().comments && post().comments!.length > 0 ? (post().comments!.length + ' ' + (post().comments!.length === 1 ? textReplySingle : textReplyPlural)) : ''">
22445
22511
  @if (post().comments && post().comments!.length > 0) {
22446
22512
  <div class="comments-list">
22447
22513
  @for (comment of post().comments!; track comment.id) {
@@ -22464,10 +22530,10 @@ class DsMobilePostDetailModalComponent {
22464
22530
  } @else {
22465
22531
  <!-- Empty State -->
22466
22532
  <ds-mobile-empty-state
22467
- [imageSrc]="'/Assets/empty-state-inquiry.svg'"
22468
- [imageAlt]="'Ingen kommentarer endnu'"
22469
- [title]="'Ingen svar endnu'"
22470
- [description]="'Vær den første til at svare på dette opslag'">
22533
+ [imageSrc]="'/assets/empty-state-inquiry.svg'"
22534
+ [imageAlt]="textNoRepliesTitle"
22535
+ [title]="textNoRepliesTitle"
22536
+ [description]="textNoRepliesDesc">
22471
22537
  </ds-mobile-empty-state>
22472
22538
  }
22473
22539
  </ds-mobile-section>
@@ -22480,7 +22546,7 @@ class DsMobilePostDetailModalComponent {
22480
22546
  <div class="edit-indicator">
22481
22547
  <div class="edit-indicator-content">
22482
22548
  <ds-icon name="remixEditLine" size="16px" />
22483
- <span class="edit-text">Redigerer kommentar</span>
22549
+ <span class="edit-text">{{ textEditingComment }}</span>
22484
22550
  </div>
22485
22551
  <button class="cancel-edit" (click)="cancelEdit()">
22486
22552
  <ds-icon name="remixCloseLine" size="16px" />
@@ -22492,7 +22558,7 @@ class DsMobilePostDetailModalComponent {
22492
22558
  <div class="reply-indicator-content">
22493
22559
  <ds-icon name="remixReplyLine" size="16px" />
22494
22560
  <span class="reply-to-text">
22495
- Svarer til <span class="reply-author">{{ replyingTo()!.authorName }}</span>
22561
+ {{ textReplyingTo }} <span class="reply-author">{{ replyingTo()!.authorName }}</span>
22496
22562
  </span>
22497
22563
  </div>
22498
22564
  <button class="cancel-reply" (click)="cancelReply()">
@@ -22507,7 +22573,7 @@ class DsMobilePostDetailModalComponent {
22507
22573
  <textarea
22508
22574
  #commentInput
22509
22575
  class="composer-input"
22510
- [placeholder]="editingComment() ? 'Rediger din kommentar...' : replyingTo() ? 'Tilføj et svar...' : 'Tilføj et svar...'"
22576
+ [placeholder]="editingComment() ? textEditComment : textAddReply"
22511
22577
  [ngModel]="commentText()"
22512
22578
  (ngModelChange)="commentText.set($event)"
22513
22579
  (input)="handleInput($event)"
@@ -22521,7 +22587,7 @@ class DsMobilePostDetailModalComponent {
22521
22587
  variant="primary"
22522
22588
  size="sm"
22523
22589
  (clicked)="submitComment()"
22524
- aria-label="Send kommentar"
22590
+ [attr.aria-label]="textSend"
22525
22591
  [class.send-button-fixed]="true"
22526
22592
  [class.show]="commentText().trim().length > 0"
22527
22593
  >
@@ -22556,7 +22622,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
22556
22622
  [headerMeta]="post().authorRole + ' · ' + post().timestamp"
22557
22623
  [hasFixedBottom]="true"
22558
22624
  [enableKeyboardHandling]="true"
22559
- closeButtonLabel="Luk opslag"
22625
+ [closeButtonLabel]="textClosePost"
22560
22626
  >
22561
22627
  <!-- Header Avatar -->
22562
22628
  <ds-avatar header-leading [initials]="post().avatarInitials || ''" [type]="post().avatarType || 'initials'" [src]="post().avatarSrc || ''" size="md" />
@@ -22587,7 +22653,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
22587
22653
 
22588
22654
  <!-- Comments Section -->
22589
22655
  <ds-mobile-section
22590
- [headline]="post().comments && post().comments!.length > 0 ? (post().comments!.length + ' ' + (post().comments!.length === 1 ? 'reply' : 'replies')) : ''">
22656
+ [headline]="post().comments && post().comments!.length > 0 ? (post().comments!.length + ' ' + (post().comments!.length === 1 ? textReplySingle : textReplyPlural)) : ''">
22591
22657
  @if (post().comments && post().comments!.length > 0) {
22592
22658
  <div class="comments-list">
22593
22659
  @for (comment of post().comments!; track comment.id) {
@@ -22610,10 +22676,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
22610
22676
  } @else {
22611
22677
  <!-- Empty State -->
22612
22678
  <ds-mobile-empty-state
22613
- [imageSrc]="'/Assets/empty-state-inquiry.svg'"
22614
- [imageAlt]="'Ingen kommentarer endnu'"
22615
- [title]="'Ingen svar endnu'"
22616
- [description]="'Vær den første til at svare på dette opslag'">
22679
+ [imageSrc]="'/assets/empty-state-inquiry.svg'"
22680
+ [imageAlt]="textNoRepliesTitle"
22681
+ [title]="textNoRepliesTitle"
22682
+ [description]="textNoRepliesDesc">
22617
22683
  </ds-mobile-empty-state>
22618
22684
  }
22619
22685
  </ds-mobile-section>
@@ -22626,7 +22692,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
22626
22692
  <div class="edit-indicator">
22627
22693
  <div class="edit-indicator-content">
22628
22694
  <ds-icon name="remixEditLine" size="16px" />
22629
- <span class="edit-text">Redigerer kommentar</span>
22695
+ <span class="edit-text">{{ textEditingComment }}</span>
22630
22696
  </div>
22631
22697
  <button class="cancel-edit" (click)="cancelEdit()">
22632
22698
  <ds-icon name="remixCloseLine" size="16px" />
@@ -22638,7 +22704,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
22638
22704
  <div class="reply-indicator-content">
22639
22705
  <ds-icon name="remixReplyLine" size="16px" />
22640
22706
  <span class="reply-to-text">
22641
- Svarer til <span class="reply-author">{{ replyingTo()!.authorName }}</span>
22707
+ {{ textReplyingTo }} <span class="reply-author">{{ replyingTo()!.authorName }}</span>
22642
22708
  </span>
22643
22709
  </div>
22644
22710
  <button class="cancel-reply" (click)="cancelReply()">
@@ -22653,7 +22719,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
22653
22719
  <textarea
22654
22720
  #commentInput
22655
22721
  class="composer-input"
22656
- [placeholder]="editingComment() ? 'Rediger din kommentar...' : replyingTo() ? 'Tilføj et svar...' : 'Tilføj et svar...'"
22722
+ [placeholder]="editingComment() ? textEditComment : textAddReply"
22657
22723
  [ngModel]="commentText()"
22658
22724
  (ngModelChange)="commentText.set($event)"
22659
22725
  (input)="handleInput($event)"
@@ -22667,7 +22733,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
22667
22733
  variant="primary"
22668
22734
  size="sm"
22669
22735
  (clicked)="submitComment()"
22670
- aria-label="Send kommentar"
22736
+ [attr.aria-label]="textSend"
22671
22737
  [class.send-button-fixed]="true"
22672
22738
  [class.show]="commentText().trim().length > 0"
22673
22739
  >
@@ -22697,6 +22763,32 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
22697
22763
  type: Input
22698
22764
  }], onDeleteComment: [{
22699
22765
  type: Input
22766
+ }], textReplySingle: [{
22767
+ type: Input
22768
+ }], textReplyPlural: [{
22769
+ type: Input
22770
+ }], textNoRepliesTitle: [{
22771
+ type: Input
22772
+ }], textNoRepliesDesc: [{
22773
+ type: Input
22774
+ }], textAddReply: [{
22775
+ type: Input
22776
+ }], textEditComment: [{
22777
+ type: Input
22778
+ }], textEditingComment: [{
22779
+ type: Input
22780
+ }], textReplyingTo: [{
22781
+ type: Input
22782
+ }], textSend: [{
22783
+ type: Input
22784
+ }], textClosePost: [{
22785
+ type: Input
22786
+ }], textJustNow: [{
22787
+ type: Input
22788
+ }], textEdited: [{
22789
+ type: Input
22790
+ }], textConfirmDelete: [{
22791
+ type: Input
22700
22792
  }], commentInput: [{
22701
22793
  type: ViewChild,
22702
22794
  args: ['commentInput']
@@ -22766,8 +22858,23 @@ class DsMobilePostDetailModalService extends BaseModalService {
22766
22858
  onTogglePostLike: options?.onTogglePostLike,
22767
22859
  onSubmitComment: options?.onSubmitComment,
22768
22860
  onToggleCommentLike: options?.onToggleCommentLike,
22861
+ onEditComment: options?.onEditComment,
22862
+ onDeleteComment: options?.onDeleteComment,
22769
22863
  currentUserName: options?.currentUserName ?? '',
22770
22864
  currentUserInitialsInput: options?.currentUserInitials ?? '',
22865
+ ...(options?.textReplySingle && { textReplySingle: options.textReplySingle }),
22866
+ ...(options?.textReplyPlural && { textReplyPlural: options.textReplyPlural }),
22867
+ ...(options?.textNoRepliesTitle && { textNoRepliesTitle: options.textNoRepliesTitle }),
22868
+ ...(options?.textNoRepliesDesc && { textNoRepliesDesc: options.textNoRepliesDesc }),
22869
+ ...(options?.textAddReply && { textAddReply: options.textAddReply }),
22870
+ ...(options?.textEditComment && { textEditComment: options.textEditComment }),
22871
+ ...(options?.textEditingComment && { textEditingComment: options.textEditingComment }),
22872
+ ...(options?.textReplyingTo && { textReplyingTo: options.textReplyingTo }),
22873
+ ...(options?.textSend && { textSend: options.textSend }),
22874
+ ...(options?.textClosePost && { textClosePost: options.textClosePost }),
22875
+ ...(options?.textJustNow && { textJustNow: options.textJustNow }),
22876
+ ...(options?.textEdited && { textEdited: options.textEdited }),
22877
+ ...(options?.textConfirmDelete && { textConfirmDelete: options.textConfirmDelete }),
22771
22878
  }, {
22772
22879
  keyboardClose: true, // Keep keyboard close behavior for this modal
22773
22880
  });
@@ -24103,7 +24210,7 @@ class DsMobileBookingModalComponent {
24103
24210
  </ds-button>
24104
24211
  </div>
24105
24212
  </ds-mobile-modal-base>
24106
- `, 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{z-index:20001}\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"] }] });
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]{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"] }] });
24107
24214
  }
24108
24215
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingModalComponent, decorators: [{
24109
24216
  type: Component,
@@ -24187,7 +24294,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
24187
24294
  </ds-button>
24188
24295
  </div>
24189
24296
  </ds-mobile-modal-base>
24190
- `, 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{z-index:20001}\n"] }]
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]{z-index:20005!important}\n"] }]
24191
24298
  }], ctorParameters: () => [{ type: i1.ModalController }], propDecorators: { facilityId: [{
24192
24299
  type: Input
24193
24300
  }], facilityTitle: [{
@@ -24382,10 +24489,17 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
24382
24489
  class DsMobileBookingConfirmationWrapperComponent {
24383
24490
  booking;
24384
24491
  facilityThumbnail;
24492
+ textTitle = 'Booking accepteret';
24493
+ textMessageTemplate = 'Din booking til den {{date}} er bekræftet. Du kan annullere fra startdatoen.';
24494
+ textClose = 'Luk';
24495
+ monthNamesShort = [
24496
+ 'jan', 'feb', 'mar', 'apr', 'maj', 'jun',
24497
+ 'jul', 'aug', 'sep', 'okt', 'nov', 'dec'
24498
+ ];
24385
24499
  get confirmationMessage() {
24386
24500
  const date = this.booking.selectedDate.fullDate;
24387
24501
  const dateStr = this.formatFullDate(date);
24388
- return `Din booking til den ${dateStr} er bekræftet. Du kan annullere fra startdatoen.`;
24502
+ return this.textMessageTemplate.replace('{{date}}', dateStr);
24389
24503
  }
24390
24504
  get formattedDate() {
24391
24505
  const { dayName, date, monthName } = this.booking.selectedDate;
@@ -24397,20 +24511,16 @@ class DsMobileBookingConfirmationWrapperComponent {
24397
24511
  }
24398
24512
  formatFullDate(date) {
24399
24513
  const day = date.getDate();
24400
- const monthNames = [
24401
- 'januar', 'februar', 'marts', 'april', 'maj', 'juni',
24402
- 'juli', 'august', 'september', 'oktober', 'november', 'december'
24403
- ];
24404
- const month = monthNames[date.getMonth()];
24514
+ const month = this.monthNamesShort[date.getMonth()];
24405
24515
  const year = date.getFullYear();
24406
- return `${day}. ${month}, ${year}`;
24516
+ return `${day}. ${month} ${year}`;
24407
24517
  }
24408
24518
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingConfirmationWrapperComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
24409
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: DsMobileBookingConfirmationWrapperComponent, isStandalone: true, selector: "ds-mobile-booking-confirmation-wrapper", inputs: { booking: "booking", facilityThumbnail: "facilityThumbnail" }, ngImport: i0, template: `
24519
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.3.16", type: DsMobileBookingConfirmationWrapperComponent, isStandalone: true, selector: "ds-mobile-booking-confirmation-wrapper", inputs: { booking: "booking", facilityThumbnail: "facilityThumbnail", textTitle: "textTitle", textMessageTemplate: "textMessageTemplate", textClose: "textClose", monthNamesShort: "monthNamesShort" }, ngImport: i0, template: `
24410
24520
  <ds-mobile-confirmation-sheet
24411
- [title]="'Booking accepteret'"
24521
+ [title]="textTitle"
24412
24522
  [message]="confirmationMessage"
24413
- [buttonText]="'Luk'"
24523
+ [buttonText]="textClose"
24414
24524
  [illustrationVariant]="'confirmation'">
24415
24525
  <ng-template #summary>
24416
24526
  <ds-mobile-booking-summary
@@ -24435,9 +24545,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
24435
24545
  ],
24436
24546
  template: `
24437
24547
  <ds-mobile-confirmation-sheet
24438
- [title]="'Booking accepteret'"
24548
+ [title]="textTitle"
24439
24549
  [message]="confirmationMessage"
24440
- [buttonText]="'Luk'"
24550
+ [buttonText]="textClose"
24441
24551
  [illustrationVariant]="'confirmation'">
24442
24552
  <ng-template #summary>
24443
24553
  <ds-mobile-booking-summary
@@ -24454,6 +24564,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
24454
24564
  type: Input
24455
24565
  }], facilityThumbnail: [{
24456
24566
  type: Input
24567
+ }], textTitle: [{
24568
+ type: Input
24569
+ }], textMessageTemplate: [{
24570
+ type: Input
24571
+ }], textClose: [{
24572
+ type: Input
24573
+ }], monthNamesShort: [{
24574
+ type: Input
24457
24575
  }] } });
24458
24576
 
24459
24577
  /**
@@ -24506,7 +24624,7 @@ class DsMobileBookingModalService extends BaseModalService {
24506
24624
  // Dismiss all open modals (booking modal + facility detail modal)
24507
24625
  await this.dismissAllModals();
24508
24626
  // Show confirmation sheet after all modals are dismissed
24509
- await this.openConfirmationSheet(result.data, facilityThumbnail);
24627
+ await this.openConfirmationSheet(result.data, facilityThumbnail, extras?.labels);
24510
24628
  }
24511
24629
  }
24512
24630
  /**
@@ -24526,12 +24644,16 @@ class DsMobileBookingModalService extends BaseModalService {
24526
24644
  * @param facilityThumbnail Optional thumbnail image URL
24527
24645
  * @returns Promise that resolves when the sheet is dismissed
24528
24646
  */
24529
- async openConfirmationSheet(booking, facilityThumbnail) {
24647
+ async openConfirmationSheet(booking, facilityThumbnail, labels) {
24530
24648
  const sheet = await this.modalController.create({
24531
24649
  component: DsMobileBookingConfirmationWrapperComponent,
24532
24650
  componentProps: {
24533
24651
  booking,
24534
- facilityThumbnail
24652
+ facilityThumbnail,
24653
+ ...(labels?.confirmationTitle && { textTitle: labels.confirmationTitle }),
24654
+ ...(labels?.confirmationMessageTemplate && { textMessageTemplate: labels.confirmationMessageTemplate }),
24655
+ ...(labels?.confirmationClose && { textClose: labels.confirmationClose }),
24656
+ ...(labels?.monthNamesShort && { monthNamesShort: labels.monthNamesShort })
24535
24657
  },
24536
24658
  breakpoints: [0, 1],
24537
24659
  initialBreakpoint: 1,
@@ -27659,7 +27781,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
27659
27781
  * await this.facilityModal.open({
27660
27782
  * id: 'facility-1',
27661
27783
  * facilityTitle: 'Festlokale på taget',
27662
- * heroImage: '/Assets/Dummy-photos/balcony-view.jpg',
27784
+ * heroImage: '/assets/Dummy-photos/balcony-view.jpg',
27663
27785
  * fullDescription: '<p>The rooftop terrace is designed...</p>',
27664
27786
  * requirements: ['Kræver nøglekort'],
27665
27787
  * bookingType: 'Instant booking',
@@ -27839,7 +27961,8 @@ class DsMobileHandbookDetailModalComponent {
27839
27961
  // Translations
27840
27962
  textLoading = 'Henter...';
27841
27963
  textError = 'Fejl';
27842
- textItems = 'emner';
27964
+ textItemSingle = 'emne';
27965
+ textItemsPlural = 'emner';
27843
27966
  textClose = 'Luk';
27844
27967
  textEmptyTitle = 'Ingen emner endnu';
27845
27968
  textEmptyDescription = 'Denne mappe er tom';
@@ -28023,8 +28146,8 @@ class DsMobileHandbookDetailModalComponent {
28023
28146
  // Attachment action is now handled by DsMobileCardInlineFileComponent via fileUrl input
28024
28147
  }
28025
28148
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileHandbookDetailModalComponent, deps: [{ token: i1.ModalController }], target: i0.ɵɵFactoryTarget.Component });
28026
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DsMobileHandbookDetailModalComponent, isStandalone: true, selector: "ds-mobile-handbook-detail-modal", inputs: { handbookData: "handbookData", loading: "loading", error: "error", textLoading: "textLoading", textError: "textError", textItems: "textItems", textClose: "textClose", textEmptyTitle: "textEmptyTitle", textEmptyDescription: "textEmptyDescription", textCall: "textCall", textCopyPhone: "textCopyPhone", textEmail: "textEmail", textCopyEmail: "textCopyEmail" }, ngImport: i0, template: `
28027
- <ds-mobile-modal-base [loading]="loading" [error]="error" [textLoading]="textLoading" [textErrorTitle]="textError" [headerTitle]="handbook().title" [headerMeta]="handbook().itemCount + ' ' + textItems" [closeButtonLabel]="textClose">
28149
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DsMobileHandbookDetailModalComponent, isStandalone: true, selector: "ds-mobile-handbook-detail-modal", inputs: { handbookData: "handbookData", loading: "loading", error: "error", textLoading: "textLoading", textError: "textError", textItemSingle: "textItemSingle", textItemsPlural: "textItemsPlural", textClose: "textClose", textEmptyTitle: "textEmptyTitle", textEmptyDescription: "textEmptyDescription", textCall: "textCall", textCopyPhone: "textCopyPhone", textEmail: "textEmail", textCopyEmail: "textCopyEmail" }, ngImport: i0, template: `
28150
+ <ds-mobile-modal-base [loading]="loading" [error]="error" [textLoading]="textLoading" [textErrorTitle]="textError" [headerTitle]="handbook().title" [headerMeta]="handbook().itemCount + ' ' + (handbook().itemCount === 1 ? textItemSingle : textItemsPlural)" [closeButtonLabel]="textClose">
28028
28151
  <!-- Header Folder Icon -->
28029
28152
  <ds-mobile-handbook-folder-mini header-leading [variant]="handbook().variant" [customColor]="handbook().customColor" [iconName]="handbook().iconName">
28030
28153
  </ds-mobile-handbook-folder-mini>
@@ -28085,7 +28208,7 @@ class DsMobileHandbookDetailModalComponent {
28085
28208
  <!-- Empty State -->
28086
28209
  <ds-mobile-section>
28087
28210
  <div class="handbook-empty-state">
28088
- <img src="/Assets/Empty%20state-chat.png" alt="No items yet" class="empty-state-image" />
28211
+ <img src="/assets/Empty%20state-chat.png" alt="No items yet" class="empty-state-image" />
28089
28212
  <h3 class="empty-state-title">{{ textEmptyTitle }}</h3>
28090
28213
  <p class="empty-state-description">{{ textEmptyDescription }}</p>
28091
28214
  </div>
@@ -28105,7 +28228,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
28105
28228
  DsMobileModalBaseComponent,
28106
28229
  DsMobileSectionComponent,
28107
28230
  ], schemas: [CUSTOM_ELEMENTS_SCHEMA], template: `
28108
- <ds-mobile-modal-base [loading]="loading" [error]="error" [textLoading]="textLoading" [textErrorTitle]="textError" [headerTitle]="handbook().title" [headerMeta]="handbook().itemCount + ' ' + textItems" [closeButtonLabel]="textClose">
28231
+ <ds-mobile-modal-base [loading]="loading" [error]="error" [textLoading]="textLoading" [textErrorTitle]="textError" [headerTitle]="handbook().title" [headerMeta]="handbook().itemCount + ' ' + (handbook().itemCount === 1 ? textItemSingle : textItemsPlural)" [closeButtonLabel]="textClose">
28109
28232
  <!-- Header Folder Icon -->
28110
28233
  <ds-mobile-handbook-folder-mini header-leading [variant]="handbook().variant" [customColor]="handbook().customColor" [iconName]="handbook().iconName">
28111
28234
  </ds-mobile-handbook-folder-mini>
@@ -28166,7 +28289,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
28166
28289
  <!-- Empty State -->
28167
28290
  <ds-mobile-section>
28168
28291
  <div class="handbook-empty-state">
28169
- <img src="/Assets/Empty%20state-chat.png" alt="No items yet" class="empty-state-image" />
28292
+ <img src="/assets/Empty%20state-chat.png" alt="No items yet" class="empty-state-image" />
28170
28293
  <h3 class="empty-state-title">{{ textEmptyTitle }}</h3>
28171
28294
  <p class="empty-state-description">{{ textEmptyDescription }}</p>
28172
28295
  </div>
@@ -28184,7 +28307,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
28184
28307
  type: Input
28185
28308
  }], textError: [{
28186
28309
  type: Input
28187
- }], textItems: [{
28310
+ }], textItemSingle: [{
28311
+ type: Input
28312
+ }], textItemsPlural: [{
28188
28313
  type: Input
28189
28314
  }], textClose: [{
28190
28315
  type: Input
@@ -28257,16 +28382,17 @@ class DsMobileHandbookDetailModalService extends BaseModalService {
28257
28382
  handbookData: handbookData,
28258
28383
  loading: options?.loading ?? false,
28259
28384
  error: options?.error,
28260
- textLoading: handbookData.textLoading,
28261
- textError: handbookData.textError,
28262
- textItems: handbookData.textItems,
28263
- textClose: handbookData.textClose,
28264
- textEmptyTitle: handbookData.textEmptyTitle,
28265
- textEmptyDescription: handbookData.textEmptyDescription,
28266
- textCall: handbookData.textCall,
28267
- textCopyPhone: handbookData.textCopyPhone,
28268
- textEmail: handbookData.textEmail,
28269
- textCopyEmail: handbookData.textCopyEmail,
28385
+ textLoading: handbookData.textLoading ?? 'Henter...',
28386
+ textError: handbookData.textError ?? 'Fejl',
28387
+ textItemSingle: handbookData.textItemSingle ?? 'emne',
28388
+ textItemsPlural: handbookData.textItemsPlural ?? 'emner',
28389
+ textClose: handbookData.textClose ?? 'Luk',
28390
+ textEmptyTitle: handbookData.textEmptyTitle ?? 'Ingen emner endnu',
28391
+ textEmptyDescription: handbookData.textEmptyDescription ?? 'Denne mappe er tom',
28392
+ textCall: handbookData.textCall ?? 'Ring',
28393
+ textCopyPhone: handbookData.textCopyPhone ?? 'Kopier nummer',
28394
+ textEmail: handbookData.textEmail ?? 'Skriv e-mail',
28395
+ textCopyEmail: handbookData.textCopyEmail ?? 'Kopier e-mail',
28270
28396
  }, {
28271
28397
  keyboardClose: true, // Keep keyboard close behavior for this modal
28272
28398
  });
@@ -28353,7 +28479,8 @@ class DsMobileHandbookFolderComponent {
28353
28479
  // Translations
28354
28480
  textLoading = 'Henter...';
28355
28481
  textError = 'Fejl';
28356
- textItems = 'emner';
28482
+ textItemSingle = 'emne';
28483
+ textItemsPlural = 'emner';
28357
28484
  textClose = 'Luk';
28358
28485
  textEmptyTitle = 'Ingen emner endnu';
28359
28486
  textEmptyDescription = 'Denne mappe er tom';
@@ -28448,7 +28575,8 @@ class DsMobileHandbookFolderComponent {
28448
28575
  items: this.items,
28449
28576
  textLoading: this.textLoading,
28450
28577
  textError: this.textError,
28451
- textItems: this.textItems,
28578
+ textItemSingle: this.textItemSingle,
28579
+ textItemsPlural: this.textItemsPlural,
28452
28580
  textClose: this.textClose,
28453
28581
  textEmptyTitle: this.textEmptyTitle,
28454
28582
  textEmptyDescription: this.textEmptyDescription,
@@ -28474,7 +28602,7 @@ class DsMobileHandbookFolderComponent {
28474
28602
  this.handbookModal = handbookModal;
28475
28603
  }
28476
28604
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileHandbookFolderComponent, deps: [{ token: DsMobileHandbookDetailModalService }], target: i0.ɵɵFactoryTarget.Component });
28477
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DsMobileHandbookFolderComponent, isStandalone: true, selector: "ds-mobile-handbook-folder", inputs: { variant: "variant", customColor: "customColor", iconName: "iconName", itemCount: "itemCount", label: "label", items: "items", loading: "loading", error: "error", textLoading: "textLoading", textError: "textError", textItems: "textItems", textClose: "textClose", textEmptyTitle: "textEmptyTitle", textEmptyDescription: "textEmptyDescription", textCall: "textCall", textCopyPhone: "textCopyPhone", textEmail: "textEmail", textCopyEmail: "textCopyEmail" }, host: { listeners: { "mouseenter": "open()", "mouseleave": "close()", "touchstart": "onTouchStart($event)", "touchend": "onTouchEnd()", "touchcancel": "onTouchCancel()", "click": "onClick()" } }, ngImport: i0, template: `
28605
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DsMobileHandbookFolderComponent, isStandalone: true, selector: "ds-mobile-handbook-folder", inputs: { variant: "variant", customColor: "customColor", iconName: "iconName", itemCount: "itemCount", label: "label", items: "items", loading: "loading", error: "error", textLoading: "textLoading", textError: "textError", textItemSingle: "textItemSingle", textItemsPlural: "textItemsPlural", textClose: "textClose", textEmptyTitle: "textEmptyTitle", textEmptyDescription: "textEmptyDescription", textCall: "textCall", textCopyPhone: "textCopyPhone", textEmail: "textEmail", textCopyEmail: "textCopyEmail" }, host: { listeners: { "mouseenter": "open()", "mouseleave": "close()", "touchstart": "onTouchStart($event)", "touchend": "onTouchEnd()", "touchcancel": "onTouchCancel()", "click": "onClick()" } }, ngImport: i0, template: `
28478
28606
  <div class="folder-container" [class.open]="isOpen()">
28479
28607
  <!-- Folder Tab SVG -->
28480
28608
  <svg class="folder-tab" width="101" height="24" viewBox="0 0 101 24" fill="none" xmlns="http://www.w3.org/2000/svg">
@@ -28504,18 +28632,18 @@ class DsMobileHandbookFolderComponent {
28504
28632
  <!-- Label and Item Count -->
28505
28633
  <div class="folder-label-container">
28506
28634
  <div class="folder-label ui-sm-semiBold">{{ label }}</div>
28507
- <div class="item-count ui-sm-regular" [style.color]="'var(--color-text-secondary, #6b7280)'">
28635
+ <div class="item-count ui-xs-regular" [style.color]="'var(--color-text-secondary, #6b7280)'">
28508
28636
  @if (loading) {
28509
28637
  <span class="loading-indicator">{{ textLoading }}</span>
28510
28638
  } @else if (error) {
28511
28639
  <span class="error-indicator" [style.color]="'var(--color-destructive-base)'">{{ textError }}</span>
28512
28640
  } @else {
28513
28641
  <span>{{ itemCount }}</span>
28514
- <span class="item-count-label">{{ textItems }}</span>
28642
+ <span>{{ itemCount === 1 ? textItemSingle : textItemsPlural }}</span>
28515
28643
  }
28516
28644
  </div>
28517
28645
  </div>
28518
- `, isInline: true, styles: [":host{display:inline-flex;flex-direction:column;align-items:center;gap:16px;width:100%;min-width:140px;cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;padding:16px;border-radius:16px;background:var(--color-background-neutral-secondary, #f0f0f0);transition:background .2s ease}:host:active{background:var(--color-background-neutral-secondary-hover, #ebebeb)}@media (hover: hover){:host:hover{background:var(--color-background-neutral-secondary-hover, #ebebeb)}}:host{--color-red-base: #dc3545;--color-red-strong: #ae1d3b;--color-green-base: #28a745;--color-green-strong: #058057;--color-yellow-base: #ffc107;--color-yellow-strong: #e4b200;--color-purple-base: #6f42c1;--color-purple-strong: #4204c5;--color-indigo-base: #6610f2;--color-indigo-strong: #a527a2;--color-lime-base: #82c91e;--color-lime-strong: #58a503;--color-teal-base: #20c997;--color-teal-strong: #0ca678;--color-cyan-base: #17a2b8;--color-cyan-strong: #1098ad;--color-brown-base: #795548;--color-brown-strong: #5c4033;--color-light-blue-base: #add8e6;--color-light-blue-strong: #87ceeb;--color-light-green-base: #90ee90;--color-light-green-strong: #32cd32;--color-coral-base: #f08080;--color-coral-strong: #cd5c5c;--color-salmon-base: #ffa07a;--color-salmon-strong: #fa8072;--color-seagreen-base: #20b2aa;--color-seagreen-strong: #2e8b57}.folder-container{position:relative;width:100%;display:flex;flex-direction:column;perspective:800px;-webkit-perspective:800px;max-width:160px;transform-style:preserve-3d;-webkit-transform-style:preserve-3d}.folder-container.open .page-sheet{-webkit-transform:translateY(-8px);transform:translateY(-8px);transition-delay:.2s}.folder-container.open .page-sheet:nth-child(1){-webkit-transform:scale(1) translateY(-8px) rotateX(-45deg) translateZ(.1px);transform:scale(1) translateY(-8px) rotateX(-45deg) translateZ(.1px)}.folder-container.open .page-sheet:nth-child(2){-webkit-transform:scale(.98) translateY(-12px) rotateX(-36deg) translateZ(.1px);transform:scale(.98) translateY(-12px) rotateX(-36deg) translateZ(.1px)}.folder-container.open .page-sheet:nth-child(3){-webkit-transform:scale(.96) translateY(-16px) rotateX(-27deg) translateZ(.1px);transform:scale(.96) translateY(-16px) rotateX(-27deg) translateZ(.1px)}.folder-container.open .page-sheet:nth-child(4){-webkit-transform:scale(.94) translateY(-20px) rotateX(-18deg) translateZ(.1px);transform:scale(.94) translateY(-20px) rotateX(-18deg) translateZ(.1px)}.folder-container.open .page-sheet:nth-child(5){-webkit-transform:scale(.92) translateY(-24px) rotateX(-9deg) translateZ(.1px);transform:scale(.92) translateY(-24px) rotateX(-9deg) translateZ(.1px)}.folder-container.open .page-sheet:nth-child(6){-webkit-transform:scale(.9) translateY(-28px) rotateX(0deg) translateZ(.1px);transform:scale(.9) translateY(-28px) rotateX(.1px)}.folder-container.open .folder-front{-webkit-transform:translate3d(0,0,0) rotateX(-45deg);transform:translateZ(0) rotateX(-45deg)}.folder-tab{width:50%;height:auto;display:block}.folder-back{height:128px;border-radius:0 12px 12px;position:relative;margin-top:-1px;transform-style:preserve-3d;-webkit-transform-style:preserve-3d;backface-visibility:hidden;-webkit-backface-visibility:hidden;-webkit-transform:translateZ(0);transform:translateZ(0)}.page-sheet{position:absolute;width:80%;height:120px;background:#fff;border-radius:8px;box-shadow:0 -1px 5px #0000001a;border:1px solid var(--border-color-default);transition:transform .3s ease-out;-webkit-transition:-webkit-transform .3s ease-out;left:10%;-webkit-transform:translateZ(0);transform:translateZ(0);transform-style:preserve-3d;-webkit-transform-style:preserve-3d;backface-visibility:hidden;-webkit-backface-visibility:hidden;-webkit-font-smoothing:antialiased;will-change:transform}.page-sheet:nth-child(1){bottom:2px;z-index:6;transform-origin:bottom center;-webkit-transform-origin:bottom center;-webkit-transform:scale(1) translateZ(.1px);transform:scale(1) translateZ(.1px)}.page-sheet:nth-child(2){bottom:8px;z-index:5;transform-origin:bottom center;-webkit-transform-origin:bottom center;-webkit-transform:scale(.98) translateZ(.1px);transform:scale(.98) translateZ(.1px)}.page-sheet:nth-child(3){bottom:14px;z-index:4;transform-origin:bottom center;-webkit-transform-origin:bottom center;-webkit-transform:scale(.96) translateZ(.1px);transform:scale(.96) translateZ(.1px)}.page-sheet:nth-child(4){bottom:20px;z-index:3;transform-origin:bottom center;-webkit-transform-origin:bottom center;-webkit-transform:scale(.94) translateZ(.1px);transform:scale(.94) translateZ(.1px)}.page-sheet:nth-child(5){bottom:26px;z-index:2;transform-origin:bottom center;-webkit-transform-origin:bottom center;-webkit-transform:scale(.92) translateZ(.1px);transform:scale(.92) translateZ(.1px)}.page-sheet:nth-child(6){bottom:32px;z-index:1;transform-origin:bottom center;-webkit-transform-origin:bottom center;-webkit-transform:scale(.9) translateZ(.1px);transform:scale(.9) translateZ(.1px)}.folder-front{position:absolute;bottom:0;left:0;right:0;height:116px;border-radius:12px;display:flex;align-items:center;justify-content:center;padding:8px;z-index:2;transform-origin:bottom center;-webkit-transform-origin:bottom center;transform-style:preserve-3d;-webkit-transform-style:preserve-3d;transition:transform .4s ease-in-out,-webkit-transform .4s ease-in-out;-webkit-transition:-webkit-transform .4s ease-in-out;will-change:transform;backface-visibility:hidden;-webkit-backface-visibility:hidden;-webkit-font-smoothing:antialiased;-webkit-transform:rotateX(-20deg) translateZ(.1px);transform:rotateX(-20deg) translateZ(.1px);-webkit-transform:translate3d(0,0,0) rotateX(-20deg);transform:translateZ(0) rotateX(-20deg);box-shadow:inset 0 64px 48px #fff3,inset 0 2px 4px #ffffff4d,inset 0 1px 1px #ffffff4d}.item-count{display:flex;align-items:center;gap:4px}.item-count-label{letter-spacing:.5px}.folder-icon{display:flex;align-items:center;justify-content:center}.folder-label-container{display:flex;flex-direction:column;align-items:center;gap:4px;width:100%;min-width:0}.folder-label{text-align:center;width:100%;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.loading-indicator,.error-indicator{font-size:var(--font-size-xs)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }] });
28646
+ `, isInline: true, styles: [":host{display:inline-flex;flex-direction:column;align-items:center;gap:16px;width:100%;min-width:140px;cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;padding:16px;border-radius:16px;background:var(--color-background-neutral-secondary, #f0f0f0);transition:background .2s ease}:host:active{background:var(--color-background-neutral-secondary-hover, #ebebeb)}@media (hover: hover){:host:hover{background:var(--color-background-neutral-secondary-hover, #ebebeb)}}:host{--color-red-base: #dc3545;--color-red-strong: #ae1d3b;--color-green-base: #28a745;--color-green-strong: #058057;--color-yellow-base: #ffc107;--color-yellow-strong: #e4b200;--color-purple-base: #6f42c1;--color-purple-strong: #4204c5;--color-indigo-base: #6610f2;--color-indigo-strong: #a527a2;--color-lime-base: #82c91e;--color-lime-strong: #58a503;--color-teal-base: #20c997;--color-teal-strong: #0ca678;--color-cyan-base: #17a2b8;--color-cyan-strong: #1098ad;--color-brown-base: #795548;--color-brown-strong: #5c4033;--color-light-blue-base: #add8e6;--color-light-blue-strong: #87ceeb;--color-light-green-base: #90ee90;--color-light-green-strong: #32cd32;--color-coral-base: #f08080;--color-coral-strong: #cd5c5c;--color-salmon-base: #ffa07a;--color-salmon-strong: #fa8072;--color-seagreen-base: #20b2aa;--color-seagreen-strong: #2e8b57}.folder-container{position:relative;width:100%;display:flex;flex-direction:column;perspective:800px;-webkit-perspective:800px;max-width:160px;transform-style:preserve-3d;-webkit-transform-style:preserve-3d}.folder-container.open .page-sheet{-webkit-transform:translateY(-8px);transform:translateY(-8px);transition-delay:.2s}.folder-container.open .page-sheet:nth-child(1){-webkit-transform:scale(1) translateY(-8px) rotateX(-45deg) translateZ(.1px);transform:scale(1) translateY(-8px) rotateX(-45deg) translateZ(.1px)}.folder-container.open .page-sheet:nth-child(2){-webkit-transform:scale(.98) translateY(-12px) rotateX(-36deg) translateZ(.1px);transform:scale(.98) translateY(-12px) rotateX(-36deg) translateZ(.1px)}.folder-container.open .page-sheet:nth-child(3){-webkit-transform:scale(.96) translateY(-16px) rotateX(-27deg) translateZ(.1px);transform:scale(.96) translateY(-16px) rotateX(-27deg) translateZ(.1px)}.folder-container.open .page-sheet:nth-child(4){-webkit-transform:scale(.94) translateY(-20px) rotateX(-18deg) translateZ(.1px);transform:scale(.94) translateY(-20px) rotateX(-18deg) translateZ(.1px)}.folder-container.open .page-sheet:nth-child(5){-webkit-transform:scale(.92) translateY(-24px) rotateX(-9deg) translateZ(.1px);transform:scale(.92) translateY(-24px) rotateX(-9deg) translateZ(.1px)}.folder-container.open .page-sheet:nth-child(6){-webkit-transform:scale(.9) translateY(-28px) rotateX(0deg) translateZ(.1px);transform:scale(.9) translateY(-28px) rotateX(.1px)}.folder-container.open .folder-front{-webkit-transform:translate3d(0,0,0) rotateX(-45deg);transform:translateZ(0) rotateX(-45deg)}.folder-tab{width:50%;height:auto;display:block}.folder-back{height:128px;border-radius:0 12px 12px;position:relative;margin-top:-1px;transform-style:preserve-3d;-webkit-transform-style:preserve-3d;backface-visibility:hidden;-webkit-backface-visibility:hidden;-webkit-transform:translateZ(0);transform:translateZ(0)}.page-sheet{position:absolute;width:80%;height:120px;background:#fff;border-radius:8px;box-shadow:0 -1px 5px #0000001a;border:1px solid var(--border-color-default);transition:transform .3s ease-out;-webkit-transition:-webkit-transform .3s ease-out;left:10%;-webkit-transform:translateZ(0);transform:translateZ(0);transform-style:preserve-3d;-webkit-transform-style:preserve-3d;backface-visibility:hidden;-webkit-backface-visibility:hidden;-webkit-font-smoothing:antialiased;will-change:transform}.page-sheet:nth-child(1){bottom:2px;z-index:6;transform-origin:bottom center;-webkit-transform-origin:bottom center;-webkit-transform:scale(1) translateZ(.1px);transform:scale(1) translateZ(.1px)}.page-sheet:nth-child(2){bottom:8px;z-index:5;transform-origin:bottom center;-webkit-transform-origin:bottom center;-webkit-transform:scale(.98) translateZ(.1px);transform:scale(.98) translateZ(.1px)}.page-sheet:nth-child(3){bottom:14px;z-index:4;transform-origin:bottom center;-webkit-transform-origin:bottom center;-webkit-transform:scale(.96) translateZ(.1px);transform:scale(.96) translateZ(.1px)}.page-sheet:nth-child(4){bottom:20px;z-index:3;transform-origin:bottom center;-webkit-transform-origin:bottom center;-webkit-transform:scale(.94) translateZ(.1px);transform:scale(.94) translateZ(.1px)}.page-sheet:nth-child(5){bottom:26px;z-index:2;transform-origin:bottom center;-webkit-transform-origin:bottom center;-webkit-transform:scale(.92) translateZ(.1px);transform:scale(.92) translateZ(.1px)}.page-sheet:nth-child(6){bottom:32px;z-index:1;transform-origin:bottom center;-webkit-transform-origin:bottom center;-webkit-transform:scale(.9) translateZ(.1px);transform:scale(.9) translateZ(.1px)}.folder-front{position:absolute;bottom:0;left:0;right:0;height:116px;border-radius:12px;display:flex;align-items:center;justify-content:center;padding:8px;z-index:2;transform-origin:bottom center;-webkit-transform-origin:bottom center;transform-style:preserve-3d;-webkit-transform-style:preserve-3d;transition:transform .4s ease-in-out,-webkit-transform .4s ease-in-out;-webkit-transition:-webkit-transform .4s ease-in-out;will-change:transform;backface-visibility:hidden;-webkit-backface-visibility:hidden;-webkit-font-smoothing:antialiased;-webkit-transform:rotateX(-20deg) translateZ(.1px);transform:rotateX(-20deg) translateZ(.1px);-webkit-transform:translate3d(0,0,0) rotateX(-20deg);transform:translateZ(0) rotateX(-20deg);box-shadow:inset 0 64px 48px #fff3,inset 0 2px 4px #ffffff4d,inset 0 1px 1px #ffffff4d}.item-count{display:flex;align-items:center;gap:4px}.folder-icon{display:flex;align-items:center;justify-content:center}.folder-label-container{display:flex;flex-direction:column;align-items:center;gap:4px;width:100%;min-width:0}.folder-label{text-align:center;width:100%;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.loading-indicator,.error-indicator{font-size:var(--font-size-xs)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }] });
28519
28647
  }
28520
28648
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileHandbookFolderComponent, decorators: [{
28521
28649
  type: Component,
@@ -28549,18 +28677,18 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
28549
28677
  <!-- Label and Item Count -->
28550
28678
  <div class="folder-label-container">
28551
28679
  <div class="folder-label ui-sm-semiBold">{{ label }}</div>
28552
- <div class="item-count ui-sm-regular" [style.color]="'var(--color-text-secondary, #6b7280)'">
28680
+ <div class="item-count ui-xs-regular" [style.color]="'var(--color-text-secondary, #6b7280)'">
28553
28681
  @if (loading) {
28554
28682
  <span class="loading-indicator">{{ textLoading }}</span>
28555
28683
  } @else if (error) {
28556
28684
  <span class="error-indicator" [style.color]="'var(--color-destructive-base)'">{{ textError }}</span>
28557
28685
  } @else {
28558
28686
  <span>{{ itemCount }}</span>
28559
- <span class="item-count-label">{{ textItems }}</span>
28687
+ <span>{{ itemCount === 1 ? textItemSingle : textItemsPlural }}</span>
28560
28688
  }
28561
28689
  </div>
28562
28690
  </div>
28563
- `, styles: [":host{display:inline-flex;flex-direction:column;align-items:center;gap:16px;width:100%;min-width:140px;cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;padding:16px;border-radius:16px;background:var(--color-background-neutral-secondary, #f0f0f0);transition:background .2s ease}:host:active{background:var(--color-background-neutral-secondary-hover, #ebebeb)}@media (hover: hover){:host:hover{background:var(--color-background-neutral-secondary-hover, #ebebeb)}}:host{--color-red-base: #dc3545;--color-red-strong: #ae1d3b;--color-green-base: #28a745;--color-green-strong: #058057;--color-yellow-base: #ffc107;--color-yellow-strong: #e4b200;--color-purple-base: #6f42c1;--color-purple-strong: #4204c5;--color-indigo-base: #6610f2;--color-indigo-strong: #a527a2;--color-lime-base: #82c91e;--color-lime-strong: #58a503;--color-teal-base: #20c997;--color-teal-strong: #0ca678;--color-cyan-base: #17a2b8;--color-cyan-strong: #1098ad;--color-brown-base: #795548;--color-brown-strong: #5c4033;--color-light-blue-base: #add8e6;--color-light-blue-strong: #87ceeb;--color-light-green-base: #90ee90;--color-light-green-strong: #32cd32;--color-coral-base: #f08080;--color-coral-strong: #cd5c5c;--color-salmon-base: #ffa07a;--color-salmon-strong: #fa8072;--color-seagreen-base: #20b2aa;--color-seagreen-strong: #2e8b57}.folder-container{position:relative;width:100%;display:flex;flex-direction:column;perspective:800px;-webkit-perspective:800px;max-width:160px;transform-style:preserve-3d;-webkit-transform-style:preserve-3d}.folder-container.open .page-sheet{-webkit-transform:translateY(-8px);transform:translateY(-8px);transition-delay:.2s}.folder-container.open .page-sheet:nth-child(1){-webkit-transform:scale(1) translateY(-8px) rotateX(-45deg) translateZ(.1px);transform:scale(1) translateY(-8px) rotateX(-45deg) translateZ(.1px)}.folder-container.open .page-sheet:nth-child(2){-webkit-transform:scale(.98) translateY(-12px) rotateX(-36deg) translateZ(.1px);transform:scale(.98) translateY(-12px) rotateX(-36deg) translateZ(.1px)}.folder-container.open .page-sheet:nth-child(3){-webkit-transform:scale(.96) translateY(-16px) rotateX(-27deg) translateZ(.1px);transform:scale(.96) translateY(-16px) rotateX(-27deg) translateZ(.1px)}.folder-container.open .page-sheet:nth-child(4){-webkit-transform:scale(.94) translateY(-20px) rotateX(-18deg) translateZ(.1px);transform:scale(.94) translateY(-20px) rotateX(-18deg) translateZ(.1px)}.folder-container.open .page-sheet:nth-child(5){-webkit-transform:scale(.92) translateY(-24px) rotateX(-9deg) translateZ(.1px);transform:scale(.92) translateY(-24px) rotateX(-9deg) translateZ(.1px)}.folder-container.open .page-sheet:nth-child(6){-webkit-transform:scale(.9) translateY(-28px) rotateX(0deg) translateZ(.1px);transform:scale(.9) translateY(-28px) rotateX(.1px)}.folder-container.open .folder-front{-webkit-transform:translate3d(0,0,0) rotateX(-45deg);transform:translateZ(0) rotateX(-45deg)}.folder-tab{width:50%;height:auto;display:block}.folder-back{height:128px;border-radius:0 12px 12px;position:relative;margin-top:-1px;transform-style:preserve-3d;-webkit-transform-style:preserve-3d;backface-visibility:hidden;-webkit-backface-visibility:hidden;-webkit-transform:translateZ(0);transform:translateZ(0)}.page-sheet{position:absolute;width:80%;height:120px;background:#fff;border-radius:8px;box-shadow:0 -1px 5px #0000001a;border:1px solid var(--border-color-default);transition:transform .3s ease-out;-webkit-transition:-webkit-transform .3s ease-out;left:10%;-webkit-transform:translateZ(0);transform:translateZ(0);transform-style:preserve-3d;-webkit-transform-style:preserve-3d;backface-visibility:hidden;-webkit-backface-visibility:hidden;-webkit-font-smoothing:antialiased;will-change:transform}.page-sheet:nth-child(1){bottom:2px;z-index:6;transform-origin:bottom center;-webkit-transform-origin:bottom center;-webkit-transform:scale(1) translateZ(.1px);transform:scale(1) translateZ(.1px)}.page-sheet:nth-child(2){bottom:8px;z-index:5;transform-origin:bottom center;-webkit-transform-origin:bottom center;-webkit-transform:scale(.98) translateZ(.1px);transform:scale(.98) translateZ(.1px)}.page-sheet:nth-child(3){bottom:14px;z-index:4;transform-origin:bottom center;-webkit-transform-origin:bottom center;-webkit-transform:scale(.96) translateZ(.1px);transform:scale(.96) translateZ(.1px)}.page-sheet:nth-child(4){bottom:20px;z-index:3;transform-origin:bottom center;-webkit-transform-origin:bottom center;-webkit-transform:scale(.94) translateZ(.1px);transform:scale(.94) translateZ(.1px)}.page-sheet:nth-child(5){bottom:26px;z-index:2;transform-origin:bottom center;-webkit-transform-origin:bottom center;-webkit-transform:scale(.92) translateZ(.1px);transform:scale(.92) translateZ(.1px)}.page-sheet:nth-child(6){bottom:32px;z-index:1;transform-origin:bottom center;-webkit-transform-origin:bottom center;-webkit-transform:scale(.9) translateZ(.1px);transform:scale(.9) translateZ(.1px)}.folder-front{position:absolute;bottom:0;left:0;right:0;height:116px;border-radius:12px;display:flex;align-items:center;justify-content:center;padding:8px;z-index:2;transform-origin:bottom center;-webkit-transform-origin:bottom center;transform-style:preserve-3d;-webkit-transform-style:preserve-3d;transition:transform .4s ease-in-out,-webkit-transform .4s ease-in-out;-webkit-transition:-webkit-transform .4s ease-in-out;will-change:transform;backface-visibility:hidden;-webkit-backface-visibility:hidden;-webkit-font-smoothing:antialiased;-webkit-transform:rotateX(-20deg) translateZ(.1px);transform:rotateX(-20deg) translateZ(.1px);-webkit-transform:translate3d(0,0,0) rotateX(-20deg);transform:translateZ(0) rotateX(-20deg);box-shadow:inset 0 64px 48px #fff3,inset 0 2px 4px #ffffff4d,inset 0 1px 1px #ffffff4d}.item-count{display:flex;align-items:center;gap:4px}.item-count-label{letter-spacing:.5px}.folder-icon{display:flex;align-items:center;justify-content:center}.folder-label-container{display:flex;flex-direction:column;align-items:center;gap:4px;width:100%;min-width:0}.folder-label{text-align:center;width:100%;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.loading-indicator,.error-indicator{font-size:var(--font-size-xs)}\n"] }]
28691
+ `, styles: [":host{display:inline-flex;flex-direction:column;align-items:center;gap:16px;width:100%;min-width:140px;cursor:pointer;-webkit-user-select:none;user-select:none;-webkit-tap-highlight-color:transparent;padding:16px;border-radius:16px;background:var(--color-background-neutral-secondary, #f0f0f0);transition:background .2s ease}:host:active{background:var(--color-background-neutral-secondary-hover, #ebebeb)}@media (hover: hover){:host:hover{background:var(--color-background-neutral-secondary-hover, #ebebeb)}}:host{--color-red-base: #dc3545;--color-red-strong: #ae1d3b;--color-green-base: #28a745;--color-green-strong: #058057;--color-yellow-base: #ffc107;--color-yellow-strong: #e4b200;--color-purple-base: #6f42c1;--color-purple-strong: #4204c5;--color-indigo-base: #6610f2;--color-indigo-strong: #a527a2;--color-lime-base: #82c91e;--color-lime-strong: #58a503;--color-teal-base: #20c997;--color-teal-strong: #0ca678;--color-cyan-base: #17a2b8;--color-cyan-strong: #1098ad;--color-brown-base: #795548;--color-brown-strong: #5c4033;--color-light-blue-base: #add8e6;--color-light-blue-strong: #87ceeb;--color-light-green-base: #90ee90;--color-light-green-strong: #32cd32;--color-coral-base: #f08080;--color-coral-strong: #cd5c5c;--color-salmon-base: #ffa07a;--color-salmon-strong: #fa8072;--color-seagreen-base: #20b2aa;--color-seagreen-strong: #2e8b57}.folder-container{position:relative;width:100%;display:flex;flex-direction:column;perspective:800px;-webkit-perspective:800px;max-width:160px;transform-style:preserve-3d;-webkit-transform-style:preserve-3d}.folder-container.open .page-sheet{-webkit-transform:translateY(-8px);transform:translateY(-8px);transition-delay:.2s}.folder-container.open .page-sheet:nth-child(1){-webkit-transform:scale(1) translateY(-8px) rotateX(-45deg) translateZ(.1px);transform:scale(1) translateY(-8px) rotateX(-45deg) translateZ(.1px)}.folder-container.open .page-sheet:nth-child(2){-webkit-transform:scale(.98) translateY(-12px) rotateX(-36deg) translateZ(.1px);transform:scale(.98) translateY(-12px) rotateX(-36deg) translateZ(.1px)}.folder-container.open .page-sheet:nth-child(3){-webkit-transform:scale(.96) translateY(-16px) rotateX(-27deg) translateZ(.1px);transform:scale(.96) translateY(-16px) rotateX(-27deg) translateZ(.1px)}.folder-container.open .page-sheet:nth-child(4){-webkit-transform:scale(.94) translateY(-20px) rotateX(-18deg) translateZ(.1px);transform:scale(.94) translateY(-20px) rotateX(-18deg) translateZ(.1px)}.folder-container.open .page-sheet:nth-child(5){-webkit-transform:scale(.92) translateY(-24px) rotateX(-9deg) translateZ(.1px);transform:scale(.92) translateY(-24px) rotateX(-9deg) translateZ(.1px)}.folder-container.open .page-sheet:nth-child(6){-webkit-transform:scale(.9) translateY(-28px) rotateX(0deg) translateZ(.1px);transform:scale(.9) translateY(-28px) rotateX(.1px)}.folder-container.open .folder-front{-webkit-transform:translate3d(0,0,0) rotateX(-45deg);transform:translateZ(0) rotateX(-45deg)}.folder-tab{width:50%;height:auto;display:block}.folder-back{height:128px;border-radius:0 12px 12px;position:relative;margin-top:-1px;transform-style:preserve-3d;-webkit-transform-style:preserve-3d;backface-visibility:hidden;-webkit-backface-visibility:hidden;-webkit-transform:translateZ(0);transform:translateZ(0)}.page-sheet{position:absolute;width:80%;height:120px;background:#fff;border-radius:8px;box-shadow:0 -1px 5px #0000001a;border:1px solid var(--border-color-default);transition:transform .3s ease-out;-webkit-transition:-webkit-transform .3s ease-out;left:10%;-webkit-transform:translateZ(0);transform:translateZ(0);transform-style:preserve-3d;-webkit-transform-style:preserve-3d;backface-visibility:hidden;-webkit-backface-visibility:hidden;-webkit-font-smoothing:antialiased;will-change:transform}.page-sheet:nth-child(1){bottom:2px;z-index:6;transform-origin:bottom center;-webkit-transform-origin:bottom center;-webkit-transform:scale(1) translateZ(.1px);transform:scale(1) translateZ(.1px)}.page-sheet:nth-child(2){bottom:8px;z-index:5;transform-origin:bottom center;-webkit-transform-origin:bottom center;-webkit-transform:scale(.98) translateZ(.1px);transform:scale(.98) translateZ(.1px)}.page-sheet:nth-child(3){bottom:14px;z-index:4;transform-origin:bottom center;-webkit-transform-origin:bottom center;-webkit-transform:scale(.96) translateZ(.1px);transform:scale(.96) translateZ(.1px)}.page-sheet:nth-child(4){bottom:20px;z-index:3;transform-origin:bottom center;-webkit-transform-origin:bottom center;-webkit-transform:scale(.94) translateZ(.1px);transform:scale(.94) translateZ(.1px)}.page-sheet:nth-child(5){bottom:26px;z-index:2;transform-origin:bottom center;-webkit-transform-origin:bottom center;-webkit-transform:scale(.92) translateZ(.1px);transform:scale(.92) translateZ(.1px)}.page-sheet:nth-child(6){bottom:32px;z-index:1;transform-origin:bottom center;-webkit-transform-origin:bottom center;-webkit-transform:scale(.9) translateZ(.1px);transform:scale(.9) translateZ(.1px)}.folder-front{position:absolute;bottom:0;left:0;right:0;height:116px;border-radius:12px;display:flex;align-items:center;justify-content:center;padding:8px;z-index:2;transform-origin:bottom center;-webkit-transform-origin:bottom center;transform-style:preserve-3d;-webkit-transform-style:preserve-3d;transition:transform .4s ease-in-out,-webkit-transform .4s ease-in-out;-webkit-transition:-webkit-transform .4s ease-in-out;will-change:transform;backface-visibility:hidden;-webkit-backface-visibility:hidden;-webkit-font-smoothing:antialiased;-webkit-transform:rotateX(-20deg) translateZ(.1px);transform:rotateX(-20deg) translateZ(.1px);-webkit-transform:translate3d(0,0,0) rotateX(-20deg);transform:translateZ(0) rotateX(-20deg);box-shadow:inset 0 64px 48px #fff3,inset 0 2px 4px #ffffff4d,inset 0 1px 1px #ffffff4d}.item-count{display:flex;align-items:center;gap:4px}.folder-icon{display:flex;align-items:center;justify-content:center}.folder-label-container{display:flex;flex-direction:column;align-items:center;gap:4px;width:100%;min-width:0}.folder-label{text-align:center;width:100%;min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.loading-indicator,.error-indicator{font-size:var(--font-size-xs)}\n"] }]
28564
28692
  }], ctorParameters: () => [{ type: DsMobileHandbookDetailModalService }], propDecorators: { variant: [{
28565
28693
  type: Input
28566
28694
  }], customColor: [{
@@ -28581,7 +28709,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
28581
28709
  type: Input
28582
28710
  }], textError: [{
28583
28711
  type: Input
28584
- }], textItems: [{
28712
+ }], textItemSingle: [{
28713
+ type: Input
28714
+ }], textItemsPlural: [{
28585
28715
  type: Input
28586
28716
  }], textClose: [{
28587
28717
  type: Input
@@ -28845,7 +28975,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
28845
28975
  * ```html
28846
28976
  * <ds-mobile-property-banner
28847
28977
  * address="Toftegårds Allé 5A, 2. tv."
28848
- * photoUrl="/Assets/building.jpg"
28978
+ * photoUrl="/assets/building.jpg"
28849
28979
  * [tenantCount]="12">
28850
28980
  * </ds-mobile-property-banner>
28851
28981
  * ```
@@ -29172,7 +29302,7 @@ const SAMPLE_NOTIFICATIONS = [
29172
29302
  // Today — Marcus Lindqvist sent message in conv-2
29173
29303
  { id: '3', type: 'message_new', leading: 'avatar', targetId: 'conv-2', avatarInitials: 'ML', title: 'Marcus Lindqvist', message: 'Kan du tjekke støjproblemet igen?', createdAt: minutesAgo(10), read: false },
29174
29304
  // Today — booking-1 "Festlokale på taget" confirmed
29175
- { id: '4', type: 'booking_confirmed', leading: 'image', targetId: 'booking-1', imageSrc: '/Assets/Dummy-photos/rooftop-party.jpg', title: 'Festlokale på taget', message: 'Din booking d. 14. feb kl. 9:00–17:00 er bekræftet.', createdAt: hoursAgo(2), read: true },
29305
+ { id: '4', type: 'booking_confirmed', leading: 'image', targetId: 'booking-1', imageSrc: '/assets/Dummy-photos/rooftop-party.jpg', title: 'Festlokale på taget', message: 'Din booking d. 14. feb kl. 9:00–17:00 er bekræftet.', createdAt: hoursAgo(2), read: true },
29176
29306
  // Today — Anders Jensen commented on post-2
29177
29307
  { id: '5', type: 'community_comment', leading: 'avatar', targetId: 'post-2', avatarInitials: 'AJ', title: 'Anders Jensen', message: 'Kommenterede: "Wow, den udsigt er fantastisk!"', createdAt: hoursAgo(3), read: true },
29178
29308
  // Yesterday — Blik Partner A/S assigned to inquiry #2
@@ -29180,9 +29310,9 @@ const SAMPLE_NOTIFICATIONS = [
29180
29310
  // Yesterday — Sophie Andersen posted in community (post-2)
29181
29311
  { id: '7', type: 'community_post', leading: 'avatar', targetId: 'post-2', avatarInitials: 'SA', title: 'Sophie Andersen', message: 'Nyt opslag med billeder fra ejendommen.', createdAt: daysAgo(1, 14, 20), read: true },
29182
29312
  // Yesterday — booking-3 "Boremaskinen" reminder
29183
- { id: '8', type: 'booking_reminder', leading: 'image', targetId: 'booking-3', imageSrc: '/Assets/Dummy-photos/handyman.jpg', title: 'Boremaskinen', message: 'Du har en booking d. 25. mar kl. 10:00–14:00.', createdAt: daysAgo(1, 9, 0), read: true },
29313
+ { id: '8', type: 'booking_reminder', leading: 'image', targetId: 'booking-3', imageSrc: '/assets/Dummy-photos/handyman.jpg', title: 'Boremaskinen', message: 'Du har en booking d. 25. mar kl. 10:00–14:00.', createdAt: daysAgo(1, 9, 0), read: true },
29184
29314
  // Yesterday — facility-1 "Boremaskinen" available
29185
- { id: '9', type: 'facility_available', leading: 'image', targetId: 'facility-1', imageSrc: '/Assets/Dummy-photos/handyman.jpg', title: 'Boremaskinen', message: 'Boremaskinen er nu ledig til booking.', createdAt: daysAgo(1, 8, 15), read: true },
29315
+ { id: '9', type: 'facility_available', leading: 'image', targetId: 'facility-1', imageSrc: '/assets/Dummy-photos/handyman.jpg', title: 'Boremaskinen', message: 'Boremaskinen er nu ledig til booking.', createdAt: daysAgo(1, 8, 15), read: true },
29186
29316
  // Yesterday — group "Vaskeri & møde" message
29187
29317
  { id: '10', type: 'message_group', leading: 'avatar', targetId: 'conv-group-demo', avatarInitials: 'VM', title: 'Vaskeri & møde', message: 'Anna Berg: "Vi mødes kl. 19 i fællesrummet."', createdAt: daysAgo(1, 19, 30), read: true },
29188
29318
  // Earlier — inquiry #3 resolved
@@ -29190,11 +29320,11 @@ const SAMPLE_NOTIFICATIONS = [
29190
29320
  // Earlier — handbook updated
29191
29321
  { id: '12', type: 'handbook_update', leading: 'logo', title: 'Håndbog opdateret', message: 'Afsnittet "Forsyninger" er blevet opdateret med ny information.', createdAt: daysAgo(4), read: true },
29192
29322
  // Earlier — ElektroTek ApS service update
29193
- { id: '13', type: 'service_update', leading: 'image', targetId: 'v-4', imageSrc: '/Assets/dummy-logos/electrician-logo.svg', title: 'ElektroTek ApS', message: 'El-service er nu tilgængelig via Services.', createdAt: daysAgo(5), read: true },
29323
+ { id: '13', type: 'service_update', leading: 'image', targetId: 'v-4', imageSrc: '/assets/dummy-logos/electrician-logo.svg', title: 'ElektroTek ApS', message: 'El-service er nu tilgængelig via Services.', createdAt: daysAgo(5), read: true },
29194
29324
  // Earlier — Thomas Hansen commented on post-2
29195
29325
  { id: '14', type: 'community_comment', leading: 'avatar', targetId: 'post-2', avatarInitials: 'TH', title: 'Thomas Hansen', message: 'Kommenterede: "Smuk! Jeg kan også se byens silhuet fra min lejlighed 🌆"', createdAt: daysAgo(6), read: true },
29196
29326
  // Earlier — booking-2 "Gæsteparkering" cancelled
29197
- { id: '15', type: 'booking_cancelled', leading: 'image', targetId: 'booking-2', imageSrc: '/Assets/Dummy-photos/parking.jpg', title: 'Gæsteparkering', message: 'Din booking d. 20. mar kl. 8:00–20:00 er blevet annulleret.', createdAt: daysAgo(7), read: true },
29327
+ { id: '15', type: 'booking_cancelled', leading: 'image', targetId: 'booking-2', imageSrc: '/assets/Dummy-photos/parking.jpg', title: 'Gæsteparkering', message: 'Din booking d. 20. mar kl. 8:00–20:00 er blevet annulleret.', createdAt: daysAgo(7), read: true },
29198
29328
  // Earlier — system announcement
29199
29329
  { id: '16', type: 'system_announcement', leading: 'logo', title: 'Systemmeddelelse', message: 'Planlagt vedligeholdelse d. 1. maj kl. 02:00–04:00.', createdAt: daysAgo(8), read: true },
29200
29330
  // Earlier — Karl Johansson message in conv-4
@@ -29538,7 +29668,7 @@ class DsMobileNotificationModalComponent {
29538
29668
  }
29539
29669
  } @else {
29540
29670
  <ds-mobile-empty-state
29541
- imageSrc="/Assets/empty-state-notification.svg"
29671
+ imageSrc="/assets/empty-state-notification.svg"
29542
29672
  imageAlt="Ingen notifikationer"
29543
29673
  title="Alt er stille herinde"
29544
29674
  description="Når der sker noget nyt, finder du det her."
@@ -29636,7 +29766,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
29636
29766
  }
29637
29767
  } @else {
29638
29768
  <ds-mobile-empty-state
29639
- imageSrc="/Assets/empty-state-notification.svg"
29769
+ imageSrc="/assets/empty-state-notification.svg"
29640
29770
  imageAlt="Ingen notifikationer"
29641
29771
  title="Alt er stille herinde"
29642
29772
  description="Når der sker noget nyt, finder du det her."
@@ -30563,7 +30693,7 @@ const BOOKING_DETAIL_MAP = {
30563
30693
  'booking-1': {
30564
30694
  id: 'booking-1',
30565
30695
  facilityTitle: 'Festlokale på taget',
30566
- heroImage: '/Assets/Dummy-photos/rooftop-party.jpg',
30696
+ heroImage: '/assets/Dummy-photos/rooftop-party.jpg',
30567
30697
  bookingDate: '14. februar',
30568
30698
  bookingTime: '9:00 - 17:00',
30569
30699
  price: '200 kr. per booking',
@@ -30572,7 +30702,7 @@ const BOOKING_DETAIL_MAP = {
30572
30702
  'booking-2': {
30573
30703
  id: 'booking-2',
30574
30704
  facilityTitle: 'Gæsteparkering',
30575
- heroImage: '/Assets/Dummy-photos/parking.jpg',
30705
+ heroImage: '/assets/Dummy-photos/parking.jpg',
30576
30706
  bookingDate: '20. marts',
30577
30707
  bookingTime: '8:00 - 20:00',
30578
30708
  price: '50 kr. per booking',
@@ -30581,7 +30711,7 @@ const BOOKING_DETAIL_MAP = {
30581
30711
  'booking-3': {
30582
30712
  id: 'booking-3',
30583
30713
  facilityTitle: 'Boremaskinen',
30584
- heroImage: '/Assets/Dummy-photos/handyman.jpg',
30714
+ heroImage: '/assets/Dummy-photos/handyman.jpg',
30585
30715
  bookingDate: '25. marts',
30586
30716
  bookingTime: '10:00 - 14:00',
30587
30717
  price: 'Gratis',
@@ -30592,31 +30722,31 @@ const VENDOR_DETAIL_MAP = {
30592
30722
  'v-1': {
30593
30723
  vendorName: 'CleanTeam ApS',
30594
30724
  vendorDescription: '<h3>Rengøring</h3><p>CleanTeam ApS tilbyder professionel trappevask og vinduespolering for ejendommen. Servicen udføres ugentligt og kan tilpasses jeres behov.</p><h3>Pris</h3><p>350 kr. per besøg</p>',
30595
- vendorImage: '/Assets/Dummy-photos/clean-team.jpg',
30596
- vendorLogo: '/Assets/dummy-logos/cleanteam-logo.svg',
30725
+ vendorImage: '/assets/Dummy-photos/clean-team.jpg',
30726
+ vendorLogo: '/assets/dummy-logos/cleanteam-logo.svg',
30597
30727
  },
30598
30728
  'v-2': {
30599
30729
  vendorName: 'Nordisk Rengøring',
30600
30730
  vendorDescription: '<h3>Rengøring</h3><p>Nordisk Rengøring leverer fleksibel erhvervs- og boligrengøring. Vi tilpasser rengøringen til jeres specifikke behov.</p><h3>Pris</h3><p>275 kr. per time</p>',
30601
- vendorImage: '/Assets/Dummy-photos/nordic-cleaning.jpg',
30602
- vendorLogo: '/Assets/dummy-logos/nordiccleaning-logo.svg',
30731
+ vendorImage: '/assets/Dummy-photos/nordic-cleaning.jpg',
30732
+ vendorLogo: '/assets/dummy-logos/nordiccleaning-logo.svg',
30603
30733
  },
30604
30734
  'v-3': {
30605
30735
  vendorName: 'Blik Partner A/S',
30606
30736
  vendorDescription: '<h3>VVS</h3><p>BlikPartner A/S er jeres VVS-partner til alt fra løbende vedligeholdelse til akutte udkald. Vi dækker reparation af vandrør, afløb, radiatorer og blandingsbatterier.</p><h3>Pris</h3><p>450 kr. per udkald + tid</p>',
30607
- vendorImage: '/Assets/Dummy-photos/plumbing.jpg',
30737
+ vendorImage: '/assets/Dummy-photos/plumbing.jpg',
30608
30738
  },
30609
30739
  'v-4': {
30610
30740
  vendorName: 'ElektroTek ApS',
30611
30741
  vendorDescription: '<h3>Elektriker</h3><p>ElektroTek ApS varetager el-installationer, fejlsøgning og lovpligtige eftersyn for ejendommen. Vi udfører også småopgaver som udskiftning af kontakter og lampeudtag.</p><h3>Pris</h3><p>395 kr. per time</p>',
30612
- vendorImage: '/Assets/Dummy-photos/electrician.jpg',
30613
- vendorLogo: '/Assets/dummy-logos/electrician-logo.svg',
30742
+ vendorImage: '/assets/Dummy-photos/electrician.jpg',
30743
+ vendorLogo: '/assets/dummy-logos/electrician-logo.svg',
30614
30744
  },
30615
30745
  'v-5': {
30616
30746
  vendorName: 'HaveService Danmark',
30617
30747
  vendorDescription: '<h3>Have & Grønne arealer</h3><p>HaveService Danmark står for den løbende pleje af fællesarealer og haver — herunder græsslåning, hækklipning, ukrudtsbekæmpelse og sæsonbeplantning.</p><h3>Pris</h3><p>500 kr. per besøg</p>',
30618
- vendorImage: '/Assets/Dummy-photos/gardener.jpg',
30619
- vendorLogo: '/Assets/dummy-logos/gardener-logo.svg',
30748
+ vendorImage: '/assets/Dummy-photos/gardener.jpg',
30749
+ vendorLogo: '/assets/dummy-logos/gardener-logo.svg',
30620
30750
  },
30621
30751
  };
30622
30752
  class DsMobileNotificationModalService extends BaseModalService {
@@ -31002,7 +31132,7 @@ class MobileCommunityPageComponent {
31002
31132
  await this.lightbox.openPdf({
31003
31133
  pdf: {
31004
31134
  type: 'pdf',
31005
- src: '/Assets/House_Rules.pdf', // Capital A to match public/Assets folder structure
31135
+ src: '/assets/House_Rules.pdf', // Capital A to match public/Assets folder structure
31006
31136
  title: 'House Rules',
31007
31137
  description: 'Building regulations and community guidelines',
31008
31138
  fileSize: 250880, // 245 KB in bytes
@@ -31248,10 +31378,10 @@ class MobileCommunityPageComponent {
31248
31378
  <post-text>{{ post.content }}</post-text>
31249
31379
  <ds-mobile-inline-photo
31250
31380
  [images]="[
31251
- '/Assets/Dummy-photos/balcony-view.jpg',
31252
- '/Assets/Dummy-photos/staircase.jpg',
31253
- '/Assets/Dummy-photos/park.jpg',
31254
- '/Assets/Dummy-photos/yard.jpg'
31381
+ '/assets/Dummy-photos/balcony-view.jpg',
31382
+ '/assets/Dummy-photos/staircase.jpg',
31383
+ '/assets/Dummy-photos/park.jpg',
31384
+ '/assets/Dummy-photos/yard.jpg'
31255
31385
  ]"
31256
31386
  [author]="{
31257
31387
  name: 'Sophie Andersen',
@@ -31287,12 +31417,12 @@ class MobileCommunityPageComponent {
31287
31417
  <post-text>{{ post.content }}</post-text>
31288
31418
  <ds-mobile-inline-photo
31289
31419
  [images]="[
31290
- '/Assets/Dummy-photos/mailboxes.jpg',
31291
- '/Assets/Dummy-photos/staircase.jpg',
31292
- '/Assets/Dummy-photos/yard.jpg',
31293
- '/Assets/Dummy-photos/park.jpg',
31294
- '/Assets/Dummy-photos/balcony-view.jpg',
31295
- '/Assets/Dummy-photos/handyman.jpg'
31420
+ '/assets/Dummy-photos/mailboxes.jpg',
31421
+ '/assets/Dummy-photos/staircase.jpg',
31422
+ '/assets/Dummy-photos/yard.jpg',
31423
+ '/assets/Dummy-photos/park.jpg',
31424
+ '/assets/Dummy-photos/balcony-view.jpg',
31425
+ '/assets/Dummy-photos/handyman.jpg'
31296
31426
  ]"
31297
31427
  [author]="{
31298
31428
  name: 'Karen Nielsen',
@@ -31353,7 +31483,7 @@ class MobileCommunityPageComponent {
31353
31483
  <!-- Empty State -->
31354
31484
  <div class="community-empty-state">
31355
31485
  <img
31356
- src="/Assets/Empty%20state-chat.png"
31486
+ src="/assets/Empty%20state-chat.png"
31357
31487
  alt="Ingen opslag endnu"
31358
31488
  class="empty-state-image"
31359
31489
  />
@@ -31531,10 +31661,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
31531
31661
  <post-text>{{ post.content }}</post-text>
31532
31662
  <ds-mobile-inline-photo
31533
31663
  [images]="[
31534
- '/Assets/Dummy-photos/balcony-view.jpg',
31535
- '/Assets/Dummy-photos/staircase.jpg',
31536
- '/Assets/Dummy-photos/park.jpg',
31537
- '/Assets/Dummy-photos/yard.jpg'
31664
+ '/assets/Dummy-photos/balcony-view.jpg',
31665
+ '/assets/Dummy-photos/staircase.jpg',
31666
+ '/assets/Dummy-photos/park.jpg',
31667
+ '/assets/Dummy-photos/yard.jpg'
31538
31668
  ]"
31539
31669
  [author]="{
31540
31670
  name: 'Sophie Andersen',
@@ -31570,12 +31700,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
31570
31700
  <post-text>{{ post.content }}</post-text>
31571
31701
  <ds-mobile-inline-photo
31572
31702
  [images]="[
31573
- '/Assets/Dummy-photos/mailboxes.jpg',
31574
- '/Assets/Dummy-photos/staircase.jpg',
31575
- '/Assets/Dummy-photos/yard.jpg',
31576
- '/Assets/Dummy-photos/park.jpg',
31577
- '/Assets/Dummy-photos/balcony-view.jpg',
31578
- '/Assets/Dummy-photos/handyman.jpg'
31703
+ '/assets/Dummy-photos/mailboxes.jpg',
31704
+ '/assets/Dummy-photos/staircase.jpg',
31705
+ '/assets/Dummy-photos/yard.jpg',
31706
+ '/assets/Dummy-photos/park.jpg',
31707
+ '/assets/Dummy-photos/balcony-view.jpg',
31708
+ '/assets/Dummy-photos/handyman.jpg'
31579
31709
  ]"
31580
31710
  [author]="{
31581
31711
  name: 'Karen Nielsen',
@@ -31636,7 +31766,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
31636
31766
  <!-- Empty State -->
31637
31767
  <div class="community-empty-state">
31638
31768
  <img
31639
- src="/Assets/Empty%20state-chat.png"
31769
+ src="/assets/Empty%20state-chat.png"
31640
31770
  alt="Ingen opslag endnu"
31641
31771
  class="empty-state-image"
31642
31772
  />
@@ -31750,7 +31880,7 @@ class MobileHandbookPageComponent {
31750
31880
  {
31751
31881
  title: 'Fælles områder og sikkerhed',
31752
31882
  description: 'Trappeopgange med nødbelysning og brandsikre døre. Postkasser placeret i indgangspartiet. Hold altid flugtveje fri.',
31753
- images: ['/Assets/Dummy-photos/staircase.jpg', '/Assets/Dummy-photos/mailboxes.jpg'],
31883
+ images: ['/assets/Dummy-photos/staircase.jpg', '/assets/Dummy-photos/mailboxes.jpg'],
31754
31884
  },
31755
31885
  {
31756
31886
  title: 'Hjertestarter (AED)',
@@ -31813,7 +31943,7 @@ class MobileHandbookPageComponent {
31813
31943
  {
31814
31944
  title: 'Udendørs arealer',
31815
31945
  description: 'Fælles grønne områder med bede, siddepladser og terrasse. Beboere må frit benytte området. Respektér planterne og hold området pænt.',
31816
- images: ['/Assets/Dummy-photos/park.jpg', '/Assets/Dummy-photos/yard.jpg'],
31946
+ images: ['/assets/Dummy-photos/park.jpg', '/assets/Dummy-photos/yard.jpg'],
31817
31947
  },
31818
31948
  {
31819
31949
  title: 'Havevedligeholdelse',
@@ -31868,7 +31998,7 @@ class MobileHandbookPageComponent {
31868
31998
  {
31869
31999
  title: 'Balkon udsigt',
31870
32000
  description: 'Eksempel på udsigt fra øverste etagers balkoner. Flere lejligheder har privat altan med fantastisk udsyn.',
31871
- images: ['/Assets/Dummy-photos/balcony-view.jpg'],
32001
+ images: ['/assets/Dummy-photos/balcony-view.jpg'],
31872
32002
  },
31873
32003
  {
31874
32004
  title: 'Vaskerum',
@@ -31892,7 +32022,7 @@ class MobileHandbookPageComponent {
31892
32022
  {
31893
32023
  title: 'Vedligeholdelse og reparationer',
31894
32024
  description: 'Ved behov for reparationer eller vedligeholdelse i din lejlighed, kontakt vores hausmeister. Akutte problemer håndteres samme dag.',
31895
- images: ['/Assets/Dummy-photos/handyman.jpg'],
32025
+ images: ['/assets/Dummy-photos/handyman.jpg'],
31896
32026
  contacts: [
31897
32027
  {
31898
32028
  name: 'Hausmeister Service',
@@ -31955,7 +32085,7 @@ class MobileHandbookPageComponent {
31955
32085
  </div>
31956
32086
  </ds-mobile-section>
31957
32087
  </ds-mobile-page-main>
31958
- `, isInline: true, styles: [".folders-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:20px;justify-items:center}@media (min-width: 768px){.folders-grid{grid-template-columns:repeat(3,1fr)}}ds-mobile-handbook-folder{width:100%;min-width:0}\n"], dependencies: [{ kind: "component", type: DsMobilePageMainComponent, selector: "ds-mobile-page-main", inputs: ["title", "headerTitle", "headerSubtitle", "firstEntry", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "showNotification", "notificationCount", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["notificationClick", "avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileHandbookFolderComponent, selector: "ds-mobile-handbook-folder", inputs: ["variant", "customColor", "iconName", "itemCount", "label", "items", "loading", "error", "textLoading", "textError", "textItems", "textClose", "textEmptyTitle", "textEmptyDescription", "textCall", "textCopyPhone", "textEmail", "textCopyEmail"] }, { kind: "component", type: DsMobileOfflineBannerComponent, selector: "ds-mobile-offline-banner", inputs: ["icon", "title", "message"] }] });
32088
+ `, isInline: true, styles: [".folders-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:20px;justify-items:center}@media (min-width: 768px){.folders-grid{grid-template-columns:repeat(3,1fr)}}ds-mobile-handbook-folder{width:100%;min-width:0}\n"], dependencies: [{ kind: "component", type: DsMobilePageMainComponent, selector: "ds-mobile-page-main", inputs: ["title", "headerTitle", "headerSubtitle", "firstEntry", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "showNotification", "notificationCount", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["notificationClick", "avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileHandbookFolderComponent, selector: "ds-mobile-handbook-folder", inputs: ["variant", "customColor", "iconName", "itemCount", "label", "items", "loading", "error", "textLoading", "textError", "textItemSingle", "textItemsPlural", "textClose", "textEmptyTitle", "textEmptyDescription", "textCall", "textCopyPhone", "textEmail", "textCopyEmail"] }, { kind: "component", type: DsMobileOfflineBannerComponent, selector: "ds-mobile-offline-banner", inputs: ["icon", "title", "message"] }] });
31959
32089
  }
31960
32090
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MobileHandbookPageComponent, decorators: [{
31961
32091
  type: Component,
@@ -32551,8 +32681,8 @@ class MobileHomePageComponent {
32551
32681
  category: 'Rengøring',
32552
32682
  description: 'Trappevask og vinduespolering',
32553
32683
  phone: '+45 70 20 30 40',
32554
- logo: '/Assets/dummy-logos/cleanteam-logo.svg',
32555
- thumbnail: '/Assets/Dummy-photos/clean-team.jpg',
32684
+ logo: '/assets/dummy-logos/cleanteam-logo.svg',
32685
+ thumbnail: '/assets/Dummy-photos/clean-team.jpg',
32556
32686
  fullDescription: '<h3>Rengøring</h3><p>CleanTeam ApS tilbyder professionel trappevask og vinduespolering for ejendommen. Servicen udføres ugentligt og kan tilpasses jeres behov.</p><h3>Pris</h3><p>350 kr. per besøg</p>',
32557
32687
  },
32558
32688
  {
@@ -32561,7 +32691,7 @@ class MobileHomePageComponent {
32561
32691
  category: 'VVS',
32562
32692
  description: 'VVS-service og akut udkald',
32563
32693
  phone: '+45 33 44 55 66',
32564
- thumbnail: '/Assets/Dummy-photos/plumbing.jpg',
32694
+ thumbnail: '/assets/Dummy-photos/plumbing.jpg',
32565
32695
  fullDescription: '<h3>VVS</h3><p>BlikPartner A/S er jeres VVS-partner til alt fra løbende vedligeholdelse til akutte udkald. Vi dækker reparation af vandrør, afløb, radiatorer og blandingsbatterier.</p><h3>Pris</h3><p>450 kr. per udkald + tid</p>',
32566
32696
  },
32567
32697
  {
@@ -32570,9 +32700,9 @@ class MobileHomePageComponent {
32570
32700
  category: 'Elektriker',
32571
32701
  description: 'El-installationer og fejlsøgning',
32572
32702
  phone: '+45 23 45 67 89',
32573
- logo: '/Assets/dummy-logos/electrician-logo.svg',
32574
- thumbnail: '/Assets/Dummy-photos/electrician.jpg',
32575
- heroImage: '/Assets/Dummy-photos/electrician.jpg',
32703
+ logo: '/assets/dummy-logos/electrician-logo.svg',
32704
+ thumbnail: '/assets/Dummy-photos/electrician.jpg',
32705
+ heroImage: '/assets/Dummy-photos/electrician.jpg',
32576
32706
  fullDescription: '<h3>Elektriker</h3><p>ElektroTek ApS varetager el-installationer, fejlsøgning og lovpligtige eftersyn for ejendommen. Vi udfører også småopgaver som udskiftning af kontakter og lampeudtag.</p><h3>Pris</h3><p>395 kr. per time</p>',
32577
32707
  },
32578
32708
  ], ...(ngDevMode ? [{ debugName: "allVendors" }] : []));
@@ -32781,7 +32911,7 @@ class MobileHomePageComponent {
32781
32911
  (keydown.space)="$event.preventDefault(); navigateToTenants()"
32782
32912
  aria-label="Se beboere på ejendommen"
32783
32913
  >
32784
- <ds-mobile-property-banner address="Toftegårds Allé 5A, 2. tv." photoUrl="/Assets/Dummy-photos/building.jpg" [tenantCount]="24"> </ds-mobile-property-banner>
32914
+ <ds-mobile-property-banner address="Toftegårds Allé 5A, 2. tv." photoUrl="/assets/Dummy-photos/building.jpg" [tenantCount]="24"> </ds-mobile-property-banner>
32785
32915
  </div>
32786
32916
 
32787
32917
  @if (familyAccessService.acceptedInviteContext(); as invite) {
@@ -32993,7 +33123,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
32993
33123
  (keydown.space)="$event.preventDefault(); navigateToTenants()"
32994
33124
  aria-label="Se beboere på ejendommen"
32995
33125
  >
32996
- <ds-mobile-property-banner address="Toftegårds Allé 5A, 2. tv." photoUrl="/Assets/Dummy-photos/building.jpg" [tenantCount]="24"> </ds-mobile-property-banner>
33126
+ <ds-mobile-property-banner address="Toftegårds Allé 5A, 2. tv." photoUrl="/assets/Dummy-photos/building.jpg" [tenantCount]="24"> </ds-mobile-property-banner>
32997
33127
  </div>
32998
33128
 
32999
33129
  @if (familyAccessService.acceptedInviteContext(); as invite) {
@@ -33451,11 +33581,11 @@ class MobileInquiryDetailPageComponent {
33451
33581
  }
33452
33582
  }
33453
33583
  photos = [
33454
- { type: 'image', src: '/Assets/Dummy-photos/handyman.jpg', alt: 'Handyman', title: 'Handyman' },
33455
- { type: 'image', src: '/Assets/Dummy-photos/balcony-view.jpg', alt: 'Balcony view', title: 'Balcony view' },
33456
- { type: 'image', src: '/Assets/Dummy-photos/staircase.jpg', alt: 'Staircase', title: 'Staircase' },
33457
- { type: 'image', src: '/Assets/Dummy-photos/yard.jpg', alt: 'Yard', title: 'Yard' },
33458
- { type: 'image', src: '/Assets/Dummy-photos/mailboxes.jpg', alt: 'Mailboxes', title: 'Mailboxes' }
33584
+ { type: 'image', src: '/assets/Dummy-photos/handyman.jpg', alt: 'Handyman', title: 'Handyman' },
33585
+ { type: 'image', src: '/assets/Dummy-photos/balcony-view.jpg', alt: 'Balcony view', title: 'Balcony view' },
33586
+ { type: 'image', src: '/assets/Dummy-photos/staircase.jpg', alt: 'Staircase', title: 'Staircase' },
33587
+ { type: 'image', src: '/assets/Dummy-photos/yard.jpg', alt: 'Yard', title: 'Yard' },
33588
+ { type: 'image', src: '/assets/Dummy-photos/mailboxes.jpg', alt: 'Mailboxes', title: 'Mailboxes' }
33459
33589
  ];
33460
33590
  get photoUrls() {
33461
33591
  return this.photos.map(photo => photo.src);
@@ -33755,7 +33885,7 @@ class MobileInquiryDetailPageComponent {
33755
33885
  } @else {
33756
33886
  <ds-mobile-section>
33757
33887
  <div class="empty-messages">
33758
- <img class="empty-messages-image" src="/Assets/Empty state-chat.png" alt="Ingen beskeder" />
33888
+ <img class="empty-messages-image" src="/assets/Empty state-chat.png" alt="Ingen beskeder" />
33759
33889
  <p class="empty-messages-text">Ingen beskeder endnu</p>
33760
33890
  </div>
33761
33891
  </ds-mobile-section>
@@ -33911,7 +34041,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
33911
34041
  } @else {
33912
34042
  <ds-mobile-section>
33913
34043
  <div class="empty-messages">
33914
- <img class="empty-messages-image" src="/Assets/Empty state-chat.png" alt="Ingen beskeder" />
34044
+ <img class="empty-messages-image" src="/assets/Empty state-chat.png" alt="Ingen beskeder" />
33915
34045
  <p class="empty-messages-text">Ingen beskeder endnu</p>
33916
34046
  </div>
33917
34047
  </ds-mobile-section>
@@ -34168,8 +34298,8 @@ class WhitelabelDemoModalComponent {
34168
34298
  applyDefaultTheme() {
34169
34299
  this.currentTheme = 'default';
34170
34300
  this.whitelabelService.updateConfig({
34171
- logoUrl: '/Assets/logos/propbinder-logomark.svg',
34172
- logoMarkUrl: '/Assets/logos/propbinder-logomark.svg',
34301
+ logoUrl: '/assets/logos/propbinder-logomark.svg',
34302
+ logoMarkUrl: '/assets/logos/propbinder-logomark.svg',
34173
34303
  logoAlt: 'Propbinder',
34174
34304
  logoSize: 'md',
34175
34305
  appIconSurface: '#6B5FF5',
@@ -34196,8 +34326,8 @@ class WhitelabelDemoModalComponent {
34196
34326
  applyCejTheme() {
34197
34327
  this.currentTheme = 'cej';
34198
34328
  this.whitelabelService.updateConfig({
34199
- logoUrl: '/Assets/logos/cej-logo.png',
34200
- logoMarkUrl: '/Assets/logos/cej-logo.png',
34329
+ logoUrl: '/assets/logos/cej-logo.png',
34330
+ logoMarkUrl: '/assets/logos/cej-logo.png',
34201
34331
  logoAlt: 'CEJ',
34202
34332
  logoSize: 'xl',
34203
34333
  appIconSurface: '#A70923',
@@ -34224,8 +34354,8 @@ class WhitelabelDemoModalComponent {
34224
34354
  applyPkaTheme() {
34225
34355
  this.currentTheme = 'pka';
34226
34356
  this.whitelabelService.updateConfig({
34227
- logoUrl: '/Assets/logos/pka-logo.svg',
34228
- logoMarkUrl: '/Assets/logos/pka-logo.svg',
34357
+ logoUrl: '/assets/logos/pka-logo.svg',
34358
+ logoMarkUrl: '/assets/logos/pka-logo.svg',
34229
34359
  logoAlt: 'PKA',
34230
34360
  logoSize: 'md',
34231
34361
  appIconSurface: '#CC006C',
@@ -34252,8 +34382,8 @@ class WhitelabelDemoModalComponent {
34252
34382
  applyClaveTheme() {
34253
34383
  this.currentTheme = 'clave';
34254
34384
  this.whitelabelService.updateConfig({
34255
- logoUrl: '/Assets/logos/clave-logo.svg',
34256
- logoMarkUrl: '/Assets/logos/clave-logo.svg',
34385
+ logoUrl: '/assets/logos/clave-logo.svg',
34386
+ logoMarkUrl: '/assets/logos/clave-logo.svg',
34257
34387
  logoAlt: 'Clave',
34258
34388
  logoSize: 'lg',
34259
34389
  appIconSurface: '#262424',
@@ -34280,8 +34410,8 @@ class WhitelabelDemoModalComponent {
34280
34410
  applyFreedomTheme() {
34281
34411
  this.currentTheme = 'freedom';
34282
34412
  this.whitelabelService.updateConfig({
34283
- logoUrl: '/Assets/logos/freedom-logo.svg',
34284
- logoMarkUrl: '/Assets/logos/freedom-logomark.svg',
34413
+ logoUrl: '/assets/logos/freedom-logo.svg',
34414
+ logoMarkUrl: '/assets/logos/freedom-logomark.svg',
34285
34415
  logoAlt: 'Freedom',
34286
34416
  logoSize: 'md',
34287
34417
  appIconSurface: '#1D4A49',
@@ -34308,8 +34438,8 @@ class WhitelabelDemoModalComponent {
34308
34438
  applyCobblestoneTheme() {
34309
34439
  this.currentTheme = 'cobblestone';
34310
34440
  this.whitelabelService.updateConfig({
34311
- logoUrl: '/Assets/logos/cobblestone-logo.svg',
34312
- logoMarkUrl: '/Assets/logos/cobblestone-logomark.svg',
34441
+ logoUrl: '/assets/logos/cobblestone-logo.svg',
34442
+ logoMarkUrl: '/assets/logos/cobblestone-logomark.svg',
34313
34443
  logoAlt: 'Cobblestone',
34314
34444
  logoSize: 'sm',
34315
34445
  appIconSurface: '#2C3E50',
@@ -35681,12 +35811,12 @@ class MobileBookingPageComponent {
35681
35811
  activeBookings = signal([
35682
35812
  {
35683
35813
  id: 'booking-1',
35684
- thumbnail: '/Assets/Dummy-photos/rooftop-party.jpg',
35814
+ thumbnail: '/assets/Dummy-photos/rooftop-party.jpg',
35685
35815
  facilityTitle: 'Festlokale på taget',
35686
35816
  bookingDate: '14. februar, 2026',
35687
35817
  bookingTime: '9:00 - 17:00',
35688
35818
  price: '200 kr. per booking',
35689
- heroImage: '/Assets/Dummy-photos/rooftop-party.jpg',
35819
+ heroImage: '/assets/Dummy-photos/rooftop-party.jpg',
35690
35820
  fullDescription: '<p>Festlokalet på taget giver jer et lyst og indbydende rum med flot udsigt over byen. Lokalet er velegnet til fødselsdage, mindre sammenkomster og hyggelige middage med naboer og venner.</p>',
35691
35821
  requirements: ['Kræver nøglekort'],
35692
35822
  bookingType: 'Øjeblikkelig booking',
@@ -35699,12 +35829,12 @@ class MobileBookingPageComponent {
35699
35829
  },
35700
35830
  {
35701
35831
  id: 'booking-2',
35702
- thumbnail: '/Assets/Dummy-photos/parking.jpg',
35832
+ thumbnail: '/assets/Dummy-photos/parking.jpg',
35703
35833
  facilityTitle: 'Gæsteparkering',
35704
35834
  bookingDate: '20. marts, 2026',
35705
35835
  bookingTime: '8:00 - 20:00',
35706
35836
  price: '50 kr. per booking',
35707
- heroImage: '/Assets/Dummy-photos/parking.jpg',
35837
+ heroImage: '/assets/Dummy-photos/parking.jpg',
35708
35838
  fullDescription: '<p>Ekstra gæsteparkeringspladser er tilgængelige for beboere, der har brug for parkering til besøgende.</p>',
35709
35839
  requirements: ['Kræver nøglekort'],
35710
35840
  bookingType: 'Forudgående booking påkrævet',
@@ -35715,12 +35845,12 @@ class MobileBookingPageComponent {
35715
35845
  },
35716
35846
  {
35717
35847
  id: 'booking-3',
35718
- thumbnail: '/Assets/Dummy-photos/handyman.jpg',
35848
+ thumbnail: '/assets/Dummy-photos/handyman.jpg',
35719
35849
  facilityTitle: 'Boremaskinen',
35720
35850
  bookingDate: '25. marts, 2026',
35721
35851
  bookingTime: '10:00 - 14:00',
35722
35852
  price: 'Gratis',
35723
- heroImage: '/Assets/Dummy-photos/handyman.jpg',
35853
+ heroImage: '/assets/Dummy-photos/handyman.jpg',
35724
35854
  fullDescription: '<p>Vores boremaskine i professionel kvalitet er tilgængelig for alle beboere til mindre forbedringer i hjemmet.</p>',
35725
35855
  requirements: ['Kræver nøglekort'],
35726
35856
  bookingType: 'Øjeblikkelig booking',
@@ -35734,14 +35864,14 @@ class MobileBookingPageComponent {
35734
35864
  availableFacilities = signal([
35735
35865
  {
35736
35866
  id: 'facility-1',
35737
- thumbnail: '/Assets/Dummy-photos/handyman.jpg',
35867
+ thumbnail: '/assets/Dummy-photos/handyman.jpg',
35738
35868
  facilityTitle: 'Boremaskinen',
35739
35869
  availabilityStatus: 'available-today',
35740
35870
  statusLabel: 'Ledig i dag',
35741
35871
  whenCanBook: 'Lørdag, søndag, 09:00 til 17:30, Op til 48 timer',
35742
35872
  price: 'Gratis',
35743
35873
  capacity: '2–5 personer',
35744
- heroImage: '/Assets/Dummy-photos/handyman.jpg',
35874
+ heroImage: '/assets/Dummy-photos/handyman.jpg',
35745
35875
  fullDescription: `
35746
35876
  <p>Vores boremaskine i professionel kvalitet er tilgængelig for alle beboere til mindre forbedringer i hjemmet. Den er ideel til ophængning af hylder, montering af beslag og andre boreopgaver i lejligheden.</p>
35747
35877
 
@@ -35763,14 +35893,14 @@ class MobileBookingPageComponent {
35763
35893
  },
35764
35894
  {
35765
35895
  id: 'facility-2',
35766
- thumbnail: '/Assets/Dummy-photos/rooftop-party.jpg',
35896
+ thumbnail: '/assets/Dummy-photos/rooftop-party.jpg',
35767
35897
  facilityTitle: 'Festlokale på taget',
35768
35898
  availabilityStatus: 'available-today',
35769
35899
  statusLabel: 'Ledig i dag',
35770
35900
  whenCanBook: 'Fredag–søndag, 10:00 til 22:00, Op til 3 timer',
35771
35901
  price: '200 kr. per booking',
35772
35902
  capacity: '6–15 personer',
35773
- heroImage: '/Assets/Dummy-photos/rooftop-party.jpg',
35903
+ heroImage: '/assets/Dummy-photos/rooftop-party.jpg',
35774
35904
  fullDescription: `
35775
35905
  <p>Tagterrassen er indrettet som et afslappende fristed og et levende samlingspunkt for beboerne med flot udsigt over byen. Uanset om du planlægger en mindre sammenkomst, en rolig aften udendørs eller en hyggelig stund med venner, giver terrassen de perfekte rammer.</p>
35776
35906
 
@@ -35810,14 +35940,14 @@ class MobileBookingPageComponent {
35810
35940
  },
35811
35941
  {
35812
35942
  id: 'facility-3',
35813
- thumbnail: '/Assets/Dummy-photos/parking.jpg',
35943
+ thumbnail: '/assets/Dummy-photos/parking.jpg',
35814
35944
  facilityTitle: 'Gæsteparkering',
35815
35945
  availabilityStatus: 'available-from',
35816
35946
  statusLabel: 'Ledig fra 28. februar, 2026',
35817
35947
  whenCanBook: 'Alle dage, 08:00 til 20:00, Op til 12 timer',
35818
35948
  price: '50 kr. per booking',
35819
35949
  capacity: '1 person',
35820
- heroImage: '/Assets/Dummy-photos/parking.jpg',
35950
+ heroImage: '/assets/Dummy-photos/parking.jpg',
35821
35951
  fullDescription: `
35822
35952
  <p>Ekstra gæsteparkeringspladser er tilgængelige for beboere, der har brug for parkering til besøgende. Pladserne giver dine gæster en nem og tryg parkeringsmulighed tæt på boligen.</p>
35823
35953
 
@@ -35839,14 +35969,14 @@ class MobileBookingPageComponent {
35839
35969
  },
35840
35970
  {
35841
35971
  id: 'facility-4',
35842
- thumbnail: '/Assets/Dummy-photos/yard.jpg',
35972
+ thumbnail: '/assets/Dummy-photos/yard.jpg',
35843
35973
  facilityTitle: 'BBQ område',
35844
35974
  availabilityStatus: 'unavailable',
35845
35975
  statusLabel: 'Ikke tilgængelig',
35846
35976
  whenCanBook: 'Maj–september, 12:00 til 22:00, Op til 4 timer',
35847
35977
  price: 'Gratis',
35848
35978
  capacity: '16–30 personer',
35849
- heroImage: '/Assets/Dummy-photos/yard.jpg',
35979
+ heroImage: '/assets/Dummy-photos/yard.jpg',
35850
35980
  fullDescription: `
35851
35981
  <p>BBQ-området har grill i professionel kvalitet og udendørs siddepladser, perfekt til sommerarrangementer og fællesspisning. Området er velegnet til både mindre familiemåltider og større sociale arrangementer.</p>
35852
35982
 
@@ -36078,7 +36208,7 @@ class MobileBookingPageComponent {
36078
36208
  onSubmit: async (data) => {
36079
36209
  const id = `facility-${Date.now()}`;
36080
36210
  const hero = data.attachments.find((a) => a.type === 'image')?.src;
36081
- const thumb = hero ?? '/Assets/Dummy-photos/handyman.jpg';
36211
+ const thumb = hero ?? '/assets/Dummy-photos/handyman.jpg';
36082
36212
  const row = {
36083
36213
  id,
36084
36214
  thumbnail: thumb,
@@ -36742,10 +36872,10 @@ class MobilePostDetailPageComponent {
36742
36872
  <post-text>Se denne smukke udsigt fra min altan! Morgenkaffe har aldrig smagt så godt ☕️</post-text>
36743
36873
  <post-media>
36744
36874
  <img
36745
- src="/Assets/Dummy-photos/balcony-view.jpg"
36875
+ src="/assets/Dummy-photos/balcony-view.jpg"
36746
36876
  alt="Altanudsigt"
36747
36877
  class="clickable-image"
36748
- (click)="openImageLightbox('/Assets/Dummy-photos/balcony-view.jpg', 'Altanudsigt', 'Morgenkaffe har aldrig smagt så godt ☕️')"
36878
+ (click)="openImageLightbox('/assets/Dummy-photos/balcony-view.jpg', 'Altanudsigt', 'Morgenkaffe har aldrig smagt så godt ☕️')"
36749
36879
  />
36750
36880
  </post-media>
36751
36881
  </post-content>
@@ -36883,10 +37013,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
36883
37013
  <post-text>Se denne smukke udsigt fra min altan! Morgenkaffe har aldrig smagt så godt ☕️</post-text>
36884
37014
  <post-media>
36885
37015
  <img
36886
- src="/Assets/Dummy-photos/balcony-view.jpg"
37016
+ src="/assets/Dummy-photos/balcony-view.jpg"
36887
37017
  alt="Altanudsigt"
36888
37018
  class="clickable-image"
36889
- (click)="openImageLightbox('/Assets/Dummy-photos/balcony-view.jpg', 'Altanudsigt', 'Morgenkaffe har aldrig smagt så godt ☕️')"
37019
+ (click)="openImageLightbox('/assets/Dummy-photos/balcony-view.jpg', 'Altanudsigt', 'Morgenkaffe har aldrig smagt så godt ☕️')"
36890
37020
  />
36891
37021
  </post-media>
36892
37022
  </post-content>
@@ -37125,7 +37255,7 @@ class SignInPageComponent {
37125
37255
  <!-- City background decoration -->
37126
37256
  @if (whitelabelService.showCityIllustration()) {
37127
37257
  <div class="tw-absolute tw-bottom-0 tw-left-0 tw-right-0 tw-w-full tw-h-[35%] tw-z-0 tw-pointer-events-none tw-overflow-hidden md:tw-h-[50%] md:tw-min-h-[400px]" aria-hidden="true">
37128
- <img src="/Assets/city.svg" alt="" class="tw-w-full tw-h-full tw-object-cover tw-object-top" />
37258
+ <img src="/assets/city.svg" alt="" class="tw-w-full tw-h-full tw-object-cover tw-object-top" />
37129
37259
  </div>
37130
37260
  }
37131
37261
 
@@ -37220,7 +37350,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
37220
37350
  <!-- City background decoration -->
37221
37351
  @if (whitelabelService.showCityIllustration()) {
37222
37352
  <div class="tw-absolute tw-bottom-0 tw-left-0 tw-right-0 tw-w-full tw-h-[35%] tw-z-0 tw-pointer-events-none tw-overflow-hidden md:tw-h-[50%] md:tw-min-h-[400px]" aria-hidden="true">
37223
- <img src="/Assets/city.svg" alt="" class="tw-w-full tw-h-full tw-object-cover tw-object-top" />
37353
+ <img src="/assets/city.svg" alt="" class="tw-w-full tw-h-full tw-object-cover tw-object-top" />
37224
37354
  </div>
37225
37355
  }
37226
37356
 
@@ -38227,7 +38357,7 @@ class TenantChatPageComponent {
38227
38357
  @if (peerMessaging.conversations().length === 0) {
38228
38358
  <div class="empty-state">
38229
38359
  <img
38230
- src="/Assets/Empty%20state-chat.png"
38360
+ src="/assets/Empty%20state-chat.png"
38231
38361
  alt="Ingen beskeder"
38232
38362
  class="empty-state-image"
38233
38363
  />
@@ -38303,7 +38433,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
38303
38433
  @if (peerMessaging.conversations().length === 0) {
38304
38434
  <div class="empty-state">
38305
38435
  <img
38306
- src="/Assets/Empty%20state-chat.png"
38436
+ src="/assets/Empty%20state-chat.png"
38307
38437
  alt="Ingen beskeder"
38308
38438
  class="empty-state-image"
38309
38439
  />
@@ -38375,8 +38505,8 @@ const MOCK_VENDORS = [
38375
38505
  category: 'Rengøring',
38376
38506
  description: 'Trappevask og vinduespolering',
38377
38507
  phone: '+45 70 20 30 40',
38378
- logo: '/Assets/dummy-logos/cleanteam-logo.svg',
38379
- thumbnail: '/Assets/Dummy-photos/clean-team.jpg',
38508
+ logo: '/assets/dummy-logos/cleanteam-logo.svg',
38509
+ thumbnail: '/assets/Dummy-photos/clean-team.jpg',
38380
38510
  fullDescription: '<h3>Rengøring</h3><p>CleanTeam ApS tilbyder professionel trappevask og vinduespolering for ejendommen. Servicen udføres ugentligt og kan tilpasses jeres behov.</p><h3>Pris</h3><p>350 kr. per besøg</p>',
38381
38511
  price: '350 kr. per besøg',
38382
38512
  availabilityStatus: 'available-today',
@@ -38387,9 +38517,9 @@ const MOCK_VENDORS = [
38387
38517
  name: 'Nordisk Rengøring',
38388
38518
  category: 'Rengøring',
38389
38519
  description: 'Erhvervs- og boligrengøring',
38390
- logo: '/Assets/dummy-logos/nordiccleaning-logo.svg',
38391
- thumbnail: '/Assets/Dummy-photos/nordic-cleaning.jpg',
38392
- heroImage: '/Assets/Dummy-photos/nordic-cleaning.jpg',
38520
+ logo: '/assets/dummy-logos/nordiccleaning-logo.svg',
38521
+ thumbnail: '/assets/Dummy-photos/nordic-cleaning.jpg',
38522
+ heroImage: '/assets/Dummy-photos/nordic-cleaning.jpg',
38393
38523
  fullDescription: '<h3>Rengøring</h3><p>Nordisk Rengøring leverer fleksibel erhvervs- og boligrengøring. Vi tilpasser rengøringen til jeres specifikke behov.</p><h3>Pris</h3><p>275 kr. per time</p>',
38394
38524
  price: '275 kr. per time',
38395
38525
  availabilityStatus: 'available-from',
@@ -38401,7 +38531,7 @@ const MOCK_VENDORS = [
38401
38531
  category: 'VVS',
38402
38532
  description: 'VVS-service og akut udkald',
38403
38533
  phone: '+45 33 44 55 66',
38404
- thumbnail: '/Assets/Dummy-photos/plumbing.jpg',
38534
+ thumbnail: '/assets/Dummy-photos/plumbing.jpg',
38405
38535
  fullDescription: '<h3>VVS</h3><p>BlikPartner A/S er jeres VVS-partner til alt fra løbende vedligeholdelse til akutte udkald. Vi dækker reparation af vandrør, afløb, radiatorer og blandingsbatterier.</p><h3>Pris</h3><p>450 kr. per udkald + tid</p>',
38406
38536
  price: '450 kr. per udkald + tid',
38407
38537
  availabilityStatus: 'available-today',
@@ -38413,9 +38543,9 @@ const MOCK_VENDORS = [
38413
38543
  category: 'Elektriker',
38414
38544
  description: 'El-installationer og fejlsøgning',
38415
38545
  phone: '+45 23 45 67 89',
38416
- logo: '/Assets/dummy-logos/electrician-logo.svg',
38417
- thumbnail: '/Assets/Dummy-photos/electrician.jpg',
38418
- heroImage: '/Assets/Dummy-photos/electrician.jpg',
38546
+ logo: '/assets/dummy-logos/electrician-logo.svg',
38547
+ thumbnail: '/assets/Dummy-photos/electrician.jpg',
38548
+ heroImage: '/assets/Dummy-photos/electrician.jpg',
38419
38549
  fullDescription: '<h3>Elektriker</h3><p>ElektroTek ApS varetager el-installationer, fejlsøgning og lovpligtige eftersyn for ejendommen. Vi udfører også småopgaver som udskiftning af kontakter og lampeudtag.</p><h3>Pris</h3><p>395 kr. per time</p>',
38420
38550
  price: '395 kr. per time',
38421
38551
  availabilityStatus: 'available-today',
@@ -38426,9 +38556,9 @@ const MOCK_VENDORS = [
38426
38556
  name: 'HaveService Danmark',
38427
38557
  category: 'Have & Grønne arealer',
38428
38558
  description: 'Pleje af fællesarealer og haver',
38429
- logo: '/Assets/dummy-logos/gardener-logo.svg',
38430
- thumbnail: '/Assets/Dummy-photos/gardener.jpg',
38431
- heroImage: '/Assets/Dummy-photos/gardener.jpg',
38559
+ logo: '/assets/dummy-logos/gardener-logo.svg',
38560
+ thumbnail: '/assets/Dummy-photos/gardener.jpg',
38561
+ heroImage: '/assets/Dummy-photos/gardener.jpg',
38432
38562
  fullDescription: '<h3>Have & Grønne arealer</h3><p>HaveService Danmark står for den løbende pleje af fællesarealer og haver — herunder græsslåning, hækklipning, ukrudtsbekæmpelse og sæsonbeplantning.</p><h3>Pris</h3><p>500 kr. per besøg</p>',
38433
38563
  price: '500 kr. per besøg',
38434
38564
  availabilityStatus: 'unavailable',