@propbinder/mobile-design 0.2.50 → 0.2.52
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/propbinder-mobile-design.mjs +26206 -0
- package/fesm2022/propbinder-mobile-design.mjs.map +1 -0
- package/index.d.ts +8193 -0
- package/package.json +39 -3
- package/ng-package.json +0 -24
- package/src/animations/page-transitions.ts +0 -165
- package/src/components/action-list-item/ds-mobile-action-list-item.ts +0 -102
- package/src/components/action-list-item/index.ts +0 -2
- package/src/components/app-icon/ds-app-icon.ts +0 -133
- package/src/components/app-icon/index.ts +0 -2
- package/src/components/attachment-preview/ds-mobile-attachment-preview.css +0 -139
- package/src/components/attachment-preview/ds-mobile-attachment-preview.ts +0 -164
- package/src/components/attachment-preview/index.ts +0 -1
- package/src/components/avatar-with-badge/ds-avatar-with-badge.ts +0 -142
- package/src/components/avatar-with-badge/index.ts +0 -2
- package/src/components/booking-modal/ds-mobile-booking-confirmation-wrapper.ts +0 -71
- package/src/components/booking-modal/ds-mobile-booking-modal.service.ts +0 -121
- package/src/components/booking-modal/ds-mobile-booking-modal.ts +0 -598
- package/src/components/booking-modal/ds-mobile-booking-summary.ts +0 -161
- package/src/components/booking-modal/index.ts +0 -4
- package/src/components/bottom-sheet/ds-mobile-actions-bottom-sheet.ts +0 -266
- package/src/components/bottom-sheet/ds-mobile-bottom-sheet-header.ts +0 -146
- package/src/components/bottom-sheet/ds-mobile-bottom-sheet-wrapper.ts +0 -156
- package/src/components/bottom-sheet/ds-mobile-bottom-sheet.css +0 -101
- package/src/components/bottom-sheet/ds-mobile-bottom-sheet.service.ts +0 -169
- package/src/components/bottom-sheet/ds-mobile-confirmation-sheet.ts +0 -211
- package/src/components/bottom-sheet/ds-mobile-post-create-bottom-sheet.ts +0 -578
- package/src/components/bottom-sheet/ds-mobile-profile-actions-sheet.ts +0 -614
- package/src/components/bottom-sheet/index.ts +0 -8
- package/src/components/bottom-sheet/modal-shadow-fix.ts +0 -42
- package/src/components/card-inline/ds-mobile-card-inline.ts +0 -301
- package/src/components/card-inline/index.ts +0 -2
- package/src/components/card-inline-banner/ds-mobile-card-inline-banner.ts +0 -118
- package/src/components/card-inline-banner/index.ts +0 -1
- package/src/components/card-inline-contact/ds-mobile-card-inline-contact.ts +0 -120
- package/src/components/card-inline-contact/index.ts +0 -1
- package/src/components/card-inline-file/ds-mobile-card-inline-file.ts +0 -141
- package/src/components/card-inline-file/index.ts +0 -1
- package/src/components/chat-modal/ds-mobile-chat-modal.css +0 -159
- package/src/components/chat-modal/ds-mobile-chat-modal.service.ts +0 -105
- package/src/components/chat-modal/ds-mobile-chat-modal.ts +0 -918
- package/src/components/chat-modal/index.ts +0 -8
- package/src/components/comment/ds-mobile-comment.ts +0 -568
- package/src/components/comment/index.ts +0 -2
- package/src/components/contact-list-item/ds-mobile-contact-list-item.ts +0 -182
- package/src/components/contact-list-item/index.ts +0 -2
- package/src/components/content/ds-mobile-content.ts +0 -139
- package/src/components/content/index.ts +0 -2
- package/src/components/dropdown/ds-mobile-dropdown.css +0 -199
- package/src/components/dropdown/ds-mobile-dropdown.ts +0 -340
- package/src/components/dropdown/index.ts +0 -2
- package/src/components/ds-mobile-tabs.css +0 -407
- package/src/components/ds-mobile-tabs.ts +0 -216
- package/src/components/empty-state/ds-mobile-empty-state.ts +0 -120
- package/src/components/empty-state/index.ts +0 -2
- package/src/components/fab/ds-mobile-fab.ts +0 -315
- package/src/components/fab/index.ts +0 -1
- package/src/components/facility-creation-modal/ds-mobile-facility-creation-confirmation-wrapper.ts +0 -121
- package/src/components/facility-creation-modal/ds-mobile-facility-creation-modal.css +0 -189
- package/src/components/facility-creation-modal/ds-mobile-facility-creation-modal.service.ts +0 -135
- package/src/components/facility-creation-modal/ds-mobile-facility-creation-modal.ts +0 -656
- package/src/components/facility-creation-modal/index.ts +0 -9
- package/src/components/facility-creation-modal/sheets/ds-mobile-access-sheet.ts +0 -105
- package/src/components/facility-creation-modal/sheets/ds-mobile-price-sheet.ts +0 -188
- package/src/components/facility-creation-modal/sheets/ds-mobile-when-can-book-sheet.ts +0 -460
- package/src/components/facility-creation-modal/sheets/ds-mobile-who-can-book-sheet.ts +0 -134
- package/src/components/facility-detail-modal/ds-mobile-facility-detail-modal.service.ts +0 -69
- package/src/components/facility-detail-modal/ds-mobile-facility-detail-modal.ts +0 -379
- package/src/components/facility-detail-modal/index.ts +0 -2
- package/src/components/file-attachment/ds-mobile-file-attachment.ts +0 -164
- package/src/components/file-attachment/index.ts +0 -2
- package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.css +0 -214
- package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.service.ts +0 -84
- package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.ts +0 -424
- package/src/components/handbook-detail-modal/index.ts +0 -3
- package/src/components/handbook-folder/ds-mobile-handbook-folder-mini.ts +0 -175
- package/src/components/handbook-folder/ds-mobile-handbook-folder.ts +0 -533
- package/src/components/handbook-folder/index.ts +0 -4
- package/src/components/header-content/ds-mobile-header-content.ts +0 -222
- package/src/components/header-content/index.ts +0 -2
- package/src/components/illustration/ds-mobile-illustration.ts +0 -124
- package/src/components/illustration/index.ts +0 -2
- package/src/components/index.ts +0 -124
- package/src/components/inline-photo/ds-mobile-inline-photo.ts +0 -361
- package/src/components/inline-photo/index.ts +0 -1
- package/src/components/inline-tabs/ds-mobile-inline-tabs.ts +0 -132
- package/src/components/inline-tabs/index.ts +0 -2
- package/src/components/interactive-list-item-booking/ds-mobile-interactive-list-item-booking.ts +0 -350
- package/src/components/interactive-list-item-booking/index.ts +0 -1
- package/src/components/interactive-list-item-inquiry/ds-mobile-interactive-list-item-inquiry.ts +0 -321
- package/src/components/interactive-list-item-inquiry/index.ts +0 -2
- package/src/components/interactive-list-item-message/ds-mobile-interactive-list-item-message.ts +0 -237
- package/src/components/interactive-list-item-message/index.ts +0 -2
- package/src/components/interactive-list-item-post/ds-mobile-interactive-list-item-post.ts +0 -549
- package/src/components/interactive-list-item-post/ds-mobile-post-pdf-attachment.ts +0 -124
- package/src/components/interactive-list-item-post/index.ts +0 -13
- package/src/components/lightbox/ds-mobile-lightbox-footer.ts +0 -315
- package/src/components/lightbox/ds-mobile-lightbox-header.ts +0 -202
- package/src/components/lightbox/ds-mobile-lightbox-image.ts +0 -484
- package/src/components/lightbox/ds-mobile-lightbox-pdf.css +0 -377
- package/src/components/lightbox/ds-mobile-lightbox-pdf.ts +0 -374
- package/src/components/lightbox/ds-mobile-lightbox.css +0 -587
- package/src/components/lightbox/ds-mobile-lightbox.service.ts +0 -296
- package/src/components/lightbox/ds-mobile-lightbox.ts +0 -529
- package/src/components/lightbox/index.ts +0 -22
- package/src/components/list-item/ds-mobile-list-item.ts +0 -603
- package/src/components/list-item/index.ts +0 -2
- package/src/components/list-item-static/ds-mobile-list-item-static.ts +0 -133
- package/src/components/list-item-static/index.ts +0 -2
- package/src/components/loader-overlay/ds-mobile-loader-overlay.css +0 -49
- package/src/components/loader-overlay/ds-mobile-loader-overlay.ts +0 -77
- package/src/components/loader-overlay/index.ts +0 -1
- package/src/components/logo/ds-logo.ts +0 -95
- package/src/components/logo/index.ts +0 -2
- package/src/components/message-bubble/ds-mobile-message-bubble.ts +0 -633
- package/src/components/message-bubble/index.ts +0 -7
- package/src/components/message-composer/ds-mobile-message-composer.ts +0 -1146
- package/src/components/message-composer/index.ts +0 -7
- package/src/components/modal/ds-mobile-modal.css +0 -163
- package/src/components/modal/ds-mobile-modal.service.ts +0 -329
- package/src/components/modal/index.ts +0 -8
- package/src/components/modal-base/ds-mobile-modal-base.css +0 -378
- package/src/components/modal-base/ds-mobile-modal-base.ts +0 -261
- package/src/components/modal-base/index.ts +0 -2
- package/src/components/new-inquiry-modal/ds-mobile-new-inquiry-modal.css +0 -112
- package/src/components/new-inquiry-modal/ds-mobile-new-inquiry-modal.service.ts +0 -93
- package/src/components/new-inquiry-modal/ds-mobile-new-inquiry-modal.ts +0 -442
- package/src/components/new-inquiry-modal/index.ts +0 -4
- package/src/components/offline-banner/ds-mobile-offline-banner.ts +0 -135
- package/src/components/offline-banner/index.ts +0 -1
- package/src/components/page-details/ds-mobile-page-details.css +0 -83
- package/src/components/page-details/ds-mobile-page-details.ts +0 -282
- package/src/components/page-details/index.ts +0 -2
- package/src/components/page-main/ds-mobile-page-main.css +0 -68
- package/src/components/page-main/ds-mobile-page-main.ts +0 -421
- package/src/components/page-main/index.ts +0 -2
- package/src/components/post-composer/ds-mobile-post-composer.ts +0 -140
- package/src/components/post-composer/index.ts +0 -2
- package/src/components/post-detail-modal/ds-mobile-post-detail-modal.css +0 -390
- package/src/components/post-detail-modal/ds-mobile-post-detail-modal.service.ts +0 -108
- package/src/components/post-detail-modal/ds-mobile-post-detail-modal.ts +0 -722
- package/src/components/post-detail-modal/index.ts +0 -9
- package/src/components/property-banner/ds-mobile-property-banner.ts +0 -95
- package/src/components/property-banner/index.ts +0 -2
- package/src/components/section/ds-mobile-section.ts +0 -263
- package/src/components/section/index.ts +0 -2
- package/src/components/shared/directives/index.ts +0 -2
- package/src/components/shared/directives/long-press.directive.ts +0 -212
- package/src/components/shared/index.ts +0 -3
- package/src/components/shared/mobile-modal-base.ts +0 -457
- package/src/components/shared/mobile-page-base.ts +0 -204
- package/src/components/swiper/ds-mobile-swiper-with-nav.ts +0 -160
- package/src/components/swiper/ds-mobile-swiper.ts +0 -327
- package/src/components/swiper/index.ts +0 -3
- package/src/components/system-message-banner/ds-mobile-system-message-banner.ts +0 -129
- package/src/components/system-message-banner/index.ts +0 -2
- package/src/components/tab-bar/ds-mobile-tab-bar.css +0 -533
- package/src/components/tab-bar/ds-mobile-tab-bar.ts +0 -735
- package/src/components/tab-bar/index.ts +0 -2
- package/src/components/tabs/ds-mobile-tabs.css +0 -25
- package/src/components/tabs/ds-mobile-tabs.ts +0 -89
- package/src/components/tabs/index.ts +0 -2
- package/src/components/text-input/ds-text-input.ts +0 -287
- package/src/components/text-input/index.ts +0 -2
- package/src/examples/booking.page.ts +0 -434
- package/src/examples/community.page.ts +0 -776
- package/src/examples/handbook.page.ts +0 -324
- package/src/examples/home.page.ts +0 -347
- package/src/examples/index.ts +0 -12
- package/src/examples/inquiries.example.ts +0 -273
- package/src/examples/inquiry-detail.example.css +0 -189
- package/src/examples/inquiry-detail.example.ts +0 -415
- package/src/examples/mobile-tabs-example.component.ts +0 -208
- package/src/examples/post-create.page.ts +0 -311
- package/src/examples/post-detail.page.ts +0 -296
- package/src/examples/sign-in.page.ts +0 -291
- package/src/examples/whitelabel-demo-modal.component.ts +0 -1094
- package/src/examples/whitelabel-demo-modal.service.ts +0 -77
- package/src/models/index.ts +0 -7
- package/src/models/post.model.ts +0 -41
- package/src/pages/community.page.ts +0 -769
- package/src/pages/handbook.page.ts +0 -388
- package/src/pages/home.page.ts +0 -303
- package/src/pages/index.ts +0 -11
- package/src/pages/inquiries.example.ts +0 -273
- package/src/pages/inquiry-detail.example.css +0 -189
- package/src/pages/inquiry-detail.example.ts +0 -415
- package/src/pages/mobile-tabs-example.component.ts +0 -179
- package/src/pages/post-create.page.ts +0 -311
- package/src/pages/post-detail.page.ts +0 -296
- package/src/pages/sign-in.page.ts +0 -291
- package/src/pages/whitelabel-demo-modal.component.ts +0 -1094
- package/src/pages/whitelabel-demo-modal.service.ts +0 -77
- package/src/public-api.ts +0 -6
- package/src/services/base-modal.service.ts +0 -101
- package/src/services/index.ts +0 -11
- package/src/services/posts.service.ts +0 -542
- package/src/services/tracking-permission.service.ts +0 -88
- package/src/services/user.service.ts +0 -60
- package/src/services/whitelabel.service.ts +0 -675
- package/tsconfig.lib.json +0 -17
- package/tsconfig.lib.prod.json +0 -9
- package/tsconfig.spec.json +0 -13
- /package/{src/assets → assets}/fonts/Brockmann-Bold.otf +0 -0
- /package/{src/assets → assets}/fonts/Brockmann-BoldItalic.otf +0 -0
- /package/{src/assets → assets}/fonts/Brockmann-Medium.otf +0 -0
- /package/{src/assets → assets}/fonts/Brockmann-MediumItalic.otf +0 -0
- /package/{src/assets → assets}/fonts/Brockmann-Regular.otf +0 -0
- /package/{src/assets → assets}/fonts/Brockmann-RegularItalic.otf +0 -0
- /package/{src/assets → assets}/fonts/Brockmann-SemiBold.otf +0 -0
- /package/{src/assets → assets}/fonts/Brockmann-SemiBoldItalic.otf +0 -0
- /package/{src/assets → assets}/fonts/Brockmann_desktop_license.pdf +0 -0
- /package/{src/assets → assets}/fonts/brockmann-medium-webfont.woff2 +0 -0
- /package/{src/assets → assets}/fonts/brockmann-mediumitalic-webfont.woff2 +0 -0
- /package/{src/assets → assets}/fonts/brockmann-regular-webfont.woff2 +0 -0
- /package/{src/assets → assets}/fonts/brockmann-regularitalic-webfont.woff2 +0 -0
- /package/{src/assets → assets}/fonts/brockmann-semibold-webfont.woff2 +0 -0
- /package/{src/assets → assets}/fonts/brockmann-semibolditalic-webfont.woff2 +0 -0
- /package/{src/styles → styles}/ionic.css +0 -0
- /package/{src/components/shared → styles}/mobile-common.css +0 -0
- /package/{src/components/shared → styles}/mobile-page-base.css +0 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"propbinder-mobile-design.mjs","sources":["../../../projects/mobile-design-lib/src/services/whitelabel.service.ts","../../../projects/mobile-design-lib/src/components/logo/ds-logo.ts","../../../projects/mobile-design-lib/src/components/loader-overlay/ds-mobile-loader-overlay.ts","../../../projects/mobile-design-lib/src/components/shared/mobile-page-base.ts","../../../projects/mobile-design-lib/src/components/shared/directives/long-press.directive.ts","../../../projects/mobile-design-lib/src/components/list-item/ds-mobile-list-item.ts","../../../projects/mobile-design-lib/src/components/action-list-item/ds-mobile-action-list-item.ts","../../../projects/mobile-design-lib/src/components/bottom-sheet/ds-mobile-bottom-sheet-wrapper.ts","../../../projects/mobile-design-lib/src/components/bottom-sheet/ds-mobile-actions-bottom-sheet.ts","../../../projects/mobile-design-lib/src/components/bottom-sheet/modal-shadow-fix.ts","../../../projects/mobile-design-lib/src/components/bottom-sheet/ds-mobile-bottom-sheet.service.ts","../../../projects/mobile-design-lib/src/components/bottom-sheet/ds-mobile-bottom-sheet-header.ts","../../../projects/mobile-design-lib/src/components/illustration/ds-mobile-illustration.ts","../../../projects/mobile-design-lib/src/components/bottom-sheet/ds-mobile-confirmation-sheet.ts","../../../projects/mobile-design-lib/src/components/bottom-sheet/ds-mobile-post-create-bottom-sheet.ts","../../../projects/mobile-design-lib/src/components/bottom-sheet/ds-mobile-profile-actions-sheet.ts","../../../projects/mobile-design-lib/src/services/user.service.ts","../../../projects/mobile-design-lib/src/components/app-icon/ds-app-icon.ts","../../../projects/mobile-design-lib/src/components/avatar-with-badge/ds-avatar-with-badge.ts","../../../projects/mobile-design-lib/src/pages/whitelabel-demo-modal.component.ts","../../../projects/mobile-design-lib/src/pages/whitelabel-demo-modal.service.ts","../../../projects/mobile-design-lib/src/components/page-main/ds-mobile-page-main.ts","../../../projects/mobile-design-lib/src/components/inline-tabs/ds-mobile-inline-tabs.ts","../../../projects/mobile-design-lib/src/animations/page-transitions.ts","../../../projects/mobile-design-lib/src/components/page-details/ds-mobile-page-details.ts","../../../projects/mobile-design-lib/src/components/content/ds-mobile-content.ts","../../../projects/mobile-design-lib/src/components/section/ds-mobile-section.ts","../../../projects/mobile-design-lib/src/components/header-content/ds-mobile-header-content.ts","../../../projects/mobile-design-lib/src/components/system-message-banner/ds-mobile-system-message-banner.ts","../../../projects/mobile-design-lib/src/components/file-attachment/ds-mobile-file-attachment.ts","../../../projects/mobile-design-lib/src/components/comment/ds-mobile-comment.ts","../../../projects/mobile-design-lib/src/components/post-composer/ds-mobile-post-composer.ts","../../../projects/mobile-design-lib/src/components/attachment-preview/ds-mobile-attachment-preview.ts","../../../projects/mobile-design-lib/src/components/dropdown/ds-mobile-dropdown.ts","../../../projects/mobile-design-lib/src/components/message-composer/ds-mobile-message-composer.ts","../../../projects/mobile-design-lib/src/components/message-bubble/ds-mobile-message-bubble.ts","../../../projects/mobile-design-lib/src/components/list-item-static/ds-mobile-list-item-static.ts","../../../projects/mobile-design-lib/src/components/interactive-list-item-post/ds-mobile-interactive-list-item-post.ts","../../../projects/mobile-design-lib/src/components/interactive-list-item-post/ds-mobile-post-pdf-attachment.ts","../../../projects/mobile-design-lib/src/components/interactive-list-item-post/index.ts","../../../projects/mobile-design-lib/src/components/interactive-list-item-inquiry/ds-mobile-interactive-list-item-inquiry.ts","../../../projects/mobile-design-lib/src/components/interactive-list-item-message/ds-mobile-interactive-list-item-message.ts","../../../projects/mobile-design-lib/src/components/contact-list-item/ds-mobile-contact-list-item.ts","../../../projects/mobile-design-lib/src/components/interactive-list-item-booking/ds-mobile-interactive-list-item-booking.ts","../../../projects/mobile-design-lib/src/components/tab-bar/ds-mobile-tab-bar.ts","../../../projects/mobile-design-lib/src/components/tabs/ds-mobile-tabs.ts","../../../projects/mobile-design-lib/src/components/swiper/ds-mobile-swiper.ts","../../../projects/mobile-design-lib/src/components/swiper/ds-mobile-swiper-with-nav.ts","../../../projects/mobile-design-lib/src/components/lightbox/ds-mobile-lightbox-header.ts","../../../projects/mobile-design-lib/src/components/lightbox/ds-mobile-lightbox-footer.ts","../../../projects/mobile-design-lib/src/components/lightbox/ds-mobile-lightbox-image.ts","../../../projects/mobile-design-lib/src/components/lightbox/ds-mobile-lightbox-pdf.ts","../../../projects/mobile-design-lib/src/components/lightbox/ds-mobile-lightbox.service.ts","../../../projects/mobile-design-lib/src/components/lightbox/index.ts","../../../projects/mobile-design-lib/src/components/inline-photo/ds-mobile-inline-photo.ts","../../../projects/mobile-design-lib/src/components/modal/ds-mobile-modal.service.ts","../../../projects/mobile-design-lib/src/components/modal/index.ts","../../../projects/mobile-design-lib/src/components/shared/mobile-modal-base.ts","../../../projects/mobile-design-lib/src/components/modal-base/ds-mobile-modal-base.ts","../../../projects/mobile-design-lib/src/components/empty-state/ds-mobile-empty-state.ts","../../../projects/mobile-design-lib/src/components/post-detail-modal/ds-mobile-post-detail-modal.ts","../../../projects/mobile-design-lib/src/services/base-modal.service.ts","../../../projects/mobile-design-lib/src/components/post-detail-modal/ds-mobile-post-detail-modal.service.ts","../../../projects/mobile-design-lib/src/components/post-detail-modal/index.ts","../../../projects/mobile-design-lib/src/components/card-inline/ds-mobile-card-inline.ts","../../../projects/mobile-design-lib/src/components/card-inline-banner/ds-mobile-card-inline-banner.ts","../../../projects/mobile-design-lib/src/components/card-inline-contact/ds-mobile-card-inline-contact.ts","../../../projects/mobile-design-lib/src/components/card-inline-file/ds-mobile-card-inline-file.ts","../../../projects/mobile-design-lib/src/components/chat-modal/ds-mobile-chat-modal.ts","../../../projects/mobile-design-lib/src/components/chat-modal/ds-mobile-chat-modal.service.ts","../../../projects/mobile-design-lib/src/components/new-inquiry-modal/ds-mobile-new-inquiry-modal.ts","../../../projects/mobile-design-lib/src/components/new-inquiry-modal/ds-mobile-new-inquiry-modal.service.ts","../../../projects/mobile-design-lib/src/components/booking-modal/ds-mobile-booking-modal.ts","../../../projects/mobile-design-lib/src/components/booking-modal/ds-mobile-booking-summary.ts","../../../projects/mobile-design-lib/src/components/booking-modal/ds-mobile-booking-confirmation-wrapper.ts","../../../projects/mobile-design-lib/src/components/booking-modal/ds-mobile-booking-modal.service.ts","../../../projects/mobile-design-lib/src/components/facility-creation-modal/ds-mobile-facility-creation-modal.ts","../../../projects/mobile-design-lib/src/components/facility-creation-modal/ds-mobile-facility-creation-confirmation-wrapper.ts","../../../projects/mobile-design-lib/src/components/facility-creation-modal/ds-mobile-facility-creation-modal.service.ts","../../../projects/mobile-design-lib/src/components/facility-creation-modal/sheets/ds-mobile-who-can-book-sheet.ts","../../../projects/mobile-design-lib/src/components/facility-creation-modal/sheets/ds-mobile-when-can-book-sheet.ts","../../../projects/mobile-design-lib/src/components/facility-creation-modal/sheets/ds-mobile-price-sheet.ts","../../../projects/mobile-design-lib/src/components/facility-creation-modal/sheets/ds-mobile-access-sheet.ts","../../../projects/mobile-design-lib/src/components/facility-detail-modal/ds-mobile-facility-detail-modal.ts","../../../projects/mobile-design-lib/src/components/facility-detail-modal/ds-mobile-facility-detail-modal.service.ts","../../../projects/mobile-design-lib/src/components/handbook-folder/ds-mobile-handbook-folder-mini.ts","../../../projects/mobile-design-lib/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.ts","../../../projects/mobile-design-lib/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.service.ts","../../../projects/mobile-design-lib/src/components/handbook-folder/ds-mobile-handbook-folder.ts","../../../projects/mobile-design-lib/src/components/text-input/ds-text-input.ts","../../../projects/mobile-design-lib/src/components/fab/ds-mobile-fab.ts","../../../projects/mobile-design-lib/src/components/offline-banner/ds-mobile-offline-banner.ts","../../../projects/mobile-design-lib/src/components/property-banner/ds-mobile-property-banner.ts","../../../projects/mobile-design-lib/src/components/index.ts","../../../projects/mobile-design-lib/src/services/posts.service.ts","../../../projects/mobile-design-lib/src/examples/community.page.ts","../../../projects/mobile-design-lib/src/examples/handbook.page.ts","../../../projects/mobile-design-lib/src/services/tracking-permission.service.ts","../../../projects/mobile-design-lib/src/examples/home.page.ts","../../../projects/mobile-design-lib/src/examples/inquiries.example.ts","../../../projects/mobile-design-lib/src/examples/inquiry-detail.example.ts","../../../projects/mobile-design-lib/src/examples/whitelabel-demo-modal.component.ts","../../../projects/mobile-design-lib/src/examples/whitelabel-demo-modal.service.ts","../../../projects/mobile-design-lib/src/examples/mobile-tabs-example.component.ts","../../../projects/mobile-design-lib/src/examples/booking.page.ts","../../../projects/mobile-design-lib/src/examples/post-create.page.ts","../../../projects/mobile-design-lib/src/examples/post-detail.page.ts","../../../projects/mobile-design-lib/src/examples/sign-in.page.ts","../../../projects/mobile-design-lib/src/services/index.ts","../../../projects/mobile-design-lib/src/models/post.model.ts","../../../projects/mobile-design-lib/src/models/index.ts","../../../projects/mobile-design-lib/src/public-api.ts","../../../projects/mobile-design-lib/src/propbinder-mobile-design.ts"],"sourcesContent":["import { Injectable, signal, effect, computed } from '@angular/core';\r\nimport { StatusBar, Style } from '@capacitor/status-bar';\r\n\r\nexport interface WhitelabelConfig {\r\n // Logo assets\r\n logoUrl: string; // Full logo for header (typically horizontal)\r\n logoMarkUrl: string; // Compact logo mark for avatars/badges\r\n logoAlt: string; // Alt text for accessibility\r\n logoSize: 'sm' | 'md' | 'lg' | 'xl'; // Logo size in header (sm: 24px, md: 28px, lg: 32px, xl: 36px)\r\n\r\n // Logo dimensions (optional, for optimization)\r\n logoWidth?: number;\r\n logoHeight?: number;\r\n logoMarkWidth?: number;\r\n logoMarkHeight?: number;\r\n\r\n // ============================================\r\n // APP ICON (app icons, logo badges)\r\n // ============================================\r\n appIconSurface: string; // App icon background fill\r\n appIconContent: string; // Logomark color on app icon\r\n\r\n // ============================================\r\n // ACTIONS & SELECTIONS (buttons, FABs, active tabs, selected items)\r\n // ============================================\r\n accent: string; // Main accent color (button bg, active tab icon)\r\n onAccent: string; // Content on accent-colored surfaces (button text/icon)\r\n\r\n // ============================================\r\n // HEADER/NAVIGATION (includes ion-header and header-expandable)\r\n // ============================================\r\n headerSurface: string; // Header background\r\n headerContent: string; // Header text/icons\r\n headerAccent: string; // Accent elements in header (e.g., subtle overlay)\r\n onHeaderAccent: string; // Content on header accent elements\r\n\r\n // ============================================\r\n // SIGN-IN PAGE CUSTOMIZATION\r\n // ============================================\r\n showCityIllustration: boolean; // Show/hide city illustration on sign-in page\r\n\r\n // Sign-in background\r\n signInBgType: 'solid' | 'gradient'; // Background type\r\n signInBgSolid: string; // Solid background color\r\n signInBgGradientStart: string; // Gradient start color (top)\r\n signInBgGradientEnd: string; // Gradient end color (bottom)\r\n\r\n // Sign-in content color\r\n signInContentColor: string; // Text color on sign-in page (headings, body text, links)\r\n\r\n // Organization info\r\n organizationName: string;\r\n organizationId: string;\r\n}\r\n\r\nconst DEFAULT_CONFIG: WhitelabelConfig = {\r\n logoUrl: '/Assets/logos/propbinder-logomark.svg',\r\n logoMarkUrl: '/Assets/logos/propbinder-logomark.svg',\r\n logoAlt: 'Propbinder',\r\n logoSize: 'md', // Propbinder default: md (28px mobile, 32px desktop)\r\n\r\n // App icon (brand identity)\r\n appIconSurface: '#6B5FF5', // Purple\r\n appIconContent: '#FFFFFF', // White\r\n\r\n // Accent (buttons, FABs, active tabs)\r\n accent: '#6B5FF5', // Purple\r\n onAccent: '#FFFFFF', // White\r\n\r\n // Header/navigation\r\n headerSurface: '#221a4c', // Dark purple\r\n headerContent: '#FFFFFF', // White\r\n headerAccent: '#6B5FF5', // Purple accent (matches Propbinder theme)\r\n onHeaderAccent: '#FFFFFF', // White\r\n\r\n // Sign-in page\r\n showCityIllustration: true, // Show city illustration by default\r\n signInBgType: 'gradient', // Use gradient by default\r\n signInBgSolid: '#D6C7FF', // Fallback solid color\r\n signInBgGradientStart: '#D6C7FF', // Gradient top color\r\n signInBgGradientEnd: '#8A9BFF', // Gradient bottom color\r\n signInContentColor: '#1a1a1a', // Default dark text color\r\n\r\n organizationName: 'Propbinder',\r\n organizationId: 'default',\r\n};\r\n\r\n/**\r\n * WhitelabelService\r\n *\r\n * Manages whitelabel configuration including logos and brand colors.\r\n * Automatically updates CSS custom properties when colors change.\r\n *\r\n * @example\r\n * Initialize with custom config:\r\n * ```typescript\r\n * whitelabelService.initialize({\r\n * logoUrl: '/Assets/logos/acme-logo.svg',\r\n * logoMarkUrl: '/Assets/logos/acme-mark.svg',\r\n * accent: '#2563eb',\r\n * onAccent: '#ffffff',\r\n * headerSurface: '#1e40af',\r\n * headerContent: '#ffffff',\r\n * organizationName: 'Acme Corp'\r\n * });\r\n * ```\r\n *\r\n * Load from API:\r\n * ```typescript\r\n * await whitelabelService.loadFromApi('acme-corp');\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class WhitelabelService {\r\n private _config = signal<WhitelabelConfig>(DEFAULT_CONFIG);\r\n\r\n // Readonly computed signals for accessing config values\r\n readonly logoUrl = computed(() => this._config().logoUrl);\r\n readonly logoMarkUrl = computed(() => this._config().logoMarkUrl);\r\n readonly logoAlt = computed(() => this._config().logoAlt);\r\n readonly logoSize = computed(() => this._config().logoSize);\r\n readonly logoHeight = computed(() => {\r\n const customHeight = this._config().logoHeight;\r\n const size = this._config().logoSize;\r\n\r\n // If custom height is explicitly specified, always use it\r\n if (customHeight !== undefined) {\r\n return customHeight;\r\n }\r\n\r\n // Otherwise calculate height based on logoSize\r\n switch (size) {\r\n case 'sm':\r\n return 24;\r\n case 'md':\r\n return 28;\r\n case 'lg':\r\n return 32;\r\n case 'xl':\r\n return 36;\r\n default:\r\n return 28;\r\n }\r\n });\r\n readonly appIconSurface = computed(() => this._config().appIconSurface);\r\n readonly appIconContent = computed(() => this._config().appIconContent);\r\n readonly accent = computed(() => this._config().accent);\r\n readonly onAccent = computed(() => this._config().onAccent);\r\n readonly headerSurface = computed(() => this._config().headerSurface);\r\n readonly headerContent = computed(() => this._config().headerContent);\r\n readonly headerAccent = computed(() => this._config().headerAccent);\r\n readonly onHeaderAccent = computed(() => this._config().onHeaderAccent);\r\n readonly showCityIllustration = computed(() => this._config().showCityIllustration);\r\n readonly signInBgType = computed(() => this._config().signInBgType);\r\n readonly signInBgSolid = computed(() => this._config().signInBgSolid);\r\n readonly signInBgGradientStart = computed(() => this._config().signInBgGradientStart);\r\n readonly signInBgGradientEnd = computed(() => this._config().signInBgGradientEnd);\r\n readonly signInContentColor = computed(() => this._config().signInContentColor);\r\n readonly organizationName = computed(() => this._config().organizationName);\r\n readonly organizationId = computed(() => this._config().organizationId);\r\n\r\n // Computed background style for sign-in page\r\n readonly signInBgStyle = computed(() => {\r\n const config = this._config();\r\n if (config.signInBgType === 'solid') {\r\n return config.signInBgSolid;\r\n } else {\r\n return `linear-gradient(180deg, ${config.signInBgGradientStart} 0%, ${config.signInBgGradientEnd} 100%)`;\r\n }\r\n });\r\n\r\n // Full config accessor\r\n readonly config = this._config.asReadonly();\r\n\r\n constructor() {\r\n // Apply default colors on initialization\r\n this.applyColors(DEFAULT_CONFIG);\r\n\r\n // Watch for config changes and update CSS custom properties\r\n effect(() => {\r\n const config = this._config();\r\n this.applyColors(config);\r\n });\r\n\r\n // Listen for modal dismissals and re-apply status bar\r\n // This fixes the issue where Ionic restores cached status bar state\r\n this.setupModalDismissListener();\r\n }\r\n\r\n /**\r\n * Setup global listener for modal dismiss events\r\n * Re-applies status bar after modals close to override Ionic's cached state restoration\r\n */\r\n private setupModalDismissListener(): void {\r\n if (typeof document === 'undefined') return;\r\n\r\n document.addEventListener('ionModalDidDismiss', () => {\r\n // Small delay to let Ionic's restoration happen first\r\n setTimeout(() => {\r\n // Check if we're on the sign-in page\r\n const isOnSignInPage = document.querySelector('app-sign-in') !== null;\r\n\r\n if (isOnSignInPage) {\r\n // On sign-in page - use sign-in background color\r\n const config = this._config();\r\n const backgroundColor = config.signInBgType === 'gradient' ? config.signInBgGradientStart : config.signInBgSolid;\r\n const style = this.getStatusBarStyleForColor(backgroundColor);\r\n\r\n StatusBar.setBackgroundColor({ color: backgroundColor }).catch(() => {});\r\n StatusBar.setStyle({ style }).catch(() => {});\r\n } else {\r\n // On regular page - use header color\r\n const config = this._config();\r\n const headerColor = config.headerSurface;\r\n const style = this.getStatusBarStyleForColor(headerColor);\r\n\r\n StatusBar.setStyle({ style }).catch(() => {});\r\n }\r\n }, 50);\r\n });\r\n }\r\n\r\n /**\r\n * Initialize whitelabel configuration\r\n * Call this early in app initialization (app.config.ts or app.component.ts)\r\n */\r\n initialize(config: Partial<WhitelabelConfig>) {\r\n this._config.update((current) => ({\r\n ...current,\r\n ...config,\r\n }));\r\n }\r\n\r\n /**\r\n * Load whitelabel config from API\r\n * Typically called on app startup based on subdomain, user tenant, etc.\r\n *\r\n * @param organizationId - The organization identifier (subdomain, tenant ID, etc.)\r\n */\r\n async loadFromApi(organizationId?: string): Promise<void> {\r\n try {\r\n // Example API call structure\r\n // const response = await fetch(`/api/whitelabel/${organizationId || 'default'}`);\r\n // const config = await response.json();\r\n // this.initialize(config);\r\n\r\n //console.log('Loading whitelabel config from API for:', organizationId);\r\n\r\n // Example: Different configs for different organizations\r\n if (organizationId === 'demo-client') {\r\n this.initialize({\r\n logoUrl: '/Assets/logos/demo-logo.svg',\r\n logoMarkUrl: '/Assets/logos/demo-mark.svg',\r\n logoAlt: 'Demo Client',\r\n appIconSurface: '#2563eb',\r\n appIconContent: '#FFFFFF',\r\n accent: '#2563eb',\r\n onAccent: '#FFFFFF',\r\n headerSurface: '#1e40af',\r\n headerContent: '#FFFFFF',\r\n headerAccent: 'rgba(255, 255, 255, 0.15)',\r\n onHeaderAccent: '#FFFFFF',\r\n organizationName: 'Demo Client',\r\n organizationId: 'demo-client',\r\n });\r\n } else if (organizationId === 'cobblestone') {\r\n this.initialize({\r\n logoUrl: '/Assets/logos/cobblestone-logo.svg',\r\n logoMarkUrl: '/Assets/logos/cobblestone-logomark.svg',\r\n logoAlt: 'Cobblestone',\r\n logoSize: 'sm',\r\n appIconSurface: '#2C3E50',\r\n appIconContent: '#FFFFFF',\r\n accent: '#3498DB',\r\n onAccent: '#FFFFFF',\r\n headerSurface: '#2C3E50',\r\n headerContent: '#FFFFFF',\r\n headerAccent: '#3498DB',\r\n onHeaderAccent: '#FFFFFF',\r\n showCityIllustration: false,\r\n signInBgType: 'gradient',\r\n signInBgSolid: '#E8EEF2',\r\n signInBgGradientStart: '#E8EEF2',\r\n signInBgGradientEnd: '#BDC3C7',\r\n signInContentColor: '#1a1a1a',\r\n organizationName: 'Cobblestone',\r\n organizationId: 'cobblestone',\r\n });\r\n }\r\n // Add more organization-specific configs as needed\r\n } catch (error) {\r\n console.error('Failed to load whitelabel config:', error);\r\n // Fallback to defaults already set\r\n }\r\n }\r\n\r\n /**\r\n * Update config dynamically (e.g., when user switches organizations)\r\n */\r\n updateConfig(updates: Partial<WhitelabelConfig>) {\r\n this.initialize(updates);\r\n }\r\n\r\n /**\r\n * Update only the brand colors\r\n */\r\n updateColors(colors: {\r\n appIconSurface?: string;\r\n appIconContent?: string;\r\n accent?: string;\r\n onAccent?: string;\r\n headerSurface?: string;\r\n headerContent?: string;\r\n headerAccent?: string;\r\n onHeaderAccent?: string;\r\n }) {\r\n this._config.update((current) => ({\r\n ...current,\r\n ...colors,\r\n }));\r\n }\r\n\r\n /**\r\n * Reset to default configuration\r\n */\r\n resetToDefault() {\r\n this._config.set(DEFAULT_CONFIG);\r\n }\r\n\r\n /**\r\n * Convert hex color to RGB values\r\n */\r\n private hexToRgb(hex: string): { r: number; g: number; b: number } | null {\r\n const result = /^#?([a-f\\d]{2})([a-f\\d]{2})([a-f\\d]{2})$/i.exec(hex);\r\n return result\r\n ? {\r\n r: parseInt(result[1], 16),\r\n g: parseInt(result[2], 16),\r\n b: parseInt(result[3], 16),\r\n }\r\n : null;\r\n }\r\n\r\n /**\r\n * Calculate relative luminance of a color (WCAG standard)\r\n * Returns a value between 0 (darkest) and 1 (lightest)\r\n */\r\n private getRelativeLuminance(color: string): number {\r\n const rgb = this.hexToRgb(color);\r\n if (!rgb) return 0;\r\n\r\n const rsRGB = rgb.r / 255;\r\n const gsRGB = rgb.g / 255;\r\n const bsRGB = rgb.b / 255;\r\n\r\n const r = rsRGB <= 0.03928 ? rsRGB / 12.92 : Math.pow((rsRGB + 0.055) / 1.055, 2.4);\r\n const g = gsRGB <= 0.03928 ? gsRGB / 12.92 : Math.pow((gsRGB + 0.055) / 1.055, 2.4);\r\n const b = bsRGB <= 0.03928 ? bsRGB / 12.92 : Math.pow((bsRGB + 0.055) / 1.055, 2.4);\r\n\r\n return 0.2126 * r + 0.7152 * g + 0.0722 * b;\r\n }\r\n\r\n /**\r\n * Determine if a color is light (needs dark status bar content)\r\n */\r\n private isColorLight(color: string): boolean {\r\n const luminance = this.getRelativeLuminance(color);\r\n return luminance > 0.5;\r\n }\r\n\r\n /**\r\n * Get the appropriate status bar style for a background color\r\n * Public method for use by sign-in page\r\n */\r\n getStatusBarStyleForColor(color: string): Style {\r\n // Style.Dark = black icons (for light backgrounds)\r\n // Style.Light = white icons (for dark backgrounds)\r\n return this.isColorLight(color) ? Style.Light : Style.Dark;\r\n }\r\n\r\n /**\r\n * Generate a hover state color by applying a black overlay\r\n * This simulates the effect of overlaying #000000 with 10% opacity\r\n *\r\n * @param baseColor - Hex color to overlay on (e.g., '#6B5FF5')\r\n * @param overlayColor - Overlay color (default: '#000000' for darkening)\r\n * @param overlayAlpha - Opacity of overlay (0-1, default: 0.1 = 10%)\r\n * @returns Hex color with overlay applied\r\n *\r\n * @example\r\n * generateHoverColor('#6B5FF5') // Returns darker purple for hover state\r\n * generateHoverColor('#FF0000', '#FFFFFF', 0.2) // Lighten red by 20%\r\n */\r\n private generateHoverColor(baseColor: string, overlayColor: string = '#000000', overlayAlpha: number = 0.1): string {\r\n const base = this.hexToRgb(baseColor);\r\n const overlay = this.hexToRgb(overlayColor);\r\n\r\n if (!base || !overlay) return baseColor;\r\n\r\n // Alpha blending formula: result = overlay * alpha + base * (1 - alpha)\r\n const r = Math.round(overlay.r * overlayAlpha + base.r * (1 - overlayAlpha));\r\n const g = Math.round(overlay.g * overlayAlpha + base.g * (1 - overlayAlpha));\r\n const b = Math.round(overlay.b * overlayAlpha + base.b * (1 - overlayAlpha));\r\n\r\n // Convert to hex and ensure 2-digit format\r\n const toHex = (n: number) => Math.max(0, Math.min(255, n)).toString(16).padStart(2, '0');\r\n return `#${toHex(r)}${toHex(g)}${toHex(b)}`;\r\n }\r\n\r\n /**\r\n * Generate an active/pressed state color (darker than hover)\r\n * Uses 20% black overlay for a more pronounced pressed effect\r\n *\r\n * @param baseColor - Hex color to overlay on\r\n * @returns Hex color for active/pressed state\r\n */\r\n private generateActiveColor(baseColor: string): string {\r\n return this.generateHoverColor(baseColor, '#000000', 0.2); // 20% darker\r\n }\r\n\r\n /**\r\n * Apply colors to CSS custom properties and native StatusBar\r\n * This updates the actual CSS variables used throughout the app\r\n * and the native status bar color on mobile devices\r\n */\r\n private applyColors(config: WhitelabelConfig) {\r\n if (typeof document !== 'undefined') {\r\n const { appIconSurface, appIconContent, accent, onAccent, headerSurface, headerContent, headerAccent, onHeaderAccent, signInContentColor } = config;\r\n const root = document.documentElement;\r\n const body = document.body;\r\n const ionApp = document.querySelector('ion-app');\r\n\r\n // Generate hover and active state colors for accent\r\n const accentHover = this.generateHoverColor(accent);\r\n const accentActive = this.generateActiveColor(accent);\r\n const headerAccentHover = this.generateHoverColor(headerAccent);\r\n const headerAccentActive = this.generateActiveColor(headerAccent);\r\n\r\n // Generate RGB values for Ionic color system\r\n const accentRgb = this.hexToRgb(accent);\r\n const accentRgbString = accentRgb ? `${accentRgb.r}, ${accentRgb.g}, ${accentRgb.b}` : '107, 95, 245';\r\n const onAccentRgb = this.hexToRgb(onAccent);\r\n const onAccentRgbString = onAccentRgb ? `${onAccentRgb.r}, ${onAccentRgb.g}, ${onAccentRgb.b}` : '255, 255, 255';\r\n\r\n // ============================================\r\n // APP ICON COLORS\r\n // ============================================\r\n root.style.setProperty('--color-app-icon-surface', appIconSurface);\r\n root.style.setProperty('--color-app-icon-content', appIconContent);\r\n body.style.setProperty('--color-app-icon-surface', appIconSurface);\r\n body.style.setProperty('--color-app-icon-content', appIconContent);\r\n\r\n // ============================================\r\n // ACCENT COLORS (buttons, FABs, active tabs, selections)\r\n // ============================================\r\n\r\n // Base color\r\n root.style.setProperty('--color-accent', accent);\r\n root.style.setProperty('--color-on-accent', onAccent);\r\n body.style.setProperty('--color-accent', accent);\r\n body.style.setProperty('--color-on-accent', onAccent);\r\n\r\n // Hover state (10% darker)\r\n root.style.setProperty('--color-accent-hover', accentHover);\r\n body.style.setProperty('--color-accent-hover', accentHover);\r\n\r\n // Active/pressed state (20% darker)\r\n root.style.setProperty('--color-accent-active', accentActive);\r\n body.style.setProperty('--color-accent-active', accentActive);\r\n\r\n // Legacy aliases for backward compatibility\r\n root.style.setProperty('--color-background-brand', accent);\r\n root.style.setProperty('--color-brand-base', accent);\r\n root.style.setProperty('--color-primary-surface', accent);\r\n root.style.setProperty('--color-primary-content', onAccent);\r\n root.style.setProperty('--color-brand-base-hover', accentHover);\r\n root.style.setProperty('--color-primary-surface-hover', accentHover);\r\n root.style.setProperty('--color-brand-base-active', accentActive);\r\n root.style.setProperty('--color-primary-surface-active', accentActive);\r\n\r\n body.style.setProperty('--color-background-brand', accent);\r\n body.style.setProperty('--color-brand-base', accent);\r\n body.style.setProperty('--color-primary-surface', accent);\r\n body.style.setProperty('--color-primary-content', onAccent);\r\n body.style.setProperty('--color-brand-base-hover', accentHover);\r\n body.style.setProperty('--color-primary-surface-hover', accentHover);\r\n body.style.setProperty('--color-brand-base-active', accentActive);\r\n body.style.setProperty('--color-primary-surface-active', accentActive);\r\n\r\n if (ionApp) {\r\n (ionApp as HTMLElement).style.setProperty('--color-accent', accent);\r\n (ionApp as HTMLElement).style.setProperty('--color-on-accent', onAccent);\r\n (ionApp as HTMLElement).style.setProperty('--color-accent-hover', accentHover);\r\n (ionApp as HTMLElement).style.setProperty('--color-accent-active', accentActive);\r\n (ionApp as HTMLElement).style.setProperty('--color-background-brand', accent);\r\n (ionApp as HTMLElement).style.setProperty('--color-brand-base', accent);\r\n (ionApp as HTMLElement).style.setProperty('--color-primary-surface', accent);\r\n (ionApp as HTMLElement).style.setProperty('--color-primary-content', onAccent);\r\n (ionApp as HTMLElement).style.setProperty('--color-brand-base-hover', accentHover);\r\n (ionApp as HTMLElement).style.setProperty('--color-primary-surface-hover', accentHover);\r\n (ionApp as HTMLElement).style.setProperty('--color-brand-base-active', accentActive);\r\n (ionApp as HTMLElement).style.setProperty('--color-primary-surface-active', accentActive);\r\n (ionApp as HTMLElement).style.setProperty('--color-selected', accent);\r\n }\r\n\r\n // Update tab button selected color directly\r\n // CSS variable inheritance doesn't always work dynamically with Ionic components\r\n document.querySelectorAll('ion-tab-button').forEach((tabButton) => {\r\n (tabButton as HTMLElement).style.setProperty('--color-selected', accent);\r\n });\r\n\r\n // ============================================\r\n // IONIC COLOR SYSTEM\r\n // ============================================\r\n // Update Ionic's primary color system with RGB values\r\n root.style.setProperty('--ion-color-primary', accent);\r\n root.style.setProperty('--ion-color-primary-rgb', accentRgbString);\r\n root.style.setProperty('--ion-color-primary-contrast', onAccent);\r\n root.style.setProperty('--ion-color-primary-contrast-rgb', onAccentRgbString);\r\n root.style.setProperty('--ion-color-primary-shade', accentHover);\r\n root.style.setProperty('--ion-color-primary-tint', accent);\r\n\r\n body.style.setProperty('--ion-color-primary', accent);\r\n body.style.setProperty('--ion-color-primary-rgb', accentRgbString);\r\n body.style.setProperty('--ion-color-primary-contrast', onAccent);\r\n body.style.setProperty('--ion-color-primary-contrast-rgb', onAccentRgbString);\r\n body.style.setProperty('--ion-color-primary-shade', accentHover);\r\n body.style.setProperty('--ion-color-primary-tint', accent);\r\n\r\n if (ionApp) {\r\n (ionApp as HTMLElement).style.setProperty('--ion-color-primary', accent);\r\n (ionApp as HTMLElement).style.setProperty('--ion-color-primary-rgb', accentRgbString);\r\n (ionApp as HTMLElement).style.setProperty('--ion-color-primary-contrast', onAccent);\r\n (ionApp as HTMLElement).style.setProperty('--ion-color-primary-contrast-rgb', onAccentRgbString);\r\n (ionApp as HTMLElement).style.setProperty('--ion-color-primary-shade', accentHover);\r\n (ionApp as HTMLElement).style.setProperty('--ion-color-primary-tint', accent);\r\n }\r\n\r\n // ============================================\r\n // HEADER COLORS (navigation bar, header-expandable)\r\n // ============================================\r\n\r\n // Base colors\r\n root.style.setProperty('--color-header-surface', headerSurface);\r\n root.style.setProperty('--color-header-content', headerContent);\r\n root.style.setProperty('--color-header-accent', headerAccent);\r\n root.style.setProperty('--color-on-header-accent', onHeaderAccent);\r\n body.style.setProperty('--color-header-surface', headerSurface);\r\n body.style.setProperty('--color-header-content', headerContent);\r\n body.style.setProperty('--color-header-accent', headerAccent);\r\n body.style.setProperty('--color-on-header-accent', onHeaderAccent);\r\n\r\n // Hover/active states for header accent\r\n root.style.setProperty('--color-header-accent-hover', headerAccentHover);\r\n root.style.setProperty('--color-header-accent-active', headerAccentActive);\r\n body.style.setProperty('--color-header-accent-hover', headerAccentHover);\r\n body.style.setProperty('--color-header-accent-active', headerAccentActive);\r\n\r\n // Legacy aliases for backward compatibility\r\n root.style.setProperty('--color-brand-secondary', headerSurface);\r\n root.style.setProperty('--color-secondary-surface', headerSurface);\r\n root.style.setProperty('--color-secondary-content', headerContent);\r\n root.style.setProperty('--header-content-color', headerContent);\r\n root.style.setProperty('--color-brand-secondary-hover', this.generateHoverColor(headerSurface));\r\n root.style.setProperty('--color-secondary-surface-hover', this.generateHoverColor(headerSurface));\r\n root.style.setProperty('--color-brand-secondary-active', this.generateActiveColor(headerSurface));\r\n root.style.setProperty('--color-secondary-surface-active', this.generateActiveColor(headerSurface));\r\n\r\n body.style.setProperty('--color-brand-secondary', headerSurface);\r\n body.style.setProperty('--color-secondary-surface', headerSurface);\r\n body.style.setProperty('--color-secondary-content', headerContent);\r\n body.style.setProperty('--header-content-color', headerContent);\r\n body.style.setProperty('--color-brand-secondary-hover', this.generateHoverColor(headerSurface));\r\n body.style.setProperty('--color-secondary-surface-hover', this.generateHoverColor(headerSurface));\r\n body.style.setProperty('--color-brand-secondary-active', this.generateActiveColor(headerSurface));\r\n body.style.setProperty('--color-secondary-surface-active', this.generateActiveColor(headerSurface));\r\n\r\n if (ionApp) {\r\n (ionApp as HTMLElement).style.setProperty('--color-header-surface', headerSurface);\r\n (ionApp as HTMLElement).style.setProperty('--color-header-content', headerContent);\r\n (ionApp as HTMLElement).style.setProperty('--color-header-accent', headerAccent);\r\n (ionApp as HTMLElement).style.setProperty('--color-on-header-accent', onHeaderAccent);\r\n (ionApp as HTMLElement).style.setProperty('--color-header-accent-hover', headerAccentHover);\r\n (ionApp as HTMLElement).style.setProperty('--color-header-accent-active', headerAccentActive);\r\n (ionApp as HTMLElement).style.setProperty('--color-brand-secondary', headerSurface);\r\n (ionApp as HTMLElement).style.setProperty('--color-secondary-surface', headerSurface);\r\n (ionApp as HTMLElement).style.setProperty('--color-secondary-content', headerContent);\r\n (ionApp as HTMLElement).style.setProperty('--header-content-color', headerContent);\r\n (ionApp as HTMLElement).style.setProperty('--color-brand-secondary-hover', this.generateHoverColor(headerSurface));\r\n (ionApp as HTMLElement).style.setProperty('--color-secondary-surface-hover', this.generateHoverColor(headerSurface));\r\n (ionApp as HTMLElement).style.setProperty('--color-brand-secondary-active', this.generateActiveColor(headerSurface));\r\n (ionApp as HTMLElement).style.setProperty('--color-secondary-surface-active', this.generateActiveColor(headerSurface));\r\n }\r\n\r\n // Also set RGB values for use with rgba() opacity variations\r\n const rgbContent = this.hexToRgb(headerContent);\r\n if (rgbContent) {\r\n const rgbValue = `${rgbContent.r}, ${rgbContent.g}, ${rgbContent.b}`;\r\n root.style.setProperty('--header-content-color-rgb', rgbValue);\r\n root.style.setProperty('--color-secondary-content-rgb', rgbValue);\r\n root.style.setProperty('--color-header-content-rgb', rgbValue);\r\n body.style.setProperty('--header-content-color-rgb', rgbValue);\r\n body.style.setProperty('--color-secondary-content-rgb', rgbValue);\r\n body.style.setProperty('--color-header-content-rgb', rgbValue);\r\n if (ionApp) {\r\n (ionApp as HTMLElement).style.setProperty('--header-content-color-rgb', rgbValue);\r\n (ionApp as HTMLElement).style.setProperty('--color-secondary-content-rgb', rgbValue);\r\n (ionApp as HTMLElement).style.setProperty('--color-header-content-rgb', rgbValue);\r\n }\r\n }\r\n\r\n const rgbOnHeaderAccent = this.hexToRgb(onHeaderAccent);\r\n if (rgbOnHeaderAccent) {\r\n const rgbValue = `${rgbOnHeaderAccent.r}, ${rgbOnHeaderAccent.g}, ${rgbOnHeaderAccent.b}`;\r\n root.style.setProperty('--color-on-header-accent-rgb', rgbValue);\r\n body.style.setProperty('--color-on-header-accent-rgb', rgbValue);\r\n if (ionApp) {\r\n (ionApp as HTMLElement).style.setProperty('--color-on-header-accent-rgb', rgbValue);\r\n }\r\n }\r\n\r\n // Update theme-color meta tag for browser chrome/status bar (PWA/iOS)\r\n const metaThemeColor = document.querySelector('meta[name=\"theme-color\"]');\r\n if (metaThemeColor) {\r\n metaThemeColor.setAttribute('content', headerSurface);\r\n }\r\n\r\n // ============================================\r\n // SIGN-IN PAGE COLORS\r\n // ============================================\r\n root.style.setProperty('--color-signin-content', signInContentColor);\r\n body.style.setProperty('--color-signin-content', signInContentColor);\r\n if (ionApp) {\r\n (ionApp as HTMLElement).style.setProperty('--color-signin-content', signInContentColor);\r\n }\r\n\r\n // Update native StatusBar color (Capacitor - Android only, iOS ignores this)\r\n this.updateNativeStatusBar(headerSurface);\r\n\r\n // console.log('Applied whitelabel colors:', {\r\n // appIconSurface,\r\n // appIconContent,\r\n // accent,\r\n // accentHover,\r\n // accentActive,\r\n // onAccent,\r\n // headerSurface,\r\n // headerContent,\r\n // headerAccent,\r\n // headerAccentHover,\r\n // headerAccentActive,\r\n // onHeaderAccent,\r\n // signInContentColor\r\n // });\r\n }\r\n }\r\n\r\n /**\r\n * Update the native status bar color AND style\r\n * Sets background color (Android) and content style (iOS/Android)\r\n */\r\n private async updateNativeStatusBar(color: string): Promise<void> {\r\n try {\r\n await StatusBar.setBackgroundColor({ color });\r\n\r\n // Calculate and set appropriate style for status bar content\r\n const style = this.getStatusBarStyleForColor(color);\r\n await StatusBar.setStyle({ style });\r\n } catch (e) {\r\n // StatusBar API not available (web browser) or failed\r\n }\r\n }\r\n}\r\n","import { Component, Input, inject } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { WhitelabelService } from '../../services/whitelabel.service';\r\n\r\nexport type LogoVariant = 'full' | 'mark';\r\nexport type LogoSize = 'sm' | 'md' | 'lg' | 'xl';\r\n\r\n/**\r\n * DsLogoComponent\r\n * \r\n * Displays the whitelabeled logo or logomark based on current configuration.\r\n * Automatically pulls logo assets from WhitelabelService.\r\n * \r\n * @example\r\n * Full logo in header:\r\n * ```html\r\n * <ds-logo variant=\"full\" size=\"md\" />\r\n * ```\r\n * \r\n * Logomark for compact spaces:\r\n * ```html\r\n * <ds-logo variant=\"mark\" size=\"sm\" />\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-logo',\r\n standalone: true,\r\n imports: [CommonModule],\r\n styles: [`\r\n :host {\r\n display: flex;\r\n justify-content: flex-start;\r\n line-height: 0;\r\n }\r\n \r\n .logo {\r\n display: block;\r\n object-fit: contain;\r\n width: auto;\r\n /* Base height is set via inline style, desktop adds +4px */\r\n height: var(--logo-height-mobile);\r\n }\r\n \r\n /* Desktop breakpoint: add 4px to logo height */\r\n @media (min-width: 768px) {\r\n .logo {\r\n height: var(--logo-height-desktop);\r\n }\r\n }\r\n `],\r\n template: `\r\n <img \r\n [src]=\"logoSrc\"\r\n [alt]=\"logoAlt\"\r\n class=\"logo\"\r\n [style.--logo-height-mobile.px]=\"effectiveHeight\"\r\n [style.--logo-height-desktop.px]=\"effectiveHeight + 4\"\r\n [style.width]=\"customWidth ? customWidth + 'px' : 'auto'\"\r\n />\r\n `\r\n})\r\nexport class DsLogoComponent {\r\n whitelabelService = inject(WhitelabelService);\r\n \r\n @Input() variant: LogoVariant = 'full';\r\n @Input() size: LogoSize = 'md';\r\n @Input() customHeight?: number;\r\n @Input() customWidth?: number;\r\n \r\n get logoSrc(): string {\r\n const logoUrl = this.whitelabelService.logoUrl();\r\n const logoMarkUrl = this.whitelabelService.logoMarkUrl();\r\n \r\n if (this.variant === 'full') {\r\n // Use logo, fall back to logomark if logo doesn't exist\r\n return logoUrl || logoMarkUrl;\r\n } else {\r\n // Use logomark, fall back to logo if logomark doesn't exist\r\n return logoMarkUrl || logoUrl;\r\n }\r\n }\r\n \r\n get logoAlt(): string {\r\n const alt = this.whitelabelService.logoAlt();\r\n return this.variant === 'full' ? alt : `${alt} logo`;\r\n }\r\n \r\n /** \r\n * Priority: customHeight input > whitelabel config logoHeight > default 32px\r\n */\r\n get effectiveHeight(): number {\r\n return this.customHeight ?? this.whitelabelService.logoHeight();\r\n }\r\n}\r\n\r\n","import { Component, input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n/**\r\n * DsMobileLoaderOverlayComponent\r\n * \r\n * Reusable loader overlay component that displays a spinner centered over its container.\r\n * Designed to overlay images or other content during loading states.\r\n * \r\n * Features:\r\n * - Semi-transparent white background overlay\r\n * - Centered animated spinner\r\n * - Customizable spinner size\r\n * - Absolute positioning to cover parent\r\n * - Accessible with proper z-index stacking\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Basic usage -->\r\n * <div style=\"position: relative;\">\r\n * <img src=\"image.jpg\" alt=\"Content\" />\r\n * @if (isLoading) {\r\n * <ds-mobile-loader-overlay />\r\n * }\r\n * </div>\r\n * \r\n * <!-- With custom spinner size -->\r\n * <div style=\"position: relative;\">\r\n * <div class=\"content\">Loading content...</div>\r\n * <ds-mobile-loader-overlay [spinnerSize]=\"32\" />\r\n * </div>\r\n * \r\n * <!-- Over an image with rounded corners -->\r\n * <div style=\"position: relative; border-radius: 12px; overflow: hidden;\">\r\n * <img src=\"photo.jpg\" />\r\n * <ds-mobile-loader-overlay [borderRadius]=\"12\" />\r\n * </div>\r\n * ```\r\n * \r\n * @notes\r\n * - Parent container must have position: relative for the overlay to work correctly\r\n * - The overlay covers the entire parent element using inset: 0\r\n * - Spinner animation runs continuously at 0.6s per rotation\r\n */\r\n@Component({\r\n selector: 'ds-mobile-loader-overlay',\r\n standalone: true,\r\n imports: [CommonModule],\r\n styleUrls: ['./ds-mobile-loader-overlay.css'],\r\n template: `\r\n <div \r\n class=\"loader-overlay\" \r\n [style.border-radius.px]=\"borderRadius()\"\r\n role=\"status\"\r\n aria-live=\"polite\"\r\n aria-label=\"Loading\">\r\n <div \r\n class=\"spinner\" \r\n [style.width.px]=\"spinnerSize()\"\r\n [style.height.px]=\"spinnerSize()\">\r\n </div>\r\n </div>\r\n `\r\n})\r\nexport class DsMobileLoaderOverlayComponent {\r\n /**\r\n * Size of the spinner in pixels\r\n * @default 24\r\n */\r\n spinnerSize = input<number>(24);\r\n \r\n /**\r\n * Border radius of the overlay in pixels (should match parent's border radius)\r\n * @default 0\r\n */\r\n borderRadius = input<number>(0);\r\n}\r\n","import { input, computed, signal, Directive, OnDestroy } from '@angular/core';\r\nimport { Network } from '@capacitor/network';\r\n\r\n/**\r\n * Content width preset values\r\n * - 'narrow' - 640px max width (reading content)\r\n * - 'standard' - 1024px max width (default)\r\n * - 'wide' - 1440px max width (dashboards)\r\n * - 'full' - 100% width (no max)\r\n */\r\nexport type ContentWidth = 'narrow' | 'standard' | 'wide' | 'full';\r\n\r\n/**\r\n * Network status type\r\n */\r\nexport type NetworkStatus = 'online' | 'offline' | 'unknown';\r\n\r\n/**\r\n * MobilePageBase\r\n * \r\n * Shared base class for mobile page components (ds-mobile-page-main, ds-mobile-page-details).\r\n * Provides consistent content width control and network status monitoring across all page types.\r\n * \r\n * **Padding Strategy:**\r\n * - All pages use 20px horizontal padding globally\r\n * - For tappable lists, use negative margins (e.g., margin: 0 -8px) to create full-width sections\r\n * - This approach simplifies padding management and provides consistency\r\n * \r\n * **Network Monitoring:**\r\n * - Tracks online/offline status via Capacitor Network plugin (native) or browser API (web)\r\n * - Exposes `isOffline()` computed signal for easy consumption by child components\r\n * - Pages can use this to conditionally disable features or show offline indicators\r\n * \r\n * @internal This is a base class and should not be used directly.\r\n */\r\n@Directive()\r\nexport abstract class MobilePageBase implements OnDestroy {\r\n /**\r\n * Shows a loading overlay above page content area.\r\n *\r\n * Non-breaking: defaults to false, so existing pages are unchanged\r\n * until they explicitly opt in.\r\n */\r\n contentLoading = input<boolean>(false);\r\n\r\n /**\r\n * Maximum content width (desktop only)\r\n * \r\n * **Options:**\r\n * - `'narrow'` (640px) - For reading content, forms\r\n * - `'standard'` (1024px) - Default for most pages\r\n * - `'wide'` (1440px) - For dashboards, tables\r\n * - `'full'` - No max-width constraint\r\n * \r\n * **Note:** Only applies on desktop (>= 768px). Mobile is always full width.\r\n * \r\n * @default 'standard'\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Narrow reading layout -->\r\n * <ds-mobile-page-main title=\"Article\" contentWidth=\"narrow\">\r\n * \r\n * <!-- Wide dashboard -->\r\n * <ds-mobile-page-main title=\"Dashboard\" contentWidth=\"wide\">\r\n * ```\r\n */\r\n contentWidth = input<ContentWidth>('standard');\r\n\r\n /**\r\n * Resolved max-width value (computed)\r\n * Maps preset values to pixel values\r\n * \r\n * @internal\r\n */\r\n protected maxWidthValue = computed(() => {\r\n const w = this.contentWidth();\r\n \r\n const widthMap: Record<ContentWidth, string> = {\r\n 'narrow': '640px',\r\n 'standard': '1024px',\r\n 'wide': '1440px',\r\n 'full': '100%'\r\n };\r\n \r\n return widthMap[w];\r\n });\r\n\r\n /**\r\n * Network status signal\r\n * Tracks current online/offline state\r\n * \r\n * @internal\r\n */\r\n protected networkStatus = signal<NetworkStatus>('unknown');\r\n\r\n /**\r\n * Is the device currently offline?\r\n * Public computed signal for consumption by child components and pages\r\n * \r\n * @example\r\n * ```typescript\r\n * // In a page component\r\n * @ViewChild(DsMobilePageMainComponent) pageComponent!: DsMobilePageMainComponent;\r\n * \r\n * get isOffline() {\r\n * return this.pageComponent?.isOffline();\r\n * }\r\n * ```\r\n */\r\n public isOffline = computed(() => this.networkStatus() === 'offline');\r\n\r\n /**\r\n * Is the device currently online?\r\n * Public computed signal for consumption by child components and pages\r\n */\r\n public isOnline = computed(() => this.networkStatus() === 'online');\r\n\r\n /**\r\n * Network listener ID for Capacitor Network plugin\r\n * Used to clean up listener on destroy\r\n * \r\n * @internal\r\n */\r\n private networkListenerId?: string;\r\n\r\n /**\r\n * Browser API event handlers\r\n * Stored as class properties for proper cleanup\r\n * \r\n * @internal\r\n */\r\n private handleOnline = () => {\r\n this.networkStatus.set('online');\r\n };\r\n\r\n private handleOffline = () => {\r\n this.networkStatus.set('offline');\r\n };\r\n\r\n /**\r\n * Initialize network status monitoring\r\n * Uses Capacitor Network plugin for native apps, browser API for web\r\n * \r\n * @param isNative - Whether running on native platform (iOS/Android)\r\n * @internal Called by child components in ngAfterViewInit\r\n */\r\n protected async initNetworkMonitoring(isNative: boolean): Promise<void> {\r\n if (isNative) {\r\n try {\r\n // Try to use Capacitor Network plugin for native apps\r\n const status = await Network.getStatus();\r\n this.networkStatus.set(status.connected ? 'online' : 'offline');\r\n \r\n // Listen for network status changes\r\n const listener = await Network.addListener('networkStatusChange', (status: any) => {\r\n this.networkStatus.set(status.connected ? 'online' : 'offline');\r\n });\r\n \r\n // Store listener ID for cleanup\r\n this.networkListenerId = 'networkStatusChange';\r\n } catch (error) {\r\n // Fallback to browser API if Capacitor plugin fails\r\n console.warn('Capacitor Network plugin not available, falling back to browser API', error);\r\n this.initBrowserNetworkMonitoring();\r\n }\r\n } else {\r\n // Use browser API for web/PWA\r\n this.initBrowserNetworkMonitoring();\r\n }\r\n }\r\n\r\n /**\r\n * Initialize browser-based network monitoring\r\n * Uses navigator.onLine and window events\r\n * \r\n * @internal\r\n */\r\n private initBrowserNetworkMonitoring(): void {\r\n // Set initial status from browser\r\n this.networkStatus.set(navigator.onLine ? 'online' : 'offline');\r\n \r\n // Listen for online/offline events\r\n window.addEventListener('online', this.handleOnline);\r\n window.addEventListener('offline', this.handleOffline);\r\n }\r\n\r\n /**\r\n * Cleanup network monitoring listeners\r\n * Called automatically on component destroy\r\n */\r\n ngOnDestroy(): void {\r\n // Clean up Capacitor listener if it exists\r\n if (this.networkListenerId) {\r\n Network.removeAllListeners().catch((err: any) => {\r\n console.warn('Failed to remove network listeners', err);\r\n });\r\n }\r\n \r\n // Clean up browser event listeners\r\n window.removeEventListener('online', this.handleOnline);\r\n window.removeEventListener('offline', this.handleOffline);\r\n }\r\n}\r\n","import { \r\n Directive, \r\n Output, \r\n EventEmitter, \r\n HostListener, \r\n Input,\r\n OnDestroy \r\n} from '@angular/core';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\n\r\n/**\r\n * DsMobileLongPressDirective\r\n * \r\n * A reusable directive for handling long press interactions on mobile devices.\r\n * Provides haptic feedback and prevents long press when touching interactive elements.\r\n * \r\n * Features:\r\n * - Configurable duration and movement threshold\r\n * - Automatic haptic feedback (with fallback to navigator.vibrate)\r\n * - Excludes interactive elements (buttons, links, inputs)\r\n * - Handles touchmove cancellation\r\n * - Context menu support (right-click on desktop)\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Basic usage -->\r\n * <div dsMobileLongPress (longPress)=\"handleLongPress()\">\r\n * Long press me\r\n * </div>\r\n * \r\n * <!-- Custom duration and threshold -->\r\n * <div \r\n * dsMobileLongPress \r\n * [longPressDuration]=\"800\"\r\n * [moveThreshold]=\"15\"\r\n * [excludeSelectors]=\"'button, a, .no-longpress'\"\r\n * (longPress)=\"showContextMenu()\">\r\n * Custom long press\r\n * </div>\r\n * ```\r\n */\r\n@Directive({\r\n selector: '[dsMobileLongPress]',\r\n standalone: true\r\n})\r\nexport class DsMobileLongPressDirective implements OnDestroy {\r\n /**\r\n * Duration in milliseconds to trigger long press\r\n * @default 500\r\n */\r\n @Input() longPressDuration = 500;\r\n\r\n /**\r\n * Maximum movement in pixels before canceling long press\r\n * @default 10\r\n */\r\n @Input() moveThreshold = 10;\r\n\r\n /**\r\n * CSS selectors to exclude from long press detection\r\n * @default 'button, a, input, select, textarea, [role=\"button\"]'\r\n */\r\n @Input() excludeSelectors = 'button, a, input, select, textarea, [role=\"button\"]';\r\n\r\n /**\r\n * Haptic feedback style (Light, Medium, Heavy)\r\n * @default ImpactStyle.Medium\r\n */\r\n @Input() hapticStyle: ImpactStyle = ImpactStyle.Medium;\r\n\r\n /**\r\n * Enable/disable haptic feedback\r\n * @default true\r\n */\r\n @Input() enableHaptics = true;\r\n\r\n /**\r\n * Emits when long press is triggered\r\n */\r\n @Output() longPress = new EventEmitter<void>();\r\n\r\n /**\r\n * Emits when long press starts (timer begins)\r\n */\r\n @Output() longPressStart = new EventEmitter<void>();\r\n\r\n /**\r\n * Emits when long press is cancelled\r\n */\r\n @Output() longPressCancel = new EventEmitter<void>();\r\n\r\n private longPressTimer: any = null;\r\n private longPressTriggered = false;\r\n private touchStartX = 0;\r\n private touchStartY = 0;\r\n\r\n /**\r\n * Handle touch start for long press detection\r\n */\r\n @HostListener('touchstart', ['$event'])\r\n handleTouchStart(event: TouchEvent): void {\r\n // Don't start long press if touching interactive child elements\r\n // But allow if the closest match is the host element itself (where the directive is attached)\r\n const target = event.target as HTMLElement;\r\n const closestExcluded = target.closest(this.excludeSelectors);\r\n const hostElement = (event.currentTarget as HTMLElement);\r\n \r\n // Only exclude if we found an excluded element AND it's not the host itself\r\n if (closestExcluded && closestExcluded !== hostElement) {\r\n return;\r\n }\r\n\r\n this.longPressTriggered = false;\r\n this.touchStartX = event.touches[0].clientX;\r\n this.touchStartY = event.touches[0].clientY;\r\n\r\n // Emit start event\r\n this.longPressStart.emit();\r\n\r\n // Start long press timer\r\n this.longPressTimer = setTimeout(async () => {\r\n this.longPressTriggered = true;\r\n this.longPress.emit();\r\n\r\n // Haptic feedback for long press\r\n if (this.enableHaptics) {\r\n await this.triggerHaptics();\r\n }\r\n }, this.longPressDuration);\r\n }\r\n\r\n /**\r\n * Handle touch end to clear long press timer\r\n */\r\n @HostListener('touchend', ['$event'])\r\n handleTouchEnd(event: TouchEvent): void {\r\n if (this.longPressTimer) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n \r\n if (!this.longPressTriggered) {\r\n this.longPressCancel.emit();\r\n }\r\n }\r\n\r\n // Prevent normal click if long press was triggered\r\n if (this.longPressTriggered) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.longPressTriggered = false;\r\n }\r\n }\r\n\r\n /**\r\n * Handle touch move to cancel long press if moved too much\r\n */\r\n @HostListener('touchmove', ['$event'])\r\n handleTouchMove(event: TouchEvent): void {\r\n if (!this.longPressTimer) return;\r\n\r\n const touch = event.touches[0];\r\n const deltaX = Math.abs(touch.clientX - this.touchStartX);\r\n const deltaY = Math.abs(touch.clientY - this.touchStartY);\r\n\r\n // Cancel long press if moved too far\r\n if (deltaX > this.moveThreshold || deltaY > this.moveThreshold) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n this.longPressTriggered = false;\r\n this.longPressCancel.emit();\r\n }\r\n }\r\n\r\n /**\r\n * Handle context menu (right-click on desktop) to trigger long press action\r\n */\r\n @HostListener('contextmenu', ['$event'])\r\n handleContextMenu(event: Event): void {\r\n event.preventDefault();\r\n this.longPress.emit();\r\n }\r\n\r\n /**\r\n * Trigger haptic feedback\r\n */\r\n private async triggerHaptics(): Promise<void> {\r\n try {\r\n await Haptics.impact({ style: this.hapticStyle });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n // Map haptic styles to vibration durations\r\n const vibrationMap = {\r\n [ImpactStyle.Light]: 30,\r\n [ImpactStyle.Medium]: 50,\r\n [ImpactStyle.Heavy]: 80\r\n };\r\n navigator.vibrate(vibrationMap[this.hapticStyle] || 50);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Cleanup on destroy\r\n */\r\n ngOnDestroy(): void {\r\n if (this.longPressTimer) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n }\r\n }\r\n}\r\n","import {\r\n Component,\r\n input,\r\n output,\r\n computed,\r\n signal,\r\n PLATFORM_ID,\r\n inject,\r\n ElementRef,\r\n AfterViewInit,\r\n} from '@angular/core';\r\nimport { CommonModule, isPlatformBrowser } from '@angular/common';\r\nimport { DsMobileLongPressDirective } from '../shared/directives/long-press.directive';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobileListItemComponent\r\n *\r\n * A versatile, reusable list item component for mobile applications.\r\n * Supports both interactive and non-interactive modes with flexible content projection.\r\n *\r\n * Features:\r\n * - Interactive mode with click and long-press support\r\n * - Pseudo-element background extends 8px beyond bounds (no negative margins needed)\r\n * - Flexible content slots (leading, main, trailing)\r\n * - Optional structured inputs for common use cases (title, subtitle)\r\n * - Accessibility features (focus states, ARIA attributes)\r\n * - Disabled and loading states\r\n *\r\n * This component serves as the foundation for specialized list item types like posts,\r\n * notifications, messages, contacts, and other list content.\r\n *\r\n * @example\r\n * ```html\r\n * <!-- Simple structured usage -->\r\n * <ds-mobile-list-item\r\n * title=\"Document Title\"\r\n * subtitle=\"Supporting text\"\r\n * [interactive]=\"true\"\r\n * (itemClick)=\"handleClick()\">\r\n *\r\n * <ds-icon content-leading name=\"document\" />\r\n * </ds-mobile-list-item>\r\n *\r\n * <!-- Flexible custom usage -->\r\n * <ds-mobile-list-item\r\n * [interactive]=\"true\"\r\n * (itemClick)=\"handleClick()\"\r\n * (longPress)=\"showContextMenu()\">\r\n *\r\n * <div content-leading>\r\n * <ds-avatar initials=\"JD\" />\r\n * </div>\r\n *\r\n * <div content-main>\r\n * <h3>Custom Content</h3>\r\n * <p>Full control over layout and styling</p>\r\n * </div>\r\n *\r\n * <button content-trailing (click)=\"handleAction($event)\">\r\n * Action\r\n * </button>\r\n * </ds-mobile-list-item>\r\n *\r\n * <!-- Non-interactive read-only -->\r\n * <ds-mobile-list-item\r\n * title=\"Read-only Item\"\r\n * subtitle=\"No interaction\">\r\n * <ds-icon content-leading name=\"info\" />\r\n * </ds-mobile-list-item>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-list-item',\r\n standalone: true,\r\n imports: [CommonModule, DsIconButtonComponent],\r\n hostDirectives: [\r\n {\r\n directive: DsMobileLongPressDirective,\r\n outputs: ['longPress'],\r\n },\r\n ],\r\n host: {\r\n '[class.interactive]': 'interactive() && !disabled()',\r\n '[class.disabled]': 'disabled()',\r\n '[class.loading]': 'loading()',\r\n '[class.no-divider]': '!showDivider()',\r\n '[class.no-leading-content]': '!hasLeadingContent()',\r\n '[class.variant-compact]': 'variant() === \"compact\"',\r\n '[class.align-top]': 'align() === \"top\"',\r\n '[class.align-center]': 'align() === \"center\"',\r\n '[class.align-bottom]': 'align() === \"bottom\"',\r\n '[attr.role]': 'interactive() ? \"button\" : null',\r\n '[attr.tabindex]': 'interactive() && !disabled() ? \"0\" : null',\r\n '[attr.aria-disabled]': 'disabled() ? \"true\" : null',\r\n '[style.--leading-size]': 'leadingSize()',\r\n '[style.--interactive-offset]': 'interactiveOffset()',\r\n '[style.--divider-spacing]': 'dividerSpacing()',\r\n '(click)': 'handleClick($event)',\r\n '(keydown.enter)': 'handleKeyDown($event)',\r\n '(keydown.space)': 'handleKeyDown($event)',\r\n '(longPress)': 'handleLongPress()',\r\n },\r\n styles: [\r\n `\r\n :host {\r\n display: block;\r\n position: relative;\r\n padding: var(--item-padding-top, 12px) 0\r\n var(--item-padding-bottom, 12px) 0;\r\n box-sizing: border-box;\r\n /* CSS variables defined at host level for use by children and pseudo-elements */\r\n --leading-size: 32px;\r\n --content-gap: 12px;\r\n --interactive-offset: 8px;\r\n }\r\n\r\n /* Divider line on host */\r\n :host::after {\r\n content: '';\r\n position: absolute;\r\n bottom: 0;\r\n left: calc(var(--leading-size) + var(--content-gap));\r\n right: 0;\r\n height: 1px;\r\n background: var(--border-color-default, #e5e5e5);\r\n z-index: 1;\r\n display: var(--divider-display, block);\r\n }\r\n\r\n /* Hide divider when no-divider class is present */\r\n :host(.no-divider)::after {\r\n display: none;\r\n }\r\n\r\n /* Adjust divider when no leading content */\r\n :host(.no-leading-content)::after {\r\n left: 0;\r\n }\r\n\r\n .list-item-inner {\r\n display: flex;\r\n flex-direction: row;\r\n align-items: flex-start;\r\n gap: var(--content-gap);\r\n position: relative;\r\n }\r\n\r\n :host(.align-center) .list-item-inner {\r\n align-items: center;\r\n }\r\n\r\n :host(.align-bottom) .list-item-inner {\r\n align-items: flex-end;\r\n }\r\n\r\n /* Pseudo-element for interactive background */\r\n :host(.interactive) .list-item-inner::before {\r\n content: '';\r\n position: absolute;\r\n top: calc(-1 * var(--interactive-offset));\r\n left: calc(-1 * var(--interactive-offset));\r\n right: calc(-1 * var(--interactive-offset));\r\n bottom: calc(-1 * var(--interactive-offset));\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n border-radius: 16px;\r\n z-index: -1;\r\n pointer-events: none;\r\n }\r\n\r\n /* Interactive states */\r\n :host(.interactive) {\r\n cursor: pointer;\r\n }\r\n\r\n /* Hover state (desktop only) */\r\n @media (hover: hover) and (pointer: fine) {\r\n :host(.interactive):hover .list-item-inner::before {\r\n background: var(--color-background-neutral-primary-hover, #f5f5f5);\r\n }\r\n }\r\n\r\n /* Active state */\r\n :host(.interactive):active .list-item-inner::before {\r\n background: var(--color-background-neutral-primary-hover, #f5f5f5);\r\n }\r\n\r\n /* Focus visible for keyboard navigation */\r\n :host(.interactive):focus-visible {\r\n outline: none;\r\n }\r\n\r\n :host(.interactive):focus-visible .list-item-inner::before {\r\n outline: 2px solid var(--color-brand-primary, #5d5fef);\r\n outline-offset: 2px;\r\n }\r\n\r\n /* Disabled state */\r\n :host(.disabled) {\r\n opacity: 0.5;\r\n pointer-events: none;\r\n }\r\n\r\n /* Loading state */\r\n :host(.loading) {\r\n pointer-events: none;\r\n }\r\n\r\n /* Variants */\r\n :host(.variant-compact) .list-item-inner {\r\n gap: 8px;\r\n }\r\n\r\n /* Content slots */\r\n .content-leading {\r\n flex-shrink: 0;\r\n width: var(--leading-size);\r\n height: var(--leading-size);\r\n display: flex;\r\n align-items: flex-start;\r\n justify-content: center;\r\n position: relative;\r\n z-index: 1;\r\n }\r\n\r\n :host(.align-center) .content-leading {\r\n align-items: center;\r\n }\r\n\r\n :host(.align-bottom) .content-leading {\r\n align-items: flex-end;\r\n }\r\n\r\n .content-main {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n position: relative;\r\n z-index: 1;\r\n justify-content: flex-start;\r\n }\r\n\r\n :host(.align-center) .content-main {\r\n justify-content: center;\r\n }\r\n\r\n :host(.align-bottom) .content-main {\r\n justify-content: flex-end;\r\n }\r\n\r\n .content-trailing {\r\n flex-shrink: 0;\r\n display: flex;\r\n align-items: flex-start;\r\n position: relative;\r\n z-index: 1;\r\n }\r\n\r\n /* Structured content styles */\r\n .structured-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm, 14px);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-primary, #202227);\r\n margin: 0;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n\r\n .structured-subtitle {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm, 14px);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-secondary, #545b66);\r\n margin: 0;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n\r\n /* Desktop more actions button - using ds-icon-button */\r\n .desktop-more-button::ng-deep button {\r\n border-radius: 50% !important;\r\n }\r\n `,\r\n ],\r\n template: `\r\n <div class=\"list-item-inner\">\r\n @if (hasLeadingContent()) {\r\n <div class=\"content-leading\">\r\n <ng-content select=\"[content-leading]\" />\r\n </div>\r\n }\r\n\r\n <div class=\"content-main\">\r\n @if (title()) {\r\n <h3 class=\"structured-title\">{{ title() }}</h3>\r\n } @if (subtitle()) {\r\n <p class=\"structured-subtitle\">{{ subtitle() }}</p>\r\n }\r\n\r\n <ng-content select=\"[content-main]\" />\r\n <ng-content />\r\n </div>\r\n\r\n <div class=\"content-trailing\">\r\n @if (interactive() && shouldShowMoreButton()) {\r\n <ds-icon-button\r\n class=\"desktop-more-button\"\r\n icon=\"remixMoreFill\"\r\n variant=\"secondary\"\r\n size=\"sm\"\r\n (clicked)=\"handleMoreButtonClick($event)\"\r\n aria-label=\"More options\"\r\n >\r\n </ds-icon-button>\r\n }\r\n <ng-content select=\"[content-trailing]\" />\r\n </div>\r\n </div>\r\n `,\r\n})\r\nexport class DsMobileListItemComponent implements AfterViewInit {\r\n private platformId = inject(PLATFORM_ID);\r\n private elementRef = inject(ElementRef);\r\n\r\n /**\r\n * Detect if viewport is desktop size\r\n * Use viewport width for breakpoint detection (show button on tablet and above)\r\n */\r\n isDesktop = signal<boolean>(false);\r\n\r\n constructor() {\r\n if (isPlatformBrowser(this.platformId)) {\r\n // Show button on tablet breakpoint and above (768px+)\r\n const isDesktopViewport = window.innerWidth >= 768;\r\n\r\n // console.log('[ListItem] Desktop detection:', {\r\n // innerWidth: window.innerWidth,\r\n // isDesktopViewport\r\n // });\r\n\r\n this.isDesktop.set(isDesktopViewport);\r\n\r\n // Listen for window resize to update detection\r\n window.addEventListener('resize', () => {\r\n const newIsDesktop = window.innerWidth >= 768;\r\n if (newIsDesktop !== this.isDesktop()) {\r\n // console.log('[ListItem] Viewport changed, updating desktop detection:', newIsDesktop);\r\n this.isDesktop.set(newIsDesktop);\r\n }\r\n });\r\n }\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n // Check if there's actual content in the leading slot\r\n this.checkLeadingContent();\r\n }\r\n\r\n /**\r\n * Check if leading content slot has actual content projected\r\n */\r\n private checkLeadingContent(): void {\r\n if (!isPlatformBrowser(this.platformId)) {\r\n return;\r\n }\r\n\r\n const hostElement = this.elementRef.nativeElement;\r\n const leadingElements = hostElement.querySelectorAll('[content-leading]');\r\n \r\n // Check if any element with content-leading attribute exists and has content\r\n const hasContent = Array.from(leadingElements).some((el: any) => {\r\n return el.childNodes.length > 0 || el.textContent?.trim().length > 0;\r\n });\r\n\r\n this.hasLeadingContent.set(hasContent);\r\n }\r\n\r\n /**\r\n * CSS size value for the leading content area (e.g., '32px', '40px', '48px')\r\n * Defaults to '32px' for standard list item avatars/icons\r\n */\r\n leadingSize = input<string>('32px');\r\n\r\n /**\r\n * Display variant\r\n * - undefined (default) - Standard display\r\n * - 'compact' - Compact display for nested/related items\r\n */\r\n variant = input<'compact' | undefined>(undefined);\r\n\r\n /**\r\n * Vertical alignment of leading and main content slots\r\n * - 'top' - Align to top (default)\r\n * - 'center' - Align to center\r\n * - 'bottom' - Align to bottom\r\n */\r\n align = input<'top' | 'center' | 'bottom'>('top');\r\n\r\n /**\r\n * Whether the list item is interactive (clickable and long-pressable)\r\n * When true, adds interactive background, cursor pointer, and touch handlers\r\n */\r\n interactive = input<boolean>(false);\r\n\r\n /**\r\n * Whether the list item is disabled\r\n * Disables all interactions and reduces opacity\r\n */\r\n disabled = input<boolean>(false);\r\n\r\n /**\r\n * Whether the list item is in a loading state\r\n * Disables interactions but maintains full opacity\r\n */\r\n loading = input<boolean>(false);\r\n\r\n /**\r\n * Enable long-press interaction when interactive is true\r\n * Set to false to disable long-press but keep click\r\n */\r\n enableLongPress = input<boolean>(true);\r\n\r\n /**\r\n * Show \"more actions\" button on desktop for items with long-press enabled\r\n * @deprecated Use `moreActions` instead. Kept for backwards compatibility.\r\n * @default true\r\n */\r\n showDesktopMoreButton = input<boolean>(true);\r\n\r\n /**\r\n * Unified toggle for contextual actions (more button + long press).\r\n * - `true` — more button visible on **all** breakpoints, long press enabled\r\n * - `false` — more button hidden, long press suppressed\r\n * - `undefined` (default) — falls back to legacy `enableLongPress` + `showDesktopMoreButton` + desktop check\r\n */\r\n moreActions = input<boolean | undefined>(undefined);\r\n\r\n /**\r\n * Resolved visibility of the more-actions button.\r\n * When `moreActions` is set it takes precedence; otherwise legacy inputs + breakpoint apply.\r\n */\r\n shouldShowMoreButton = computed(() => {\r\n const ma = this.moreActions();\r\n if (ma !== undefined) return ma;\r\n return this.enableLongPress() && this.showDesktopMoreButton() && this.isDesktop();\r\n });\r\n\r\n /**\r\n * Offset distance for the interactive background pseudo-element\r\n * Extends the background beyond the content bounds\r\n * @default '8px'\r\n */\r\n interactiveOffset = input<string>('8px');\r\n\r\n /**\r\n * Optional structured title text\r\n * Provides a simple way to add title without custom markup\r\n */\r\n title = input<string>();\r\n\r\n /**\r\n * Optional structured subtitle text\r\n * Provides a simple way to add subtitle without custom markup\r\n */\r\n subtitle = input<string>();\r\n\r\n /**\r\n * Whether to show the divider line below the list item\r\n * Automatically hidden on last-child and detail variant\r\n * @default true\r\n */\r\n showDivider = input<boolean>(true);\r\n\r\n /**\r\n * Spacing around the divider (top and bottom padding)\r\n * @default '4px'\r\n */\r\n dividerSpacing = input<string>('4px');\r\n\r\n /**\r\n * Emits when the list item is clicked (if interactive and not disabled)\r\n */\r\n itemClick = output<void>();\r\n\r\n /**\r\n * Emits when the desktop more actions button is clicked\r\n * This is separate from longPress to give more control to parent components\r\n * Typically, you can use (longPress) for both mobile and desktop actions\r\n */\r\n moreButtonClick = output<Event>();\r\n\r\n /**\r\n * Track if long press was triggered to prevent click\r\n */\r\n private longPressTriggered = false;\r\n\r\n /**\r\n * Check if leading content slot has content\r\n * Dynamically updated after view initialization\r\n */\r\n hasLeadingContent = signal<boolean>(true);\r\n\r\n /**\r\n * Check if trailing content slot has content\r\n * Always true to maintain consistent layout\r\n */\r\n hasTrailingContent = computed(() => true);\r\n\r\n /**\r\n * Handle click events\r\n */\r\n handleClick(event: Event): void {\r\n // console.log('[ListItem] Click event fired', {\r\n // interactive: this.interactive(),\r\n // disabled: this.disabled(),\r\n // loading: this.loading(),\r\n // longPressTriggered: this.longPressTriggered,\r\n // target: event.target\r\n // });\r\n\r\n if (!this.interactive() || this.disabled() || this.loading()) {\r\n // console.log('[ListItem] Click ignored - not interactive or disabled/loading');\r\n return;\r\n }\r\n\r\n // Don't emit click if it came from an interactive child element\r\n // (but not the host element itself)\r\n const target = event.target as HTMLElement;\r\n const closestInteractive = target.closest(\r\n 'button, a, input, select, textarea, [role=\"button\"]'\r\n );\r\n\r\n // Only block if the interactive element is a REAL child action (like a button in trailing slot),\r\n // but NOT if it's just the host itself or something inside leading/main that shouldn't block.\r\n if (closestInteractive && closestInteractive !== event.currentTarget) {\r\n // If the target is inside content-leading or content-main, we generally want to allow the click\r\n const isInsidePrimaryContent = !!target.closest('[content-leading], [content-main], .structured-title, .structured-subtitle');\r\n \r\n if (!isInsidePrimaryContent) {\r\n // console.log('[ListItem] Click ignored - came from interactive child in trailing/unknown slot:', closestInteractive);\r\n return;\r\n }\r\n }\r\n\r\n if (!this.longPressTriggered) {\r\n // console.log('[ListItem] Emitting itemClick');\r\n this.itemClick.emit();\r\n } else {\r\n // console.log('[ListItem] Click ignored - long press was triggered');\r\n }\r\n\r\n this.longPressTriggered = false;\r\n }\r\n\r\n /**\r\n * Handle keyboard events (Enter/Space)\r\n */\r\n handleKeyDown(event: Event): void {\r\n if (!this.interactive() || this.disabled() || this.loading()) {\r\n return;\r\n }\r\n\r\n event.preventDefault();\r\n this.itemClick.emit();\r\n }\r\n\r\n /**\r\n * Handle long press events from the directive\r\n * Set the flag to prevent the subsequent click event\r\n */\r\n handleLongPress(): void {\r\n if (this.moreActions() === false) return;\r\n this.longPressTriggered = true;\r\n setTimeout(() => {\r\n this.longPressTriggered = false;\r\n }, 100);\r\n }\r\n\r\n /**\r\n * Handle desktop more button click\r\n * Stops propagation to prevent triggering itemClick\r\n * Emits moreButtonClick for parent components to handle\r\n */\r\n handleMoreButtonClick(event: Event): void {\r\n // console.log('[ListItem] Desktop more button clicked');\r\n\r\n // Stop propagation to prevent triggering itemClick\r\n event.stopPropagation();\r\n event.preventDefault();\r\n\r\n // Emit the more button click event\r\n this.moreButtonClick.emit(event);\r\n }\r\n}\r\n","import { Component, input, output } from '@angular/core';\r\nimport { DsMobileListItemComponent } from '../list-item/ds-mobile-list-item';\r\n\r\n/**\r\n * DsMobileActionListItemComponent\r\n *\r\n * Specialized list item for action sheets and menus.\r\n * Wraps ds-mobile-list-item with action-specific styling:\r\n * - Vertically centered content\r\n * - Interactive by default\r\n * - No dividers (controlled per-item)\r\n *\r\n * @example\r\n * ```html\r\n * <ds-mobile-action-list-item\r\n * title=\"Edit\"\r\n * [showDivider]=\"true\"\r\n * (itemClick)=\"handleEdit()\">\r\n * <ds-icon content-leading name=\"remixEditLine\" size=\"20px\" />\r\n * </ds-mobile-action-list-item>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-action-list-item',\r\n standalone: true,\r\n imports: [DsMobileListItemComponent],\r\n template: `\r\n <ds-mobile-list-item [title]=\"title()\" [interactive]=\"true\" [enableLongPress]=\"false\" [showDivider]=\"showDivider()\" [disabled]=\"disabled()\" (itemClick)=\"itemClick.emit()\">\r\n <div class=\"action-icon-wrapper\" content-leading>\r\n <ng-content select=\"[action-icon]\" />\r\n </div>\r\n\r\n <div content-trailing>\r\n <ng-content select=\"[content-trailing]\" />\r\n </div>\r\n </ds-mobile-list-item>\r\n `,\r\n styles: [\r\n `\r\n /* Center all content vertically for action items */\r\n :host ::ng-deep ds-mobile-list-item .list-item-inner {\r\n align-items: center;\r\n }\r\n\r\n /* Center icon within leading slot */\r\n :host ::ng-deep ds-mobile-list-item .content-leading {\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n\r\n /* Wrapper div must fill parent height and center icon */\r\n :host ::ng-deep .action-icon-wrapper {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n width: 100%;\r\n height: 100%;\r\n }\r\n\r\n /* Remove gap from content-main for single-line actions */\r\n :host ::ng-deep ds-mobile-list-item .content-main {\r\n gap: 0;\r\n justify-content: center;\r\n }\r\n\r\n /* Remove blue focus border/ring and set Ionic variables */\r\n :host {\r\n outline: none;\r\n --background-focused: transparent;\r\n --background-activated: transparent;\r\n -webkit-tap-highlight-color: transparent;\r\n }\r\n\r\n :host ::ng-deep ds-mobile-list-item {\r\n outline: none;\r\n }\r\n `,\r\n ],\r\n})\r\nexport class DsMobileActionListItemComponent {\r\n /**\r\n * Action title text\r\n */\r\n title = input.required<string>();\r\n\r\n /**\r\n * Whether to show divider below item\r\n * @default false\r\n */\r\n showDivider = input<boolean>(false);\r\n\r\n /**\r\n * Whether the action is disabled\r\n * @default false\r\n */\r\n disabled = input<boolean>(false);\r\n\r\n /**\r\n * Emits when the action item is clicked\r\n */\r\n itemClick = output<void>();\r\n}\r\n","import { Component, CUSTOM_ELEMENTS_SCHEMA, OnInit, OnDestroy, ElementRef, inject } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { Keyboard } from '@capacitor/keyboard';\r\n\r\n/**\r\n * DsMobileBottomSheetWrapperComponent\r\n * \r\n * A wrapper component that provides common layout styling for all bottom sheets.\r\n * Handles safe area insets, provides consistent layout structure, and automatic\r\n * keyboard handling using the same approach as modal base.\r\n * \r\n * Features:\r\n * - Automatic keyboard push-up behavior (same as MobileModalBase)\r\n * - Auto-height for bottom sheets\r\n * - Safe area inset handling\r\n * - Consistent styling across all bottom sheets\r\n * - Only responds to keyboard when this bottom sheet is the top-most modal\r\n * \r\n * Usage:\r\n * Wrap your bottom sheet content with this component using ng-content projection.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-bottom-sheet-wrapper>\r\n * <!-- Your bottom sheet content here -->\r\n * </ds-mobile-bottom-sheet-wrapper>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-bottom-sheet-wrapper',\r\n standalone: true,\r\n imports: [CommonModule],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n template: `\r\n <div class=\"bottom-sheet-wrapper\">\r\n <ng-content></ng-content>\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n display: block;\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n background: #ffffff; /* Explicit fallback for iOS */\r\n height: auto;\r\n }\r\n \r\n .bottom-sheet-wrapper {\r\n display: flex;\r\n flex-direction: column;\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n background: #ffffff; /* Explicit fallback for iOS */\r\n padding-bottom: calc(env(safe-area-inset-bottom, 0px) + 16px);\r\n overflow: hidden;\r\n width: 100%;\r\n height: auto;\r\n min-height: unset;\r\n }\r\n\r\n :host ::ng-deep .view-container:not(.is-animating) {\r\n height: auto !important;\r\n min-height: 0 !important;\r\n }\r\n `]\r\n})\r\nexport class DsMobileBottomSheetWrapperComponent implements OnInit, OnDestroy {\r\n private modalController = inject(ModalController);\r\n \r\n constructor(private elementRef: ElementRef) {}\r\n\r\n ngOnInit(): void {\r\n // Set up keyboard listeners using the same approach as MobileModalBase\r\n this.setupKeyboardListeners();\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.cleanupKeyboardListeners();\r\n }\r\n\r\n /**\r\n * Set up keyboard event listeners to adjust bottom sheet position\r\n * Uses --keyboard-height-sheet variable (separate from modal's --keyboard-height)\r\n * Only responds if this bottom sheet is the currently active (top-most) modal\r\n */\r\n private setupKeyboardListeners(): void {\r\n Keyboard.addListener('keyboardWillShow', async (info) => {\r\n // Check if this bottom sheet is the top-most modal\r\n const topModal = await this.modalController.getTop();\r\n const thisModal = this.getModalElement();\r\n \r\n if (topModal !== thisModal) {\r\n console.log('[BottomSheetWrapper] Keyboard event ignored - not top modal');\r\n return; // Not the active modal, ignore keyboard event\r\n }\r\n \r\n console.log('[BottomSheetWrapper] Keyboard showing, height:', info.keyboardHeight);\r\n \r\n // Use a separate CSS variable for bottom sheets to avoid conflicts with modals\r\n document.documentElement.style.setProperty('--keyboard-height-sheet', `${info.keyboardHeight}px`);\r\n \r\n // Add class to the modal element for additional styling control\r\n if (thisModal) {\r\n thisModal.classList.add('keyboard-visible-sheet');\r\n }\r\n }).catch(() => {\r\n console.log('[BottomSheetWrapper] Keyboard plugin not available (web)');\r\n });\r\n\r\n Keyboard.addListener('keyboardWillHide', async () => {\r\n // Check if this bottom sheet is the top-most modal\r\n const topModal = await this.modalController.getTop();\r\n const thisModal = this.getModalElement();\r\n \r\n if (topModal !== thisModal) {\r\n console.log('[BottomSheetWrapper] Keyboard hide event ignored - not top modal');\r\n return; // Not the active modal, ignore keyboard event\r\n }\r\n \r\n console.log('[BottomSheetWrapper] Keyboard hiding');\r\n \r\n // Reset keyboard height for bottom sheets\r\n document.documentElement.style.setProperty('--keyboard-height-sheet', '0px');\r\n \r\n // Remove keyboard class\r\n if (thisModal) {\r\n thisModal.classList.remove('keyboard-visible-sheet');\r\n }\r\n }).catch(() => {\r\n console.log('[BottomSheetWrapper] Keyboard plugin not available (web)');\r\n });\r\n }\r\n\r\n /**\r\n * Clean up keyboard event listeners\r\n */\r\n private cleanupKeyboardListeners(): void {\r\n Keyboard.removeAllListeners().catch(() => {\r\n // Keyboard plugin not available\r\n });\r\n }\r\n\r\n /**\r\n * Get the parent ion-modal element\r\n */\r\n private getModalElement(): HTMLIonModalElement | null {\r\n let element = this.elementRef.nativeElement.parentElement;\r\n while (element) {\r\n if (element.tagName === 'ION-MODAL') {\r\n return element as HTMLIonModalElement;\r\n }\r\n element = element.parentElement;\r\n }\r\n return null;\r\n }\r\n}\r\n\r\n","import { Component, Input, computed, signal } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsMobileActionListItemComponent } from '../action-list-item/ds-mobile-action-list-item';\r\nimport { DsMobileBottomSheetWrapperComponent } from './ds-mobile-bottom-sheet-wrapper';\r\n\r\nexport interface ActionResult {\r\n action: string;\r\n}\r\n\r\nexport interface ActionItem {\r\n action: string;\r\n title: string;\r\n icon: string;\r\n destructive?: boolean;\r\n subtitle?: string; // Optional subtitle text (e.g., current language)\r\n showChevron?: boolean; // Show chevron indicator for navigation\r\n flagIcon?: string; // Optional flag icon path (e.g., for language selection)\r\n}\r\n\r\nexport interface ActionGroup {\r\n actions: ActionItem[];\r\n}\r\n\r\n/**\r\n * DsMobileActionsBottomSheetComponent\r\n *\r\n * Generic bottom sheet for displaying action lists.\r\n * Supports custom action groups or preset content actions (posts/comments).\r\n * Action groups are automatically separated by full-width dividers.\r\n *\r\n * @example Custom actions with auto-height (recommended to avoid cropping)\r\n * ```typescript\r\n * const sheet = await this.modalController.create({\r\n * component: DsMobileActionsBottomSheetComponent,\r\n * componentProps: {\r\n * customActionGroups: [\r\n * {\r\n * actions: [\r\n * { action: 'profile', title: 'Min profil', icon: 'remixUser3Line' },\r\n * { action: 'settings', title: 'Indstillinger', icon: 'remixSettings3Line' }\r\n * ]\r\n * },\r\n * {\r\n * actions: [\r\n * { action: 'logout', title: 'Log ud', icon: 'remixLogoutBoxLine', destructive: true }\r\n * ]\r\n * }\r\n * ]\r\n * },\r\n * breakpoints: [0, 1],\r\n * initialBreakpoint: 1,\r\n * handle: true,\r\n * cssClass: 'auto-height'\r\n * });\r\n *\r\n * const result = await sheet.onWillDismiss();\r\n * if (result.data?.action) {\r\n * // Handle the action\r\n * }\r\n * ```\r\n *\r\n * @example Preset content actions\r\n * ```typescript\r\n * const sheet = await this.modalController.create({\r\n * component: DsMobileActionsBottomSheetComponent,\r\n * componentProps: {\r\n * isOwnContent: false\r\n * },\r\n * breakpoints: [0, 1],\r\n * initialBreakpoint: 1,\r\n * handle: true,\r\n * cssClass: 'auto-height'\r\n * });\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-actions-bottom-sheet',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent, DsMobileActionListItemComponent, DsMobileBottomSheetWrapperComponent],\r\n template: `\r\n <ds-mobile-bottom-sheet-wrapper>\r\n <!-- Actions List -->\r\n <div class=\"actions-list\">\r\n @for (group of actionGroups(); track $index; let isLast = $last) {\r\n <!-- Action Group -->\r\n <div class=\"action-group\">\r\n @for (actionItem of group.actions; track actionItem.action; let isLastInGroup = $last) {\r\n <ds-mobile-action-list-item\r\n [title]=\"actionItem.title\"\r\n [showDivider]=\"!isLastInGroup\"\r\n [class.destructive]=\"actionItem.destructive\"\r\n (itemClick)=\"selectAction(actionItem.action)\"\r\n >\r\n <ds-icon action-icon [name]=\"actionItem.icon\" size=\"20px\" [class.destructive-icon]=\"actionItem.destructive\" />\r\n </ds-mobile-action-list-item>\r\n }\r\n </div>\r\n\r\n <!-- Full-width divider between groups -->\r\n @if (!isLast) {\r\n <div class=\"action-group-divider\"></div>\r\n } }\r\n </div>\r\n </ds-mobile-bottom-sheet-wrapper>\r\n `,\r\n styles: [\r\n `\r\n :host {\r\n display: block;\r\n height: auto;\r\n }\r\n\r\n /* Actions List */\r\n .actions-list {\r\n display: flex;\r\n flex-direction: column;\r\n padding-top: 16px;\r\n }\r\n\r\n /* Action Group - padding on groups instead of list */\r\n .action-group {\r\n display: flex;\r\n flex-direction: column;\r\n padding: 0 16px; /* Horizontal padding on each group */\r\n }\r\n\r\n /* Override default background color to transparent so hover state is visible */\r\n /* Need ::ng-deep because ds-mobile-list-item uses :host styles internally */\r\n ::ng-deep ds-mobile-action-list-item ds-mobile-list-item {\r\n --color-background-primary: transparent;\r\n --color-background-neutral-primary-hover: var(--color-background-neutral-secondary, #f5f5f5);\r\n }\r\n\r\n /* Ensure the interactive background is visible */\r\n ::ng-deep ds-mobile-action-list-item ds-mobile-list-item .list-item-inner::before {\r\n z-index: 0 !important;\r\n }\r\n\r\n /* Ensure content is above the background */\r\n ::ng-deep ds-mobile-action-list-item ds-mobile-list-item .content-leading,\r\n ::ng-deep ds-mobile-action-list-item ds-mobile-list-item .content-main,\r\n ::ng-deep ds-mobile-action-list-item ds-mobile-list-item .content-trailing {\r\n position: relative;\r\n z-index: 1;\r\n }\r\n\r\n /* Hide divider on last list item using CSS variable */\r\n ds-mobile-action-list-item:last-of-type {\r\n --divider-display: none;\r\n }\r\n\r\n /* Destructive action styling */\r\n ds-mobile-action-list-item.destructive {\r\n --text-color-default-primary: var(--color-error-base, #ef4444);\r\n }\r\n\r\n .destructive-icon {\r\n color: var(--color-error-base, #ef4444);\r\n }\r\n\r\n /* Full-width divider between action groups */\r\n .action-group-divider {\r\n height: 1px;\r\n background: var(--color-border-subtle, #e5e5e5);\r\n margin: 8px 0;\r\n }\r\n `,\r\n ],\r\n})\r\nexport class DsMobileActionsBottomSheetComponent {\r\n /**\r\n * Custom action groups to display (overrides isOwnContent)\r\n */\r\n @Input() customActionGroups?: ActionGroup[];\r\n\r\n /**\r\n * Whether this content belongs to the current user (for preset content actions)\r\n */\r\n @Input() isOwnContent: boolean = false;\r\n\r\n /**\r\n * Computed action groups - uses custom groups if provided, otherwise falls back to preset content actions\r\n */\r\n actionGroups = computed<ActionGroup[]>(() => {\r\n // Use custom action groups if provided\r\n if (this.customActionGroups) {\r\n return this.customActionGroups;\r\n }\r\n\r\n // Otherwise fall back to preset content actions\r\n if (this.isOwnContent) {\r\n // Own content: Group 1 (Edit, Delete) + Group 2 (Like, Reply)\r\n return [\r\n {\r\n actions: [\r\n {\r\n action: 'edit',\r\n title: 'Rediger',\r\n icon: 'remixEditLine',\r\n destructive: false,\r\n },\r\n {\r\n action: 'delete',\r\n title: 'Slet',\r\n icon: 'remixDeleteBinLine',\r\n destructive: true,\r\n },\r\n ],\r\n },\r\n {\r\n actions: [\r\n {\r\n action: 'like',\r\n title: 'Synes om',\r\n icon: 'remixHeart3Line',\r\n destructive: false,\r\n },\r\n {\r\n action: 'reply',\r\n title: 'Svar',\r\n icon: 'remixReplyLine',\r\n destructive: false,\r\n },\r\n ],\r\n },\r\n ];\r\n } else {\r\n // Other users' content: Group 1 (Like, Reply)\r\n return [\r\n {\r\n actions: [\r\n {\r\n action: 'like',\r\n title: 'Synes om',\r\n icon: 'remixHeart3Line',\r\n destructive: false,\r\n },\r\n {\r\n action: 'reply',\r\n title: 'Svar',\r\n icon: 'remixReplyLine',\r\n destructive: false,\r\n },\r\n ],\r\n },\r\n ];\r\n }\r\n });\r\n\r\n constructor(private modalController: ModalController) {}\r\n\r\n /**\r\n * Handle action selection and dismiss with result\r\n */\r\n selectAction(action: string): void {\r\n this.modalController.dismiss({ action } as ActionResult, 'select');\r\n }\r\n}\r\n\r\n// Legacy exports for backwards compatibility\r\nexport { DsMobileActionsBottomSheetComponent as DsMobilePostActionsBottomSheetComponent };\r\nexport { DsMobileActionsBottomSheetComponent as DsMobileCommentActionsBottomSheetComponent };\r\nexport type { ActionResult as PostActionResult };\r\nexport type { ActionResult as CommentActionResult };\r\n","/**\r\n * Disable pointer events for Ionic's internal modal shadow layer.\r\n *\r\n * The .modal-shadow element is rendered inside ion-modal's Shadow DOM and can\r\n * intercept backdrop taps even when visually hidden.\r\n */\r\nexport function disableModalShadowPointerEvents(modal: HTMLIonModalElement): void {\r\n const applyFix = () => {\r\n const modalShadow = modal.shadowRoot?.querySelector<HTMLElement>('.modal-shadow');\r\n if (!modalShadow) {\r\n return;\r\n }\r\n\r\n modalShadow.style.setProperty('pointer-events', 'none', 'important');\r\n modalShadow.style.setProperty('box-shadow', 'none', 'important');\r\n };\r\n\r\n applyFix();\r\n\r\n if (!modal.shadowRoot) {\r\n return;\r\n }\r\n\r\n const observer = new MutationObserver(() => {\r\n applyFix();\r\n });\r\n\r\n observer.observe(modal.shadowRoot, {\r\n childList: true,\r\n subtree: true,\r\n attributes: true,\r\n attributeFilter: ['class', 'style'],\r\n });\r\n\r\n modal.addEventListener(\r\n 'ionModalDidDismiss',\r\n () => {\r\n observer.disconnect();\r\n },\r\n { once: true }\r\n );\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { ComponentRef } from '@angular/core';\r\nimport { disableModalShadowPointerEvents } from './modal-shadow-fix';\r\n\r\n/**\r\n * Configuration options for the bottom sheet modal\r\n */\r\nexport interface BottomSheetOptions {\r\n /** The component to display in the bottom sheet */\r\n component: any;\r\n /** Component props to pass to the modal content */\r\n componentProps?: { [key: string]: any };\r\n /** Breakpoints for the bottom sheet (0-1 values representing percentage of screen) */\r\n breakpoints?: number[];\r\n /** Initial breakpoint to open the sheet at */\r\n initialBreakpoint?: number;\r\n /** Show/hide the drag handle */\r\n handle?: boolean;\r\n /** Custom CSS class for styling */\r\n cssClass?: string | string[];\r\n /** Whether backdrop dismisses the modal */\r\n backdropDismiss?: boolean;\r\n /** Backdrop opacity (0-1) */\r\n backdropOpacity?: number;\r\n /** Enable backdrop blur effect */\r\n backdropBlur?: boolean;\r\n /** Keyboard close behavior */\r\n keyboardClose?: boolean;\r\n /** Auto-height mode: sheet sizes to content instead of using fixed breakpoints */\r\n autoHeight?: boolean;\r\n}\r\n\r\n/**\r\n * DsMobileBottomSheetService\r\n * \r\n * Service for creating and managing Ionic 6 bottom sheet modals.\r\n * Based on the Ionic blog article: https://ionic.io/blog/5-examples-of-the-new-ionic-6-bottom-sheet-modal\r\n * \r\n * Features:\r\n * - Multiple breakpoints for snap-to positions\r\n * - Customizable initial height\r\n * - Optional drag handle\r\n * - Backdrop blur effect\r\n * - Custom styling support\r\n * \r\n * @example\r\n * ```typescript\r\n * constructor(private bottomSheet: DsMobileBottomSheetService) {}\r\n * \r\n * async openSheet() {\r\n * const sheet = await this.bottomSheet.create({\r\n * component: PostCreateComponent,\r\n * breakpoints: [0, 0.5, 0.9],\r\n * initialBreakpoint: 0.5,\r\n * handle: true\r\n * });\r\n * \r\n * const result = await sheet.onWillDismiss();\r\n * console.log('Sheet dismissed with:', result.data);\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class DsMobileBottomSheetService {\r\n constructor(private modalController: ModalController) {}\r\n\r\n /**\r\n * Create and present a bottom sheet modal\r\n * \r\n * @param options Configuration options for the bottom sheet\r\n * @returns Promise that resolves to the modal instance\r\n */\r\n async create(options: BottomSheetOptions): Promise<HTMLIonModalElement> {\r\n const {\r\n component,\r\n componentProps = {},\r\n breakpoints = [0, 0.5, 0.9],\r\n initialBreakpoint = 0.5,\r\n handle = true,\r\n cssClass = '',\r\n backdropDismiss = true,\r\n backdropOpacity,\r\n backdropBlur = false,\r\n keyboardClose = true,\r\n autoHeight = false\r\n } = options;\r\n\r\n // Build CSS classes array\r\n const cssClasses = ['ds-bottom-sheet'];\r\n if (backdropBlur) {\r\n cssClasses.push('ds-bottom-sheet--blur');\r\n }\r\n if (autoHeight) {\r\n cssClasses.push('auto-height');\r\n }\r\n if (typeof cssClass === 'string' && cssClass) {\r\n cssClasses.push(cssClass);\r\n } else if (Array.isArray(cssClass)) {\r\n cssClasses.push(...cssClass);\r\n }\r\n\r\n const modal = await this.modalController.create({\r\n component,\r\n componentProps,\r\n breakpoints: autoHeight ? undefined : breakpoints,\r\n initialBreakpoint: autoHeight ? undefined : initialBreakpoint,\r\n handle: autoHeight ? false : handle,\r\n cssClass: cssClasses,\r\n backdropDismiss,\r\n keyboardClose,\r\n showBackdrop: true,\r\n canDismiss: backdropDismiss,\r\n // Remove animation delay for instant appearance\r\n animated: true,\r\n enterAnimation: undefined, // Use default but we'll customize via CSS\r\n leaveAnimation: undefined,\r\n ...(backdropOpacity !== undefined && { \r\n cssClass: [...cssClasses, 'ds-bottom-sheet--custom-backdrop']\r\n })\r\n });\r\n\r\n // Apply custom backdrop opacity if specified\r\n if (backdropOpacity !== undefined) {\r\n modal.style.setProperty('--backdrop-opacity', backdropOpacity.toString());\r\n }\r\n\r\n // Add ESC key listener to dismiss the modal\r\n const escKeyHandler = (event: KeyboardEvent) => {\r\n if (event.key === 'Escape') {\r\n modal.dismiss(undefined, 'escape');\r\n }\r\n };\r\n \r\n // Add listener when modal is presented\r\n modal.addEventListener('ionModalDidPresent', () => {\r\n document.addEventListener('keydown', escKeyHandler);\r\n });\r\n \r\n // Remove listener when modal is dismissed\r\n modal.addEventListener('ionModalDidDismiss', () => {\r\n document.removeEventListener('keydown', escKeyHandler);\r\n });\r\n\r\n await modal.present();\r\n disableModalShadowPointerEvents(modal);\r\n \r\n // Don't wait - return immediately so component can try to focus\r\n // while still in user gesture context\r\n return modal;\r\n }\r\n\r\n /**\r\n * Dismiss all open modals\r\n */\r\n async dismiss(data?: any, role?: string): Promise<boolean> {\r\n return this.modalController.dismiss(data, role);\r\n }\r\n\r\n /**\r\n * Get the top-most modal overlay\r\n */\r\n async getTop(): Promise<HTMLIonModalElement | undefined> {\r\n return this.modalController.getTop();\r\n }\r\n}\r\n\r\n","import { Component, Input, Output, EventEmitter, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { IonHeader, IonToolbar, IonTitle, IonButtons } from '@ionic/angular/standalone';\r\nimport { DsButtonComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobileBottomSheetHeaderComponent\r\n *\r\n * Reusable header component for bottom sheets with left button, center title, and right button.\r\n * Styling matches the language switcher pattern (source of truth).\r\n *\r\n * Usage:\r\n * ```html\r\n * <ds-mobile-bottom-sheet-header\r\n * title=\"Sheet Title\"\r\n * leftButtonLabel=\"Tilbage\"\r\n * rightButtonLabel=\"Færdig\"\r\n * [rightButtonDisabled]=\"!isValid()\"\r\n * (leftButtonClick)=\"handleCancel()\"\r\n * (rightButtonClick)=\"handleConfirm()\">\r\n * </ds-mobile-bottom-sheet-header>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-bottom-sheet-header',\r\n standalone: true,\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n imports: [\r\n CommonModule,\r\n IonHeader,\r\n IonToolbar,\r\n IonTitle,\r\n IonButtons,\r\n DsButtonComponent\r\n ],\r\n template: `\r\n <ion-header>\r\n <ion-toolbar>\r\n <ion-buttons slot=\"start\">\r\n <ds-button \r\n variant=\"secondary\" \r\n size=\"sm\" \r\n (clicked)=\"leftButtonClick.emit()\">\r\n {{ leftButtonLabel }}\r\n </ds-button>\r\n </ion-buttons>\r\n <ion-title>{{ title }}</ion-title>\r\n <ion-buttons slot=\"end\">\r\n <ds-button \r\n variant=\"primary\" \r\n size=\"sm\" \r\n [disabled]=\"rightButtonDisabled\"\r\n (clicked)=\"rightButtonClick.emit()\">\r\n {{ rightButtonLabel }}\r\n </ds-button>\r\n </ion-buttons>\r\n </ion-toolbar>\r\n </ion-header>\r\n `,\r\n styles: [`\r\n /* Styles copied 1:1 from language switcher (lines 200-249) */\r\n ion-header {\r\n box-shadow: none;\r\n }\r\n\r\n /* Override Ionic's default iOS header border */\r\n :host ::ng-deep .header-ios ion-toolbar:last-of-type {\r\n --border-width: 0 !important;\r\n }\r\n\r\n ion-toolbar {\r\n --background: var(--color-background-neutral-primary, #ffffff);\r\n --border-width: 0 !important;\r\n --border-color: var(--color-border-default, #e5e7eb) !important;\r\n --padding-top: 12px;\r\n --padding-bottom: 8px;\r\n --min-height: 56px;\r\n border-bottom: 1px solid var(--color-border-default, #e5e7eb) !important;\r\n }\r\n\r\n /* Ensure the border is applied correctly */\r\n ion-toolbar::part(native) {\r\n border-bottom: 1px solid var(--color-border-default, #e5e7eb) !important;\r\n }\r\n\r\n ion-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n line-height: 22px;\r\n letter-spacing: -0.4px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n\r\n /* Make buttons pill-shaped - both start and end */\r\n ion-buttons[slot='start'] ds-button {\r\n --border-radius: 100px;\r\n }\r\n\r\n ion-buttons[slot='start'] ds-button::ng-deep button {\r\n border-radius: 100px;\r\n }\r\n\r\n ion-buttons[slot='end'] ds-button {\r\n --border-radius: 100px;\r\n }\r\n\r\n ion-buttons[slot='end'] ds-button::ng-deep button {\r\n border-radius: 100px;\r\n }\r\n `]\r\n})\r\nexport class DsMobileBottomSheetHeaderComponent {\r\n /**\r\n * Center title text\r\n */\r\n @Input() title!: string;\r\n\r\n /**\r\n * Left button label\r\n * @default 'Tilbage'\r\n */\r\n @Input() leftButtonLabel: string = 'Tilbage';\r\n\r\n /**\r\n * Right button label\r\n * @default 'Færdig'\r\n */\r\n @Input() rightButtonLabel: string = 'Færdig';\r\n\r\n /**\r\n * Disable right button\r\n * @default false\r\n */\r\n @Input() rightButtonDisabled: boolean = false;\r\n\r\n /**\r\n * Emitted when left button is clicked\r\n */\r\n @Output() leftButtonClick = new EventEmitter<void>();\r\n\r\n /**\r\n * Emitted when right button is clicked\r\n */\r\n @Output() rightButtonClick = new EventEmitter<void>();\r\n}\r\n","import { Component, input, computed } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DomSanitizer, SafeHtml } from '@angular/platform-browser';\r\n\r\n/**\r\n * DsMobileIllustrationComponent\r\n * \r\n * A component that displays illustrations with dynamic whitelabel color adaptation.\r\n * Inlines SVG and uses CSS variables to adapt colors to your theme.\r\n * \r\n * **Features:**\r\n * - Predefined variants (post, inquiry) for common empty states\r\n * - Automatic color adaptation using CSS variables\r\n * - Preserves all SVG details (textures, filters, gradients, shadows)\r\n * - White radial gradient overlay for depth effect\r\n * - Configurable size\r\n * \r\n * **Color Adaptation:**\r\n * The SVGs use the `--color-accent` CSS variable for the main page colors.\r\n * All texture details, shadows, and effects are preserved.\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Using predefined variant -->\r\n * <ds-mobile-illustration variant=\"post\" />\r\n * \r\n * <!-- Using predefined variant with custom size -->\r\n * <ds-mobile-illustration variant=\"inquiry\" size=\"150px\" />\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-illustration',\r\n standalone: true,\r\n imports: [CommonModule],\r\n styles: [`\r\n :host {\r\n display: inline-block;\r\n position: relative;\r\n }\r\n \r\n .illustration-container {\r\n position: relative;\r\n width: var(--illustration-size);\r\n height: var(--illustration-size);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n .illustration-svg {\r\n width: 100%;\r\n height: 100%;\r\n display: block;\r\n position: relative;\r\n z-index: 1;\r\n }\r\n \r\n .illustration-svg :deep(svg) {\r\n width: 100%;\r\n height: 100%;\r\n display: block;\r\n }\r\n \r\n .illustration-gradient-overlay {\r\n position: absolute;\r\n top: 0;\r\n left: 0;\r\n right: 0;\r\n bottom: 0;\r\n background: radial-gradient(125% 100% at center top, transparent 15%, white 80%);\r\n opacity: 1;\r\n pointer-events: none;\r\n z-index: 2;\r\n }\r\n `],\r\n template: `\r\n <div \r\n class=\"illustration-container\"\r\n role=\"img\"\r\n [attr.aria-label]=\"alt()\"\r\n [style.--illustration-size]=\"size()\">\r\n <div class=\"illustration-svg\" [innerHTML]=\"svgContent()\"></div>\r\n <div class=\"illustration-gradient-overlay\"></div>\r\n </div>\r\n `\r\n})\r\nexport class DsMobileIllustrationComponent {\r\n /**\r\n * Predefined illustration variant\r\n * Available variants: 'post', 'inquiry', 'confirmation'\r\n */\r\n variant = input<'post' | 'inquiry' | 'confirmation'>('post');\r\n \r\n /**\r\n * Illustration size (width and height)\r\n * @default '120px'\r\n */\r\n size = input<string>('120px');\r\n\r\n /**\r\n * Accessible description for the illustration\r\n */\r\n alt = input<string>('');\r\n \r\n constructor(private sanitizer: DomSanitizer) {}\r\n \r\n /**\r\n * Inline SVG content for each variant\r\n */\r\n private svgMap: Record<string, string> = {\r\n 'post': `<svg viewBox=\"0 0 344 300\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><style>.illustration-primary{fill:var(--color-accent,#6B5FF5);}</style><g filter=\"url(#filter0_n_3889_10866)\"><g filter=\"url(#filter1_iiii_3889_10866)\"><path d=\"M128.894 29.437C132.332 13.2359 148.247 2.89554 164.447 6.33719L314.615 38.2392C330.826 41.6832 341.182 57.6224 337.742 73.8344L333.497 93.8393L295.98 270.644C292.541 286.85 276.617 297.191 260.413 293.741L110.256 261.77C94.0517 258.32 83.7032 242.385 87.1425 226.178L128.894 29.437Z\" class=\"illustration-primary\"/><path d=\"M128.894 29.437C132.332 13.2359 148.247 2.89554 164.447 6.33719L314.615 38.2392C330.826 41.6832 341.182 57.6224 337.742 73.8344L333.497 93.8393L295.98 270.644C292.541 286.85 276.617 297.191 260.413 293.741L110.256 261.77C94.0517 258.32 83.7032 242.385 87.1425 226.178L128.894 29.437Z\" fill=\"url(#paint0_linear_3889_10866)\"/></g><rect width=\"23.9872\" height=\"24\" rx=\"11.9936\" transform=\"matrix(0.978231 0.207519 -0.208206 0.978085 164.344 44.0215)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"73.2211\" height=\"12\" rx=\"6\" transform=\"matrix(0.978231 0.207519 -0.208206 0.978085 191.531 55.6562)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"119.815\" height=\"10.6931\" rx=\"5.34656\" transform=\"matrix(0.978231 0.207519 -0.208206 0.978085 157.594 79.082)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"70.3126\" height=\"10.6931\" rx=\"5.34656\" transform=\"matrix(0.978231 0.207519 -0.208206 0.978085 154.484 93.4844)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"101.001\" height=\"10.6931\" rx=\"5.34656\" transform=\"matrix(0.978231 0.207519 -0.208206 0.978085 151.344 108.045)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"140.874\" height=\"97.9525\" rx=\"18\" transform=\"matrix(0.978231 0.207519 -0.208206 0.978085 146.484 131.383)\" fill=\"black\" fill-opacity=\"0.5\"/><g filter=\"url(#filter2_iiii_3889_10866)\"><path d=\"M6.24706 73.9096C2.80889 57.7085 13.1487 41.7772 29.3457 38.3199L179.482 6.27234C195.69 2.81267 211.623 13.1535 215.064 29.3654L219.31 49.3702L256.834 226.173C260.273 242.38 249.926 258.315 233.722 261.766L83.5677 293.746C67.3633 297.198 51.4385 286.857 47.9991 270.65L6.24706 73.9096Z\" class=\"illustration-primary\"/></g><rect width=\"23.9872\" height=\"24\" rx=\"11.9936\" transform=\"matrix(0.977991 -0.208645 0.207959 0.978137 41.4062 69.4883)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"73.2211\" height=\"12\" rx=\"6\" transform=\"matrix(0.977991 -0.208645 0.207959 0.978137 70.9688 69.0527)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"119.815\" height=\"10.6931\" rx=\"5.34656\" transform=\"matrix(0.977991 -0.208645 0.207959 0.978137 49.5156 104.264)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"70.3126\" height=\"10.6931\" rx=\"5.34656\" transform=\"matrix(0.977991 -0.208645 0.207959 0.978137 52.5312 118.684)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"101.001\" height=\"10.6931\" rx=\"5.34656\" transform=\"matrix(0.977991 -0.208645 0.207959 0.978137 55.5938 133.262)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"140.874\" height=\"97.9525\" rx=\"18\" transform=\"matrix(0.977991 -0.208645 0.207959 0.978137 60.6562 156.555)\" fill=\"black\" fill-opacity=\"0.5\"/></g><defs><filter id=\"filter0_n_3889_10866\" x=\"5.58594\" y=\"5.60547\" width=\"332.816\" height=\"288.805\" filterUnits=\"userSpaceOnUse\" color-interpolation-filters=\"sRGB\"><feFlood flood-opacity=\"0\" result=\"BackgroundImageFix\"/><feBlend mode=\"normal\" in=\"SourceGraphic\" in2=\"BackgroundImageFix\" result=\"shape\"/><feTurbulence type=\"fractalNoise\" baseFrequency=\"0.25 0.25\" stitchTiles=\"stitch\" numOctaves=\"3\" result=\"noise\" seed=\"9191\" /><feColorMatrix in=\"noise\" type=\"luminanceToAlpha\" result=\"alphaNoise\" /><feComponentTransfer in=\"alphaNoise\" result=\"coloredNoise1\"><feFuncA type=\"discrete\" tableValues=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \"/></feComponentTransfer><feComposite operator=\"in\" in2=\"shape\" in=\"coloredNoise1\" result=\"noise1Clipped\" /><feComponentTransfer in=\"alphaNoise\" result=\"coloredNoise2\"><feFuncA type=\"discrete\" tableValues=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \"/></feComponentTransfer><feComposite operator=\"in\" in2=\"shape\" in=\"coloredNoise2\" result=\"noise2Clipped\" /><feFlood flood-color=\"rgba(0, 0, 0, 0.25)\" result=\"color1Flood\" /><feComposite operator=\"in\" in2=\"noise1Clipped\" in=\"color1Flood\" result=\"color1\" /><feFlood flood-color=\"rgba(255, 255, 255, 0.25)\" result=\"color2Flood\" /><feComposite operator=\"in\" in2=\"noise2Clipped\" in=\"color2Flood\" result=\"color2\" /><feMerge result=\"effect1_noise_3889_10866\"><feMergeNode in=\"shape\" /><feMergeNode in=\"color1\" /><feMergeNode in=\"color2\" /></feMerge></filter><filter id=\"filter1_iiii_3889_10866\" x=\"86.4844\" y=\"-10.3237\" width=\"251.918\" height=\"344.729\" filterUnits=\"userSpaceOnUse\" color-interpolation-filters=\"sRGB\"><feFlood flood-opacity=\"0\" result=\"BackgroundImageFix\"/><feBlend mode=\"normal\" in=\"SourceGraphic\" in2=\"BackgroundImageFix\" result=\"shape\"/><feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/><feOffset dy=\"2\"/><feGaussianBlur stdDeviation=\"2\"/><feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\"/><feColorMatrix type=\"matrix\" values=\"0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.25 0\"/><feBlend mode=\"normal\" in2=\"shape\" result=\"effect1_innerShadow_3889_10866\"/><feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/><feOffset dy=\"-2\"/><feGaussianBlur stdDeviation=\"2\"/><feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\"/><feColorMatrix type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0\"/><feBlend mode=\"normal\" in2=\"effect1_innerShadow_3889_10866\" result=\"effect2_innerShadow_3889_10866\"/><feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/><feOffset dy=\"40\"/><feGaussianBlur stdDeviation=\"40\"/><feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\"/><feColorMatrix type=\"matrix\" values=\"0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.1 0\"/><feBlend mode=\"normal\" in2=\"effect2_innerShadow_3889_10866\" result=\"effect3_innerShadow_3889_10866\"/><feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/><feOffset dy=\"-16\"/><feGaussianBlur stdDeviation=\"40\"/><feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\"/><feColorMatrix type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0\"/><feBlend mode=\"normal\" in2=\"effect3_innerShadow_3889_10866\" result=\"effect4_innerShadow_3889_10866\"/></filter><filter id=\"filter2_iiii_3889_10866\" x=\"5.58594\" y=\"-10.3945\" width=\"251.906\" height=\"344.805\" filterUnits=\"userSpaceOnUse\" color-interpolation-filters=\"sRGB\"><feFlood flood-opacity=\"0\" result=\"BackgroundImageFix\"/><feBlend mode=\"normal\" in=\"SourceGraphic\" in2=\"BackgroundImageFix\" result=\"shape\"/><feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/><feOffset dy=\"2\"/><feGaussianBlur stdDeviation=\"2\"/><feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\"/><feColorMatrix type=\"matrix\" values=\"0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.25 0\"/><feBlend mode=\"normal\" in2=\"shape\" result=\"effect1_innerShadow_3889_10866\"/><feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/><feOffset dy=\"-2\"/><feGaussianBlur stdDeviation=\"2\"/><feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\"/><feColorMatrix type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0\"/><feBlend mode=\"normal\" in2=\"effect1_innerShadow_3889_10866\" result=\"effect2_innerShadow_3889_10866\"/><feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/><feOffset dy=\"40\"/><feGaussianBlur stdDeviation=\"40\"/><feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\"/><feColorMatrix type=\"matrix\" values=\"0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.1 0\"/><feBlend mode=\"normal\" in2=\"effect2_innerShadow_3889_10866\" result=\"effect3_innerShadow_3889_10866\"/><feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/><feOffset dy=\"-16\"/><feGaussianBlur stdDeviation=\"40\"/><feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\"/><feColorMatrix type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0\"/><feBlend mode=\"normal\" in2=\"effect3_innerShadow_3889_10866\" result=\"effect4_innerShadow_3889_10866\"/></filter><linearGradient id=\"paint0_linear_3889_10866\" x1=\"111.488\" y1=\"162.199\" x2=\"335.745\" y2=\"98.2353\" gradientUnits=\"userSpaceOnUse\"><stop/><stop offset=\"1\" stop-opacity=\"0\"/></linearGradient></defs></svg>`,\r\n 'inquiry': `<svg viewBox=\"0 0 344 300\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><style>.illustration-primary{fill:var(--color-accent,#6B5FF5);}</style><g filter=\"url(#filter0_n_3889_10915)\"><g filter=\"url(#filter1_iiii_3889_10915)\"><path d=\"M128.909 29.437C132.347 13.2359 148.262 2.89554 164.463 6.33719L314.63 38.2392C330.841 41.6832 341.197 57.6224 337.757 73.8344L333.512 93.8393L295.995 270.644C292.556 286.85 276.632 297.191 260.428 293.741L110.272 261.77C94.0673 258.32 83.7188 242.385 87.1581 226.178L128.909 29.437Z\" class=\"illustration-primary\"/><path d=\"M128.909 29.437C132.347 13.2359 148.262 2.89554 164.463 6.33719L314.63 38.2392C330.841 41.6832 341.197 57.6224 337.757 73.8344L333.512 93.8393L295.995 270.644C292.556 286.85 276.632 297.191 260.428 293.741L110.272 261.77C94.0673 258.32 83.7188 242.385 87.1581 226.178L128.909 29.437Z\" fill=\"url(#paint0_linear_3889_10915)\"/></g><rect width=\"112.101\" height=\"10.6931\" rx=\"5.34657\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 173.844 55.5391)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"10.6763\" height=\"10.6931\" rx=\"5.33815\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 158.188 52.2148)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"130.785\" height=\"10.6931\" rx=\"5.34657\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 168.297 81.6992)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"10.6763\" height=\"10.6931\" rx=\"5.33815\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 152.641 78.3652)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"112.101\" height=\"10.6931\" rx=\"5.34657\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 162.75 107.842)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"10.6763\" height=\"10.6931\" rx=\"5.33815\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 147.094 104.516)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"96.0867\" height=\"10.6931\" rx=\"5.34657\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 157.203 133.99)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"96.0867\" height=\"10.6931\" rx=\"5.34657\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 140.562 212.443)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"10.6763\" height=\"10.6931\" rx=\"5.33815\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 141.547 130.666)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"10.6763\" height=\"10.6931\" rx=\"5.33815\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 124.891 209.117)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"125.447\" height=\"10.6931\" rx=\"5.34657\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 151.656 160.141)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"10.6763\" height=\"10.6931\" rx=\"5.33815\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 135.984 156.816)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"85.4104\" height=\"10.6931\" rx=\"5.34657\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 146.109 186.293)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"10.6763\" height=\"10.6931\" rx=\"5.33815\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 130.438 182.967)\" fill=\"black\" fill-opacity=\"0.5\"/><g filter=\"url(#filter2_iiii_3889_10915)\"><path d=\"M6.24705 73.9095C2.80888 57.7085 13.1487 41.7772 29.3457 38.3199L179.482 6.27234C195.69 2.81268 211.623 13.1536 215.064 29.3654L219.31 49.3702L256.834 226.173C260.273 242.38 249.926 258.315 233.722 261.766L83.5677 293.746C67.3633 297.198 51.4385 286.857 47.9991 270.65L6.24705 73.9095Z\" class=\"illustration-primary\"/></g><rect width=\"112.101\" height=\"10.6931\" rx=\"5.34656\" transform=\"matrix(0.978064 -0.208304 0.207618 0.97821 57.8906 79.4453)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"10.6763\" height=\"10.6931\" rx=\"5.33815\" transform=\"matrix(0.978064 -0.208304 0.207618 0.97821 42.2344 82.791)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"130.785\" height=\"10.6931\" rx=\"5.34656\" transform=\"matrix(0.978064 -0.208304 0.207618 0.97821 63.4531 105.605)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"10.6763\" height=\"10.6931\" rx=\"5.33815\" transform=\"matrix(0.978064 -0.208304 0.207618 0.97821 47.7812 108.941)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"112.101\" height=\"10.6931\" rx=\"5.34656\" transform=\"matrix(0.978064 -0.208304 0.207618 0.97821 69 131.746)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"10.6763\" height=\"10.6931\" rx=\"5.33815\" transform=\"matrix(0.978064 -0.208304 0.207618 0.97821 53.3281 135.092)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"96.0867\" height=\"10.6931\" rx=\"5.34656\" transform=\"matrix(0.978064 -0.208304 0.207618 0.97821 74.5469 157.896)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"96.0867\" height=\"10.6931\" rx=\"5.34656\" transform=\"matrix(0.978064 -0.208304 0.207618 0.97821 91.2031 236.348)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"10.6763\" height=\"10.6931\" rx=\"5.33815\" transform=\"matrix(0.978064 -0.208304 0.207618 0.97821 58.8906 161.24)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"10.6763\" height=\"10.6931\" rx=\"5.33815\" transform=\"matrix(0.978064 -0.208304 0.207618 0.97821 75.5312 239.693)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"125.447\" height=\"10.6931\" rx=\"5.34656\" transform=\"matrix(0.978064 -0.208304 0.207618 0.97821 80.0938 184.047)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"10.6763\" height=\"10.6931\" rx=\"5.33815\" transform=\"matrix(0.978064 -0.208304 0.207618 0.97821 64.4375 187.391)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"85.4104\" height=\"10.6931\" rx=\"5.34656\" transform=\"matrix(0.978064 -0.208304 0.207618 0.97821 85.6406 210.197)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"10.6763\" height=\"10.6931\" rx=\"5.33815\" transform=\"matrix(0.978064 -0.208304 0.207618 0.97821 69.9844 213.543)\" fill=\"black\" fill-opacity=\"0.5\"/></g><defs><filter id=\"filter0_n_3889_10915\" x=\"5.58594\" y=\"5.60547\" width=\"332.832\" height=\"288.805\" filterUnits=\"userSpaceOnUse\" color-interpolation-filters=\"sRGB\"><feFlood flood-opacity=\"0\" result=\"BackgroundImageFix\"/><feBlend mode=\"normal\" in=\"SourceGraphic\" in2=\"BackgroundImageFix\" result=\"shape\"/><feTurbulence type=\"fractalNoise\" baseFrequency=\"0.25 0.25\" stitchTiles=\"stitch\" numOctaves=\"3\" result=\"noise\" seed=\"9191\" /><feColorMatrix in=\"noise\" type=\"luminanceToAlpha\" result=\"alphaNoise\" /><feComponentTransfer in=\"alphaNoise\" result=\"coloredNoise1\"><feFuncA type=\"discrete\" tableValues=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \"/></feComponentTransfer><feComposite operator=\"in\" in2=\"shape\" in=\"coloredNoise1\" result=\"noise1Clipped\" /><feComponentTransfer in=\"alphaNoise\" result=\"coloredNoise2\"><feFuncA type=\"discrete\" tableValues=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \"/></feComponentTransfer><feComposite operator=\"in\" in2=\"shape\" in=\"coloredNoise2\" result=\"noise2Clipped\" /><feFlood flood-color=\"rgba(0, 0, 0, 0.25)\" result=\"color1Flood\" /><feComposite operator=\"in\" in2=\"noise1Clipped\" in=\"color1Flood\" result=\"color1\" /><feFlood flood-color=\"rgba(255, 255, 255, 0.25)\" result=\"color2Flood\" /><feComposite operator=\"in\" in2=\"noise2Clipped\" in=\"color2Flood\" result=\"color2\" /><feMerge result=\"effect1_noise_3889_10915\"><feMergeNode in=\"shape\" /><feMergeNode in=\"color1\" /><feMergeNode in=\"color2\" /></feMerge></filter><filter id=\"filter1_iiii_3889_10915\" x=\"86.5\" y=\"-10.3237\" width=\"251.918\" height=\"344.729\" filterUnits=\"userSpaceOnUse\" color-interpolation-filters=\"sRGB\"><feFlood flood-opacity=\"0\" result=\"BackgroundImageFix\"/><feBlend mode=\"normal\" in=\"SourceGraphic\" in2=\"BackgroundImageFix\" result=\"shape\"/><feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/><feOffset dy=\"2\"/><feGaussianBlur stdDeviation=\"2\"/><feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\"/><feColorMatrix type=\"matrix\" values=\"0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.25 0\"/><feBlend mode=\"normal\" in2=\"shape\" result=\"effect1_innerShadow_3889_10915\"/><feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/><feOffset dy=\"-2\"/><feGaussianBlur stdDeviation=\"2\"/><feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\"/><feColorMatrix type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0\"/><feBlend mode=\"normal\" in2=\"effect1_innerShadow_3889_10915\" result=\"effect2_innerShadow_3889_10915\"/><feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/><feOffset dy=\"40\"/><feGaussianBlur stdDeviation=\"40\"/><feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\"/><feColorMatrix type=\"matrix\" values=\"0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.1 0\"/><feBlend mode=\"normal\" in2=\"effect2_innerShadow_3889_10915\" result=\"effect3_innerShadow_3889_10915\"/><feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/><feOffset dy=\"-16\"/><feGaussianBlur stdDeviation=\"40\"/><feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\"/><feColorMatrix type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0\"/><feBlend mode=\"normal\" in2=\"effect3_innerShadow_3889_10915\" result=\"effect4_innerShadow_3889_10915\"/></filter><filter id=\"filter2_iiii_3889_10915\" x=\"5.58594\" y=\"-10.3945\" width=\"251.906\" height=\"344.805\" filterUnits=\"userSpaceOnUse\" color-interpolation-filters=\"sRGB\"><feFlood flood-opacity=\"0\" result=\"BackgroundImageFix\"/><feBlend mode=\"normal\" in=\"SourceGraphic\" in2=\"BackgroundImageFix\" result=\"shape\"/><feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/><feOffset dy=\"2\"/><feGaussianBlur stdDeviation=\"2\"/><feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\"/><feColorMatrix type=\"matrix\" values=\"0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.25 0\"/><feBlend mode=\"normal\" in2=\"shape\" result=\"effect1_innerShadow_3889_10915\"/><feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/><feOffset dy=\"-2\"/><feGaussianBlur stdDeviation=\"2\"/><feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\"/><feColorMatrix type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0\"/><feBlend mode=\"normal\" in2=\"effect1_innerShadow_3889_10915\" result=\"effect2_innerShadow_3889_10915\"/><feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/><feOffset dy=\"40\"/><feGaussianBlur stdDeviation=\"40\"/><feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\"/><feColorMatrix type=\"matrix\" values=\"0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.1 0\"/><feBlend mode=\"normal\" in2=\"effect2_innerShadow_3889_10915\" result=\"effect3_innerShadow_3889_10915\"/><feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/><feOffset dy=\"-16\"/><feGaussianBlur stdDeviation=\"40\"/><feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\"/><feColorMatrix type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0\"/><feBlend mode=\"normal\" in2=\"effect3_innerShadow_3889_10915\" result=\"effect4_innerShadow_3889_10915\"/></filter><linearGradient id=\"paint0_linear_3889_10915\" x1=\"111.503\" y1=\"162.199\" x2=\"335.761\" y2=\"98.2353\" gradientUnits=\"userSpaceOnUse\"><stop/><stop offset=\"1\" stop-opacity=\"0\"/></linearGradient></defs></svg>`,\r\n 'confirmation': `<svg viewBox=\"0 0 344 300\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\"><style>.illustration-success{fill:var(--color-success,#2FB282);}</style><g clip-path=\"url(#clip0_conf)\"><g filter=\"url(#filter0_n_conf)\"><g filter=\"url(#filter1_iiii_conf)\"><path d=\"M128.909 29.437C132.347 13.2359 148.262 2.89554 164.463 6.33719L314.63 38.2392C330.841 41.6832 341.197 57.6224 337.757 73.8344L333.512 93.8393L295.995 270.644C292.556 286.85 276.632 297.191 260.428 293.741L110.272 261.77C94.0673 258.32 83.7188 242.385 87.1581 226.178L128.909 29.437Z\" class=\"illustration-success\"/><path d=\"M128.909 29.437C132.347 13.2359 148.262 2.89554 164.463 6.33719L314.63 38.2392C330.841 41.6832 341.197 57.6224 337.757 73.8344L333.512 93.8393L295.995 270.644C292.556 286.85 276.632 297.191 260.428 293.741L110.272 261.77C94.0673 258.32 83.7188 242.385 87.1581 226.178L128.909 29.437Z\" fill=\"url(#paint0_linear_conf)\"/></g><rect width=\"112.101\" height=\"10.6931\" rx=\"5.34657\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 173.848 55.5391)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"10.6763\" height=\"10.6931\" rx=\"5.33815\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 158.191 52.2148)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"130.785\" height=\"10.6931\" rx=\"5.34657\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 168.301 81.6992)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"10.6763\" height=\"10.6931\" rx=\"5.33815\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 152.645 78.3652)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"112.101\" height=\"10.6931\" rx=\"5.34657\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 162.754 107.842)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"10.6763\" height=\"10.6931\" rx=\"5.33815\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 147.098 104.516)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"96.0867\" height=\"10.6931\" rx=\"5.34657\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 157.207 133.99)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"96.0867\" height=\"10.6931\" rx=\"5.34657\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 140.566 212.443)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"10.6763\" height=\"10.6931\" rx=\"5.33815\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 141.551 130.666)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"10.6763\" height=\"10.6931\" rx=\"5.33815\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 124.895 209.117)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"125.447\" height=\"10.6931\" rx=\"5.34657\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 151.66 160.141)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"10.6763\" height=\"10.6931\" rx=\"5.33815\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 135.988 156.816)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"85.4104\" height=\"10.6931\" rx=\"5.34657\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 146.113 186.293)\" fill=\"black\" fill-opacity=\"0.5\"/><rect width=\"10.6763\" height=\"10.6931\" rx=\"5.33815\" transform=\"matrix(0.978075 0.208255 -0.207569 0.97822 130.441 182.967)\" fill=\"black\" fill-opacity=\"0.5\"/><g filter=\"url(#filter2_iiii_conf)\"><path d=\"M6.24705 73.9095C2.80888 57.7085 13.1487 41.7772 29.3457 38.3199L179.482 6.27234C195.69 2.81268 211.623 13.1536 215.064 29.3654L219.31 49.3703L256.834 226.173C260.273 242.38 249.926 258.315 233.722 261.766L83.5677 293.746C67.3633 297.198 51.4385 286.857 47.9991 270.65L6.24705 73.9095Z\" class=\"illustration-success\"/></g><path d=\"M142.997 202.463C114.185 208.587 85.8652 190.196 79.741 161.384C73.6167 132.571 92.0079 104.251 120.82 98.1272C149.633 92.003 177.952 110.394 184.077 139.206C190.201 168.019 171.81 196.339 142.997 202.463ZM131.143 172.268L160.185 127.54L151.241 121.732L128.007 157.515L110.112 145.893L104.303 154.838L131.143 172.268Z\" fill=\"black\" fill-opacity=\"0.5\"/></g></g><defs><filter id=\"filter0_n_conf\" x=\"5.58594\" y=\"5.60547\" width=\"332.832\" height=\"288.805\" filterUnits=\"userSpaceOnUse\" color-interpolation-filters=\"sRGB\"><feFlood flood-opacity=\"0\" result=\"BackgroundImageFix\"/><feBlend mode=\"normal\" in=\"SourceGraphic\" in2=\"BackgroundImageFix\" result=\"shape\"/><feTurbulence type=\"fractalNoise\" baseFrequency=\"0.25 0.25\" stitchTiles=\"stitch\" numOctaves=\"3\" result=\"noise\" seed=\"9191\" /><feColorMatrix in=\"noise\" type=\"luminanceToAlpha\" result=\"alphaNoise\" /><feComponentTransfer in=\"alphaNoise\" result=\"coloredNoise1\"><feFuncA type=\"discrete\" tableValues=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \"/></feComponentTransfer><feComposite operator=\"in\" in2=\"shape\" in=\"coloredNoise1\" result=\"noise1Clipped\" /><feComponentTransfer in=\"alphaNoise\" result=\"coloredNoise2\"><feFuncA type=\"discrete\" tableValues=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 \"/></feComponentTransfer><feComposite operator=\"in\" in2=\"shape\" in=\"coloredNoise2\" result=\"noise2Clipped\" /><feFlood flood-color=\"rgba(0, 0, 0, 0.25)\" result=\"color1Flood\" /><feComposite operator=\"in\" in2=\"noise1Clipped\" in=\"color1Flood\" result=\"color1\" /><feFlood flood-color=\"rgba(255, 255, 255, 0.25)\" result=\"color2Flood\" /><feComposite operator=\"in\" in2=\"noise2Clipped\" in=\"color2Flood\" result=\"color2\" /><feMerge result=\"effect1_noise_conf\"><feMergeNode in=\"shape\" /><feMergeNode in=\"color1\" /><feMergeNode in=\"color2\" /></feMerge></filter><filter id=\"filter1_iiii_conf\" x=\"86.5\" y=\"-10.3237\" width=\"251.918\" height=\"344.729\" filterUnits=\"userSpaceOnUse\" color-interpolation-filters=\"sRGB\"><feFlood flood-opacity=\"0\" result=\"BackgroundImageFix\"/><feBlend mode=\"normal\" in=\"SourceGraphic\" in2=\"BackgroundImageFix\" result=\"shape\"/><feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/><feOffset dy=\"2\"/><feGaussianBlur stdDeviation=\"2\"/><feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\"/><feColorMatrix type=\"matrix\" values=\"0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.25 0\"/><feBlend mode=\"normal\" in2=\"shape\" result=\"effect1_innerShadow_conf\"/><feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/><feOffset dy=\"-2\"/><feGaussianBlur stdDeviation=\"2\"/><feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\"/><feColorMatrix type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0\"/><feBlend mode=\"normal\" in2=\"effect1_innerShadow_conf\" result=\"effect2_innerShadow_conf\"/><feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/><feOffset dy=\"40\"/><feGaussianBlur stdDeviation=\"40\"/><feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\"/><feColorMatrix type=\"matrix\" values=\"0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.1 0\"/><feBlend mode=\"normal\" in2=\"effect2_innerShadow_conf\" result=\"effect3_innerShadow_conf\"/><feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/><feOffset dy=\"-16\"/><feGaussianBlur stdDeviation=\"40\"/><feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\"/><feColorMatrix type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0\"/><feBlend mode=\"normal\" in2=\"effect3_innerShadow_conf\" result=\"effect4_innerShadow_conf\"/></filter><filter id=\"filter2_iiii_conf\" x=\"5.58594\" y=\"-10.3945\" width=\"251.906\" height=\"344.805\" filterUnits=\"userSpaceOnUse\" color-interpolation-filters=\"sRGB\"><feFlood flood-opacity=\"0\" result=\"BackgroundImageFix\"/><feBlend mode=\"normal\" in=\"SourceGraphic\" in2=\"BackgroundImageFix\" result=\"shape\"/><feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/><feOffset dy=\"2\"/><feGaussianBlur stdDeviation=\"2\"/><feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\"/><feColorMatrix type=\"matrix\" values=\"0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.25 0\"/><feBlend mode=\"normal\" in2=\"shape\" result=\"effect1_innerShadow_conf\"/><feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/><feOffset dy=\"-2\"/><feGaussianBlur stdDeviation=\"2\"/><feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\"/><feColorMatrix type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0\"/><feBlend mode=\"normal\" in2=\"effect1_innerShadow_conf\" result=\"effect2_innerShadow_conf\"/><feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/><feOffset dy=\"40\"/><feGaussianBlur stdDeviation=\"40\"/><feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\"/><feColorMatrix type=\"matrix\" values=\"0 0 0 0 1 0 0 0 0 1 0 0 0 0 1 0 0 0 0.1 0\"/><feBlend mode=\"normal\" in2=\"effect2_innerShadow_conf\" result=\"effect3_innerShadow_conf\"/><feColorMatrix in=\"SourceAlpha\" type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0\" result=\"hardAlpha\"/><feOffset dy=\"-16\"/><feGaussianBlur stdDeviation=\"40\"/><feComposite in2=\"hardAlpha\" operator=\"arithmetic\" k2=\"-1\" k3=\"1\"/><feColorMatrix type=\"matrix\" values=\"0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0\"/><feBlend mode=\"normal\" in2=\"effect3_innerShadow_conf\" result=\"effect4_innerShadow_conf\"/></filter><linearGradient id=\"paint0_linear_conf\" x1=\"111.503\" y1=\"162.199\" x2=\"335.761\" y2=\"98.2353\" gradientUnits=\"userSpaceOnUse\"><stop/><stop offset=\"1\" stop-opacity=\"0\"/></linearGradient><clipPath id=\"clip0_conf\"><rect width=\"344\" height=\"300\" fill=\"white\"/></clipPath></defs></svg>`\r\n };\r\n \r\n /**\r\n * Computed SVG content - sanitized for security\r\n */\r\n svgContent = computed(() => {\r\n const variantKey = this.variant();\r\n const svg = this.svgMap[variantKey] || this.svgMap['post'];\r\n return this.sanitizer.bypassSecurityTrustHtml(svg);\r\n });\r\n}\r\n","import { Component, Input, ContentChild, TemplateRef } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { DsButtonComponent } from '@propbinder/design-system';\r\nimport { DsMobileBottomSheetWrapperComponent } from './ds-mobile-bottom-sheet-wrapper';\r\nimport { DsMobileIllustrationComponent } from '../illustration/ds-mobile-illustration';\r\n\r\n/**\r\n * DsMobileConfirmationSheetComponent\r\n * \r\n * Generic bottom sheet for displaying confirmation messages with optional summary content.\r\n * Highly flexible and reusable across different confirmation scenarios.\r\n * \r\n * **Features:**\r\n * - Customizable title and message\r\n * - Optional illustration with variant selection\r\n * - Content projection for custom summary section\r\n * - Customizable button text and action\r\n * \r\n * @example\r\n * ```typescript\r\n * // Simple confirmation\r\n * const sheet = await modalController.create({\r\n * component: DsMobileConfirmationSheetComponent,\r\n * componentProps: {\r\n * title: 'Booking accepteret',\r\n * message: 'Din booking er bekræftet.',\r\n * buttonText: 'Luk',\r\n * illustrationVariant: 'confirmation'\r\n * },\r\n * breakpoints: [0, 1],\r\n * initialBreakpoint: 1,\r\n * handle: true,\r\n * cssClass: ['ds-bottom-sheet', 'auto-height']\r\n * });\r\n * await sheet.present();\r\n * ```\r\n * \r\n * @example\r\n * ```html\r\n * <!-- With custom summary content -->\r\n * <ds-mobile-confirmation-sheet\r\n * title=\"Post created\"\r\n * message=\"Your post has been published successfully.\"\r\n * buttonText=\"Done\">\r\n * <div summary>\r\n * <!-- Custom summary content here -->\r\n * </div>\r\n * </ds-mobile-confirmation-sheet>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-confirmation-sheet',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n DsMobileBottomSheetWrapperComponent,\r\n DsMobileIllustrationComponent,\r\n DsButtonComponent\r\n ],\r\n styles: [`\r\n .confirmation-content {\r\n padding: 48px 20px 24px 20px;\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n gap: 24px;\r\n }\r\n\r\n .success-icon {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n margin-bottom: -32px;\r\n z-index: 0;\r\n }\r\n\r\n .confirmation-text {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n gap: 8px;\r\n z-index: 1;\r\n }\r\n\r\n .confirmation-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xl, 20px);\r\n font-weight: 600;\r\n color: var(--text-color-default-primary, #202227);\r\n text-align: center;\r\n margin: 0;\r\n }\r\n\r\n .confirmation-message {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm, 14px);\r\n font-weight: 400;\r\n line-height: 1.6;\r\n color: var(--text-color-default-secondary, #71727a);\r\n text-align: center;\r\n margin: 0;\r\n max-width: 320px;\r\n }\r\n\r\n .summary-section {\r\n width: 100%;\r\n }\r\n\r\n .button-container {\r\n width: 100%;\r\n }\r\n\r\n .button-container ::ng-deep ds-button {\r\n display: block;\r\n width: 100%;\r\n }\r\n\r\n .button-container ::ng-deep ds-button button {\r\n width: 100%;\r\n border-radius: 100px;\r\n height: 48px;\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-bottom-sheet-wrapper>\r\n <div class=\"confirmation-content\">\r\n <!-- Illustration -->\r\n @if (showIllustration) {\r\n <div class=\"success-icon\">\r\n <ds-mobile-illustration \r\n [variant]=\"illustrationVariant\" \r\n [size]=\"illustrationSize\" />\r\n </div>\r\n }\r\n\r\n <!-- Title and Message -->\r\n <div class=\"confirmation-text\">\r\n <h2 class=\"confirmation-title\">{{ title }}</h2>\r\n <p class=\"confirmation-message\">{{ message }}</p>\r\n </div>\r\n\r\n <!-- Optional Summary Content (projected) -->\r\n @if (summaryTemplate) {\r\n <div class=\"summary-section\">\r\n <ng-container *ngTemplateOutlet=\"summaryTemplate\"></ng-container>\r\n </div>\r\n }\r\n\r\n <!-- Action Button -->\r\n <div class=\"button-container\">\r\n <ds-button \r\n size=\"lg\" \r\n variant=\"primary\"\r\n (clicked)=\"handleButtonClick()\">\r\n {{ buttonText }}\r\n </ds-button>\r\n </div>\r\n </div>\r\n </ds-mobile-bottom-sheet-wrapper>\r\n `\r\n})\r\nexport class DsMobileConfirmationSheetComponent {\r\n /**\r\n * Confirmation title\r\n */\r\n @Input({ required: true }) title!: string;\r\n\r\n /**\r\n * Confirmation message\r\n */\r\n @Input({ required: true }) message!: string;\r\n\r\n /**\r\n * Button text\r\n * @default 'Luk'\r\n */\r\n @Input() buttonText: string = 'Luk';\r\n\r\n /**\r\n * Whether to show the illustration\r\n * @default true\r\n */\r\n @Input() showIllustration: boolean = true;\r\n\r\n /**\r\n * Illustration variant\r\n * @default 'confirmation'\r\n */\r\n @Input() illustrationVariant: 'post' | 'inquiry' | 'confirmation' = 'confirmation';\r\n\r\n /**\r\n * Illustration size\r\n * @default '120px'\r\n */\r\n @Input() illustrationSize: string = '120px';\r\n\r\n /**\r\n * Optional summary content template\r\n */\r\n @ContentChild('summary', { read: TemplateRef }) summaryTemplate?: TemplateRef<any>;\r\n\r\n constructor(private modalController: ModalController) {}\r\n\r\n /**\r\n * Handle button click - dismisses the sheet\r\n */\r\n async handleButtonClick(): Promise<void> {\r\n await this.modalController.dismiss();\r\n }\r\n}\r\n","import { Component, signal, ViewChild, ElementRef, AfterViewInit, OnInit, inject } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { ModalController, IonContent } from '@ionic/angular/standalone';\r\nimport { Capacitor } from '@capacitor/core';\r\nimport { Keyboard } from '@capacitor/keyboard';\r\nimport { FilePicker } from '@capawesome/capacitor-file-picker';\r\nimport { StatusBar } from '@capacitor/status-bar';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { WhitelabelService } from '../../services/whitelabel.service';\r\nimport { DsMobileBottomSheetHeaderComponent } from './ds-mobile-bottom-sheet-header';\r\n\r\n/**\r\n * DsMobilePostCreateBottomSheetComponent\r\n * \r\n * Bottom sheet modal for creating new posts in the community feed.\r\n * This is the modal content that gets displayed in the bottom sheet.\r\n * Features Threads-inspired interface with rich text editing capabilities.\r\n * \r\n * Auto-focuses the textarea and brings up the keyboard when opened.\r\n * \r\n * Usage: Use with DsMobileBottomSheetService to present as a bottom sheet\r\n */\r\n@Component({\r\n selector: 'ds-mobile-post-create-bottom-sheet',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n IonContent,\r\n DsIconButtonComponent,\r\n DsMobileBottomSheetHeaderComponent\r\n ],\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n height: 100%;\r\n }\r\n\r\n /* ============================================\r\n CONTENT AREA\r\n ============================================ */\r\n \r\n ion-content {\r\n --background: var(--color-background-neutral-primary, #ffffff);\r\n --padding-top: 0;\r\n --padding-bottom: 0;\r\n }\r\n\r\n .post-create-container {\r\n padding: 24px 16px 16px;\r\n max-width: 640px;\r\n margin: 0 auto;\r\n }\r\n \r\n .post-composer {\r\n display: flex;\r\n gap: 12px;\r\n align-items: flex-start;\r\n }\r\n \r\n .post-composer__main {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n }\r\n \r\n .post-composer__header {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n height: 32px;\r\n }\r\n \r\n .post-composer__username {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n .post-composer__textarea {\r\n width: 100%;\r\n min-height: 60px;\r\n max-height: 400px;\r\n border: none;\r\n outline: none;\r\n resize: none;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 400;\r\n line-height: 22px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n background: transparent;\r\n padding: 0;\r\n cursor: text;\r\n overflow-y: auto;\r\n /* Auto-resize as user types */\r\n field-sizing: content;\r\n }\r\n \r\n .post-composer__textarea::placeholder {\r\n color: var(--color-text-tertiary, #999999);\r\n }\r\n \r\n /* Visual focus indicator - helps users see the textarea is ready */\r\n .post-composer__textarea:focus {\r\n outline: none;\r\n }\r\n \r\n /* Subtle animation to draw attention when empty */\r\n @keyframes gentlePulse {\r\n 0%, 100% { opacity: 1; }\r\n 50% { opacity: 0.6; }\r\n }\r\n \r\n .post-composer__textarea:not(:focus):empty + .focus-hint {\r\n animation: gentlePulse 2s ease-in-out 1;\r\n }\r\n \r\n .post-composer__actions {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n padding-top: 12px;\r\n }\r\n \r\n .post-composer__actions ds-icon-button::ng-deep button {\r\n width: 44px;\r\n height: 44px;\r\n border-radius: 50%;\r\n }\r\n \r\n /* ============================================\r\n IMAGE PREVIEW\r\n ============================================ */\r\n \r\n .image-previews {\r\n display: flex;\r\n flex-wrap: wrap;\r\n gap: 8px;\r\n margin-top: 12px;\r\n }\r\n \r\n .image-preview {\r\n position: relative;\r\n width: 96px;\r\n height: 96px;\r\n border-radius: 12px;\r\n overflow: visible;\r\n }\r\n \r\n .preview-image {\r\n width: 100%;\r\n height: 100%;\r\n display: block;\r\n border-radius: 12px;\r\n border: 1px solid var(--border-color-default);\r\n object-fit: cover;\r\n }\r\n \r\n .remove-image-btn {\r\n position: absolute;\r\n top: -8px;\r\n right: -8px;\r\n width: 24px;\r\n height: 24px;\r\n border-radius: 50%;\r\n background: rgba(0, 0, 0, 0.6);\r\n backdrop-filter: blur(8px);\r\n border: 2px solid white;\r\n color: white;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n padding: 0;\r\n }\r\n \r\n .remove-image-btn:hover {\r\n background: rgba(0, 0, 0, 0.8);\r\n transform: scale(1.05);\r\n }\r\n \r\n .remove-image-btn:active {\r\n transform: scale(0.95);\r\n }\r\n \r\n /* ============================================\r\n MOBILE OPTIMIZATIONS\r\n ============================================ */\r\n \r\n @media (max-width: 768px) {\r\n .post-create-container {\r\n padding: 12px 16px 24px;\r\n }\r\n\r\n .post-composer__textarea {\r\n min-height: 60px;\r\n max-height: 300px;\r\n /* Make tap target larger on mobile */\r\n padding: 8px;\r\n margin: -8px;\r\n }\r\n }\r\n `],\r\n template: `\r\n <!-- Header with cancel and post buttons -->\r\n <ds-mobile-bottom-sheet-header\r\n [title]=\"modalTitle()\"\r\n leftButtonLabel=\"Annuller\"\r\n [rightButtonLabel]=\"submitButtonLabel()\"\r\n [rightButtonDisabled]=\"!canPost()\"\r\n (leftButtonClick)=\"handleCancel()\"\r\n (rightButtonClick)=\"handlePost()\">\r\n </ds-mobile-bottom-sheet-header>\r\n\r\n <!-- Content -->\r\n <ion-content>\r\n <div class=\"post-create-container\">\r\n <div class=\"post-composer\">\r\n <div class=\"post-composer__main\">\r\n <textarea\r\n #textareaInput\r\n class=\"post-composer__textarea\"\r\n [(ngModel)]=\"postContent\"\r\n [placeholder]=\"placeholder()\"\r\n [readonly]=\"isReadonly\"\r\n (input)=\"handleInput()\"\r\n (focus)=\"handleFocus()\"\r\n inputmode=\"text\"\r\n enterkeyhint=\"done\"\r\n rows=\"1\">\r\n </textarea>\r\n \r\n <!-- Image Previews -->\r\n @if (selectedImages().length > 0) {\r\n <div class=\"image-previews\">\r\n @for (image of selectedImages(); track image; let i = $index) {\r\n <div class=\"image-preview\">\r\n <img [src]=\"image\" alt=\"Selected image\" class=\"preview-image\" />\r\n <button \r\n class=\"remove-image-btn\" \r\n (click)=\"handleRemoveImage(i)\"\r\n type=\"button\"\r\n aria-label=\"Fjern billede\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n <path d=\"M12 4L4 12M4 4L12 12\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n }\r\n </div>\r\n }\r\n \r\n <div class=\"post-composer__actions\">\r\n <ds-icon-button\r\n icon=\"remixImageLine\"\r\n variant=\"secondary\"\r\n size=\"md\"\r\n (clicked)=\"handleAddImage()\"\r\n aria-label=\"Tilføj billede\">\r\n </ds-icon-button>\r\n <ds-icon-button\r\n icon=\"remixAttachmentLine\"\r\n variant=\"secondary\"\r\n size=\"md\"\r\n (clicked)=\"handleAddAttachment()\"\r\n aria-label=\"Tilføj vedhæftning\">\r\n </ds-icon-button>\r\n \r\n <!-- Hidden file input for file selection -->\r\n <input\r\n #fileInput\r\n type=\"file\"\r\n accept=\"*/*\"\r\n multiple\r\n (change)=\"handleFileSelect($event)\"\r\n style=\"display: none;\"\r\n aria-hidden=\"true\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ion-content>\r\n `\r\n})\r\nexport class DsMobilePostCreateBottomSheetComponent implements AfterViewInit, OnInit {\r\n @ViewChild('textareaInput') textareaInput?: ElementRef<HTMLTextAreaElement>;\r\n @ViewChild('fileInput') fileInput?: ElementRef<HTMLInputElement>;\r\n \r\n private whitelabelService = inject(WhitelabelService);\r\n \r\n // Optional input to control auto-focus behavior\r\n autoFocus = true;\r\n \r\n // Control readonly state for keyboard trick\r\n isReadonly = true;\r\n \r\n // Edit mode properties - can be set via componentProps\r\n isEditMode = false;\r\n postId?: string;\r\n initialContent = '';\r\n \r\n postContent = '';\r\n selectedImages = signal<string[]>([]);\r\n username = signal('Lars Mikkelsen');\r\n placeholder = signal(\"Hvad er nyt?\");\r\n modalTitle = signal('Nyt opslag');\r\n submitButtonLabel = signal('Slå op');\r\n \r\n constructor(\r\n private modalController: ModalController,\r\n private elementRef: ElementRef\r\n ) {}\r\n \r\n /**\r\n * Ensure toolbar doesn't have unnecessary padding\r\n * Modal is already positioned below status bar, so no extra safe area needed\r\n */\r\n private applySafeAreaToToolbar(): void {\r\n try {\r\n const hostElement = this.elementRef?.nativeElement;\r\n if (hostElement) {\r\n const header = hostElement.querySelector('ion-header');\r\n if (header) {\r\n const toolbar = header.querySelector('ion-toolbar');\r\n if (toolbar) {\r\n const toolbarElement = toolbar as HTMLElement;\r\n // Ensure toolbar uses standard padding (no safe area since modal is already offset)\r\n toolbarElement.style.setProperty('--padding-top', '12px', 'important');\r\n toolbarElement.style.setProperty('--min-height', '56px', 'important');\r\n }\r\n }\r\n }\r\n } catch (e) {\r\n console.log('[SafeArea] Failed to apply to toolbar:', e);\r\n }\r\n }\r\n \r\n ngOnInit(): void {\r\n // Initialize edit mode if provided\r\n if (this.isEditMode && this.initialContent) {\r\n this.postContent = this.initialContent;\r\n this.modalTitle.set('Rediger opslag');\r\n this.submitButtonLabel.set('Gem');\r\n }\r\n }\r\n \r\n ngAfterViewInit(): void {\r\n // Apply safe area padding immediately to prevent corruption\r\n this.applySafeAreaToToolbar();\r\n \r\n // Auto-resize textarea if there's initial content (edit mode)\r\n if (this.postContent && this.textareaInput) {\r\n setTimeout(() => {\r\n this.resizeTextarea();\r\n }, 0);\r\n }\r\n \r\n // Try to focus IMMEDIATELY - no delay\r\n // This maximizes our chance of being in user gesture context\r\n if (this.autoFocus && this.textareaInput) {\r\n const textarea = this.textareaInput.nativeElement;\r\n \r\n // Remove readonly immediately\r\n this.isReadonly = false;\r\n \r\n // Try focusing with minimal delay\r\n setTimeout(() => {\r\n textarea.focus();\r\n textarea.click();\r\n \r\n // Explicitly show keyboard\r\n Keyboard.show().catch(e => console.log('Keyboard.show() not available'));\r\n \r\n // iOS sometimes needs a second attempt\r\n setTimeout(() => {\r\n textarea.focus();\r\n Keyboard.show().catch(e => console.log('Keyboard.show() not available'));\r\n }, 100);\r\n }, 10);\r\n }\r\n }\r\n \r\n /**\r\n * Ionic lifecycle hook - called when modal enters view\r\n * At 95% height, this acts more like a page than a modal\r\n * which might allow keyboard to open\r\n */\r\n ionViewDidEnter(): void {\r\n // Resize textarea in case initial attempt didn't work\r\n if (this.postContent && this.textareaInput) {\r\n this.resizeTextarea();\r\n }\r\n \r\n // Final focus attempt when view fully enters\r\n if (this.autoFocus && this.textareaInput) {\r\n this.isReadonly = false;\r\n const textarea = this.textareaInput.nativeElement;\r\n \r\n // Try to focus as if this was a page navigation\r\n textarea.focus();\r\n textarea.click();\r\n \r\n // Explicitly show keyboard\r\n Keyboard.show().catch(e => console.log('Keyboard.show() not available'));\r\n \r\n // Set cursor position\r\n const length = textarea.value.length;\r\n textarea.setSelectionRange(length, length);\r\n }\r\n }\r\n \r\n handleFocus(): void {\r\n // When user focuses (or we focus programmatically), remove readonly\r\n this.isReadonly = false;\r\n // Explicitly show keyboard\r\n Keyboard.show().catch(e => console.log('Keyboard.show() not available'));\r\n }\r\n \r\n handleInput(): void {\r\n this.resizeTextarea();\r\n }\r\n \r\n /**\r\n * Auto-resize textarea based on content\r\n */\r\n private resizeTextarea(): void {\r\n if (this.textareaInput) {\r\n const textarea = this.textareaInput.nativeElement;\r\n // Reset height to auto to get the correct scrollHeight\r\n textarea.style.height = 'auto';\r\n // Set height based on content, respecting min/max from CSS\r\n textarea.style.height = Math.min(textarea.scrollHeight, 400) + 'px';\r\n }\r\n }\r\n \r\n canPost(): boolean {\r\n return this.postContent.trim().length > 0 || this.selectedImages().length > 0;\r\n }\r\n \r\n async handleCancel(): Promise<void> {\r\n if (this.postContent.trim().length > 0 || this.selectedImages().length > 0) {\r\n // Show confirmation\r\n const confirmed = confirm('Kassér dette opslag?');\r\n if (confirmed) {\r\n await this.modalController.dismiss(null, 'cancel');\r\n }\r\n } else {\r\n await this.modalController.dismiss(null, 'cancel');\r\n }\r\n }\r\n \r\n async handlePost(): Promise<void> {\r\n if (!this.canPost()) return;\r\n \r\n if (this.isEditMode) {\r\n console.log('Updating post:', this.postId, this.postContent);\r\n } else {\r\n console.log('Creating post:', this.postContent, 'with images:', this.selectedImages().length);\r\n }\r\n \r\n // Pass the post content, images, and edit info back to the parent\r\n await this.modalController.dismiss(\r\n { \r\n content: this.postContent,\r\n images: this.selectedImages(),\r\n timestamp: new Date(),\r\n isEdit: this.isEditMode,\r\n postId: this.postId\r\n },\r\n 'post'\r\n );\r\n }\r\n \r\n async handleAddImage(): Promise<void> {\r\n console.log('Add image button clicked');\r\n \r\n // Re-apply safe area padding before opening camera (preventive)\r\n // This ensures the value is locked in before iOS corrupts it\r\n this.applySafeAreaToToolbar();\r\n \r\n try {\r\n console.log('Requesting photo from library...');\r\n\r\n const result = await FilePicker.pickImages({\r\n limit: 1,\r\n });\r\n const image = result.files?.[0];\r\n\r\n console.log('Photo selected successfully:', image);\r\n \r\n // Add the image path to the array\r\n if (image) {\r\n const imageSrc = image.path ? Capacitor.convertFileSrc(image.path) : (image.blob ? URL.createObjectURL(image.blob) : '');\r\n if (imageSrc) {\r\n this.selectedImages.update(images => [...images, imageSrc]);\r\n console.log('Image added to preview:', imageSrc);\r\n }\r\n }\r\n \r\n // Re-apply safe area padding immediately after returning\r\n // Since we're using fixed values, this won't cause flickering\r\n requestAnimationFrame(() => {\r\n this.applySafeAreaToToolbar();\r\n });\r\n \r\n // NOTE: Removed restoreStatusBar() call - WhitelabelService now handles\r\n // status bar state globally, no need to restore after photo selection\r\n \r\n } catch (error) {\r\n console.error('Photo selection error:', error);\r\n // Only show alert for non-cancellation errors\r\n if (error && typeof error === 'object' && 'message' in error) {\r\n const errorMessage = (error as any).message;\r\n if (!errorMessage.includes('cancel')) {\r\n alert(`Error selecting photo: ${JSON.stringify(error)}`);\r\n }\r\n }\r\n }\r\n }\r\n \r\n \r\n handleRemoveImage(index: number): void {\r\n console.log('Removing image at index:', index);\r\n this.selectedImages.update(images => images.filter((_, i) => i !== index));\r\n }\r\n \r\n handleAddAttachment(): void {\r\n console.log('Add attachment button clicked');\r\n // Trigger the hidden file input\r\n if (this.fileInput) {\r\n this.fileInput.nativeElement.click();\r\n }\r\n }\r\n \r\n handleFileSelect(event: Event): void {\r\n const input = event.target as HTMLInputElement;\r\n const files = input.files;\r\n \r\n if (!files || files.length === 0) {\r\n console.log('No files selected');\r\n return;\r\n }\r\n \r\n console.log('Files selected:', files.length);\r\n \r\n // Process each selected file\r\n Array.from(files).forEach(file => {\r\n console.log('File:', file.name, file.type, file.size);\r\n \r\n // Create a data URL for preview (for images and other files)\r\n const reader = new FileReader();\r\n reader.onload = (e) => {\r\n const result = e.target?.result as string;\r\n if (result) {\r\n // Add to selectedImages array for preview\r\n this.selectedImages.update(images => [...images, result]);\r\n console.log('File added to preview:', file.name);\r\n }\r\n };\r\n reader.readAsDataURL(file);\r\n });\r\n \r\n // Reset the input so the same file can be selected again\r\n input.value = '';\r\n }\r\n}\r\n\r\n","import {\r\n Component,\r\n Input,\r\n signal,\r\n computed,\r\n ViewChild,\r\n ElementRef,\r\n afterNextRender,\r\n Injector,\r\n OnInit,\r\n OnChanges,\r\n SimpleChanges,\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { DsIconComponent, DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { DsMobileActionListItemComponent } from '../action-list-item/ds-mobile-action-list-item';\r\nimport { ActionResult, ActionItem, ActionGroup } from './ds-mobile-actions-bottom-sheet';\r\nimport { DsMobileBottomSheetWrapperComponent } from './ds-mobile-bottom-sheet-wrapper';\r\nimport { DsMobileBottomSheetHeaderComponent } from './ds-mobile-bottom-sheet-header';\r\n\r\nexport interface Language {\r\n code: string;\r\n nativeName: string;\r\n englishName: string;\r\n flagIcon: string; // Path to flag SVG or icon name\r\n}\r\n\r\n/**\r\n * DsMobileProfileActionsSheetComponent\r\n *\r\n * Bottom sheet for profile actions with navigable language selection.\r\n * Features a smooth slide-in navigation pattern for sub-menus.\r\n *\r\n * @example\r\n * ```typescript\r\n * const sheet = await this.modalController.create({\r\n * component: DsMobileProfileActionsSheetComponent,\r\n * componentProps: {\r\n * actionGroups: [...],\r\n * currentLanguage: 'da',\r\n * availableLanguages: [...]\r\n * },\r\n * breakpoints: [0, 1],\r\n * initialBreakpoint: 1,\r\n * handle: true,\r\n * cssClass: ['ds-bottom-sheet', 'auto-height']\r\n * });\r\n *\r\n * const result = await sheet.onWillDismiss();\r\n * if (result.data?.action) {\r\n * // Handle the action (e.g., 'language:da', 'profile', 'logout')\r\n * }\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-profile-actions-sheet',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent, DsMobileActionListItemComponent, DsMobileBottomSheetWrapperComponent, DsMobileBottomSheetHeaderComponent],\r\n template: `\r\n <ds-mobile-bottom-sheet-wrapper>\r\n <div class=\"profile-sheet-content\" #sheetWrapper>\r\n <!-- View Container with CSS Animation -->\r\n <div class=\"view-container\" #viewContainer \r\n [class.show-language]=\"currentView() === 'language'\" \r\n [class.is-animating]=\"isAnimating()\"\r\n [style.height.px]=\"isAnimating() ? containerHeight() : null\">\r\n <!-- Main Actions View -->\r\n <div class=\"view main-view\" [class.active]=\"currentView() === 'main'\">\r\n <div class=\"actions-list\">\r\n @for (group of actionGroups; track $index; let isLast = $last) {\r\n <!-- Action Group -->\r\n <div class=\"action-group\">\r\n @for (actionItem of group.actions; track actionItem.action; let isLastInGroup = $last) {\r\n <ds-mobile-action-list-item\r\n [title]=\"actionItem.title\"\r\n [showDivider]=\"!isLastInGroup\"\r\n [class.destructive]=\"actionItem.destructive\"\r\n (itemClick)=\"handleActionClick(actionItem)\"\r\n >\r\n <ds-icon action-icon [name]=\"actionItem.icon\" size=\"20px\" [class.destructive-icon]=\"actionItem.destructive\" />\r\n\r\n @if (actionItem.showChevron || actionItem.subtitle || actionItem.flagIcon) {\r\n <div content-trailing class=\"trailing-content\">\r\n @if (actionItem.flagIcon) {\r\n <img [src]=\"actionItem.flagIcon\" [alt]=\"actionItem.title + ' flag'\" class=\"subtitle-flag\" />\r\n } @if (actionItem.subtitle) {\r\n <span class=\"subtitle\">{{ actionItem.subtitle }}</span>\r\n } @if (actionItem.showChevron) {\r\n <ds-icon name=\"remixArrowRightSLine\" size=\"20px\" class=\"chevron-icon\" />\r\n }\r\n </div>\r\n }\r\n </ds-mobile-action-list-item>\r\n }\r\n </div>\r\n\r\n <!-- Full-width divider between groups -->\r\n @if (!isLast) {\r\n <div class=\"action-group-divider\"></div>\r\n } }\r\n </div>\r\n </div>\r\n\r\n <!-- Language Selection View -->\r\n <div class=\"view language-view\" [class.active]=\"currentView() === 'language'\">\r\n <!-- Header with back and done buttons -->\r\n <ds-mobile-bottom-sheet-header\r\n title=\"Sprog\"\r\n leftButtonLabel=\"Tilbage\"\r\n rightButtonLabel=\"Færdig\"\r\n [rightButtonDisabled]=\"!hasLanguageChanged()\"\r\n (leftButtonClick)=\"navigateBack()\"\r\n (rightButtonClick)=\"confirmLanguageSelection()\">\r\n </ds-mobile-bottom-sheet-header>\r\n\r\n <!-- Language Options -->\r\n <div class=\"language-list\">\r\n @for (language of availableLanguages; track language.code; let isLast = $last) {\r\n <ds-mobile-action-list-item [title]=\"language.nativeName\" [showDivider]=\"!isLast\" (itemClick)=\"selectLanguage(language.code)\">\r\n <!-- Country Flag -->\r\n <img action-icon [src]=\"language.flagIcon\" [alt]=\"language.englishName + ' flag'\" class=\"language-flag\" />\r\n\r\n <!-- Radio Indicator in trailing slot -->\r\n <div content-trailing class=\"radio-wrapper\">\r\n <div class=\"radio-indicator\" [class.radio-checked]=\"language.code === selectedLanguage()\">\r\n <div class=\"radio-inner\"></div>\r\n </div>\r\n </div>\r\n </ds-mobile-action-list-item>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ds-mobile-bottom-sheet-wrapper>\r\n `,\r\n styles: [\r\n `\r\n :host {\r\n display: block;\r\n height: auto;\r\n }\r\n\r\n .profile-sheet-content {\r\n overflow: hidden;\r\n width: 100%;\r\n }\r\n\r\n /* View Container - holds both views side by side */\r\n .view-container {\r\n display: grid;\r\n grid-template-columns: 50% 50%;\r\n width: 200%;\r\n transform: translateX(0);\r\n transition: transform 0.3s cubic-bezier(0.4, 0, 0.2, 1), height 0.3s cubic-bezier(0.4, 0, 0.2, 1), opacity 0.15s ease-in-out;\r\n overflow: hidden;\r\n /* Height will be set dynamically via inline style */\r\n }\r\n\r\n .view-container.show-language {\r\n transform: translateX(-50%);\r\n }\r\n\r\n /* Individual Views */\r\n .view {\r\n width: 100%;\r\n /* Remove any min-height constraints */\r\n }\r\n\r\n .view-container:not(.is-animating) .view:not(.active) {\r\n height: 0 !important;\r\n overflow: hidden !important;\r\n }\r\n\r\n /* Main View */\r\n .main-view {\r\n padding-top: 16px;\r\n }\r\n\r\n .actions-list {\r\n display: flex;\r\n flex-direction: column;\r\n }\r\n\r\n .action-group {\r\n display: flex;\r\n flex-direction: column;\r\n padding: 0 16px;\r\n }\r\n\r\n /* Language View */\r\n .language-view {\r\n display: flex;\r\n flex-direction: column;\r\n }\r\n\r\n /* Language list styles */\r\n .language-list {\r\n padding: 8px 16px;\r\n }\r\n\r\n .language-flag {\r\n width: 24px;\r\n height: 24px;\r\n object-fit: cover;\r\n }\r\n\r\n /* Radio wrapper to ensure proper positioning */\r\n .radio-wrapper {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n\r\n /* Radio Button Indicator (Custom styled to match DS radio) */\r\n .radio-indicator {\r\n width: 20px;\r\n height: 20px;\r\n border: 2px solid var(--color-border-default, #d1d5db);\r\n border-radius: 50%;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n transition: all 0.2s ease;\r\n flex-shrink: 0;\r\n }\r\n\r\n .radio-indicator.radio-checked {\r\n border-color: var(--color-accent, #7c3aed);\r\n }\r\n\r\n .radio-inner {\r\n width: 10px;\r\n height: 10px;\r\n border-radius: 50%;\r\n background: transparent;\r\n transition: background 0.2s ease;\r\n }\r\n\r\n .radio-checked .radio-inner {\r\n background: var(--color-accent, #7c3aed);\r\n }\r\n\r\n /* Trailing Content (Subtitle + Chevron) */\r\n .trailing-content {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n }\r\n\r\n .subtitle-flag {\r\n width: 16px;\r\n height: 16px;\r\n object-fit: cover;\r\n border-radius: 2px;\r\n }\r\n\r\n .subtitle {\r\n font-size: 15px;\r\n color: var(--color-text-subtle, #6b7280);\r\n line-height: 20px;\r\n }\r\n\r\n .chevron-icon {\r\n color: var(--color-text-secondary, #737373);\r\n }\r\n\r\n .check-icon {\r\n color: var(--color-primary-base, #7c3aed);\r\n }\r\n\r\n /* Override default background for action items */\r\n ::ng-deep ds-mobile-action-list-item ds-mobile-list-item {\r\n --color-background-primary: transparent;\r\n --color-background-neutral-primary-hover: var(--color-background-neutral-secondary, #f5f5f5);\r\n }\r\n\r\n ::ng-deep ds-mobile-action-list-item ds-mobile-list-item .list-item-inner::before {\r\n z-index: 0 !important;\r\n }\r\n\r\n ::ng-deep ds-mobile-action-list-item ds-mobile-list-item .content-leading,\r\n ::ng-deep ds-mobile-action-list-item ds-mobile-list-item .content-main,\r\n ::ng-deep ds-mobile-action-list-item ds-mobile-list-item .content-trailing {\r\n position: relative;\r\n z-index: 1;\r\n }\r\n\r\n /* Destructive action styling */\r\n ds-mobile-action-list-item.destructive {\r\n --text-color-default-primary: var(--color-error-base, #ef4444);\r\n }\r\n\r\n .destructive-icon {\r\n color: var(--color-error-base, #ef4444);\r\n }\r\n\r\n /* Full-width divider between action groups */\r\n .action-group-divider {\r\n height: 1px;\r\n background: var(--color-border-subtle, #e5e5e5);\r\n margin: 8px 0;\r\n }\r\n `,\r\n ],\r\n})\r\nexport class DsMobileProfileActionsSheetComponent implements OnInit, OnChanges {\r\n /**\r\n * Action groups to display in main view\r\n */\r\n @Input() actionGroups: ActionGroup[] = [];\r\n\r\n /**\r\n * Currently selected language code\r\n */\r\n @Input() currentLanguage: string = 'da';\r\n\r\n /**\r\n * Initial language (for tracking changes)\r\n */\r\n private initialLanguage: string = '';\r\n\r\n /**\r\n * Currently selected language in the view (before confirmation)\r\n */\r\n selectedLanguage = signal<string>('');\r\n\r\n /**\r\n * Check if language has changed\r\n */\r\n hasLanguageChanged = computed(() => {\r\n return this.selectedLanguage() !== this.initialLanguage && this.selectedLanguage() !== '';\r\n });\r\n\r\n /**\r\n * Available languages for selection\r\n */\r\n @Input() availableLanguages: Language[] = [\r\n {\r\n code: 'da',\r\n nativeName: 'Dansk',\r\n englishName: 'Danish',\r\n flagIcon: '/Assets/country-flags/denmark.svg',\r\n },\r\n {\r\n code: 'en',\r\n nativeName: 'English',\r\n englishName: 'English',\r\n flagIcon: '/Assets/country-flags/united kingdom.svg',\r\n },\r\n {\r\n code: 'sv',\r\n nativeName: 'Svenska',\r\n englishName: 'Swedish',\r\n flagIcon: '/Assets/country-flags/sweden.svg',\r\n },\r\n {\r\n code: 'no',\r\n nativeName: 'Norsk',\r\n englishName: 'Norwegian',\r\n flagIcon: '/Assets/country-flags/norway.svg',\r\n },\r\n {\r\n code: 'de',\r\n nativeName: 'Deutsch',\r\n englishName: 'German',\r\n flagIcon: '/Assets/country-flags/germany.svg',\r\n },\r\n ];\r\n\r\n /**\r\n * Current view state\r\n */\r\n currentView = signal<'main' | 'language'>('main');\r\n\r\n /**\r\n * Reference to the view container for height calculations\r\n */\r\n @ViewChild('viewContainer', { read: ElementRef })\r\n viewContainer?: ElementRef<HTMLDivElement>;\r\n\r\n /**\r\n * Reference to the profile actions sheet wrapper\r\n */\r\n @ViewChild('sheetWrapper', { read: ElementRef })\r\n sheetWrapper?: ElementRef<HTMLDivElement>;\r\n\r\n /**\r\n * Current container height (for dynamic transitions)\r\n */\r\n containerHeight = signal<number | null>(null);\r\n\r\n /**\r\n * Is animating between views\r\n */\r\n isAnimating = signal<boolean>(false);\r\n\r\n constructor(private modalController: ModalController, private injector: Injector) {\r\n // Set initial height after render\r\n afterNextRender(\r\n () => {\r\n this.updateHeight();\r\n },\r\n { injector: this.injector }\r\n );\r\n }\r\n\r\n ngOnChanges(changes: SimpleChanges): void {\r\n if (changes['currentLanguage']) {\r\n const val = changes['currentLanguage'].currentValue;\r\n if (val) {\r\n this.selectedLanguage.set(val);\r\n this.initialLanguage = val;\r\n }\r\n }\r\n }\r\n\r\n ngOnInit(): void {\r\n // Try to get language from localStorage as fallback\r\n const storedLangCode = this.getLanguageFromStorage();\r\n \r\n if (storedLangCode) {\r\n this.selectedLanguage.set(storedLangCode);\r\n this.initialLanguage = storedLangCode;\r\n } else if (!this.selectedLanguage()) {\r\n // Fallback to input if storage is empty\r\n this.selectedLanguage.set(this.currentLanguage);\r\n this.initialLanguage = this.currentLanguage;\r\n }\r\n }\r\n\r\n /**\r\n * Try to resolve short language code from localStorage ('selectedLanguage' key)\r\n */\r\n private getLanguageFromStorage(): string | null {\r\n try {\r\n const stored = localStorage.getItem('selectedLanguage'); // e.g. \"da-DK\", \"sv-SE\"\r\n if (!stored) return null;\r\n\r\n // Find the code from availableLanguages that matches this locale/string\r\n // We check if any language code is part of the stored string (e.g. 'da' in 'da-DK')\r\n const match = this.availableLanguages.find(lang => \r\n lang.code === stored || stored.startsWith(lang.code + '-')\r\n );\r\n\r\n return match ? match.code : null;\r\n } catch (e) {\r\n return null;\r\n }\r\n }\r\n\r\n /**\r\n * Handle action item click\r\n */\r\n handleActionClick(actionItem: ActionItem): void {\r\n // If it's the language action, navigate to language view\r\n if (actionItem.action === 'language') {\r\n this.animateViewTransition('language');\r\n return;\r\n }\r\n\r\n // Otherwise, dismiss with the action\r\n this.selectAction(actionItem.action);\r\n }\r\n\r\n /**\r\n * Navigate back to main view\r\n */\r\n navigateBack(): void {\r\n if (this.currentView() === 'language') {\r\n this.animateViewTransition('main');\r\n }\r\n }\r\n\r\n /**\r\n * Confirm language selection and dismiss\r\n */\r\n confirmLanguageSelection(): void {\r\n if (this.hasLanguageChanged()) {\r\n this.modalController.dismiss({ action: `language:${this.selectedLanguage()}` } as ActionResult, 'select');\r\n } else {\r\n // If no change, just go back\r\n this.navigateBack();\r\n }\r\n }\r\n\r\n /**\r\n * Handle language selection (update selection, don't dismiss)\r\n */\r\n selectLanguage(languageCode: string): void {\r\n this.selectedLanguage.set(languageCode);\r\n }\r\n\r\n /**\r\n * Get current language flag icon\r\n */\r\n getCurrentLanguageFlag(): string {\r\n const language = this.availableLanguages.find((lang) => lang.code === this.currentLanguage);\r\n return language?.flagIcon || '';\r\n }\r\n\r\n /**\r\n * Update container height based on active view\r\n */\r\n private updateHeight(): void {\r\n if (!this.viewContainer || !this.sheetWrapper) return;\r\n\r\n const container = this.viewContainer.nativeElement;\r\n const activeView = this.currentView() === 'main' ? container.querySelector('.main-view') : container.querySelector('.language-view');\r\n\r\n if (activeView instanceof HTMLElement) {\r\n const height = activeView.scrollHeight;\r\n this.containerHeight.set(height);\r\n }\r\n }\r\n\r\n /**\r\n * Animate view transition with height change\r\n */\r\n private async animateViewTransition(toView: 'main' | 'language'): Promise<void> {\r\n if (!this.viewContainer || !this.sheetWrapper || this.isAnimating()) return;\r\n\r\n this.isAnimating.set(true);\r\n\r\n const container = this.viewContainer.nativeElement;\r\n\r\n // Step 1: Fade out current view (150ms)\r\n container.style.opacity = '0';\r\n\r\n await this.delay(150);\r\n\r\n // Step 2: Measure target view height\r\n // We need to temporarily position it to measure accurately\r\n const mainView = container.querySelector('.main-view') as HTMLElement;\r\n const langView = container.querySelector('.language-view') as HTMLElement;\r\n const targetView = toView === 'main' ? mainView : langView;\r\n\r\n // Temporarily make both views absolute positioned at same location to measure\r\n const containerStyle = window.getComputedStyle(container);\r\n const currentHeight = container.offsetHeight;\r\n\r\n // Save current state\r\n const savedTransition = container.style.transition;\r\n const savedTransform = container.style.transform;\r\n\r\n // Disable transitions and position target view for measurement\r\n container.style.transition = 'none';\r\n container.style.height = `${currentHeight}px`;\r\n\r\n // Position target view to measure it\r\n if (mainView && langView) {\r\n mainView.style.position = 'absolute';\r\n mainView.style.left = '0';\r\n mainView.style.top = '0';\r\n mainView.style.width = '50%';\r\n mainView.style.visibility = toView === 'main' ? 'visible' : 'hidden';\r\n\r\n langView.style.position = 'absolute';\r\n langView.style.left = '0';\r\n langView.style.top = '0';\r\n langView.style.width = '50%';\r\n langView.style.visibility = toView === 'language' ? 'visible' : 'hidden';\r\n }\r\n\r\n // Force reflow and measure\r\n container.offsetHeight;\r\n const newHeight = targetView ? targetView.scrollHeight : currentHeight;\r\n\r\n // Restore grid layout\r\n if (mainView && langView) {\r\n mainView.style.position = '';\r\n mainView.style.left = '';\r\n mainView.style.top = '';\r\n mainView.style.width = '';\r\n mainView.style.visibility = '';\r\n\r\n langView.style.position = '';\r\n langView.style.left = '';\r\n langView.style.top = '';\r\n langView.style.width = '';\r\n langView.style.visibility = '';\r\n }\r\n\r\n // Wait a frame\r\n await this.delay(10);\r\n\r\n // Step 3: Re-enable transitions, switch view, and set new height\r\n container.style.transition = savedTransition || '';\r\n this.currentView.set(toView);\r\n this.containerHeight.set(newHeight);\r\n\r\n // Step 4: Wait for height animation (300ms) then fade in\r\n await this.delay(250);\r\n container.style.opacity = '1';\r\n\r\n await this.delay(150);\r\n this.isAnimating.set(false);\r\n }\r\n\r\n /**\r\n * Helper to create delay promise\r\n */\r\n private delay(ms: number): Promise<void> {\r\n return new Promise((resolve) => setTimeout(resolve, ms));\r\n }\r\n\r\n /**\r\n * Handle regular action selection\r\n */\r\n selectAction(action: string): void {\r\n this.modalController.dismiss({ action } as ActionResult, 'select');\r\n }\r\n}\r\n","import { Injectable, signal } from '@angular/core';\r\nimport { Subject } from 'rxjs';\r\nimport { ActionGroup, ActionResult } from '../components/bottom-sheet';\r\n\r\n/**\r\n * User service for managing current user data globally\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class UserService {\r\n // User avatar configuration\r\n private _avatarInitials = signal('LM');\r\n private _avatarType = signal<'initials' | 'photo' | 'icon'>('initials');\r\n private _avatarSrc = signal('');\r\n\r\n // Profile menu items configuration\r\n private _profileMenuItems = signal<ActionGroup[] | undefined>(undefined);\r\n\r\n // Readonly computed values\r\n readonly avatarInitials = this._avatarInitials.asReadonly();\r\n readonly avatarType = this._avatarType.asReadonly();\r\n readonly avatarSrc = this._avatarSrc.asReadonly();\r\n readonly profileMenuItems = this._profileMenuItems.asReadonly();\r\n\r\n // Profile action selection notification\r\n private profileActionSelectedSubject = new Subject<ActionResult>();\r\n readonly profileActionSelected$ = this.profileActionSelectedSubject.asObservable();\r\n\r\n /**\r\n * Update avatar configuration\r\n */\r\n setAvatarInitials(initials: string) {\r\n this._avatarInitials.set(initials);\r\n }\r\n\r\n setAvatarType(type: 'initials' | 'photo' | 'icon') {\r\n this._avatarType.set(type);\r\n }\r\n\r\n setAvatarSrc(src: string) {\r\n this._avatarSrc.set(src);\r\n }\r\n\r\n /**\r\n * Set profile menu items globally.\r\n * This will be used by both ds-mobile-tab-bar and ds-mobile-page-main\r\n * if they don't receive profileMenuItems as an input.\r\n */\r\n setProfileMenuItems(items: ActionGroup[]) {\r\n this._profileMenuItems.set(items);\r\n }\r\n\r\n /**\r\n * Notify subscribers that a profile action was selected\r\n */\r\n notifyProfileAction(result: ActionResult) {\r\n this.profileActionSelectedSubject.next(result);\r\n }\r\n}\r\n","import { Component, Input, inject, computed } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { WhitelabelService } from '../../services/whitelabel.service';\r\n\r\nexport type AppIconSize = 'sm' | 'md' | 'lg' | 'xl';\r\n\r\n/**\r\n * DsAppIconComponent\r\n * \r\n * Displays the organization's logomark styled as an app icon with rounded corners\r\n * and shadow. The logomark fill color adapts to the background.\r\n * Perfect for sign-in pages, splash screens, etc.\r\n * \r\n * Uses percentage-based padding and border-radius for perfect proportional scaling.\r\n * \r\n * @example\r\n * Sign-in page (large):\r\n * ```html\r\n * <ds-app-icon size=\"xl\" />\r\n * ```\r\n * \r\n * Settings preview (small):\r\n * ```html\r\n * <ds-app-icon size=\"sm\" />\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-app-icon',\r\n standalone: true,\r\n imports: [CommonModule],\r\n host: {\r\n '[class]': 'sizeClass()'\r\n },\r\n template: `\r\n <div class=\"app-icon\">\r\n <img \r\n [src]=\"whitelabelService.logoMarkUrl()\"\r\n [alt]=\"whitelabelService.logoAlt() + ' app icon'\"\r\n class=\"app-icon__logo\"\r\n />\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n display: inline-block;\r\n flex-shrink: 0;\r\n vertical-align: top;\r\n }\r\n \r\n .app-icon {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n background: var(--app-icon-background, var(--color-app-icon-surface, #6B5FF5));\r\n /* Rounded corners - scales with size */\r\n border-radius: 20%;\r\n /* Padding scales with size - logomark fills ~70% of container */\r\n padding: 15%;\r\n width: 100%;\r\n height: 100%;\r\n }\r\n \r\n .app-icon__logo {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: contain;\r\n display: block;\r\n }\r\n \r\n /* Size variants - applied to :host, everything inside scales automatically! */\r\n :host(.app-icon--sm) { \r\n width: 16px; \r\n height: 16px;\r\n }\r\n \r\n :host(.app-icon--sm) .app-icon {\r\n box-shadow: \r\n inset 0 0 0.75px 0 rgba(255, 255, 255, 0.5),\r\n inset 0 0 15px 0 rgba(255, 255, 255, 0.2);\r\n }\r\n \r\n :host(.app-icon--md) { \r\n width: 24px; \r\n height: 24px;\r\n }\r\n \r\n :host(.app-icon--md) .app-icon {\r\n box-shadow: \r\n inset 0 0 1.5px 0 rgba(255, 255, 255, 0.5),\r\n inset 0 0 30px 0 rgba(255, 255, 255, 0.2);\r\n }\r\n \r\n :host(.app-icon--lg) { \r\n width: 32px; \r\n height: 32px;\r\n }\r\n \r\n :host(.app-icon--lg) .app-icon {\r\n box-shadow: \r\n inset 0 0 2.25px 0 rgba(255, 255, 255, 0.5),\r\n inset 0 0 45px 0 rgba(255, 255, 255, 0.2);\r\n }\r\n \r\n :host(.app-icon--xl) { \r\n width: 64px; \r\n height: 64px;\r\n }\r\n \r\n :host(.app-icon--xl) .app-icon {\r\n box-shadow: \r\n inset 0 0 3px 0 rgba(255, 255, 255, 0.5),\r\n inset 0 0 60px 0 rgba(255, 255, 255, 0.2);\r\n }\r\n `]\r\n})\r\nexport class DsAppIconComponent {\r\n whitelabelService = inject(WhitelabelService);\r\n \r\n /**\r\n * Size of the app icon\r\n * - sm: 16x16px (padding: 2.4px, radius: 3.2px)\r\n * - md: 32x32px (padding: 4.8px, radius: 6.4px)\r\n * - lg: 48x48px (padding: 7.2px, radius: 9.6px)\r\n * - xl: 64x64px (padding: 9.6px, radius: 12.8px)\r\n */\r\n @Input() size: AppIconSize = 'lg';\r\n \r\n /**\r\n * Computed CSS class for size variant\r\n */\r\n sizeClass = computed(() => `app-icon app-icon--${this.size}`);\r\n}\r\n\r\n","import { Component, Input, computed, ViewEncapsulation, inject } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsAppIconComponent, AppIconSize } from '../app-icon/ds-app-icon';\r\nimport { WhitelabelService } from '../../services/whitelabel.service';\r\n\r\nexport type AvatarType = 'initials' | 'photo' | 'icon';\r\nexport type AvatarSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\r\nexport type BadgePosition = 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';\r\n\r\n/**\r\n * DsAvatarWithBadgeComponent\r\n * \r\n * Displays an avatar with a logomark badge overlay.\r\n * Useful for showing user avatars with organization branding.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-avatar-with-badge\r\n * [type]=\"'initials'\"\r\n * [initials]=\"'JD'\"\r\n * [size]=\"'lg'\"\r\n * [badgePosition]=\"'bottom-right'\"\r\n * />\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-avatar-with-badge',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent, DsAppIconComponent],\r\n encapsulation: ViewEncapsulation.Emulated,\r\n styles: [`\r\n :host {\r\n display: inline-block;\r\n position: relative;\r\n }\r\n \r\n .avatar-badge-container {\r\n position: relative;\r\n display: inline-block;\r\n }\r\n \r\n .avatar-badge {\r\n position: absolute;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n border-radius: 22%;\r\n /* White shadow acting as a border */\r\n box-shadow: 0 0 0 2px var(--color-background-primary, #ffffff);\r\n /* Set background color for app icon inside */\r\n --app-icon-background: var(--color-app-icon-surface, #5d5fef);\r\n }\r\n \r\n /* Prevent the app icon from stretching */\r\n .avatar-badge ds-app-icon {\r\n flex-shrink: 0;\r\n }\r\n \r\n \r\n /* Badge positioning */\r\n .avatar-badge--bottom-right {\r\n bottom: -4px;\r\n right: -4px;\r\n }\r\n \r\n .avatar-badge--bottom-left {\r\n bottom: -6px;\r\n left: -6px;\r\n }\r\n \r\n .avatar-badge--top-right {\r\n top: -6px;\r\n right: -6px;\r\n }\r\n \r\n .avatar-badge--top-left {\r\n top: -6px;\r\n left: -6px;\r\n }\r\n \r\n /* Badge container sizes - matches the app-icon size inside\r\n xs/sm/md/lg use 16px (app-icon sm)\r\n xl uses 32px (app-icon md) */\r\n .avatar-badge--xs { width: 16px; height: 16px; }\r\n .avatar-badge--sm { width: 16px; height: 16px; }\r\n .avatar-badge--md { width: 16px; height: 16px; }\r\n .avatar-badge--lg { width: 16px; height: 16px; }\r\n .avatar-badge--xl { width: 24px; height: 24px; }\r\n `],\r\n template: `\r\n <div class=\"avatar-badge-container\">\r\n <ds-avatar\r\n [type]=\"type\"\r\n [size]=\"size\"\r\n [initials]=\"initials\"\r\n [src]=\"src\"\r\n [iconName]=\"iconName\"\r\n />\r\n \r\n @if (showBadge) {\r\n <div [class]=\"badgeClasses()\">\r\n <ds-app-icon [size]=\"badgeIconSize()\" />\r\n </div>\r\n }\r\n </div>\r\n `\r\n})\r\nexport class DsAvatarWithBadgeComponent {\r\n whitelabelService = inject(WhitelabelService);\r\n \r\n // Avatar props\r\n @Input() type: AvatarType = 'initials';\r\n @Input() size: AvatarSize = 'md';\r\n @Input() initials: string = '';\r\n @Input() src: string = '';\r\n @Input() iconName: string = 'remixUser3Fill';\r\n \r\n // Badge props\r\n @Input() showBadge: boolean = true;\r\n @Input() badgePosition: BadgePosition = 'bottom-right';\r\n \r\n badgeClasses = computed(() => {\r\n return `avatar-badge avatar-badge--${this.badgePosition} avatar-badge--${this.size}`;\r\n });\r\n\r\n /**\r\n * Computed badge icon size that scales with avatar size\r\n * Maps avatar sizes to appropriate app icon sizes\r\n */\r\n badgeIconSize = computed((): AppIconSize => {\r\n const sizeMap: Record<AvatarSize, AppIconSize> = {\r\n xs: 'sm',\r\n sm: 'sm',\r\n md: 'sm',\r\n lg: 'sm',\r\n xl: 'md',\r\n };\r\n return sizeMap[this.size];\r\n });\r\n}\r\n\r\n","import { Component, OnInit, inject, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { WhitelabelService } from '../services/whitelabel.service';\r\nimport { DsLogoComponent } from '../components/logo/ds-logo';\r\nimport { DsAvatarWithBadgeComponent } from '../components/avatar-with-badge/ds-avatar-with-badge';\r\nimport { DsAppIconComponent } from '../components/app-icon/ds-app-icon';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { IonContent, ModalController } from '@ionic/angular/standalone';\r\n\r\n/**\r\n * Whitelabel Demo Modal Component\r\n * \r\n * Demonstrates the whitelabeling system with theme selection, brand colors, and logo previews.\r\n * Opens as a full-screen modal similar to post details.\r\n */\r\n@Component({\r\n selector: 'ds-whitelabel-demo-modal',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n IonContent,\r\n DsLogoComponent,\r\n DsAvatarWithBadgeComponent,\r\n DsAppIconComponent,\r\n DsIconButtonComponent\r\n ],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n styles: [`\r\n /* Host fills the modal with flex layout */\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n height: 100%;\r\n width: 100%;\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n }\r\n \r\n /* Fixed header at top */\r\n .modal-header {\r\n flex-shrink: 0;\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n border-bottom: 1px solid var(--border-color-default, #e0e0e0);\r\n padding: 0 16px;\r\n }\r\n \r\n /* ion-content fills remaining space and scrolls */\r\n ion-content,\r\n .modal-content {\r\n --background: #ffffff;\r\n flex: 1;\r\n width: 100%;\r\n }\r\n \r\n .header-content {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 12px;\r\n min-height: 56px;\r\n }\r\n \r\n .header-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: 17px;\r\n font-weight: 600;\r\n color: var(--color-text-primary, #1a1a1a);\r\n flex: 1;\r\n }\r\n \r\n .close-button {\r\n flex-shrink: 0;\r\n border-radius: 50%;\r\n }\r\n \r\n .close-button::ng-deep button {\r\n border-radius: 50% !important;\r\n width: 36px !important;\r\n height: 36px !important;\r\n min-width: 36px !important;\r\n min-height: 36px !important;\r\n padding: 0 !important;\r\n display: flex !important;\r\n align-items: center !important;\r\n justify-content: center !important;\r\n background: var(--color-background-neutral-secondary, #f5f5f5) !important;\r\n color: var(--color-text-primary, #1a1a1a) !important;\r\n }\r\n \r\n .demo-container {\r\n padding: 20px;\r\n max-width: 600px;\r\n margin: 0 auto;\r\n width: 100%;\r\n }\r\n \r\n .demo-section {\r\n margin-bottom: 32px;\r\n }\r\n \r\n .demo-section h2 {\r\n margin-bottom: 16px;\r\n font-size: 18px;\r\n font-weight: 600;\r\n color: #333;\r\n }\r\n \r\n /* Theme Selection */\r\n .theme-buttons {\r\n display: flex;\r\n gap: 12px;\r\n flex-wrap: wrap;\r\n }\r\n \r\n .theme-btn {\r\n padding: 8px 16px;\r\n border-radius: 8px;\r\n font-size: 14px;\r\n font-weight: 500;\r\n border: none;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n background: #e0e0e0;\r\n color: #333;\r\n }\r\n \r\n .theme-btn:active {\r\n transform: scale(0.98);\r\n }\r\n \r\n .theme-btn.active {\r\n background: var(--color-secondary-surface);\r\n color: var(--color-secondary-content);\r\n }\r\n \r\n /* Logo Preview */\r\n .logo-preview {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 24px;\r\n background: var(--color-brand-secondary);\r\n border-radius: 12px;\r\n min-height: 80px;\r\n }\r\n \r\n .logomark-preview {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 24px;\r\n background: white;\r\n border: 1px solid #e0e0e0;\r\n border-radius: 12px;\r\n min-height: 80px;\r\n }\r\n \r\n .preview-grid {\r\n display: grid;\r\n grid-template-columns: 1fr 1fr;\r\n gap: 16px;\r\n }\r\n \r\n .preview-tile {\r\n background: white;\r\n border-radius: 12px;\r\n }\r\n \r\n .preview-tile h3 {\r\n font-size: 13px;\r\n font-weight: 600;\r\n color: #666;\r\n margin-top: 0;\r\n margin-bottom: 12px;\r\n }\r\n \r\n /* App Icon Sizes */\r\n .app-icon-sizes {\r\n display: flex;\r\n gap: 24px;\r\n align-items: flex-end;\r\n justify-content: center;\r\n padding: 24px;\r\n background: white;\r\n border-radius: 12px;\r\n border: 1px solid var(--border-color-default, #e0e0e0);\r\n flex-wrap: wrap;\r\n }\r\n \r\n .app-icon-demo {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n gap: 12px;\r\n /* Use app icon surface color as app icon background */\r\n --app-icon-background: var(--color-app-icon-surface);\r\n }\r\n \r\n .app-icon-demo span {\r\n font-size: 12px;\r\n color: #666;\r\n font-family: monospace;\r\n }\r\n \r\n /* Brand Colors */\r\n .color-section {\r\n background: white;\r\n border-radius: 12px;\r\n }\r\n \r\n .color-swatches {\r\n display: grid;\r\n grid-template-columns: 1fr 1fr;\r\n gap: 16px;\r\n margin-bottom: 24px;\r\n }\r\n \r\n .swatch {\r\n padding: 16px;\r\n border-radius: 8px;\r\n text-align: center;\r\n }\r\n \r\n .swatch-label {\r\n font-size: 12px;\r\n font-weight: 600;\r\n margin-bottom: 4px;\r\n }\r\n \r\n .swatch-value {\r\n font-size: 11px;\r\n opacity: 0.8;\r\n font-family: monospace;\r\n }\r\n \r\n .swatch--app-icon-surface {\r\n background: var(--color-app-icon-surface);\r\n color: var(--color-app-icon-content);\r\n }\r\n \r\n .swatch--app-icon-content {\r\n background: var(--color-app-icon-content);\r\n color: var(--color-app-icon-surface);\r\n border: 1px solid #e0e0e0;\r\n }\r\n \r\n .swatch--accent {\r\n background: var(--color-accent);\r\n color: var(--color-on-accent);\r\n }\r\n \r\n .swatch--on-accent {\r\n background: var(--color-on-accent);\r\n color: var(--color-accent);\r\n border: 1px solid #e0e0e0;\r\n }\r\n \r\n .swatch--header-surface {\r\n background: var(--color-header-surface);\r\n color: var(--color-header-content);\r\n }\r\n \r\n .swatch--header-content {\r\n background: var(--color-header-content);\r\n color: var(--color-header-surface);\r\n border: 1px solid #e0e0e0;\r\n }\r\n \r\n /* Color Inputs */\r\n .color-inputs {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n }\r\n \r\n .color-group-label {\r\n font-size: 13px;\r\n font-weight: 600;\r\n color: #333;\r\n margin-top: 8px;\r\n }\r\n \r\n .color-row {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n }\r\n \r\n .color-row label {\r\n min-width: 70px;\r\n font-size: 13px;\r\n color: #666;\r\n }\r\n \r\n .color-row input[type=\"color\"] {\r\n width: 40px;\r\n height: 32px;\r\n border: none;\r\n border-radius: 6px;\r\n cursor: pointer;\r\n padding: 0;\r\n }\r\n \r\n .color-row input[type=\"text\"] {\r\n flex: 1;\r\n padding: 8px 12px;\r\n border: 1px solid #ddd;\r\n border-radius: 6px;\r\n font-family: monospace;\r\n font-size: 13px;\r\n }\r\n\r\n /* Toggle switch styling */\r\n .toggle-row {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 12px;\r\n padding: 12px 0;\r\n }\r\n \r\n .toggle-row label {\r\n font-size: 14px;\r\n color: #333;\r\n font-weight: 500;\r\n }\r\n \r\n .toggle-row input[type=\"checkbox\"] {\r\n width: 48px;\r\n height: 28px;\r\n -webkit-appearance: none;\r\n appearance: none;\r\n background: #ddd;\r\n border-radius: 14px;\r\n position: relative;\r\n cursor: pointer;\r\n transition: background 0.2s ease;\r\n flex-shrink: 0;\r\n }\r\n \r\n .toggle-row input[type=\"checkbox\"]:checked {\r\n background: var(--color-accent);\r\n }\r\n \r\n .toggle-row input[type=\"checkbox\"]::before {\r\n content: '';\r\n position: absolute;\r\n width: 24px;\r\n height: 24px;\r\n border-radius: 50%;\r\n background: white;\r\n top: 2px;\r\n left: 2px;\r\n transition: transform 0.2s ease;\r\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\r\n }\r\n \r\n .toggle-row input[type=\"checkbox\"]:checked::before {\r\n transform: translateX(20px);\r\n }\r\n\r\n /* Radio button styling */\r\n .radio-group {\r\n display: flex;\r\n gap: 16px;\r\n margin-bottom: 16px;\r\n }\r\n \r\n .radio-option {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n cursor: pointer;\r\n }\r\n \r\n .radio-option input[type=\"radio\"] {\r\n width: 18px;\r\n height: 18px;\r\n cursor: pointer;\r\n accent-color: var(--color-accent);\r\n }\r\n \r\n .radio-option label {\r\n font-size: 14px;\r\n color: #333;\r\n cursor: pointer;\r\n font-weight: 500;\r\n }\r\n\r\n /* Background preview */\r\n .bg-preview {\r\n height: 80px;\r\n border-radius: 8px;\r\n margin-bottom: 16px;\r\n border: 1px solid #e0e0e0;\r\n position: relative;\r\n overflow: hidden;\r\n }\r\n \r\n .bg-preview::after {\r\n content: 'Preview';\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n font-size: 12px;\r\n font-weight: 600;\r\n color: rgba(0, 0, 0, 0.3);\r\n text-shadow: 0 1px 2px rgba(255, 255, 255, 0.5);\r\n }\r\n\r\n /* Safe area support */\r\n @supports (padding: env(safe-area-inset-bottom)) {\r\n .demo-container {\r\n padding-bottom: calc(20px + env(safe-area-inset-bottom));\r\n }\r\n }\r\n `],\r\n template: `\r\n <!-- Fixed Header -->\r\n <div class=\"modal-header\">\r\n <div class=\"header-content\">\r\n <span class=\"header-title\">Whitelabel</span>\r\n <ds-icon-button\r\n icon=\"remixCloseLine\"\r\n variant=\"secondary\"\r\n size=\"lg\"\r\n (click)=\"close()\"\r\n class=\"close-button\"\r\n aria-label=\"Close\">\r\n </ds-icon-button>\r\n </div>\r\n </div>\r\n \r\n <!-- Scrollable Content -->\r\n <ion-content [scrollY]=\"true\" class=\"modal-content\">\r\n <div class=\"demo-container\">\r\n <!-- Theme Selection -->\r\n <div class=\"demo-section\">\r\n <h2>Theme</h2>\r\n <div class=\"theme-buttons\">\r\n <button class=\"theme-btn\" (click)=\"applyDefaultTheme()\" [class.active]=\"currentTheme === 'default'\">\r\n Propbinder\r\n </button>\r\n <button class=\"theme-btn\" (click)=\"applyCejTheme()\" [class.active]=\"currentTheme === 'cej'\">\r\n CEJ\r\n </button>\r\n <button class=\"theme-btn\" (click)=\"applyPkaTheme()\" [class.active]=\"currentTheme === 'pka'\">\r\n PKA\r\n </button>\r\n <button class=\"theme-btn\" (click)=\"applyClaveTheme()\" [class.active]=\"currentTheme === 'clave'\">\r\n Clave\r\n </button>\r\n <button class=\"theme-btn\" (click)=\"applyFreedomTheme()\" [class.active]=\"currentTheme === 'freedom'\">\r\n Freedom\r\n </button>\r\n <button class=\"theme-btn\" (click)=\"applyCobblestoneTheme()\" [class.active]=\"currentTheme === 'cobblestone'\">\r\n Cobblestone\r\n </button>\r\n </div>\r\n </div>\r\n \r\n <!-- Sign-in Page Options -->\r\n <div class=\"demo-section\">\r\n <h2>Sign-in Page</h2>\r\n <div class=\"color-section\">\r\n <div class=\"toggle-row\">\r\n <label>Show City Illustration</label>\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"whitelabelService.showCityIllustration()\"\r\n [disabled]=\"currentTheme !== 'default'\"\r\n (change)=\"toggleCityIllustration()\"\r\n [style.opacity]=\"currentTheme !== 'default' ? '0.5' : '1'\"\r\n [style.cursor]=\"currentTheme !== 'default' ? 'not-allowed' : 'pointer'\"\r\n />\r\n </div>\r\n \r\n <div style=\"margin-top: 24px;\">\r\n <h3 style=\"font-size: 14px; font-weight: 600; color: #333; margin: 0 0 12px 0;\">Background</h3>\r\n \r\n <!-- Background type selector -->\r\n <div class=\"radio-group\">\r\n <div class=\"radio-option\">\r\n <input \r\n type=\"radio\" \r\n id=\"bg-solid\"\r\n name=\"bgType\"\r\n value=\"solid\"\r\n [checked]=\"whitelabelService.signInBgType() === 'solid'\"\r\n (change)=\"updateSignInBgType('solid')\"\r\n />\r\n <label for=\"bg-solid\">Solid</label>\r\n </div>\r\n <div class=\"radio-option\">\r\n <input \r\n type=\"radio\" \r\n id=\"bg-gradient\"\r\n name=\"bgType\"\r\n value=\"gradient\"\r\n [checked]=\"whitelabelService.signInBgType() === 'gradient'\"\r\n (change)=\"updateSignInBgType('gradient')\"\r\n />\r\n <label for=\"bg-gradient\">Gradient</label>\r\n </div>\r\n </div>\r\n \r\n <!-- Background preview -->\r\n <div class=\"bg-preview\" [style.background]=\"whitelabelService.signInBgStyle()\"></div>\r\n \r\n <!-- Solid color input -->\r\n @if (whitelabelService.signInBgType() === 'solid') {\r\n <div class=\"color-row\">\r\n <label>Color</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customSignInBgSolid\"\r\n (change)=\"applySignInBackground()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customSignInBgSolid\"\r\n (change)=\"applySignInBackground()\"\r\n />\r\n </div>\r\n }\r\n \r\n <!-- Gradient color inputs -->\r\n @if (whitelabelService.signInBgType() === 'gradient') {\r\n <div class=\"color-row\">\r\n <label>Start</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customSignInBgGradientStart\"\r\n (change)=\"applySignInBackground()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customSignInBgGradientStart\"\r\n (change)=\"applySignInBackground()\"\r\n />\r\n </div>\r\n <div class=\"color-row\">\r\n <label>End</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customSignInBgGradientEnd\"\r\n (change)=\"applySignInBackground()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customSignInBgGradientEnd\"\r\n (change)=\"applySignInBackground()\"\r\n />\r\n </div>\r\n }\r\n \r\n <!-- Sign-in content color -->\r\n <div style=\"margin-top: 24px;\">\r\n <h3 style=\"font-size: 14px; font-weight: 600; color: #333; margin: 0 0 12px 0;\">Content Color</h3>\r\n <div class=\"color-row\">\r\n <label>Text</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customSignInContentColor\"\r\n (change)=\"applySignInContentColor()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customSignInContentColor\"\r\n (change)=\"applySignInContentColor()\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Logo & Logomark Preview -->\r\n <div class=\"demo-section\">\r\n <h2>Logo Preview</h2>\r\n \r\n <!-- Logo Size Selector -->\r\n <div style=\"margin-bottom: 16px;\">\r\n <h3 style=\"font-size: 14px; font-weight: 600; color: #333; margin: 0 0 12px 0;\">Header Logo Size</h3>\r\n <div class=\"theme-buttons\">\r\n <button\r\n class=\"theme-btn\"\r\n (click)=\"updateLogoSize('sm')\"\r\n [class.active]=\"whitelabelService.logoSize() === 'sm'\">\r\n Small (24px)\r\n </button>\r\n <button\r\n class=\"theme-btn\"\r\n (click)=\"updateLogoSize('md')\"\r\n [class.active]=\"whitelabelService.logoSize() === 'md'\">\r\n Medium (28px)\r\n </button>\r\n <button\r\n class=\"theme-btn\"\r\n (click)=\"updateLogoSize('lg')\"\r\n [class.active]=\"whitelabelService.logoSize() === 'lg'\">\r\n Large (32px)\r\n </button>\r\n <button\r\n class=\"theme-btn\"\r\n (click)=\"updateLogoSize('xl')\"\r\n [class.active]=\"whitelabelService.logoSize() === 'xl'\">\r\n XLarge (36px)\r\n </button>\r\n </div>\r\n </div>\r\n \r\n <div class=\"preview-grid\">\r\n <div class=\"preview-tile\">\r\n <h3>Logo</h3>\r\n <div class=\"logo-preview\">\r\n <ds-logo variant=\"full\" />\r\n </div>\r\n </div>\r\n <div class=\"preview-tile\">\r\n <h3>Logomark</h3>\r\n <div class=\"logomark-preview\">\r\n <ds-avatar-with-badge\r\n [type]=\"'initials'\"\r\n [initials]=\"'KN'\"\r\n [size]=\"'md'\"\r\n [badgePosition]=\"'bottom-right'\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- App Icon -->\r\n <div class=\"demo-section\">\r\n <h2>App Icon</h2>\r\n <div class=\"app-icon-sizes\">\r\n <div class=\"app-icon-demo\">\r\n <ds-app-icon size=\"xl\" />\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Brand Colors -->\r\n <div class=\"demo-section\">\r\n <h2>Brand Colors</h2>\r\n <div class=\"color-section\">\r\n <div class=\"color-swatches\">\r\n <div class=\"swatch swatch--app-icon-surface\">\r\n <div class=\"swatch-label\">App Icon Surface</div>\r\n <div class=\"swatch-value\">{{ whitelabelService.appIconSurface() }}</div>\r\n </div>\r\n <div class=\"swatch swatch--app-icon-content\">\r\n <div class=\"swatch-label\">App Icon Content</div>\r\n <div class=\"swatch-value\">{{ whitelabelService.appIconContent() }}</div>\r\n </div>\r\n <div class=\"swatch swatch--accent\">\r\n <div class=\"swatch-label\">Accent</div>\r\n <div class=\"swatch-value\">{{ whitelabelService.accent() }}</div>\r\n </div>\r\n <div class=\"swatch swatch--on-accent\">\r\n <div class=\"swatch-label\">On Accent</div>\r\n <div class=\"swatch-value\">{{ whitelabelService.onAccent() }}</div>\r\n </div>\r\n <div class=\"swatch swatch--header-surface\">\r\n <div class=\"swatch-label\">Header Surface</div>\r\n <div class=\"swatch-value\">{{ whitelabelService.headerSurface() }}</div>\r\n </div>\r\n <div class=\"swatch swatch--header-content\">\r\n <div class=\"swatch-label\">Header Content</div>\r\n <div class=\"swatch-value\">{{ whitelabelService.headerContent() }}</div>\r\n </div>\r\n </div>\r\n \r\n <div class=\"color-inputs\">\r\n <div class=\"color-group-label\">App Icon</div>\r\n <div class=\"color-row\">\r\n <label>Surface</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customAppIconSurface\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customAppIconSurface\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n </div>\r\n <div class=\"color-row\">\r\n <label>Content</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customAppIconContent\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customAppIconContent\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n </div>\r\n \r\n <div class=\"color-group-label\">Accent</div>\r\n <div class=\"color-row\">\r\n <label>Base</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customAccent\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customAccent\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n </div>\r\n <div class=\"color-row\">\r\n <label>On Accent</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customOnAccent\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customOnAccent\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n </div>\r\n \r\n <div class=\"color-group-label\">Header</div>\r\n <div class=\"color-row\">\r\n <label>Surface</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customHeaderSurface\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customHeaderSurface\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n </div>\r\n <div class=\"color-row\">\r\n <label>Content</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customHeaderContent\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customHeaderContent\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n </div>\r\n <div class=\"color-row\">\r\n <label>Accent</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customHeaderAccent\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customHeaderAccent\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n </div>\r\n <div class=\"color-row\">\r\n <label>On Accent</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customOnHeaderAccent\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customOnHeaderAccent\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ion-content>\r\n `\r\n})\r\nexport class WhitelabelDemoModalComponent implements OnInit {\r\n whitelabelService = inject(WhitelabelService);\r\n \r\n private modalController = inject(ModalController);\r\n \r\n // Current active theme\r\n currentTheme = 'default';\r\n \r\n // Custom color inputs\r\n customAppIconSurface = '#6B5FF5';\r\n customAppIconContent = '#FFFFFF';\r\n customAccent = '#6B5FF5';\r\n customOnAccent = '#FFFFFF';\r\n customHeaderSurface = '#221a4c';\r\n customHeaderContent = '#FFFFFF';\r\n customHeaderAccent = 'rgba(255, 255, 255, 0.15)';\r\n customOnHeaderAccent = '#FFFFFF';\r\n \r\n // Sign-in background inputs\r\n customSignInBgSolid = '#D6C7FF';\r\n customSignInBgGradientStart = '#D6C7FF';\r\n customSignInBgGradientEnd = '#8A9BFF';\r\n customSignInContentColor = '#1a1a1a';\r\n \r\n ngOnInit() {\r\n this.updateCustomColorInputs();\r\n this.updateSignInBgInputs();\r\n this.updateSignInContentColorInput();\r\n this.detectCurrentTheme();\r\n }\r\n \r\n /**\r\n * Detect the current active theme based on colors\r\n */\r\n private detectCurrentTheme() {\r\n const headerSurface = this.whitelabelService.headerSurface().toUpperCase();\r\n \r\n if (headerSurface === '#A70923') {\r\n this.currentTheme = 'cej';\r\n } else if (headerSurface === '#660036') {\r\n this.currentTheme = 'pka';\r\n } else if (headerSurface === '#262424') {\r\n this.currentTheme = 'clave';\r\n } else if (headerSurface === '#1D4A49') {\r\n this.currentTheme = 'freedom';\r\n } else if (headerSurface === '#2C3E50') {\r\n this.currentTheme = 'cobblestone';\r\n } else {\r\n this.currentTheme = 'default';\r\n }\r\n }\r\n \r\n /**\r\n * Close the modal\r\n */\r\n close(): void {\r\n this.modalController.dismiss();\r\n }\r\n \r\n applyDefaultTheme() {\r\n this.currentTheme = 'default';\r\n this.whitelabelService.updateConfig({\r\n logoUrl: '/Assets/logos/propbinder-logomark.svg',\r\n logoMarkUrl: '/Assets/logos/propbinder-logomark.svg',\r\n logoAlt: 'Propbinder',\r\n logoSize: 'md',\r\n appIconSurface: '#6B5FF5',\r\n appIconContent: '#FFFFFF',\r\n accent: '#6B5FF5',\r\n onAccent: '#FFFFFF',\r\n headerSurface: '#221a4c',\r\n headerContent: '#FFFFFF',\r\n headerAccent: '#6B5FF5',\r\n onHeaderAccent: '#FFFFFF',\r\n showCityIllustration: true,\r\n signInBgType: 'gradient',\r\n signInBgSolid: '#D6C7FF',\r\n signInBgGradientStart: '#D6C7FF',\r\n signInBgGradientEnd: '#8A9BFF',\r\n signInContentColor: '#1a1a1a',\r\n organizationName: 'Propbinder',\r\n organizationId: 'default'\r\n });\r\n this.updateCustomColorInputs();\r\n this.updateSignInBgInputs();\r\n this.updateSignInContentColorInput();\r\n }\r\n \r\n applyCejTheme() {\r\n this.currentTheme = 'cej';\r\n this.whitelabelService.updateConfig({\r\n logoUrl: '/Assets/logos/cej-logo.png',\r\n logoMarkUrl: '/Assets/logos/cej-logo.png',\r\n logoAlt: 'CEJ',\r\n logoSize: 'xl',\r\n appIconSurface: '#A70923',\r\n appIconContent: '#FFFFFF',\r\n accent: '#dc092c',\r\n onAccent: '#FFFFFF',\r\n headerSurface: '#A70923',\r\n headerContent: '#FFFFFF',\r\n headerAccent: '#dc092c',\r\n onHeaderAccent: '#FFFFFF',\r\n showCityIllustration: false,\r\n signInBgType: 'gradient',\r\n signInBgSolid: '#FFE5E8',\r\n signInBgGradientStart: '#FFE5E8',\r\n signInBgGradientEnd: '#FFC7CE',\r\n signInContentColor: '#1a1a1a',\r\n organizationName: 'CEJ',\r\n organizationId: 'cej'\r\n });\r\n this.updateCustomColorInputs();\r\n this.updateSignInBgInputs();\r\n this.updateSignInContentColorInput();\r\n }\r\n \r\n applyPkaTheme() {\r\n this.currentTheme = 'pka';\r\n this.whitelabelService.updateConfig({\r\n logoUrl: '/Assets/logos/pka-logo.svg',\r\n logoMarkUrl: '/Assets/logos/pka-logo.svg',\r\n logoAlt: 'PKA',\r\n logoSize: 'md',\r\n appIconSurface: '#CC006C',\r\n appIconContent: '#FFFFFF',\r\n accent: '#CC006C',\r\n onAccent: '#FFFFFF',\r\n headerSurface: '#660036',\r\n headerContent: '#FFFFFF',\r\n headerAccent: '#CC006C',\r\n onHeaderAccent: '#FFFFFF',\r\n showCityIllustration: false,\r\n signInBgType: 'gradient',\r\n signInBgSolid: '#FFE0F0',\r\n signInBgGradientStart: '#FFE0F0',\r\n signInBgGradientEnd: '#FFB3D9',\r\n signInContentColor: '#1a1a1a',\r\n organizationName: 'PKA',\r\n organizationId: 'pka'\r\n });\r\n this.updateCustomColorInputs();\r\n this.updateSignInBgInputs();\r\n this.updateSignInContentColorInput();\r\n }\r\n \r\n applyClaveTheme() {\r\n this.currentTheme = 'clave';\r\n this.whitelabelService.updateConfig({\r\n logoUrl: '/Assets/logos/clave-logo.svg',\r\n logoMarkUrl: '/Assets/logos/clave-logo.svg',\r\n logoAlt: 'Clave',\r\n logoSize: 'lg',\r\n appIconSurface: '#262424',\r\n appIconContent: '#FFFFFF',\r\n accent: '#868764',\r\n onAccent: '#FFFFFF',\r\n headerSurface: '#262424',\r\n headerContent: '#FFFFFF',\r\n headerAccent: '#868764',\r\n onHeaderAccent: '#FFFFFF',\r\n showCityIllustration: false,\r\n signInBgType: 'gradient',\r\n signInBgSolid: '#E8E8E0',\r\n signInBgGradientStart: '#E8E8E0',\r\n signInBgGradientEnd: '#D4D4C3',\r\n signInContentColor: '#1a1a1a',\r\n organizationName: 'Clave',\r\n organizationId: 'clave'\r\n });\r\n this.updateCustomColorInputs();\r\n this.updateSignInBgInputs();\r\n this.updateSignInContentColorInput();\r\n }\r\n \r\n applyFreedomTheme() {\r\n this.currentTheme = 'freedom';\r\n this.whitelabelService.updateConfig({\r\n logoUrl: '/Assets/logos/freedom-logo.svg',\r\n logoMarkUrl: '/Assets/logos/freedom-logomark.svg',\r\n logoAlt: 'Freedom',\r\n logoSize: 'md',\r\n appIconSurface: '#1D4A49',\r\n appIconContent: '#FFFFFF',\r\n accent: '#1D4A49',\r\n onAccent: '#FFFFFF',\r\n headerSurface: '#1D4A49',\r\n headerContent: '#FFFFFF',\r\n headerAccent: '#AACFC3',\r\n onHeaderAccent: '#1D4A49',\r\n showCityIllustration: false,\r\n signInBgType: 'gradient',\r\n signInBgSolid: '#D5E8E6',\r\n signInBgGradientStart: '#D5E8E6',\r\n signInBgGradientEnd: '#AACFC3',\r\n signInContentColor: '#FFFFFF',\r\n organizationName: 'Freedom',\r\n organizationId: 'freedom'\r\n });\r\n this.updateCustomColorInputs();\r\n this.updateSignInBgInputs();\r\n this.updateSignInContentColorInput();\r\n }\r\n \r\n applyCobblestoneTheme() {\r\n this.currentTheme = 'cobblestone';\r\n this.whitelabelService.updateConfig({\r\n logoUrl: '/Assets/logos/cobblestone-logo.svg',\r\n logoMarkUrl: '/Assets/logos/cobblestone-logomark.svg',\r\n logoAlt: 'Cobblestone',\r\n logoSize: 'sm',\r\n appIconSurface: '#2C3E50',\r\n appIconContent: '#FFFFFF',\r\n accent: '#3498DB',\r\n onAccent: '#FFFFFF',\r\n headerSurface: '#2C3E50',\r\n headerContent: '#FFFFFF',\r\n headerAccent: '#3498DB',\r\n onHeaderAccent: '#FFFFFF',\r\n showCityIllustration: false,\r\n signInBgType: 'gradient',\r\n signInBgSolid: '#E8EEF2',\r\n signInBgGradientStart: '#E8EEF2',\r\n signInBgGradientEnd: '#BDC3C7',\r\n signInContentColor: '#1a1a1a',\r\n organizationName: 'Cobblestone',\r\n organizationId: 'cobblestone'\r\n });\r\n this.updateCustomColorInputs();\r\n this.updateSignInBgInputs();\r\n this.updateSignInContentColorInput();\r\n }\r\n \r\n applyCustomColors() {\r\n this.whitelabelService.updateColors({\r\n appIconSurface: this.customAppIconSurface,\r\n appIconContent: this.customAppIconContent,\r\n accent: this.customAccent,\r\n onAccent: this.customOnAccent,\r\n headerSurface: this.customHeaderSurface,\r\n headerContent: this.customHeaderContent,\r\n headerAccent: this.customHeaderAccent,\r\n onHeaderAccent: this.customOnHeaderAccent\r\n });\r\n }\r\n \r\n toggleCityIllustration() {\r\n this.whitelabelService.updateConfig({\r\n showCityIllustration: !this.whitelabelService.showCityIllustration()\r\n });\r\n }\r\n \r\n updateSignInBgType(type: 'solid' | 'gradient') {\r\n this.whitelabelService.updateConfig({\r\n signInBgType: type\r\n });\r\n }\r\n \r\n updateLogoSize(size: 'sm' | 'md' | 'lg' | 'xl') {\r\n this.whitelabelService.updateConfig({\r\n logoSize: size,\r\n logoHeight: undefined // Clear custom height to use size-based calculation\r\n });\r\n }\r\n \r\n applySignInBackground() {\r\n this.whitelabelService.updateConfig({\r\n signInBgSolid: this.customSignInBgSolid,\r\n signInBgGradientStart: this.customSignInBgGradientStart,\r\n signInBgGradientEnd: this.customSignInBgGradientEnd\r\n });\r\n }\r\n \r\n applySignInContentColor() {\r\n this.whitelabelService.updateConfig({\r\n signInContentColor: this.customSignInContentColor\r\n });\r\n }\r\n \r\n private updateSignInBgInputs() {\r\n this.customSignInBgSolid = this.whitelabelService.signInBgSolid();\r\n this.customSignInBgGradientStart = this.whitelabelService.signInBgGradientStart();\r\n this.customSignInBgGradientEnd = this.whitelabelService.signInBgGradientEnd();\r\n }\r\n \r\n private updateSignInContentColorInput() {\r\n this.customSignInContentColor = this.whitelabelService.signInContentColor();\r\n }\r\n \r\n private updateCustomColorInputs() {\r\n this.customAppIconSurface = this.whitelabelService.appIconSurface();\r\n this.customAppIconContent = this.whitelabelService.appIconContent();\r\n this.customAccent = this.whitelabelService.accent();\r\n this.customOnAccent = this.whitelabelService.onAccent();\r\n this.customHeaderSurface = this.whitelabelService.headerSurface();\r\n this.customHeaderContent = this.whitelabelService.headerContent();\r\n this.customHeaderAccent = this.whitelabelService.headerAccent();\r\n this.customOnHeaderAccent = this.whitelabelService.onHeaderAccent();\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { WhitelabelDemoModalComponent } from './whitelabel-demo-modal.component';\r\n\r\n/**\r\n * WhitelabelDemoModalService\r\n *\r\n * Service for displaying the whitelabel demo in a full-screen modal.\r\n * Built on Ionic's modal system with native gestures and animations.\r\n *\r\n * @example\r\n * ```typescript\r\n * constructor(private whitelabelModal: WhitelabelDemoModalService) {}\r\n *\r\n * async openDemo() {\r\n * await this.whitelabelModal.open();\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class WhitelabelDemoModalService {\r\n constructor(private modalController: ModalController) {}\r\n\r\n /**\r\n * Open the whitelabel demo modal\r\n *\r\n * @returns Promise that resolves when the modal is presented\r\n */\r\n async open(): Promise<void> {\r\n try {\r\n // console.log('[WhitelabelDemoModal] Opening...');\r\n\r\n const modal = await this.modalController.create({\r\n component: WhitelabelDemoModalComponent,\r\n cssClass: 'ds-whitelabel-demo-modal',\r\n mode: 'ios',\r\n presentingElement:\r\n document.querySelector('ion-router-outlet') || undefined,\r\n backdropDismiss: true,\r\n showBackdrop: true,\r\n animated: true,\r\n keyboardClose: true,\r\n // Control the presenting element animation\r\n enterAnimation: undefined, // Use default\r\n leaveAnimation: undefined, // Use default\r\n });\r\n\r\n // console.log('[WhitelabelDemoModal] Modal created, presenting...');\r\n await modal.present();\r\n // console.log('[WhitelabelDemoModal] Modal presented');\r\n } catch (error) {\r\n // console.error('[WhitelabelDemoModal] Error opening modal:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Close the currently open whitelabel demo modal\r\n *\r\n * @param data Optional data to pass back when dismissing\r\n * @returns Promise that resolves when the modal is dismissed\r\n */\r\n async close(data?: any): Promise<boolean> {\r\n return this.modalController.dismiss(data);\r\n }\r\n\r\n /**\r\n * Get the top-most modal if one exists\r\n *\r\n * @returns Promise that resolves to the modal element or undefined\r\n */\r\n async getTop(): Promise<HTMLIonModalElement | undefined> {\r\n return this.modalController.getTop();\r\n }\r\n}\r\n","import { Component, input, output, HostListener, ElementRef, ViewChild, AfterViewInit, computed, inject } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { Router } from '@angular/router';\r\nimport { IonHeader, IonToolbar, IonTitle, IonContent, IonRefresher, IonRefresherContent, Platform, ModalController } from '@ionic/angular/standalone';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsLogoComponent } from '../logo/ds-logo';\r\nimport { DsMobileLoaderOverlayComponent } from '../loader-overlay';\r\nimport { MobilePageBase } from '../shared/mobile-page-base';\r\nimport { DsMobileProfileActionsSheetComponent, ActionResult, ActionGroup, Language } from '../bottom-sheet';\r\nimport { disableModalShadowPointerEvents } from '../bottom-sheet/modal-shadow-fix';\r\nimport { UserService } from '../../services/user.service';\r\nimport { WhitelabelDemoModalService } from '../../pages/whitelabel-demo-modal.service';\r\n\r\n/**\r\n * DsMobilePageMainComponent\r\n *\r\n * A complete mobile page layout for main/tab pages with:\r\n * - Fixed header with logomark + title + avatar\r\n * - Purple expandable header section (scrolls with content)\r\n * - White rounded content wrapper\r\n * - Pull-to-refresh support\r\n * - Auto scroll title fade-in\r\n *\r\n * @example\r\n * ```html\r\n * <!-- Simple page -->\r\n * <ds-mobile-page-main\r\n * title=\"Inquiries\"\r\n * [avatarInitials]=\"'JD'\">\r\n * <div class=\"page-content\">\r\n * <!-- Your content -->\r\n * </div>\r\n * </ds-mobile-page-main>\r\n *\r\n * <!-- Page with custom header content -->\r\n * <ds-mobile-page-main\r\n * title=\"Home\"\r\n * headerTitle=\"Welcome, Lars\"\r\n * headerSubtitle=\"Your rental property at a glance.\"\r\n * [avatarInitials]=\"'L'\">\r\n *\r\n * <div header-content class=\"property-tiles\">\r\n * <!-- Custom header content like tiles -->\r\n * </div>\r\n *\r\n * <div class=\"page-content\">\r\n * <!-- Main page content -->\r\n * </div>\r\n * </ds-mobile-page-main>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-page-main',\r\n standalone: true,\r\n imports: [CommonModule, IonHeader, IonToolbar, IonTitle, IonContent, IonRefresher, IonRefresherContent, DsAvatarComponent, DsLogoComponent, DsMobileLoaderOverlayComponent],\r\n styleUrls: ['../shared/mobile-page-base.css', './ds-mobile-page-main.css'],\r\n host: {\r\n '[style.--content-wrapper-padding]': 'contentPadding()'\r\n },\r\n template: `\r\n <!-- Fixed header at top -->\r\n <ion-header>\r\n <ion-toolbar>\r\n <div class=\"header-main\">\r\n <!-- Whitelabel logo (full in header, logomark used for app icon/avatars) -->\r\n <ds-logo variant=\"full\" size=\"lg\" />\r\n\r\n <!-- Title - fades in on scroll -->\r\n <ion-title class=\"header-main__title\">{{ title() }}</ion-title>\r\n\r\n <!-- Avatar -->\r\n <div class=\"header-main__actions\">\r\n <ds-avatar\r\n [size]=\"'md'\"\r\n [type]=\"avatarType()\"\r\n [initials]=\"avatarInitials()\"\r\n [src]=\"avatarSrc()\"\r\n [iconName]=\"avatarIconName()\"\r\n (click)=\"handleAvatarClick()\"\r\n style=\"cursor: pointer;\"\r\n />\r\n </div>\r\n </div>\r\n </ion-toolbar>\r\n </ion-header>\r\n\r\n <!-- Content with expandable header -->\r\n <ion-content [scrollEvents]=\"true\" [forceOverscroll]=\"true\" (ionScroll)=\"handleScroll($event)\">\r\n <!-- Condensed header for Ionic scroll effects -->\r\n @if (showCondensedHeader()) {\r\n <ion-header collapse=\"condense\">\r\n <ion-toolbar>\r\n <ion-title size=\"large\">{{ title() }}</ion-title>\r\n </ion-toolbar>\r\n </ion-header>\r\n }\r\n\r\n <!-- Pull to refresh (only on native iOS/Android) -->\r\n @if (showRefresh() && isNativePlatform()) {\r\n <ion-refresher slot=\"fixed\" (ionRefresh)=\"handleRefresh($event)\" [pullFactor]=\"0.4\" [pullMin]=\"80\" [pullMax]=\"240\" closeDuration=\"600ms\">\r\n <ion-refresher-content pullingIcon=\"remixArrowDownS\" refreshingSpinner=\"crescent\"> </ion-refresher-content>\r\n </ion-refresher>\r\n }\r\n\r\n <!-- Expandable header section (purple background) -->\r\n <div class=\"header-expandable\">\r\n <div class=\"header-expandable-inner\">\r\n <div class=\"header-expandable__text\">\r\n <h1 class=\"header-expandable__title\">\r\n {{ headerTitle() || title() }}\r\n </h1>\r\n @if (headerSubtitle()) {\r\n <p class=\"header-expandable__subtitle\">{{ headerSubtitle() }}</p>\r\n }\r\n </div>\r\n\r\n <!-- Slot for custom header content (e.g., property tiles) -->\r\n <ng-content select=\"[header-content]\"></ng-content>\r\n </div>\r\n </div>\r\n\r\n <!-- Content wrapper -->\r\n <div class=\"content-wrapper\">\r\n @if (contentLoading()) {\r\n <ds-mobile-loader-overlay />\r\n }\r\n\r\n <!-- Offline indicator slot (appears at top of content) -->\r\n <ng-content select=\"[offline-indicator]\"></ng-content>\r\n \r\n <div class=\"content-inner\">\r\n <!-- Main page content -->\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n </ion-content>\r\n `,\r\n})\r\nexport class DsMobilePageMainComponent extends MobilePageBase implements AfterViewInit {\r\n @ViewChild(IonContent) ionContent?: IonContent;\r\n\r\n // Platform detection\r\n private platform = inject(Platform);\r\n private modalController = inject(ModalController);\r\n private router = inject(Router);\r\n private userService = inject(UserService);\r\n private whitelabelDemoModal = inject(WhitelabelDemoModalService);\r\n\r\n // Computed property to check if running on native platform\r\n isNativePlatform = computed(() => this.platform.is('ios') || this.platform.is('android') || this.platform.is('capacitor'));\r\n\r\n // Inputs - Title\r\n title = input.required<string>(); // For fixed header title\r\n headerTitle = input<string>(''); // Optional different title for expandable header\r\n headerSubtitle = input<string>('');\r\n\r\n // Inputs - Avatar\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n avatarInitials = input<string>('U');\r\n avatarSrc = input<string>('');\r\n avatarIconName = input<string>('remixUser3Line');\r\n\r\n // Inputs - Features\r\n showRefresh = input<boolean>(true);\r\n showCondensedHeader = input<boolean>(true);\r\n scrollThreshold = input<number>(160); // Pixels to scroll before title appears\r\n headerFadeDistance = input<number>(150); // Distance over which header fades out\r\n \r\n /**\r\n * Content wrapper padding\r\n * - '0' (default) - No padding, use ds-mobile-section for content organization\r\n * - '20px' - Legacy padding for content without sections\r\n * - Any custom CSS padding value\r\n * \r\n * Note: Bottom padding for safe area and tab bar is always preserved\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Default: sections handle padding -->\r\n * <ds-mobile-page-main title=\"Home\">\r\n * <ds-mobile-section>...</ds-mobile-section>\r\n * </ds-mobile-page-main>\r\n * \r\n * <!-- Legacy: content without sections -->\r\n * <ds-mobile-page-main title=\"Home\" contentPadding=\"20px\">\r\n * <div>Content without sections...</div>\r\n * </ds-mobile-page-main>\r\n * ```\r\n */\r\n contentPadding = input<string>('0');\r\n\r\n /**\r\n * Profile menu action groups to display when avatar is clicked.\r\n * If not provided, a default menu will be used (without Whitelabel Demo).\r\n *\r\n * @example\r\n * ```typescript\r\n * profileMenuItems: ActionGroup[] = [\r\n * {\r\n * actions: [\r\n * { action: 'profile', title: 'Min profil', icon: 'remixUser3Line' },\r\n * { action: 'settings', title: 'Indstillinger', icon: 'remixSettings3Line' }\r\n * ]\r\n * },\r\n * {\r\n * actions: [\r\n * { action: 'logout', title: 'Log ud', icon: 'remixLogoutBoxLine', destructive: true }\r\n * ]\r\n * }\r\n * ];\r\n * ```\r\n */\r\n profileMenuItems = input<ActionGroup[] | undefined>(undefined);\r\n\r\n // Outputs\r\n avatarClick = output<void>();\r\n\r\n /**\r\n * Emitted when a profile menu action is selected.\r\n * Parent component should handle the action logic (navigation, logout, etc.).\r\n */\r\n profileActionSelected = output<ActionResult>();\r\n\r\n refresh = output<any>();\r\n scroll = output<any>();\r\n\r\n constructor(private elementRef: ElementRef) {\r\n super();\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n // Initialize network monitoring\r\n this.initNetworkMonitoring(this.isNativePlatform());\r\n }\r\n\r\n /**\r\n * Handle avatar click - opens profile actions bottom sheet\r\n */\r\n async handleAvatarClick(): Promise<void> {\r\n // Emit the event for any parent listeners\r\n this.avatarClick.emit();\r\n\r\n // Use input if provided, otherwise fall back to service, otherwise use default menu\r\n const menuItems = this.profileMenuItems() ||\r\n this.userService.profileMenuItems() || [\r\n {\r\n actions: [\r\n {\r\n action: 'profile',\r\n title: 'Min profil',\r\n icon: 'remixUser3Line',\r\n destructive: false,\r\n },\r\n {\r\n action: 'settings',\r\n title: 'Indstillinger',\r\n icon: 'remixSettings3Line',\r\n destructive: false,\r\n },\r\n {\r\n action: 'appearance',\r\n title: 'Udseende',\r\n icon: 'remixPaletteLine',\r\n destructive: false,\r\n },\r\n ],\r\n },\r\n {\r\n actions: [\r\n {\r\n action: 'language',\r\n title: 'Sprog',\r\n subtitle: 'Dansk',\r\n flagIcon: '/Assets/country-flags/denmark.svg',\r\n icon: 'remixGlobalLine',\r\n destructive: false,\r\n showChevron: true,\r\n },\r\n ],\r\n },\r\n {\r\n actions: [\r\n {\r\n action: 'logout',\r\n title: 'Log ud',\r\n icon: 'remixLogoutBoxLine',\r\n destructive: true,\r\n },\r\n ],\r\n },\r\n ];\r\n\r\n // If no menu items configured, just emit and return\r\n if (!menuItems || menuItems.length === 0) {\r\n return;\r\n }\r\n\r\n const sheet = await this.modalController.create({\r\n component: DsMobileProfileActionsSheetComponent,\r\n componentProps: {\r\n actionGroups: menuItems,\r\n currentLanguage: 'da', // TODO: Get from language service\r\n availableLanguages: [\r\n {\r\n code: 'da',\r\n nativeName: 'Dansk',\r\n englishName: 'Danish',\r\n flagIcon: '/Assets/country-flags/denmark.svg',\r\n },\r\n {\r\n code: 'en',\r\n nativeName: 'English',\r\n englishName: 'English',\r\n flagIcon: '/Assets/country-flags/united kingdom.svg',\r\n },\r\n {\r\n code: 'sv',\r\n nativeName: 'Svenska',\r\n englishName: 'Swedish',\r\n flagIcon: '/Assets/country-flags/sweden.svg',\r\n },\r\n {\r\n code: 'no',\r\n nativeName: 'Norsk',\r\n englishName: 'Norwegian',\r\n flagIcon: '/Assets/country-flags/norway.svg',\r\n },\r\n {\r\n code: 'de',\r\n nativeName: 'Deutsch',\r\n englishName: 'German',\r\n flagIcon: '/Assets/country-flags/germany.svg',\r\n },\r\n ],\r\n },\r\n breakpoints: [0, 1],\r\n initialBreakpoint: 1,\r\n handle: true,\r\n cssClass: ['ds-bottom-sheet', 'auto-height'],\r\n });\r\n\r\n await sheet.present();\r\n disableModalShadowPointerEvents(sheet);\r\n\r\n const result = await sheet.onWillDismiss<ActionResult>();\r\n if (result.data?.action) {\r\n // Handle appearance/whitelabel-demo action internally (works on all pages)\r\n if (result.data.action === 'appearance' || result.data.action === 'whitelabel-demo') {\r\n // Small delay to ensure bottom sheet is fully dismissed\r\n setTimeout(async () => {\r\n try {\r\n await this.whitelabelDemoModal.open();\r\n } catch (error) {\r\n console.error('Failed to open whitelabel demo modal:', error);\r\n }\r\n }, 100);\r\n }\r\n\r\n // Emit the selected action to parent (for other actions)\r\n this.profileActionSelected.emit(result.data);\r\n // Also notify globally via UserService\r\n this.userService.notifyProfileAction(result.data);\r\n }\r\n }\r\n\r\n /**\r\n * Handle scroll events\r\n * - Shows title in fixed header when scrolled past threshold\r\n * - Fades out expandable header content based on scroll position\r\n * - Emits scroll event for custom handling\r\n */\r\n handleScroll(event: any): void {\r\n const scrollTop = event.detail.scrollTop;\r\n const header = this.elementRef.nativeElement.querySelector('ion-header:not([collapse])');\r\n const headerExpandable = this.elementRef.nativeElement.querySelector('.header-expandable');\r\n\r\n // Show title in fixed header when scrolled past threshold\r\n if (scrollTop > this.scrollThreshold()) {\r\n header?.classList.add('header-scrolled');\r\n } else {\r\n header?.classList.remove('header-scrolled');\r\n }\r\n\r\n // Fade out header-expandable content based on scroll\r\n if (headerExpandable) {\r\n const fadeDistance = this.headerFadeDistance();\r\n const fadeProgress = Math.min(scrollTop / fadeDistance, 1);\r\n\r\n // Calculate opacity (1 to 0)\r\n const opacity = 1 - fadeProgress;\r\n\r\n // Calculate transform (0px to -20px upward)\r\n const translateY = fadeProgress * -20;\r\n\r\n // Apply styles\r\n headerExpandable.style.opacity = opacity.toString();\r\n headerExpandable.style.transform = `translateY(${translateY}px)`;\r\n }\r\n\r\n this.scroll.emit(event);\r\n }\r\n\r\n /**\r\n * Handle pull-to-refresh\r\n * Emits refresh event - parent should call event.target.complete()\r\n */\r\n async handleRefresh(event: any): Promise<void> {\r\n // Haptic feedback for pull-to-refresh\r\n try {\r\n await Haptics.impact({ style: ImpactStyle.Medium });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n navigator.vibrate(50);\r\n }\r\n }\r\n\r\n this.refresh.emit(event);\r\n }\r\n}\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\n\r\nexport interface InlineTabItem {\r\n id: string;\r\n label: string;\r\n badge?: number;\r\n}\r\n\r\n/**\r\n * DsMobileInlineTabsComponent\r\n * \r\n * Pill-style inline tabs for filtering/switching views\r\n * Used in the purple header section of pages\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-inline-tabs\r\n * [tabs]=\"[\r\n * { id: 'all', label: 'All' },\r\n * { id: 'open', label: 'Open' },\r\n * { id: 'closed', label: 'Closed' }\r\n * ]\"\r\n * [activeTab]=\"'all'\"\r\n * (tabChange)=\"handleTabChange($event)\">\r\n * </ds-mobile-inline-tabs>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-inline-tabs',\r\n standalone: true,\r\n imports: [CommonModule],\r\n styles: [`\r\n .filter-tabs {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n flex-wrap: wrap;\r\n height: 40px;\r\n }\r\n \r\n .filter-tab {\r\n min-width: 48px;\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n padding: 0px 12px;\r\n height: 32px;\r\n border-radius: 20px;\r\n background: transparent;\r\n border: none;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 500;\r\n color: rgba(var(--header-content-color-rgb, 255, 255, 255), 0.6);\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n white-space: nowrap;\r\n }\r\n \r\n .filter-tab.active {\r\n background: var(--color-header-accent, #5d5fef);\r\n color: var(--color-on-header-accent, white);\r\n }\r\n \r\n .filter-tab:hover:not(.active) {\r\n background: rgba(var(--header-content-color-rgb, 255, 255, 255), 0.1);\r\n }\r\n \r\n .tab-badge {\r\n min-width: 24px;\r\n height: 16px;\r\n padding: 0 6px;\r\n border-radius: 10px;\r\n background: rgba(var(--header-content-color-rgb, 255, 255, 255), 0.2);\r\n color: var(--header-content-color, white);\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 600;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n line-height: 1;\r\n }\r\n \r\n .filter-tab.active .tab-badge {\r\n background: rgba(var(--color-on-header-accent-rgb, 255, 255, 255), 0.3);\r\n color: var(--color-on-header-accent, white);\r\n }\r\n `],\r\n template: `\r\n <div class=\"filter-tabs\">\r\n @for (tab of tabs(); track tab.id) {\r\n <button \r\n class=\"filter-tab\"\r\n [class.active]=\"activeTab() === tab.id\"\r\n (click)=\"handleTabClick(tab.id)\"\r\n [attr.aria-label]=\"tab.label\"\r\n [attr.aria-selected]=\"activeTab() === tab.id\">\r\n {{ tab.label }}\r\n @if (tab.badge && tab.badge > 0) {\r\n <span class=\"tab-badge\">{{ tab.badge }}</span>\r\n }\r\n </button>\r\n }\r\n </div>\r\n `\r\n})\r\nexport class DsMobileInlineTabsComponent {\r\n /**\r\n * Array of tab items to display\r\n */\r\n tabs = input.required<InlineTabItem[]>();\r\n \r\n /**\r\n * Currently active tab ID\r\n */\r\n activeTab = input.required<string>();\r\n \r\n /**\r\n * Emitted when a tab is clicked\r\n */\r\n tabChange = output<string>();\r\n \r\n handleTabClick(tabId: string): void {\r\n this.tabChange.emit(tabId);\r\n }\r\n}\r\n\r\n","import { Animation } from '@ionic/angular';\r\nimport { createAnimation } from '@ionic/core';\r\n\r\n/**\r\n * Custom page transition - iOS-style push/pop with dark overlay\r\n * \r\n * FORWARD (navigating TO detail):\r\n * - Entering page (detail): slides in from RIGHT, z-index 10 (on top)\r\n * - Leaving page (list): slides LEFT slightly, z-index 9 (underneath)\r\n * - Dark overlay: fades in on leaving page (opacity 0 to 0.70)\r\n * \r\n * REVERSE (swipe back FROM detail):\r\n * - Entering page (list): slides in from LEFT, z-index 9 (underneath)\r\n * - Leaving page (detail): slides out to RIGHT, z-index 10 (on top)\r\n * - Dark overlay: fades out on entering page (main page underneath, opacity 0.70 to 0)\r\n */\r\nexport const customPageTransition = (_: HTMLElement, opts: any): Animation => {\r\n const DURATION = 600;\r\n const isBackDirection = opts.direction === 'back';\r\n \r\n const rootTransition = createAnimation()\r\n .duration(opts.duration || DURATION)\r\n .easing('cubic-bezier(0.32,0.72,0,1)');\r\n\r\n // Create overlay element\r\n // Forward: overlay on leaving page (main page underneath)\r\n // Back: overlay on entering page (main page underneath)\r\n const overlayEl = document.createElement('div');\r\n overlayEl.style.position = 'absolute';\r\n overlayEl.style.top = '0';\r\n overlayEl.style.left = '0';\r\n overlayEl.style.right = '0';\r\n overlayEl.style.bottom = '0';\r\n overlayEl.style.backgroundColor = '#000';\r\n overlayEl.style.opacity = isBackDirection ? '0.70' : '0';\r\n overlayEl.style.zIndex = '1';\r\n overlayEl.style.pointerEvents = 'none';\r\n \r\n // Add overlay to the page that should have it (main page underneath)\r\n // Forward: leaving page is main page\r\n // Back: entering page is main page\r\n const targetPageEl = isBackDirection ? opts.enteringEl : opts.leavingEl;\r\n if (targetPageEl) {\r\n const currentPosition = window.getComputedStyle(targetPageEl).position;\r\n if (currentPosition === 'static') {\r\n targetPageEl.style.position = 'relative';\r\n }\r\n targetPageEl.appendChild(overlayEl);\r\n }\r\n \r\n // Entering page animation\r\n const enteringPage = createAnimation()\r\n .addElement(opts.enteringEl)\r\n .beforeRemoveClass('ion-page-invisible')\r\n .beforeStyles({\r\n 'z-index': isBackDirection ? '9' : '10',\r\n 'opacity': '1'\r\n })\r\n .fromTo('transform', \r\n isBackDirection ? 'translateX(-20%)' : 'translateX(100%)', \r\n 'translateX(0)'\r\n );\r\n\r\n // Leaving page animation\r\n const leavingPage = createAnimation()\r\n .addElement(opts.leavingEl)\r\n .beforeStyles({\r\n 'z-index': isBackDirection ? '10' : '9'\r\n })\r\n .fromTo('transform', \r\n 'translateX(0)', \r\n isBackDirection ? 'translateX(100%)' : 'translateX(-20%)'\r\n );\r\n\r\n // Overlay fade animation\r\n const overlayAnimation = createAnimation()\r\n .addElement(overlayEl)\r\n .fromTo('opacity',\r\n isBackDirection ? '0.70' : '0',\r\n isBackDirection ? '0' : '0.70'\r\n );\r\n\r\n // Clean up overlay after animation completes\r\n rootTransition.afterAddWrite(() => {\r\n if (overlayEl && overlayEl.parentNode) {\r\n overlayEl.parentNode.removeChild(overlayEl);\r\n }\r\n });\r\n\r\n rootTransition.addAnimation([enteringPage, leavingPage, overlayAnimation]);\r\n \r\n return rootTransition;\r\n};\r\n\r\n/**\r\n * Custom back transition - iOS style where page slides out to reveal page underneath\r\n * The entering page (inquiries) slides in from the LEFT underneath\r\n * The leaving page (detail) slides out to the RIGHT on top\r\n * Dark overlay: fades out on entering page (main page underneath, opacity 0.70 to 0)\r\n */\r\nexport const customBackTransition = (_: HTMLElement, opts: any): Animation => {\r\n const DURATION = 700;\r\n \r\n const rootTransition = createAnimation()\r\n .duration(opts.duration || DURATION)\r\n .easing('cubic-bezier(0.32,0.72,0,1)');\r\n\r\n // Create overlay element for the entering page (main page underneath)\r\n // This page should already have an overlay from the forward transition, but we'll ensure it exists\r\n const overlayEl = document.createElement('div');\r\n overlayEl.style.position = 'absolute';\r\n overlayEl.style.top = '0';\r\n overlayEl.style.left = '0';\r\n overlayEl.style.right = '0';\r\n overlayEl.style.bottom = '0';\r\n overlayEl.style.backgroundColor = '#000';\r\n overlayEl.style.opacity = '0.70';\r\n overlayEl.style.zIndex = '1';\r\n overlayEl.style.pointerEvents = 'none';\r\n \r\n // Ensure entering page has relative positioning for overlay\r\n const enteringPageEl = opts.enteringEl as HTMLElement;\r\n if (enteringPageEl) {\r\n const currentPosition = window.getComputedStyle(enteringPageEl).position;\r\n if (currentPosition === 'static') {\r\n enteringPageEl.style.position = 'relative';\r\n }\r\n enteringPageEl.appendChild(overlayEl);\r\n }\r\n\r\n // Entering page: underneath, sliding in from LEFT (-20% to 0)\r\n const enteringPage = createAnimation()\r\n .addElement(opts.enteringEl)\r\n .beforeRemoveClass('ion-page-invisible')\r\n .beforeStyles({\r\n 'z-index': '9',\r\n 'opacity': '1'\r\n })\r\n .fromTo('transform', 'translateX(-20%)', 'translateX(0)');\r\n\r\n // Leaving page: on top, sliding out to the RIGHT (0 to 100%)\r\n const leavingPage = createAnimation()\r\n .addElement(opts.leavingEl)\r\n .beforeStyles({\r\n 'z-index': '10',\r\n })\r\n .fromTo('transform', 'translateX(0)', 'translateX(100%)');\r\n\r\n // Overlay fade out animation on the entering page (main page)\r\n const overlayAnimation = createAnimation()\r\n .addElement(overlayEl)\r\n .fromTo('opacity', '0.70', '0');\r\n\r\n // Clean up overlay after animation completes\r\n rootTransition.afterAddWrite(() => {\r\n if (overlayEl && overlayEl.parentNode) {\r\n overlayEl.parentNode.removeChild(overlayEl);\r\n }\r\n });\r\n\r\n rootTransition.addAnimation([enteringPage, leavingPage, overlayAnimation]);\r\n \r\n return rootTransition;\r\n};\r\n\r\n","import { Component, input, output, ElementRef, ViewChild, AfterViewInit, computed, inject } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { NavController, Platform } from '@ionic/angular/standalone';\r\nimport { \r\n IonHeader, \r\n IonToolbar, \r\n IonTitle,\r\n IonContent, \r\n IonRefresher, \r\n IonRefresherContent \r\n} from '@ionic/angular/standalone';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { MobilePageBase } from '../shared/mobile-page-base';\r\nimport { DsMobileLoaderOverlayComponent } from '../loader-overlay';\r\nimport { DsMobileInlineTabsComponent, type InlineTabItem } from '../inline-tabs';\r\nimport { customBackTransition } from '../../animations/page-transitions';\r\nimport { WhitelabelService } from '../../services/whitelabel.service';\r\n\r\n/**\r\n * DsMobilePageDetailsComponent\r\n * \r\n * A complete mobile page layout for detail/drill-down pages with:\r\n * - Fixed header with back button + title (fades in on scroll)\r\n * - Purple expandable header section (scrolls with content)\r\n * - Optional inline tabs in expandable header\r\n * - White rounded content wrapper\r\n * - Pull-to-refresh support (native platforms only)\r\n * - Auto scroll title fade-in and header fade-out\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Simple detail page -->\r\n * <ds-mobile-page-details\r\n * title=\"Property Details\"\r\n * (back)=\"goBack()\">\r\n * <div class=\"page-content\">\r\n * <!-- Your content -->\r\n * </div>\r\n * </ds-mobile-page-details>\r\n * \r\n * <!-- With tabs -->\r\n * <ds-mobile-page-details\r\n * title=\"Inquiry Details\"\r\n * [tabs]=\"tabItems\"\r\n * [activeTab]=\"activeTab()\"\r\n * (tabChange)=\"setActiveTab($event)\"\r\n * (back)=\"goBack()\">\r\n * <div class=\"page-content\">\r\n * <!-- Your content -->\r\n * </div>\r\n * </ds-mobile-page-details>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-page-details',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonHeader,\r\n IonToolbar,\r\n IonTitle,\r\n IonContent,\r\n IonRefresher,\r\n IonRefresherContent,\r\n DsIconComponent,\r\n DsMobileLoaderOverlayComponent,\r\n DsMobileInlineTabsComponent\r\n ],\r\n host: {\r\n '[style.--content-wrapper-padding]': 'contentPadding()'\r\n },\r\n styleUrls: [\r\n '../shared/mobile-page-base.css',\r\n './ds-mobile-page-details.css'\r\n ],\r\n template: `\r\n <!-- Fixed header at top -->\r\n <ion-header>\r\n <ion-toolbar>\r\n <div class=\"header-details\">\r\n <!-- Back Button -->\r\n <button class=\"back-button\" (click)=\"handleBack()\" [attr.aria-label]=\"'Go back'\">\r\n <ds-icon name=\"remixArrowLeftSLine\" size=\"24px\" [color]=\"whitelabelService.headerContent()\" />\r\n </button>\r\n \r\n <!-- Title - fades in on scroll -->\r\n <ion-title class=\"header-title\">{{ title() }}</ion-title>\r\n </div>\r\n </ion-toolbar>\r\n </ion-header>\r\n\r\n <!-- Content with expandable header -->\r\n <ion-content [scrollEvents]=\"true\" [forceOverscroll]=\"true\" (ionScroll)=\"handleScroll($event)\">\r\n <!-- Pull to refresh (only on native iOS/Android) -->\r\n @if (showRefresh() && isNativePlatform()) {\r\n <ion-refresher \r\n slot=\"fixed\" \r\n (ionRefresh)=\"handleRefresh($event)\"\r\n [pullFactor]=\"0.4\" \r\n [pullMin]=\"80\" \r\n [pullMax]=\"240\"\r\n closeDuration=\"600ms\">\r\n <ion-refresher-content\r\n pullingIcon=\"remixArrowDownS\"\r\n refreshingSpinner=\"crescent\">\r\n </ion-refresher-content>\r\n </ion-refresher>\r\n }\r\n\r\n <!-- Expandable header section (purple background) -->\r\n <div class=\"header-expandable\">\r\n <div class=\"header-expandable-inner\">\r\n <div class=\"header-expandable__text\">\r\n <h1 class=\"header-expandable__title\">{{ title() }}</h1>\r\n </div>\r\n \r\n <!-- Tabs in header (optional) -->\r\n @if (tabs() && tabs()!.length > 0) {\r\n <ds-mobile-inline-tabs\r\n [tabs]=\"tabs()!\"\r\n [activeTab]=\"activeTab()\"\r\n (tabChange)=\"handleTabChange($event)\">\r\n </ds-mobile-inline-tabs>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Content wrapper -->\r\n <div class=\"content-wrapper\">\r\n @if (contentLoading()) {\r\n <ds-mobile-loader-overlay />\r\n }\r\n\r\n <!-- Offline indicator slot (appears at top of content) -->\r\n <ng-content select=\"[offline-indicator]\"></ng-content>\r\n \r\n <div class=\"content-inner\">\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n </ion-content>\r\n `\r\n})\r\nexport class DsMobilePageDetailsComponent extends MobilePageBase implements AfterViewInit {\r\n @ViewChild(IonContent) ionContent?: IonContent;\r\n \r\n // Platform detection\r\n private platform = inject(Platform);\r\n \r\n // Whitelabel service\r\n whitelabelService = inject(WhitelabelService);\r\n \r\n // Computed property to check if running on native platform\r\n isNativePlatform = computed(() => \r\n this.platform.is('ios') || \r\n this.platform.is('android') || \r\n this.platform.is('capacitor')\r\n );\r\n \r\n // Inputs\r\n title = input.required<string>();\r\n backRoute = input<string>(''); // Optional default back route\r\n \r\n /**\r\n * Content wrapper padding\r\n * - '0' (default) - No padding, use ds-mobile-section for content organization\r\n * - '20px' - Legacy padding for content without sections\r\n * - Any custom CSS padding value\r\n * \r\n * Note: Bottom padding for safe area and tab bar is always preserved\r\n */\r\n contentPadding = input<string>('0');\r\n \r\n // Inputs - Tabs (optional)\r\n tabs = input<InlineTabItem[] | undefined>(undefined);\r\n activeTab = input<string>('');\r\n \r\n // Inputs - Features\r\n showRefresh = input<boolean>(true);\r\n scrollThreshold = input<number>(160); // Pixels to scroll before title appears\r\n headerFadeDistance = input<number>(200); // Distance over which header fades out\r\n \r\n // Outputs\r\n back = output<void>();\r\n tabChange = output<string>();\r\n refresh = output<any>();\r\n scroll = output<any>();\r\n \r\n constructor(\r\n private navCtrl: NavController,\r\n private elementRef: ElementRef\r\n ) {\r\n super();\r\n }\r\n \r\n ngAfterViewInit(): void {\r\n // Initialize network monitoring\r\n this.initNetworkMonitoring(this.isNativePlatform());\r\n }\r\n \r\n /**\r\n * Handle back navigation\r\n * \r\n * By default, navigates using the provided backRoute or browser back.\r\n * Parent components can listen to the (back) event to override this behavior.\r\n */\r\n handleBack(): void {\r\n // Emit event for parent to optionally handle\r\n this.back.emit();\r\n \r\n // Default behavior: navigate using backRoute or browser back\r\n if (this.backRoute()) {\r\n this.navCtrl.navigateBack(this.backRoute());\r\n } else {\r\n this.navCtrl.back({ animation: customBackTransition });\r\n }\r\n }\r\n \r\n /**\r\n * Handle tab change\r\n */\r\n handleTabChange(tabId: string): void {\r\n this.tabChange.emit(tabId);\r\n }\r\n \r\n /**\r\n * Handle scroll events\r\n * - Shows title in fixed header when scrolled past threshold\r\n * - Fades out expandable header content based on scroll position\r\n * - Emits scroll event for custom handling\r\n */\r\n handleScroll(event: any): void {\r\n const scrollTop = event.detail.scrollTop;\r\n const threshold = this.scrollThreshold();\r\n const fadeDistance = this.headerFadeDistance();\r\n const header = this.elementRef.nativeElement.querySelector('ion-header:not([collapse])');\r\n const headerExpandable = this.elementRef.nativeElement.querySelector('.header-expandable');\r\n \r\n // Show title in fixed header when scrolled past threshold\r\n if (scrollTop > threshold) {\r\n header?.classList.add('header-scrolled');\r\n } else {\r\n header?.classList.remove('header-scrolled');\r\n }\r\n \r\n // Fade out header-expandable content based on scroll\r\n if (headerExpandable) {\r\n const fadeProgress = Math.min(scrollTop / fadeDistance, 1);\r\n \r\n // Calculate opacity (1 to 0)\r\n const opacity = 1 - fadeProgress;\r\n \r\n // Calculate transform (0px to -20px upward)\r\n const translateY = fadeProgress * -20;\r\n \r\n // Apply styles\r\n headerExpandable.style.opacity = opacity.toString();\r\n headerExpandable.style.transform = `translateY(${translateY}px)`;\r\n }\r\n \r\n this.scroll.emit(event);\r\n }\r\n \r\n /**\r\n * Handle pull-to-refresh\r\n * Emits refresh event - parent should call event.target.complete()\r\n */\r\n async handleRefresh(event: any): Promise<void> {\r\n // Haptic feedback for pull-to-refresh\r\n try {\r\n await Haptics.impact({ style: ImpactStyle.Medium });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n navigator.vibrate(50);\r\n }\r\n }\r\n \r\n this.refresh.emit(event);\r\n }\r\n}\r\n","import { Component, input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n/**\r\n * DsMobileContentComponent\r\n *\r\n * Main content container for mobile pages with flexible layout options.\r\n * Provides consistent spacing and layout patterns.\r\n *\r\n * **Note:** For production use, prefer `ds-mobile-section` for individual sections.\r\n * This component is maintained for grid layouts and prototyping.\r\n *\r\n * @example\r\n * ```html\r\n * <!-- Default: stacked layout -->\r\n * <ds-mobile-content>\r\n * <ds-mobile-section>...</ds-mobile-section>\r\n * <ds-mobile-section>...</ds-mobile-section>\r\n * </ds-mobile-content>\r\n *\r\n * <!-- Grid layout -->\r\n * <ds-mobile-content layout=\"grid-2\">\r\n * <div>Grid item 1</div>\r\n * <div>Grid item 2</div>\r\n * </ds-mobile-content>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-content',\r\n standalone: true,\r\n imports: [CommonModule],\r\n host: {\r\n '[class.layout-stacked]': 'layout() === \"stacked\"',\r\n '[class.layout-grid-2]': 'layout() === \"grid-2\"',\r\n '[class.layout-grid-3]': 'layout() === \"grid-3\"',\r\n },\r\n styles: [\r\n `\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 16px;\r\n max-width: 640px;\r\n margin: 0 auto;\r\n }\r\n\r\n /* Grid layouts */\r\n :host.layout-grid-2 {\r\n display: grid;\r\n grid-template-columns: repeat(2, 1fr);\r\n gap: 16px;\r\n }\r\n\r\n :host.layout-grid-3 {\r\n display: grid;\r\n grid-template-columns: repeat(3, 1fr);\r\n gap: 16px;\r\n }\r\n\r\n @media (max-width: 768px) {\r\n :host.layout-grid-2,\r\n :host.layout-grid-3 {\r\n grid-template-columns: 1fr;\r\n }\r\n }\r\n `,\r\n ],\r\n template: `<ng-content />`,\r\n})\r\nexport class DsMobileContentComponent {\r\n /**\r\n * Layout mode for content sections\r\n * - 'stacked' - Vertical stack with 32px gap (default)\r\n * - 'grid-2' - 2 column grid\r\n * - 'grid-3' - 3 column grid (stacks on mobile)\r\n */\r\n layout = input<'stacked' | 'grid-2' | 'grid-3'>('stacked');\r\n}\r\n\r\n/**\r\n * SectionHeaderComponent\r\n *\r\n * Semantic placeholder header for content sections.\r\n * Used for prototyping/placeholders.\r\n */\r\n@Component({\r\n selector: 'section-header',\r\n standalone: true,\r\n host: {\r\n '[class.w-half]': 'width() === \"half\"',\r\n '[class.w-third]': 'width() === \"third\"',\r\n '[class.w-full]': 'width() === \"full\"',\r\n },\r\n styles: [\r\n `\r\n :host {\r\n height: 20px;\r\n border-radius: 8px;\r\n background: var(--color-background-neutral-tertiary);\r\n display: block;\r\n }\r\n\r\n :host.w-half {\r\n width: 50%;\r\n }\r\n :host.w-third {\r\n width: 33%;\r\n }\r\n :host.w-full {\r\n width: 100%;\r\n }\r\n `,\r\n ],\r\n template: `<ng-content />`,\r\n})\r\nexport class SectionHeaderComponent {\r\n /** Width of the header placeholder */\r\n width = input<'half' | 'third' | 'full'>('half');\r\n}\r\n\r\n/**\r\n * ContentRowComponent\r\n *\r\n * Horizontal row container for content items.\r\n */\r\n@Component({\r\n selector: 'content-row',\r\n standalone: true,\r\n styles: [\r\n `\r\n :host {\r\n display: flex;\r\n gap: 12px;\r\n }\r\n `,\r\n ],\r\n template: `<ng-content />`,\r\n})\r\nexport class ContentRowComponent {}\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobileSectionComponent\r\n * \r\n * Universal section component for mobile pages, modals, and content containers.\r\n * Provides consistent layout with optional headlines, action links, flexible padding, and borders.\r\n * \r\n * **Features:**\r\n * - Optional section headline with icon support\r\n * - Optional action link with click handler\r\n * - Flexible padding control\r\n * - Border management (bottom border by default)\r\n * - Works in pages, modals, and any content container\r\n * \r\n * **Usage Patterns:**\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Section with headline and link -->\r\n * <ds-mobile-section \r\n * headline=\"Recent Posts\"\r\n * linkText=\"See all\"\r\n * (linkClick)=\"navigate()\">\r\n * <div class=\"posts-list\">...</div>\r\n * </ds-mobile-section>\r\n * \r\n * <!-- Section with icon in headline -->\r\n * <ds-mobile-section \r\n * headline=\"Messages\"\r\n * icon=\"remixChat3Line\"\r\n * linkText=\"View all\"\r\n * (linkClick)=\"viewMessages()\">\r\n * <div class=\"messages\">...</div>\r\n * </ds-mobile-section>\r\n * \r\n * <!-- Empty state section (no headline) -->\r\n * <ds-mobile-section>\r\n * <div class=\"empty-state\">\r\n * <ds-avatar type=\"icon\" iconName=\"remixInboxLine\" />\r\n * <h3>No messages yet</h3>\r\n * </div>\r\n * </ds-mobile-section>\r\n * \r\n * <!-- Last section without border -->\r\n * <ds-mobile-section \r\n * headline=\"Contact\"\r\n * [showBorder]=\"false\">\r\n * <div class=\"contact-form\">...</div>\r\n * </ds-mobile-section>\r\n * \r\n * <!-- Section with custom padding -->\r\n * <ds-mobile-section \r\n * headline=\"Photos\"\r\n * padding=\"20px 0\">\r\n * <div class=\"photo-grid\">...</div>\r\n * </ds-mobile-section>\r\n *\r\n * <!-- Full-width section in page (default behavior) -->\r\n * <ds-mobile-page-main title=\"Home\">\r\n * <ds-mobile-section headline=\"Posts\">\r\n * <div class=\"posts\">...</div>\r\n * </ds-mobile-section>\r\n * </ds-mobile-page-main>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-section',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent],\r\n host: {\r\n '[class.has-border]': 'showBorder()'\r\n },\r\n styles: [`\r\n :host {\r\n display: block;\r\n width: 100%;\r\n border-bottom: 1px solid transparent;\r\n transition: border-color 0.2s ease;\r\n }\r\n \r\n :host(.has-border) {\r\n border-bottom-color: var(--border-color-default);\r\n }\r\n \r\n /* Automatically hide border on last section */\r\n :host(.has-border):last-child {\r\n border-bottom-color: transparent;\r\n }\r\n \r\n .section {\r\n width: 100%;\r\n display: flex;\r\n flex-direction: column;\r\n padding: var(--section-padding, 20px);\r\n gap: var(--section-gap, 12px);\r\n overflow: var(--section-overflow);\r\n }\r\n \r\n /* Increase padding on desktop breakpoints */\r\n @media (min-width: 768px) {\r\n .section {\r\n padding: var(--section-padding, 32px);\r\n }\r\n \r\n /* Remove horizontal padding on desktop when inside page components */\r\n ds-mobile-page-main :host .section,\r\n ds-mobile-page-details :host .section {\r\n padding-left: 0;\r\n padding-right: 0;\r\n }\r\n }\r\n \r\n .section-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 12px;\r\n min-height: 24px;\r\n }\r\n \r\n .section-headline {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n color: var(--text-color-default-primary);\r\n margin: 0;\r\n padding: 0;\r\n letter-spacing: -0.2px;\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n line-height: 1.4;\r\n }\r\n \r\n .section-link {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 500;\r\n color: var(--color-accent, #5d5fef);\r\n text-decoration: none;\r\n cursor: pointer;\r\n white-space: nowrap;\r\n transition: opacity 0.2s ease;\r\n -webkit-tap-highlight-color: transparent;\r\n display: flex;\r\n align-items: center;\r\n gap: 2px;\r\n line-height: 1;\r\n user-select: none;\r\n }\r\n \r\n .section-link:hover {\r\n opacity: 0.8;\r\n }\r\n \r\n .section-link:active {\r\n opacity: 0.6;\r\n }\r\n \r\n .section-content {\r\n display: flex;\r\n flex-direction: column;\r\n gap: var(--section-content-gap);\r\n }\r\n `],\r\n template: `\r\n <section class=\"section\" [style.--section-padding]=\"padding()\" [style.--section-gap]=\"gap()\" [style.--section-content-gap]=\"contentGap()\" [style.--section-overflow]=\"overflow()\">\r\n @if (headline() || linkText()) {\r\n <header class=\"section-header\">\r\n @if (headline()) {\r\n <h2 class=\"section-headline\">\r\n @if (icon()) {\r\n <ds-icon [name]=\"icon()!\" size=\"20px\" />\r\n }\r\n {{ headline() }}\r\n </h2>\r\n }\r\n @if (linkText()) {\r\n <a class=\"section-link\" (click)=\"handleLinkClick()\" [attr.role]=\"'button'\" [attr.tabindex]=\"0\">\r\n {{ linkText() }}\r\n <ds-icon name=\"remixArrowRightSLine\" size=\"16px\" />\r\n </a>\r\n }\r\n <ng-content select=\"[header-action]\" />\r\n </header>\r\n }\r\n \r\n <div class=\"section-content\">\r\n <ng-content />\r\n </div>\r\n </section>\r\n `\r\n})\r\nexport class DsMobileSectionComponent {\r\n /**\r\n * Section headline text\r\n * @default ''\r\n */\r\n headline = input<string>('');\r\n \r\n /**\r\n * Optional icon to display before headline\r\n * @default ''\r\n */\r\n icon = input<string>('');\r\n \r\n /**\r\n * Link text (e.g., \"See all\", \"View more\")\r\n * When provided, displays a clickable link in the section header\r\n * @default ''\r\n */\r\n linkText = input<string>('');\r\n \r\n /**\r\n * Section padding\r\n * Accepts any valid CSS padding value\r\n * When not set, defaults to 20px on mobile and 32px on desktop\r\n * @default ''\r\n */\r\n padding = input<string>('');\r\n \r\n /**\r\n * Gap between section header and content\r\n * Accepts any valid CSS gap value\r\n * @default '12px'\r\n */\r\n gap = input<string>('12px');\r\n \r\n /**\r\n * Gap between child elements within section-content\r\n * Accepts any valid CSS gap value\r\n * @default '12px'\r\n */\r\n contentGap = input<string>('12px');\r\n \r\n /**\r\n * Whether to show bottom border\r\n * @default true\r\n */\r\n showBorder = input<boolean>(true);\r\n \r\n /**\r\n * CSS overflow property for the section\r\n * @default 'visible'\r\n */\r\n overflow = input<string>('visible');\r\n \r\n /**\r\n * Emitted when section link is clicked\r\n */\r\n linkClick = output<void>();\r\n \r\n /**\r\n * Handle link click event\r\n */\r\n handleLinkClick(): void {\r\n this.linkClick.emit();\r\n }\r\n}\r\n\r\n","import { Component, input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n/**\r\n * DsMobileHeaderContentComponent\r\n * \r\n * Container for header content tiles - displays tiles in a responsive grid.\r\n * Used within the expandable header section of mobile pages to show\r\n * summary information like property details, statistics, etc.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-header-content header-content>\r\n * <ds-mobile-header-content-tile>\r\n * <tile-icon>\r\n * <ds-icon name=\"remixHome4Line\" />\r\n * </tile-icon>\r\n * <tile-content>\r\n * <tile-label>Area</tile-label>\r\n * <tile-value>120 m²</tile-value>\r\n * </tile-content>\r\n * </ds-mobile-header-content-tile>\r\n * </ds-mobile-header-content>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-header-content',\r\n standalone: true,\r\n imports: [CommonModule],\r\n styles: [`\r\n :host {\r\n display: grid;\r\n grid-template-columns: repeat(2, 1fr);\r\n gap: 12px;\r\n }\r\n \r\n @media (min-width: 768px) {\r\n :host {\r\n grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));\r\n }\r\n }\r\n `],\r\n template: `<ng-content select=\"ds-mobile-header-content-tile\" />`\r\n})\r\nexport class DsMobileHeaderContentComponent {}\r\n\r\n/**\r\n * DsMobileHeaderContentTileComponent\r\n * \r\n * Individual tile for displaying summary information in the header.\r\n * Styled with purple background to match the mobile header theme.\r\n * \r\n * Must contain:\r\n * - `<tile-icon>` - Icon container (optional)\r\n * - `<tile-content>` - Label and value container\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-header-content-tile>\r\n * <tile-icon>\r\n * <ds-icon name=\"remixHome4Line\" size=\"20px\" color=\"#DFE4FF\" />\r\n * </tile-icon>\r\n * <tile-content>\r\n * <tile-label>Rooms</tile-label>\r\n * <tile-value>3 rooms</tile-value>\r\n * </tile-content>\r\n * </ds-mobile-header-content-tile>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-header-content-tile',\r\n standalone: true,\r\n imports: [CommonModule],\r\n styles: [`\r\n :host {\r\n background: rgba(var(--color-header-content-rgb, 255, 255, 255), 0.05);\r\n border: 1px solid rgba(var(--color-header-content-rgb, 255, 255, 255), 0.1);\r\n border-radius: 12px;\r\n padding: 12px;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 16px;\r\n }\r\n `],\r\n template: `\r\n <ng-content select=\"tile-icon\" />\r\n <ng-content select=\"tile-content\" />\r\n `\r\n})\r\nexport class DsMobileHeaderContentTileComponent {}\r\n\r\n/**\r\n * TileIconComponent\r\n * \r\n * Semantic slot for tile icon with dark purple background.\r\n * Use within `ds-mobile-header-content-tile`.\r\n */\r\n@Component({\r\n selector: 'tile-icon',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n background: var(--color-header-surface);\r\n border-radius: 8px;\r\n width: 32px;\r\n height: 32px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n color: var(--color-header-content, #ffffff);\r\n }\r\n \r\n /* Apply color to ds-icon inside */\r\n :host ::ng-deep ds-icon {\r\n --icon-color: var(--color-header-content, #ffffff);\r\n color: var(--color-header-content, #ffffff);\r\n }\r\n \r\n :host ::ng-deep ds-icon svg {\r\n fill: var(--color-header-content, #ffffff);\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class TileIconComponent {}\r\n\r\n/**\r\n * TileContentComponent\r\n * \r\n * Semantic slot for tile content containing label and value.\r\n * Use within `ds-mobile-header-content-tile`.\r\n * \r\n * Contains:\r\n * - `<tile-label>` - Small label text\r\n * - `<tile-value>` - Large value text\r\n */\r\n@Component({\r\n selector: 'tile-content',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 0;\r\n }\r\n \r\n ::ng-deep tile-label {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.56px;\r\n color: rgba(var(--color-header-content-rgb, 255, 255, 255), 0.8);\r\n display: block;\r\n }\r\n \r\n ::ng-deep tile-value {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-lg);\r\n font-weight: 600;\r\n line-height: 26px;\r\n letter-spacing: -0.72px;\r\n color: var(--color-header-content, #ffffff);\r\n display: block;\r\n }\r\n `],\r\n template: `\r\n <ng-content select=\"tile-label\" />\r\n <ng-content select=\"tile-value\" />\r\n `\r\n})\r\nexport class TileContentComponent {}\r\n\r\n/**\r\n * TileLabelComponent\r\n * \r\n * Label text for tile content.\r\n * Use within `tile-content` inside `ds-mobile-header-content-tile`.\r\n */\r\n@Component({\r\n selector: 'tile-label',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.56px;\r\n color: rgba(var(--color-header-content-rgb, 255, 255, 255), 0.8);\r\n display: block;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class TileLabelComponent {}\r\n\r\n/**\r\n * TileValueComponent\r\n * \r\n * Value text for tile content.\r\n * Use within `tile-content` inside `ds-mobile-header-content-tile`.\r\n */\r\n@Component({\r\n selector: 'tile-value',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-lg);\r\n font-weight: 600;\r\n line-height: 26px;\r\n letter-spacing: -0.72px;\r\n color: var(--color-header-content, #ffffff);\r\n display: block;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class TileValueComponent {}\r\n\r\n","import { Component, input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n/**\r\n * DsMobileSystemMessageBannerComponent\r\n * \r\n * Full-width centered banner component for displaying system messages in chat conversations.\r\n * Uses the same text styling as message bubbles for consistency.\r\n * \r\n * Features:\r\n * - Full-width centered layout\r\n * - Subtle background with theming support\r\n * - Same typography as message bubbles\r\n * - Optional icon support\r\n * \r\n * Common use cases:\r\n * - Inquiry status updates (\"Your inquiry has been assigned to...\")\r\n * - System notifications (\"This inquiry is marked as resolved\")\r\n * - Auto-replies (\"We aim to respond within 24 hours...\")\r\n * - Time/date separators\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Simple system message -->\r\n * <ds-mobile-system-message-banner\r\n * [message]=\"'Ricki Meihlen har overtaget din henvendelse og vil kontakte dig snart.'\">\r\n * </ds-mobile-system-message-banner>\r\n * \r\n * <!-- With icon -->\r\n * <ds-mobile-system-message-banner\r\n * [message]=\"'Vi bestræber os på at svare inden for 24 timer på hverdage.'\"\r\n * [iconName]=\"'remixInformationLine'\">\r\n * </ds-mobile-system-message-banner>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-system-message-banner',\r\n standalone: true,\r\n imports: [CommonModule],\r\n host: {\r\n '[class.after-timestamp]': 'afterTimestamp()'\r\n },\r\n styles: [`\r\n :host {\r\n display: block;\r\n width: 100%;\r\n padding: 12px 0;\r\n }\r\n \r\n :host(.after-timestamp) {\r\n padding-top: 0;\r\n }\r\n \r\n .system-message-container {\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n width: 100%;\r\n padding: 0 16px;\r\n }\r\n \r\n .system-message-content {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 8px;\r\n padding: 8px 16px;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-radius: 16px;\r\n max-width: 85%;\r\n text-align: center;\r\n }\r\n \r\n .system-message-icon {\r\n flex-shrink: 0;\r\n width: 16px;\r\n height: 16px;\r\n color: var(--color-text-tertiary, #a0a0a0);\r\n }\r\n \r\n .system-message-text {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-secondary, #666666);\r\n margin: 0;\r\n }\r\n `],\r\n template: `\r\n <div class=\"system-message-container\">\r\n <div class=\"system-message-content\">\r\n @if (iconName()) {\r\n <span class=\"system-message-icon\">\r\n <!-- Icon slot - you can add ds-icon component here if needed -->\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 24 24\" fill=\"currentColor\">\r\n <path d=\"M12 22C6.477 22 2 17.523 2 12S6.477 2 12 2s10 4.477 10 10-4.477 10-10 10zm0-2a8 8 0 1 0 0-16 8 8 0 0 0 0 16zM11 7h2v2h-2V7zm0 4h2v6h-2v-6z\"/>\r\n </svg>\r\n </span>\r\n }\r\n <p class=\"system-message-text\">{{ message() }}</p>\r\n </div>\r\n </div>\r\n `\r\n})\r\nexport class DsMobileSystemMessageBannerComponent {\r\n /**\r\n * System message text to display\r\n */\r\n message = input.required<string>();\r\n \r\n /**\r\n * Optional icon name (currently using inline SVG for info icon)\r\n * Can be extended to support full icon library integration\r\n */\r\n iconName = input<string>('');\r\n \r\n /**\r\n * Whether this system message appears directly after a timestamp\r\n * When true, removes top padding to reduce spacing\r\n */\r\n afterTimestamp = input<boolean>(false);\r\n}\r\n\r\n\r\n\r\n\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobileFileAttachmentComponent\r\n * \r\n * File attachment display for various document types.\r\n * Shows file info card with icon, filename, and file size.\r\n * Supports PDF and generic document formats.\r\n * Emits click event to open file in viewer.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-file-attachment\r\n * [fileName]=\"'Document.pdf'\"\r\n * [fileSize]=\"'1.2 MB'\"\r\n * [variant]=\"'pdf'\"\r\n * (fileClick)=\"openFile()\">\r\n * </ds-mobile-file-attachment>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-file-attachment',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent, DsIconComponent],\r\n host: {\r\n '(click)': 'handleClick($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n padding: 10px 12px;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-radius: 16px;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n }\r\n \r\n :host:hover {\r\n background: var(--color-background-neutral-secondary-hover, #ebebeb);\r\n }\r\n \r\n :host:active {\r\n transform: scale(0.98);\r\n }\r\n \r\n .file-avatar {\r\n flex-shrink: 0;\r\n }\r\n \r\n .file-avatar.pdf::ng-deep .avatar--icon {\r\n background-color: #ff5757 !important;\r\n }\r\n \r\n .file-avatar.doc::ng-deep .avatar--icon {\r\n background-color: var(--color-blue-base, #3B82F6) !important;\r\n }\r\n \r\n .file-info {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 2px;\r\n }\r\n \r\n .file-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n .file-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--color-text-tertiary, #737373);\r\n }\r\n \r\n .open-icon {\r\n color: var(--color-text-tertiary, #a3a3a3);\r\n flex-shrink: 0;\r\n }\r\n `],\r\n template: `\r\n <div class=\"file-avatar\" [class.pdf]=\"variant() === 'pdf'\" [class.doc]=\"variant() === 'doc'\">\r\n <ds-avatar\r\n type=\"icon\"\r\n [iconName]=\"getIconName()\"\r\n size=\"lg\"\r\n />\r\n </div>\r\n \r\n <div class=\"file-info\">\r\n <div class=\"file-name\">{{ fileName() }}</div>\r\n @if (fileSize()) {\r\n <div class=\"file-meta\">{{ getFileTypeLabel() }} · {{ fileSize() }}</div>\r\n } @else {\r\n <div class=\"file-meta\">{{ getFileTypeLabel() }}</div>\r\n }\r\n </div>\r\n \r\n <ds-icon \r\n name=\"remixArrowRightSLine\" \r\n size=\"20px\"\r\n class=\"open-icon\"\r\n />\r\n `\r\n})\r\nexport class DsMobileFileAttachmentComponent {\r\n /**\r\n * File name\r\n */\r\n fileName = input<string>('Document');\r\n \r\n /**\r\n * File size display (e.g., \"1.2 MB\")\r\n */\r\n fileSize = input<string>('');\r\n \r\n /**\r\n * File type variant\r\n * - 'pdf' - PDF document (red icon)\r\n * - 'doc' - Generic document (blue icon)\r\n */\r\n variant = input<'pdf' | 'doc'>('doc');\r\n \r\n /**\r\n * Emits when the file attachment is clicked\r\n */\r\n fileClick = output<void>();\r\n \r\n /**\r\n * Get the appropriate icon name based on variant\r\n */\r\n getIconName(): string {\r\n return this.variant() === 'pdf' ? 'remixFileTextLine' : 'remixAttachmentLine';\r\n }\r\n \r\n /**\r\n * Get the file type label based on variant\r\n */\r\n getFileTypeLabel(): string {\r\n return this.variant() === 'pdf' ? 'PDF' : 'DOC';\r\n }\r\n \r\n handleClick(event: Event): void {\r\n event.stopPropagation();\r\n this.fileClick.emit();\r\n }\r\n}\r\n\r\n","import { Component, input, output, signal, computed, inject, PLATFORM_ID, effect } from '@angular/core';\r\nimport { CommonModule, isPlatformBrowser } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\n\r\n/**\r\n * DsMobileCommentComponent\r\n *\r\n * Individual comment component for post discussions.\r\n * Displays user comments with avatar, content, and like action.\r\n *\r\n * @example\r\n * ```html\r\n * <ds-mobile-comment\r\n * [authorName]=\"'John Doe'\"\r\n * [authorRole]=\"'Tenant'\"\r\n * [timestamp]=\"'1h ago'\"\r\n * [avatarInitials]=\"'JD'\"\r\n * [content]=\"'Great post!'\">\r\n * </ds-mobile-comment>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-comment',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent, DsIconComponent, DsIconButtonComponent],\r\n styleUrls: ['../shared/mobile-common.css'],\r\n host: {\r\n '[class.clickable]': 'clickable()',\r\n '(click)': 'handleCommentClick($event)',\r\n '(touchstart)': 'handleTouchStart($event)',\r\n '(touchend)': 'handleTouchEnd($event)',\r\n '(touchmove)': 'handleTouchMove($event)',\r\n '(contextmenu)': 'handleContextMenu($event)',\r\n },\r\n styles: [\r\n `\r\n :host {\r\n display: flex;\r\n gap: 12px;\r\n padding: 8px;\r\n position: relative;\r\n border-radius: 16px;\r\n transition: all 0.2s ease;\r\n background: var(--color-background-primary, #ffffff);\r\n margin-bottom: 8px;\r\n margin-left: -8px;\r\n margin-right: -8px;\r\n }\r\n\r\n :host:last-child {\r\n margin-bottom: 0;\r\n }\r\n\r\n :host::after {\r\n content: '';\r\n position: absolute;\r\n bottom: -4px;\r\n /* Align with comment content: padding (8px) + avatar (32px) + gap (12px) */\r\n left: 44px;\r\n /* Align with comment content right edge: padding (8px) from right */\r\n right: 8px;\r\n height: 1px;\r\n background: var(--border-color-default);\r\n }\r\n\r\n :host:last-child::after {\r\n display: none;\r\n }\r\n\r\n :host.clickable {\r\n cursor: pointer;\r\n }\r\n\r\n :host.clickable:active {\r\n background: var(--color-background-neutral-primary-hover, #f5f5f5);\r\n }\r\n\r\n .avatar-wrapper {\r\n position: relative;\r\n display: flex;\r\n align-items: flex-start;\r\n justify-content: center;\r\n flex-shrink: 0;\r\n }\r\n\r\n .comment-content {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 4px;\r\n }\r\n\r\n .comment-header {\r\n display: flex;\r\n align-items: baseline;\r\n gap: 6px;\r\n flex-wrap: wrap;\r\n }\r\n\r\n /* Wrapper for like and more actions */\r\n .header-actions {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n margin-left: auto;\r\n }\r\n\r\n /* Desktop more actions button - using ds-icon-button */\r\n .desktop-more-button::ng-deep button {\r\n border-radius: 50% !important;\r\n }\r\n\r\n /* Author styles imported from mobile-common.css */\r\n\r\n .action-like {\r\n display: flex;\r\n align-items: center;\r\n gap: 2px;\r\n color: var(--color-text-secondary, #737373);\r\n cursor: pointer;\r\n transition: color 0.2s ease;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 500;\r\n line-height: 18px;\r\n }\r\n\r\n .like-count {\r\n opacity: 1;\r\n }\r\n\r\n .like-count.hidden {\r\n opacity: 0;\r\n }\r\n\r\n .action-like.active {\r\n color: #f91880;\r\n }\r\n\r\n .icon-wrapper {\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n\r\n .icon-pulse {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n opacity: 0;\r\n pointer-events: none;\r\n }\r\n\r\n .icon-pulse.animating {\r\n animation: pulse 0.4s cubic-bezier(0.4, 0, 0.2, 1);\r\n }\r\n\r\n @keyframes pulse {\r\n 0% {\r\n transform: translate(-50%, -50%) scale(1);\r\n opacity: 0.8;\r\n }\r\n 100% {\r\n transform: translate(-50%, -50%) scale(2.5);\r\n opacity: 0;\r\n }\r\n }\r\n\r\n .comment-text {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 22px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n white-space: pre-wrap;\r\n word-wrap: break-word;\r\n }\r\n\r\n .comment-text ::ng-deep .mention {\r\n color: var(--color-accent, #6b5ff5) !important;\r\n font-weight: 600;\r\n }\r\n\r\n .comment-actions {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n margin-top: 4px;\r\n }\r\n\r\n .action-reply {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 500;\r\n line-height: 18px;\r\n color: var(--color-text-secondary, #737373);\r\n cursor: pointer;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n transition: color 0.2s ease;\r\n }\r\n\r\n .action-reply:hover {\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n\r\n .action-edit {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 500;\r\n line-height: 18px;\r\n color: var(--color-text-secondary, #737373);\r\n cursor: pointer;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n transition: color 0.2s ease;\r\n }\r\n\r\n .action-edit:hover {\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n `,\r\n ],\r\n template: `\r\n <div class=\"avatar-wrapper\">\r\n <ds-avatar [initials]=\"avatarInitials()\" [type]=\"avatarType()\" size=\"sm\" />\r\n </div>\r\n\r\n <div class=\"comment-content\">\r\n <div class=\"comment-header\">\r\n <span class=\"author-name\">{{ authorName() }}</span>\r\n <span class=\"author-meta\">{{ authorRole() }} · {{ timestamp() }}</span>\r\n\r\n <!-- Wrapper for like and more actions -->\r\n <div class=\"header-actions\">\r\n <div class=\"action-like\" [class.active]=\"internalIsLiked()\" (click)=\"toggleLike()\">\r\n <span class=\"like-count\" [class.hidden]=\"internalLikeCount() === 0\">{{ internalLikeCount() }}</span>\r\n <div class=\"icon-wrapper\">\r\n <ds-icon class=\"icon-pulse\" [class.animating]=\"isPulsing()\" [name]=\"internalIsLiked() ? 'remixHeart3Fill' : 'remixHeart3Line'\" size=\"16px\" />\r\n <ds-icon [name]=\"internalIsLiked() ? 'remixHeart3Fill' : 'remixHeart3Line'\" size=\"16px\" />\r\n </div>\r\n </div>\r\n\r\n @if (shouldShowMoreButton()) {\r\n <ds-icon-button class=\"desktop-more-button\" icon=\"remixMoreFill\" variant=\"secondary\" size=\"sm\" (clicked)=\"handleMoreButtonClick($event)\" aria-label=\"More options\">\r\n </ds-icon-button>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"comment-text\" [innerHTML]=\"formattedContent()\"></div>\r\n\r\n <div class=\"comment-actions\">\r\n <div class=\"action-reply\" (click)=\"handleReply()\">{{ replyLabel() }}</div>\r\n @if (isOwnComment()) {\r\n <div class=\"action-edit\" (click)=\"handleEdit()\">{{ editLabel() }}</div>\r\n }\r\n </div>\r\n </div>\r\n `,\r\n})\r\nexport class DsMobileCommentComponent {\r\n private platformId = inject(PLATFORM_ID);\r\n \r\n /**\r\n * Detect if viewport is desktop size\r\n * Use viewport width for breakpoint detection (show button on tablet and above)\r\n */\r\n isDesktop = signal<boolean>(false);\r\n \r\n constructor() {\r\n if (isPlatformBrowser(this.platformId)) {\r\n // Show button on tablet breakpoint and above (768px+)\r\n const isDesktopViewport = window.innerWidth >= 768;\r\n \r\n console.log('[Comment] Desktop detection:', {\r\n innerWidth: window.innerWidth,\r\n isDesktopViewport\r\n });\r\n \r\n this.isDesktop.set(isDesktopViewport);\r\n \r\n // Listen for window resize to update detection\r\n window.addEventListener('resize', () => {\r\n const newIsDesktop = window.innerWidth >= 768;\r\n if (newIsDesktop !== this.isDesktop()) {\r\n console.log('[Comment] Viewport changed, updating desktop detection:', newIsDesktop);\r\n this.isDesktop.set(newIsDesktop);\r\n }\r\n });\r\n }\r\n\r\n // Sync input signals with internal signals\r\n effect(() => {\r\n this.internalIsLiked.set(this.isLiked());\r\n });\r\n\r\n effect(() => {\r\n this.internalLikeCount.set(this.likeCount());\r\n });\r\n }\r\n \r\n /**\r\n * Author's display name\r\n */\r\n authorName = input.required<string>();\r\n\r\n /**\r\n * Author's role (e.g., \"Tenant\", \"Property Manager\")\r\n */\r\n authorRole = input.required<string>();\r\n\r\n /**\r\n * Timestamp text (e.g., \"1h ago\", \"2d ago\")\r\n */\r\n timestamp = input.required<string>();\r\n\r\n /**\r\n * Comment content text\r\n */\r\n content = input.required<string>();\r\n\r\n /**\r\n * Avatar initials\r\n */\r\n avatarInitials = input<string>('');\r\n\r\n /**\r\n * Avatar type\r\n */\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n\r\n /**\r\n * Whether the comment is clickable\r\n */\r\n clickable = input<boolean>(false);\r\n\r\n /**\r\n * Unified toggle for contextual actions (more button + long press).\r\n * - `true` — more button visible on **all** breakpoints, long press enabled\r\n * - `false` — more button hidden, long press suppressed\r\n * - `undefined` (default) — falls back to desktop-only button\r\n */\r\n moreActions = input<boolean | undefined>(undefined);\r\n\r\n shouldShowMoreButton = computed(() => {\r\n const ma = this.moreActions();\r\n if (ma !== undefined) return ma;\r\n return this.isDesktop();\r\n });\r\n\r\n /**\r\n * Label for the reply action button\r\n */\r\n replyLabel = input<string>('Svar');\r\n\r\n /**\r\n * Label for the edit action button\r\n */\r\n editLabel = input<string>('Rediger');\r\n\r\n /**\r\n * Whether this comment belongs to the current user\r\n */\r\n isOwnComment = input<boolean>(false);\r\n\r\n /**\r\n * Whether the comment is liked by current user\r\n */\r\n isLiked = input<boolean>(false);\r\n\r\n /**\r\n * Emits when like is toggled (after UI is opdateret)\r\n */\r\n likeToggled = output<{ active: boolean; count: number }>();\r\n\r\n /**\r\n * Number of likes\r\n */\r\n likeCount = input<number>(0);\r\n\r\n /**\r\n * Internal signal to track like state for UI updates\r\n */\r\n internalIsLiked = signal<boolean>(false);\r\n\r\n /**\r\n * Internal signal to track like count for UI updates\r\n */\r\n internalLikeCount = signal<number>(0);\r\n\r\n /**\r\n * Signal to control pulse animation\r\n */\r\n isPulsing = signal(false);\r\n\r\n /**\r\n * Computed property to format content with @mentions\r\n */\r\n formattedContent = computed(() => {\r\n const text = this.content();\r\n // Replace @mentions with styled spans\r\n // Matches @FirstName or @FirstName LastName (max 2 words)\r\n return text.replace(/@([A-Za-z]+(?:\\s+[A-Za-z]+)?)\\b/g, '<span class=\"mention\">@$1</span>');\r\n });\r\n\r\n /**\r\n * Emits when the comment card is clicked (if clickable)\r\n */\r\n commentClick = output<void>();\r\n\r\n /**\r\n * Emits when reply is clicked\r\n */\r\n replyClick = output<void>();\r\n\r\n /**\r\n * Emits when edit is clicked\r\n */\r\n editClick = output<void>();\r\n\r\n /**\r\n * Emits when the comment is long-pressed\r\n */\r\n longPress = output<void>();\r\n\r\n /**\r\n * Long press tracking\r\n */\r\n private longPressTimer: any = null;\r\n private longPressTriggered = false;\r\n private touchStartX = 0;\r\n private touchStartY = 0;\r\n private readonly LONG_PRESS_DURATION = 500; // ms\r\n private readonly MOVE_THRESHOLD = 10; // px\r\n\r\n handleCommentClick(event: Event): void {\r\n // Only emit if clickable and not clicking on action buttons\r\n if (this.clickable() && !(event.target as HTMLElement).closest('.comment-actions')) {\r\n this.commentClick.emit();\r\n }\r\n }\r\n\r\n async toggleLike(): Promise<void> {\r\n const newLiked = !this.internalIsLiked();\r\n this.internalIsLiked.set(newLiked);\r\n\r\n const newCount = newLiked ? this.internalLikeCount() + 1 : this.internalLikeCount() - 1;\r\n this.internalLikeCount.set(Math.max(0, newCount));\r\n\r\n // Emit the like toggled event\r\n this.likeToggled.emit({ active: newLiked, count: Math.max(0, newCount) });\r\n\r\n // Trigger pulse animation only when liking\r\n if (newLiked) {\r\n this.isPulsing.set(true);\r\n setTimeout(() => this.isPulsing.set(false), 400);\r\n }\r\n\r\n // Haptic feedback for like/unlike\r\n try {\r\n await Haptics.impact({ style: ImpactStyle.Light });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n navigator.vibrate(50);\r\n }\r\n }\r\n }\r\n\r\n handleReply(): void {\r\n this.replyClick.emit();\r\n }\r\n\r\n handleEdit(): void {\r\n this.editClick.emit();\r\n }\r\n\r\n /**\r\n * Handle touch start for long press detection\r\n */\r\n handleTouchStart(event: TouchEvent): void {\r\n if (this.moreActions() === false) return;\r\n this.longPressTriggered = false;\r\n this.touchStartX = event.touches[0].clientX;\r\n this.touchStartY = event.touches[0].clientY;\r\n\r\n // Start long press timer\r\n this.longPressTimer = setTimeout(async () => {\r\n this.longPressTriggered = true;\r\n this.longPress.emit();\r\n\r\n // Haptic feedback for long press\r\n try {\r\n await Haptics.impact({ style: ImpactStyle.Medium });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n navigator.vibrate(50);\r\n }\r\n }\r\n }, this.LONG_PRESS_DURATION);\r\n }\r\n\r\n /**\r\n * Handle touch end to clear long press timer\r\n */\r\n handleTouchEnd(event: TouchEvent): void {\r\n if (this.longPressTimer) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n }\r\n\r\n // Prevent normal click if long press was triggered\r\n if (this.longPressTriggered) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.longPressTriggered = false;\r\n }\r\n }\r\n\r\n /**\r\n * Handle touch move to cancel long press if moved too much\r\n */\r\n handleTouchMove(event: TouchEvent): void {\r\n if (!this.longPressTimer) return;\r\n\r\n const touch = event.touches[0];\r\n const deltaX = Math.abs(touch.clientX - this.touchStartX);\r\n const deltaY = Math.abs(touch.clientY - this.touchStartY);\r\n\r\n // Cancel long press if moved too far\r\n if (deltaX > this.MOVE_THRESHOLD || deltaY > this.MOVE_THRESHOLD) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n this.longPressTriggered = false;\r\n }\r\n }\r\n\r\n /**\r\n * Handle context menu (right-click on desktop) to trigger long press action\r\n */\r\n handleContextMenu(event: Event): void {\r\n if (this.moreActions() === false) return;\r\n event.preventDefault();\r\n this.longPress.emit();\r\n }\r\n\r\n /**\r\n * Handle desktop more button click\r\n * Stops propagation and triggers long press action\r\n */\r\n handleMoreButtonClick(event: Event): void {\r\n console.log('[Comment] Desktop more button clicked');\r\n event.stopPropagation();\r\n event.preventDefault();\r\n this.longPress.emit();\r\n }\r\n}\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobilePostComposerComponent\r\n * \r\n * A \"fake\" input composer for creating new posts in the community feed.\r\n * Features a user avatar, placeholder input, and post button.\r\n * Clicking opens the full post creation modal/page.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-post-composer\r\n * [avatarInitials]=\"'LM'\"\r\n * [avatarType]=\"'photo'\"\r\n * [avatarSrc]=\"'...'\"\r\n * (composerClick)=\"openPostCreator()\">\r\n * </ds-mobile-post-composer>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-post-composer',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent],\r\n host: {\r\n '(click)': 'handleClick()'\r\n },\r\n styles: [`\r\n :host {\r\n display: block;\r\n max-width: 640px;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n }\r\n \r\n .composer-container {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n }\r\n \r\n .composer-input-wrapper {\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .composer-input {\r\n width: 100%;\r\n background: rgba(var(--header-content-color-rgb, 255, 255, 255), 0.1);\r\n border: none;\r\n border-radius: 24px;\r\n padding: 10px 16px;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: rgba(var(--header-content-color-rgb, 255, 255, 255), 0.75);\r\n outline: none;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n pointer-events: none;\r\n user-select: none;\r\n }\r\n \r\n .composer-input::placeholder {\r\n color: rgba(var(--header-content-color-rgb, 255, 255, 255), 0.75);\r\n opacity: 1;\r\n }\r\n \r\n /* Hover effects for desktop */\r\n @media (hover: hover) {\r\n :host:hover .composer-input {\r\n opacity: 0.8;\r\n }\r\n }\r\n `],\r\n template: `\r\n <div class=\"composer-container\">\r\n <ds-avatar \r\n [initials]=\"avatarInitials()\"\r\n [type]=\"avatarType()\"\r\n [src]=\"avatarSrc()\"\r\n [iconName]=\"avatarIconName()\"\r\n size=\"md\" />\r\n \r\n <div class=\"composer-input-wrapper\">\r\n <input \r\n type=\"text\" \r\n class=\"composer-input\" \r\n [placeholder]=\"placeholder()\"\r\n readonly\r\n tabindex=\"-1\"\r\n />\r\n </div>\r\n </div>\r\n `\r\n})\r\nexport class DsMobilePostComposerComponent {\r\n /**\r\n * Avatar initials (for initials type)\r\n */\r\n avatarInitials = input<string>('');\r\n \r\n /**\r\n * Avatar type\r\n */\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n \r\n /**\r\n * Avatar photo source (for photo type)\r\n */\r\n avatarSrc = input<string>('');\r\n \r\n /**\r\n * Icon name (for icon type avatars)\r\n */\r\n avatarIconName = input<string>('remixUser3Fill');\r\n \r\n /**\r\n * Placeholder text for the input\r\n */\r\n placeholder = input<string>(\"Hvad er nyt?\");\r\n \r\n /**\r\n * Text for the post button\r\n */\r\n buttonText = input<string>('Slå op');\r\n \r\n /**\r\n * Emits when the composer is clicked\r\n */\r\n composerClick = output<void>();\r\n \r\n handleClick(): void {\r\n this.composerClick.emit();\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsMobileLoaderOverlayComponent } from '../loader-overlay';\r\n\r\n/**\r\n * File type for attachment preview\r\n */\r\nexport type AttachmentFileType = 'image' | 'pdf' | 'doc' | 'docx' | 'xls' | 'xlsx' | 'other';\r\n\r\n/**\r\n * Attachment data interface\r\n */\r\nexport interface AttachmentData {\r\n id: string;\r\n src: string;\r\n type: AttachmentFileType;\r\n name?: string;\r\n size?: string;\r\n isLoading?: boolean;\r\n}\r\n\r\n/**\r\n * DsMobileAttachmentPreviewComponent\r\n * \r\n * Reusable component for displaying attachment previews.\r\n * Supports both image previews and file type indicators (PDF, DOCX, etc.).\r\n * \r\n * Features:\r\n * - Image preview for photos\r\n * - File type indicator box for documents\r\n * - Remove button overlay\r\n * - Consistent 96x96 size\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Image attachment -->\r\n * <ds-mobile-attachment-preview\r\n * [attachment]=\"{ id: '1', src: 'photo.jpg', type: 'image' }\"\r\n * (remove)=\"handleRemove($event)\">\r\n * </ds-mobile-attachment-preview>\r\n * \r\n * <!-- PDF attachment -->\r\n * <ds-mobile-attachment-preview\r\n * [attachment]=\"{ id: '2', src: 'doc.pdf', type: 'pdf', name: 'Document.pdf' }\"\r\n * (remove)=\"handleRemove($event)\">\r\n * </ds-mobile-attachment-preview>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-attachment-preview',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent, DsMobileLoaderOverlayComponent],\r\n styleUrls: ['./ds-mobile-attachment-preview.css'],\r\n template: `\r\n <div class=\"attachment-preview\" [class.loading]=\"attachment().isLoading\">\r\n @if (attachment().type === 'image') {\r\n <!-- Image Preview -->\r\n <img \r\n [src]=\"attachment().src\" \r\n [alt]=\"attachment().name || 'Attachment'\" \r\n class=\"preview-image\" \r\n />\r\n } @else {\r\n <!-- File Type Preview -->\r\n <div class=\"preview-file\">\r\n <div class=\"file-avatar\">\r\n <ds-avatar\r\n type=\"icon\"\r\n [iconName]=\"getIconName()\"\r\n size=\"md\"\r\n [class]=\"'file-' + attachment().type\"\r\n />\r\n </div>\r\n <div class=\"file-info\">\r\n <div class=\"file-name\" [title]=\"attachment().name || 'Unknown file'\">\r\n {{ attachment().name || 'Unknown file' }}\r\n </div>\r\n <div class=\"file-type-label\">{{ getFileTypeLabel() }}</div>\r\n </div>\r\n </div>\r\n }\r\n \r\n <!-- Loading Overlay -->\r\n @if (attachment().isLoading) {\r\n <ds-mobile-loader-overlay [borderRadius]=\"12\" />\r\n }\r\n \r\n <!-- Remove Button (hidden when loading) -->\r\n @if (!attachment().isLoading) {\r\n <button \r\n class=\"remove-btn\" \r\n (mousedown)=\"handleRemove($event)\"\r\n type=\"button\"\r\n [attr.aria-label]=\"'Remove ' + (attachment().name || 'attachment')\">\r\n <svg width=\"16\" height=\"16\" viewBox=\"0 0 16 16\" fill=\"none\">\r\n <path d=\"M12 4L4 12M4 4L12 12\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\"/>\r\n </svg>\r\n </button>\r\n }\r\n </div>\r\n `\r\n})\r\nexport class DsMobileAttachmentPreviewComponent {\r\n /**\r\n * Attachment data to display\r\n */\r\n attachment = input.required<AttachmentData>();\r\n \r\n /**\r\n * Emits when the remove button is clicked\r\n */\r\n remove = output<string>();\r\n \r\n /**\r\n * Get the file type label (PDF, DOCX, etc.)\r\n */\r\n getFileTypeLabel(): string {\r\n const type = this.attachment().type.toUpperCase();\r\n \r\n // Map common types to their display labels\r\n const labelMap: Record<string, string> = {\r\n 'PDF': 'PDF',\r\n 'DOC': 'DOC',\r\n 'DOCX': 'DOCX',\r\n 'XLS': 'XLS',\r\n 'XLSX': 'XLSX',\r\n 'OTHER': 'FILE'\r\n };\r\n \r\n return labelMap[type] || type;\r\n }\r\n \r\n /**\r\n * Get the appropriate icon name based on file type\r\n */\r\n getIconName(): string {\r\n const type = this.attachment().type;\r\n \r\n const iconMap: Record<AttachmentFileType, string> = {\r\n 'image': 'remixImageLine',\r\n 'pdf': 'remixFileTextLine',\r\n 'doc': 'remixFileTextLine',\r\n 'docx': 'remixFileTextLine',\r\n 'xls': 'remixFileList3Line',\r\n 'xlsx': 'remixFileList3Line',\r\n 'other': 'remixAttachmentLine'\r\n };\r\n \r\n return iconMap[type] || 'remixAttachmentLine';\r\n }\r\n \r\n /**\r\n * Handle remove button click\r\n * Uses mousedown to prevent keyboard from closing\r\n */\r\n handleRemove(event?: MouseEvent): void {\r\n if (event) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n }\r\n this.remove.emit(this.attachment().id);\r\n }\r\n}\r\n","import { \r\n Component, \r\n input, \r\n output, \r\n signal, \r\n computed, \r\n ContentChild, \r\n TemplateRef,\r\n ElementRef,\r\n inject,\r\n CUSTOM_ELEMENTS_SCHEMA,\r\n effect\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { IonPopover } from '@ionic/angular/standalone';\r\n\r\nexport interface DsMobileDropdownItem {\r\n id: string;\r\n /** Optional leading icon */\r\n leadingIcon?: string;\r\n /** Optional trailing icon */\r\n trailingIcon?: string;\r\n /** Main label text */\r\n label?: string;\r\n /** Whether the item is disabled */\r\n disabled?: boolean;\r\n /** Optional action callback */\r\n action?: () => void;\r\n /** Custom data for template rendering */\r\n data?: any;\r\n}\r\n\r\nexport type DropdownPosition = 'above' | 'below';\r\nexport type DropdownAlign = 'start' | 'end';\r\n\r\n/**\r\n * DsMobileDropdownComponent\r\n * \r\n * A mobile-optimized dropdown component for action menus, mention lists, and selection lists.\r\n * Uses Ionic Popover for robust mobile positioning and backdrop management.\r\n * \r\n * Features:\r\n * - Vertical list layout with leading/main/trailing slots\r\n * - Custom template support via content projection\r\n * - Mobile-friendly touch interactions (mousedown events)\r\n * - Ionic-powered backdrop overlay for dismissal\r\n * - Configurable positioning (above/below) and alignment (start/end)\r\n * - Max height with scroll support\r\n * - Smooth enter/exit animations\r\n * \r\n * @example\r\n * Basic dropdown with default items:\r\n * ```html\r\n * <button (click)=\"toggleMenu()\">Open Menu</button>\r\n * <ds-mobile-dropdown \r\n * [items]=\"menuItems\"\r\n * [isOpen]=\"isMenuOpen()\"\r\n * position=\"below\"\r\n * align=\"start\"\r\n * (itemSelected)=\"handleSelection($event)\"\r\n * (closed)=\"closeMenu()\">\r\n * </ds-mobile-dropdown>\r\n * ```\r\n * \r\n * @example\r\n * Custom template for mention menu with avatars:\r\n * ```html\r\n * <textarea (input)=\"handleInput($event)\"></textarea>\r\n * <ds-mobile-dropdown \r\n * [items]=\"users\"\r\n * [isOpen]=\"showMentions()\"\r\n * position=\"above\"\r\n * [maxHeight]=\"200\"\r\n * (itemSelected)=\"selectUser($event)\"\r\n * (closed)=\"closeMentions()\">\r\n * <ng-template #itemTemplate let-item>\r\n * <ds-avatar \r\n * [initials]=\"item.data.initials\" \r\n * size=\"sm\" />\r\n * <div class=\"user-info\">\r\n * <span>{{ item.data.name }}</span>\r\n * <span>{{ item.data.role }}</span>\r\n * </div>\r\n * </ng-template>\r\n * </ds-mobile-dropdown>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-dropdown',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent, IonPopover],\r\n styleUrls: ['./ds-mobile-dropdown.css'],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n template: `\r\n <ion-popover\r\n [isOpen]=\"isOpen()\"\r\n [trigger]=\"trigger()\"\r\n [side]=\"position() === 'above' ? 'top' : 'bottom'\"\r\n [alignment]=\"'start'\"\r\n [showBackdrop]=\"true\"\r\n [dismissOnSelect]=\"false\"\r\n [backdropDismiss]=\"true\"\r\n [keepContentsMounted]=\"false\"\r\n [keyboardClose]=\"false\"\r\n (didDismiss)=\"closed.emit()\"\r\n [style.--offset-y]=\"offsetY()\"\r\n [style.--offset-x]=\"offsetX()\"\r\n [style.--max-width]=\"maxWidth()\"\r\n [style.--background]=\"'transparent'\"\r\n [style.--box-shadow]=\"'none'\"\r\n [style.--backdrop-opacity]=\"'0'\">\r\n \r\n <ng-template>\r\n @if (customContent) {\r\n <!-- Fully custom popover content (e.g. picker, form) -->\r\n <ng-container *ngTemplateOutlet=\"customContent\" />\r\n } @else {\r\n <!-- Standard item list -->\r\n <div \r\n [class]=\"dropdownClasses()\"\r\n [style.max-height.px]=\"maxHeight()\"\r\n (mousedown)=\"$event.stopPropagation()\"\r\n (click)=\"$event.stopPropagation()\"\r\n role=\"menu\"\r\n [attr.aria-label]=\"ariaLabel()\">\r\n \r\n @if (customItemTemplate) {\r\n <!-- Custom template for each item -->\r\n @for (item of items(); track item.id) {\r\n <div\r\n [class]=\"getItemClass(item)\"\r\n [attr.data-disabled]=\"item.disabled ? '' : null\"\r\n [attr.aria-disabled]=\"item.disabled\"\r\n (mousedown)=\"handleItemClick(item, $event)\"\r\n role=\"menuitem\">\r\n <ng-container \r\n *ngTemplateOutlet=\"customItemTemplate; context: { $implicit: item }\" />\r\n </div>\r\n }\r\n } @else {\r\n <!-- Default three-slot template: leading - main - trailing -->\r\n @for (item of items(); track item.id) {\r\n <div\r\n [class]=\"getItemClass(item)\"\r\n [attr.data-disabled]=\"item.disabled ? '' : null\"\r\n [attr.aria-disabled]=\"item.disabled\"\r\n (mousedown)=\"handleItemClick(item, $event)\"\r\n role=\"menuitem\">\r\n \r\n <!-- Leading slot -->\r\n @if (item.leadingIcon) {\r\n <div class=\"ds-mobile-dropdown__slot ds-mobile-dropdown__slot--leading\">\r\n <ds-icon [name]=\"item.leadingIcon\" size=\"16px\" />\r\n </div>\r\n }\r\n \r\n <!-- Main slot -->\r\n @if (item.label) {\r\n <div class=\"ds-mobile-dropdown__slot ds-mobile-dropdown__slot--main\">\r\n <span class=\"ds-mobile-dropdown__label\">{{ item.label }}</span>\r\n </div>\r\n }\r\n \r\n <!-- Trailing slot -->\r\n @if (item.trailingIcon) {\r\n <div class=\"ds-mobile-dropdown__slot ds-mobile-dropdown__slot--trailing\">\r\n <ds-icon [name]=\"item.trailingIcon\" size=\"20px\" />\r\n </div>\r\n }\r\n </div>\r\n }\r\n }\r\n \r\n @if (items().length === 0 && emptyMessage()) {\r\n <div class=\"ds-mobile-dropdown__empty\">{{ emptyMessage() }}</div>\r\n }\r\n </div>\r\n }\r\n </ng-template>\r\n </ion-popover>\r\n `\r\n})\r\nexport class DsMobileDropdownComponent {\r\n private elementRef = inject(ElementRef);\r\n \r\n constructor() {\r\n // Effect to refocus the keepFocusOn element when popover opens\r\n effect(() => {\r\n const isOpen = this.isOpen();\r\n const focusElement = this.keepFocusOn();\r\n \r\n if (isOpen && focusElement?.nativeElement) {\r\n // Wait for popover to mount, then refocus\r\n setTimeout(() => {\r\n focusElement.nativeElement.focus();\r\n }, 100);\r\n }\r\n });\r\n }\r\n \r\n /**\r\n * Content projection for custom item template (per-item renderer)\r\n */\r\n @ContentChild('itemTemplate') customItemTemplate?: TemplateRef<any>;\r\n\r\n /**\r\n * Content projection for fully custom popover content.\r\n * When provided, the item list is bypassed entirely and this template\r\n * is rendered directly inside the popover — use for pickers, forms, etc.\r\n */\r\n @ContentChild('customContent') customContent?: TemplateRef<any>;\r\n \r\n /**\r\n * Optional trigger element ID for Ionic Popover positioning\r\n */\r\n trigger = input<string>();\r\n \r\n /**\r\n * Optional element to keep focused (prevent keyboard from dismissing)\r\n * Pass ElementRef to maintain focus when popover opens\r\n */\r\n keepFocusOn = input<ElementRef<any>>();\r\n \r\n /**\r\n * Array of dropdown items to display.\r\n * Not required when using the #customContent slot.\r\n */\r\n items = input<DsMobileDropdownItem[]>([]);\r\n \r\n /**\r\n * Whether the dropdown is open\r\n */\r\n isOpen = input<boolean>(false);\r\n \r\n /**\r\n * Position relative to parent container\r\n * - 'above': Appears above the anchor\r\n * - 'below': Appears below the anchor\r\n */\r\n position = input<DropdownPosition>('above');\r\n \r\n /**\r\n * Horizontal alignment\r\n * - 'start': Left-aligned (default)\r\n * - 'end': Right-aligned\r\n */\r\n align = input<DropdownAlign>('start');\r\n \r\n /**\r\n * Maximum height in pixels before scrolling\r\n */\r\n maxHeight = input<number>(200);\r\n \r\n /**\r\n * Message to show when items array is empty\r\n */\r\n emptyMessage = input<string>('No items available');\r\n \r\n /**\r\n * ARIA label for the dropdown menu\r\n */\r\n ariaLabel = input<string>('Dropdown menu');\r\n\r\n /**\r\n * Maximum width of the popover.\r\n * Defaults to '192px' (standard dropdown width).\r\n * Override when using #customContent that requires more space (e.g. '280px' for a picker).\r\n */\r\n maxWidth = input<string>('192px');\r\n \r\n /**\r\n * Emits when an item is selected\r\n */\r\n itemSelected = output<DsMobileDropdownItem>();\r\n \r\n /**\r\n * Emits when the dropdown should be closed (backdrop click)\r\n */\r\n closed = output<void>();\r\n \r\n /**\r\n * Computed dropdown CSS classes\r\n */\r\n dropdownClasses = computed(() => {\r\n const classes = [\r\n 'ds-mobile-dropdown',\r\n `ds-mobile-dropdown--${this.position()}`,\r\n `ds-mobile-dropdown--align-${this.align()}`\r\n ];\r\n \r\n return classes.join(' ');\r\n });\r\n \r\n /**\r\n * Computed offset Y for Ionic Popover\r\n * Uses CSS variable for precise control\r\n */\r\n offsetY = computed(() => {\r\n // 4px offset - works well on both web and iOS\r\n return this.position() === 'above' ? '-4px' : '4px';\r\n });\r\n \r\n /**\r\n * Computed offset X for Ionic Popover\r\n * Negative value to shift left by trigger position + add 20px left margin\r\n */\r\n offsetX = computed(() => {\r\n // This will be calculated to position it 20px from the left edge\r\n // The exact value depends on where the trigger is positioned\r\n return '0px'; // Ionic will handle this based on alignment=\"start\"\r\n });\r\n \r\n /**\r\n * Get CSS classes for a dropdown item\r\n */\r\n getItemClass(item: DsMobileDropdownItem): string {\r\n const classes = ['ds-mobile-dropdown__item'];\r\n if (item.disabled) classes.push('ds-mobile-dropdown__item--disabled');\r\n return classes.join(' ');\r\n }\r\n \r\n /**\r\n * Handle item click with mousedown to prevent keyboard loss\r\n */\r\n handleItemClick(item: DsMobileDropdownItem, event: MouseEvent): void {\r\n if (item.disabled) return;\r\n \r\n event.preventDefault();\r\n event.stopPropagation();\r\n \r\n // Execute item action if provided\r\n if (item.action) {\r\n item.action();\r\n }\r\n \r\n // Emit selection event\r\n this.itemSelected.emit(item);\r\n }\r\n}\r\n","import { Component, input, output, signal, computed, ViewChild, ElementRef, AfterViewInit, OnDestroy, ChangeDetectorRef } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { Capacitor } from '@capacitor/core';\r\nimport { Keyboard } from '@capacitor/keyboard';\r\nimport { FilePicker } from '@capawesome/capacitor-file-picker';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsMobileAttachmentPreviewComponent, type AttachmentData, type AttachmentFileType } from '../attachment-preview/ds-mobile-attachment-preview';\r\nimport { DsMobileDropdownComponent, type DsMobileDropdownItem } from '../dropdown';\r\n\r\n/**\r\n * DsMobileMessageComposerComponent\r\n *\r\n * Reusable message composer component extracted from post-detail-modal.\r\n * Can be used for both comments and chat messages.\r\n *\r\n * Features:\r\n * - Text input with auto-resize\r\n * - Avatar display\r\n * - Send button (appears when text is entered)\r\n * - Optional mention menu support\r\n * - Optional edit/reply indicators\r\n * - Keyboard handling for mobile\r\n * - Safe area support\r\n *\r\n * @example\r\n * ```html\r\n * <ds-mobile-message-composer\r\n * [avatarInitials]=\"'JD'\"\r\n * [placeholder]=\"'Write a message...'\"\r\n * (messageSent)=\"handleMessage($event)\">\r\n * </ds-mobile-message-composer>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-message-composer',\r\n standalone: true,\r\n imports: [CommonModule, FormsModule, DsAvatarComponent, DsIconButtonComponent, DsIconComponent, DsMobileAttachmentPreviewComponent, DsMobileDropdownComponent],\r\n styles: [\r\n `\r\n :host {\r\n display: block;\r\n }\r\n\r\n /* Composer Container */\r\n .message-composer {\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n border-top: 1px solid var(--border-color-default);\r\n border-bottom-left-radius: 0;\r\n border-bottom-right-radius: 0;\r\n padding: 12px 16px;\r\n width: 100%;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n }\r\n\r\n /* Edit indicator (optional) */\r\n .edit-indicator {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 8px 12px;\r\n background: var(--color-background-brand-subtle, #f0edfe);\r\n border-radius: 8px;\r\n animation: slideDown 0.2s ease-out;\r\n }\r\n\r\n .edit-indicator-content {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n color: var(--color-accent, #6b5ff5);\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n\r\n .edit-text {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 500;\r\n line-height: 18px;\r\n color: var(--color-accent, #6b5ff5);\r\n }\r\n\r\n .cancel-edit {\r\n background: none;\r\n border: none;\r\n padding: 4px;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n color: var(--color-accent, #6b5ff5);\r\n border-radius: 4px;\r\n transition: background 0.2s ease;\r\n flex-shrink: 0;\r\n }\r\n\r\n .cancel-edit:active {\r\n background: var(--color-brand-subtle, #e0dbfe);\r\n }\r\n\r\n /* Reply indicator (optional) */\r\n .reply-indicator {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n padding: 8px 12px;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-radius: 8px;\r\n animation: slideDown 0.2s ease-out;\r\n }\r\n\r\n .reply-indicator-content {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n color: var(--color-text-secondary, #737373);\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n\r\n .reply-to-text {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n line-height: 18px;\r\n color: var(--color-text-secondary, #737373);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n\r\n .reply-author {\r\n color: var(--color-accent, #6b5ff5);\r\n font-weight: 600;\r\n }\r\n\r\n .cancel-reply {\r\n background: none;\r\n border: none;\r\n padding: 4px;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n color: var(--color-text-secondary, #737373);\r\n border-radius: 4px;\r\n transition: background 0.2s ease;\r\n flex-shrink: 0;\r\n }\r\n\r\n .cancel-reply:active {\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n }\r\n\r\n @keyframes slideDown {\r\n from {\r\n opacity: 0;\r\n transform: translateY(-10px);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n }\r\n\r\n /* Attachment previews section */\r\n .attachment-previews-section {\r\n padding: 0 0 8px 0;\r\n animation: slideDown 0.2s ease-out;\r\n }\r\n\r\n .attachment-previews {\r\n display: flex;\r\n flex-wrap: wrap;\r\n gap: 8px;\r\n }\r\n\r\n .composer-content {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n width: 100%;\r\n position: relative;\r\n }\r\n\r\n /* Attachment button replacing avatar */\r\n .composer-leading-button {\r\n flex-shrink: 0;\r\n }\r\n\r\n .composer-leading-button::ng-deep button {\r\n width: 40px !important;\r\n height: 40px !important;\r\n min-width: 40px !important;\r\n min-height: 40px !important;\r\n padding: 0 !important;\r\n border-radius: 50% !important;\r\n transition: transform 0.3s ease;\r\n }\r\n\r\n .composer-leading-button--open::ng-deep button {\r\n transform: rotate(45deg);\r\n }\r\n\r\n .composer-input-wrapper {\r\n flex: 1;\r\n display: flex;\r\n align-items: flex-start;\r\n gap: 8px;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-radius: 24px;\r\n padding: 12px 16px;\r\n padding-right: 16px; /* Remove extra padding - no buttons on right anymore */\r\n min-height: 44px;\r\n position: relative;\r\n }\r\n\r\n /* Mention menu custom styles */\r\n .mention-user-info {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 2px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n\r\n .mention-user-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n line-height: 20px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n\r\n .mention-user-role {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n line-height: 18px;\r\n color: var(--color-text-secondary, #737373);\r\n }\r\n\r\n .composer-input {\r\n flex: 1;\r\n border: none;\r\n background: transparent;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n line-height: 20px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n outline: none;\r\n resize: none;\r\n min-height: 20px;\r\n max-height: 120px;\r\n overflow-y: auto;\r\n padding: 0;\r\n margin: 0;\r\n }\r\n\r\n .composer-input::placeholder {\r\n color: var(--color-text-tertiary, #a0a0a0);\r\n font-size: var(--font-size-sm);\r\n }\r\n\r\n /* Send button - positioned absolute in top right corner like comment composer */\r\n .send-button-inline {\r\n position: absolute;\r\n top: 6px;\r\n right: 6px;\r\n z-index: 10;\r\n flex-shrink: 0;\r\n opacity: 0;\r\n transform: translateX(20px) scale(0.8);\r\n pointer-events: none;\r\n transition:\r\n opacity 0.15s ease-in,\r\n transform 0.15s ease-in;\r\n }\r\n\r\n .send-button-inline.show {\r\n opacity: 1;\r\n transform: translateX(0) scale(1);\r\n pointer-events: auto;\r\n animation: slideInFromRight var(--spring-bouncy);\r\n }\r\n\r\n .send-button-inline::ng-deep button {\r\n width: 32px !important;\r\n height: 32px !important;\r\n min-width: 32px !important;\r\n min-height: 32px !important;\r\n padding: 0 !important;\r\n border-radius: 50% !important;\r\n }\r\n\r\n @keyframes slideInFromRight {\r\n from {\r\n opacity: 0;\r\n transform: translateX(20px) scale(0.8);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateX(0) scale(1);\r\n }\r\n }\r\n `,\r\n ],\r\n template: `\r\n <div class=\"message-composer\">\r\n <!-- Edit indicator (optional) -->\r\n @if (editingMessage()) {\r\n <div class=\"edit-indicator\">\r\n <div class=\"edit-indicator-content\">\r\n <ds-icon name=\"remixEditLine\" size=\"16px\" />\r\n <span class=\"edit-text\">{{ editIndicatorText() }}</span>\r\n </div>\r\n <button class=\"cancel-edit\" (click)=\"cancelEdit()\" type=\"button\">\r\n <ds-icon name=\"remixCloseLine\" size=\"16px\" />\r\n </button>\r\n </div>\r\n }\r\n\r\n <!-- Reply indicator (optional) -->\r\n @if (replyingTo() && !editingMessage()) {\r\n <div class=\"reply-indicator\">\r\n <div class=\"reply-indicator-content\">\r\n <ds-icon name=\"remixReplyLine\" size=\"16px\" />\r\n <span class=\"reply-to-text\">\r\n {{ replyIndicatorText() }} <span class=\"reply-author\">{{ replyingTo()!.authorName }}</span>\r\n </span>\r\n </div>\r\n <button class=\"cancel-reply\" (click)=\"cancelReply()\" type=\"button\">\r\n <ds-icon name=\"remixCloseLine\" size=\"16px\" />\r\n </button>\r\n </div>\r\n }\r\n\r\n <!-- Attachment Previews (if any) -->\r\n @if (attachments().length > 0) {\r\n <div class=\"attachment-previews-section\">\r\n <div class=\"attachment-previews\">\r\n @for (attachment of attachments(); track attachment.id) {\r\n <ds-mobile-attachment-preview [attachment]=\"attachment\" (remove)=\"removeAttachment($event)\" />\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n <div class=\"composer-content\">\r\n <!-- Attachment button replacing avatar (left side) -->\r\n @if (showAttachmentButton()) {\r\n <div class=\"composer-leading-button\" [class.composer-leading-button--open]=\"isAttachmentMenuOpen()\">\r\n <!-- Main attachment button -->\r\n <ds-icon-button\r\n id=\"attachment-trigger\"\r\n icon=\"remixAddLine\"\r\n variant=\"secondary\"\r\n size=\"lg\"\r\n (clicked)=\"toggleAttachmentMenu($event)\"\r\n [attr.aria-label]=\"attachmentButtonLabel()\"\r\n [attr.aria-expanded]=\"isAttachmentMenuOpen()\"\r\n >\r\n </ds-icon-button>\r\n\r\n <!-- Attachment menu using dropdown -->\r\n <ds-mobile-dropdown\r\n [items]=\"attachmentMenuItems\"\r\n [isOpen]=\"isAttachmentMenuOpen()\"\r\n [trigger]=\"'attachment-trigger'\"\r\n [keepFocusOn]=\"messageInputRef\"\r\n position=\"above\"\r\n align=\"start\"\r\n (itemSelected)=\"handleAttachmentMenuSelect($event)\"\r\n (closed)=\"closeAttachmentMenu()\"\r\n >\r\n </ds-mobile-dropdown>\r\n </div>\r\n } @else {\r\n <!-- Avatar (only shown when attachment button is hidden) -->\r\n <ds-avatar [initials]=\"avatarInitials()\" [type]=\"avatarType()\" [src]=\"avatarSrc()\" size=\"lg\" />\r\n }\r\n\r\n <div class=\"composer-input-wrapper\">\r\n <textarea\r\n #messageInputEl\r\n id=\"message-input-trigger\"\r\n class=\"composer-input\"\r\n [placeholder]=\"placeholder()\"\r\n [(ngModel)]=\"messageText\"\r\n (input)=\"handleInput($event)\"\r\n (keydown)=\"handleKeyDown($event)\"\r\n (focus)=\"showKeyboard()\"\r\n (click)=\"showKeyboard()\"\r\n rows=\"1\"\r\n >\r\n </textarea>\r\n\r\n <!-- Mention menu using dropdown (only render if mentions are enabled) -->\r\n @if (enableMentions()) {\r\n <ds-mobile-dropdown\r\n [items]=\"mentionDropdownItems()\"\r\n [isOpen]=\"showMentionMenu() && !editingMessage() && mentionDropdownItems().length > 0\"\r\n [trigger]=\"'message-input-trigger'\"\r\n position=\"above\"\r\n align=\"start\"\r\n [maxHeight]=\"200\"\r\n (itemSelected)=\"handleMentionSelect($event)\"\r\n (closed)=\"closeMentionMenu()\"\r\n >\r\n <ng-template #itemTemplate let-item>\r\n <ds-avatar [initials]=\"item.data.initials\" [type]=\"'initials'\" size=\"sm\" />\r\n <div class=\"mention-user-info\">\r\n <span class=\"mention-user-name\">{{ item.data.name }}</span>\r\n <span class=\"mention-user-role\">{{ item.data.role }}</span>\r\n </div>\r\n </ng-template>\r\n </ds-mobile-dropdown>\r\n }\r\n\r\n <!-- Send button (absolute positioned in top right, always rendered) -->\r\n <ds-icon-button\r\n icon=\"remixCheckLine\"\r\n variant=\"primary\"\r\n size=\"sm\"\r\n (clicked)=\"sendMessage()\"\r\n [attr.aria-label]=\"sendButtonLabel()\"\r\n [class.send-button-inline]=\"true\"\r\n [class.show]=\"messageText().trim().length > 0 || attachments().length > 0\"\r\n >\r\n </ds-icon-button>\r\n </div>\r\n </div>\r\n\r\n <!-- Hidden file input -->\r\n <input\r\n #fileInput\r\n type=\"file\"\r\n accept=\".pdf,.doc,.docx,.xls,.xlsx,.txt,.csv,.zip,.rar\"\r\n multiple\r\n aria-hidden=\"true\"\r\n style=\"display: none;\"\r\n (change)=\"handleFileSelect($event)\"\r\n />\r\n </div>\r\n `,\r\n})\r\nexport class DsMobileMessageComposerComponent implements AfterViewInit, OnDestroy {\r\n constructor(private cdr: ChangeDetectorRef) {}\r\n\r\n /**\r\n * Avatar initials\r\n */\r\n avatarInitials = input<string>('');\r\n\r\n /**\r\n * Avatar type\r\n */\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n\r\n /**\r\n * Avatar photo source (for photo type)\r\n */\r\n avatarSrc = input<string>('');\r\n\r\n /**\r\n * Placeholder text for the input\r\n */\r\n placeholder = input<string>('Write a message...');\r\n\r\n /**\r\n * Send button aria label\r\n */\r\n sendButtonLabel = input<string>('Send message');\r\n\r\n /**\r\n * Attachment button aria label\r\n */\r\n attachmentButtonLabel = input<string>('Add attachment');\r\n\r\n /**\r\n * Whether to show the attachment button\r\n */\r\n showAttachmentButton = input<boolean>(false);\r\n\r\n /**\r\n * Edit indicator text (when editing)\r\n */\r\n editIndicatorText = input<string>('Editing message');\r\n\r\n /**\r\n * Reply indicator text prefix\r\n */\r\n replyIndicatorText = input<string>('Replying to');\r\n\r\n /**\r\n * Whether to enable mention support\r\n */\r\n enableMentions = input<boolean>(false);\r\n\r\n /**\r\n * Available users for mentions (if mentions enabled)\r\n */\r\n mentionUsers = input<Array<{ name: string; initials: string; role: string }>>([]);\r\n\r\n /**\r\n * Auto-focus input on mount\r\n */\r\n autoFocus = input<boolean>(false);\r\n\r\n /**\r\n * ViewChild for message input\r\n */\r\n @ViewChild('messageInputEl') messageInputRef?: ElementRef<HTMLTextAreaElement>;\r\n\r\n /**\r\n * ViewChild for file input\r\n */\r\n @ViewChild('fileInput') fileInput?: ElementRef<HTMLInputElement>;\r\n\r\n /**\r\n * Message text signal\r\n */\r\n messageText = signal('');\r\n\r\n /**\r\n * Attachments signal\r\n */\r\n attachments = signal<AttachmentData[]>([]);\r\n\r\n /**\r\n * Attachment menu open state\r\n */\r\n isAttachmentMenuOpen = signal(false);\r\n\r\n /**\r\n * Editing message state (optional)\r\n */\r\n editingMessage = signal<{ authorName: string; originalContent: string; timestamp: string } | null>(null);\r\n\r\n /**\r\n * Replying to state (optional)\r\n */\r\n replyingTo = signal<{ authorName: string; content: string } | null>(null);\r\n\r\n /**\r\n * Mention menu state\r\n */\r\n showMentionMenu = signal(false);\r\n\r\n /**\r\n * Mention query for filtering\r\n */\r\n mentionQuery = signal('');\r\n\r\n /**\r\n * Filtered users based on mention query\r\n */\r\n filteredUsers = computed(() => {\r\n if (!this.enableMentions()) return [];\r\n\r\n const query = this.mentionQuery().toLowerCase();\r\n const users = this.mentionUsers();\r\n\r\n if (!query) return users;\r\n return users.filter((user) => user.name.toLowerCase().includes(query));\r\n });\r\n\r\n /**\r\n * Convert filtered users to dropdown items\r\n */\r\n mentionDropdownItems = computed((): DsMobileDropdownItem[] => {\r\n return this.filteredUsers().map((user) => ({\r\n id: user.name,\r\n label: user.name,\r\n data: {\r\n name: user.name,\r\n initials: user.initials,\r\n role: user.role,\r\n },\r\n }));\r\n });\r\n\r\n /**\r\n * Attachment menu items\r\n * Static list to prevent change detection loops\r\n */\r\n readonly attachmentMenuItems: DsMobileDropdownItem[] = [\r\n {\r\n id: 'photo',\r\n leadingIcon: 'remixImageLine',\r\n label: 'Photo',\r\n action: () => this.handleAddPhoto(),\r\n },\r\n {\r\n id: 'file',\r\n leadingIcon: 'remixFile3Line',\r\n label: 'File',\r\n action: () => this.handleAddFile(),\r\n },\r\n ];\r\n\r\n /**\r\n * Emits when a message is sent\r\n */\r\n messageSent = output<{\r\n content: string;\r\n isReply?: boolean;\r\n replyTo?: string;\r\n isEdit?: boolean;\r\n attachments?: AttachmentData[];\r\n }>();\r\n\r\n /**\r\n * Emits when edit is cancelled\r\n */\r\n editCancelled = output<void>();\r\n\r\n /**\r\n * Emits when reply is cancelled\r\n */\r\n replyCancelled = output<void>();\r\n\r\n /**\r\n * Emits when mention is selected\r\n */\r\n mentionSelected = output<{ userName: string }>();\r\n\r\n /**\r\n * Emits when attachment button is clicked\r\n */\r\n attachmentClicked = output<void>();\r\n\r\n /**\r\n * Emits when attachments array changes (added or removed)\r\n * Parent components (like chat modal) can use this to scroll to bottom\r\n */\r\n attachmentsChanged = output<void>();\r\n\r\n ngAfterViewInit(): void {\r\n // Auto-focus input if requested\r\n if (this.autoFocus()) {\r\n setTimeout(() => {\r\n this.messageInputRef?.nativeElement.focus();\r\n this.showKeyboard();\r\n }, 300);\r\n }\r\n\r\n // Set up keyboard listeners\r\n this.setupKeyboardListeners();\r\n\r\n // Explicitly trigger change detection to avoid NG0100 with ViewChild bindings\r\n this.cdr.detectChanges();\r\n }\r\n\r\n ngOnDestroy(): void {\r\n // Clean up keyboard listeners\r\n this.cleanupKeyboardListeners();\r\n }\r\n\r\n /**\r\n * Set up keyboard event listeners\r\n */\r\n private setupKeyboardListeners(): void {\r\n Keyboard.addListener('keyboardWillShow', (info) => {\r\n document.documentElement.style.setProperty('--keyboard-height', `${info.keyboardHeight}px`);\r\n }).catch(() => {});\r\n\r\n Keyboard.addListener('keyboardWillHide', () => {\r\n document.documentElement.style.setProperty('--keyboard-height', '0px');\r\n }).catch(() => {});\r\n }\r\n\r\n /**\r\n * Clean up keyboard event listeners\r\n */\r\n private cleanupKeyboardListeners(): void {\r\n Keyboard.removeAllListeners().catch(() => {});\r\n }\r\n\r\n /**\r\n * Show the keyboard when user interacts with input\r\n */\r\n showKeyboard(): void {\r\n Keyboard.show().catch(() => {});\r\n }\r\n\r\n /**\r\n * Handle keyboard shortcuts (Shift+Enter to send)\r\n */\r\n handleKeyDown(event: KeyboardEvent): void {\r\n // Shift+Enter sends the message\r\n if (event.key === 'Enter' && event.shiftKey) {\r\n event.preventDefault();\r\n const hasContent = this.messageText().trim().length > 0 || this.attachments().length > 0;\r\n if (hasContent) {\r\n this.sendMessage();\r\n }\r\n }\r\n // Regular Enter just creates a new line (default behavior)\r\n }\r\n\r\n /**\r\n * Handle input changes and detect @ mentions\r\n */\r\n handleInput(event: Event): void {\r\n const textarea = event.target as HTMLTextAreaElement;\r\n const text = textarea.value;\r\n const cursorPosition = textarea.selectionStart || 0;\r\n\r\n // Update signal\r\n this.messageText.set(text);\r\n\r\n // Auto-resize textarea\r\n textarea.style.height = 'auto';\r\n textarea.style.height = textarea.scrollHeight + 'px';\r\n\r\n // Handle mentions if enabled\r\n if (this.enableMentions()) {\r\n // Find the last @ before cursor\r\n const textBeforeCursor = text.substring(0, cursorPosition);\r\n const lastAtIndex = textBeforeCursor.lastIndexOf('@');\r\n\r\n if (lastAtIndex !== -1) {\r\n // Check if there's a space after @\r\n const textAfterAt = textBeforeCursor.substring(lastAtIndex + 1);\r\n const hasSpace = textAfterAt.includes(' ');\r\n\r\n if (!hasSpace) {\r\n // Show mention menu\r\n this.showMentionMenu.set(true);\r\n this.mentionQuery.set(textAfterAt);\r\n } else {\r\n this.showMentionMenu.set(false);\r\n }\r\n } else {\r\n this.showMentionMenu.set(false);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Handle mention selection from dropdown\r\n */\r\n handleMentionSelect(item: DsMobileDropdownItem): void {\r\n this.selectMention(item.data.name);\r\n }\r\n\r\n /**\r\n * Close mention menu\r\n */\r\n closeMentionMenu(): void {\r\n this.showMentionMenu.set(false);\r\n }\r\n\r\n /**\r\n * Handle attachment menu selection from dropdown\r\n */\r\n handleAttachmentMenuSelect(item: DsMobileDropdownItem): void {\r\n // Action is already called by the dropdown, just close the menu\r\n this.closeAttachmentMenu();\r\n }\r\n\r\n /**\r\n * Select a user from mention menu\r\n */\r\n selectMention(userName: string): void {\r\n // Set as reply (similar to clicking Reply)\r\n this.replyingTo.set({ authorName: userName, content: '' });\r\n\r\n // Clear the @ from the input\r\n const currentText = this.messageText();\r\n const textWithoutMention = currentText.substring(0, currentText.lastIndexOf('@'));\r\n this.messageText.set(textWithoutMention);\r\n\r\n // Hide mention menu\r\n this.showMentionMenu.set(false);\r\n\r\n // Emit mention selected event\r\n this.mentionSelected.emit({ userName });\r\n\r\n // Focus back on input\r\n setTimeout(() => {\r\n this.messageInputRef?.nativeElement.focus();\r\n }, 0);\r\n }\r\n\r\n /**\r\n * Cancel edit\r\n */\r\n cancelEdit(): void {\r\n this.editingMessage.set(null);\r\n this.messageText.set('');\r\n this.editCancelled.emit();\r\n }\r\n\r\n /**\r\n * Cancel reply\r\n */\r\n cancelReply(): void {\r\n this.replyingTo.set(null);\r\n this.replyCancelled.emit();\r\n }\r\n\r\n /**\r\n * Set reply state (for external use)\r\n */\r\n setReply(authorName: string, content: string): void {\r\n this.replyingTo.set({ authorName, content });\r\n // Focus the input and show keyboard\r\n setTimeout(() => {\r\n this.messageInputRef?.nativeElement.focus();\r\n this.showKeyboard();\r\n }, 100);\r\n }\r\n\r\n /**\r\n * Set edit state (for external use)\r\n */\r\n setEdit(authorName: string, originalContent: string, timestamp: string): void {\r\n // Clear reply state if active\r\n this.replyingTo.set(null);\r\n\r\n // Remove @mention from the content if it exists\r\n let contentToEdit = originalContent;\r\n const mentionMatch = originalContent.match(/^@([A-Za-z]+(?:\\s+[A-Za-z]+)?)\\s+/);\r\n if (mentionMatch) {\r\n contentToEdit = originalContent.substring(mentionMatch[0].length);\r\n }\r\n\r\n // Set edit state\r\n this.editingMessage.set({ authorName, originalContent, timestamp });\r\n\r\n // Populate the input with existing content\r\n this.messageText.set(contentToEdit);\r\n\r\n // Focus the input, show keyboard, and auto-resize\r\n setTimeout(() => {\r\n if (this.messageInputRef?.nativeElement) {\r\n const textarea = this.messageInputRef.nativeElement;\r\n textarea.focus();\r\n\r\n // Auto-resize textarea to fit content\r\n textarea.style.height = 'auto';\r\n textarea.style.height = textarea.scrollHeight + 'px';\r\n\r\n this.showKeyboard();\r\n }\r\n }, 100);\r\n }\r\n\r\n /**\r\n * Clear composer state\r\n */\r\n clear(): void {\r\n this.messageText.set('');\r\n this.editingMessage.set(null);\r\n this.replyingTo.set(null);\r\n this.showMentionMenu.set(false);\r\n this.attachments.set([]);\r\n\r\n // Reset textarea height\r\n if (this.messageInputRef?.nativeElement) {\r\n this.messageInputRef.nativeElement.style.height = 'auto';\r\n }\r\n }\r\n\r\n /**\r\n * Focus the input\r\n */\r\n focus(): void {\r\n this.messageInputRef?.nativeElement.focus();\r\n this.showKeyboard();\r\n }\r\n\r\n /**\r\n * Toggle attachment menu open/closed\r\n * Uses mousedown/touchstart to prevent focus loss from textarea\r\n */\r\n toggleAttachmentMenu(event?: MouseEvent | TouchEvent): void {\r\n if (event) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n }\r\n this.isAttachmentMenuOpen.update((open) => !open);\r\n }\r\n\r\n /**\r\n * Close attachment menu\r\n */\r\n closeAttachmentMenu(event?: MouseEvent): void {\r\n if (event) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n }\r\n this.isAttachmentMenuOpen.set(false);\r\n }\r\n\r\n /**\r\n * Handle add photo button click from menu\r\n * Uses Capawesome File Picker API to open photo library directly\r\n * Allows multiple photo selection\r\n */\r\n async handleAddPhoto(event?: MouseEvent): Promise<void> {\r\n if (event) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n }\r\n\r\n if (this.attachments().length >= 6) {\r\n return;\r\n }\r\n\r\n try {\r\n //console.log('[MessageComposer] Opening photo library');\r\n\r\n // Calculate remaining slots\r\n const remainingSlots = 6 - this.attachments().length;\r\n\r\n // Open photo library with multiple selection using pickImages\r\n const result = await FilePicker.pickImages({\r\n limit: remainingSlots, // Limit to remaining slots\r\n });\r\n\r\n if (result.files && result.files.length > 0) {\r\n //console.log(`[MessageComposer] ${result.files.length} photo(s) selected`);\r\n\r\n // Process each selected photo\r\n for (const photo of result.files) {\r\n const attachmentId = `photo-${Date.now()}-${Math.random()}`;\r\n\r\n // Add attachment with loading state\r\n const loadingAttachment: AttachmentData = {\r\n id: attachmentId,\r\n src: photo.path ? Capacitor.convertFileSrc(photo.path) : (photo.blob ? URL.createObjectURL(photo.blob) : ''),\r\n type: 'image',\r\n name: photo.name,\r\n size: this.formatFileSize(photo.size ?? 0),\r\n isLoading: true,\r\n };\r\n\r\n this.attachments.update((attachments) => [...attachments, loadingAttachment]);\r\n\r\n // Simulate processing time (in real app, this would be actual image processing)\r\n // TODO: Reduce to 300ms or remove in production\r\n setTimeout(() => {\r\n this.attachments.update((attachments) => attachments.map((a) => (a.id === attachmentId ? { ...a, isLoading: false } : a)));\r\n }, 1500); // 1.5s for testing - shows loading overlay clearly\r\n }\r\n\r\n //console.log('[MessageComposer] All photos added successfully');\r\n\r\n // Notify parent that attachments changed so it can scroll\r\n this.attachmentsChanged.emit();\r\n\r\n // ResizeObserver in MobileModalBase automatically handles layout adjustments\r\n }\r\n } catch (error: any) {\r\n if (error.message && !error.message.includes('cancel')) {\r\n //console.error('[MessageComposer] Error adding photo:', error);\r\n }\r\n // User cancelled - that's fine\r\n }\r\n }\r\n\r\n /**\r\n * Handle add file button click from menu\r\n * Opens file picker\r\n */\r\n handleAddFile(event?: MouseEvent): void {\r\n if (event) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n }\r\n\r\n if (this.attachments().length >= 6) {\r\n return;\r\n }\r\n\r\n console.log('[MessageComposer] Opening file picker');\r\n\r\n // Trigger the hidden file input\r\n if (this.fileInput) {\r\n this.fileInput.nativeElement.click();\r\n }\r\n this.attachmentClicked.emit();\r\n }\r\n\r\n /**\r\n * Detect file type from file name or mime type\r\n */\r\n private detectFileType(file: File): AttachmentFileType {\r\n const fileName = file.name.toLowerCase();\r\n const mimeType = file.type.toLowerCase();\r\n\r\n // Check if it's an image\r\n if (mimeType.startsWith('image/')) {\r\n return 'image';\r\n }\r\n\r\n // Check file extension\r\n if (fileName.endsWith('.pdf')) {\r\n return 'pdf';\r\n } else if (fileName.endsWith('.doc')) {\r\n return 'doc';\r\n } else if (fileName.endsWith('.docx')) {\r\n return 'docx';\r\n } else if (fileName.endsWith('.xls')) {\r\n return 'xls';\r\n } else if (fileName.endsWith('.xlsx')) {\r\n return 'xlsx';\r\n }\r\n\r\n return 'other';\r\n }\r\n\r\n /**\r\n * Format file size for display\r\n */\r\n private formatFileSize(bytes: number): string {\r\n if (bytes === 0) return '0 B';\r\n const k = 1024;\r\n const sizes = ['B', 'KB', 'MB', 'GB'];\r\n const i = Math.floor(Math.log(bytes) / Math.log(k));\r\n return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + ' ' + sizes[i];\r\n }\r\n\r\n /**\r\n * Handle file selection from file input\r\n */\r\n handleFileSelect(event: Event): void {\r\n const input = event.target as HTMLInputElement;\r\n const files = input.files;\r\n\r\n if (!files || files.length === 0) {\r\n // User cancelled - blur handler will restore keyboard\r\n return;\r\n }\r\n\r\n // Process each selected file (up to 6 total)\r\n const remainingSlots = 6 - this.attachments().length;\r\n const filesToProcess = Array.from(files).slice(0, remainingSlots);\r\n\r\n filesToProcess.forEach((file) => {\r\n const fileType = this.detectFileType(file);\r\n const attachmentId = `file-${Date.now()}-${Math.random()}`;\r\n\r\n // Add attachment with loading state immediately\r\n const loadingAttachment: AttachmentData = {\r\n id: attachmentId,\r\n src: '', // Will be set after reading\r\n type: fileType,\r\n name: file.name,\r\n size: this.formatFileSize(file.size),\r\n isLoading: true,\r\n };\r\n this.attachments.update((attachments) => [...attachments, loadingAttachment]);\r\n\r\n // Create a data URL for preview\r\n const reader = new FileReader();\r\n reader.onload = (e) => {\r\n const result = e.target?.result as string;\r\n if (result) {\r\n // Add minimum loading time for better UX feedback\r\n // TODO: Remove setTimeout in production (use actual FileReader timing)\r\n setTimeout(() => {\r\n // Update attachment with actual data and remove loading state\r\n this.attachments.update((attachments) => attachments.map((a) => (a.id === attachmentId ? { ...a, src: result, isLoading: false } : a)));\r\n\r\n // Notify parent that attachments changed so it can scroll\r\n setTimeout(() => {\r\n this.attachmentsChanged.emit();\r\n }, 100);\r\n }, 1000); // 1s minimum for testing - shows loading overlay clearly\r\n }\r\n };\r\n reader.readAsDataURL(file);\r\n });\r\n\r\n // Reset the input so the same file can be selected again\r\n input.value = '';\r\n\r\n // ResizeObserver in MobileModalBase automatically handles layout adjustments\r\n }\r\n\r\n /**\r\n * Remove an attachment from the list\r\n * Keeps keyboard open by maintaining focus\r\n */\r\n removeAttachment(attachmentId: string): void {\r\n this.attachments.update((attachments) => attachments.filter((a) => a.id !== attachmentId));\r\n\r\n // Immediately refocus input to prevent keyboard from closing\r\n setTimeout(() => {\r\n if (this.messageInputRef?.nativeElement) {\r\n this.messageInputRef.nativeElement.focus();\r\n Keyboard.show().catch((e) => console.log('Keyboard.show() not available:', e));\r\n }\r\n }, 0);\r\n\r\n // Notify parent that attachments changed so it can scroll\r\n this.attachmentsChanged.emit();\r\n\r\n // ResizeObserver in MobileModalBase automatically handles layout adjustments\r\n }\r\n\r\n /**\r\n * Send message\r\n */\r\n sendMessage(): void {\r\n const text = this.messageText().trim();\r\n const hasAttachments = this.attachments().length > 0;\r\n\r\n // Must have either text or attachments\r\n if (!text && !hasAttachments) return;\r\n\r\n const isEdit = !!this.editingMessage();\r\n const isReply = !!this.replyingTo();\r\n\r\n // Emit message sent event\r\n this.messageSent.emit({\r\n content: isReply && this.replyingTo() ? `@${this.replyingTo()!.authorName} ${text}` : text,\r\n isReply,\r\n replyTo: this.replyingTo()?.authorName,\r\n isEdit,\r\n attachments: hasAttachments ? [...this.attachments()] : undefined,\r\n });\r\n\r\n // Keep keyboard open by explicitly showing it before clearing\r\n // This prevents the keyboard from starting to close during the clear operation\r\n Keyboard.show().catch(() => {\r\n // Keyboard.show() not available on web, that's fine\r\n });\r\n\r\n // Clear the input and states\r\n this.clear();\r\n\r\n // Ensure input stays focused for quick follow-up messages\r\n // The keyboard should remain open throughout this process\r\n if (this.messageInputRef?.nativeElement) {\r\n this.messageInputRef.nativeElement.focus();\r\n }\r\n }\r\n}\r\n","import { Component, input, output, computed } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * Chat attachment interface\r\n */\r\nexport interface ChatAttachment {\r\n id: string;\r\n type: 'image' | 'pdf' | 'file';\r\n url: string;\r\n name: string;\r\n size?: number;\r\n thumbnail?: string;\r\n}\r\n\r\n/**\r\n * DsMobileMessageBubbleComponent\r\n * \r\n * Individual message bubble component for chat conversations.\r\n * Supports left-aligned (sender) and right-aligned (user) messages with different styling.\r\n * \r\n * Features:\r\n * - Left/right alignment based on sender\r\n * - Avatar display (left for sender, right for user)\r\n * - Message content with text wrapping\r\n * - Timestamp display\r\n * - Read receipt indicator (for user's messages)\r\n * - Attachment support\r\n * - Long press support for actions\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Sender's message (left-aligned) -->\r\n * <ds-mobile-message-bubble\r\n * [isOwnMessage]=\"false\"\r\n * [senderName]=\"'Ricki Meihlen'\"\r\n * [content]=\"'We have received your case...'\"\r\n * [timestamp]=\"'12:34'\"\r\n * [avatarInitials]=\"'RM'\">\r\n * </ds-mobile-message-bubble>\r\n * \r\n * <!-- User's message (right-aligned) -->\r\n * <ds-mobile-message-bubble\r\n * [isOwnMessage]=\"true\"\r\n * [senderName]=\"'You'\"\r\n * [content]=\"'Thank you!'\"\r\n * [timestamp]=\"'12:35'\"\r\n * [readStatus]=\"true\"\r\n * [avatarInitials]=\"'JD'\">\r\n * </ds-mobile-message-bubble>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-message-bubble',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent, DsIconComponent],\r\n host: {\r\n '[class.is-own-message]': 'isOwnMessage()',\r\n '[class.has-attachments]': 'attachments() && attachments()!.length > 0',\r\n '[class.cluster-single]': 'clusterPosition() === \"single\"',\r\n '[class.cluster-first]': 'clusterPosition() === \"first\"',\r\n '[class.cluster-middle]': 'clusterPosition() === \"middle\"',\r\n '[class.cluster-last]': 'clusterPosition() === \"last\"',\r\n '[class.tapped]': 'isTapped',\r\n '[class.is-new-message]': 'isNewMessage()',\r\n '(touchstart)': 'handleTouchStart($event)',\r\n '(touchend)': 'handleTouchEnd($event)',\r\n '(touchmove)': 'handleTouchMove($event)',\r\n '(contextmenu)': 'handleContextMenu($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n gap: 8px;\r\n margin-bottom: 4px;\r\n width: 100%;\r\n align-items: flex-end;\r\n box-sizing: border-box;\r\n }\r\n \r\n /* Adjust spacing for clustered messages */\r\n :host.cluster-single {\r\n margin-bottom: 12px; /* More space after standalone messages */\r\n }\r\n \r\n :host.cluster-first {\r\n margin-bottom: 2px; /* Tight spacing in cluster */\r\n }\r\n \r\n :host.cluster-middle {\r\n margin-bottom: 2px; /* Tight spacing in cluster */\r\n }\r\n \r\n :host.cluster-last {\r\n margin-bottom: 12px; /* More space after cluster ends */\r\n }\r\n \r\n /* Left-aligned (sender's message) */\r\n :host:not(.is-own-message) {\r\n justify-content: flex-start !important;\r\n flex-direction: row !important;\r\n }\r\n \r\n /* Right-aligned (user's message) - MUST be right-aligned */\r\n :host.is-own-message {\r\n justify-content: flex-end !important;\r\n flex-direction: row-reverse !important;\r\n margin-left: auto !important;\r\n margin-right: 0 !important;\r\n }\r\n \r\n .avatar-wrapper {\r\n flex-shrink: 0;\r\n display: flex;\r\n align-items: flex-end;\r\n width: 32px; /* Reserve space for avatar even when hidden */\r\n }\r\n \r\n .avatar-wrapper.hidden {\r\n visibility: hidden; /* Use visibility instead of display to maintain space */\r\n }\r\n \r\n .message-content-wrapper {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 0;\r\n max-width: 75%;\r\n min-width: 0;\r\n }\r\n \r\n /* Left-aligned message bubble */\r\n :host:not(.is-own-message) .message-content-wrapper {\r\n align-items: flex-start;\r\n }\r\n \r\n /* Right-aligned message bubble */\r\n :host.is-own-message .message-content-wrapper {\r\n align-items: flex-end !important;\r\n margin-left: auto !important;\r\n margin-right: 0 !important;\r\n }\r\n \r\n .message-bubble {\r\n padding: 8px 12px;\r\n border-radius: 20px;\r\n position: relative;\r\n word-wrap: break-word;\r\n white-space: pre-wrap;\r\n max-width: 100%;\r\n display: flex;\r\n flex-direction: column;\r\n /* Tap animation with spring bounce, including border-radius */\r\n transition: \r\n transform var(--spring-bouncy),\r\n border-radius var(--spring-bouncy);\r\n will-change: transform, border-radius;\r\n }\r\n \r\n /* Scale down on tap */\r\n :host.tapped .message-bubble {\r\n transform: scale(0.96);\r\n }\r\n \r\n /* Cluster position border radius overrides */\r\n /* Order: top-left, top-right, bottom-right, bottom-left */\r\n \r\n /* Single message in cluster - 20px all around (default) */\r\n \r\n /* Own messages (right side) - tight corners on the RIGHT */\r\n /* First message in cluster - 20px 20px 4px 20px */\r\n :host.is-own-message.cluster-first .message-bubble {\r\n border-radius: 20px 20px 4px 20px;\r\n }\r\n \r\n /* Middle message in cluster - 20px 4px 4px 20px */\r\n :host.is-own-message.cluster-middle .message-bubble {\r\n border-radius: 20px 4px 4px 20px;\r\n }\r\n \r\n /* Last message in cluster - 20px 4px 20px 20px */\r\n :host.is-own-message.cluster-last .message-bubble {\r\n border-radius: 20px 4px 20px 20px;\r\n }\r\n \r\n /* Sender messages (left side, grey) - tight corners on the LEFT */\r\n /* First message in cluster - 20px 20px 20px 4px */\r\n :host:not(.is-own-message).cluster-first .message-bubble {\r\n border-radius: 20px 20px 20px 4px;\r\n }\r\n \r\n /* Middle message in cluster - 4px 20px 20px 4px */\r\n :host:not(.is-own-message).cluster-middle .message-bubble {\r\n border-radius: 4px 20px 20px 4px;\r\n }\r\n \r\n /* Last message in cluster - 4px 20px 20px 20px */\r\n :host:not(.is-own-message).cluster-last .message-bubble {\r\n border-radius: 4px 20px 20px 20px;\r\n }\r\n \r\n /* Sender's message - neutral secondary background, no border */\r\n :host:not(.is-own-message) .message-bubble {\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n }\r\n \r\n /* User's message - brand primary surface background */\r\n :host.is-own-message .message-bubble {\r\n background: var(--color-accent, var(--color-accent, #6B5FF5));\r\n color: var(--color-on-accent, #ffffff);\r\n }\r\n \r\n .message-text {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n margin: 0;\r\n }\r\n \r\n :host:not(.is-own-message) .message-text {\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n :host.is-own-message .message-text {\r\n color: var(--color-on-accent, #ffffff);\r\n }\r\n \r\n /* Attachments container */\r\n .attachments {\r\n display: flex;\r\n flex-wrap: wrap;\r\n gap: 8px;\r\n margin-top: 8px;\r\n }\r\n \r\n :host:not(.is-own-message) .attachments {\r\n justify-content: flex-start;\r\n }\r\n \r\n :host.is-own-message .attachments {\r\n justify-content: flex-end;\r\n }\r\n \r\n .attachment-item {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n padding: 8px 12px;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-radius: 8px;\r\n border: 1px solid var(--border-color-default, #e5e5e5);\r\n cursor: pointer;\r\n transition: background 0.2s ease;\r\n }\r\n \r\n :host.is-own-message .attachment-item {\r\n background: rgba(255, 255, 255, 0.2);\r\n border-color: rgba(255, 255, 255, 0.3);\r\n }\r\n \r\n .attachment-item:active {\r\n background: var(--color-background-neutral-secondary-hover, #ebebeb);\r\n }\r\n \r\n :host.is-own-message .attachment-item:active {\r\n background: rgba(255, 255, 255, 0.3);\r\n }\r\n \r\n .attachment-icon {\r\n flex-shrink: 0;\r\n width: 24px;\r\n height: 24px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n border-radius: 4px;\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n }\r\n \r\n :host.is-own-message .attachment-icon {\r\n background: rgba(255, 255, 255, 0.3);\r\n }\r\n \r\n .attachment-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 500;\r\n line-height: 16px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n max-width: 150px;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n }\r\n \r\n :host.is-own-message .attachment-name {\r\n color: var(--color-text-on-brand, #ffffff);\r\n }\r\n \r\n /* Timestamp inside bubble */\r\n .message-footer {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n align-self: flex-end; /* Always align to right within bubble */\r\n height: 0;\r\n margin-top: 0;\r\n opacity: 0;\r\n overflow: hidden;\r\n transform: scale(0.95);\r\n /* Spring bounce animation using design system variable */\r\n transition: \r\n height var(--spring-bouncy),\r\n margin-top var(--spring-bouncy),\r\n opacity var(--spring-bouncy),\r\n transform var(--spring-bouncy);\r\n }\r\n \r\n /* Visible state - fade in and expand */\r\n .message-footer.visible {\r\n height: 14px;\r\n margin-top: 4px;\r\n opacity: 1;\r\n transform: scale(1);\r\n }\r\n \r\n /* Timestamp always right-aligned for both message types */\r\n :host:not(.is-own-message) .message-footer {\r\n align-self: flex-end; /* Right-align timestamp for sender's messages */\r\n }\r\n \r\n .timestamp {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: 11px;\r\n font-weight: 400;\r\n line-height: 14px;\r\n white-space: nowrap;\r\n }\r\n \r\n /* Timestamp color for sender's messages (grey background) */\r\n :host:not(.is-own-message) .timestamp {\r\n color: var(--color-text-tertiary, #a0a0a0);\r\n }\r\n \r\n /* Timestamp color for user's messages (brand background) */\r\n :host.is-own-message .timestamp {\r\n color: var(--color-on-accent, #ffffff);\r\n opacity: 0.7;\r\n }\r\n \r\n /* Long press tracking */\r\n :host {\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n }\r\n \r\n /* New message animation - bouncy appearance with scale, opacity, and translateY */\r\n :host.is-new-message {\r\n animation: message-appear var(--spring-bouncy) forwards;\r\n }\r\n \r\n @keyframes message-appear {\r\n 0% {\r\n opacity: 0;\r\n transform: translateY(20px) scale(0.92);\r\n }\r\n 100% {\r\n opacity: 1;\r\n transform: translateY(0) scale(1);\r\n }\r\n }\r\n `],\r\n template: `\r\n @if (!isOwnMessage()) {\r\n <div class=\"avatar-wrapper\" [class.hidden]=\"!showAvatar()\">\r\n <ds-avatar\r\n [initials]=\"avatarInitials()\"\r\n [type]=\"avatarType()\"\r\n [src]=\"avatarSrc()\"\r\n size=\"sm\" />\r\n </div>\r\n }\r\n \r\n <div class=\"message-content-wrapper\" (click)=\"handleClick($event)\">\r\n <div class=\"message-bubble\">\r\n <!-- Only show text if content is not empty -->\r\n @if (content().trim()) {\r\n <p class=\"message-text\">{{ content() }}</p>\r\n }\r\n \r\n <!-- Attachments -->\r\n @if (attachments() && attachments()!.length > 0) {\r\n <div class=\"attachments\">\r\n @for (attachment of attachments(); track attachment.id) {\r\n <div \r\n class=\"attachment-item\"\r\n (click)=\"handleAttachmentClick(attachment); $event.stopPropagation()\">\r\n <div class=\"attachment-icon\">\r\n @if (attachment.type === 'image') {\r\n <ds-icon name=\"remixImageLine\" size=\"16px\" />\r\n } @else if (attachment.type === 'pdf') {\r\n <ds-icon name=\"remixFilePdfLine\" size=\"16px\" />\r\n } @else {\r\n <ds-icon name=\"remixFileLine\" size=\"16px\" />\r\n }\r\n </div>\r\n <span class=\"attachment-name\">{{ attachment.name }}</span>\r\n </div>\r\n }\r\n </div>\r\n }\r\n \r\n <!-- Timestamp inside bubble, animated on tap -->\r\n <div class=\"message-footer\" [class.visible]=\"showTimestamp()\">\r\n <span class=\"timestamp\">{{ timestamp() }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n `\r\n})\r\nexport class DsMobileMessageBubbleComponent {\r\n /**\r\n * Message content text\r\n */\r\n content = input.required<string>();\r\n \r\n /**\r\n * Whether this is the current user's message (right-aligned)\r\n */\r\n isOwnMessage = input<boolean>(false);\r\n \r\n /**\r\n * Sender's name (for display purposes)\r\n */\r\n senderName = input<string>('');\r\n \r\n /**\r\n * Timestamp text (e.g., \"12:34\", \"08-12-2025 13:18\")\r\n */\r\n timestamp = input.required<string>();\r\n \r\n /**\r\n * Whether to show the timestamp below the bubble\r\n */\r\n showTimestamp = input<boolean>(false);\r\n \r\n /**\r\n * Avatar initials\r\n */\r\n avatarInitials = input<string>('');\r\n \r\n /**\r\n * Avatar type\r\n */\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n \r\n /**\r\n * Avatar photo source (for photo type)\r\n */\r\n avatarSrc = input<string>('');\r\n \r\n /**\r\n * Whether to show the avatar (for clustering logic)\r\n */\r\n showAvatar = input<boolean>(true);\r\n \r\n /**\r\n * Cluster position for border radius styling\r\n */\r\n clusterPosition = input<'single' | 'first' | 'middle' | 'last'>('single');\r\n \r\n /**\r\n * Whether to show read receipt (only for user's messages)\r\n */\r\n /**\r\n * Message attachments\r\n */\r\n attachments = input<ChatAttachment[] | undefined>(undefined);\r\n \r\n /**\r\n * Whether the message is clickable\r\n */\r\n clickable = input<boolean>(false);\r\n \r\n /**\r\n * Whether this is a newly sent message (triggers appearance animation)\r\n */\r\n isNewMessage = input<boolean>(false);\r\n \r\n /**\r\n * Emits when attachment is clicked\r\n */\r\n attachmentClick = output<ChatAttachment>();\r\n \r\n /**\r\n * Emits when the message is long-pressed\r\n */\r\n longPress = output<void>();\r\n \r\n /**\r\n * Emits when the message is clicked (to toggle timestamp)\r\n */\r\n messageClick = output<void>();\r\n \r\n /**\r\n * Long press tracking\r\n */\r\n private longPressTimer: any = null;\r\n private longPressTriggered = false;\r\n private touchStartX = 0;\r\n private touchStartY = 0;\r\n private readonly LONG_PRESS_DURATION = 500; // ms\r\n private readonly MOVE_THRESHOLD = 10; // px\r\n private clickStartTime = 0;\r\n \r\n /**\r\n * Tap animation state\r\n */\r\n isTapped = false;\r\n \r\n /**\r\n * Handle attachment click\r\n */\r\n handleAttachmentClick(attachment: ChatAttachment): void {\r\n this.attachmentClick.emit(attachment);\r\n }\r\n \r\n /**\r\n * Handle click (for web/mouse support)\r\n */\r\n handleClick(event: MouseEvent): void {\r\n if (!this.clickable()) return;\r\n \r\n // Prevent double-firing on touch devices\r\n // Touch events will be handled by handleTouchEnd\r\n if ((event as any).sourceCapabilities?.firesTouchEvents) {\r\n return;\r\n }\r\n \r\n // Emit message click to toggle timestamp\r\n this.messageClick.emit();\r\n }\r\n \r\n /**\r\n * Handle touch start for long press detection\r\n */\r\n handleTouchStart(event: TouchEvent): void {\r\n if (!this.clickable()) return;\r\n \r\n // Add tap scale animation\r\n this.isTapped = true;\r\n \r\n this.longPressTriggered = false;\r\n this.clickStartTime = Date.now();\r\n this.touchStartX = event.touches[0].clientX;\r\n this.touchStartY = event.touches[0].clientY;\r\n \r\n // Start long press timer\r\n this.longPressTimer = setTimeout(() => {\r\n this.longPressTriggered = true;\r\n this.longPress.emit();\r\n }, this.LONG_PRESS_DURATION);\r\n }\r\n \r\n /**\r\n * Handle touch end to clear long press timer and detect short tap\r\n */\r\n handleTouchEnd(event: TouchEvent): void {\r\n // Remove tap scale animation\r\n this.isTapped = false;\r\n \r\n const pressDuration = Date.now() - this.clickStartTime;\r\n \r\n if (this.longPressTimer) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n }\r\n \r\n // If long press was triggered, prevent other actions\r\n if (this.longPressTriggered) {\r\n event.preventDefault();\r\n event.stopPropagation();\r\n this.longPressTriggered = false;\r\n return;\r\n }\r\n \r\n // Short tap (less than long press duration) - show timestamp\r\n if (this.clickable() && pressDuration < this.LONG_PRESS_DURATION) {\r\n // Check if moved too much\r\n const touch = event.changedTouches[0];\r\n const deltaX = Math.abs(touch.clientX - this.touchStartX);\r\n const deltaY = Math.abs(touch.clientY - this.touchStartY);\r\n \r\n if (deltaX <= this.MOVE_THRESHOLD && deltaY <= this.MOVE_THRESHOLD) {\r\n this.messageClick.emit();\r\n event.preventDefault();\r\n }\r\n }\r\n }\r\n \r\n /**\r\n * Handle touch move to cancel long press if moved too much\r\n */\r\n handleTouchMove(event: TouchEvent): void {\r\n if (!this.longPressTimer) return;\r\n \r\n const touch = event.touches[0];\r\n const deltaX = Math.abs(touch.clientX - this.touchStartX);\r\n const deltaY = Math.abs(touch.clientY - this.touchStartY);\r\n \r\n // Cancel long press if moved too far\r\n if (deltaX > this.MOVE_THRESHOLD || deltaY > this.MOVE_THRESHOLD) {\r\n clearTimeout(this.longPressTimer);\r\n this.longPressTimer = null;\r\n this.longPressTriggered = false;\r\n // Remove tap animation if moved too far\r\n this.isTapped = false;\r\n }\r\n }\r\n \r\n /**\r\n * Handle context menu (right-click on desktop) to trigger long press action\r\n */\r\n handleContextMenu(event: Event): void {\r\n if (!this.clickable()) return;\r\n event.preventDefault();\r\n this.longPress.emit();\r\n }\r\n}\r\n\r\n","import { Component, input, computed } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n/**\r\n * DsMobileListItemStaticComponent\r\n * \r\n * A read-only version of the interactive list item component.\r\n * Used for displaying static information without interaction.\r\n * \r\n * This component has the same structure as the interactive list item but without:\r\n * - Padding\r\n * - Rounded corners\r\n * - Hover states\r\n * - Click interactions\r\n * - Background fill (transparent)\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-list-item-static\r\n * [leadingSize]=\"'40px'\">\r\n * \r\n * <div content-leading>\r\n * <ds-avatar initials=\"JD\" />\r\n * </div>\r\n * \r\n * <div content-main>\r\n * <h3>Main Content</h3>\r\n * <p>Supporting text goes here...</p>\r\n * </div>\r\n * \r\n * <div content-trailing>\r\n * <span>Info</span>\r\n * </div>\r\n * </ds-mobile-list-item-static>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-list-item-static',\r\n standalone: true,\r\n imports: [CommonModule],\r\n host: {\r\n '[style.--leading-size]': 'leadingSize()'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: row;\r\n align-items: flex-start;\r\n background: transparent;\r\n padding: 0;\r\n gap: 12px;\r\n position: relative;\r\n --leading-size: 32px;\r\n }\r\n \r\n :host::after {\r\n content: '';\r\n position: absolute;\r\n bottom: -10px;\r\n left: calc(var(--leading-size) + 12px);\r\n right: 0;\r\n height: 1px;\r\n background: var(--border-color-default);\r\n }\r\n \r\n :host:last-child::after {\r\n display: none;\r\n }\r\n \r\n .content-leading {\r\n flex-shrink: 0;\r\n width: var(--leading-size);\r\n min-height: var(--leading-size);\r\n height: auto;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n .content-main {\r\n flex: 1;\r\n min-width: 0;\r\n min-height: var(--leading-size);\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: center;\r\n align-items: flex-start;\r\n gap: 8px;\r\n }\r\n \r\n .content-trailing {\r\n flex-shrink: 0;\r\n display: flex;\r\n align-items: flex-start;\r\n }\r\n `],\r\n template: `\r\n @if (hasLeadingContent()) {\r\n <div class=\"content-leading\">\r\n <ng-content select=\"[content-leading]\" />\r\n </div>\r\n }\r\n \r\n <div class=\"content-main\">\r\n <ng-content select=\"[content-main]\" />\r\n <ng-content />\r\n </div>\r\n \r\n @if (hasTrailingContent()) {\r\n <div class=\"content-trailing\">\r\n <ng-content select=\"[content-trailing]\" />\r\n </div>\r\n }\r\n `\r\n})\r\nexport class DsMobileListItemStaticComponent {\r\n /**\r\n * CSS size value for the leading content area (e.g., '32px', '40px', '48px')\r\n * Defaults to '32px' for standard list item avatars\r\n */\r\n leadingSize = input<string>('32px');\r\n \r\n /**\r\n * Check if leading content slot has content\r\n */\r\n hasLeadingContent = computed(() => true); // Always render slot container for consistency\r\n \r\n /**\r\n * Check if trailing content slot has content\r\n */\r\n hasTrailingContent = computed(() => true); // Always render slot container for consistency\r\n}\r\n\r\n","import { Component, input, output, signal, model } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\nimport { DsMobileListItemComponent } from '../list-item';\r\nimport { DsAvatarWithBadgeComponent } from '../avatar-with-badge/ds-avatar-with-badge';\r\n\r\n/**\r\n * DsMobileInteractiveListItemPostComponent\r\n * \r\n * Specialized interactive list item for displaying social media posts.\r\n * Built on top of ds-mobile-interactive-list-item base component.\r\n * Displays user posts with avatar, content, media, and action buttons.\r\n * Follows Threads-inspired design with clean layout and interactions.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-interactive-list-item-post\r\n * [authorName]=\"'John Doe'\"\r\n * [authorRole]=\"'Tenant'\"\r\n * [timestamp]=\"'2h ago'\"\r\n * [avatarInitials]=\"'JD'\"\r\n * [clickable]=\"true\"\r\n * [enableLongPress]=\"true\"\r\n * (postClick)=\"openPost()\">\r\n * \r\n * <post-content>\r\n * <post-text>This is a sample post...</post-text>\r\n * </post-content>\r\n * \r\n * <post-actions>\r\n * <action-like [active]=\"true\" count=\"42\" />\r\n * <action-comment count=\"12\" />\r\n * </post-actions>\r\n * </ds-mobile-interactive-list-item-post>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-interactive-list-item-post',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarWithBadgeComponent, DsMobileListItemComponent],\r\n styles: [`\r\n :host {\r\n display: block;\r\n }\r\n \r\n /* Hide divider on last child */\r\n :host:last-child {\r\n --divider-display: none;\r\n --item-padding-bottom: 0;\r\n }\r\n \r\n .post-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n height: 32px;\r\n margin-bottom: 8px;\r\n }\r\n \r\n .menu-slot {\r\n flex-shrink: 0;\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-list-item\r\n [leadingSize]=\"'32px'\"\r\n [align]=\"align()\"\r\n [variant]=\"variant()\"\r\n [interactive]=\"clickable()\"\r\n [enableLongPress]=\"enableLongPress()\"\r\n [moreActions]=\"moreActions()\"\r\n (itemClick)=\"handlePostClick()\"\r\n (longPress)=\"handleLongPress()\"\r\n (moreButtonClick)=\"handleMoreButtonClick($event)\">\r\n \r\n <div content-leading>\r\n <ds-avatar-with-badge\r\n [type]=\"avatarType()\"\r\n [initials]=\"avatarInitials()\"\r\n [src]=\"avatarSrc()\"\r\n [iconName]=\"avatarIconName()\"\r\n [size]=\"'md'\"\r\n [showBadge]=\"showBadge()\"\r\n [badgePosition]=\"'bottom-right'\"\r\n />\r\n </div>\r\n \r\n <div content-main>\r\n <div class=\"post-header\">\r\n <div class=\"author-details\">\r\n <div class=\"author-name\">{{ authorName() }}</div>\r\n <div class=\"author-meta\">{{ authorRole() }} · {{ timestamp() }}</div>\r\n </div>\r\n \r\n <div class=\"menu-slot\">\r\n <ng-content select=\"post-menu\" />\r\n </div>\r\n </div>\r\n \r\n <ng-content select=\"post-content\" />\r\n <ng-content select=\"post-actions\" />\r\n </div>\r\n </ds-mobile-list-item>\r\n `\r\n})\r\nexport class DsMobileInteractiveListItemPostComponent {\r\n /**\r\n * Author's display name\r\n */\r\n authorName = input.required<string>();\r\n \r\n /**\r\n * Author's role (e.g., \"Tenant\", \"Property Manager\")\r\n */\r\n authorRole = input.required<string>();\r\n \r\n /**\r\n * Timestamp text (e.g., \"2h ago\", \"1d ago\")\r\n */\r\n timestamp = input.required<string>();\r\n \r\n /**\r\n * Avatar initials (for initials type)\r\n */\r\n avatarInitials = input<string>('');\r\n \r\n /**\r\n * Avatar type\r\n */\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n \r\n /**\r\n * Avatar photo source (for photo type)\r\n */\r\n avatarSrc = input<string>('');\r\n \r\n /**\r\n * Icon name (for icon type avatars)\r\n */\r\n avatarIconName = input<string>('remixUser3Fill');\r\n \r\n /**\r\n * Show badge on avatar (e.g., for property managers)\r\n */\r\n showBadge = input<boolean>(false);\r\n \r\n /**\r\n * Display variant\r\n * - undefined (default) - Standard display\r\n * - 'compact' - Compact display for nested/related posts\r\n */\r\n variant = input<'compact' | undefined>(undefined);\r\n \r\n /**\r\n * Vertical alignment of content\r\n * - 'top' - Align to top (default)\r\n * - 'center' - Align to center\r\n * - 'bottom' - Align to bottom\r\n */\r\n align = input<'top' | 'center' | 'bottom'>('top');\r\n \r\n /**\r\n * Whether the post card is clickable\r\n */\r\n clickable = input<boolean>(false);\r\n \r\n /**\r\n * Enable long-press interaction when clickable is true\r\n * Set to false to disable long-press but keep click\r\n * Also controls visibility of desktop \"more\" button\r\n * @default true\r\n */\r\n enableLongPress = input<boolean>(true);\r\n\r\n /**\r\n * Unified toggle for contextual actions (more button + long press).\r\n * When set, takes precedence over `enableLongPress`.\r\n */\r\n moreActions = input<boolean | undefined>(undefined);\r\n\r\n /**\r\n * Emits when the post card is clicked (if clickable)\r\n */\r\n postClick = output<void>();\r\n \r\n /**\r\n * Emits when the comment button is clicked\r\n */\r\n commentClick = output<void>();\r\n \r\n /**\r\n * Emits when the post card is long-pressed\r\n */\r\n longPress = output<void>();\r\n \r\n handlePostClick(): void {\r\n console.log('[InteractiveListItemPost] handlePostClick called, emitting postClick');\r\n this.postClick.emit();\r\n }\r\n \r\n handleCommentClick(): void {\r\n this.commentClick.emit();\r\n }\r\n \r\n handleLongPress(): void {\r\n this.longPress.emit();\r\n }\r\n \r\n handleMoreButtonClick(event: Event): void {\r\n // Desktop more button click - trigger the same action as long press\r\n this.longPress.emit();\r\n }\r\n}\r\n\r\n/**\r\n * PostContentComponent\r\n * \r\n * Main content section of the post.\r\n * \r\n * Contains:\r\n * - `<post-text>` - Text content\r\n * - `<post-media>` - Optional images/videos\r\n * - `<post-attachments>` - Optional file attachments\r\n */\r\n@Component({\r\n selector: 'post-content',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n margin-bottom: 8px;\r\n }\r\n `],\r\n template: `\r\n <ng-content select=\"post-text\" />\r\n <ng-content select=\"post-media\" />\r\n <ng-content select=\"ds-mobile-inline-photo\" />\r\n <ng-content select=\"post-attachments\" />\r\n `\r\n})\r\nexport class PostContentComponent {}\r\n\r\n/**\r\n * PostTextComponent\r\n * \r\n * Text content of the post.\r\n */\r\n@Component({\r\n selector: 'post-text',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 22px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n display: block;\r\n white-space: pre-wrap;\r\n word-wrap: break-word;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostTextComponent {}\r\n\r\n/**\r\n * PostMediaComponent\r\n * \r\n * Media container for images/videos.\r\n */\r\n@Component({\r\n selector: 'post-media',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: block;\r\n border-radius: 8px;\r\n overflow: hidden;\r\n }\r\n \r\n ::ng-deep img {\r\n width: 100%;\r\n height: auto;\r\n display: block;\r\n }\r\n \r\n ::ng-deep video {\r\n width: 100%;\r\n height: auto;\r\n display: block;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostMediaComponent {}\r\n\r\n/**\r\n * PostAttachmentsComponent\r\n * \r\n * Container for file attachments, links, etc.\r\n */\r\n@Component({\r\n selector: 'post-attachments',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostAttachmentsComponent {}\r\n\r\n/**\r\n * PostActionsComponent\r\n * \r\n * Action buttons container (like, comment, share).\r\n * \r\n * Contains:\r\n * - `<action-like>` - Like button with count\r\n * - `<action-comment>` - Comment button with count\r\n * - `<action-share>` - Share button\r\n */\r\n@Component({\r\n selector: 'post-actions',\r\n standalone: true,\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 16px;\r\n padding-top: 4px;\r\n }\r\n `],\r\n template: `<ng-content />`\r\n})\r\nexport class PostActionsComponent {}\r\n\r\n/**\r\n * ActionLikeComponent\r\n * \r\n * Like action button with count display and animated heart icon.\r\n */\r\n@Component({\r\n selector: 'action-like',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent],\r\n host: {\r\n '[class.active]': 'active()',\r\n '(click)': 'handleClick($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 2px;\r\n color: var(--color-text-secondary, #737373);\r\n cursor: pointer;\r\n transition: color 0.2s ease;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n }\r\n \r\n :host.active {\r\n color: #f91880;\r\n }\r\n \r\n .icon-wrapper {\r\n position: relative;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n .icon-pulse {\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n opacity: 0;\r\n pointer-events: none;\r\n }\r\n \r\n .icon-pulse.animating {\r\n animation: pulse 0.4s cubic-bezier(0.4, 0, 0.2, 1);\r\n }\r\n \r\n @keyframes pulse {\r\n 0% {\r\n transform: translate(-50%, -50%) scale(1);\r\n opacity: 0.8;\r\n }\r\n 100% {\r\n transform: translate(-50%, -50%) scale(2.5);\r\n opacity: 0;\r\n }\r\n }\r\n \r\n .count {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 500;\r\n line-height: 20px;\r\n letter-spacing: -0.28px;\r\n }\r\n `],\r\n template: `\r\n <div class=\"icon-wrapper\">\r\n <ds-icon \r\n #pulseIcon\r\n class=\"icon-pulse\"\r\n [class.animating]=\"isPulsing()\"\r\n [name]=\"active() ? 'remixHeart3Fill' : 'remixHeart3Line'\" \r\n size=\"20px\" />\r\n <ds-icon \r\n [name]=\"active() ? 'remixHeart3Fill' : 'remixHeart3Line'\" \r\n size=\"20px\" />\r\n </div>\r\n @if (count() > 0) {\r\n <span class=\"count\">{{ count() }}</span>\r\n }\r\n `\r\n})\r\nexport class ActionLikeComponent {\r\n /**\r\n * Whether the like is active (user has liked)\r\n * Using model() for two-way binding\r\n */\r\n active = model<boolean>(false);\r\n \r\n /**\r\n * Number of likes\r\n * Using model() for two-way binding\r\n */\r\n count = model<number>(0);\r\n \r\n /**\r\n * Emits when the like button is clicked\r\n */\r\n likeClick = output<{ active: boolean; count: number }>();\r\n \r\n /**\r\n * Signal to control pulse animation\r\n */\r\n isPulsing = signal(false);\r\n \r\n async handleClick(event: Event): Promise<void> {\r\n event.stopPropagation();\r\n \r\n // Toggle active state\r\n const newActive = !this.active();\r\n this.active.set(newActive);\r\n \r\n // Update count\r\n const newCount = newActive ? this.count() + 1 : this.count() - 1;\r\n this.count.set(Math.max(0, newCount));\r\n \r\n // Trigger pulse animation only when liking\r\n if (newActive) {\r\n this.isPulsing.set(true);\r\n setTimeout(() => this.isPulsing.set(false), 400);\r\n }\r\n \r\n // Haptic feedback for like/unlike\r\n try {\r\n await Haptics.impact({ style: ImpactStyle.Light });\r\n } catch {\r\n // Fallback to Web Vibration API if Capacitor Haptics is not available\r\n if ('vibrate' in navigator) {\r\n navigator.vibrate(50);\r\n }\r\n }\r\n \r\n // Emit the event with the new state\r\n this.likeClick.emit({ active: newActive, count: newCount });\r\n }\r\n}\r\n\r\n/**\r\n * ActionCommentComponent\r\n * \r\n * Comment action button with count display.\r\n */\r\n@Component({\r\n selector: 'action-comment',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent],\r\n host: {\r\n '(click)': 'handleClick($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 2px;\r\n color: var(--color-text-secondary, #737373);\r\n cursor: pointer;\r\n transition: color 0.2s ease;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n }\r\n \r\n :host:active {\r\n transform: scale(0.95);\r\n }\r\n \r\n :host:hover {\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n .count {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 500;\r\n line-height: 20px;\r\n letter-spacing: -0.28px;\r\n }\r\n `],\r\n template: `\r\n <ds-icon name=\"remixChat3Line\" size=\"20px\" />\r\n @if (count() > 0) {\r\n <span class=\"count\">{{ count() }}</span>\r\n }\r\n `\r\n})\r\nexport class ActionCommentComponent {\r\n /**\r\n * Number of comments\r\n */\r\n count = input<number>(0);\r\n \r\n /**\r\n * Emits when the comment button is clicked\r\n */\r\n commentClick = output<void>();\r\n \r\n handleClick(event: Event): void {\r\n event.stopPropagation();\r\n this.commentClick.emit();\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * PostPdfAttachmentComponent\r\n * \r\n * PDF file attachment display for posts.\r\n * Shows PDF info card with icon, filename, and file size.\r\n * Emits click event to open PDF in viewer.\r\n */\r\n@Component({\r\n selector: 'post-pdf-attachment',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarComponent, DsIconComponent],\r\n host: {\r\n '(click)': 'handleClick($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n padding: 10px 12px;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-radius: 16px;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n }\r\n \r\n :host:hover {\r\n background: var(--color-background-neutral-secondary-hover, #ebebeb);\r\n }\r\n \r\n :host:active {\r\n transform: scale(0.98);\r\n }\r\n \r\n .pdf-avatar {\r\n flex-shrink: 0;\r\n }\r\n \r\n .pdf-avatar::ng-deep .avatar--icon {\r\n background-color: #ff5757 !important;\r\n }\r\n \r\n .pdf-info {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 2px;\r\n }\r\n \r\n .pdf-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n .pdf-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--color-text-tertiary, #737373);\r\n }\r\n \r\n .open-icon {\r\n color: var(--color-text-tertiary, #a3a3a3);\r\n flex-shrink: 0;\r\n }\r\n `],\r\n template: `\r\n <div class=\"pdf-avatar\">\r\n <ds-avatar\r\n type=\"icon\"\r\n iconName=\"remixFileTextLine\"\r\n size=\"md\"\r\n />\r\n </div>\r\n \r\n <div class=\"pdf-info\">\r\n <div class=\"pdf-name\">{{ fileName() }}</div>\r\n <div class=\"pdf-meta\">PDF · {{ fileSize() }}</div>\r\n </div>\r\n \r\n <ds-icon \r\n name=\"remixArrowRightSLine\" \r\n size=\"24px\"\r\n class=\"open-icon\"\r\n />\r\n `\r\n})\r\nexport class PostPdfAttachmentComponent {\r\n /**\r\n * PDF file name\r\n */\r\n fileName = input<string>('Document.pdf');\r\n \r\n /**\r\n * File size display (e.g., \"1.2 MB\")\r\n */\r\n fileSize = input<string>('');\r\n \r\n /**\r\n * Emits when the PDF attachment is clicked\r\n */\r\n pdfClick = output<void>();\r\n \r\n handleClick(event: Event): void {\r\n event.stopPropagation();\r\n this.pdfClick.emit();\r\n }\r\n}\r\n\r\n","// Export the main component and shared post components without the indent\r\nexport {\r\n DsMobileInteractiveListItemPostComponent,\r\n PostContentComponent,\r\n PostTextComponent,\r\n PostMediaComponent,\r\n PostAttachmentsComponent,\r\n PostActionsComponent,\r\n ActionLikeComponent,\r\n ActionCommentComponent\r\n} from './ds-mobile-interactive-list-item-post';\r\nexport { PostPdfAttachmentComponent } from './ds-mobile-post-pdf-attachment';\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsShapeIndicatorComponent } from '@propbinder/design-system';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsMobileListItemComponent } from '../list-item';\r\n\r\n/**\r\n * DsMobileInteractiveListItemInquiryComponent\r\n * \r\n * Specialized interactive list item for displaying inquiries/tickets.\r\n * Built on top of ds-mobile-interactive-list-item base component.\r\n * Displays inquiry title, description, status, and timestamp.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-interactive-list-item-inquiry\r\n * [title]=\"'Tumble dryer is not working'\"\r\n * [description]=\"'For the past three days, I have been experiencing...'\"\r\n * [status]=\"'open'\"\r\n * [timestamp]=\"'12 days ago'\"\r\n * [iconName]=\"'remixCalendarLine'\"\r\n * [clickable]=\"true\"\r\n * [enableLongPress]=\"true\"\r\n * (inquiryClick)=\"openInquiry()\">\r\n * </ds-mobile-interactive-list-item-inquiry>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-interactive-list-item-inquiry',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent, DsShapeIndicatorComponent, DsAvatarComponent, DsMobileListItemComponent],\r\n styles: [`\r\n :host {\r\n display: block;\r\n }\r\n \r\n /* Hide divider on last child */\r\n :host:last-child {\r\n --divider-display: none;\r\n --item-padding-bottom: 0;\r\n }\r\n \r\n .inquiry-avatar {\r\n flex-shrink: 0;\r\n }\r\n \r\n /* Default/Open inquiries: brand-primary surface with brand-primary content */\r\n .inquiry-avatar:not(.closed)::ng-deep .avatar--icon {\r\n background-color: var(--color-accent, #5d5fef) !important;\r\n }\r\n \r\n .inquiry-avatar:not(.closed)::ng-deep .avatar--icon ds-icon,\r\n .inquiry-avatar:not(.closed)::ng-deep .avatar--icon ds-icon::ng-deep svg {\r\n color: var(--color-on-accent, #ffffff) !important;\r\n fill: var(--color-on-accent, #ffffff) !important;\r\n }\r\n \r\n /* Closed inquiries: content tertiary surface with white icon */\r\n .inquiry-avatar.closed::ng-deep .avatar--icon {\r\n background-color: var(--text-color-default-tertiary, #737373) !important;\r\n }\r\n \r\n .inquiry-avatar.closed::ng-deep .avatar--icon ds-icon,\r\n .inquiry-avatar.closed::ng-deep .avatar--icon ds-icon::ng-deep svg {\r\n color: #ffffff !important;\r\n fill: #ffffff !important;\r\n }\r\n \r\n .inquiry-content {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 4px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .inquiry-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm, 14px);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-primary, #202227);\r\n margin: 0;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n .inquiry-description {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm, 14px);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n margin: 0;\r\n display: -webkit-box;\r\n -webkit-line-clamp: 2;\r\n -webkit-box-orient: vertical;\r\n overflow: hidden;\r\n }\r\n \r\n .inquiry-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs, 12px);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n margin-top: 4px;\r\n }\r\n \r\n .inquiry-status {\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 500;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n }\r\n \r\n .inquiry-status.open {\r\n color: var(--text-color-default-tertiary, #737373);\r\n }\r\n \r\n .inquiry-status.closed {\r\n color: var(--text-color-default-tertiary, #737373);\r\n }\r\n \r\n .inquiry-timestamp {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n }\r\n \r\n .inquiry-trailing {\r\n display: flex;\r\n align-items: center;\r\n color: var(--color-text-tertiary, #a3a3a3);\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-list-item\r\n [leadingSize]=\"'32px'\"\r\n [align]=\"align()\"\r\n [variant]=\"variant()\"\r\n [interactive]=\"clickable()\"\r\n [enableLongPress]=\"enableLongPress()\"\r\n [moreActions]=\"moreActions()\"\r\n (itemClick)=\"handleInquiryClick()\"\r\n (longPress)=\"handleLongPress()\"\r\n (moreButtonClick)=\"handleMoreButtonClick($event)\">\r\n \r\n <div content-leading>\r\n <div class=\"inquiry-avatar\" [class.closed]=\"status() === 'closed'\">\r\n <ds-avatar\r\n type=\"icon\"\r\n [iconName]=\"iconName()\"\r\n size=\"md\"\r\n />\r\n </div>\r\n </div>\r\n \r\n <div content-main>\r\n <div class=\"inquiry-content\">\r\n <h3 class=\"inquiry-title\">{{ title() }}</h3>\r\n \r\n @if (description()) {\r\n <p class=\"inquiry-description\">{{ description() }}</p>\r\n }\r\n \r\n <div class=\"inquiry-meta\">\r\n <div class=\"inquiry-status\" [class.open]=\"status() === 'open'\" [class.closed]=\"status() === 'closed'\">\r\n <ds-shape-indicator \r\n shape=\"circle\" \r\n [variant]=\"status() === 'open' ? 'brand' : 'grey'\">\r\n </ds-shape-indicator>\r\n <span>{{ computedStatusLabel() }}</span>\r\n </div>\r\n \r\n <div class=\"inquiry-timestamp\">\r\n <ds-icon name=\"remixTimeLine\" size=\"14px\" color=\"--color-text-secondary\" />\r\n <span>{{ timestamp() }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n @if (showChevron()) {\r\n <div content-trailing>\r\n <div class=\"inquiry-trailing\">\r\n <ds-icon name=\"remixArrowRightSLine\" size=\"20px\" />\r\n </div>\r\n </div>\r\n }\r\n </ds-mobile-list-item>\r\n `\r\n})\r\nexport class DsMobileInteractiveListItemInquiryComponent {\r\n /**\r\n * Inquiry title\r\n */\r\n title = input.required<string>();\r\n \r\n /**\r\n * Inquiry description/preview text\r\n */\r\n description = input<string>('');\r\n \r\n /**\r\n * Inquiry status\r\n */\r\n status = input<'open' | 'closed'>('open');\r\n \r\n /**\r\n * Status label (defaults to capitalized status)\r\n */\r\n statusLabel = input<string>('');\r\n \r\n /**\r\n * Timestamp text (e.g., \"12 days ago\", \"2 months ago\")\r\n */\r\n timestamp = input.required<string>();\r\n \r\n /**\r\n * Icon name for the leading icon\r\n */\r\n iconName = input<string>('remixTodoLine');\r\n \r\n /**\r\n * Icon color\r\n */\r\n iconColor = input<string>('secondary');\r\n \r\n /**\r\n * Display variant\r\n * - undefined (default) - Standard display\r\n * - 'compact' - Compact display\r\n */\r\n variant = input<'compact' | undefined>(undefined);\r\n \r\n /**\r\n * Vertical alignment of content\r\n * - 'top' - Align to top (default)\r\n * - 'center' - Align to center\r\n * - 'bottom' - Align to bottom\r\n */\r\n align = input<'top' | 'center' | 'bottom'>('top');\r\n \r\n /**\r\n * Whether the inquiry item is clickable\r\n */\r\n clickable = input<boolean>(true);\r\n \r\n /**\r\n * Whether to show chevron icon\r\n */\r\n showChevron = input<boolean>(true);\r\n \r\n /**\r\n * Enable long-press interaction when clickable is true\r\n * Set to false to disable long-press but keep click\r\n * Also controls visibility of desktop \"more\" button\r\n * @default true\r\n */\r\n enableLongPress = input<boolean>(true);\r\n\r\n /**\r\n * Unified toggle for contextual actions (more button + long press).\r\n * When set, takes precedence over `enableLongPress`.\r\n */\r\n moreActions = input<boolean | undefined>(undefined);\r\n\r\n /**\r\n * Emits when the inquiry item is clicked (if clickable)\r\n */\r\n inquiryClick = output<void>();\r\n \r\n /**\r\n * Emits when the inquiry item is long-pressed\r\n */\r\n longPress = output<void>();\r\n \r\n /**\r\n * Get computed status label\r\n */\r\n computedStatusLabel(): string {\r\n if (this.statusLabel()) {\r\n return this.statusLabel();\r\n }\r\n return this.status() === 'open' ? 'Åben' : 'Lukket';\r\n }\r\n \r\n handleInquiryClick(): void {\r\n this.inquiryClick.emit();\r\n }\r\n \r\n handleLongPress(): void {\r\n this.longPress.emit();\r\n }\r\n \r\n handleMoreButtonClick(event: Event): void {\r\n // Desktop more button click - trigger the same action as long press\r\n this.longPress.emit();\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsMobileListItemComponent } from '../list-item';\r\nimport { DsAvatarWithBadgeComponent } from '../avatar-with-badge';\r\n\r\n/**\r\n * DsMobileInteractiveListItemMessageComponent\r\n * \r\n * Specialized interactive list item for displaying message threads.\r\n * Built on top of ds-mobile-interactive-list-item base component.\r\n * Displays message preview with sender info - simplified version without actions.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-interactive-list-item-message\r\n * [senderName]=\"'John Doe'\"\r\n * [senderRole]=\"'Tenant'\"\r\n * [timestamp]=\"'2h ago'\"\r\n * [message]=\"'Hey, when is the maintenance scheduled?'\"\r\n * [avatarInitials]=\"'JD'\"\r\n * [unread]=\"true\"\r\n * [clickable]=\"true\"\r\n * (messageClick)=\"openThread()\">\r\n * </ds-mobile-interactive-list-item-message>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-interactive-list-item-message',\r\n standalone: true,\r\n imports: [CommonModule, DsAvatarWithBadgeComponent, DsMobileListItemComponent],\r\n styles: [`\r\n :host {\r\n display: block;\r\n }\r\n \r\n /* Hide divider on last child */\r\n :host:last-child {\r\n --divider-display: none;\r\n --item-padding-bottom: 0;\r\n }\r\n \r\n .message-header {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n height: 32px;\r\n margin-bottom: 8px;\r\n }\r\n \r\n .sender-details {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: flex-start;\r\n gap: 2px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .sender-name-row {\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n flex-shrink: 0;\r\n }\r\n \r\n .sender-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm, 14px);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-primary, #202227);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n flex-shrink: 0;\r\n }\r\n \r\n .sender-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs, 12px);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--text-color-default-tertiary, #737373);\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n flex-shrink: 1;\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n }\r\n \r\n .meta-separator {\r\n color: var(--text-color-default-tertiary, #737373);\r\n opacity: 0.5;\r\n }\r\n \r\n .unread-indicator {\r\n width: 8px;\r\n height: 8px;\r\n border-radius: 50%;\r\n background: var(--color-brand-primary, #5d5fef);\r\n flex-shrink: 0;\r\n }\r\n \r\n .message-preview {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n margin: 0;\r\n display: -webkit-box;\r\n -webkit-line-clamp: 2;\r\n -webkit-box-orient: vertical;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-list-item\r\n [leadingSize]=\"'32px'\"\r\n [align]=\"align()\"\r\n [interactive]=\"clickable()\"\r\n [enableLongPress]=\"false\"\r\n [showDesktopMoreButton]=\"false\"\r\n [moreActions]=\"false\"\r\n (itemClick)=\"handleMessageClick()\">\r\n \r\n <div content-leading>\r\n <ds-avatar-with-badge \r\n [initials]=\"avatarInitials()\"\r\n [type]=\"avatarType()\"\r\n [src]=\"avatarSrc()\"\r\n size=\"md\" />\r\n </div>\r\n \r\n <div content-main>\r\n <div class=\"message-header\">\r\n <div class=\"sender-details\">\r\n <div class=\"sender-name-row\">\r\n <span class=\"sender-name\">{{ senderName() }}</span>\r\n @if (unread()) {\r\n <div class=\"unread-indicator\"></div>\r\n }\r\n </div>\r\n <span class=\"sender-meta\">\r\n {{ senderRole() }}\r\n @if (timestamp()) {\r\n <span class=\"meta-separator\">·</span>\r\n <span>{{ timestamp() }}</span>\r\n }\r\n </span>\r\n </div>\r\n </div>\r\n \r\n <p class=\"message-preview\">{{ message() }}</p>\r\n </div>\r\n </ds-mobile-list-item>\r\n `\r\n})\r\nexport class DsMobileInteractiveListItemMessageComponent {\r\n /**\r\n * Sender's display name\r\n */\r\n senderName = input.required<string>();\r\n \r\n /**\r\n * Sender's role (e.g., \"Tenant\", \"Property Manager\")\r\n */\r\n senderRole = input.required<string>();\r\n \r\n /**\r\n * Timestamp for the message (e.g., \"2h ago\", \"2t siden\")\r\n */\r\n timestamp = input<string>('');\r\n \r\n /**\r\n * Message preview text\r\n */\r\n message = input.required<string>();\r\n \r\n /**\r\n * Avatar initials (for initials type)\r\n */\r\n avatarInitials = input<string>('');\r\n \r\n /**\r\n * Avatar type\r\n */\r\n avatarType = input<'initials' | 'photo' | 'icon'>('initials');\r\n \r\n /**\r\n * Avatar photo source (for photo type)\r\n */\r\n avatarSrc = input<string>('');\r\n \r\n /**\r\n * Whether the message is unread\r\n */\r\n unread = input<boolean>(false);\r\n \r\n /**\r\n * Whether the message item is clickable\r\n */\r\n clickable = input<boolean>(true);\r\n \r\n /**\r\n * Vertical alignment of content\r\n * - 'top' - Align to top (default)\r\n * - 'center' - Align to center\r\n * - 'bottom' - Align to bottom\r\n */\r\n align = input<'top' | 'center' | 'bottom'>('top');\r\n \r\n /**\r\n * Emits when the message item is clicked\r\n */\r\n messageClick = output<void>();\r\n \r\n /**\r\n * Emits when the message item is long-pressed\r\n */\r\n longPress = output<void>();\r\n \r\n handleMessageClick(): void {\r\n this.messageClick.emit();\r\n }\r\n \r\n handleLongPress(): void {\r\n this.longPress.emit();\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobileContactListItemComponent\r\n * \r\n * Specialized interactive component for displaying contacts.\r\n * Displays contact name with avatar initials and metadata (person name + phone number).\r\n * Similar styling to file attachments with rounded corners and hover states.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-contact-list-item\r\n * [name]=\"'Mortensen & Søn ApS'\"\r\n * [initials]=\"'M'\"\r\n * [contactPerson]=\"'John Mortensen'\"\r\n * [phoneNumber]=\"'+45 12 34 56 78'\"\r\n * [clickable]=\"true\"\r\n * (contactClick)=\"openContact()\">\r\n * </ds-mobile-contact-list-item>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-contact-list-item',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent, DsAvatarComponent],\r\n host: {\r\n '[class.clickable]': 'clickable()',\r\n '(click)': 'handleContactClick()'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n padding: 10px 12px;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-radius: 16px;\r\n transition: all 0.2s ease;\r\n }\r\n \r\n :host.clickable {\r\n cursor: pointer;\r\n }\r\n \r\n :host.clickable:hover {\r\n background: var(--color-background-neutral-secondary-hover, #ebebeb);\r\n }\r\n \r\n :host.clickable:active {\r\n transform: scale(0.98);\r\n }\r\n \r\n .contact-avatar {\r\n flex-shrink: 0;\r\n }\r\n\r\n .contact-content {\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: center;\r\n gap: 2px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .contact-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n margin: 0;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n .contact-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--color-text-tertiary, #737373);\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n margin: 0;\r\n }\r\n \r\n .meta-separator {\r\n color: var(--color-text-tertiary, #a0a0a0);\r\n }\r\n \r\n .contact-trailing {\r\n display: flex;\r\n align-items: center;\r\n color: var(--color-text-tertiary, #a3a3a3);\r\n flex-shrink: 0;\r\n }\r\n `],\r\n template: `\r\n <div class=\"contact-avatar\">\r\n <ds-avatar\r\n [initials]=\"initials()\"\r\n type=\"initials\"\r\n size=\"md\"\r\n />\r\n </div>\r\n \r\n <div class=\"contact-content\">\r\n <div class=\"contact-name\">{{ name() }}</div>\r\n \r\n @if (contactPerson() || phoneNumber()) {\r\n <div class=\"contact-meta\">\r\n @if (contactPerson()) {\r\n <span>{{ contactPerson() }}</span>\r\n }\r\n @if (contactPerson() && phoneNumber()) {\r\n <span class=\"meta-separator\">·</span>\r\n }\r\n @if (phoneNumber()) {\r\n <span>{{ phoneNumber() }}</span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n \r\n @if (showChevron()) {\r\n <div class=\"contact-trailing\">\r\n <ds-icon name=\"remixArrowRightSLine\" size=\"20px\" />\r\n </div>\r\n }\r\n `\r\n})\r\nexport class DsMobileContactListItemComponent {\r\n /**\r\n * Contact/company name\r\n */\r\n name = input.required<string>();\r\n \r\n /**\r\n * Avatar initials (usually 1-2 letters)\r\n */\r\n initials = input.required<string>();\r\n \r\n /**\r\n * Contact person name (optional)\r\n */\r\n contactPerson = input<string>('');\r\n \r\n /**\r\n * Phone number (optional)\r\n */\r\n phoneNumber = input<string>('');\r\n \r\n /**\r\n * Whether the contact item is clickable\r\n */\r\n clickable = input<boolean>(true);\r\n \r\n /**\r\n * Whether to show chevron icon\r\n */\r\n showChevron = input<boolean>(true);\r\n \r\n /**\r\n * Emits when the contact item is clicked (if clickable)\r\n */\r\n contactClick = output<void>();\r\n \r\n handleContactClick(): void {\r\n if (this.clickable()) {\r\n this.contactClick.emit();\r\n }\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsShapeIndicatorComponent } from '@propbinder/design-system';\r\nimport { DsMobileListItemComponent } from '../list-item';\r\n\r\n/**\r\n * DsMobileInteractiveListItemBookingComponent\r\n * \r\n * Specialized interactive list item for displaying facility bookings.\r\n * Built on top of ds-mobile-list-item base component.\r\n * Displays facility thumbnail, title, description, booking dates/times, and availability status.\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Active booking variant -->\r\n * <ds-mobile-interactive-list-item-booking\r\n * [thumbnail]=\"'assets/facility.jpg'\"\r\n * [facilityTitle]=\"'Gæsteparkering'\"\r\n * [bookingDate]=\"'14. februar, 2026'\"\r\n * [bookingTime]=\"'9:00 - 17:00'\"\r\n * [clickable]=\"false\">\r\n * </ds-mobile-interactive-list-item-booking>\r\n * \r\n * <!-- Available facility variant -->\r\n * <ds-mobile-interactive-list-item-booking\r\n * [thumbnail]=\"'assets/facility.jpg'\"\r\n * [facilityTitle]=\"'Boremaskinen'\"\r\n * [description]=\"'Book a guest parking spot to give your visitors...'\"\r\n * [availabilityStatus]=\"'available-today'\"\r\n * [statusLabel]=\"'Ledig i dag'\"\r\n * [clickable]=\"true\"\r\n * [enableLongPress]=\"false\"\r\n * (bookingClick)=\"openBooking()\">\r\n * </ds-mobile-interactive-list-item-booking>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-interactive-list-item-booking',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent, DsShapeIndicatorComponent, DsMobileListItemComponent],\r\n styles: [`\r\n :host {\r\n display: block;\r\n }\r\n \r\n /* Hide divider on last child */\r\n :host:last-child {\r\n --divider-display: none;\r\n --item-padding-bottom: 0;\r\n }\r\n \r\n .booking-thumbnail {\r\n flex-shrink: 0;\r\n width: 64px;\r\n height: 64px;\r\n border-radius: 12px;\r\n overflow: hidden;\r\n background: var(--color-surface-secondary, #f5f5f5);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n .booking-thumbnail img {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n }\r\n \r\n .booking-thumbnail-placeholder {\r\n width: 100%;\r\n height: 100%;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n color: var(--text-color-default-tertiary, #737373);\r\n }\r\n \r\n .booking-content {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 4px;\r\n flex: 1;\r\n min-width: 0;\r\n }\r\n \r\n .booking-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm, 14px);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-primary, #202227);\r\n margin: 0;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n \r\n .booking-description {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm, 14px);\r\n font-weight: 400;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n margin: 0;\r\n display: -webkit-box;\r\n -webkit-line-clamp: 2;\r\n -webkit-box-orient: vertical;\r\n overflow: hidden;\r\n }\r\n \r\n .booking-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs, 12px);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n margin-top: 4px;\r\n }\r\n \r\n .booking-status {\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 500;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n }\r\n \r\n .booking-status.available-today {\r\n color: var(--color-accent, #5d5fef);\r\n }\r\n \r\n .booking-status.available-from {\r\n color: var(--color-warning, #f59e0b);\r\n }\r\n \r\n .booking-status.unavailable {\r\n color: var(--text-color-default-tertiary, #737373);\r\n }\r\n \r\n .booking-datetime {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--text-color-default-secondary, #545B66);\r\n }\r\n \r\n .booking-trailing {\r\n display: flex;\r\n align-items: center;\r\n color: var(--color-text-tertiary, #a3a3a3);\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-list-item\r\n [leadingSize]=\"'64px'\"\r\n [align]=\"align()\"\r\n [variant]=\"variant()\"\r\n [interactive]=\"clickable()\"\r\n [enableLongPress]=\"enableLongPress()\"\r\n [moreActions]=\"moreActions()\"\r\n (itemClick)=\"handleBookingClick()\"\r\n (longPress)=\"handleLongPress()\"\r\n (moreButtonClick)=\"handleMoreButtonClick($event)\">\r\n \r\n <div content-leading>\r\n <div class=\"booking-thumbnail\">\r\n @if (thumbnail()) {\r\n <img [src]=\"thumbnail()\" [alt]=\"facilityTitle()\" />\r\n } @else {\r\n <div class=\"booking-thumbnail-placeholder\">\r\n <ds-icon name=\"remixImageLine\" size=\"24px\" color=\"--text-color-default-tertiary\" />\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n \r\n <div content-main>\r\n <div class=\"booking-content\">\r\n <h3 class=\"booking-title\">{{ facilityTitle() }}</h3>\r\n \r\n @if (description()) {\r\n <p class=\"booking-description\">{{ description() }}</p>\r\n }\r\n \r\n <div class=\"booking-meta\">\r\n @if (availabilityStatus()) {\r\n <div class=\"booking-status\" \r\n [class.available-today]=\"availabilityStatus() === 'available-today'\" \r\n [class.available-from]=\"availabilityStatus() === 'available-from'\"\r\n [class.unavailable]=\"availabilityStatus() === 'unavailable'\">\r\n <ds-shape-indicator \r\n shape=\"circle\" \r\n [variant]=\"getStatusVariant()\">\r\n </ds-shape-indicator>\r\n <span>{{ statusLabel() }}</span>\r\n </div>\r\n }\r\n \r\n @if (bookingDate()) {\r\n <div class=\"booking-datetime\">\r\n <ds-icon name=\"remixCalendarLine\" size=\"14px\" color=\"--color-text-secondary\" />\r\n <span>{{ bookingDate() }}</span>\r\n </div>\r\n }\r\n \r\n @if (bookingTime()) {\r\n <div class=\"booking-datetime\">\r\n <ds-icon name=\"remixTimeLine\" size=\"14px\" color=\"--color-text-secondary\" />\r\n <span>{{ bookingTime() }}</span>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n \r\n @if (showChevron()) {\r\n <div content-trailing>\r\n <div class=\"booking-trailing\">\r\n <ds-icon name=\"remixArrowRightSLine\" size=\"20px\" />\r\n </div>\r\n </div>\r\n }\r\n </ds-mobile-list-item>\r\n `\r\n})\r\nexport class DsMobileInteractiveListItemBookingComponent {\r\n /**\r\n * Facility thumbnail image URL\r\n */\r\n thumbnail = input<string>('');\r\n \r\n /**\r\n * Facility title\r\n */\r\n facilityTitle = input.required<string>();\r\n \r\n /**\r\n * Facility description/preview text (only for available facilities)\r\n */\r\n description = input<string>('');\r\n \r\n /**\r\n * Booking date (only for active bookings, e.g., \"14. februar, 2026\")\r\n */\r\n bookingDate = input<string>('');\r\n \r\n /**\r\n * Booking time range (only for active bookings, e.g., \"9:00 - 17:00\")\r\n */\r\n bookingTime = input<string>('');\r\n \r\n /**\r\n * Availability status (only for available facilities)\r\n */\r\n availabilityStatus = input<'available-today' | 'available-from' | 'unavailable' | undefined>(undefined);\r\n \r\n /**\r\n * Status label text (e.g., \"Ledig i dag\", \"Ledig fra 28. februar, 2026\")\r\n */\r\n statusLabel = input<string>('');\r\n \r\n /**\r\n * Display variant\r\n * - undefined (default) - Standard display\r\n * - 'compact' - Compact display\r\n */\r\n variant = input<'compact' | undefined>(undefined);\r\n \r\n /**\r\n * Vertical alignment of content\r\n * - 'top' - Align to top (default)\r\n * - 'center' - Align to center\r\n * - 'bottom' - Align to bottom\r\n */\r\n align = input<'top' | 'center' | 'bottom'>('top');\r\n \r\n /**\r\n * Whether the booking item is clickable\r\n */\r\n clickable = input<boolean>(true);\r\n \r\n /**\r\n * Whether to show chevron icon\r\n */\r\n showChevron = input<boolean>(true);\r\n \r\n /**\r\n * Enable long-press interaction when clickable is true\r\n * Set to false to disable long-press but keep click\r\n * Also controls visibility of desktop \"more\" button\r\n * @default true\r\n */\r\n enableLongPress = input<boolean>(true);\r\n\r\n /**\r\n * Unified toggle for contextual actions (more button + long press).\r\n * When set, takes precedence over `enableLongPress`.\r\n */\r\n moreActions = input<boolean | undefined>(undefined);\r\n\r\n /**\r\n * Emits when the booking item is clicked (if clickable)\r\n */\r\n bookingClick = output<void>();\r\n \r\n /**\r\n * Emits when the booking item is long-pressed\r\n */\r\n longPress = output<void>();\r\n \r\n /**\r\n * Get status indicator variant based on availability status\r\n */\r\n getStatusVariant(): 'brand' | 'warning' | 'grey' {\r\n const status = this.availabilityStatus();\r\n if (status === 'available-today') return 'brand';\r\n if (status === 'available-from') return 'warning';\r\n return 'grey';\r\n }\r\n \r\n handleBookingClick(): void {\r\n this.bookingClick.emit();\r\n }\r\n \r\n handleLongPress(): void {\r\n this.longPress.emit();\r\n }\r\n \r\n handleMoreButtonClick(event: Event): void {\r\n // Desktop more button click - trigger the same action as long press\r\n this.longPress.emit();\r\n }\r\n}\r\n","import { Component, Input, Output, EventEmitter, signal, OnInit, AfterViewInit, OnDestroy, ElementRef, computed, inject, effect } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { Router, NavigationEnd } from '@angular/router';\r\nimport { filter } from 'rxjs/operators';\r\nimport { IonTabBar, IonTabButton, IonLabel, ModalController } from '@ionic/angular/standalone';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsLogoComponent } from '../logo/ds-logo';\r\nimport { DsMobileProfileActionsSheetComponent, ActionResult, ActionGroup, Language } from '../bottom-sheet';\r\nimport { disableModalShadowPointerEvents } from '../bottom-sheet/modal-shadow-fix';\r\nimport { UserService } from '../../services/user.service';\r\n\r\nexport interface TabConfig {\r\n id: string;\r\n label: string;\r\n route: string;\r\n icon: string;\r\n iconActive: string;\r\n}\r\n\r\n/**\r\n * DsMobileTabBarComponent\r\n *\r\n * Responsive navigation tab bar that adapts from mobile to desktop:\r\n * - Mobile (< 768px): Bottom tab bar with icons + labels\r\n * - Desktop (≥ 768px): Top navigation bar with logo, tabs, and avatar\r\n *\r\n * Use this component INSIDE your own `ion-tabs` when Angular routing\r\n * requires `ion-tabs` to be a direct child in your component.\r\n *\r\n * @example\r\n * ```html\r\n * <!-- In your component with child routes -->\r\n * <!-- IMPORTANT: Add class=\"ds-tabs-wrapper\" to ion-tabs for proper styling -->\r\n * <ion-tabs class=\"ds-tabs-wrapper\">\r\n * <ds-mobile-tab-bar\r\n * [tabs]=\"tabs\"\r\n * [avatarInitials]=\"'JD'\"\r\n * [profileMenuItems]=\"profileMenuItems\"\r\n * (profileActionSelected)=\"handleProfileAction($event)\"\r\n * />\r\n * </ion-tabs>\r\n * ```\r\n *\r\n * @example With profile menu configuration\r\n * ```typescript\r\n * profileMenuItems: ActionGroup[] = [\r\n * {\r\n * actions: [\r\n * { action: 'profile', title: 'My Profile', icon: 'remixUser3Line' },\r\n * { action: 'settings', title: 'Settings', icon: 'remixSettings3Line' }\r\n * ]\r\n * },\r\n * {\r\n * actions: [\r\n * { action: 'logout', title: 'Log Out', icon: 'remixLogoutBoxLine', destructive: true }\r\n * ]\r\n * }\r\n * ];\r\n *\r\n * handleProfileAction(result: ActionResult): void {\r\n * switch (result.action) {\r\n * case 'profile': // Navigate to profile\r\n * case 'settings': // Navigate to settings\r\n * case 'logout': // Handle logout\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @note When using this component, you must add the class \"ds-tabs-wrapper\"\r\n * to your `ion-tabs` element, or manually apply these styles:\r\n * ```css\r\n * ion-tabs {\r\n * height: 100%;\r\n * background: var(--color-header-surface);\r\n * }\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-tab-bar',\r\n standalone: true,\r\n imports: [CommonModule, IonTabBar, IonTabButton, IonLabel, DsIconComponent, DsAvatarComponent, DsLogoComponent],\r\n styleUrls: ['./ds-mobile-tab-bar.css'],\r\n template: `\r\n <ion-tab-bar [attr.slot]=\"isDesktop() ? 'top' : 'bottom'\" class=\"ds-tab-bar\" [class.ds-tab-bar--desktop]=\"isDesktop()\">\r\n <!-- Logo (desktop only, full logo in header) -->\r\n <div class=\"ds-tab-bar__logo\">\r\n <ds-logo variant=\"full\" size=\"lg\" />\r\n </div>\r\n\r\n <!-- Tab buttons container -->\r\n <div class=\"ds-tab-bar__tabs\" *ngIf=\"tabs\">\r\n <ion-tab-button\r\n *ngFor=\"let tab of tabs; trackBy: trackByTabId\"\r\n [tab]=\"tab.route\"\r\n [attr.data-icon]=\"tab.icon\"\r\n [attr.data-icon-active]=\"tab.iconActive\"\r\n [attr.aria-label]=\"tab.label\"\r\n class=\"ds-tab-button ion-activatable\"\r\n [class.tab-selected]=\"isTabActive(tab.route)\"\r\n >\r\n <div class=\"tab-icon-ripple\"></div>\r\n <div class=\"tab-icon-wrapper\">\r\n <ds-icon [name]=\"tab.icon\" [size]=\"isDesktop() ? '20px' : '24px'\" class=\"tab-icon-inactive\" />\r\n <ds-icon [name]=\"tab.iconActive\" [size]=\"isDesktop() ? '20px' : '24px'\" class=\"tab-icon-active\" />\r\n </div>\r\n <ion-label [attr.aria-hidden]=\"true\">{{ tab.label }}</ion-label>\r\n </ion-tab-button>\r\n </div>\r\n\r\n <!-- Avatar (desktop only, positioned via CSS) -->\r\n <div class=\"ds-tab-bar__actions\">\r\n <ds-avatar [size]=\"'md'\" [type]=\"avatarType\" [initials]=\"avatarInitials\" [src]=\"avatarSrc\" [iconName]=\"avatarIconName\" (click)=\"handleAvatarClick()\" />\r\n </div>\r\n </ion-tab-bar>\r\n `,\r\n})\r\nexport class DsMobileTabBarComponent implements OnInit, AfterViewInit, OnDestroy {\r\n // Inputs\r\n @Input() tabs: TabConfig[] = [];\r\n\r\n // Avatar inputs\r\n @Input() avatarType: 'initials' | 'photo' | 'icon' = 'initials';\r\n @Input() avatarInitials: string = 'U';\r\n @Input() avatarSrc: string = '';\r\n @Input() avatarIconName: string = 'remixUser3Line';\r\n\r\n /**\r\n * Profile menu action groups to display when avatar is clicked.\r\n * If not provided, only the avatarClick event will be emitted.\r\n *\r\n * @example\r\n * ```typescript\r\n * profileMenuItems: ActionGroup[] = [\r\n * {\r\n * actions: [\r\n * { action: 'profile', title: 'My Profile', icon: 'remixUser3Line' },\r\n * { action: 'settings', title: 'Settings', icon: 'remixSettings3Line' }\r\n * ]\r\n * }\r\n * ];\r\n * ```\r\n */\r\n @Input() profileMenuItems?: ActionGroup[];\r\n\r\n // Outputs\r\n @Output() avatarClick = new EventEmitter<void>();\r\n\r\n /**\r\n * Emitted when a profile menu action is selected.\r\n * Parent component should handle the action logic (navigation, logout, etc.).\r\n */\r\n @Output() profileActionSelected = new EventEmitter<ActionResult>();\r\n\r\n // Internal state - exposed for template binding\r\n activeTab = signal<string>('');\r\n isDesktop = signal<boolean>(false);\r\n\r\n private mutationObserver?: MutationObserver;\r\n private slotEnforcementObserver?: MutationObserver;\r\n private resizeObserver?: ResizeObserver;\r\n private mediaQuery?: MediaQueryList;\r\n private routerSubscription?: any;\r\n\r\n private router?: Router | null;\r\n private modalController = inject(ModalController);\r\n private userService = inject(UserService);\r\n\r\n constructor(private elementRef: ElementRef) {\r\n // Inject Router optionally\r\n this.router = inject(Router, { optional: true }) || undefined;\r\n\r\n // Initialize breakpoint detection EARLY (before effect)\r\n // This ensures isDesktop() is set before the effect runs\r\n this.setupBreakpointDetection();\r\n\r\n // Debug: Log initial state\r\n setTimeout(() => {\r\n // console.log('[ds-mobile-tab-bar] Initial state:', {\r\n // isDesktop: this.isDesktop(),\r\n // windowWidth: window.innerWidth,\r\n // mediaQuery: this.mediaQuery?.matches,\r\n // userAgent: navigator.userAgent\r\n // });\r\n }, 100);\r\n\r\n // Watch for isDesktop changes and update slot reactively\r\n // effect() must be called in constructor (injection context)\r\n effect(() => {\r\n // This effect runs whenever isDesktop() changes\r\n const _ = this.isDesktop(); // Read the signal to create dependency\r\n // console.log('[ds-mobile-tab-bar] effect() triggered, isDesktop:', this.isDesktop());\r\n if (this.elementRef.nativeElement) {\r\n // Use setTimeout to ensure DOM is ready\r\n setTimeout(() => this.updateSlot(), 0);\r\n }\r\n });\r\n }\r\n\r\n ngOnInit(): void {\r\n // Listen to router events to detect active tab from URL\r\n if (this.router) {\r\n this.routerSubscription = this.router.events.pipe(filter((event) => event instanceof NavigationEnd)).subscribe((event: any) => {\r\n const url = event.urlAfterRedirects || event.url;\r\n // Extract the route segment (e.g., /tab-bar-test/home -> home)\r\n const segments = url.split('/').filter((s: string) => s);\r\n const lastSegment = segments[segments.length - 1];\r\n\r\n // Find matching tab by route\r\n if (this.tabs && lastSegment) {\r\n const matchingTab = this.tabs.find((tab) => tab.route === lastSegment);\r\n if (matchingTab) {\r\n this.activeTab.set(matchingTab.route);\r\n }\r\n }\r\n });\r\n }\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n // Initial removal\r\n this.removeTitleAttributes();\r\n\r\n // Set up mutation observer to continuously remove title attributes\r\n this.setupTitleRemovalObserver();\r\n\r\n // Set up active tab detection\r\n this.setupActiveTabDetection();\r\n\r\n // Ensure slot is set correctly on initial render (with retries)\r\n this.updateSlot();\r\n\r\n // Set up slot enforcement to prevent Ionic from overriding\r\n setTimeout(() => {\r\n this.setupSlotEnforcement();\r\n // Also retry updateSlot a few times to ensure it sticks\r\n setTimeout(() => this.updateSlot(), 100);\r\n setTimeout(() => this.updateSlot(), 300);\r\n }, 0);\r\n }\r\n\r\n private updateSlot(): void {\r\n // CRITICAL: Set slot on the HOST element (ds-mobile-tab-bar) first\r\n // Ionic positions children based on the wrapper's slot, not the inner element's slot\r\n const hostElement = this.elementRef.nativeElement;\r\n const hostSlotValue = this.isDesktop() ? 'top' : 'bottom';\r\n const currentHostSlot = hostElement.getAttribute('slot');\r\n\r\n if (currentHostSlot !== hostSlotValue) {\r\n // console.log('[ds-mobile-tab-bar] updateSlot: Setting HOST slot from', currentHostSlot, 'to', hostSlotValue);\r\n hostElement.setAttribute('slot', hostSlotValue);\r\n (hostElement as any).slot = hostSlotValue;\r\n }\r\n\r\n // Get the ion-tab-bar element\r\n const tabBar = this.elementRef.nativeElement.querySelector('ion-tab-bar');\r\n if (!tabBar) {\r\n // console.log('[ds-mobile-tab-bar] updateSlot: tabBar not found, retrying...');\r\n // Retry if element not found yet\r\n setTimeout(() => this.updateSlot(), 50);\r\n return;\r\n }\r\n\r\n const slotValue = this.isDesktop() ? 'top' : 'bottom';\r\n const currentSlot = tabBar.getAttribute('slot');\r\n const currentSlotProperty = (tabBar as any).slot;\r\n\r\n // Debug logging\r\n // console.log('[ds-mobile-tab-bar] updateSlot:', {\r\n // isDesktop: this.isDesktop(),\r\n // windowWidth: window.innerWidth,\r\n // slotValue,\r\n // currentSlotAttribute: currentSlot,\r\n // currentSlotProperty: currentSlotProperty,\r\n // tabBarElement: tabBar,\r\n // tabBarParent: tabBar.parentElement?.tagName,\r\n // tabBarInIonTabs: tabBar.closest('ion-tabs') !== null\r\n // });\r\n\r\n // Only update if different to avoid unnecessary DOM manipulation\r\n if (currentSlot !== slotValue || currentSlotProperty !== slotValue) {\r\n // console.log('[ds-mobile-tab-bar] updateSlot: Setting slot from', currentSlot, 'to', slotValue);\r\n\r\n // Set both attribute and property to ensure it works\r\n tabBar.setAttribute('slot', slotValue);\r\n (tabBar as any).slot = slotValue;\r\n\r\n // Also try setting it on the parent ion-tabs\r\n const parentIonTabs = tabBar.closest('ion-tabs');\r\n if (parentIonTabs) {\r\n // console.log('[ds-mobile-tab-bar] updateSlot: Found parent ion-tabs');\r\n // Force Ionic to recognize the slot change\r\n (parentIonTabs as any).forceUpdate?.();\r\n }\r\n\r\n // Force a reflow to ensure Ionic processes the change\r\n void tabBar.offsetHeight;\r\n\r\n // Verify it was set\r\n const verifySlot = tabBar.getAttribute('slot');\r\n const verifySlotProperty = (tabBar as any).slot;\r\n // console.log('[ds-mobile-tab-bar] updateSlot: After update, slot attribute:', verifySlot, 'slot property:', verifySlotProperty);\r\n\r\n // Check computed styles\r\n const computedStyle = window.getComputedStyle(tabBar);\r\n const parentComputedStyle = tabBar.parentElement ? window.getComputedStyle(tabBar.parentElement) : null;\r\n const ionTabsForStyles = tabBar.closest('ion-tabs');\r\n const ionTabsComputedStyle = ionTabsForStyles ? window.getComputedStyle(ionTabsForStyles) : null;\r\n\r\n // console.log('[ds-mobile-tab-bar] updateSlot: Computed styles:', {\r\n // tabBar: {\r\n // position: computedStyle.position,\r\n // top: computedStyle.top,\r\n // bottom: computedStyle.bottom,\r\n // order: computedStyle.order,\r\n // display: computedStyle.display,\r\n // zIndex: computedStyle.zIndex,\r\n // transform: computedStyle.transform\r\n // },\r\n // parent: parentComputedStyle ? {\r\n // display: parentComputedStyle.display,\r\n // flexDirection: parentComputedStyle.flexDirection,\r\n // gridTemplateRows: parentComputedStyle.gridTemplateRows\r\n // } : null,\r\n // ionTabs: ionTabsComputedStyle ? {\r\n // display: ionTabsComputedStyle.display,\r\n // flexDirection: ionTabsComputedStyle.flexDirection,\r\n // gridTemplateRows: ionTabsComputedStyle.gridTemplateRows,\r\n // position: ionTabsComputedStyle.position\r\n // } : null,\r\n // tabBarRect: tabBar.getBoundingClientRect(),\r\n // windowHeight: window.innerHeight\r\n // });\r\n } else {\r\n // console.log('[ds-mobile-tab-bar] updateSlot: Slot already correct, no update needed');\r\n\r\n // Even if slot is correct, check computed styles to see why it's not at top\r\n const computedStyle = window.getComputedStyle(tabBar);\r\n const ionTabsForStyles = tabBar.closest('ion-tabs');\r\n const ionTabsComputedStyle = ionTabsForStyles ? window.getComputedStyle(ionTabsForStyles) : null;\r\n const tabBarRect = tabBar.getBoundingClientRect();\r\n\r\n // Log key values directly so they're always visible\r\n // console.log('[ds-mobile-tab-bar] KEY VALUES:');\r\n // console.log(' tabBar.position:', computedStyle.position);\r\n // console.log(' tabBar.top:', computedStyle.top);\r\n // console.log(' tabBar.bottom:', computedStyle.bottom);\r\n // console.log(' tabBar.order:', computedStyle.order);\r\n // console.log(' tabBar.display:', computedStyle.display);\r\n // console.log(' tabBarRect.top:', tabBarRect.top, 'px from top');\r\n // console.log(' tabBarRect.bottom:', tabBarRect.bottom, 'px from top');\r\n // console.log(' window.innerHeight:', window.innerHeight);\r\n if (ionTabsComputedStyle) {\r\n // console.log(' ionTabs.display:', ionTabsComputedStyle.display);\r\n // console.log(' ionTabs.flexDirection:', ionTabsComputedStyle.flexDirection);\r\n // console.log(' ionTabs.gridTemplateRows:', ionTabsComputedStyle.gridTemplateRows);\r\n }\r\n if (ionTabsForStyles) {\r\n const children = Array.from(ionTabsForStyles.children);\r\n // console.log(' ionTabs children count:', children.length);\r\n children.forEach((child: any, index) => {\r\n // console.log(` [${index}] ${child.tagName} slot=\"${child.getAttribute('slot')}\" order=\"${window.getComputedStyle(child).order}\"`);\r\n });\r\n }\r\n\r\n // console.log('[ds-mobile-tab-bar] updateSlot: Computed styles (slot correct but visually wrong):', {\r\n // tabBar: {\r\n // position: computedStyle.position,\r\n // top: computedStyle.top,\r\n // bottom: computedStyle.bottom,\r\n // order: computedStyle.order,\r\n // display: computedStyle.display,\r\n // zIndex: computedStyle.zIndex,\r\n // transform: computedStyle.transform,\r\n // marginTop: computedStyle.marginTop,\r\n // marginBottom: computedStyle.marginBottom,\r\n // width: computedStyle.width,\r\n // height: computedStyle.height\r\n // },\r\n // ionTabs: ionTabsComputedStyle ? {\r\n // display: ionTabsComputedStyle.display,\r\n // flexDirection: ionTabsComputedStyle.flexDirection,\r\n // gridTemplateRows: ionTabsComputedStyle.gridTemplateRows,\r\n // gridTemplateColumns: ionTabsComputedStyle.gridTemplateColumns,\r\n // position: ionTabsComputedStyle.position,\r\n // alignItems: ionTabsComputedStyle.alignItems,\r\n // justifyContent: ionTabsComputedStyle.justifyContent,\r\n // height: ionTabsComputedStyle.height,\r\n // minHeight: ionTabsComputedStyle.minHeight\r\n // } : null,\r\n // tabBarRect: {\r\n // top: tabBarRect.top,\r\n // bottom: tabBarRect.bottom,\r\n // height: tabBarRect.height,\r\n // y: tabBarRect.y,\r\n // left: tabBarRect.left,\r\n // right: tabBarRect.right,\r\n // width: tabBarRect.width\r\n // },\r\n // windowHeight: window.innerHeight,\r\n // distanceFromTop: tabBarRect.top,\r\n // distanceFromBottom: window.innerHeight - tabBarRect.bottom,\r\n // // Check if tab bar is actually in the DOM at the right position\r\n // tabBarParent: tabBar.parentElement?.tagName,\r\n // tabBarNextSibling: tabBar.nextElementSibling?.tagName,\r\n // tabBarPreviousSibling: tabBar.previousElementSibling?.tagName,\r\n // // Check all children of ion-tabs to see DOM order\r\n // ionTabsChildren: ionTabsForStyles ? Array.from(ionTabsForStyles.children).map((child: any) => ({\r\n // tagName: child.tagName,\r\n // slot: child.getAttribute('slot'),\r\n // order: window.getComputedStyle(child).order\r\n // })) : null\r\n // });\r\n }\r\n }\r\n\r\n private setupSlotEnforcement(): void {\r\n const hostElement = this.elementRef.nativeElement;\r\n const tabBar = this.elementRef.nativeElement.querySelector('ion-tab-bar');\r\n if (!tabBar) {\r\n // console.log('[ds-mobile-tab-bar] setupSlotEnforcement: tabBar not found, retrying...');\r\n // Retry if element not found yet\r\n setTimeout(() => this.setupSlotEnforcement(), 50);\r\n return;\r\n }\r\n\r\n // console.log('[ds-mobile-tab-bar] setupSlotEnforcement: Setting up MutationObserver');\r\n\r\n const observer = new MutationObserver((mutations) => {\r\n mutations.forEach((mutation) => {\r\n if (mutation.type === 'attributes' && mutation.attributeName === 'slot') {\r\n const target = mutation.target as HTMLElement;\r\n const expectedSlot = this.isDesktop() ? 'top' : 'bottom';\r\n\r\n // Check both host element and tab bar\r\n if (target === hostElement || target === tabBar) {\r\n const currentSlot = target.getAttribute('slot');\r\n\r\n // console.log('[ds-mobile-tab-bar] Slot changed by external source:', {\r\n // target: target.tagName,\r\n // currentSlot,\r\n // expectedSlot,\r\n // isDesktop: this.isDesktop()\r\n // });\r\n\r\n // If Ionic or something else changed it, force it back\r\n if (currentSlot !== expectedSlot) {\r\n // console.log('[ds-mobile-tab-bar] Enforcing slot back to:', expectedSlot);\r\n // Use requestAnimationFrame to avoid infinite loops\r\n requestAnimationFrame(() => {\r\n target.setAttribute('slot', expectedSlot);\r\n (target as any).slot = expectedSlot;\r\n });\r\n }\r\n }\r\n }\r\n });\r\n });\r\n\r\n // Observe both host element and tab bar for slot changes\r\n observer.observe(hostElement, {\r\n attributes: true,\r\n attributeFilter: ['slot'],\r\n });\r\n\r\n observer.observe(tabBar, {\r\n attributes: true,\r\n attributeFilter: ['slot'],\r\n });\r\n\r\n // Store observer for cleanup\r\n this.slotEnforcementObserver = observer;\r\n }\r\n\r\n ngOnDestroy(): void {\r\n if (this.mutationObserver) {\r\n this.mutationObserver.disconnect();\r\n }\r\n if (this.slotEnforcementObserver) {\r\n this.slotEnforcementObserver.disconnect();\r\n }\r\n if (this.mediaQuery) {\r\n this.mediaQuery.removeEventListener('change', this.handleBreakpointChange);\r\n }\r\n if (this.routerSubscription) {\r\n this.routerSubscription.unsubscribe();\r\n }\r\n }\r\n\r\n private setupBreakpointDetection(): void {\r\n // Use matchMedia for responsive breakpoint detection\r\n this.mediaQuery = window.matchMedia('(min-width: 768px)');\r\n this.isDesktop.set(this.mediaQuery.matches);\r\n\r\n this.handleBreakpointChange = this.handleBreakpointChange.bind(this);\r\n this.mediaQuery.addEventListener('change', this.handleBreakpointChange);\r\n }\r\n\r\n private handleBreakpointChange = (e: MediaQueryListEvent): void => {\r\n // console.log('[ds-mobile-tab-bar] handleBreakpointChange:', {\r\n // matches: e.matches,\r\n // windowWidth: window.innerWidth,\r\n // previousIsDesktop: this.isDesktop()\r\n // });\r\n this.isDesktop.set(e.matches);\r\n // Force update the slot when breakpoint changes\r\n this.updateSlot();\r\n };\r\n\r\n private setupTitleRemovalObserver(): void {\r\n const config = {\r\n attributes: true,\r\n attributeFilter: ['title'],\r\n subtree: true,\r\n childList: true,\r\n };\r\n\r\n this.mutationObserver = new MutationObserver((mutations) => {\r\n mutations.forEach((mutation) => {\r\n if (mutation.type === 'attributes' && mutation.attributeName === 'title') {\r\n const target = mutation.target as HTMLElement;\r\n if (target.tagName === 'ION-TAB-BUTTON' && target.hasAttribute('title')) {\r\n target.removeAttribute('title');\r\n }\r\n }\r\n });\r\n // Also do a sweep after any changes\r\n this.removeTitleAttributes();\r\n });\r\n\r\n this.mutationObserver.observe(this.elementRef.nativeElement, config);\r\n }\r\n\r\n private removeTitleAttributes(): void {\r\n const tabButtons = this.elementRef.nativeElement.querySelectorAll('ion-tab-button');\r\n tabButtons.forEach((button: HTMLElement) => {\r\n if (button.hasAttribute('title')) {\r\n button.removeAttribute('title');\r\n }\r\n // Also remove from the native button inside shadow DOM\r\n const nativeButton = button.shadowRoot?.querySelector('button');\r\n if (nativeButton?.hasAttribute('title')) {\r\n nativeButton.removeAttribute('title');\r\n }\r\n });\r\n }\r\n\r\n private setupActiveTabDetection(): void {\r\n // Find the parent ion-tabs element\r\n const ionTabs = this.elementRef.nativeElement.closest('ion-tabs');\r\n if (!ionTabs) {\r\n console.warn('ds-mobile-tab-bar: Could not find parent ion-tabs element');\r\n return;\r\n }\r\n\r\n // Listen for tab changes using Ionic events\r\n ionTabs.addEventListener('ionTabsDidChange', (event: any) => {\r\n const tabRoute = event.detail?.tab;\r\n if (tabRoute) {\r\n this.activeTab.set(tabRoute);\r\n } else {\r\n // Fallback: check DOM immediately after event\r\n setTimeout(() => this.updateActiveTabFromDOM(), 0);\r\n }\r\n });\r\n\r\n // Also listen for tab button clicks\r\n this.elementRef.nativeElement.addEventListener('click', (event: any) => {\r\n const button = event.target.closest('ion-tab-button');\r\n if (button) {\r\n setTimeout(() => this.updateActiveTabFromDOM(), 50);\r\n }\r\n });\r\n\r\n // Get initial selected tab\r\n this.updateActiveTabFromDOM();\r\n\r\n // Watch for selected attribute changes on tab buttons (more reliable)\r\n const observer = new MutationObserver(() => {\r\n this.updateActiveTabFromDOM();\r\n });\r\n\r\n observer.observe(this.elementRef.nativeElement, {\r\n attributes: true,\r\n attributeFilter: ['selected', 'tab'],\r\n subtree: true,\r\n childList: true,\r\n });\r\n\r\n // Also watch the parent ion-tabs for changes\r\n observer.observe(ionTabs, {\r\n attributes: true,\r\n attributeFilter: ['selected', 'tab'],\r\n subtree: true,\r\n });\r\n\r\n // Periodic check as fallback (in case events don't fire)\r\n setInterval(() => {\r\n this.updateActiveTabFromDOM();\r\n }, 100);\r\n }\r\n\r\n private updateActiveTabFromDOM(): void {\r\n // Check parent ion-tabs for selected tab (most reliable)\r\n const ionTabs = this.elementRef.nativeElement.closest('ion-tabs');\r\n if (ionTabs) {\r\n // Method 1: Check for ion-tab with selected attribute\r\n const selectedTab = ionTabs.querySelector('ion-tab[selected]');\r\n if (selectedTab) {\r\n const tabRoute = selectedTab.getAttribute('tab');\r\n if (tabRoute) {\r\n this.activeTab.set(tabRoute);\r\n return;\r\n }\r\n }\r\n\r\n // Method 2: Check for ion-tab without tab-hidden class (Ionic shows active tab)\r\n const visibleTab = ionTabs.querySelector('ion-tab:not(.tab-hidden)');\r\n if (visibleTab) {\r\n const tabRoute = visibleTab.getAttribute('tab');\r\n if (tabRoute) {\r\n this.activeTab.set(tabRoute);\r\n return;\r\n }\r\n }\r\n }\r\n\r\n // Method 3: Check tab buttons for selected state\r\n const tabButtons = this.elementRef.nativeElement.querySelectorAll('ion-tab-button');\r\n tabButtons.forEach((button: any) => {\r\n // Check Ionic's native selected property\r\n if (button.selected === true) {\r\n const tabRoute = button.getAttribute('tab');\r\n if (tabRoute) {\r\n this.activeTab.set(tabRoute);\r\n }\r\n }\r\n });\r\n }\r\n\r\n trackByTabId(index: number, tab: TabConfig): string {\r\n return tab.id;\r\n }\r\n\r\n isTabActive(tabRoute: string): boolean {\r\n const currentActive = this.activeTab();\r\n // Match by route (primary) or by checking if the tab button is selected\r\n if (currentActive === tabRoute) {\r\n return true;\r\n }\r\n\r\n // Fallback: check if this button is actually selected in the DOM\r\n const tabButtons = this.elementRef.nativeElement.querySelectorAll('ion-tab-button');\r\n for (let i = 0; i < tabButtons.length; i++) {\r\n const button = tabButtons[i] as any;\r\n if (button.getAttribute('tab') === tabRoute && button.selected === true) {\r\n return true;\r\n }\r\n }\r\n\r\n return false;\r\n }\r\n\r\n /**\r\n * Handle avatar click - opens profile menu if configured, otherwise just emits avatarClick\r\n */\r\n async handleAvatarClick(): Promise<void> {\r\n // Emit the basic click event (for backwards compatibility)\r\n this.avatarClick.emit();\r\n\r\n // Use input if provided, otherwise fall back to service\r\n const menuItems = this.profileMenuItems || this.userService.profileMenuItems();\r\n\r\n // If no menu items configured, just emit and return\r\n if (!menuItems || menuItems.length === 0) {\r\n return;\r\n }\r\n\r\n // Open the bottom sheet with configured menu items\r\n const sheet = await this.modalController.create({\r\n component: DsMobileProfileActionsSheetComponent,\r\n componentProps: {\r\n actionGroups: menuItems,\r\n currentLanguage: 'da', // TODO: Get from language service\r\n availableLanguages: [\r\n {\r\n code: 'da',\r\n nativeName: 'Dansk',\r\n englishName: 'Danish',\r\n flagIcon: '/Assets/country-flags/denmark.svg',\r\n },\r\n {\r\n code: 'en',\r\n nativeName: 'English',\r\n englishName: 'English',\r\n flagIcon: '/Assets/country-flags/united kingdom.svg',\r\n },\r\n {\r\n code: 'sv',\r\n nativeName: 'Svenska',\r\n englishName: 'Swedish',\r\n flagIcon: '/Assets/country-flags/sweden.svg',\r\n },\r\n {\r\n code: 'no',\r\n nativeName: 'Norsk',\r\n englishName: 'Norwegian',\r\n flagIcon: '/Assets/country-flags/norway.svg',\r\n },\r\n {\r\n code: 'de',\r\n nativeName: 'Deutsch',\r\n englishName: 'German',\r\n flagIcon: '/Assets/country-flags/germany.svg',\r\n },\r\n ],\r\n },\r\n breakpoints: [0, 1],\r\n initialBreakpoint: 1,\r\n handle: true,\r\n cssClass: ['ds-bottom-sheet', 'auto-height'],\r\n });\r\n\r\n await sheet.present();\r\n disableModalShadowPointerEvents(sheet);\r\n\r\n const result = await sheet.onWillDismiss<ActionResult>();\r\n if (result.data?.action) {\r\n // Emit the selected action to parent\r\n this.profileActionSelected.emit(result.data);\r\n // Also notify globally via UserService\r\n this.userService.notifyProfileAction(result.data);\r\n }\r\n }\r\n}\r\n","import { Component, Input, Output, EventEmitter, OnInit } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { \r\n IonTabs, \r\n IonTab\r\n} from '@ionic/angular/standalone';\r\nimport { DsMobileTabBarComponent, TabConfig } from '../tab-bar';\r\n\r\n// Re-export TabConfig for backwards compatibility\r\nexport type { TabConfig } from '../tab-bar';\r\n\r\n/**\r\n * DsMobileTabsComponent\r\n * \r\n * Responsive tab navigation that adapts from mobile to desktop:\r\n * - Mobile (< 768px): Bottom tab bar with icons + labels\r\n * - Desktop (≥ 768px): Top navigation bar with logo, tabs, and avatar\r\n * \r\n * Wraps ion-tabs to maintain native routing functionality while\r\n * providing a responsive navigation experience with branding.\r\n * \r\n * NOTE: This component wraps `ion-tabs` internally. If your Angular\r\n * routing requires `ion-tabs` to be a direct child in your component\r\n * (e.g., when using `ion-router-outlet` in app.html), use the\r\n * `DsMobileTabBarComponent` directly inside your own `ion-tabs` instead.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-tabs\r\n * [tabs]=\"tabsConfig\"\r\n * [avatarInitials]=\"'JD'\"\r\n * (avatarClick)=\"handleAvatarClick()\"\r\n * />\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-tabs',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonTabs,\r\n IonTab,\r\n DsMobileTabBarComponent\r\n ],\r\n styleUrls: ['./ds-mobile-tabs.css'],\r\n template: `\r\n <ion-tabs>\r\n <ng-container *ngIf=\"tabs && tabs.length > 0\">\r\n <ion-tab *ngFor=\"let tab of tabs; trackBy: trackByTabId\" [tab]=\"tab.id\"></ion-tab>\r\n </ng-container>\r\n \r\n <ds-mobile-tab-bar\r\n [tabs]=\"tabs\"\r\n [avatarType]=\"avatarType\"\r\n [avatarInitials]=\"avatarInitials\"\r\n [avatarSrc]=\"avatarSrc\"\r\n [avatarIconName]=\"avatarIconName\"\r\n (avatarClick)=\"handleAvatarClick()\"\r\n />\r\n </ion-tabs>\r\n `\r\n})\r\nexport class DsMobileTabsComponent implements OnInit {\r\n // Inputs\r\n @Input() tabs: TabConfig[] = [];\r\n \r\n // Avatar inputs\r\n @Input() avatarType: 'initials' | 'photo' | 'icon' = 'initials';\r\n @Input() avatarInitials: string = 'U';\r\n @Input() avatarSrc: string = '';\r\n @Input() avatarIconName: string = 'remixUser3Line';\r\n \r\n // Outputs\r\n @Output() avatarClick = new EventEmitter<void>();\r\n \r\n constructor() {}\r\n \r\n ngOnInit(): void {\r\n console.log('DsMobileTabsComponent initialized');\r\n }\r\n \r\n trackByTabId(index: number, tab: TabConfig): string {\r\n return tab.id;\r\n }\r\n \r\n handleAvatarClick(): void {\r\n this.avatarClick.emit();\r\n }\r\n}\r\n","import {\r\n Component,\r\n input,\r\n AfterViewInit,\r\n OnDestroy,\r\n ElementRef,\r\n ViewChild,\r\n CUSTOM_ELEMENTS_SCHEMA\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport Swiper from 'swiper';\r\nimport { Pagination } from 'swiper/modules';\r\n\r\n/**\r\n * DsMobileSwiperComponent\r\n * \r\n * A reusable swiper/carousel component with configurable child width and spacing.\r\n * \r\n * Features:\r\n * - First slide is left-aligned\r\n * - Middle slides are centered when active\r\n * - Last slide is right-aligned\r\n * - Configurable slide width and gap\r\n * - Content projection via ng-content\r\n * \r\n * Usage:\r\n * ```html\r\n * <ds-mobile-swiper [slideWidth]=\"'75vw'\" [gap]=\"16\">\r\n * <div class=\"swiper-slide\">Slide 1</div>\r\n * <div class=\"swiper-slide\">Slide 2</div>\r\n * <div class=\"swiper-slide\">Slide 3</div>\r\n * </ds-mobile-swiper>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-swiper',\r\n standalone: true,\r\n imports: [CommonModule],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n template: `\r\n <div class=\"swiper-container\" #swiperContainer>\r\n <div class=\"swiper-wrapper\">\r\n <ng-content></ng-content>\r\n </div>\r\n @if (pagination()) {\r\n <div class=\"swiper-pagination\"></div>\r\n }\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n display: block;\r\n width: 100%;\r\n }\r\n\r\n .swiper-container {\r\n width: 100%;\r\n position: relative;\r\n overflow: visible;\r\n }\r\n\r\n .swiper-wrapper {\r\n display: flex;\r\n box-sizing: content-box;\r\n }\r\n\r\n :host ::ng-deep .swiper-slide {\r\n flex-shrink: 0;\r\n height: auto;\r\n position: relative;\r\n display: flex;\r\n align-items: flex-start;\r\n justify-content: center;\r\n transition: opacity 300ms ease, transform 300ms ease;\r\n }\r\n\r\n /* Hide all slides by default when progressive opacity is enabled */\r\n :host(.progressive-opacity) ::ng-deep .swiper-slide {\r\n opacity: 0;\r\n }\r\n\r\n /* Show first slide immediately */\r\n :host(.progressive-opacity) ::ng-deep .swiper-slide:first-child {\r\n opacity: 1;\r\n }\r\n\r\n /* Pagination styles */\r\n .swiper-pagination {\r\n position: relative;\r\n text-align: center;\r\n display: flex;\r\n justify-content: center;\r\n margin-top: 20px;\r\n margin-bottom: -16px;\r\n }\r\n\r\n :host ::ng-deep .swiper-pagination-bullet {\r\n width: 6px;\r\n height: 6px;\r\n border-radius: 50%;\r\n background: var(--color-accent);\r\n opacity: 0.25;\r\n transition: all 0.3s ease;\r\n cursor: pointer;\r\n }\r\n\r\n :host ::ng-deep .swiper-pagination-bullet-active {\r\n opacity: 1;\r\n background: var(--color-accent);\r\n width: 20px;\r\n border-radius: 3px;\r\n }\r\n `]\r\n})\r\nexport class DsMobileSwiperComponent implements AfterViewInit, OnDestroy {\r\n /**\r\n * Width of each slide (e.g., '75vw', '300px', '80%')\r\n */\r\n slideWidth = input<string>('75vw');\r\n\r\n /**\r\n * Gap between slides in pixels\r\n */\r\n gap = input<number>(16);\r\n\r\n /**\r\n * Enable pagination dots\r\n */\r\n pagination = input<boolean>(false);\r\n\r\n /**\r\n * Enable auto height - container adapts to active slide's height\r\n */\r\n autoHeight = input<boolean>(false);\r\n\r\n /**\r\n * Enable progressive opacity based on slide position\r\n * Slides fade in/out smoothly as they move toward/away from center\r\n */\r\n progressiveOpacity = input<boolean>(false);\r\n\r\n /**\r\n * Enable progressive scale based on slide position\r\n * Slides scale down smoothly as they move away from center\r\n */\r\n progressiveScale = input<boolean>(false);\r\n\r\n @ViewChild('swiperContainer', { static: false }) swiperContainer!: ElementRef;\r\n\r\n private swiperInstance: Swiper | null = null;\r\n\r\n constructor(private elementRef: ElementRef) {}\r\n\r\n ngAfterViewInit(): void {\r\n // Add progressive-opacity class to host if enabled\r\n if (this.progressiveOpacity()) {\r\n this.elementRef.nativeElement.classList.add('progressive-opacity');\r\n }\r\n \r\n setTimeout(() => {\r\n this.initializeSwiper();\r\n }, 100);\r\n }\r\n\r\n private initializeSwiper(): void {\r\n if (!this.swiperContainer) return;\r\n\r\n // Apply slide width to all slides\r\n const slides = this.swiperContainer.nativeElement.querySelectorAll('.swiper-slide');\r\n slides.forEach((slide: HTMLElement, index: number) => {\r\n slide.style.width = this.slideWidth();\r\n \r\n // Set initial opacity BEFORE Swiper initializes to prevent flash of inactive slides\r\n if (this.progressiveOpacity()) {\r\n // Hide all slides except the first one (active slide)\r\n slide.style.opacity = index === 0 ? '1' : '0';\r\n }\r\n });\r\n\r\n const config: any = {\r\n slidesPerView: 'auto',\r\n spaceBetween: this.gap(),\r\n centeredSlides: true,\r\n centeredSlidesBounds: true,\r\n speed: 300,\r\n resistance: true,\r\n resistanceRatio: 0.85,\r\n autoHeight: this.autoHeight(),\r\n watchSlidesProgress: this.progressiveOpacity() || this.progressiveScale(), // Enable progress tracking\r\n };\r\n\r\n // Configure event handlers\r\n config.on = {};\r\n\r\n // Configure autoHeight animation\r\n if (this.autoHeight()) {\r\n config.autoHeight = true;\r\n // The height transition will use the speed value (300ms)\r\n config.on.slideChangeTransitionStart = () => {\r\n // Height transition happens automatically\r\n };\r\n }\r\n\r\n // Configure progressive effects (opacity and/or scale)\r\n if (this.progressiveOpacity() || this.progressiveScale()) {\r\n config.on.setTranslate = () => {\r\n if (!this.swiperInstance) return;\r\n \r\n this.swiperInstance.slides.forEach((slideEl: any) => {\r\n const progress = slideEl.progress || 0;\r\n const absProgress = Math.abs(progress);\r\n \r\n // Progressive opacity with sharper cutoff\r\n if (this.progressiveOpacity()) {\r\n // Make opacity drop off more aggressively\r\n // Slides with absProgress > 0.5 will be completely hidden\r\n let opacity;\r\n if (absProgress > 0.5) {\r\n opacity = 0;\r\n } else {\r\n opacity = 1 - (absProgress * 2); // 2x multiplier for faster fade\r\n }\r\n slideEl.style.opacity = Math.max(opacity, 0).toString();\r\n }\r\n \r\n // Progressive scale\r\n if (this.progressiveScale()) {\r\n // Scale from 1 (center) to 0.9 (edges)\r\n const minScale = 0.9;\r\n const scale = 1 - (absProgress * (1 - minScale));\r\n slideEl.style.transform = `scale(${Math.max(scale, minScale)})`;\r\n }\r\n });\r\n };\r\n \r\n // Also update on init\r\n config.on.init = () => {\r\n if (!this.swiperInstance) return;\r\n \r\n this.swiperInstance.slides.forEach((slideEl: any) => {\r\n const progress = slideEl.progress || 0;\r\n const absProgress = Math.abs(progress);\r\n \r\n // Set initial opacity with sharper cutoff\r\n if (this.progressiveOpacity()) {\r\n let opacity;\r\n if (absProgress > 0.5) {\r\n opacity = 0;\r\n } else {\r\n opacity = 1 - (absProgress * 2);\r\n }\r\n slideEl.style.opacity = Math.max(opacity, 0).toString();\r\n }\r\n \r\n // Set initial scale\r\n if (this.progressiveScale()) {\r\n const minScale = 0.9;\r\n const scale = 1 - (absProgress * (1 - minScale));\r\n slideEl.style.transform = `scale(${Math.max(scale, minScale)})`;\r\n }\r\n });\r\n };\r\n }\r\n\r\n // Add pagination if enabled\r\n if (this.pagination()) {\r\n config.modules = [Pagination];\r\n config.pagination = {\r\n el: '.swiper-pagination',\r\n clickable: true,\r\n dynamicBullets: false,\r\n };\r\n }\r\n\r\n this.swiperInstance = new Swiper(this.swiperContainer.nativeElement, config);\r\n }\r\n \r\n /**\r\n * Navigate to previous slide\r\n */\r\n slidePrev(): void {\r\n this.swiperInstance?.slidePrev();\r\n }\r\n \r\n /**\r\n * Navigate to next slide\r\n */\r\n slideNext(): void {\r\n this.swiperInstance?.slideNext();\r\n }\r\n\r\n /**\r\n * Navigate to a specific slide by index\r\n */\r\n slideTo(index: number, speed = 300): void {\r\n this.swiperInstance?.slideTo(index, speed);\r\n }\r\n \r\n /**\r\n * Check if at the beginning\r\n */\r\n isBeginning(): boolean {\r\n return this.swiperInstance?.isBeginning ?? true;\r\n }\r\n \r\n /**\r\n * Check if at the end\r\n */\r\n isEnd(): boolean {\r\n return this.swiperInstance?.isEnd ?? true;\r\n }\r\n\r\n /**\r\n * Get the total number of slides\r\n */\r\n getSlideCount(): number {\r\n return this.swiperInstance?.slides?.length ?? 0;\r\n }\r\n\r\n ngOnDestroy(): void {\r\n if (this.swiperInstance) {\r\n this.swiperInstance.destroy();\r\n this.swiperInstance = null;\r\n }\r\n }\r\n}\r\n\r\n","import { Component, ContentChild, AfterContentInit, ChangeDetectorRef } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { DsMobileSwiperComponent } from './ds-mobile-swiper';\r\n\r\n/**\r\n * DsMobileSwiperWithNavComponent\r\n * \r\n * Wrapper component that adds navigation buttons to a ds-mobile-swiper.\r\n * Automatically handles button states (disabled at start/end) and mobile visibility.\r\n * \r\n * Features:\r\n * - Automatic prev/next navigation buttons\r\n * - Auto-hide buttons when there's only one slide\r\n * - Auto-disable buttons at start/end of swiper\r\n * - Hidden on mobile devices (< 768px)\r\n * - No pointer-events blocking using display: contents\r\n * - Self-contained navigation logic\r\n * \r\n * Usage:\r\n * ```html\r\n * <ds-mobile-swiper-with-nav>\r\n * <ds-mobile-swiper [slideWidth]=\"'100%'\" [gap]=\"32\">\r\n * <div class=\"swiper-slide\">Slide 1</div>\r\n * <div class=\"swiper-slide\">Slide 2</div>\r\n * </ds-mobile-swiper>\r\n * </ds-mobile-swiper-with-nav>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-swiper-with-nav',\r\n standalone: true,\r\n imports: [CommonModule, DsIconButtonComponent],\r\n styles: [`\r\n :host {\r\n display: block;\r\n }\r\n\r\n .swiper-nav-wrapper {\r\n position: relative;\r\n }\r\n\r\n /* Use display: contents to avoid blocking pointer events */\r\n .swiper-nav-buttons {\r\n display: contents;\r\n }\r\n\r\n .swiper-nav-button {\r\n position: absolute;\r\n top: 50%;\r\n transform: translateY(-50%);\r\n z-index: 10;\r\n }\r\n\r\n .swiper-nav-button:first-child {\r\n left: -48px;\r\n }\r\n\r\n .swiper-nav-button:last-child {\r\n right: -48px;\r\n }\r\n\r\n /* Force buttons to be perfectly round */\r\n ::ng-deep .swiper-nav-button button {\r\n border-radius: 50% !important;\r\n width: 48px !important;\r\n height: 48px !important;\r\n padding: 0 !important;\r\n }\r\n\r\n /* Hide on mobile */\r\n @media (max-width: 767px) {\r\n .swiper-nav-button {\r\n display: none;\r\n }\r\n }\r\n `],\r\n template: `\r\n <div class=\"swiper-nav-wrapper\">\r\n <ng-content></ng-content>\r\n \r\n @if (shouldShowNavButtons()) {\r\n <div class=\"swiper-nav-buttons\">\r\n <ds-icon-button\r\n class=\"swiper-nav-button\"\r\n icon=\"remixArrowLeftSLine\"\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n [disabled]=\"isFirstSlide()\"\r\n (clicked)=\"slidePrev()\"\r\n aria-label=\"Previous\"\r\n />\r\n <ds-icon-button\r\n class=\"swiper-nav-button\"\r\n icon=\"remixArrowRightSLine\"\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n [disabled]=\"isLastSlide()\"\r\n (clicked)=\"slideNext()\"\r\n aria-label=\"Next\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n `\r\n})\r\nexport class DsMobileSwiperWithNavComponent implements AfterContentInit {\r\n @ContentChild(DsMobileSwiperComponent) swiper?: DsMobileSwiperComponent;\r\n\r\n constructor(private cdr: ChangeDetectorRef) {}\r\n\r\n ngAfterContentInit(): void {\r\n // Trigger change detection when swiper is initialized\r\n // This ensures button states are correct on initial render\r\n if (this.swiper) {\r\n setTimeout(() => {\r\n this.cdr.detectChanges();\r\n }, 200);\r\n }\r\n }\r\n\r\n /**\r\n * Navigate to previous slide\r\n */\r\n slidePrev(): void {\r\n this.swiper?.slidePrev();\r\n this.cdr.detectChanges();\r\n }\r\n\r\n /**\r\n * Navigate to next slide\r\n */\r\n slideNext(): void {\r\n this.swiper?.slideNext();\r\n this.cdr.detectChanges();\r\n }\r\n\r\n /**\r\n * Check if at first slide\r\n */\r\n isFirstSlide(): boolean {\r\n return this.swiper?.isBeginning() ?? true;\r\n }\r\n\r\n /**\r\n * Check if at last slide\r\n */\r\n isLastSlide(): boolean {\r\n return this.swiper?.isEnd() ?? true;\r\n }\r\n\r\n /**\r\n * Check if navigation buttons should be shown\r\n * Hide buttons if there's only one slide\r\n */\r\n shouldShowNavButtons(): boolean {\r\n const slideCount = this.swiper?.getSlideCount() ?? 0;\r\n return slideCount > 1;\r\n }\r\n}\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport type { LightboxAuthor } from './ds-mobile-lightbox.service';\r\n\r\n/**\r\n * DsMobileLightboxHeaderComponent\r\n * \r\n * Shared header component for all lightbox types (image, PDF, etc.)\r\n * Displays author information and close button with consistent styling.\r\n */\r\n@Component({\r\n selector: 'ds-mobile-lightbox-header',\r\n standalone: true,\r\n imports: [CommonModule, DsIconButtonComponent, DsAvatarComponent],\r\n styleUrls: ['../shared/mobile-common.css'],\r\n template: `\r\n <div class=\"lightbox-header lightbox-context\">\r\n <div class=\"header-content\">\r\n <!-- Post author info -->\r\n @if (author()) {\r\n <div class=\"post-author-info\">\r\n <ds-avatar\r\n [initials]=\"author()!.avatarInitials ?? ''\"\r\n [type]=\"author()!.avatarType ?? 'initials'\"\r\n [src]=\"author()!.avatarSrc ?? ''\"\r\n size=\"md\"\r\n />\r\n <div class=\"author-details\">\r\n <div class=\"author-name\">{{ author()!.name }}</div>\r\n <div class=\"author-meta\">\r\n @if (author()!.role) {\r\n <span>{{ author()!.role }}</span>\r\n }\r\n @if (author()!.role && author()!.timestamp) {\r\n <span class=\"separator\">·</span>\r\n }\r\n @if (author()!.timestamp) {\r\n <span>{{ author()!.timestamp }}</span>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n }\r\n \r\n <!-- Action buttons - always visible -->\r\n <div class=\"header-actions\">\r\n <ds-icon-button\r\n icon=\"remixShare2Line\"\r\n variant=\"ghost\"\r\n size=\"md\"\r\n (clicked)=\"shareClick.emit()\"\r\n class=\"share-button\"\r\n [ariaLabel]=\"'Share'\">\r\n </ds-icon-button>\r\n \r\n <ds-icon-button\r\n icon=\"remixCloseLine\"\r\n variant=\"ghost\"\r\n size=\"md\"\r\n (clicked)=\"closeClick.emit()\"\r\n class=\"close-button\"\r\n [ariaLabel]=\"'Close'\">\r\n </ds-icon-button>\r\n </div>\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n .lightbox-header {\r\n position: fixed;\r\n top: 0;\r\n left: 0;\r\n right: 0;\r\n z-index: 1000;\r\n padding: 0 16px;\r\n background: linear-gradient(to bottom, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.4) 80%, transparent 100%);\r\n pointer-events: none;\r\n }\r\n\r\n .header-content {\r\n display: flex;\r\n align-items: center;\r\n justify-content: flex-end;\r\n gap: 12px;\r\n pointer-events: auto;\r\n }\r\n\r\n .post-author-info {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n flex: 1;\r\n min-width: 0;\r\n margin-right: auto;\r\n }\r\n\r\n .author-details {\r\n display: flex;\r\n flex-direction: column;\r\n min-width: 0;\r\n flex: 1;\r\n }\r\n\r\n .author-name {\r\n color: white;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n }\r\n\r\n .author-meta {\r\n color: rgba(255, 255, 255, 0.7);\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n }\r\n\r\n .author-meta .separator {\r\n color: rgba(255, 255, 255, 0.5);\r\n }\r\n\r\n .header-actions {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n flex-shrink: 0;\r\n }\r\n\r\n .close-button,\r\n .share-button {\r\n pointer-events: auto;\r\n flex-shrink: 0;\r\n border-radius: 50%;\r\n }\r\n\r\n .close-button::ng-deep button,\r\n .share-button::ng-deep button {\r\n color: white !important;\r\n background: rgba(255, 255, 255, 0.1) !important;\r\n border-radius: 50%;\r\n transition: background 0.2s ease;\r\n border: none;\r\n width: 36px !important;\r\n height: 36px !important;\r\n min-width: 36px !important;\r\n min-height: 36px !important;\r\n padding: 0 !important;\r\n display: flex !important;\r\n align-items: center !important;\r\n justify-content: center !important;\r\n }\r\n\r\n .close-button::ng-deep button:hover,\r\n .share-button::ng-deep button:hover {\r\n background: rgba(255, 255, 255, 0.15) !important;\r\n }\r\n\r\n .close-button::ng-deep button:active,\r\n .share-button::ng-deep button:active {\r\n background: rgba(255, 255, 255, 0.15) !important;\r\n }\r\n\r\n .close-button::ng-deep svg,\r\n .share-button::ng-deep svg {\r\n color: white !important;\r\n fill: white !important;\r\n }\r\n\r\n /* Safe area support for notched devices */\r\n @supports (padding-top: env(safe-area-inset-top)) {\r\n .lightbox-header {\r\n padding-top: calc(16px + env(safe-area-inset-top));\r\n }\r\n }\r\n `]\r\n})\r\nexport class DsMobileLightboxHeaderComponent {\r\n /**\r\n * Author information to display\r\n */\r\n author = input<LightboxAuthor>();\r\n\r\n /**\r\n * Emitted when close button is clicked\r\n */\r\n closeClick = output<void>();\r\n \r\n /**\r\n * Emitted when share button is clicked\r\n */\r\n shareClick = output<void>();\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobileLightboxFooterComponent\r\n * \r\n * Shared footer component for all lightbox types (image, PDF, etc.)\r\n * Displays navigation controls (for multiple images) and action buttons.\r\n */\r\n@Component({\r\n selector: 'ds-mobile-lightbox-footer',\r\n standalone: true,\r\n imports: [CommonModule, DsIconButtonComponent],\r\n template: `\r\n <div class=\"lightbox-footer\">\r\n <!-- Navigation controls (only shown for multiple images) -->\r\n @if (showNavigation() && totalImages() > 1) {\r\n <div class=\"footer-navigation\">\r\n <button \r\n class=\"nav-button prev\"\r\n (click)=\"prevClick.emit()\"\r\n [disabled]=\"currentIndex() === 0\"\r\n aria-label=\"Previous image\">\r\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path d=\"M15 18L9 12L15 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg>\r\n </button>\r\n \r\n <div class=\"counter\">\r\n {{ currentIndex() + 1 }} / {{ totalImages() }}\r\n </div>\r\n \r\n <button \r\n class=\"nav-button next\"\r\n (click)=\"nextClick.emit()\"\r\n [disabled]=\"currentIndex() === totalImages() - 1\"\r\n aria-label=\"Next image\">\r\n <svg width=\"24\" height=\"24\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path d=\"M9 18L15 12L9 6\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg>\r\n </button>\r\n </div>\r\n }\r\n \r\n <!-- Action buttons -->\r\n @if (showActions()) {\r\n <div class=\"footer-actions\">\r\n <div class=\"action-buttons-left\">\r\n <!-- Like button -->\r\n <ds-icon-button\r\n [icon]=\"isLiked() ? 'remixHeart3Fill' : 'remixHeart3Line'\"\r\n variant=\"ghost\"\r\n size=\"md\"\r\n (click)=\"likeClick.emit()\"\r\n [attr.data-liked]=\"isLiked()\"\r\n class=\"action-button-like\"\r\n [ariaLabel]=\"'Like'\">\r\n </ds-icon-button>\r\n \r\n <!-- Comment button -->\r\n <ds-icon-button\r\n icon=\"remixChat3Line\"\r\n variant=\"ghost\"\r\n size=\"md\"\r\n (click)=\"commentClick.emit()\"\r\n class=\"action-button-comment\"\r\n [ariaLabel]=\"'Comment'\">\r\n </ds-icon-button>\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n `,\r\n styles: [`\r\n .lightbox-footer {\r\n position: fixed;\r\n bottom: 0;\r\n left: 0;\r\n right: 0;\r\n z-index: 100;\r\n padding: 16px 20px 20px 20px;\r\n background: linear-gradient(to top, rgba(0, 0, 0, 0.8) 0%, rgba(0, 0, 0, 0.6) 50%, rgba(0, 0, 0, 0.4) 75%, transparent 100%);\r\n pointer-events: none;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n }\r\n\r\n /* Navigation controls */\r\n .footer-navigation {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n gap: 24px;\r\n pointer-events: auto;\r\n }\r\n\r\n .nav-button {\r\n background: rgba(255, 255, 255, 0.1);\r\n border: 1px solid rgba(255, 255, 255, 0.2);\r\n border-radius: 50%;\r\n color: white;\r\n width: 40px;\r\n height: 40px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n backdrop-filter: blur(10px);\r\n -webkit-backdrop-filter: blur(10px);\r\n padding: 0;\r\n }\r\n\r\n .nav-button:hover:not(:disabled) {\r\n background: rgba(255, 255, 255, 0.2);\r\n transform: scale(1.05);\r\n }\r\n\r\n .nav-button:active:not(:disabled) {\r\n transform: scale(0.95);\r\n }\r\n\r\n .nav-button:disabled {\r\n opacity: 0.3;\r\n cursor: not-allowed;\r\n }\r\n\r\n .nav-button svg {\r\n width: 24px;\r\n height: 24px;\r\n flex-shrink: 0;\r\n }\r\n\r\n .counter {\r\n background: rgba(255, 255, 255, 0.1);\r\n border: 1px solid rgba(255, 255, 255, 0.2);\r\n backdrop-filter: blur(10px);\r\n -webkit-backdrop-filter: blur(10px);\r\n border-radius: 100px;\r\n padding: 8px 16px;\r\n color: white;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 500;\r\n line-height: 1;\r\n letter-spacing: -0.3px;\r\n pointer-events: auto;\r\n user-select: none;\r\n }\r\n\r\n .footer-actions {\r\n display: flex;\r\n align-items: center;\r\n gap: 16px;\r\n pointer-events: auto;\r\n }\r\n\r\n .action-buttons-left {\r\n display: flex;\r\n align-items: center;\r\n gap: 16px;\r\n }\r\n\r\n /* Style the action buttons to match the ghost/transparent look */\r\n .action-button-like::ng-deep button,\r\n .action-button-comment::ng-deep button {\r\n background: rgba(255, 255, 255, 0.1) !important;\r\n border: 1px solid rgba(255, 255, 255, 0.2) !important;\r\n color: white !important;\r\n backdrop-filter: blur(10px);\r\n -webkit-backdrop-filter: blur(10px);\r\n transition: all 0.2s ease;\r\n }\r\n\r\n .action-button-like::ng-deep button:hover,\r\n .action-button-comment::ng-deep button:hover {\r\n background: rgba(255, 255, 255, 0.2) !important;\r\n transform: scale(1.02);\r\n }\r\n\r\n .action-button-like::ng-deep button:active,\r\n .action-button-comment::ng-deep button:active {\r\n transform: scale(0.98);\r\n }\r\n\r\n /* Icon and label colors */\r\n .action-button-like::ng-deep button svg,\r\n .action-button-comment::ng-deep button svg,\r\n .action-button-like::ng-deep button .btn__icon,\r\n .action-button-comment::ng-deep button .btn__icon,\r\n .action-button-like::ng-deep button .btn__content,\r\n .action-button-comment::ng-deep button .btn__content {\r\n color: white !important;\r\n fill: white !important;\r\n }\r\n\r\n /* Make sure icons are visible */\r\n .action-button-like::ng-deep button .btn__icon svg,\r\n .action-button-comment::ng-deep button .btn__icon svg {\r\n color: white !important;\r\n fill: white !important;\r\n display: block !important;\r\n opacity: 1 !important;\r\n visibility: visible !important;\r\n width: 20px !important;\r\n height: 20px !important;\r\n }\r\n\r\n /* Ensure icon wrapper is visible */\r\n .action-button-like::ng-deep button .btn__icon,\r\n .action-button-comment::ng-deep button .btn__icon {\r\n display: flex !important;\r\n align-items: center !important;\r\n justify-content: center !important;\r\n flex-shrink: 0 !important;\r\n }\r\n\r\n /* Like button active state (pink heart) */\r\n .action-button-like[data-liked=\"true\"]::ng-deep button svg {\r\n fill: #f91880 !important;\r\n color: #f91880 !important;\r\n }\r\n\r\n .action-button-like[data-liked=\"true\"]::ng-deep button {\r\n border-color: rgba(249, 24, 128, 0.3) !important;\r\n }\r\n\r\n /* All action buttons should have same circular styling */\r\n .action-button-like,\r\n .action-button-comment {\r\n flex-shrink: 0;\r\n border-radius: 50%;\r\n }\r\n\r\n .action-button-like::ng-deep button,\r\n .action-button-comment::ng-deep button {\r\n border-radius: 50% !important;\r\n width: 44px !important;\r\n height: 44px !important;\r\n min-width: 44px !important;\r\n min-height: 44px !important;\r\n padding: 0 !important;\r\n display: flex !important;\r\n align-items: center !important;\r\n justify-content: center !important;\r\n }\r\n\r\n /* Safe area support for footer */\r\n @supports (padding-bottom: env(safe-area-inset-bottom)) {\r\n .lightbox-footer {\r\n padding-bottom: calc(20px + env(safe-area-inset-bottom));\r\n }\r\n }\r\n `]\r\n})\r\nexport class DsMobileLightboxFooterComponent {\r\n /**\r\n * Whether to show navigation controls\r\n */\r\n showNavigation = input<boolean>(false);\r\n\r\n /**\r\n * Current image index (0-based)\r\n */\r\n currentIndex = input<number>(0);\r\n\r\n /**\r\n * Total number of images\r\n */\r\n totalImages = input<number>(1);\r\n\r\n /**\r\n * Whether to show like & comment action buttons\r\n * @default false\r\n */\r\n showActions = input<boolean>(false);\r\n \r\n /**\r\n * Whether the content is liked\r\n */\r\n isLiked = input<boolean>(false);\r\n \r\n /**\r\n * Number of likes\r\n */\r\n likeCount = input<number>(0);\r\n \r\n /**\r\n * Number of comments\r\n */\r\n commentCount = input<number>(0);\r\n\r\n /**\r\n * Emitted when previous button is clicked\r\n */\r\n prevClick = output<void>();\r\n\r\n /**\r\n * Emitted when next button is clicked\r\n */\r\n nextClick = output<void>();\r\n\r\n /**\r\n * Emitted when like button is clicked\r\n */\r\n likeClick = output<void>();\r\n\r\n /**\r\n * Emitted when comment button is clicked\r\n */\r\n commentClick = output<void>();\r\n}\r\n\r\n","import {\r\n Component,\r\n signal,\r\n computed,\r\n ViewChild,\r\n ElementRef,\r\n AfterViewInit,\r\n OnDestroy,\r\n OnInit,\r\n CUSTOM_ELEMENTS_SCHEMA,\r\n HostListener\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport {\r\n IonSpinner,\r\n GestureController,\r\n Gesture\r\n} from '@ionic/angular/standalone';\r\nimport { Share } from '@capacitor/share';\r\nimport { Haptics, ImpactStyle } from '@capacitor/haptics';\r\nimport { DsMobileLightboxHeaderComponent } from './ds-mobile-lightbox-header';\r\nimport { DsMobileLightboxFooterComponent } from './ds-mobile-lightbox-footer';\r\nimport type { LightboxImage, LightboxAuthor } from './ds-mobile-lightbox.service';\r\nimport Swiper from 'swiper';\r\nimport type { SwiperOptions } from 'swiper/types';\r\n\r\n/**\r\n * DsMobileLightboxImageComponent\r\n * \r\n * Full-screen image lightbox component with Swiper.js navigation and pinch-zoom.\r\n * \r\n * This component is typically not used directly - use DsMobileLightboxService instead.\r\n * \r\n * Features:\r\n * - Swiper.js for smooth image navigation\r\n * - Pinch to zoom in/out\r\n * - Double-tap to toggle zoom\r\n * - Swipe down to close (when not zoomed)\r\n * - Image counter and navigation controls\r\n * \r\n * @example\r\n * ```typescript\r\n * // Don't instantiate directly - use the service:\r\n * constructor(private lightbox: DsMobileLightboxService) {}\r\n * \r\n * openImage() {\r\n * this.lightbox.openImages({\r\n * images: [{ type: 'image', src: 'image.jpg', title: 'My Image' }]\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-lightbox-image',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonSpinner,\r\n DsMobileLightboxHeaderComponent,\r\n DsMobileLightboxFooterComponent\r\n ],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n template: `\r\n <div class=\"lightbox-overlay\" \r\n [class.zoomed]=\"isZoomed()\">\r\n \r\n <div class=\"lightbox-wrapper\">\r\n <!-- Header with author info and action buttons -->\r\n <ds-mobile-lightbox-header \r\n [author]=\"author\"\r\n (closeClick)=\"close()\"\r\n (shareClick)=\"onShare()\"\r\n />\r\n\r\n <!-- Swiper container -->\r\n <div class=\"swiper-container\" #swiperContainer>\r\n <div class=\"swiper-wrapper\">\r\n @for (image of images; track image.src; let i = $index) {\r\n <div class=\"swiper-slide\">\r\n <div class=\"image-zoom-container\" [attr.data-index]=\"i\">\r\n <img \r\n [src]=\"image.src\"\r\n [alt]=\"image.alt || 'Lightbox image'\"\r\n class=\"lightbox-image\"\r\n (load)=\"onImageLoad(i)\"\r\n (error)=\"onImageError(i)\">\r\n </div>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n \r\n <!-- Loading indicator -->\r\n @if (isLoading()) {\r\n <div class=\"loading-spinner\">\r\n <ion-spinner name=\"crescent\"></ion-spinner>\r\n </div>\r\n }\r\n\r\n <!-- Footer with navigation and actions -->\r\n <ds-mobile-lightbox-footer\r\n [showNavigation]=\"showControls && images.length > 1\"\r\n [showActions]=\"showActions\"\r\n [currentIndex]=\"currentIndex()\"\r\n [totalImages]=\"images.length\"\r\n [isLiked]=\"isLiked()\"\r\n [likeCount]=\"likeCount()\"\r\n [commentCount]=\"commentCount()\"\r\n (prevClick)=\"previousImage()\"\r\n (nextClick)=\"nextImage()\"\r\n (likeClick)=\"onLikeToggle()\"\r\n (commentClick)=\"onReply()\"\r\n />\r\n </div>\r\n </div>\r\n `,\r\n styleUrl: './ds-mobile-lightbox.css'\r\n})\r\nexport class DsMobileLightboxImageComponent implements OnInit, AfterViewInit, OnDestroy {\r\n // Inputs (passed from service as regular properties, not signals)\r\n images!: LightboxImage[];\r\n author?: LightboxAuthor;\r\n initialIndex: number = 0;\r\n enableZoom: boolean = true;\r\n showControls: boolean = true;\r\n enableSwipe: boolean = true;\r\n showInfo: boolean = true;\r\n showActions: boolean = false;\r\n animation: 'fade' | 'zoom' | 'slide' = 'fade';\r\n onCloseRequested?: () => void;\r\n\r\n // View children\r\n @ViewChild('swiperContainer', { read: ElementRef }) swiperContainer!: ElementRef<HTMLDivElement>;\r\n\r\n // State\r\n currentIndex = signal(0);\r\n scale = signal(1);\r\n isZoomed = signal(false);\r\n isLoading = signal(true);\r\n hasError = signal(false);\r\n \r\n // Action states\r\n isLiked = signal(false);\r\n likeCount = signal(0);\r\n commentCount = signal(0);\r\n\r\n // Computed\r\n currentImage = computed(() => this.images[this.currentIndex()]);\r\n\r\n // Swiper instance\r\n private swiper?: Swiper;\r\n private zoomData: Map<number, { scale: number; x: number; y: number }> = new Map();\r\n\r\n constructor(\r\n private gestureCtrl: GestureController\r\n ) {}\r\n\r\n ngOnInit(): void {\r\n // Set initial index from the passed property\r\n if (this.initialIndex !== undefined) {\r\n this.currentIndex.set(this.initialIndex);\r\n }\r\n \r\n // Initialize action states from current image\r\n const currentImg = this.images[this.currentIndex()];\r\n if (currentImg) {\r\n this.isLiked.set(currentImg.isLiked ?? false);\r\n this.likeCount.set(currentImg.likeCount ?? 0);\r\n this.commentCount.set(currentImg.commentCount ?? 0);\r\n }\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n setTimeout(() => {\r\n this.initializeSwiper();\r\n this.initializeZoomGestures();\r\n }, 100);\r\n }\r\n\r\n ngOnDestroy(): void {\r\n // Clean up Swiper\r\n if (this.swiper) {\r\n this.swiper.destroy();\r\n this.swiper = undefined;\r\n }\r\n }\r\n /**\r\n * Initialize Swiper for image navigation\r\n */\r\n private initializeSwiper(): void {\r\n if (!this.swiperContainer) {\r\n console.error('[Lightbox] Swiper container not found');\r\n return;\r\n }\r\n\r\n const swiperOptions: SwiperOptions = {\r\n initialSlide: this.initialIndex,\r\n speed: 300,\r\n resistance: true,\r\n resistanceRatio: 0.85,\r\n slidesPerView: 1,\r\n spaceBetween: 0,\r\n touchRatio: 1,\r\n longSwipesRatio: 0.5,\r\n threshold: 10,\r\n on: {\r\n slideChange: (swiper) => {\r\n this.currentIndex.set(swiper.activeIndex);\r\n this.updateActionStates();\r\n \r\n // Check if the image is already loaded\r\n const currentSlide = swiper.slides[swiper.activeIndex];\r\n const img = currentSlide?.querySelector('img');\r\n if (img && img.complete && img.naturalHeight !== 0) {\r\n // Image is already loaded\r\n this.isLoading.set(false);\r\n }\r\n },\r\n slideChangeTransitionStart: () => {\r\n // Don't show loading spinner if image is already loaded\r\n const currentSlide = this.swiper?.slides[this.swiper.activeIndex];\r\n const img = currentSlide?.querySelector('img');\r\n if (!img || !img.complete || img.naturalHeight === 0) {\r\n this.isLoading.set(true);\r\n }\r\n }\r\n }\r\n };\r\n\r\n this.swiper = new Swiper(this.swiperContainer.nativeElement, swiperOptions);\r\n \r\n // Check if the initial image is already loaded\r\n setTimeout(() => {\r\n const currentSlide = this.swiper?.slides[this.currentIndex()];\r\n const img = currentSlide?.querySelector('img');\r\n if (img && img.complete && img.naturalHeight !== 0) {\r\n this.isLoading.set(false);\r\n }\r\n }, 0);\r\n }\r\n\r\n /**\r\n * Initialize pinch-zoom gestures for all slides\r\n */\r\n private initializeZoomGestures(): void {\r\n if (!this.enableZoom) return;\r\n\r\n const slides = this.swiperContainer.nativeElement.querySelectorAll('.image-zoom-container');\r\n \r\n slides.forEach((slide, index) => {\r\n this.initializeZoomForSlide(slide as HTMLElement, index);\r\n });\r\n }\r\n\r\n /**\r\n * Initialize zoom gestures for a specific slide\r\n */\r\n private initializeZoomForSlide(container: HTMLElement, index: number): void {\r\n let initialDistance = 0;\r\n let initialScale = 1;\r\n let currentScale = 1;\r\n let lastTap = 0;\r\n\r\n // Double-tap to zoom\r\n container.addEventListener('click', (event: MouseEvent) => {\r\n const now = Date.now();\r\n const timeSinceLastTap = now - lastTap;\r\n\r\n if (timeSinceLastTap < 300 && timeSinceLastTap > 0) {\r\n event.preventDefault();\r\n this.toggleZoom(container, index);\r\n }\r\n\r\n lastTap = now;\r\n });\r\n\r\n // Pinch to zoom\r\n const getTouchDistance = (touches: TouchList) => {\r\n const dx = touches[0].clientX - touches[1].clientX;\r\n const dy = touches[0].clientY - touches[1].clientY;\r\n return Math.sqrt(dx * dx + dy * dy);\r\n };\r\n\r\n container.addEventListener('touchstart', (event: TouchEvent) => {\r\n if (event.touches.length === 2) {\r\n event.preventDefault();\r\n initialDistance = getTouchDistance(event.touches);\r\n const zoomData = this.zoomData.get(index) || { scale: 1, x: 0, y: 0 };\r\n initialScale = zoomData.scale;\r\n \r\n // Disable Swiper when zooming\r\n if (this.swiper) {\r\n this.swiper.allowTouchMove = false;\r\n }\r\n }\r\n }, { passive: false });\r\n\r\n container.addEventListener('touchmove', (event: TouchEvent) => {\r\n if (event.touches.length === 2) {\r\n event.preventDefault();\r\n \r\n const currentDistance = getTouchDistance(event.touches);\r\n const pinchScale = currentDistance / initialDistance;\r\n \r\n currentScale = Math.max(1, Math.min(initialScale * pinchScale, 4));\r\n \r\n const img = container.querySelector('img');\r\n if (img) {\r\n img.style.transform = `scale(${currentScale})`;\r\n }\r\n \r\n if (currentScale > 1) {\r\n this.isZoomed.set(true);\r\n } else {\r\n this.isZoomed.set(false);\r\n }\r\n }\r\n }, { passive: false });\r\n\r\n container.addEventListener('touchend', (event: TouchEvent) => {\r\n if (event.touches.length < 2) {\r\n // Save zoom state\r\n this.zoomData.set(index, { scale: currentScale, x: 0, y: 0 });\r\n \r\n // Re-enable Swiper if not zoomed\r\n if (this.swiper && currentScale <= 1) {\r\n this.swiper.allowTouchMove = true;\r\n }\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * Toggle zoom on double-tap\r\n */\r\n private toggleZoom(container: HTMLElement, index: number): void {\r\n const zoomData = this.zoomData.get(index) || { scale: 1, x: 0, y: 0 };\r\n const img = container.querySelector('img');\r\n \r\n if (!img) return;\r\n\r\n if (zoomData.scale > 1) {\r\n // Zoom out\r\n img.style.transform = 'scale(1)';\r\n this.zoomData.set(index, { scale: 1, x: 0, y: 0 });\r\n this.isZoomed.set(false);\r\n if (this.swiper) {\r\n this.swiper.allowTouchMove = true;\r\n }\r\n } else {\r\n // Zoom in\r\n img.style.transform = 'scale(2)';\r\n this.zoomData.set(index, { scale: 2, x: 0, y: 0 });\r\n this.isZoomed.set(true);\r\n if (this.swiper) {\r\n this.swiper.allowTouchMove = false;\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Update action states (like, comments) when slide changes\r\n */\r\n private updateActionStates(): void {\r\n const currentImg = this.images[this.currentIndex()];\r\n if (currentImg) {\r\n this.isLiked.set(currentImg.isLiked ?? false);\r\n this.likeCount.set(currentImg.likeCount ?? 0);\r\n this.commentCount.set(currentImg.commentCount ?? 0);\r\n }\r\n }\r\n\r\n /**\r\n * Close the lightbox\r\n */\r\n close(): void {\r\n if (this.onCloseRequested) {\r\n this.onCloseRequested();\r\n }\r\n }\r\n\r\n /**\r\n * Handle share button click\r\n */\r\n async onShare(): Promise<void> {\r\n console.log('[Lightbox] Share button clicked');\r\n const currentImg = this.currentImage();\r\n \r\n if (!currentImg?.src) {\r\n console.warn('[Lightbox] No image to share');\r\n return;\r\n }\r\n \r\n try {\r\n // Check if Web Share API is available (for browser)\r\n if (navigator.share) {\r\n await navigator.share({\r\n title: currentImg.title || 'Shared Image',\r\n text: currentImg.description || '',\r\n url: currentImg.src,\r\n });\r\n console.log('[Lightbox] Shared via Web Share API');\r\n } else {\r\n // Fallback to Capacitor Share API (for native apps)\r\n await Share.share({\r\n title: currentImg.title || 'Shared Image',\r\n url: currentImg.src,\r\n dialogTitle: 'Share Image',\r\n });\r\n console.log('[Lightbox] Shared via Capacitor Share API');\r\n }\r\n } catch (error: any) {\r\n // User cancellation is expected and not an error\r\n if (error?.message?.includes('cancel') || error?.code === 'USER_CANCELLED') {\r\n console.log('[Lightbox] Share cancelled by user');\r\n return;\r\n }\r\n console.error('[Lightbox] Share failed:', error);\r\n }\r\n }\r\n\r\n /**\r\n * Handle like button toggle\r\n */\r\n onLikeToggle(): void {\r\n console.log('[Lightbox] Like button toggled');\r\n this.isLiked.update(liked => !liked);\r\n \r\n if (this.isLiked()) {\r\n this.likeCount.update(count => count + 1);\r\n } else {\r\n this.likeCount.update(count => Math.max(0, count - 1));\r\n }\r\n }\r\n\r\n /**\r\n * Handle reply/comment button click\r\n */\r\n onReply(): void {\r\n console.log('[Lightbox] Reply button clicked');\r\n if (this.onCloseRequested) {\r\n this.onCloseRequested();\r\n }\r\n }\r\n\r\n /**\r\n * Navigate to the next image\r\n */\r\n nextImage(): void {\r\n if (this.swiper && this.currentIndex() < this.images.length - 1) {\r\n this.swiper.slideNext();\r\n }\r\n }\r\n\r\n /**\r\n * Navigate to the previous image\r\n */\r\n previousImage(): void {\r\n if (this.swiper && this.currentIndex() > 0) {\r\n this.swiper.slidePrev();\r\n }\r\n }\r\n\r\n /**\r\n * Handle image load success\r\n */\r\n onImageLoad(index: number): void {\r\n if (index === this.currentIndex()) {\r\n this.isLoading.set(false);\r\n }\r\n }\r\n\r\n /**\r\n * Handle image load error\r\n */\r\n onImageError(index: number): void {\r\n if (index === this.currentIndex()) {\r\n console.error(`[Lightbox] Image ${index} failed to load`);\r\n this.isLoading.set(false);\r\n this.hasError.set(true);\r\n }\r\n }\r\n}\r\n\r\n","import {\r\n Component,\r\n OnInit,\r\n CUSTOM_ELEMENTS_SCHEMA\r\n} from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport {\r\n IonContent,\r\n IonSpinner\r\n} from '@ionic/angular/standalone';\r\nimport { Filesystem, Directory } from '@capacitor/filesystem';\r\nimport { Browser } from '@capacitor/browser';\r\nimport { Share } from '@capacitor/share';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsButtonComponent } from '@propbinder/design-system';\r\nimport { DsMobileLightboxHeaderComponent } from './ds-mobile-lightbox-header';\r\nimport { DsMobileLightboxFooterComponent } from './ds-mobile-lightbox-footer';\r\nimport type { LightboxPdf, LightboxAuthor } from './ds-mobile-lightbox.service';\r\n\r\n/**\r\n * DsMobileLightboxPdfComponent\r\n * \r\n * PDF viewer component that displays PDF info and allows users to open PDFs in the native device viewer.\r\n * Shows a lightbox with PDF details first, then user can choose to open in native viewer.\r\n * \r\n * This component is typically not used directly - use DsMobileLightboxService instead.\r\n * \r\n * Features:\r\n * - PDF info preview (title, size, icon)\r\n * - User-initiated native PDF viewing (iOS/Android)\r\n * - Download and cache support\r\n * - Share functionality\r\n * - Loading states\r\n * \r\n * @example\r\n * ```typescript\r\n * // Don't instantiate directly - use the service:\r\n * constructor(private lightbox: DsMobileLightboxService) {}\r\n * \r\n * openPdf() {\r\n * this.lightbox.openPdf({\r\n * pdf: { type: 'pdf', src: 'document.pdf', title: 'My Document' }\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-lightbox-pdf',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n IonContent,\r\n IonSpinner,\r\n DsAvatarComponent,\r\n DsButtonComponent,\r\n DsMobileLightboxHeaderComponent,\r\n DsMobileLightboxFooterComponent\r\n ],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n template: `\r\n <ion-content \r\n [fullscreen]=\"true\"\r\n class=\"lightbox-content pdf-viewer\">\r\n \r\n <div class=\"lightbox-wrapper\">\r\n <!-- Header with author info and close button -->\r\n <ds-mobile-lightbox-header \r\n [author]=\"author\"\r\n (closeClick)=\"close()\"\r\n />\r\n\r\n <!-- PDF Info & Actions -->\r\n <div class=\"pdf-container\">\r\n @if (isLoading) {\r\n <div class=\"loading-state\">\r\n <ion-spinner name=\"crescent\"></ion-spinner>\r\n <p>Loading PDF...</p>\r\n </div>\r\n } @else if (hasError) {\r\n <div class=\"error-state\">\r\n <svg width=\"64\" height=\"64\" viewBox=\"0 0 24 24\" fill=\"none\">\r\n <path d=\"M12 8V12M12 16H12.01M21 12C21 16.9706 16.9706 21 12 21C7.02944 21 3 16.9706 3 12C3 7.02944 7.02944 3 12 3C16.9706 3 21 7.02944 21 12Z\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\"/>\r\n </svg>\r\n <h3>Failed to Load PDF</h3>\r\n <p>{{ errorMessage }}</p>\r\n <button class=\"retry-button\" (click)=\"openPdfInNativeViewer()\">\r\n Try Again\r\n </button>\r\n </div>\r\n } @else {\r\n <div class=\"pdf-content\">\r\n <!-- PDF Icon -->\r\n <ds-avatar\r\n type=\"icon\"\r\n iconName=\"remixFileTextLine\"\r\n size=\"xl\"\r\n />\r\n \r\n <!-- PDF Title (same as attachment fileName) -->\r\n <h2 class=\"pdf-title\">{{ getDisplayTitle() }}</h2>\r\n \r\n <!-- PDF Metadata (same format as attachment: PDF · fileSize) -->\r\n <div class=\"pdf-meta\">\r\n PDF · {{ pdf.fileSize ? formatFileSize(pdf.fileSize) : '' }}\r\n </div>\r\n \r\n <!-- Open Button -->\r\n <ds-button\r\n variant=\"secondary\"\r\n size=\"lg\"\r\n (clicked)=\"openPdfInNativeViewer()\"\r\n class=\"open-pdf-button\">\r\n Open Preview\r\n </ds-button>\r\n </div>\r\n }\r\n </div>\r\n\r\n <!-- Bottom actions -->\r\n <ds-mobile-lightbox-footer\r\n [isLiked]=\"false\"\r\n [likeCount]=\"0\"\r\n [commentCount]=\"0\"\r\n (likeClick)=\"onLikeToggle()\"\r\n (commentClick)=\"onReply()\"\r\n (shareClick)=\"onShare()\"\r\n />\r\n </div>\r\n </ion-content>\r\n `,\r\n styleUrl: './ds-mobile-lightbox-pdf.css'\r\n})\r\nexport class DsMobileLightboxPdfComponent implements OnInit {\r\n // Inputs (passed from service as regular properties)\r\n pdf!: LightboxPdf;\r\n author?: LightboxAuthor;\r\n onCloseRequested?: () => void;\r\n\r\n // State\r\n isLoading = false;\r\n hasError = false;\r\n errorMessage = '';\r\n cachedFilePath?: string;\r\n\r\n constructor() {}\r\n\r\n ngOnInit(): void {\r\n console.log('[PDF Lightbox] Initializing with PDF:', this.pdf);\r\n \r\n // Don't automatically open - let user click the \"Open\" button\r\n // this.openPdfInNativeViewer();\r\n }\r\n\r\n /**\r\n * Open the PDF in the native device viewer\r\n */\r\n async openPdfInNativeViewer(): Promise<void> {\r\n if (!this.pdf?.src) {\r\n console.error('[PDF Lightbox] No PDF source provided');\r\n this.hasError = true;\r\n this.errorMessage = 'No PDF file provided';\r\n return;\r\n }\r\n\r\n this.isLoading = true;\r\n this.hasError = false;\r\n this.errorMessage = '';\r\n\r\n try {\r\n console.log('[PDF Lightbox] Opening PDF:', this.pdf.src);\r\n \r\n // Check if it's already a full URL\r\n let pdfUrl: string;\r\n \r\n if (this.pdf.src.startsWith('http://') || this.pdf.src.startsWith('https://')) {\r\n // Already a full URL\r\n pdfUrl = this.pdf.src;\r\n } else {\r\n // Relative path - construct full URL\r\n // Use current origin (which includes the dev server URL in Capacitor)\r\n // Remove leading slash if present to avoid double slashes\r\n const cleanPath = this.pdf.src.startsWith('/') ? this.pdf.src.slice(1) : this.pdf.src;\r\n pdfUrl = `${window.location.origin}/${cleanPath}`;\r\n }\r\n \r\n console.log('[PDF Lightbox] Opening PDF at URL:', pdfUrl);\r\n \r\n // Use Browser to open the PDF\r\n await Browser.open({ \r\n url: pdfUrl,\r\n presentationStyle: 'fullscreen'\r\n });\r\n \r\n this.isLoading = false;\r\n \r\n // Close the modal after opening browser\r\n setTimeout(() => {\r\n this.close();\r\n }, 500);\r\n } catch (error: any) {\r\n console.error('[PDF Lightbox] Error opening PDF:', error);\r\n this.isLoading = false;\r\n this.hasError = true;\r\n this.errorMessage = error?.message || 'Failed to open PDF';\r\n }\r\n }\r\n\r\n /**\r\n * Download a remote PDF and open it\r\n */\r\n private async downloadAndOpenPdf(): Promise<void> {\r\n try {\r\n console.log('[PDF Lightbox] Downloading PDF from:', this.pdf.src);\r\n \r\n // Fetch the PDF\r\n const response = await fetch(this.pdf.src);\r\n if (!response.ok) {\r\n throw new Error(`Failed to download PDF: ${response.statusText}`);\r\n }\r\n \r\n const blob = await response.blob();\r\n const base64Data = await this.blobToBase64(blob);\r\n \r\n // Generate a filename\r\n const fileName = this.pdf.title \r\n ? `${this.pdf.title.replace(/[^a-z0-9]/gi, '_')}.pdf`\r\n : 'document.pdf';\r\n \r\n // Save to cache directory\r\n const result = await Filesystem.writeFile({\r\n path: fileName,\r\n data: base64Data,\r\n directory: Directory.Cache\r\n });\r\n \r\n console.log('[PDF Lightbox] PDF saved to cache:', result.uri);\r\n this.cachedFilePath = result.uri;\r\n \r\n // Open using Browser\r\n await Browser.open({ \r\n url: result.uri,\r\n presentationStyle: 'fullscreen'\r\n });\r\n \r\n console.log('[PDF Lightbox] PDF opened successfully');\r\n } catch (error) {\r\n console.error('[PDF Lightbox] Error downloading/opening PDF:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Open a local PDF file\r\n */\r\n private async openLocalPdf(): Promise<void> {\r\n try {\r\n // Remove leading slash if present to avoid double slashes\r\n const cleanPath = this.pdf.src.startsWith('/') ? this.pdf.src.slice(1) : this.pdf.src;\r\n const fullUrl = window.location.origin + '/' + cleanPath;\r\n \r\n await Browser.open({ \r\n url: fullUrl,\r\n presentationStyle: 'fullscreen'\r\n });\r\n \r\n console.log('[PDF Lightbox] Local PDF opened successfully');\r\n } catch (error) {\r\n console.error('[PDF Lightbox] Error opening local PDF:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Convert Blob to base64 string\r\n */\r\n private blobToBase64(blob: Blob): Promise<string> {\r\n return new Promise((resolve, reject) => {\r\n const reader = new FileReader();\r\n reader.onloadend = () => {\r\n const base64String = reader.result as string;\r\n // Remove the data URL prefix\r\n const base64Data = base64String.split(',')[1];\r\n resolve(base64Data);\r\n };\r\n reader.onerror = reject;\r\n reader.readAsDataURL(blob);\r\n });\r\n }\r\n\r\n /**\r\n * Get display title with file extension\r\n * If title is provided, ensure it has .pdf extension\r\n * Otherwise, extract filename from src\r\n */\r\n getDisplayTitle(): string {\r\n if (this.pdf.title) {\r\n // If title doesn't end with .pdf, add it\r\n return this.pdf.title.endsWith('.pdf') ? this.pdf.title : `${this.pdf.title}.pdf`;\r\n }\r\n \r\n // Extract filename from src\r\n if (this.pdf.src) {\r\n const filename = this.pdf.src.split('/').pop() || 'PDF Document.pdf';\r\n return filename;\r\n }\r\n \r\n return 'PDF Document.pdf';\r\n }\r\n\r\n /**\r\n * Format file size for display\r\n */\r\n formatFileSize(bytes: number): string {\r\n if (bytes === 0) return '0 Bytes';\r\n \r\n const k = 1024;\r\n const sizes = ['Bytes', 'KB', 'MB', 'GB'];\r\n const i = Math.floor(Math.log(bytes) / Math.log(k));\r\n \r\n return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + ' ' + sizes[i];\r\n }\r\n\r\n /**\r\n * Share the PDF\r\n */\r\n async onShare(): Promise<void> {\r\n console.log('[PDF Lightbox] Share button clicked');\r\n \r\n if (!this.pdf?.src) return;\r\n \r\n try {\r\n await Share.share({\r\n title: this.pdf.title || 'PDF Document',\r\n text: this.pdf.description || '',\r\n url: this.pdf.src,\r\n dialogTitle: 'Share PDF'\r\n });\r\n \r\n console.log('[PDF Lightbox] PDF shared successfully');\r\n } catch (error) {\r\n console.error('[PDF Lightbox] Error sharing PDF:', error);\r\n }\r\n }\r\n\r\n /**\r\n * Close the PDF viewer\r\n */\r\n close(): void {\r\n if (this.onCloseRequested) {\r\n this.onCloseRequested();\r\n }\r\n }\r\n\r\n /**\r\n * Handle like toggle\r\n */\r\n onLikeToggle(): void {\r\n console.log('[PDF Lightbox] Like toggled');\r\n // TODO: Implement like logic for PDFs if needed\r\n }\r\n\r\n /**\r\n * Handle reply/comment\r\n * Close the lightbox and signal to open post detail with comment focus\r\n */\r\n onReply(): void {\r\n console.log('[PDF Lightbox] Reply button clicked');\r\n if (this.onCloseRequested) {\r\n this.onCloseRequested();\r\n // The calling code should handle opening the post detail modal\r\n }\r\n }\r\n}\r\n\r\n","import { Injectable, ApplicationRef, ComponentRef, createComponent, EnvironmentInjector, Injector } from '@angular/core';\r\nimport { DsMobileLightboxImageComponent } from './ds-mobile-lightbox-image';\r\nimport { DsMobileLightboxPdfComponent } from './ds-mobile-lightbox-pdf';\r\n\r\n/**\r\n * Media file types supported by the lightbox\r\n */\r\nexport type LightboxMediaType = 'image' | 'pdf';\r\n\r\n/**\r\n * Base media file interface\r\n */\r\nexport interface LightboxMediaFile {\r\n /** File source URL */\r\n src: string;\r\n /** Media type - determines which viewer to use */\r\n type: LightboxMediaType;\r\n /** File title */\r\n title?: string;\r\n /** File description */\r\n description?: string;\r\n}\r\n\r\n/**\r\n * Image data for lightbox display\r\n */\r\nexport interface LightboxImage extends LightboxMediaFile {\r\n type: 'image';\r\n /** Alt text for accessibility */\r\n alt?: string;\r\n /** Thumbnail URL for faster loading (optional) */\r\n thumbnail?: string;\r\n /** Whether the image is liked */\r\n isLiked?: boolean;\r\n /** Number of likes */\r\n likeCount?: number;\r\n /** Number of comments */\r\n commentCount?: number;\r\n}\r\n\r\n/**\r\n * PDF document data for lightbox display\r\n */\r\nexport interface LightboxPdf extends LightboxMediaFile {\r\n type: 'pdf';\r\n /** File size in bytes (optional, for display) */\r\n fileSize?: number;\r\n /** Number of pages (optional, for display) */\r\n pageCount?: number;\r\n}\r\n\r\n/**\r\n * Author metadata for the lightbox\r\n */\r\nexport interface LightboxAuthor {\r\n /** Author name */\r\n name: string;\r\n /** Author role/subtitle */\r\n role?: string;\r\n /** Author avatar URL */\r\n avatarSrc?: string;\r\n /** Author avatar initials (if no photo) */\r\n avatarInitials?: string;\r\n /** Avatar type */\r\n avatarType?: 'photo' | 'initials';\r\n /** Timestamp */\r\n timestamp?: string;\r\n}\r\n\r\n/**\r\n * Configuration options for image lightbox\r\n */\r\nexport interface LightboxImageOptions {\r\n /** Array of images to display */\r\n images: LightboxImage[];\r\n /** Author information to display in header */\r\n author?: LightboxAuthor;\r\n /** Initial image index to show (0-based) */\r\n initialIndex?: number;\r\n /** Enable pinch-to-zoom and double-tap zoom */\r\n enableZoom?: boolean;\r\n /** Show navigation controls (arrows, counter) */\r\n showControls?: boolean;\r\n /** Enable swipe gestures to navigate between images */\r\n enableSwipe?: boolean;\r\n /** Show image info (title, description) */\r\n showInfo?: boolean;\r\n /** Show like & comment action buttons */\r\n showActions?: boolean;\r\n /** Animation type for opening */\r\n animation?: 'fade' | 'zoom' | 'slide';\r\n}\r\n\r\n/**\r\n * Configuration options for PDF lightbox\r\n */\r\nexport interface LightboxPdfOptions {\r\n /** PDF document to display */\r\n pdf: LightboxPdf;\r\n /** Author information to display */\r\n author?: LightboxAuthor;\r\n}\r\n\r\n/**\r\n * Generic lightbox options (for backward compatibility)\r\n */\r\nexport type LightboxOptions = LightboxImageOptions;\r\n\r\n/**\r\n * DsMobileLightboxService\r\n * \r\n * Service for displaying media files (images and PDFs) in full-screen viewers.\r\n * - Images: Full-screen modal with gestures (pinch-zoom, swipe navigation)\r\n * - PDFs: Native device PDF viewer (iOS/Android)\r\n * \r\n * Features:\r\n * - Full-screen image viewing with gestures\r\n * - Native PDF viewing\r\n * - Swipe navigation between images\r\n * - Pinch-to-zoom and double-tap zoom for images\r\n * - Mobile-optimized touch gestures\r\n * - Share functionality\r\n * \r\n * @example\r\n * ```typescript\r\n * constructor(private lightbox: DsMobileLightboxService) {}\r\n * \r\n * // Open images\r\n * async openImages() {\r\n * const modal = await this.lightbox.openImages({\r\n * images: [\r\n * {\r\n * type: 'image',\r\n * src: 'https://example.com/image1.jpg',\r\n * title: 'Beautiful Sunset'\r\n * }\r\n * ]\r\n * });\r\n * \r\n * // Listen for when lightbox is dismissed\r\n * const { data } = await modal.onDidDismiss();\r\n * if (data?.action === 'comment') {\r\n * // Open post detail modal with comment focus\r\n * this.openPostDetail({ focusComment: true });\r\n * }\r\n * }\r\n * \r\n * // Open PDF\r\n * async openPdf() {\r\n * await this.lightbox.openPdf({\r\n * pdf: {\r\n * type: 'pdf',\r\n * src: 'https://example.com/document.pdf',\r\n * title: 'Document'\r\n * }\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class DsMobileLightboxService {\r\n private currentLightbox: ComponentRef<any> | null = null;\r\n\r\n constructor(\r\n private appRef: ApplicationRef,\r\n private injector: EnvironmentInjector\r\n ) {}\r\n\r\n /**\r\n * Open the lightbox with images (backward compatible method)\r\n * \r\n * @param options Configuration options for the image lightbox\r\n * @returns Promise that resolves to a dismiss function\r\n */\r\n async open(options: LightboxOptions): Promise<() => void> {\r\n return this.openImages(options);\r\n }\r\n\r\n /**\r\n * Open the image lightbox with one or more images\r\n * \r\n * @param options Configuration options for the image lightbox\r\n * @returns Promise that resolves to a dismiss function\r\n */\r\n async openImages(options: LightboxImageOptions): Promise<() => void> {\r\n console.log('[Lightbox] Opening images with options:', options);\r\n \r\n // Close any existing lightbox\r\n if (this.currentLightbox) {\r\n this.close();\r\n }\r\n\r\n // Create the component\r\n const componentRef = createComponent(DsMobileLightboxImageComponent, {\r\n environmentInjector: this.injector\r\n });\r\n\r\n // Set component props\r\n componentRef.instance.images = options.images;\r\n componentRef.instance.author = options.author;\r\n componentRef.instance.initialIndex = options.initialIndex ?? 0;\r\n componentRef.instance.enableZoom = options.enableZoom !== false;\r\n componentRef.instance.showControls = options.showControls !== false;\r\n componentRef.instance.enableSwipe = options.enableSwipe !== false;\r\n componentRef.instance.showInfo = options.showInfo !== false;\r\n componentRef.instance.showActions = options.showActions ?? false;\r\n componentRef.instance.animation = options.animation ?? 'fade';\r\n \r\n // Set up close callback\r\n componentRef.instance.onCloseRequested = () => {\r\n this.close();\r\n };\r\n\r\n // Attach to application\r\n this.appRef.attachView(componentRef.hostView);\r\n \r\n // Append to body\r\n const domElem = (componentRef.hostView as any).rootNodes[0] as HTMLElement;\r\n document.body.appendChild(domElem);\r\n \r\n // Store reference\r\n this.currentLightbox = componentRef;\r\n\r\n console.log('[Lightbox] Image lightbox rendered');\r\n \r\n // Return dismiss function\r\n return () => this.close();\r\n }\r\n\r\n /**\r\n * Open the PDF lightbox (opens native PDF viewer)\r\n * \r\n * @param options Configuration options for the PDF lightbox\r\n * @returns Promise that resolves to a dismiss function\r\n */\r\n async openPdf(options: LightboxPdfOptions): Promise<() => void> {\r\n console.log('[Lightbox] Opening PDF with options:', options);\r\n \r\n // Close any existing lightbox\r\n if (this.currentLightbox) {\r\n this.close();\r\n }\r\n\r\n // Create the component\r\n const componentRef = createComponent(DsMobileLightboxPdfComponent, {\r\n environmentInjector: this.injector\r\n });\r\n\r\n // Set component props\r\n componentRef.instance.pdf = options.pdf;\r\n componentRef.instance.author = options.author;\r\n \r\n // Set up close callback\r\n componentRef.instance.onCloseRequested = () => {\r\n this.close();\r\n };\r\n\r\n // Attach to application\r\n this.appRef.attachView(componentRef.hostView);\r\n \r\n // Append to body\r\n const domElem = (componentRef.hostView as any).rootNodes[0] as HTMLElement;\r\n document.body.appendChild(domElem);\r\n \r\n // Store reference\r\n this.currentLightbox = componentRef;\r\n\r\n console.log('[Lightbox] PDF lightbox rendered');\r\n \r\n // Return dismiss function\r\n return () => this.close();\r\n }\r\n\r\n /**\r\n * Close the currently open lightbox\r\n */\r\n close(): void {\r\n if (this.currentLightbox) {\r\n const domElem = (this.currentLightbox.hostView as any).rootNodes[0] as HTMLElement;\r\n domElem.remove();\r\n this.appRef.detachView(this.currentLightbox.hostView);\r\n this.currentLightbox.destroy();\r\n this.currentLightbox = null;\r\n }\r\n }\r\n\r\n /**\r\n * Check if a lightbox is currently open\r\n */\r\n isOpen(): boolean {\r\n return this.currentLightbox !== null;\r\n }\r\n}\r\n\r\n","// Components\r\nexport { DsMobileLightboxImageComponent } from './ds-mobile-lightbox-image';\r\nexport { DsMobileLightboxPdfComponent } from './ds-mobile-lightbox-pdf';\r\nexport { DsMobileLightboxHeaderComponent } from './ds-mobile-lightbox-header';\r\nexport { DsMobileLightboxFooterComponent } from './ds-mobile-lightbox-footer';\r\n\r\n// Service and Types\r\nexport { \r\n DsMobileLightboxService,\r\n type LightboxImage,\r\n type LightboxPdf,\r\n type LightboxMediaFile,\r\n type LightboxMediaType,\r\n type LightboxAuthor,\r\n type LightboxOptions,\r\n type LightboxImageOptions,\r\n type LightboxPdfOptions\r\n} from './ds-mobile-lightbox.service';\r\n\r\n// Legacy export for backward compatibility\r\nexport { DsMobileLightboxImageComponent as DsMobileLightboxComponent } from './ds-mobile-lightbox-image';\r\n\r\n","import { Component, Input, output, signal, OnInit } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsMobileLightboxService, LightboxImage } from '../lightbox/ds-mobile-lightbox.service';\r\nimport { DsMobileLoaderOverlayComponent } from '../loader-overlay';\r\n\r\n/**\r\n * DsMobileInlinePhotoComponent\r\n * \r\n * Displays one or multiple photos in a grid layout optimized for social feeds.\r\n * Supports up to 5 visible images with automatic grid layouts.\r\n * \r\n * Features:\r\n * - Automatic grid layouts for 1-5 images\r\n * - Shows \"+N more\" overlay if more than 5 images\r\n * - Opens lightbox with all images (including hidden ones) when clicked\r\n * - Optimized layouts: 1 full, 2 split, 3 masonry, 4 grid, 5 grid\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-inline-photo\r\n * [images]=\"['img1.jpg', 'img2.jpg', 'img3.jpg']\"\r\n * [author]=\"authorInfo\"\r\n * />\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-inline-photo',\r\n standalone: true,\r\n imports: [CommonModule, DsMobileLoaderOverlayComponent],\r\n template: `\r\n <div \r\n class=\"photo-grid\" \r\n [class.flex-layout]=\"!useGrid\"\r\n [attr.data-count]=\"useGrid ? visibleImages.length : null\"\r\n [class.has-more]=\"hiddenCount > 0\">\r\n @for (image of visibleImages; track image; let i = $index) {\r\n <div \r\n class=\"photo-item\"\r\n [class.last]=\"i === visibleImages.length - 1\"\r\n (click)=\"openLightbox(i, $event)\">\r\n <img \r\n [src]=\"image\" \r\n [alt]=\"'Photo ' + (i + 1)\"\r\n (load)=\"onImageLoad(i)\"\r\n (error)=\"onImageError(i)\"\r\n loading=\"lazy\">\r\n \r\n <!-- Loading Overlay -->\r\n @if (isImageLoading(i)) {\r\n <ds-mobile-loader-overlay />\r\n }\r\n \r\n <!-- Show \"+N more\" overlay on last image if there are hidden images -->\r\n @if (i === visibleImages.length - 1 && hiddenCount > 0) {\r\n <div class=\"more-overlay\">\r\n <span class=\"more-text\">+{{ hiddenCount }}</span>\r\n </div>\r\n }\r\n </div>\r\n }\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n display: block;\r\n }\r\n\r\n .photo-grid {\r\n display: grid;\r\n gap: 4px;\r\n border-radius: 8px;\r\n overflow: hidden;\r\n background: var(--ds-color-neutral-100);\r\n width: 100%;\r\n }\r\n\r\n .photo-item {\r\n position: relative;\r\n overflow: hidden;\r\n cursor: pointer;\r\n background: var(--ds-color-neutral-200);\r\n aspect-ratio: 1;\r\n }\r\n\r\n .photo-item img {\r\n width: 100%;\r\n height: 100%;\r\n object-fit: cover;\r\n display: block;\r\n transition: transform 0.2s ease;\r\n }\r\n\r\n .photo-item:active img {\r\n transform: scale(0.98);\r\n }\r\n\r\n .more-overlay {\r\n position: absolute;\r\n inset: 0;\r\n background: rgba(0, 0, 0, 0.6);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n pointer-events: none;\r\n }\r\n\r\n .more-text {\r\n color: white;\r\n font-size: 32px;\r\n font-weight: 600;\r\n font-family: var(--ds-font-family-medium);\r\n }\r\n\r\n /* 1 image: full width, 4:3 ratio */\r\n .photo-grid[data-count=\"1\"] {\r\n grid-template-columns: 1fr;\r\n }\r\n \r\n .photo-grid[data-count=\"1\"] .photo-item {\r\n aspect-ratio: 4/3;\r\n }\r\n\r\n /* 2 images: side by side */\r\n .photo-grid[data-count=\"2\"] {\r\n grid-template-columns: 1fr 1fr;\r\n }\r\n\r\n /* 3 images: 1 large left, 2 stacked right */\r\n .photo-grid[data-count=\"3\"] {\r\n grid-template-columns: 2fr 1fr;\r\n grid-auto-rows: 1fr;\r\n }\r\n \r\n .photo-grid[data-count=\"3\"] .photo-item:first-child {\r\n grid-row: 1 / 3;\r\n aspect-ratio: auto;\r\n }\r\n \r\n /* Right side images remain 1:1 squares */\r\n .photo-grid[data-count=\"3\"] .photo-item:nth-child(2),\r\n .photo-grid[data-count=\"3\"] .photo-item:nth-child(3) {\r\n aspect-ratio: 1;\r\n }\r\n\r\n /* 4 images: 2x2 grid */\r\n .photo-grid[data-count=\"4\"] {\r\n grid-template-columns: 1fr 1fr;\r\n grid-template-rows: 1fr 1fr;\r\n }\r\n\r\n /* 5 images: 2 on top, 3 on bottom */\r\n .photo-grid[data-count=\"5\"] {\r\n grid-template-columns: repeat(6, 1fr);\r\n grid-template-rows: auto auto;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item {\r\n aspect-ratio: 1;\r\n width: 100%;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(1) {\r\n grid-column: 1 / 4;\r\n grid-row: 1;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(2) {\r\n grid-column: 4 / 7;\r\n grid-row: 1;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(3) {\r\n grid-column: 1 / 3;\r\n grid-row: 2;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(4) {\r\n grid-column: 3 / 5;\r\n grid-row: 2;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(5) {\r\n grid-column: 5 / 7;\r\n grid-row: 2;\r\n }\r\n\r\n /* Round bottom corners for 5-image layout */\r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(3) {\r\n border-bottom-left-radius: 8px;\r\n overflow: hidden;\r\n }\r\n \r\n .photo-grid[data-count=\"5\"] .photo-item:nth-child(5) {\r\n border-bottom-right-radius: 8px;\r\n overflow: hidden;\r\n }\r\n\r\n /* ============================================\r\n FLEX LAYOUT (when useGrid is false)\r\n ============================================ */\r\n \r\n .photo-grid.flex-layout {\r\n display: flex;\r\n flex-wrap: wrap;\r\n gap: 8px;\r\n border-radius: 0;\r\n background: transparent;\r\n }\r\n \r\n .photo-grid.flex-layout .photo-item {\r\n flex: 0 0 auto;\r\n width: 96px;\r\n height: 96px;\r\n aspect-ratio: 1;\r\n border-radius: 8px;\r\n overflow: hidden;\r\n }\r\n \r\n .photo-grid.flex-layout .photo-item img {\r\n border-radius: 8px;\r\n }\r\n `]\r\n})\r\nexport class DsMobileInlinePhotoComponent implements OnInit {\r\n /**\r\n * Array of image URLs to display\r\n */\r\n @Input() images: string[] = [];\r\n\r\n /**\r\n * Optional array of loading states for each image (by index)\r\n * If provided, shows loader overlay for images that are still loading\r\n */\r\n @Input() loadingStates?: boolean[];\r\n\r\n /**\r\n * Internal signal to track image loading states\r\n */\r\n private internalLoadingStates = signal<Map<number, boolean>>(new Map());\r\n\r\n /**\r\n * Author information (passed to lightbox)\r\n */\r\n @Input() author?: {\r\n name: string;\r\n role?: string;\r\n avatarSrc?: string;\r\n avatarInitials?: string;\r\n avatarType?: 'photo' | 'initials';\r\n timestamp?: string;\r\n };\r\n\r\n /**\r\n * Maximum number of images to show inline (default: 5)\r\n * Remaining images shown in lightbox only\r\n */\r\n @Input() maxVisible: number = 5;\r\n\r\n /**\r\n * Whether to use grid layout (true) or flex-wrap layout (false)\r\n * @default true\r\n */\r\n @Input() useGrid: boolean = true;\r\n\r\n /**\r\n * Event emitted when lightbox is opened\r\n */\r\n photoClick = output<{ index: number; totalImages: number }>();\r\n\r\n constructor(private lightboxService: DsMobileLightboxService) {}\r\n\r\n /**\r\n * Initialize loading states for all visible images\r\n */\r\n ngOnInit(): void {\r\n // Set all images as loading initially\r\n const loadingMap = new Map<number, boolean>();\r\n this.visibleImages.forEach((_, index) => {\r\n loadingMap.set(index, true);\r\n });\r\n this.internalLoadingStates.set(loadingMap);\r\n }\r\n\r\n /**\r\n * Handle image load event\r\n */\r\n onImageLoad(index: number): void {\r\n const loadingMap = new Map(this.internalLoadingStates());\r\n loadingMap.set(index, false);\r\n this.internalLoadingStates.set(loadingMap);\r\n }\r\n\r\n /**\r\n * Handle image error event\r\n */\r\n onImageError(index: number): void {\r\n const loadingMap = new Map(this.internalLoadingStates());\r\n loadingMap.set(index, false);\r\n this.internalLoadingStates.set(loadingMap);\r\n }\r\n\r\n /**\r\n * Get the first N images to display inline\r\n */\r\n get visibleImages(): string[] {\r\n return this.images.slice(0, this.maxVisible);\r\n }\r\n\r\n /**\r\n * Check if a specific image is loading\r\n */\r\n isImageLoading(index: number): boolean {\r\n // Use external loadingStates if provided, otherwise use internal state\r\n if (this.loadingStates !== undefined) {\r\n return this.loadingStates[index] ?? false;\r\n }\r\n return this.internalLoadingStates().get(index) ?? true;\r\n }\r\n\r\n /**\r\n * Calculate how many images are hidden\r\n */\r\n get hiddenCount(): number {\r\n return Math.max(0, this.images.length - this.maxVisible);\r\n }\r\n\r\n /**\r\n * Open lightbox with all images, starting at the clicked index\r\n */\r\n openLightbox(index: number, event?: Event): void {\r\n // Stop event propagation to prevent triggering parent click handlers\r\n if (event) {\r\n event.stopPropagation();\r\n event.preventDefault();\r\n }\r\n\r\n // Emit event\r\n this.photoClick.emit({\r\n index,\r\n totalImages: this.images.length\r\n });\r\n\r\n // Convert image URLs to LightboxImage format\r\n const lightboxImages: LightboxImage[] = this.images.map((src, i) => ({\r\n type: 'image',\r\n src,\r\n alt: `Photo ${i + 1}`\r\n }));\r\n\r\n // Open lightbox with all images (not just visible ones)\r\n this.lightboxService.openImages({\r\n images: lightboxImages,\r\n initialIndex: index,\r\n author: this.author,\r\n enableZoom: true,\r\n showControls: true,\r\n enableSwipe: true\r\n });\r\n }\r\n}\r\n\r\n","import { Injectable, Type } from '@angular/core';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\n\r\n/**\r\n * Configuration options for modal presentation\r\n */\r\nexport interface ModalOptions<T = any> {\r\n /** The component to display in the modal */\r\n component: Type<T>;\r\n /** Props to pass to the component */\r\n componentProps?: Record<string, any>;\r\n /** CSS class(es) to apply to the modal */\r\n cssClass?: string | string[];\r\n /** Modal presentation style */\r\n presentationStyle?: 'fullscreen' | 'card' | 'sheet';\r\n /** Enable backdrop dismiss (tap outside to close) */\r\n backdropDismiss?: boolean;\r\n /** Show backdrop */\r\n showBackdrop?: boolean;\r\n /** Enable keyboard close (ESC key) */\r\n keyboardClose?: boolean;\r\n /** Enable swipe to close */\r\n swipeToClose?: boolean;\r\n /** Initial breakpoint (0-1) for sheet presentation */\r\n initialBreakpoint?: number;\r\n /** Available breakpoints for sheet presentation */\r\n breakpoints?: number[];\r\n /** Animation type */\r\n animated?: boolean;\r\n /** Mode (ios or md) */\r\n mode?: 'ios' | 'md';\r\n /** Whether to handle navigation back button */\r\n handleNavigationBack?: boolean;\r\n}\r\n\r\n/**\r\n * DsMobileModalService\r\n *\r\n * Generic service for displaying any component as a modal.\r\n * Built on Ionic's modal system with customizable presentation styles.\r\n *\r\n * Features:\r\n * - Open any component as a modal\r\n * - Fullscreen, card, or sheet presentation styles\r\n * - Customizable backdrop and dismissal behavior\r\n * - Native gestures and animations\r\n * - Type-safe component props\r\n *\r\n * @example\r\n * ```typescript\r\n * import { MobilePostDetailPageComponent } from './post-detail.page';\r\n *\r\n * constructor(private modal: DsMobileModalService) {}\r\n *\r\n * async openPostModal() {\r\n * await this.modal.open({\r\n * component: MobilePostDetailPageComponent,\r\n * componentProps: {\r\n * postId: '123',\r\n * authorName: 'John Doe'\r\n * },\r\n * presentationStyle: 'card',\r\n * backdropDismiss: true\r\n * });\r\n * }\r\n * ```\r\n *\r\n * @example Sheet presentation with breakpoints\r\n * ```typescript\r\n * async openSheet() {\r\n * await this.modal.open({\r\n * component: CommentsComponent,\r\n * presentationStyle: 'sheet',\r\n * initialBreakpoint: 0.5,\r\n * breakpoints: [0, 0.5, 0.75, 1],\r\n * swipeToClose: true\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class DsMobileModalService {\r\n constructor(private modalController: ModalController) {}\r\n\r\n /**\r\n * Open a component as a modal\r\n *\r\n * @param options Configuration options for the modal\r\n * @returns Promise that resolves when the modal is presented\r\n *\r\n * @example\r\n * ```typescript\r\n * await this.modal.open({\r\n * component: MyComponent,\r\n * componentProps: { data: 'value' },\r\n * presentationStyle: 'fullscreen'\r\n * });\r\n * ```\r\n */\r\n async open<T = any>(options: ModalOptions<T>): Promise<HTMLIonModalElement> {\r\n // console.log('[Modal] Opening modal with options:', options);\r\n\r\n const {\r\n component,\r\n componentProps,\r\n cssClass,\r\n presentationStyle = 'card',\r\n backdropDismiss = true,\r\n showBackdrop = true,\r\n keyboardClose = true,\r\n swipeToClose,\r\n initialBreakpoint,\r\n breakpoints,\r\n animated = true,\r\n mode = 'ios',\r\n handleNavigationBack = true,\r\n } = options;\r\n\r\n // Build modal configuration\r\n const modalConfig: any = {\r\n component,\r\n componentProps: componentProps || {},\r\n cssClass: this.buildCssClasses(cssClass, presentationStyle),\r\n mode,\r\n backdropDismiss,\r\n showBackdrop,\r\n animated,\r\n keyboardClose,\r\n presentingElement:\r\n document.querySelector('ion-router-outlet') || undefined,\r\n handle: presentationStyle === 'sheet', // Show handle for sheet presentation\r\n };\r\n\r\n // Add swipe to close for sheet presentation\r\n if (swipeToClose !== undefined) {\r\n modalConfig.canDismiss = swipeToClose;\r\n }\r\n\r\n // Add breakpoints for sheet presentation\r\n if (presentationStyle === 'sheet' && breakpoints) {\r\n modalConfig.breakpoints = breakpoints;\r\n if (initialBreakpoint !== undefined) {\r\n modalConfig.initialBreakpoint = initialBreakpoint;\r\n }\r\n }\r\n\r\n // Handle navigation back button\r\n if (handleNavigationBack) {\r\n modalConfig.canDismiss = async () => {\r\n // You can add custom logic here if needed\r\n return true;\r\n };\r\n }\r\n\r\n const modal = await this.modalController.create(modalConfig);\r\n\r\n // console.log('[Modal] Modal created, presenting...');\r\n await modal.present();\r\n // console.log('[Modal] Modal presented');\r\n\r\n return modal;\r\n }\r\n\r\n /**\r\n * Open a component as a fullscreen modal\r\n *\r\n * @param component Component to display\r\n * @param componentProps Props to pass to the component\r\n * @returns Promise that resolves when the modal is presented\r\n *\r\n * @example\r\n * ```typescript\r\n * await this.modal.openFullscreen(PostDetailPage, { postId: '123' });\r\n * ```\r\n */\r\n async openFullscreen<T = any>(\r\n component: Type<T>,\r\n componentProps?: Record<string, any>\r\n ): Promise<HTMLIonModalElement> {\r\n return this.open({\r\n component,\r\n componentProps,\r\n presentationStyle: 'fullscreen',\r\n backdropDismiss: false,\r\n showBackdrop: false,\r\n });\r\n }\r\n\r\n /**\r\n * Open a component as a card modal\r\n *\r\n * @param component Component to display\r\n * @param componentProps Props to pass to the component\r\n * @returns Promise that resolves when the modal is presented\r\n *\r\n * @example\r\n * ```typescript\r\n * await this.modal.openCard(DetailComponent, { itemId: '456' });\r\n * ```\r\n */\r\n async openCard<T = any>(\r\n component: Type<T>,\r\n componentProps?: Record<string, any>\r\n ): Promise<HTMLIonModalElement> {\r\n return this.open({\r\n component,\r\n componentProps,\r\n presentationStyle: 'card',\r\n backdropDismiss: true,\r\n showBackdrop: true,\r\n });\r\n }\r\n\r\n /**\r\n * Open a component as a bottom sheet\r\n *\r\n * @param component Component to display\r\n * @param componentProps Props to pass to the component\r\n * @param options Additional sheet options (breakpoints, etc.)\r\n * @returns Promise that resolves when the modal is presented\r\n *\r\n * @example\r\n * ```typescript\r\n * await this.modal.openSheet(\r\n * CommentsComponent,\r\n * { postId: '789' },\r\n * { initialBreakpoint: 0.5, breakpoints: [0, 0.5, 1] }\r\n * );\r\n * ```\r\n */\r\n async openSheet<T = any>(\r\n component: Type<T>,\r\n componentProps?: Record<string, any>,\r\n options?: {\r\n initialBreakpoint?: number;\r\n breakpoints?: number[];\r\n swipeToClose?: boolean;\r\n }\r\n ): Promise<HTMLIonModalElement> {\r\n return this.open({\r\n component,\r\n componentProps,\r\n presentationStyle: 'sheet',\r\n backdropDismiss: true,\r\n showBackdrop: true,\r\n swipeToClose: options?.swipeToClose ?? true,\r\n initialBreakpoint: options?.initialBreakpoint ?? 0.5,\r\n breakpoints: options?.breakpoints ?? [0, 0.5, 0.75, 1],\r\n });\r\n }\r\n\r\n /**\r\n * Close the currently open modal\r\n *\r\n * @param data Optional data to pass back when dismissing\r\n * @param role Optional role (e.g., 'cancel', 'confirm')\r\n * @returns Promise that resolves when the modal is dismissed\r\n *\r\n * @example\r\n * ```typescript\r\n * await this.modal.dismiss({ saved: true }, 'confirm');\r\n * ```\r\n */\r\n async dismiss(data?: any, role?: string): Promise<boolean> {\r\n return this.modalController.dismiss(data, role);\r\n }\r\n\r\n /**\r\n * Get the top-most modal if one exists\r\n *\r\n * @returns Promise that resolves to the modal element or undefined\r\n *\r\n * @example\r\n * ```typescript\r\n * const topModal = await this.modal.getTop();\r\n * if (topModal) {\r\n * await topModal.dismiss();\r\n * }\r\n * ```\r\n */\r\n async getTop(): Promise<HTMLIonModalElement | undefined> {\r\n return this.modalController.getTop();\r\n }\r\n\r\n /**\r\n * Get all currently open modals\r\n *\r\n * @returns Promise that resolves to an array of modal elements\r\n */\r\n async getAll(): Promise<HTMLIonModalElement[]> {\r\n const modals: HTMLIonModalElement[] = [];\r\n let modal = await this.modalController.getTop();\r\n\r\n while (modal) {\r\n modals.push(modal);\r\n // Get the next modal in the stack\r\n await modal.dismiss();\r\n modal = await this.modalController.getTop();\r\n }\r\n\r\n return modals;\r\n }\r\n\r\n /**\r\n * Build CSS classes for the modal\r\n */\r\n private buildCssClasses(\r\n customClass?: string | string[],\r\n presentationStyle?: string\r\n ): string[] {\r\n const classes: string[] = ['ds-mobile-modal'];\r\n\r\n if (presentationStyle) {\r\n classes.push(`ds-modal-${presentationStyle}`);\r\n }\r\n\r\n if (customClass) {\r\n if (Array.isArray(customClass)) {\r\n classes.push(...customClass);\r\n } else {\r\n classes.push(customClass);\r\n }\r\n }\r\n\r\n return classes;\r\n }\r\n}\r\n","/**\r\n * Mobile Modal Module\r\n * \r\n * Generic service for opening any component as a modal\r\n */\r\n\r\nexport * from './ds-mobile-modal.service';\r\n\r\n","import { input, output, Directive, OnInit, OnDestroy, inject, ViewChild } from '@angular/core';\r\nimport { ModalController, IonContent } from '@ionic/angular/standalone';\r\nimport { Keyboard } from '@capacitor/keyboard';\r\n\r\n/**\r\n * MobileModalBase\r\n *\r\n * Shared base class for mobile modal components.\r\n * Provides consistent modal behavior, state management, and keyboard handling.\r\n *\r\n * **Key Features:**\r\n * - Loading and error state management\r\n * - Header configuration (title, meta)\r\n * - Automatic keyboard height tracking (iOS/Android)\r\n * - Fixed bottom component support\r\n * - Consistent close behavior\r\n *\r\n * **Usage:**\r\n * ```typescript\r\n * export class MyModalComponent extends MobileModalBase {\r\n * constructor() {\r\n * super();\r\n * }\r\n * }\r\n * ```\r\n *\r\n * @internal This is a base class and should not be used directly.\r\n */\r\n@Directive()\r\nexport abstract class MobileModalBase implements OnInit, OnDestroy {\r\n protected modalController = inject(ModalController);\r\n\r\n /**\r\n * Reference to IonContent for accessing scroll element\r\n */\r\n @ViewChild(IonContent, { read: IonContent }) protected ionContent?: IonContent;\r\n\r\n /**\r\n * ResizeObserver for tracking fixed bottom height\r\n */\r\n private fixedBottomObserver?: ResizeObserver;\r\n\r\n /**\r\n * Flag to prevent ResizeObserver from updating padding during keyboard animations\r\n */\r\n private isKeyboardAnimating = false;\r\n\r\n /**\r\n * Loading state - when true, shows loading indicator\r\n * @default false\r\n */\r\n loading = input<boolean>(false);\r\n\r\n /**\r\n * Error state - when set, shows error message\r\n * @default undefined\r\n */\r\n error = input<string | undefined>();\r\n\r\n /**\r\n * Modal header title\r\n * @default ''\r\n */\r\n headerTitle = input<string>('');\r\n\r\n /**\r\n * Modal header metadata (subtitle/secondary text)\r\n * @default ''\r\n */\r\n headerMeta = input<string>('');\r\n\r\n /**\r\n * Accessibility label for close button\r\n * @default 'Close'\r\n */\r\n closeButtonLabel = input<string>('Close');\r\n\r\n /**\r\n * Enable automatic keyboard height tracking\r\n * When enabled, sets --keyboard-height CSS variable for sliding content\r\n * @default false\r\n */\r\n enableKeyboardHandling = input<boolean>(false);\r\n\r\n /**\r\n * Whether modal has a fixed bottom component\r\n * Used to manage spacing and keyboard interactions\r\n * @default false\r\n */\r\n hasFixedBottom = input<boolean>(false);\r\n\r\n /**\r\n * Content padding for modal content\r\n * Controls padding inside .modal-main-content\r\n * - '0' (default) - No padding, use ds-mobile-section for content organization\r\n * - '20px' - Legacy padding for content without sections\r\n * - Any custom CSS padding value\r\n *\r\n * @default '0'\r\n */\r\n contentPadding = input<string>('0');\r\n\r\n /**\r\n * Enable auto-height behavior for bottom sheets\r\n * When true, sets [fullscreen]=\"false\" on ion-content and enforces flex: 0 0 auto\r\n * @default false\r\n */\r\n isAutoHeight = input<boolean>(false);\r\n\r\n /**\r\n * Controls how modal content behaves when the keyboard opens.\r\n * - 'follow': content is pushed to follow keyboard movement\r\n * - 'overlay': keyboard/footer overlays lower content (no auto scroll push)\r\n * @default 'follow'\r\n */\r\n keyboardContentBehavior = input<'follow' | 'overlay'>('follow');\r\n\r\n /**\r\n * Emitted when modal is closed\r\n */\r\n closed = output<void>();\r\n\r\n /**\r\n * Emitted when keyboard is about to show\r\n * Provides keyboard height in pixels\r\n * Child components can listen to this to react to keyboard appearance\r\n */\r\n keyboardWillShow = output<number>();\r\n\r\n /**\r\n * Emitted when keyboard is about to hide\r\n * Child components can listen to this to react to keyboard dismissal\r\n */\r\n keyboardWillHide = output<void>();\r\n\r\n ngOnInit(): void {\r\n if (this.enableKeyboardHandling()) {\r\n this.setupKeyboardListeners();\r\n }\r\n\r\n if (this.hasFixedBottom()) {\r\n this.setupFixedBottomObserver();\r\n }\r\n }\r\n\r\n ngOnDestroy(): void {\r\n if (this.enableKeyboardHandling()) {\r\n this.cleanupKeyboardListeners();\r\n }\r\n\r\n if (this.fixedBottomObserver) {\r\n this.fixedBottomObserver.disconnect();\r\n }\r\n }\r\n\r\n /**\r\n * Close the modal\r\n * Emits closed event and dismisses the modal\r\n */\r\n close(): void {\r\n this.closed.emit();\r\n this.modalController.dismiss();\r\n }\r\n\r\n /**\r\n * Set up keyboard event listeners to adjust component position\r\n * Uses --keyboard-height for fixed bottom composer and adds padding to scroll area.\r\n * Adjusts scroll position so content smoothly follows the keyboard up (like Messenger/Telegram).\r\n * Only responds if this modal is the currently active (top-most) modal.\r\n * @protected\r\n */\r\n protected setupKeyboardListeners(): void {\r\n Keyboard.addListener('keyboardWillShow', async (info) => {\r\n // Check if this modal is the top-most modal\r\n const topModal = await this.modalController.getTop();\r\n if (!topModal || !this.isThisModal(topModal)) {\r\n // console.log('[MobileModalBase] Keyboard event ignored - not top modal');\r\n return; // Not the active modal, ignore keyboard event\r\n }\r\n \r\n // console.log('[MobileModalBase] 🎹 Keyboard showing, height:', info.keyboardHeight);\r\n // Set flag to prevent ResizeObserver from interfering\r\n this.isKeyboardAnimating = true;\r\n\r\n // Set global keyboard height FIRST so ResizeObserver can use it\r\n document.documentElement.style.setProperty('--keyboard-height', `${info.keyboardHeight}px`);\r\n\r\n // Update padding immediately to include keyboard height\r\n if (this.ionContent) {\r\n try {\r\n const scrollElement = await this.ionContent.getScrollElement();\r\n if (scrollElement) {\r\n // Get current fixed bottom height and add keyboard height\r\n const fixedBottomHeight = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--fixed-bottom-height') || '0');\r\n const totalPadding = this.getScrollPadding(fixedBottomHeight, info.keyboardHeight);\r\n scrollElement.style.paddingBottom = `${totalPadding}px`;\r\n // console.log('[MobileModalBase] Updated padding:', totalPadding, '(fixed:', fixedBottomHeight, '+ keyboard:', info.keyboardHeight, ')');\r\n\r\n // In overlay mode, keep content stationary and let keyboard/footer overlap.\r\n if (this.isOverlayBehavior()) {\r\n this.isKeyboardAnimating = false;\r\n } else {\r\n // Store current scroll position before keyboard animation\r\n const currentScrollTop = scrollElement.scrollTop;\r\n // Animate scroll position to match keyboard\r\n const startTime = performance.now();\r\n const duration = 300; // Match keyboard animation duration\r\n\r\n const animateScroll = (currentTime: number) => {\r\n const elapsed = currentTime - startTime;\r\n const progress = Math.min(elapsed / duration, 1);\r\n\r\n // Ease-out cubic (matches iOS/Android keyboard animation curve)\r\n const easeProgress = 1 - Math.pow(1 - progress, 3);\r\n\r\n // Scroll down by keyboard height so content \"follows\" keyboard up\r\n scrollElement.scrollTop = currentScrollTop + info.keyboardHeight * easeProgress;\r\n\r\n if (progress < 1) {\r\n requestAnimationFrame(animateScroll);\r\n } else {\r\n // Animation complete - re-enable ResizeObserver\r\n // console.log('[MobileModalBase] ✅ Keyboard animation complete');\r\n this.isKeyboardAnimating = false;\r\n }\r\n };\r\n\r\n requestAnimationFrame(animateScroll);\r\n }\r\n }\r\n } catch (e) {\r\n // console.log('[MobileModalBase] Could not access scroll element:', e);\r\n this.isKeyboardAnimating = false;\r\n }\r\n } else {\r\n this.isKeyboardAnimating = false;\r\n }\r\n\r\n // Emit event for child components to react to keyboard appearance\r\n this.keyboardWillShow.emit(info.keyboardHeight);\r\n }).catch((e) => {\r\n // console.log('[MobileModalBase] Keyboard listeners not available:', e);\r\n });\r\n\r\n Keyboard.addListener('keyboardWillHide', async () => {\r\n // Check if this modal is the top-most modal\r\n const topModal = await this.modalController.getTop();\r\n if (!topModal || !this.isThisModal(topModal)) {\r\n // console.log('[MobileModalBase] Keyboard hide event ignored - not top modal');\r\n return; // Not the active modal, ignore keyboard event\r\n }\r\n \r\n // console.log('[MobileModalBase] 🎹 Keyboard hiding');\r\n // Set flag to prevent ResizeObserver from interfering\r\n this.isKeyboardAnimating = true;\r\n\r\n // Get keyboard height before resetting (for scroll position adjustment)\r\n const keyboardHeight = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--keyboard-height') || '0');\r\n\r\n // Reset keyboard height variable FIRST\r\n document.documentElement.style.setProperty('--keyboard-height', '0px');\r\n\r\n // Update padding immediately to remove keyboard height\r\n if (this.ionContent) {\r\n try {\r\n const scrollElement = await this.ionContent.getScrollElement();\r\n if (scrollElement) {\r\n // Get current fixed bottom height (without keyboard)\r\n const fixedBottomHeight = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--fixed-bottom-height') || '0');\r\n const totalPadding = this.getScrollPadding(fixedBottomHeight, 0);\r\n scrollElement.style.paddingBottom = `${totalPadding}px`;\r\n // console.log('[MobileModalBase] Removed keyboard padding, now:', fixedBottomHeight);\r\n\r\n // In overlay mode, keep content stationary and let keyboard/footer overlap.\r\n if (this.isOverlayBehavior()) {\r\n this.isKeyboardAnimating = false;\r\n } else {\r\n // Store current scroll position\r\n const currentScrollTop = scrollElement.scrollTop;\r\n // Animate scroll position back\r\n const startTime = performance.now();\r\n const duration = 300;\r\n\r\n const animateScroll = (currentTime: number) => {\r\n const elapsed = currentTime - startTime;\r\n const progress = Math.min(elapsed / duration, 1);\r\n\r\n // Ease-out cubic\r\n const easeProgress = 1 - Math.pow(1 - progress, 3);\r\n\r\n // Scroll up by keyboard height (reverse the push)\r\n const newScrollTop = currentScrollTop - keyboardHeight * easeProgress;\r\n scrollElement.scrollTop = Math.max(0, newScrollTop);\r\n\r\n if (progress < 1) {\r\n requestAnimationFrame(animateScroll);\r\n } else {\r\n // Animation complete - re-enable ResizeObserver\r\n // console.log('[MobileModalBase] ✅ Keyboard hide animation complete');\r\n this.isKeyboardAnimating = false;\r\n }\r\n };\r\n\r\n requestAnimationFrame(animateScroll);\r\n }\r\n }\r\n } catch (e) {\r\n // console.log('[MobileModalBase] Could not access scroll element:', e);\r\n this.isKeyboardAnimating = false;\r\n }\r\n } else {\r\n this.isKeyboardAnimating = false;\r\n }\r\n\r\n // Emit event for child components to react to keyboard dismissal\r\n this.keyboardWillHide.emit();\r\n }).catch((e) => {\r\n // console.log('[MobileModalBase] Keyboard listeners not available:', e);\r\n });\r\n }\r\n\r\n /**\r\n * Set up ResizeObserver to track fixed bottom height and apply as CSS variable\r\n * This allows dynamic bottom padding that adjusts to content\r\n * @protected\r\n */\r\n protected async setupFixedBottomObserver(): Promise<void> {\r\n // Use measured fixed-bottom height directly; safe-area tuning is handled in CSS.\r\n const offset = 0;\r\n\r\n // Small delay to ensure DOM is ready\r\n setTimeout(async () => {\r\n const fixedBottom = document.querySelector('.modal-fixed-bottom');\r\n // console.log('[MobileModalBase] Fixed bottom element:', fixedBottom, 'Offset:', offset);\r\n\r\n if (fixedBottom) {\r\n this.fixedBottomObserver = new ResizeObserver(async (entries) => {\r\n // Skip updates during keyboard animations to prevent conflicts\r\n if (this.isKeyboardAnimating) {\r\n // console.log('[MobileModalBase] 🚫 ResizeObserver - skipping update during keyboard animation');\r\n return;\r\n }\r\n\r\n // console.log('[MobileModalBase] ✅ ResizeObserver - processing update');\r\n for (const entry of entries) {\r\n // Use getBoundingClientRect to get full border-box height (includes padding)\r\n const height = (entry.target as HTMLElement).getBoundingClientRect().height;\r\n // Add platform-specific offset\r\n const totalHeight = height + offset;\r\n\r\n // CRITICAL: Include keyboard height if keyboard is visible!\r\n const keyboardHeight = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--keyboard-height') || '0');\r\n const paddingWithKeyboard = this.getScrollPadding(totalHeight, keyboardHeight);\r\n\r\n // console.log('[MobileModalBase] ResizeObserver - height:', height, 'totalHeight:', totalHeight, 'keyboard:', keyboardHeight, 'finalPadding:', paddingWithKeyboard);\r\n document.documentElement.style.setProperty('--fixed-bottom-height', `${totalHeight}px`);\r\n\r\n // Also update scroll element padding (including keyboard height!)\r\n if (this.ionContent) {\r\n try {\r\n const scrollElement = await this.ionContent.getScrollElement();\r\n if (scrollElement) {\r\n // Get PREVIOUS padding to calculate the difference\r\n const previousPadding = parseFloat(scrollElement.style.paddingBottom || '0');\r\n const paddingDifference = paddingWithKeyboard - previousPadding;\r\n\r\n // Update padding\r\n scrollElement.style.paddingBottom = `${paddingWithKeyboard}px`;\r\n\r\n // CRITICAL: Adjust scroll to maintain visual position\r\n // When padding increases, we need to scroll down by the same amount\r\n if (!this.isOverlayBehavior() && paddingDifference !== 0) {\r\n const currentScrollTop = scrollElement.scrollTop;\r\n scrollElement.scrollTop = currentScrollTop + paddingDifference;\r\n // console.log('[MobileModalBase] Adjusted scroll by', paddingDifference, 'px (from', currentScrollTop, 'to', scrollElement.scrollTop, ')');\r\n }\r\n }\r\n } catch (e) {\r\n // console.log('[MobileModalBase] Could not update scroll element padding:', e);\r\n }\r\n }\r\n }\r\n });\r\n\r\n this.fixedBottomObserver.observe(fixedBottom);\r\n\r\n // Set initial height immediately (with platform-specific offset)\r\n const initialHeight = fixedBottom.getBoundingClientRect().height;\r\n const initialTotal = initialHeight + offset;\r\n // console.log('[MobileModalBase] Initial height:', initialHeight, 'initialTotal:', initialTotal);\r\n document.documentElement.style.setProperty('--fixed-bottom-height', `${initialTotal}px`);\r\n\r\n // Set initial scroll element padding\r\n if (this.ionContent) {\r\n try {\r\n const scrollElement = await this.ionContent.getScrollElement();\r\n if (scrollElement) {\r\n // Include keyboard height if present\r\n const keyboardHeight = parseFloat(getComputedStyle(document.documentElement).getPropertyValue('--keyboard-height') || '0');\r\n const paddingWithKeyboard = this.getScrollPadding(initialTotal, keyboardHeight);\r\n scrollElement.style.paddingBottom = `${paddingWithKeyboard}px`;\r\n }\r\n } catch (e) {\r\n // console.log('[MobileModalBase] Could not set initial scroll element padding:', e);\r\n }\r\n }\r\n }\r\n }, 100);\r\n }\r\n\r\n /**\r\n * Clean up keyboard event listeners\r\n * @protected\r\n */\r\n protected cleanupKeyboardListeners(): void {\r\n Keyboard.removeAllListeners().catch((e) => {\r\n // console.log('[MobileModalBase] Keyboard cleanup not available:', e);\r\n });\r\n }\r\n\r\n /**\r\n * Check if the given modal element is this modal component's parent modal\r\n * @protected\r\n */\r\n protected isThisModal(modalElement: HTMLIonModalElement): boolean {\r\n // The modal element should contain this component\r\n // We traverse up from the component to find the ion-modal\r\n let element = document.querySelector('ds-mobile-modal-base')?.parentElement;\r\n while (element) {\r\n if (element === modalElement) {\r\n return true;\r\n }\r\n if (element.tagName === 'ION-MODAL') {\r\n return element === modalElement;\r\n }\r\n element = element.parentElement;\r\n }\r\n return false;\r\n }\r\n\r\n /**\r\n * Returns true when keyboard should overlay content without push-scrolling.\r\n */\r\n private isOverlayBehavior(): boolean {\r\n return this.keyboardContentBehavior() === 'overlay';\r\n }\r\n\r\n /**\r\n * Computes scroll bottom inset for current keyboard behavior.\r\n */\r\n private getScrollPadding(fixedBottomHeight: number, keyboardHeight: number): number {\r\n if (this.isOverlayBehavior()) {\r\n return fixedBottomHeight;\r\n }\r\n return fixedBottomHeight + keyboardHeight;\r\n }\r\n}\r\n","import { Component, ContentChild, ElementRef, CUSTOM_ELEMENTS_SCHEMA, AfterContentInit, ChangeDetectorRef, input, HostBinding, ViewChild, OnDestroy, OnInit } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { IonContent } from '@ionic/angular/standalone';\r\nimport { DsIconButtonComponent, DsIconComponent } from '@propbinder/design-system';\r\nimport { MobileModalBase } from '../shared/mobile-modal-base';\r\n\r\n/**\r\n * DsMobileModalBaseComponent\r\n * \r\n * Base modal component providing consistent layout and behavior for all modals.\r\n * \r\n * **Features:**\r\n * - Optional header with auto-detection of content\r\n * - Flexible header with slots for leading content (avatar, icon)\r\n * - Title and metadata inputs or custom header slot\r\n * - Default loading and error state templates (with override capability)\r\n * - Fixed bottom component support (e.g., message composer)\r\n * - Automatic keyboard handling\r\n * - Configurable keyboard content behavior (`follow` or `overlay`)\r\n * - Safe area support\r\n * \r\n * **Slot Structure:**\r\n * - `[header-leading]` - Left side of header (avatar, icon)\r\n * - `[header-main]` - Custom header content (replaces title/meta)\r\n * - `[loading-state]` - Custom loading template\r\n * - `[error-state]` - Custom error template\r\n * - `[footer]` or `[fixed-bottom]` - Fixed bottom component (slides with keyboard)\r\n * - Default slot - Main modal content\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Simple title modal -->\r\n * <ds-mobile-modal-base \r\n * headerTitle=\"Settings\"\r\n * closeButtonLabel=\"Close\">\r\n * <div class=\"content\">...</div>\r\n * </ds-mobile-modal-base>\r\n * \r\n * <!-- Avatar header modal -->\r\n * <ds-mobile-modal-base\r\n * headerTitle=\"John Doe\"\r\n * headerMeta=\"Tenant · 2h ago\"\r\n * [hasFixedBottom]=\"true\"\r\n * [enableKeyboardHandling]=\"true\">\r\n * \r\n * <ds-avatar header-leading [initials]=\"'JD'\" size=\"md\" />\r\n * \r\n * <div class=\"content\">...</div>\r\n * \r\n * <div fixed-bottom class=\"composer\">...</div>\r\n * </ds-mobile-modal-base>\r\n * \r\n * <!-- Headerless modal (close button positioned absolutely) -->\r\n * <ds-mobile-modal-base [showHeader]=\"false\">\r\n * <div class=\"full-width-content\">...</div>\r\n * </ds-mobile-modal-base>\r\n * \r\n * <!-- Modal with footer actions (slides with keyboard) -->\r\n * <ds-mobile-modal-base\r\n * headerTitle=\"Create Inquiry\"\r\n * [hasFixedBottom]=\"true\"\r\n * [enableKeyboardHandling]=\"true\"\r\n * [keyboardContentBehavior]=\"'overlay'\">\r\n * \r\n * <div class=\"content\">\r\n * <input type=\"text\" placeholder=\"Type something...\" />\r\n * </div>\r\n * \r\n * <div footer class=\"action-bar\">\r\n * <button>Cancel</button>\r\n * <button>Submit</button>\r\n * </div>\r\n * </ds-mobile-modal-base>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-modal-base',\r\n standalone: true,\r\n imports: [CommonModule, IonContent, DsIconButtonComponent, DsIconComponent],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n styleUrls: ['./ds-mobile-modal-base.css'],\r\n host: {\r\n '[style.--modal-content-padding]': 'contentPadding()',\r\n '[class.is-auto-height]': 'isAutoHeight()',\r\n },\r\n template: `\r\n <ion-content\r\n [fullscreen]=\"!isAutoHeight()\"\r\n [scrollY]=\"true\"\r\n [class.is-auto-height]=\"isAutoHeight()\"\r\n class=\"modal-base-content\"\r\n [style.--padding-bottom]=\"contentPadding() || (hasFixedBottom() ? 'var(--fixed-bottom-height)' : '24px')\"\r\n >\r\n <div class=\"modal-wrapper\" [class.headerless]=\"!shouldShowHeader()\" [class.is-auto-height]=\"isAutoHeight()\">\r\n <!-- Header (conditional) -->\r\n @if (shouldShowHeader()) {\r\n <div class=\"modal-header\" [class.no-leading-content]=\"!hasHeaderLeadingContent()\">\r\n <div class=\"header-content\">\r\n <!-- Leading slot (avatar, icon) - always rendered, CSS handles empty state -->\r\n <div class=\"header-leading\">\r\n <ng-content select=\"[header-leading]\"></ng-content>\r\n </div>\r\n\r\n <!-- Main (title + meta or custom) -->\r\n <div class=\"header-main\">\r\n @if (headerTitle()) {\r\n <div class=\"modal-title\">{{ headerTitle() }}</div>\r\n }\r\n @if (headerMeta()) {\r\n <div class=\"modal-meta\">{{ headerMeta() }}</div>\r\n }\r\n <ng-content select=\"[header-main]\"></ng-content>\r\n </div>\r\n\r\n <!-- Close button (in header) -->\r\n <ds-icon-button icon=\"remixCloseLine\" variant=\"secondary\" size=\"lg\" (clicked)=\"close()\" class=\"close-button\" [attr.aria-label]=\"closeButtonLabel()\" />\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Absolute close button (when header is hidden) -->\r\n @if (!shouldShowHeader()) {\r\n <ds-icon-button icon=\"remixCloseLine\" variant=\"secondary\" size=\"lg\" (clicked)=\"close()\" class=\"close-button-absolute\" [attr.aria-label]=\"closeButtonLabel()\" />\r\n }\r\n\r\n <!-- Content Container -->\r\n <div class=\"modal-content-container\">\r\n <!-- Custom Loading State Slot - always present -->\r\n <div class=\"custom-loading-slot\" [class.state-hidden]=\"!(loading() && hasCustomLoadingState)\">\r\n <ng-content select=\"[loading-state]\"></ng-content>\r\n </div>\r\n\r\n <!-- Default Loading State -->\r\n @if (loading() && !hasCustomLoadingState) {\r\n <div class=\"modal-loading-state\">\r\n <div class=\"loading-spinner\"></div>\r\n <p class=\"loading-text\">Loading...</p>\r\n </div>\r\n }\r\n\r\n <!-- Custom Error State Slot - always present -->\r\n <div class=\"custom-error-slot\" [class.state-hidden]=\"!(error() && !loading() && hasCustomErrorState)\">\r\n <ng-content select=\"[error-state]\"></ng-content>\r\n </div>\r\n\r\n <!-- Default Error State -->\r\n @if (error() && !loading() && !hasCustomErrorState) {\r\n <div class=\"modal-error-state\">\r\n <ds-icon name=\"remixErrorWarningLine\" size=\"48px\" [style.color]=\"'var(--color-destructive-base)'\" />\r\n <h3 class=\"error-state-title\">Error</h3>\r\n <p class=\"error-state-description\">{{ error() }}</p>\r\n </div>\r\n }\r\n\r\n <!-- Main content - always rendered but hidden when loading/error -->\r\n <div class=\"modal-main-content\" [class.content-hidden]=\"loading() || !!error()\">\r\n <ng-content></ng-content>\r\n </div>\r\n </div>\r\n </div>\r\n </ion-content>\r\n\r\n <!-- Fixed Bottom Component / Footer (slides with keyboard) -->\r\n <div class=\"modal-fixed-bottom\" [class.bottom-hidden]=\"!hasFixedBottom() || loading() || error()\" [class.is-auto-height]=\"isAutoHeight()\">\r\n <ng-content select=\"[fixed-bottom]\"></ng-content>\r\n <ng-content select=\"[footer]\"></ng-content>\r\n </div>\r\n `,\r\n})\r\nexport class DsMobileModalBaseComponent extends MobileModalBase implements OnInit, AfterContentInit, OnDestroy {\r\n /**\r\n * Reference to ion-content for keyboard handling\r\n */\r\n @ViewChild(IonContent, { read: IonContent }) override ionContent?: IonContent = undefined;\r\n\r\n /**\r\n * Control header visibility\r\n * - true: Always show header\r\n * - false: Never show header (close button becomes absolute)\r\n * - 'auto' (default): Auto-detect based on header content\r\n */\r\n showHeader = input<boolean | 'auto'>('auto');\r\n\r\n /**\r\n * Detect if custom loading state is provided\r\n */\r\n @ContentChild('[loading-state]', { read: ElementRef }) customLoadingState?: ElementRef;\r\n\r\n /**\r\n * Detect if custom error state is provided\r\n */\r\n @ContentChild('[error-state]', { read: ElementRef }) customErrorState?: ElementRef;\r\n\r\n /**\r\n * Detect if header leading content is provided\r\n */\r\n @ContentChild('[header-leading]', { read: ElementRef }) headerLeading?: ElementRef;\r\n\r\n /**\r\n * Detect if header main content is provided\r\n */\r\n @ContentChild('[header-main]', { read: ElementRef }) headerMain?: ElementRef;\r\n\r\n /**\r\n * Flag to track if content has been initialized\r\n */\r\n hasCustomLoadingState = false;\r\n hasCustomErrorState = false;\r\n\r\n constructor(private cdr: ChangeDetectorRef) {\r\n super();\r\n }\r\n\r\n override ngOnInit(): void {\r\n // Call parent to set up keyboard listeners and ResizeObserver\r\n super.ngOnInit();\r\n }\r\n\r\n ngAfterContentInit(): void {\r\n // Check for content after content has been initialized\r\n this.hasCustomLoadingState = !!this.customLoadingState;\r\n this.hasCustomErrorState = !!this.customErrorState;\r\n\r\n // Trigger change detection to update the view\r\n this.cdr.detectChanges();\r\n }\r\n\r\n override ngOnDestroy(): void {\r\n super.ngOnDestroy();\r\n }\r\n\r\n /**\r\n * Determine if header should be shown based on showHeader input and content detection\r\n */\r\n shouldShowHeader(): boolean {\r\n const showHeaderValue = this.showHeader();\r\n\r\n // Explicit override\r\n if (showHeaderValue === true) return true;\r\n if (showHeaderValue === false) return false;\r\n\r\n // Auto-detect: show header if there's any header content\r\n return !!(this.headerTitle() || this.headerMeta() || this.hasContentInSlot(this.headerLeading) || this.hasContentInSlot(this.headerMain));\r\n }\r\n\r\n /**\r\n * Check whether header-leading slot has actual projected content.\r\n */\r\n hasHeaderLeadingContent(): boolean {\r\n return this.hasContentInSlot(this.headerLeading);\r\n }\r\n\r\n /**\r\n * Check if a content child slot has actual content\r\n */\r\n private hasContentInSlot(slot?: ElementRef): boolean {\r\n if (!slot) return false;\r\n const element = slot.nativeElement;\r\n return element && (element.childNodes.length > 0 || element.textContent?.trim().length > 0);\r\n }\r\n}\r\n","import { Component, input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n/**\r\n * DsMobileEmptyStateComponent\r\n *\r\n * Reusable empty state component for displaying when there's no content.\r\n * Used in chat modals, comment sections, and other list-based views.\r\n *\r\n * Features:\r\n * - Optional image display\r\n * - Customizable title and description\r\n * - Consistent styling across the app\r\n * - Flexible image sizing\r\n *\r\n * @example\r\n * ```html\r\n * <!-- With image -->\r\n * <ds-mobile-empty-state\r\n * [imageSrc]=\"'/Assets/empty-state-inquiry.svg'\"\r\n * [imageAlt]=\"'No messages'\"\r\n * [title]=\"'Ingen beskeder endnu'\"\r\n * [description]=\"'Start samtalen ved at sende en besked'\">\r\n * </ds-mobile-empty-state>\r\n *\r\n * <!-- Without image -->\r\n * <ds-mobile-empty-state\r\n * [title]=\"'Ingen resultater'\"\r\n * [description]=\"'Prøv at justere dine søgekriterier'\">\r\n * </ds-mobile-empty-state>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-empty-state',\r\n standalone: true,\r\n imports: [CommonModule],\r\n styles: [`\r\n :host {\r\n display: block;\r\n }\r\n\r\n .empty-state {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 60px 20px;\r\n text-align: center;\r\n gap: 24px;\r\n }\r\n\r\n .empty-state-image {\r\n width: 96px;\r\n height: 96px;\r\n margin: 0 auto;\r\n }\r\n\r\n .empty-state-text {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n }\r\n\r\n .empty-state-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n line-height: 1.3;\r\n color: var(--color-text-primary, #1a1a1a);\r\n margin: 0;\r\n }\r\n\r\n .empty-state-description {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 1.4;\r\n color: var(--color-text-secondary, #737373);\r\n margin: 0;\r\n }\r\n `],\r\n template: `\r\n <div class=\"empty-state\">\r\n @if (imageSrc()) {\r\n <img \r\n [src]=\"imageSrc()\" \r\n [alt]=\"imageAlt()\" \r\n class=\"empty-state-image\" />\r\n }\r\n <div class=\"empty-state-text\">\r\n <h3 class=\"empty-state-title\">{{ title() }}</h3>\r\n @if (description()) {\r\n <p class=\"empty-state-description\">{{ description() }}</p>\r\n }\r\n </div>\r\n </div>\r\n `\r\n})\r\nexport class DsMobileEmptyStateComponent {\r\n /**\r\n * Source URL for the empty state image (optional)\r\n */\r\n imageSrc = input<string>('');\r\n\r\n /**\r\n * Alt text for the image\r\n */\r\n imageAlt = input<string>('Empty state');\r\n\r\n /**\r\n * Title text for the empty state\r\n */\r\n title = input.required<string>();\r\n\r\n /**\r\n * Description text for the empty state (optional)\r\n */\r\n description = input<string>('');\r\n}\r\n\r\n","import { Component, signal, computed, CUSTOM_ELEMENTS_SCHEMA, Input, ViewChild, ElementRef, OnInit, AfterViewInit } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { Keyboard } from '@capacitor/keyboard';\r\nimport { DsIconComponent, DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { PostContentComponent, PostTextComponent, PostMediaComponent, PostActionsComponent, ActionLikeComponent, ActionCommentComponent } from '../interactive-list-item-post';\r\nimport { DsMobileCommentComponent } from '../comment/ds-mobile-comment';\r\nimport { DsMobileLightboxService, LightboxAuthor } from '../lightbox';\r\nimport { DsMobileBottomSheetService, DsMobileCommentActionsBottomSheetComponent, CommentActionResult } from '../bottom-sheet';\r\nimport { DsMobileModalBaseComponent } from '../modal-base/ds-mobile-modal-base';\r\nimport { DsMobileEmptyStateComponent } from '../empty-state';\r\nimport { DsMobileSectionComponent } from '../section';\r\n\r\n/**\r\n * Post data interface for the modal\r\n *\r\n * Represents a post with its content, author info, and comments.\r\n * Use this interface to map your API response data to the component.\r\n *\r\n * @example\r\n * ```typescript\r\n * const postData: PostDetailData = {\r\n * postId: '123',\r\n * authorName: 'John Doe',\r\n * authorRole: 'Tenant',\r\n * timestamp: '2h ago',\r\n * avatarInitials: 'JD',\r\n * content: 'Post content here...',\r\n * likeCount: 42,\r\n * commentCount: 12,\r\n * comments: [...]\r\n * };\r\n * ```\r\n */\r\nexport interface PostDetailData {\r\n /** Unique post identifier */\r\n postId: string;\r\n /** Post author name */\r\n authorName: string;\r\n /** Author role (e.g., 'Tenant', 'Manager') */\r\n authorRole: string;\r\n /** Post timestamp (e.g., '2h ago', 'Yesterday') */\r\n timestamp: string;\r\n /** Author avatar initials (1-2 letters) */\r\n avatarInitials?: string;\r\n /** Avatar display type */\r\n avatarType?: 'photo' | 'initials';\r\n /** Author avatar image URL */\r\n avatarSrc?: string;\r\n /** Post text content */\r\n content: string;\r\n /** Optional post image URL */\r\n imageSrc?: string;\r\n /** Image alt text */\r\n imageAlt?: string;\r\n /** Whether the current user has liked this post */\r\n isLiked?: boolean;\r\n /** Number of likes */\r\n likeCount?: number;\r\n /** Number of comments */\r\n commentCount?: number;\r\n /** Array of comments */\r\n comments?: CommentData[];\r\n /** Auto-focus comment input when modal opens */\r\n focusComment?: boolean;\r\n}\r\n\r\n/**\r\n * Comment data interface\r\n *\r\n * Represents a single comment on a post.\r\n *\r\n * @example\r\n * ```typescript\r\n * const comment: CommentData = {\r\n * authorName: 'Jane Smith',\r\n * authorRole: 'Tenant',\r\n * timestamp: '1h ago',\r\n * avatarInitials: 'JS',\r\n * content: 'Great post!',\r\n * isLiked: false,\r\n * likeCount: 5,\r\n * isOwnComment: false\r\n * };\r\n * ```\r\n */\r\nexport interface CommentData {\r\n /** Unique comment identifier */\r\n id?: string;\r\n /** Comment author name */\r\n authorName: string;\r\n /** Author role */\r\n authorRole: string;\r\n /** Comment timestamp */\r\n timestamp: string;\r\n /** Author avatar initials */\r\n avatarInitials: string;\r\n /** Comment text content */\r\n content: string;\r\n /** Whether the current user has liked this comment */\r\n isLiked?: boolean;\r\n /** Number of likes on this comment */\r\n likeCount?: number;\r\n /** Whether this comment belongs to the current user */\r\n isOwnComment?: boolean;\r\n}\r\n\r\n/**\r\n * DsMobilePostDetailModalComponent\r\n *\r\n * Modal wrapper for displaying post details with comments.\r\n * Follows the same pattern as the lightbox modal for consistent behavior.\r\n *\r\n * Features:\r\n * - Full post content display\r\n * - Comments section\r\n * - Image lightbox integration\r\n * - Native modal controls (close, swipe down)\r\n * - Safe area support\r\n *\r\n * This component is typically not used directly - use DsMobilePostDetailModalService instead.\r\n *\r\n * @example\r\n * ```typescript\r\n * // Don't instantiate directly - use the service:\r\n * constructor(private postModal: DsMobilePostDetailModalService) {}\r\n *\r\n * openPost() {\r\n * this.postModal.open({\r\n * postId: '123',\r\n * authorName: 'John Doe',\r\n * content: 'Post content...'\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-post-detail-modal',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n DsIconComponent,\r\n DsIconButtonComponent,\r\n DsAvatarComponent,\r\n PostTextComponent,\r\n PostMediaComponent,\r\n ActionLikeComponent,\r\n ActionCommentComponent,\r\n DsMobileCommentComponent,\r\n DsMobileModalBaseComponent,\r\n DsMobileEmptyStateComponent,\r\n DsMobileSectionComponent\r\n ],\r\n styleUrls: ['../shared/mobile-common.css', './ds-mobile-post-detail-modal.css'],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n template: `\r\n <ds-mobile-modal-base\r\n [loading]=\"loading\"\r\n [error]=\"error\"\r\n [headerTitle]=\"post().authorName\"\r\n [headerMeta]=\"post().authorRole + ' · ' + post().timestamp\"\r\n [hasFixedBottom]=\"true\"\r\n [enableKeyboardHandling]=\"true\"\r\n closeButtonLabel=\"Luk opslag\"\r\n >\r\n <!-- Header Avatar -->\r\n <ds-avatar header-leading [initials]=\"post().avatarInitials || ''\" [type]=\"post().avatarType || 'initials'\" [src]=\"post().avatarSrc || ''\" size=\"md\" />\r\n \r\n <!-- Post Section -->\r\n <ds-mobile-section>\r\n <div class=\"post-content-only\">\r\n <post-text>\r\n <div [innerHTML]=\"post().content\"></div>\r\n </post-text>\r\n @if (post().imageSrc) {\r\n <post-media>\r\n <img [src]=\"post().imageSrc\" [alt]=\"post().imageAlt || 'Post image'\" class=\"clickable-image\" (click)=\"openImageLightbox()\" />\r\n </post-media>\r\n }\r\n </div>\r\n\r\n <!-- Post actions -->\r\n <div class=\"post-actions\">\r\n <action-like \r\n [active]=\"post().isLiked || false\" \r\n [count]=\"post().likeCount || 0\" \r\n (likeClick)=\"handlePostLikeToggle($event)\" \r\n />\r\n <action-comment [count]=\"post().commentCount || 0\" (commentClick)=\"focusCommentInput()\" />\r\n </div>\r\n </ds-mobile-section>\r\n\r\n <!-- Comments Section -->\r\n <ds-mobile-section \r\n [headline]=\"post().comments && post().comments!.length > 0 ? (post().comments!.length + ' ' + (post().comments!.length === 1 ? 'reply' : 'replies')) : ''\">\r\n @if (post().comments && post().comments!.length > 0) {\r\n <div class=\"comments-list\">\r\n @for (comment of post().comments!; track comment.id) {\r\n <ds-mobile-comment\r\n [authorName]=\"comment.authorName\"\r\n [authorRole]=\"comment.authorRole\"\r\n [timestamp]=\"comment.timestamp\"\r\n [avatarInitials]=\"comment.avatarInitials\"\r\n [content]=\"comment.content\"\r\n [isLiked]=\"comment.isLiked || false\"\r\n [likeCount]=\"comment.likeCount || 0\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"comment.isOwnComment || false\"\r\n (likeToggled)=\"handleCommentLikeToggle(comment, $event)\"\r\n (replyClick)=\"handleReply(comment.authorName, comment.content)\"\r\n (editClick)=\"handleEditComment(comment)\"\r\n (longPress)=\"handleCommentLongPress(comment.authorName, comment.content, comment.isOwnComment || false)\" />\r\n }\r\n </div>\r\n } @else {\r\n <!-- Empty State -->\r\n <ds-mobile-empty-state\r\n [imageSrc]=\"'/Assets/empty-state-inquiry.svg'\"\r\n [imageAlt]=\"'Ingen kommentarer endnu'\"\r\n [title]=\"'Ingen svar endnu'\"\r\n [description]=\"'Vær den første til at svare på dette opslag'\">\r\n </ds-mobile-empty-state>\r\n }\r\n </ds-mobile-section>\r\n \r\n <!-- Fixed comment composer -->\r\n <div fixed-bottom>\r\n <div class=\"comment-composer\">\r\n <!-- Edit indicator -->\r\n @if (editingComment()) {\r\n <div class=\"edit-indicator\">\r\n <div class=\"edit-indicator-content\">\r\n <ds-icon name=\"remixEditLine\" size=\"16px\" />\r\n <span class=\"edit-text\">Redigerer kommentar</span>\r\n </div>\r\n <button class=\"cancel-edit\" (click)=\"cancelEdit()\">\r\n <ds-icon name=\"remixCloseLine\" size=\"16px\" />\r\n </button>\r\n </div>\r\n } @else if (replyingTo()) {\r\n <!-- Reply indicator -->\r\n <div class=\"reply-indicator\">\r\n <div class=\"reply-indicator-content\">\r\n <ds-icon name=\"remixReplyLine\" size=\"16px\" />\r\n <span class=\"reply-to-text\">\r\n Svarer til <span class=\"reply-author\">{{ replyingTo()!.authorName }}</span>\r\n </span>\r\n </div>\r\n <button class=\"cancel-reply\" (click)=\"cancelReply()\">\r\n <ds-icon name=\"remixCloseLine\" size=\"16px\" />\r\n </button>\r\n </div>\r\n }\r\n\r\n <div class=\"composer-content\">\r\n <ds-avatar [initials]=\"currentUserInitials()\" [type]=\"'initials'\" size=\"md\" />\r\n <div class=\"composer-input-wrapper\">\r\n <textarea\r\n #commentInput\r\n class=\"composer-input\"\r\n [placeholder]=\"editingComment() ? 'Rediger din kommentar...' : replyingTo() ? 'Tilføj et svar...' : 'Tilføj et svar...'\"\r\n [ngModel]=\"commentText()\"\r\n (ngModelChange)=\"commentText.set($event)\"\r\n (input)=\"handleInput($event)\"\r\n (focus)=\"showKeyboard()\"\r\n (click)=\"showKeyboard()\"\r\n rows=\"1\"\r\n ></textarea>\r\n </div>\r\n <ds-icon-button\r\n icon=\"remixCheckLine\"\r\n variant=\"primary\"\r\n size=\"sm\"\r\n (clicked)=\"submitComment()\"\r\n aria-label=\"Send kommentar\"\r\n [class.send-button-fixed]=\"true\"\r\n [class.show]=\"commentText().trim().length > 0\"\r\n >\r\n </ds-icon-button>\r\n </div>\r\n </div>\r\n </div>\r\n </ds-mobile-modal-base>\r\n `,\r\n})\r\nexport class DsMobilePostDetailModalComponent implements OnInit, AfterViewInit {\r\n // Post data passed from service\r\n @Input() postData!: PostDetailData;\r\n\r\n // Current user info for comment composer\r\n @Input() currentUserName: string = '';\r\n @Input() currentUserInitialsInput: string = '';\r\n\r\n // State management inputs (passed to modal base)\r\n @Input() loading: boolean = false;\r\n @Input() error: string | undefined;\r\n\r\n // Callback for toggling like on the main post\r\n @Input() onTogglePostLike?: (payload: { postId: string; active: boolean }) => void;\r\n\r\n // Callback for submitting a new comment\r\n @Input() onSubmitComment?: (payload: { postId: string; text: string }) => void;\r\n\r\n // Callback for liking/unliking a comment\r\n @Input() onToggleCommentLike?: (payload: { commentId: string; active: boolean }) => void;\r\n\r\n // Callback for editing a comment\r\n @Input() onEditComment?: (payload: { commentId: string; newText: string }) => void;\r\n\r\n // Callback for deleting a comment\r\n @Input() onDeleteComment?: (payload: { commentId: string }) => void;\r\n\r\n // ViewChild for comment input\r\n @ViewChild('commentInput') commentInput?: ElementRef<HTMLTextAreaElement>;\r\n\r\n // Signal for reactive post data\r\n post = signal<PostDetailData>({\r\n postId: '',\r\n authorName: '',\r\n authorRole: '',\r\n timestamp: '',\r\n content: '',\r\n comments: [],\r\n });\r\n\r\n // Comment composer state\r\n commentText = signal('');\r\n currentUserInitials = signal('');\r\n replyingTo = signal<{ authorName: string; content: string } | null>(null);\r\n editingComment = signal<{ id?: string; authorName: string; originalContent: string; timestamp: string } | null>(null);\r\n\r\n constructor(private lightbox: DsMobileLightboxService, private bottomSheet: DsMobileBottomSheetService) {}\r\n\r\n ngOnInit(): void {\r\n // Initialize post data from input\r\n if (this.postData) {\r\n this.post.set(this.postData);\r\n }\r\n\r\n // Set current user initials\r\n if (this.currentUserInitialsInput) {\r\n this.currentUserInitials.set(this.currentUserInitialsInput);\r\n } else if (this.currentUserName) {\r\n // fallback: derive from name\r\n const initials = this.currentUserName\r\n .trim()\r\n .split(/\\s+/)\r\n .map((p) => p[0])\r\n .join('')\r\n .substring(0, 2)\r\n .toUpperCase();\r\n this.currentUserInitials.set(initials);\r\n }\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n // Auto-focus comment input if requested\r\n if (this.postData?.focusComment) {\r\n // Small delay to ensure modal animation is complete\r\n setTimeout(() => {\r\n this.commentInput?.nativeElement.focus();\r\n // Show keyboard on mobile\r\n this.showKeyboard();\r\n }, 300);\r\n }\r\n }\r\n\r\n /**\r\n * Show the keyboard when user interacts with input\r\n */\r\n showKeyboard(): void {\r\n Keyboard.show().catch((e) => {\r\n // console.log('Keyboard.show() not available')\r\n });\r\n }\r\n\r\n /**\r\n * Focus the comment input when comment icon is tapped\r\n */\r\n focusCommentInput(): void {\r\n // Focus the input\r\n this.commentInput?.nativeElement.focus();\r\n // Show keyboard on mobile\r\n this.showKeyboard();\r\n }\r\n\r\n /**\r\n * Handle input changes for auto-resize\r\n */\r\n handleInput(event: Event): void {\r\n const textarea = event.target as HTMLTextAreaElement;\r\n\r\n // Auto-resize textarea\r\n textarea.style.height = 'auto';\r\n textarea.style.height = textarea.scrollHeight + 'px';\r\n }\r\n\r\n /**\r\n * Handle reply to a comment\r\n */\r\n handleReply(authorName: string, content: string): void {\r\n this.replyingTo.set({ authorName, content });\r\n // Focus the input and show keyboard\r\n setTimeout(() => {\r\n this.commentInput?.nativeElement.focus();\r\n this.showKeyboard();\r\n }, 100);\r\n }\r\n\r\n /**\r\n * Cancel reply\r\n */\r\n cancelReply(): void {\r\n this.replyingTo.set(null);\r\n }\r\n\r\n /**\r\n * Cancel edit\r\n */\r\n cancelEdit(): void {\r\n this.editingComment.set(null);\r\n this.commentText.set('');\r\n }\r\n\r\n /**\r\n * Handle edit comment\r\n */\r\n handleEditComment(comment: CommentData): void {\r\n // Clear reply state if active\r\n this.replyingTo.set(null);\r\n\r\n // Set edit state\r\n this.editingComment.set({\r\n id: comment.id,\r\n authorName: comment.authorName,\r\n originalContent: comment.content,\r\n timestamp: comment.timestamp,\r\n });\r\n\r\n // Populate the input with existing content\r\n this.commentText.set(comment.content);\r\n\r\n // Focus the input, show keyboard, and auto-resize\r\n setTimeout(() => {\r\n if (this.commentInput?.nativeElement) {\r\n const textarea = this.commentInput.nativeElement;\r\n textarea.focus();\r\n\r\n // Auto-resize textarea to fit content\r\n textarea.style.height = 'auto';\r\n textarea.style.height = textarea.scrollHeight + 'px';\r\n\r\n this.showKeyboard();\r\n }\r\n }, 100);\r\n }\r\n\r\n /**\r\n * Handle post like/unlike toggle\r\n */\r\n handlePostLikeToggle(ev: { active: boolean; count: number }): void {\r\n const currentPost = this.post();\r\n \r\n // Update local state immediately for responsiveness\r\n this.post.set({\r\n ...currentPost,\r\n isLiked: ev.active,\r\n likeCount: ev.count\r\n });\r\n\r\n // Call the callback if provided\r\n if (this.onTogglePostLike) {\r\n this.onTogglePostLike({\r\n postId: currentPost.postId,\r\n active: ev.active\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Handle comment like/unlike toggle\r\n * @param comment The comment being liked/unliked\r\n * @param ev Event data with active state and new count\r\n */\r\n handleCommentLikeToggle(comment: CommentData, ev: { active: boolean; count: number }): void {\r\n // Update local state immediately for responsiveness\r\n const currentPost = this.post();\r\n const updatedComments = currentPost.comments?.map((c) => (c.id === comment.id ? { ...c, isLiked: ev.active, likeCount: ev.count } : c));\r\n\r\n this.post.set({\r\n ...currentPost,\r\n comments: updatedComments,\r\n });\r\n\r\n // Call the callback if provided\r\n if (this.onToggleCommentLike) {\r\n this.onToggleCommentLike({\r\n commentId: comment.id!,\r\n active: ev.active,\r\n });\r\n }\r\n }\r\n\r\n // Note: close() method is inherited from MobileModalBase\r\n\r\n /**\r\n * Submit a comment\r\n */\r\n submitComment(): void {\r\n const text = this.commentText().trim();\r\n if (!text) return;\r\n\r\n const currentPost = this.post();\r\n const postId = currentPost.postId;\r\n\r\n // Create new comment\r\n const finalText = this.replyingTo() ? `@${this.replyingTo()!.authorName} ${text}` : text;\r\n\r\n // Check if we're editing an existing comment\r\n if (this.editingComment()) {\r\n // console.log('[PostDetailModal] Updating comment:', text);\r\n\r\n const editing = this.editingComment()!;\r\n\r\n const updatedComments = currentPost.comments?.map((comment) => {\r\n if (comment.id && editing.id && comment.id === editing.id) {\r\n return {\r\n ...comment,\r\n content: text,\r\n timestamp: 'Just now (edited)',\r\n };\r\n }\r\n return comment;\r\n });\r\n\r\n this.post.set({\r\n ...currentPost,\r\n comments: updatedComments,\r\n });\r\n\r\n // Call the edit callback\r\n if (this.onEditComment && editing.id) {\r\n this.onEditComment({\r\n commentId: editing.id,\r\n newText: finalText, // or finalText if you want to include @mention\r\n });\r\n }\r\n\r\n this.editingComment.set(null);\r\n } else {\r\n // console.log('[PostDetailModal] Submitting comment:', finalText);\r\n // console.log('[PostDetailModal] onSubmitComment =', this.onSubmitComment);\r\n\r\n const newComment: CommentData = {\r\n authorName: this.currentUserName || 'Dig',\r\n authorRole: 'Dig',\r\n timestamp: 'Just now',\r\n avatarInitials: this.currentUserInitials(),\r\n content: finalText,\r\n isLiked: false,\r\n likeCount: 0,\r\n isOwnComment: true,\r\n };\r\n\r\n // Add comment to the list\r\n const updatedComments = [...(currentPost.comments || []), newComment];\r\n\r\n this.post.set({\r\n ...currentPost,\r\n comments: updatedComments,\r\n commentCount: updatedComments.length,\r\n });\r\n\r\n // Clear reply state\r\n this.replyingTo.set(null);\r\n }\r\n\r\n // Clear the input\r\n this.commentText.set('');\r\n\r\n if (this.commentInput?.nativeElement) {\r\n // Reset textarea height to initial state\r\n this.commentInput.nativeElement.style.height = 'auto';\r\n // Blur the input to hide the keyboard\r\n this.commentInput?.nativeElement.blur();\r\n }\r\n\r\n // Hide keyboard explicitly\r\n Keyboard.hide().catch(() => {});\r\n\r\n // In a real app, you would also send this to your backend\r\n // this.commentService.addComment(currentPost.postId, text);\r\n if (this.onSubmitComment) {\r\n this.onSubmitComment({ postId, text: finalText });\r\n }\r\n }\r\n\r\n /**\r\n * Open image in lightbox\r\n */\r\n openImageLightbox(): void {\r\n const postData = this.post();\r\n\r\n if (!postData.imageSrc) return;\r\n\r\n const authorMeta: LightboxAuthor = {\r\n name: postData.authorName,\r\n role: postData.authorRole,\r\n avatarInitials: postData.avatarInitials || '',\r\n avatarType: postData.avatarType || 'initials',\r\n avatarSrc: postData.avatarSrc || '',\r\n timestamp: postData.timestamp,\r\n };\r\n\r\n this.lightbox.open({\r\n images: [\r\n {\r\n type: 'image',\r\n src: postData.imageSrc,\r\n alt: postData.imageAlt || 'Post image',\r\n title: postData.imageAlt || '',\r\n description: postData.content,\r\n isLiked: postData.isLiked || false,\r\n likeCount: postData.likeCount || 0,\r\n commentCount: postData.commentCount || 0,\r\n },\r\n ],\r\n author: authorMeta,\r\n enableZoom: true,\r\n showControls: false,\r\n showInfo: true,\r\n });\r\n }\r\n\r\n /**\r\n * Handle long press on a comment to show action sheet\r\n */\r\n async handleCommentLongPress(authorName: string, content: string, isOwnComment: boolean): Promise<void> {\r\n const sheet = await this.bottomSheet.create({\r\n component: DsMobileCommentActionsBottomSheetComponent,\r\n componentProps: {\r\n isOwnContent: isOwnComment,\r\n },\r\n breakpoints: [0, 1],\r\n initialBreakpoint: 1,\r\n handle: true,\r\n backdropDismiss: true,\r\n cssClass: 'auto-height',\r\n });\r\n\r\n const result = await sheet.onWillDismiss();\r\n\r\n if (result.role === 'select' && result.data) {\r\n const action = (result.data as CommentActionResult).action;\r\n const currentPost = this.post();\r\n\r\n switch (action) {\r\n case 'like':\r\n // console.log('Like comment by', authorName);\r\n let toggledCommentId: string | null = null;\r\n let newActive = false;\r\n // Update the comment like state locally\r\n const updatedComments = currentPost.comments?.map((comment) => {\r\n if (comment.authorName === authorName && comment.content === content) {\r\n newActive = !comment.isLiked;\r\n toggledCommentId = comment.id!;\r\n\r\n return {\r\n ...comment,\r\n isLiked: newActive,\r\n likeCount: newActive ? (comment.likeCount || 0) + 1 : Math.max(0, (comment.likeCount || 0) - 1),\r\n };\r\n }\r\n return comment;\r\n });\r\n\r\n this.post.set({ ...currentPost, comments: updatedComments });\r\n\r\n // Call the like callback\r\n if (toggledCommentId && this.onToggleCommentLike) {\r\n this.onToggleCommentLike({\r\n commentId: toggledCommentId,\r\n active: newActive,\r\n });\r\n }\r\n break;\r\n case 'reply':\r\n // console.log('Reply to comment by', authorName);\r\n this.handleReply(authorName, content);\r\n break;\r\n case 'edit':\r\n // console.log('Edit comment by', authorName);\r\n // Find the full comment data to get timestamp\r\n const commentToEdit = currentPost.comments?.find((comment) => comment.authorName === authorName && comment.content === content);\r\n if (commentToEdit) {\r\n this.handleEditComment(commentToEdit);\r\n }\r\n break;\r\n case 'delete':\r\n // console.log('Delete comment by', authorName);\r\n // Show confirmation before deleting\r\n if (confirm('Are you sure you want to delete this comment?')) {\r\n const commentToDelete = currentPost.comments?.find((comment) => comment.authorName === authorName && comment.content === content);\r\n const updatedCommentsAfterDelete = currentPost.comments?.filter((comment) => !(comment.authorName === authorName && comment.content === content));\r\n this.post.set({\r\n ...currentPost,\r\n comments: updatedCommentsAfterDelete,\r\n commentCount: updatedCommentsAfterDelete?.length || 0,\r\n });\r\n\r\n // Call the delete callback\r\n if (commentToDelete?.id && this.onDeleteComment) {\r\n this.onDeleteComment({ commentId: commentToDelete.id });\r\n }\r\n }\r\n break;\r\n }\r\n }\r\n }\r\n}\r\n","import { Injectable, Type } from '@angular/core';\r\nimport { ModalController, ModalOptions as IonicModalOptions } from '@ionic/angular/standalone';\r\n\r\n/**\r\n * BaseModalService\r\n *\r\n * Abstract base class for all modal services in the application.\r\n * Enforces consistent modal configuration and presentation across all modals.\r\n *\r\n * **Features:**\r\n * - Standardized modal presentation (stacked effect with gap at top)\r\n * - Consistent backdrop and dismissal behavior\r\n * - Automatic safe area handling\r\n * - Native iOS-style animations\r\n *\r\n * **Why use this:**\r\n * - Ensures all modals have the same look and feel\r\n * - Prevents inconsistencies in modal configuration\r\n * - Single source of truth for modal settings\r\n * - Makes it impossible to forget critical configuration\r\n *\r\n * @example\r\n * ```typescript\r\n * @Injectable({ providedIn: 'root' })\r\n * export class MyModalService extends BaseModalService {\r\n * async open(data: MyData) {\r\n * const modal = await this.createModal(\r\n * MyModalComponent,\r\n * { data }\r\n * );\r\n * await modal.present();\r\n * }\r\n * }\r\n * ```\r\n */\r\n@Injectable()\r\nexport abstract class BaseModalService {\r\n constructor(protected modalController: ModalController) {}\r\n\r\n /**\r\n * Create a modal with standardized configuration\r\n *\r\n * This method enforces consistent modal behavior across the app:\r\n * - Uses 'ds-modal-base' CSS class for consistent styling\r\n * - iOS mode for native feel\r\n * - presentingElement for stacked modal effect\r\n * - Standard backdrop and dismissal settings\r\n *\r\n * @param component The component to display in the modal\r\n * @param componentProps Props to pass to the component\r\n * @param customOptions Optional overrides for specific modal needs\r\n * @returns Promise resolving to the created modal\r\n *\r\n * @example\r\n * ```typescript\r\n * const modal = await this.createModal(\r\n * PostDetailComponent,\r\n * { postId: '123', loading: false }\r\n * );\r\n * await modal.present();\r\n * ```\r\n */\r\n protected async createModal<T>(\r\n component: Type<T>,\r\n componentProps?: Record<string, any>,\r\n customOptions?: Partial<IonicModalOptions>\r\n ): Promise<HTMLIonModalElement> {\r\n return await this.modalController.create({\r\n component,\r\n componentProps,\r\n // Standard configuration for all modals\r\n cssClass: 'ds-modal-base',\r\n mode: 'ios',\r\n presentingElement: document.querySelector('ion-router-outlet') || undefined,\r\n backdropDismiss: true,\r\n showBackdrop: true,\r\n animated: true,\r\n // Allow service-specific overrides if needed\r\n ...customOptions,\r\n });\r\n }\r\n\r\n /**\r\n * Close the currently open modal\r\n *\r\n * @param data Optional data to pass back when dismissing\r\n * @returns Promise that resolves when the modal is dismissed\r\n */\r\n async close(data?: any): Promise<boolean> {\r\n return this.modalController.dismiss(data);\r\n }\r\n\r\n /**\r\n * Get the top-most modal if one exists\r\n *\r\n * @returns Promise that resolves to the modal element or undefined\r\n */\r\n async getTop(): Promise<HTMLIonModalElement | undefined> {\r\n return this.modalController.getTop();\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport {\r\n DsMobilePostDetailModalComponent,\r\n PostDetailData,\r\n} from './ds-mobile-post-detail-modal';\r\nimport { BaseModalService } from '../../services/base-modal.service';\r\n\r\n/**\r\n * DsMobilePostDetailModalService\r\n *\r\n * Service for displaying post details in a full-screen modal.\r\n * Built on Ionic's modal system with native gestures and animations.\r\n * Follows the same pattern as DsMobileLightboxService for consistent behavior.\r\n *\r\n * Features:\r\n * - Full post content display\r\n * - Comments section\r\n * - Like/comment actions\r\n * - Image lightbox integration\r\n * - Native modal animations\r\n * - Safe area support\r\n *\r\n * @example\r\n * ```typescript\r\n * constructor(private postModal: DsMobilePostDetailModalService) {}\r\n *\r\n * async openPost() {\r\n * await this.postModal.open({\r\n * postId: '123',\r\n * authorName: 'John Doe',\r\n * authorRole: 'Tenant',\r\n * timestamp: '2h ago',\r\n * avatarInitials: 'JD',\r\n * content: 'Just moved into my new apartment!',\r\n * isLiked: false,\r\n * likeCount: 42,\r\n * commentCount: 12,\r\n * comments: [\r\n * {\r\n * authorName: 'Jane Smith',\r\n * authorRole: 'Tenant',\r\n * timestamp: '1h ago',\r\n * avatarInitials: 'JS',\r\n * content: 'Welcome to the community!'\r\n * }\r\n * ]\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class DsMobilePostDetailModalService extends BaseModalService {\r\n constructor(modalController: ModalController) {\r\n super(modalController);\r\n }\r\n\r\n /**\r\n * Open the post detail modal\r\n *\r\n * @param postData Post data to display\r\n * @param options Optional loading and error states\r\n * @returns Promise that resolves when the modal is presented\r\n */\r\n async open(\r\n postData: PostDetailData,\r\n options?: {\r\n loading?: boolean;\r\n error?: string;\r\n onTogglePostLike?: (payload: { postId: string; active: boolean }) => void;\r\n onSubmitComment?: (payload: { postId: string; text: string }) => void;\r\n onToggleCommentLike?: (payload: {\r\n commentId: string;\r\n active: boolean;\r\n }) => void;\r\n onEditComment?: (payload: { commentId: string; newText: string }) => void;\r\n onDeleteComment?: (payload: { commentId: string }) => void;\r\n currentUserName?: string;\r\n currentUserInitials?: string;\r\n }\r\n ): Promise<void> {\r\n // console.log('[PostDetailModal] Opening with data:', postData);\r\n // console.log('[PostDetailModal] options.onSubmitComment =', options?.onSubmitComment);\r\n\r\n const modal = await this.createModal(\r\n DsMobilePostDetailModalComponent,\r\n {\r\n postData: postData,\r\n loading: options?.loading ?? false,\r\n error: options?.error,\r\n onTogglePostLike: options?.onTogglePostLike,\r\n onSubmitComment: options?.onSubmitComment,\r\n onToggleCommentLike: options?.onToggleCommentLike,\r\n currentUserName: options?.currentUserName ?? '',\r\n currentUserInitialsInput: options?.currentUserInitials ?? '',\r\n },\r\n {\r\n keyboardClose: true, // Keep keyboard close behavior for this modal\r\n }\r\n );\r\n\r\n // console.log('[PostDetailModal] Modal created, presenting...');\r\n await modal.present();\r\n // console.log('[PostDetailModal] Modal presented');\r\n }\r\n}\r\n","/**\r\n * Mobile Post Detail Modal Module\r\n * \r\n * Service and component for displaying posts in a modal\r\n */\r\n\r\nexport * from './ds-mobile-post-detail-modal';\r\nexport * from './ds-mobile-post-detail-modal.service';\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n/**\r\n * DsMobileCardInlineComponent\r\n * \r\n * A versatile, always-interactive inline card component for standalone or small-group usage.\r\n * Designed for tappable card-like elements such as file attachments, contact cards, etc.\r\n * Not intended for long scrolling lists - use ds-mobile-list-item for that purpose.\r\n * \r\n * Features:\r\n * - Always interactive/tappable (unless disabled)\r\n * - Two layout variants: default (column) and compact (row)\r\n * - Flexible content projection with leading/main/trailing slots\r\n * - Consistent styling with rounded corners and neutral background\r\n * - Built-in hover and active states\r\n * - Accessibility features (role, tabindex, aria attributes)\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Default variant (column layout) -->\r\n * <ds-mobile-card-inline\r\n * [variant]=\"'default'\"\r\n * (cardClick)=\"handleClick()\">\r\n * \r\n * <div content-leading>\r\n * <ds-avatar initials=\"JD\" />\r\n * </div>\r\n * \r\n * <div content-main>\r\n * <div class=\"title\">Document Title</div>\r\n * <div class=\"subtitle\">PDF · 1.2 MB</div>\r\n * </div>\r\n * \r\n * <ds-icon content-trailing name=\"remixArrowRightSLine\" />\r\n * </ds-mobile-card-inline>\r\n * \r\n * <!-- Compact variant (row layout) -->\r\n * <ds-mobile-card-inline\r\n * [variant]=\"'compact'\"\r\n * (cardClick)=\"handleClick()\">\r\n * \r\n * <ds-avatar content-leading size=\"sm\" />\r\n * \r\n * <div content-main>\r\n * <span class=\"name\">File.pdf</span>\r\n * <span class=\"size\">245 KB</span>\r\n * </div>\r\n * \r\n * <ds-icon content-trailing name=\"remixArrowRightSLine\" />\r\n * </ds-mobile-card-inline>\r\n * \r\n * <!-- Disabled state -->\r\n * <ds-mobile-card-inline [disabled]=\"true\">\r\n * <div content-main>Disabled card</div>\r\n * </ds-mobile-card-inline>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-card-inline',\r\n standalone: true,\r\n imports: [CommonModule],\r\n host: {\r\n '[class.disabled]': 'disabled()',\r\n '[class.variant-compact]': 'variant() === \"compact\"',\r\n '[class.variant-default]': 'variant() === \"default\"',\r\n '[attr.role]': '\"button\"',\r\n '[attr.tabindex]': 'disabled() ? null : \"0\"',\r\n '[attr.aria-disabled]': 'disabled() ? \"true\" : null',\r\n '(click)': 'handleClick($event)',\r\n '(keydown.enter)': 'handleKeyDown($event)',\r\n '(keydown.space)': 'handleKeyDown($event)'\r\n },\r\n styles: [`\r\n :host {\r\n display: flex;\r\n align-items: center;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-radius: 16px;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n box-sizing: border-box;\r\n }\r\n \r\n /* Default variant - column layout with more padding */\r\n :host(.variant-default) {\r\n gap: 12px;\r\n padding: 10px 12px;\r\n }\r\n \r\n /* Compact variant - row layout with less padding */\r\n :host(.variant-compact) {\r\n gap: 8px;\r\n padding: 10px;\r\n }\r\n \r\n /* Hover state (desktop only) */\r\n @media (hover: hover) and (pointer: fine) {\r\n :host(:hover):not(.disabled) {\r\n background: var(--color-background-neutral-secondary-hover, #ebebeb);\r\n }\r\n }\r\n \r\n /* Active state */\r\n :host(:active):not(.disabled) {\r\n transform: scale(0.98);\r\n background: var(--color-background-neutral-secondary-hover, #ebebeb);\r\n }\r\n \r\n /* Focus visible for keyboard navigation */\r\n :host(:focus-visible):not(.disabled) {\r\n outline: 2px solid var(--color-brand-primary, #5d5fef);\r\n outline-offset: 2px;\r\n }\r\n \r\n /* Disabled state */\r\n :host(.disabled) {\r\n opacity: 0.5;\r\n pointer-events: none;\r\n cursor: not-allowed;\r\n }\r\n \r\n /* Inner container */\r\n .card-inline-inner {\r\n display: flex;\r\n align-items: center;\r\n gap: inherit;\r\n width: 100%;\r\n min-width: 0;\r\n }\r\n \r\n /* Content slots */\r\n .content-leading {\r\n flex-shrink: 0;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n \r\n .content-main {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n align-items: center;\r\n }\r\n \r\n /* Compact variant - main content flows inline */\r\n :host(.variant-compact) .content-main {\r\n flex-direction: row;\r\n gap: 8px;\r\n }\r\n \r\n /* Default variant - main content flows column */\r\n :host(.variant-default) .content-main {\r\n flex-direction: column;\r\n align-items: flex-start;\r\n gap: 2px;\r\n }\r\n \r\n .content-trailing {\r\n flex-shrink: 0;\r\n display: flex;\r\n align-items: center;\r\n }\r\n \r\n /* ============================================\r\n Shared item styles for child components\r\n ============================================ */\r\n \r\n /* Item avatar container */\r\n ::ng-deep .item-avatar {\r\n flex-shrink: 0;\r\n }\r\n \r\n /* Item content wrapper - default stacks vertically */\r\n ::ng-deep .item-content {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n justify-content: center;\r\n gap: 2px;\r\n }\r\n \r\n /* Compact layout - content flows inline */\r\n :host(.variant-compact) ::ng-deep .item-content {\r\n flex-direction: row;\r\n align-items: center;\r\n justify-content: flex-start;\r\n gap: 8px;\r\n }\r\n \r\n /* Item name - primary text with truncation */\r\n ::ng-deep .item-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n margin: 0;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n text-align: left;\r\n }\r\n \r\n /* Item meta - secondary text */\r\n ::ng-deep .item-meta {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 400;\r\n line-height: 1.2;\r\n letter-spacing: -0.26px;\r\n color: var(--color-text-tertiary, #737373);\r\n margin: 0;\r\n display: flex;\r\n align-items: center;\r\n justify-content: flex-start;\r\n gap: 4px;\r\n white-space: nowrap;\r\n flex-shrink: 0;\r\n }\r\n \r\n /* Item trailing icon */\r\n ::ng-deep .item-trailing {\r\n display: flex;\r\n align-items: center;\r\n color: var(--color-text-tertiary, #a3a3a3);\r\n flex-shrink: 0;\r\n }\r\n `],\r\n template: `\r\n <div class=\"card-inline-inner\">\r\n <div class=\"content-leading\">\r\n <ng-content select=\"[content-leading]\" />\r\n </div>\r\n \r\n <div class=\"content-main\">\r\n <ng-content select=\"[content-main]\" />\r\n <ng-content />\r\n </div>\r\n \r\n <div class=\"content-trailing\">\r\n <ng-content select=\"[content-trailing]\" />\r\n </div>\r\n </div>\r\n `\r\n})\r\nexport class DsMobileCardInlineComponent {\r\n /**\r\n * Display variant\r\n * - 'default' - Column layout with standard padding (gap: 12px, padding: 10px 12px)\r\n * - 'compact' - Row layout with reduced padding (gap: 8px, padding: 10px)\r\n */\r\n variant = input<'default' | 'compact'>('default');\r\n \r\n /**\r\n * Whether the card is disabled\r\n * Disables all interactions and reduces opacity\r\n */\r\n disabled = input<boolean>(false);\r\n \r\n /**\r\n * Emits when the card is clicked (if not disabled)\r\n */\r\n cardClick = output<void>();\r\n \r\n /**\r\n * Handle click events\r\n */\r\n handleClick(event: Event): void {\r\n if (this.disabled()) {\r\n return;\r\n }\r\n \r\n // Don't emit click if it came from an interactive child element\r\n const target = event.target as HTMLElement;\r\n const closestInteractive = target.closest('button, a, input, select, textarea, [role=\"button\"]');\r\n \r\n // Check if the interactive element is a child, not the host itself\r\n if (closestInteractive && closestInteractive !== event.currentTarget) {\r\n return;\r\n }\r\n \r\n this.cardClick.emit();\r\n }\r\n \r\n /**\r\n * Handle keyboard events (Enter/Space)\r\n */\r\n handleKeyDown(event: KeyboardEvent): void {\r\n if (this.disabled()) {\r\n return;\r\n }\r\n \r\n event.preventDefault();\r\n this.cardClick.emit();\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsMobileCardInlineComponent } from '../card-inline';\r\n\r\n/**\r\n * DsMobileCardInlineBannerComponent\r\n * \r\n * Specialized interactive component for displaying notification banners.\r\n * Used to show unread message notifications above inquiry details.\r\n * \r\n * Features:\r\n * - Neutral background matching file/contact cards\r\n * - Avatar icon with message symbol\r\n * - Title and timestamp\r\n * - Unread count badge\r\n * - Chevron for navigation indication\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-card-inline-banner\r\n * [title]=\"'New messages'\"\r\n * [timestamp]=\"'2 min ago'\"\r\n * [unreadCount]=\"3\"\r\n * (bannerClick)=\"navigateToMessages()\">\r\n * </ds-mobile-card-inline-banner>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-card-inline-banner',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent, DsAvatarComponent, DsMobileCardInlineComponent],\r\n styles: [`\r\n /* Component-specific styles only - shared styles come from base component */\r\n \r\n /* Badge for unread count - using whitelabel brand colors */\r\n .unread-badge {\r\n min-width: 24px;\r\n height: 16px;\r\n padding: 0 6px;\r\n border-radius: 10px;\r\n background: var(--color-accent, #6B5FF5);\r\n color: var(--color-on-accent, #ffffff);\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs);\r\n font-weight: 600;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n line-height: 1;\r\n margin-right: 8px;\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-card-inline\r\n [variant]=\"layout()\"\r\n (cardClick)=\"handleBannerClick()\">\r\n \r\n <div content-leading class=\"item-avatar\">\r\n <ds-avatar\r\n type=\"icon\"\r\n [iconName]=\"'remixNotificationLine'\"\r\n [size]=\"layout() === 'compact' ? 'sm' : 'md'\"\r\n />\r\n </div>\r\n \r\n <div content-main class=\"item-content\">\r\n <div class=\"item-name\">{{ title() }}</div>\r\n \r\n @if (timestamp()) {\r\n <div class=\"item-meta\">\r\n <span>{{ timestamp() }}</span>\r\n </div>\r\n }\r\n </div>\r\n \r\n <div content-trailing class=\"item-trailing\">\r\n @if (unreadCount() && unreadCount()! > 0) {\r\n <span class=\"unread-badge\">{{ unreadCount() }}</span>\r\n }\r\n <ds-icon name=\"remixArrowRightSLine\" size=\"20px\" />\r\n </div>\r\n </ds-mobile-card-inline>\r\n `\r\n})\r\nexport class DsMobileCardInlineBannerComponent {\r\n /**\r\n * Banner title (e.g., \"New messages\", \"Unread messages\")\r\n */\r\n title = input.required<string>();\r\n \r\n /**\r\n * Timestamp text (e.g., \"2 min ago\", \"Just now\")\r\n */\r\n timestamp = input<string>('');\r\n \r\n /**\r\n * Number of unread items (optional, shows badge if > 0)\r\n */\r\n unreadCount = input<number>(0);\r\n \r\n /**\r\n * Layout variant\r\n * - 'default' - Standard padding and column layout\r\n * - 'compact' - Reduced padding and row layout\r\n */\r\n layout = input<'default' | 'compact'>('default');\r\n \r\n /**\r\n * Emits when the banner is clicked\r\n */\r\n bannerClick = output<void>();\r\n \r\n handleBannerClick(): void {\r\n this.bannerClick.emit();\r\n }\r\n}\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsMobileCardInlineComponent } from '../card-inline';\r\n\r\n/**\r\n * DsMobileCardInlineContactComponent\r\n * \r\n * Specialized interactive component for displaying contacts.\r\n * Displays contact name with avatar initials and metadata (person name + phone number).\r\n * Similar styling to file attachments with rounded corners and hover states.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-card-inline-contact\r\n * [name]=\"'Mortensen & Søn ApS'\"\r\n * [initials]=\"'M'\"\r\n * [contactPerson]=\"'John Mortensen'\"\r\n * [phoneNumber]=\"'+45 12 34 56 78'\"\r\n * [clickable]=\"true\"\r\n * (contactClick)=\"openContact()\">\r\n * </ds-mobile-card-inline-contact>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-card-inline-contact',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent, DsAvatarComponent, DsMobileCardInlineComponent],\r\n styles: [`\r\n /* Component-specific styles only - shared styles come from base component */\r\n `],\r\n template: `\r\n <ds-mobile-card-inline\r\n [variant]=\"layout()\"\r\n [disabled]=\"!clickable()\"\r\n (cardClick)=\"handleContactClick()\">\r\n \r\n <div content-leading class=\"item-avatar\">\r\n <ds-avatar\r\n [initials]=\"initials()\"\r\n type=\"initials\"\r\n [size]=\"layout() === 'compact' ? 'sm' : 'md'\"\r\n />\r\n </div>\r\n \r\n <div content-main class=\"item-content\">\r\n <div class=\"item-name\">{{ name() }}</div>\r\n \r\n @if (contactPerson() || phoneNumber()) {\r\n <div class=\"item-meta\">\r\n @if (contactPerson()) {\r\n <span>{{ contactPerson() }}</span>\r\n }\r\n @if (contactPerson() && phoneNumber()) {\r\n <span>·</span>\r\n }\r\n @if (phoneNumber()) {\r\n <span>{{ phoneNumber() }}</span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n \r\n @if (showChevron()) {\r\n <div content-trailing class=\"item-trailing\">\r\n <ds-icon name=\"remixArrowRightSLine\" size=\"20px\" />\r\n </div>\r\n }\r\n </ds-mobile-card-inline>\r\n `\r\n})\r\nexport class DsMobileCardInlineContactComponent {\r\n /**\r\n * Contact/company name\r\n */\r\n name = input.required<string>();\r\n \r\n /**\r\n * Avatar initials (usually 1-2 letters)\r\n */\r\n initials = input.required<string>();\r\n \r\n /**\r\n * Contact person name (optional)\r\n */\r\n contactPerson = input<string>('');\r\n \r\n /**\r\n * Phone number (optional)\r\n */\r\n phoneNumber = input<string>('');\r\n \r\n /**\r\n * Layout variant\r\n * - 'default' - Standard padding and column layout\r\n * - 'compact' - Reduced padding and row layout\r\n */\r\n layout = input<'default' | 'compact'>('default');\r\n \r\n /**\r\n * Whether the contact item is clickable\r\n */\r\n clickable = input<boolean>(true);\r\n \r\n /**\r\n * Whether to show chevron icon\r\n */\r\n showChevron = input<boolean>(true);\r\n \r\n /**\r\n * Emits when the contact item is clicked (if clickable)\r\n */\r\n contactClick = output<void>();\r\n \r\n handleContactClick(): void {\r\n this.contactClick.emit();\r\n }\r\n}\r\n\r\n","import { Component, input, output } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsAvatarComponent } from '@propbinder/design-system';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsMobileCardInlineComponent } from '../card-inline';\r\n\r\n/**\r\n * DsMobileCardInlineFileComponent\r\n *\r\n * File attachment display for various document types.\r\n * Shows file info card with icon, filename, and file size.\r\n * Supports PDF and generic document formats.\r\n * Emits click event to open file in viewer.\r\n *\r\n * @example\r\n * ```html\r\n * <ds-mobile-card-inline-file\r\n * [fileName]=\"'Document.pdf'\"\r\n * [fileSize]=\"'1.2 MB'\"\r\n * [variant]=\"'pdf'\"\r\n * [layout]=\"'compact'\"\r\n * (fileClick)=\"openFile()\">\r\n * </ds-mobile-card-inline-file>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-card-inline-file',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n DsAvatarComponent,\r\n DsIconComponent,\r\n DsMobileCardInlineComponent,\r\n ],\r\n styles: [\r\n `\r\n /* PDF variant - red icon background */\r\n .item-avatar.pdf ::ng-deep .avatar--icon {\r\n background-color: #ff5757 !important;\r\n }\r\n\r\n /* Doc variant - blue icon background */\r\n .item-avatar.doc ::ng-deep .avatar--icon {\r\n background-color: var(--color-blue-base, #3b82f6) !important;\r\n }\r\n `,\r\n ],\r\n template: `\r\n <ds-mobile-card-inline [variant]=\"layout()\" (cardClick)=\"handleClick()\">\r\n <div\r\n content-leading\r\n class=\"item-avatar\"\r\n [class.pdf]=\"variant() === 'pdf'\"\r\n [class.doc]=\"variant() === 'doc'\"\r\n >\r\n <ds-avatar\r\n type=\"icon\"\r\n [iconName]=\"getIconName()\"\r\n [size]=\"layout() === 'compact' ? 'sm' : 'md'\"\r\n />\r\n </div>\r\n\r\n <div content-main class=\"item-content\">\r\n <div class=\"item-name\">{{ fileName() }}</div>\r\n @if (fileSize()) {\r\n <div class=\"item-meta\">{{ getFileTypeLabel() }} · {{ fileSize() }}</div>\r\n } @else {\r\n <div class=\"item-meta\">{{ getFileTypeLabel() }}</div>\r\n }\r\n </div>\r\n\r\n <ds-icon\r\n content-trailing\r\n name=\"remixArrowRightSLine\"\r\n size=\"20px\"\r\n class=\"item-trailing\"\r\n />\r\n </ds-mobile-card-inline>\r\n `,\r\n})\r\nexport class DsMobileCardInlineFileComponent {\r\n /**\r\n * File name\r\n */\r\n fileName = input<string>('Document');\r\n\r\n /**\r\n * File size display (e.g., '1.2 MB')\r\n */\r\n fileSize = input<string>('');\r\n\r\n /**\r\n * File type variant\r\n * - 'pdf' - PDF document (red icon)\r\n * - 'doc' - Generic document (blue icon)\r\n */\r\n variant = input<'pdf' | 'doc'>('doc');\r\n\r\n /**\r\n * Layout variant\r\n * - 'default' - Standard padding and column layout\r\n * - 'compact' - Reduced padding and row layout\r\n */\r\n layout = input<'default' | 'compact'>('default');\r\n\r\n /**\r\n * Optional URL to open when clicked\r\n * If provided, clicking the card will open this URL in a new tab\r\n */\r\n fileUrl = input<string | undefined>(undefined);\r\n\r\n /**\r\n * Emits when the file attachment is clicked\r\n */\r\n fileClick = output<void>();\r\n\r\n /**\r\n * Get the appropriate icon name based on variant\r\n */\r\n getIconName(): string {\r\n return this.variant() === 'pdf'\r\n ? 'remixFileTextLine'\r\n : 'remixAttachmentLine';\r\n }\r\n\r\n /**\r\n * Get the file type label based on variant\r\n */\r\n getFileTypeLabel(): string {\r\n return this.variant() === 'pdf' ? 'PDF' : 'DOC';\r\n }\r\n\r\n handleClick(): void {\r\n const url = this.fileUrl();\r\n console.log(url);\r\n if (url) {\r\n window.open(url, '_blank', 'noopener,noreferrer');\r\n }\r\n this.fileClick.emit();\r\n }\r\n}\r\n","import { Component, signal, Input, Output, EventEmitter, OnInit, AfterViewInit, CUSTOM_ELEMENTS_SCHEMA, computed } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { Keyboard } from '@capacitor/keyboard';\r\nimport { DsMobileMessageComposerComponent } from '../message-composer';\r\nimport { DsMobileMessageBubbleComponent, ChatAttachment } from '../message-bubble';\r\nimport { DsAvatarWithBadgeComponent } from '../avatar-with-badge';\r\nimport { DsMobileModalBaseComponent } from '../modal-base/ds-mobile-modal-base';\r\nimport { DsMobileCardInlineFileComponent } from '../card-inline-file';\r\nimport { type AttachmentData } from '../attachment-preview';\r\nimport { DsMobileLightboxService, LightboxAuthor, LightboxImage } from '../lightbox';\r\nimport { DsMobileSystemMessageBannerComponent } from '../system-message-banner';\r\n\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsMobileSectionComponent } from '../section';\r\n\r\n/**\r\n * Chat message data interface\r\n */\r\nexport interface ChatMessage {\r\n id: string;\r\n content: string;\r\n senderId: string;\r\n senderName: string;\r\n senderRole?: string;\r\n timestamp: Date;\r\n avatarInitials?: string;\r\n avatarType?: 'initials' | 'photo' | 'icon';\r\n avatarSrc?: string;\r\n isOwnMessage: boolean;\r\n attachments?: ChatAttachment[];\r\n fileAttachments?: AttachmentData[];\r\n isNewMessage?: boolean;\r\n}\r\n\r\n/**\r\n * Message group interface for grouped timestamp display\r\n */\r\ninterface MessageGroup {\r\n timestamp: Date;\r\n displayTimestamp: string;\r\n messages: ChatMessage[];\r\n}\r\n\r\n/**\r\n * Extended message interface with display metadata\r\n */\r\ninterface MessageDisplay extends ChatMessage {\r\n showAvatar: boolean;\r\n clusterPosition: 'single' | 'first' | 'middle' | 'last';\r\n isNewMessage?: boolean;\r\n}\r\n\r\n/**\r\n * Chat participant interface\r\n */\r\nexport interface ChatParticipant {\r\n id: string;\r\n name: string;\r\n role?: string;\r\n avatarInitials?: string;\r\n avatarType?: 'initials' | 'photo' | 'icon';\r\n avatarSrc?: string;\r\n badge?: string;\r\n verified?: boolean;\r\n lastActive?: string;\r\n}\r\n\r\n/**\r\n * Chat modal data interface\r\n *\r\n * Represents the data needed to display a chat conversation.\r\n *\r\n * @example\r\n * ```typescript\r\n * const chatData: ChatModalData = {\r\n * participant: {\r\n * id: 'u-123',\r\n * name: 'Ricki Meihlen',\r\n * role: 'Inquiry assignee',\r\n * avatarInitials: 'RM',\r\n * avatarType: 'initials'\r\n * },\r\n * currentUserId: 'u-456',\r\n * currentUserInitials: 'SD',\r\n * currentUserAvatarType: 'initials',\r\n * autoFocus: true,\r\n * messages: [\r\n * {\r\n * id: 'm-1',\r\n * content: 'We have received your case. Please see the attached photo.',\r\n * senderId: 'u-123',\r\n * senderName: 'Ricki Meihlen',\r\n * senderRole: 'Case worker',\r\n * timestamp: '12:34',\r\n * isOwnMessage: false,\r\n * avatarInitials: 'RM',\r\n * avatarType: 'initials',\r\n * attachments: [\r\n * {\r\n * id: 'a-1',\r\n * type: 'image',\r\n * url: 'https://example.com/photo.jpg',\r\n * name: 'photo.jpg',\r\n * thumbnail: 'https://example.com/photo_thumb.jpg'\r\n * },\r\n * {\r\n * id: 'a-2',\r\n * type: 'pdf',\r\n * url: 'https://example.com/report.pdf',\r\n * name: 'report.pdf'\r\n * }\r\n * ]\r\n * },\r\n * {\r\n * id: 'm-2',\r\n * content: 'Thanks — I will take a look.',\r\n * senderId: 'u-456',\r\n * senderName: 'You',\r\n * timestamp: '12:36',\r\n * isOwnMessage: true,\r\n * avatarInitials: 'SD',\r\n * avatarType: 'initials'\r\n * }\r\n * ]\r\n * };\r\n * ```\r\n */\r\nexport interface ChatModalData {\r\n /** The other participant in the conversation */\r\n participant: ChatParticipant;\r\n /** Array of messages in the conversation */\r\n messages: ChatMessage[];\r\n /** Current user's ID */\r\n currentUserId: string;\r\n /** Current user's avatar initials */\r\n currentUserInitials?: string;\r\n /** Current user's avatar type */\r\n currentUserAvatarType?: 'initials' | 'photo' | 'icon';\r\n /** Current user's avatar source */\r\n currentUserAvatarSrc?: string;\r\n /** Auto-focus input when modal opens */\r\n autoFocus?: boolean;\r\n /**\r\n * Callback executed when a message is sent from the chat.\r\n * Use this to handle API calls to your backend.\r\n */\r\n onSend?: (message: string, attachments: AttachmentData[]) => void | Promise<void>;\r\n /**\r\n * Optional callback for when a file attachment is clicked.\r\n * If not provided, the default behavior will try to open/download the file.\r\n */\r\n onFileClick?: (file: AttachmentData) => void;\r\n}\r\n\r\n/**\r\n * DsMobileChatModalComponent\r\n *\r\n * Modal component for displaying and managing chat conversations.\r\n * Follows the same pattern as post-detail-modal for consistent behavior.\r\n *\r\n * Features:\r\n * - Header with participant info and close button\r\n * - Scrollable message thread\r\n * - Fixed message composer at bottom\r\n * - Keyboard handling\r\n * - Safe area support\r\n *\r\n * This component is typically not used directly - use DsMobileChatModalService instead.\r\n *\r\n * @example\r\n * ```typescript\r\n * // Don't instantiate directly - use the service:\r\n * constructor(private chatModal: DsMobileChatModalService) {}\r\n *\r\n * openChat() {\r\n * this.chatModal.open({\r\n * participant: { id: '123', name: 'Ricki Meihlen' },\r\n * messages: [...],\r\n * currentUserId: '456'\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-chat-modal',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n DsAvatarWithBadgeComponent,\r\n DsMobileMessageComposerComponent,\r\n DsMobileMessageBubbleComponent,\r\n DsMobileModalBaseComponent,\r\n DsMobileCardInlineFileComponent,\r\n DsMobileSystemMessageBannerComponent,\r\n DsIconComponent,\r\n DsMobileSectionComponent,\r\n ],\r\n styleUrls: ['../shared/mobile-common.css', './ds-mobile-chat-modal.css'],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n template: `\r\n <ds-mobile-modal-base\r\n [loading]=\"loading\"\r\n [error]=\"error\"\r\n [headerTitle]=\"participant().name\"\r\n [headerMeta]=\"participant().role || ''\"\r\n [hasFixedBottom]=\"true\"\r\n [isAutoHeight]=\"false\"\r\n [enableKeyboardHandling]=\"true\"\r\n (keyboardWillShow)=\"handleKeyboardShow($event)\"\r\n closeButtonLabel=\"Luk chat\"\r\n >\r\n <!-- Header Avatar -->\r\n <ds-avatar-with-badge\r\n header-leading\r\n [initials]=\"participant().avatarInitials || ''\"\r\n [type]=\"participant().avatarType || 'initials'\"\r\n [src]=\"participant().avatarSrc || ''\"\r\n size=\"md\"\r\n />\r\n\r\n <!-- Messages Section -->\r\n <ds-mobile-section>\r\n <div class=\"chat-messages-container\" (click)=\"handleContentClick()\">\r\n <!-- Centered avatar section at top of messages -->\r\n <div class=\"chat-avatar-section\">\r\n <ds-avatar-with-badge\r\n [initials]=\"participant().avatarInitials || ''\"\r\n [type]=\"participant().avatarType || 'initials'\"\r\n [src]=\"participant().avatarSrc || ''\"\r\n [badge]=\"participant().badge\"\r\n size=\"xl\"\r\n />\r\n <div class=\"chat-avatar-info\">\r\n <div class=\"chat-avatar-name\">\r\n {{ participant().name }}\r\n @if (participant().verified) {\r\n <ds-icon name=\"remixCheckboxCircleFill\" size=\"24px\" [style.color]=\"'var(--color-primary-base)'\"></ds-icon>\r\n }\r\n </div>\r\n @if (participant().role) {\r\n <div class=\"chat-avatar-role\">{{ participant().role }}</div>\r\n }\r\n @if (participant().lastActive) {\r\n <div class=\"chat-avatar-meta\">{{ participant().lastActive }}</div>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div class=\"messages-list\">\r\n @if (messages().length === 0) {\r\n <!-- Empty State - Timestamp and System Message -->\r\n <div class=\"timestamp-header\">\r\n <span class=\"timestamp-text\">{{ getInitialTimestamp() }}</span>\r\n </div>\r\n\r\n <ds-mobile-system-message-banner [message]=\"participant().name + ' har overtaget din henvendelse og vil kontakte dig snart.'\" [afterTimestamp]=\"true\">\r\n </ds-mobile-system-message-banner>\r\n } @else {\r\n @for (group of messagesWithDisplay(); track group.timestamp) {\r\n <!-- Timestamp Header -->\r\n <div class=\"timestamp-header\">\r\n <span class=\"timestamp-text\">{{ group.displayTimestamp }}</span>\r\n </div>\r\n\r\n <!-- System message example (shown after first timestamp) -->\r\n @if ($first) {\r\n <ds-mobile-system-message-banner [message]=\"participant().name + ' har overtaget din henvendelse og vil kontakte dig snart.'\" [afterTimestamp]=\"true\">\r\n </ds-mobile-system-message-banner>\r\n }\r\n @for (message of group.messages; track message.id) {\r\n <!-- Only show bubble if has content -->\r\n @if (message.content.trim()) {\r\n <ds-mobile-message-bubble\r\n [content]=\"message.content\"\r\n [isOwnMessage]=\"message.isOwnMessage\"\r\n [timestamp]=\"formatMessageTimestamp(message.timestamp)\"\r\n [showTimestamp]=\"selectedMessageId() === message.id\"\r\n [avatarInitials]=\"message.avatarInitials || ''\"\r\n [avatarType]=\"message.avatarType || 'initials'\"\r\n [avatarSrc]=\"message.avatarSrc || ''\"\r\n [showAvatar]=\"message.showAvatar\"\r\n [clusterPosition]=\"message.clusterPosition\"\r\n [attachments]=\"message.attachments\"\r\n [clickable]=\"true\"\r\n [isNewMessage]=\"message.isNewMessage || false\"\r\n (messageClick)=\"handleMessageClick(message.id)\"\r\n (attachmentClick)=\"handleAttachmentClick($event)\"\r\n (longPress)=\"handleMessageLongPress(message)\"\r\n >\r\n </ds-mobile-message-bubble>\r\n }\r\n\r\n <!-- File attachments displayed below message bubble -->\r\n @if (message.fileAttachments && message.fileAttachments.length > 0) {\r\n <div class=\"message-file-attachments\" [class.own-message]=\"message.isOwnMessage\">\r\n @for (fileAttachment of message.fileAttachments; track fileAttachment.id) {\r\n <!-- Show inline image preview for image attachments -->\r\n @if (fileAttachment.type === 'image') {\r\n <div class=\"message-image-attachment\" (click)=\"handleImageClick(fileAttachment, message)\">\r\n <img [src]=\"fileAttachment.src\" [alt]=\"fileAttachment.name || 'Image'\" class=\"inline-image\" />\r\n </div>\r\n } @else {\r\n <!-- Show file card for non-image attachments -->\r\n <ds-mobile-card-inline-file\r\n [fileName]=\"fileAttachment.name || 'Unknown file'\"\r\n [fileSize]=\"fileAttachment.size || ''\"\r\n [variant]=\"getFileVariant(fileAttachment.type)\"\r\n [layout]=\"'compact'\"\r\n (fileClick)=\"handleFileAttachmentClick(fileAttachment)\"\r\n >\r\n </ds-mobile-card-inline-file>\r\n }\r\n }\r\n </div>\r\n }\r\n }\r\n }\r\n }\r\n </div>\r\n </div>\r\n </ds-mobile-section>\r\n\r\n <!-- Fixed message composer -->\r\n <div fixed-bottom>\r\n <ds-mobile-message-composer\r\n [avatarInitials]=\"currentUserInitials()\"\r\n [avatarType]=\"currentUserAvatarType()\"\r\n [avatarSrc]=\"currentUserAvatarSrc()\"\r\n [placeholder]=\"'Skriv en besked...'\"\r\n [autoFocus]=\"autoFocus()\"\r\n [showAttachmentButton]=\"true\"\r\n (messageSent)=\"handleMessageSent($event)\"\r\n (attachmentClicked)=\"handleComposerAttachmentClick()\"\r\n (attachmentsChanged)=\"handleAttachmentsChanged()\"\r\n >\r\n </ds-mobile-message-composer>\r\n </div>\r\n </ds-mobile-modal-base>\r\n `,\r\n})\r\nexport class DsMobileChatModalComponent implements OnInit, AfterViewInit {\r\n // Chat data passed from service\r\n @Input() chatData!: ChatModalData;\r\n\r\n /**\r\n * Loading state - when true, shows loading indicator\r\n */\r\n @Input() loading: boolean = false;\r\n\r\n /**\r\n * Error state - when set, shows error message\r\n */\r\n @Input() error?: string;\r\n\r\n /**\r\n * Back button click event\r\n */\r\n @Output() back = new EventEmitter<void>();\r\n\r\n // Signal for reactive chat data\r\n participant = signal<ChatParticipant>({\r\n id: '',\r\n name: '',\r\n avatarInitials: '',\r\n });\r\n\r\n messages = signal<ChatMessage[]>([]);\r\n currentUserInitials = signal<string>('');\r\n currentUserAvatarType = signal<'initials' | 'photo' | 'icon'>('initials');\r\n currentUserAvatarSrc = signal<string>('');\r\n autoFocus = signal<boolean>(false);\r\n\r\n /**\r\n * Selected message ID for showing timestamp\r\n */\r\n selectedMessageId = signal<string | null>(null);\r\n\r\n /**\r\n * Track if keyboard is currently visible\r\n */\r\n private isKeyboardVisible = false;\r\n\r\n /**\r\n * Timeout for auto-hiding timestamp\r\n */\r\n private timestampTimeout?: ReturnType<typeof setTimeout>;\r\n\r\n /**\r\n * Computed signal for grouped messages with timestamp headers\r\n */\r\n messageGroups = computed(() => {\r\n return this.groupMessagesByTime(this.messages(), 5);\r\n });\r\n\r\n /**\r\n * Computed signal for messages with display metadata (avatar visibility)\r\n */\r\n messagesWithDisplay = computed(() => {\r\n return this.addDisplayMetadata(this.messageGroups());\r\n });\r\n\r\n constructor(private lightboxService: DsMobileLightboxService) {}\r\n\r\n ngOnInit(): void {\r\n // Initialize chat data from input\r\n if (this.chatData) {\r\n this.participant.set(this.chatData.participant);\r\n this.messages.set(this.chatData.messages || []);\r\n this.currentUserInitials.set(this.chatData.currentUserInitials || '');\r\n this.currentUserAvatarType.set(this.chatData.currentUserAvatarType || 'initials');\r\n this.currentUserAvatarSrc.set(this.chatData.currentUserAvatarSrc || '');\r\n this.autoFocus.set(this.chatData.autoFocus || false);\r\n }\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n // Scroll to bottom when messages load\r\n if (this.messages().length > 0) {\r\n setTimeout(() => {\r\n this.scrollToBottom();\r\n }, 500);\r\n }\r\n }\r\n\r\n /**\r\n * Handle back button click\r\n */\r\n handleBack(): void {\r\n this.back.emit();\r\n }\r\n\r\n /**\r\n * Handle keyboard show event from base modal\r\n * Only scrolls to bottom if user is already near the bottom, otherwise lets\r\n * the natural padding expansion push content up (like Messenger/Signal/Telegram)\r\n */\r\n handleKeyboardShow(keyboardHeight: number): void {\r\n // Track keyboard state\r\n this.isKeyboardVisible = true;\r\n\r\n // Check if user is near bottom before auto-scrolling\r\n this.isNearBottom().then((isNear) => {\r\n if (isNear) {\r\n // User is already viewing latest messages, maintain that position\r\n // Small delay to synchronize with keyboard animation\r\n setTimeout(() => {\r\n this.scrollToBottom();\r\n }, 50);\r\n }\r\n // Otherwise, let the natural padding expansion push content up smoothly\r\n });\r\n }\r\n\r\n /**\r\n * Check if scroll position is near the bottom\r\n * Used to determine if we should auto-scroll when keyboard appears\r\n */\r\n private async isNearBottom(): Promise<boolean> {\r\n const ionContent = document.querySelector('ds-mobile-chat-modal ion-content');\r\n if (ionContent) {\r\n try {\r\n const scrollElement = await (ionContent as any).getScrollElement();\r\n const scrollTop = scrollElement.scrollTop;\r\n const scrollHeight = scrollElement.scrollHeight;\r\n const clientHeight = scrollElement.clientHeight;\r\n const threshold = 150; // pixels - consider \"near bottom\" within 150px\r\n\r\n const distanceFromBottom = scrollHeight - scrollTop - clientHeight;\r\n return distanceFromBottom <= threshold;\r\n } catch (e) {\r\n console.log('[ChatModal] Could not check scroll position:', e);\r\n // The provided snippet was syntactically incorrect for this location.\r\n // Assuming the intent was to add `auto-height` to the modal's CSS class,\r\n // this change should be applied where the modal is opened or in its template.\r\n // As per the instruction, the `isAutoHeight` property is added to the component.\r\n }\r\n }\r\n return true;\r\n }\r\n\r\n /**\r\n * Scroll to bottom of messages\r\n */\r\n private async scrollToBottom(): Promise<void> {\r\n const ionContent = document.querySelector('ds-mobile-chat-modal ion-content');\r\n if (ionContent) {\r\n // Scroll with smooth animation (400ms) and add a small offset to ensure visibility\r\n await (ionContent as any).scrollToBottom(400);\r\n }\r\n }\r\n\r\n /**\r\n * Handle message sent from composer\r\n */\r\n handleMessageSent(event: { content: string; isReply?: boolean; replyTo?: string; isEdit?: boolean; attachments?: AttachmentData[] }): void {\r\n const newMessage: ChatMessage = {\r\n id: Date.now().toString(),\r\n content: event.content,\r\n senderId: this.chatData.currentUserId,\r\n senderName: 'You',\r\n timestamp: new Date(),\r\n isOwnMessage: true,\r\n avatarInitials: this.currentUserInitials(),\r\n avatarType: this.currentUserAvatarType(),\r\n avatarSrc: this.currentUserAvatarSrc(),\r\n fileAttachments: event.attachments || [],\r\n isNewMessage: true, // Mark as new message to trigger animation\r\n };\r\n\r\n // Add message to list\r\n const updatedMessages = [...this.messages(), newMessage];\r\n this.messages.set(updatedMessages);\r\n\r\n // Remove the isNewMessage flag after animation completes (using spring-bouncy duration ~600ms)\r\n setTimeout(() => {\r\n const msgs = this.messages();\r\n const msgIndex = msgs.findIndex((m) => m.id === newMessage.id);\r\n if (msgIndex !== -1) {\r\n msgs[msgIndex].isNewMessage = false;\r\n this.messages.set([...msgs]);\r\n }\r\n }, 700);\r\n\r\n // Scroll to bottom after message is added and DOM updates\r\n // Multiple delays to ensure:\r\n // 1. DOM update from new message\r\n // 2. Composer height change (clears text/attachments)\r\n // 3. ResizeObserver updates padding\r\n requestAnimationFrame(() => {\r\n requestAnimationFrame(() => {\r\n setTimeout(() => {\r\n this.scrollToBottom();\r\n console.log('[ChatModal] Scrolled to bottom after message sent');\r\n }, 150);\r\n });\r\n });\r\n\r\n // Executing the onSend callback if provided\r\n if (this.chatData.onSend) {\r\n this.chatData.onSend(event.content, event.attachments || []);\r\n }\r\n }\r\n\r\n /**\r\n * Handle attachment click\r\n */\r\n handleAttachmentClick(attachment: ChatAttachment): void {\r\n if (attachment.type !== 'image') {\r\n if (attachment.url) {\r\n window.open(attachment.url, '_blank', 'noopener,noreferrer');\r\n }\r\n return;\r\n }\r\n\r\n const msgs = this.messages();\r\n\r\n const allImages: Array<{ msg: ChatMessage; att: ChatAttachment }> = [];\r\n for (const m of msgs) {\r\n for (const att of m.attachments ?? []) {\r\n if (att.type === 'image') {\r\n allImages.push({ msg: m, att });\r\n }\r\n }\r\n }\r\n\r\n const initialIndex = Math.max(\r\n 0,\r\n allImages.findIndex((x) => x.att.id === attachment.id),\r\n );\r\n\r\n const images: LightboxImage[] = allImages.map((x) => ({\r\n type: 'image',\r\n src: x.att.url,\r\n title: x.att.name,\r\n alt: x.att.name,\r\n thumbnail: x.att.thumbnail,\r\n }));\r\n\r\n const ownerMessage = allImages[initialIndex]?.msg;\r\n\r\n const author: LightboxAuthor | undefined = ownerMessage\r\n ? {\r\n name: ownerMessage.senderName,\r\n role: ownerMessage.senderRole,\r\n timestamp: this.formatMessageTimestamp(ownerMessage.timestamp),\r\n avatarInitials: ownerMessage.avatarInitials,\r\n avatarSrc: ownerMessage.avatarSrc,\r\n avatarType: ownerMessage.avatarType === 'photo' || ownerMessage.avatarType === 'initials' ? ownerMessage.avatarType : undefined,\r\n }\r\n : undefined;\r\n\r\n this.lightboxService.openImages({\r\n images,\r\n author,\r\n initialIndex,\r\n enableZoom: true,\r\n enableSwipe: true,\r\n showControls: true,\r\n showInfo: true,\r\n animation: 'fade',\r\n });\r\n }\r\n\r\n /**\r\n * Handle composer attachment button click\r\n */\r\n handleComposerAttachmentClick(): void {\r\n console.log('[ChatModal] Composer attachment button clicked');\r\n // In a real app, you would open a file picker or show attachment options\r\n }\r\n\r\n /**\r\n * Handle attachments changed (added or removed)\r\n * ResizeObserver automatically updates padding, which naturally pushes content up.\r\n * Only scroll to bottom if user is already viewing the latest messages.\r\n */\r\n handleAttachmentsChanged(): void {\r\n console.log('[ChatModal] Attachments changed - ResizeObserver will handle padding naturally');\r\n // ResizeObserver automatically:\r\n // 1. Detects composer height change\r\n // 2. Updates --fixed-bottom-height CSS variable\r\n // 3. Updates scroll element padding\r\n // 4. Smoothly pushes content up\r\n\r\n // Only scroll if user is already at bottom (optional - can be removed entirely)\r\n requestAnimationFrame(() => {\r\n requestAnimationFrame(() => {\r\n setTimeout(() => {\r\n this.isNearBottom().then((isNear) => {\r\n if (isNear) {\r\n // User is at bottom, maintain that position as composer expands\r\n this.scrollToBottom();\r\n }\r\n // Otherwise, let natural padding expansion push content up\r\n });\r\n }, 100);\r\n });\r\n });\r\n }\r\n\r\n /**\r\n * Handle content area click - dismiss keyboard when tapping messages\r\n */\r\n handleContentClick(): void {\r\n // Hide keyboard when tapping outside the composer\r\n Keyboard.hide()\r\n .then(() => {\r\n this.isKeyboardVisible = false;\r\n })\r\n .catch((e) => console.log('[ChatModal] Keyboard.hide() not available:', e));\r\n }\r\n\r\n /**\r\n * Get file variant for card-inline-file component\r\n */\r\n getFileVariant(type: string): 'pdf' | 'doc' {\r\n return type === 'pdf' ? 'pdf' : 'doc';\r\n }\r\n\r\n /**\r\n * Handle file attachment click\r\n */\r\n handleFileAttachmentClick(fileAttachment: AttachmentData): void {\r\n // If a custom handler is provided, use it\r\n if (this.chatData.onFileClick) {\r\n this.chatData.onFileClick(fileAttachment);\r\n return;\r\n }\r\n\r\n // Default behavior: Try to open/download the file\r\n const url = fileAttachment.src || (fileAttachment as any).url;\r\n if (url) {\r\n const link = document.createElement('a');\r\n link.href = url;\r\n link.target = '_blank';\r\n // If it has a name, setting download attribute suggests downloading\r\n if (fileAttachment.name) {\r\n link.download = fileAttachment.name;\r\n }\r\n\r\n document.body.appendChild(link);\r\n link.click();\r\n document.body.removeChild(link);\r\n } else {\r\n console.warn('[ChatModal] No URL or source for file attachment:', fileAttachment);\r\n }\r\n }\r\n\r\n /**\r\n * Handle image attachment click - opens lightbox\r\n */\r\n async handleImageClick(attachment: AttachmentData, message: ChatMessage): Promise<void> {\r\n await this.lightboxService.openImages({\r\n images: [\r\n {\r\n type: 'image',\r\n src: attachment.src,\r\n title: attachment.name || 'Image',\r\n alt: attachment.name || 'Chat image',\r\n },\r\n ],\r\n author: {\r\n name: message.senderName,\r\n role: message.senderRole,\r\n avatarInitials: message.avatarInitials,\r\n avatarType: message.avatarType === 'initials' ? 'initials' : 'photo',\r\n avatarSrc: message.avatarSrc,\r\n timestamp: this.formatMessageTimestamp(message.timestamp),\r\n },\r\n initialIndex: 0,\r\n enableZoom: true,\r\n showControls: false,\r\n enableSwipe: false,\r\n showInfo: false,\r\n showActions: false,\r\n });\r\n }\r\n\r\n /**\r\n * Handle message long press\r\n */\r\n handleMessageLongPress(message: ChatMessage): void {\r\n console.log('[ChatModal] Message long pressed:', message);\r\n // In a real app, you would show an action sheet with options (copy, delete, etc.)\r\n }\r\n\r\n /**\r\n * Handle message click to show/hide timestamp\r\n * Only shows timestamp if keyboard is already hidden\r\n */\r\n handleMessageClick(messageId: string): void {\r\n // If keyboard is visible, dismiss it and don't show timestamp\r\n if (this.isKeyboardVisible) {\r\n Keyboard.hide()\r\n .then(() => {\r\n this.isKeyboardVisible = false;\r\n })\r\n .catch((e) => console.log('[ChatModal] Keyboard.hide() not available:', e));\r\n return; // Exit early, don't toggle timestamp\r\n }\r\n\r\n // Keyboard is hidden, proceed with timestamp toggle\r\n // Clear existing timeout\r\n if (this.timestampTimeout) {\r\n clearTimeout(this.timestampTimeout);\r\n }\r\n\r\n // Toggle timestamp - if clicking same message, hide it; otherwise show new one\r\n this.selectedMessageId.update((current) => (current === messageId ? null : messageId));\r\n\r\n // Auto-hide after 3 seconds if showing\r\n if (this.selectedMessageId() === messageId) {\r\n this.timestampTimeout = setTimeout(() => {\r\n this.selectedMessageId.set(null);\r\n }, 3000);\r\n }\r\n }\r\n\r\n /**\r\n * Format message timestamp for display (EU 24-hour format, Danish)\r\n */\r\n formatMessageTimestamp(date: Date): string {\r\n return date.toLocaleTimeString('da-DK', {\r\n hour: '2-digit',\r\n minute: '2-digit',\r\n hour12: false,\r\n });\r\n }\r\n\r\n /**\r\n * Get initial timestamp for empty chat state\r\n * Returns current time formatted with smart date display\r\n */\r\n getInitialTimestamp(): string {\r\n return this.formatGroupTimestamp(new Date());\r\n }\r\n\r\n /**\r\n * Group messages by time threshold\r\n * Messages within the threshold and on the same day are grouped together\r\n */\r\n private groupMessagesByTime(messages: ChatMessage[], thresholdMinutes: number): MessageGroup[] {\r\n const groups: MessageGroup[] = [];\r\n let currentGroup: MessageGroup | null = null;\r\n\r\n messages.forEach((message) => {\r\n const messageDate = message.timestamp;\r\n\r\n // Start a new group if:\r\n // 1. It's the first message\r\n // 2. More than threshold minutes have passed since last message\r\n // 3. Date changed (new day)\r\n if (!currentGroup || this.shouldStartNewGroup(currentGroup.timestamp, messageDate, thresholdMinutes)) {\r\n currentGroup = {\r\n timestamp: messageDate,\r\n displayTimestamp: this.formatGroupTimestamp(messageDate),\r\n messages: [],\r\n };\r\n groups.push(currentGroup);\r\n }\r\n\r\n currentGroup.messages.push(message);\r\n });\r\n\r\n return groups;\r\n }\r\n\r\n /**\r\n * Determine if a new message group should be started\r\n */\r\n private shouldStartNewGroup(lastTime: Date, currentTime: Date, thresholdMinutes: number): boolean {\r\n const diffMinutes = (currentTime.getTime() - lastTime.getTime()) / (1000 * 60);\r\n\r\n // New group if different day\r\n if (lastTime.toDateString() !== currentTime.toDateString()) {\r\n return true;\r\n }\r\n\r\n // New group if threshold exceeded\r\n return diffMinutes > thresholdMinutes;\r\n }\r\n\r\n /**\r\n * Format group timestamp header with smart date display\r\n * Uses 24-hour EU time format with Danish locale\r\n */\r\n private formatGroupTimestamp(date: Date): string {\r\n const now = new Date();\r\n const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());\r\n const yesterday = new Date(today);\r\n yesterday.setDate(yesterday.getDate() - 1);\r\n\r\n const messageDate = new Date(date.getFullYear(), date.getMonth(), date.getDate());\r\n\r\n // Format time in 24-hour EU format\r\n const timeStr = date.toLocaleTimeString('da-DK', {\r\n hour: '2-digit',\r\n minute: '2-digit',\r\n hour12: false,\r\n });\r\n\r\n // Today: \"14:34\"\r\n if (messageDate.getTime() === today.getTime()) {\r\n return timeStr;\r\n }\r\n\r\n // Yesterday: \"I går, 14:34\"\r\n if (messageDate.getTime() === yesterday.getTime()) {\r\n return `I går, ${timeStr}`;\r\n }\r\n\r\n // This week: \"Mandag, 14:34\"\r\n const daysAgo = Math.floor((today.getTime() - messageDate.getTime()) / (1000 * 60 * 60 * 24));\r\n if (daysAgo < 7) {\r\n return date.toLocaleDateString('da-DK', { weekday: 'long' }) + `, ${timeStr}`;\r\n }\r\n\r\n // Older: \"15. jan, 14:34\" or \"20. dec. 2024, 14:34\" if different year\r\n const dateFormat: Intl.DateTimeFormatOptions = {\r\n month: 'short',\r\n day: 'numeric',\r\n };\r\n\r\n if (date.getFullYear() !== now.getFullYear()) {\r\n dateFormat.year = 'numeric';\r\n }\r\n\r\n return date.toLocaleDateString('da-DK', dateFormat) + `, ${timeStr}`;\r\n }\r\n\r\n /**\r\n * Add display metadata to message groups\r\n * Determines which messages should show avatars (only last in cluster)\r\n * and calculates cluster positions for border radius styling\r\n */\r\n private addDisplayMetadata(groups: MessageGroup[]): Array<MessageGroup & { messages: MessageDisplay[] }> {\r\n return groups.map((group) => {\r\n const messagesWithDisplay: MessageDisplay[] = [];\r\n\r\n for (let i = 0; i < group.messages.length; i++) {\r\n const currentMsg = group.messages[i];\r\n const prevMsg = group.messages[i - 1];\r\n const nextMsg = group.messages[i + 1];\r\n\r\n // Determine if this message starts a new cluster\r\n const startsCluster = !prevMsg || prevMsg.senderId !== currentMsg.senderId;\r\n // Determine if this message ends the cluster\r\n const endsCluster = !nextMsg || nextMsg.senderId !== currentMsg.senderId;\r\n\r\n // Show avatar only at the end of a cluster\r\n const showAvatar = endsCluster;\r\n\r\n // Determine cluster position for border radius\r\n let clusterPosition: 'single' | 'first' | 'middle' | 'last';\r\n if (startsCluster && endsCluster) {\r\n clusterPosition = 'single';\r\n } else if (startsCluster) {\r\n clusterPosition = 'first';\r\n } else if (endsCluster) {\r\n clusterPosition = 'last';\r\n } else {\r\n clusterPosition = 'middle';\r\n }\r\n\r\n messagesWithDisplay.push({\r\n ...currentMsg,\r\n showAvatar,\r\n clusterPosition,\r\n });\r\n }\r\n\r\n return {\r\n ...group,\r\n messages: messagesWithDisplay,\r\n };\r\n });\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { DsMobileChatModalComponent, ChatModalData } from './ds-mobile-chat-modal';\r\nimport { BaseModalService } from '../../services/base-modal.service';\r\n\r\n/**\r\n * DsMobileChatModalService\r\n *\r\n * Service for displaying chat conversations in a full-screen modal.\r\n * Built on Ionic's modal system with native gestures and animations.\r\n * Follows the same pattern as DsMobilePostDetailModalService for consistent behavior.\r\n *\r\n * Features:\r\n * - Full conversation display\r\n * - Message thread with bubbles\r\n * - Message composer\r\n * - Native modal animations\r\n * - Safe area support\r\n * - Keyboard handling\r\n *\r\n * @example\r\n * ```typescript\r\n * constructor(private chatModal: DsMobileChatModalService) {}\r\n *\r\n * async openChat() {\r\n * await this.chatModal.open({\r\n * participant: {\r\n * id: '123',\r\n * name: 'Ricki Meihlen',\r\n * role: 'Inquiry assignee',\r\n * avatarInitials: 'RM'\r\n * },\r\n * messages: [\r\n * {\r\n * id: '1',\r\n * content: 'We have received your case...',\r\n * senderId: '123',\r\n * senderName: 'Ricki Meihlen',\r\n * timestamp: '12:34',\r\n * isOwnMessage: false,\r\n * avatarInitials: 'RM'\r\n * },\r\n * {\r\n * id: '2',\r\n * content: 'Thank you!',\r\n * senderId: '456',\r\n * senderName: 'You',\r\n * timestamp: '12:35',\r\n * isOwnMessage: true,\r\n * avatarInitials: 'JD',\r\n * readStatus: true\r\n * }\r\n * ],\r\n * currentUserId: '456',\r\n * currentUserInitials: 'JD',\r\n * currentUserInitials: 'JD',\r\n * autoFocus: true,\r\n * onSend: async (message, attachments) => {\r\n * console.log('Sending message:', message);\r\n * // await this.chatService.sendMessage(participant.id, message, attachments);\r\n * },\r\n * onFileClick: (file) => {\r\n * console.log('File clicked:', file);\r\n * // window.open(file.url, '_blank');\r\n * }\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class DsMobileChatModalService extends BaseModalService {\r\n constructor(modalController: ModalController) {\r\n super(modalController);\r\n }\r\n\r\n /**\r\n * Open the chat modal\r\n *\r\n * @param chatData Chat data to display\r\n * @param options Optional loading and error states\r\n * @returns Promise that resolves when the modal is presented\r\n */\r\n async open(chatData: ChatModalData, options?: { loading?: boolean; error?: string }): Promise<void> {\r\n // console.log('[ChatModal] Opening with data:', chatData);\r\n\r\n const modal = await this.createModal(\r\n DsMobileChatModalComponent,\r\n {\r\n chatData: chatData,\r\n loading: options?.loading ?? false,\r\n error: options?.error,\r\n },\r\n {\r\n keyboardClose: true, // Keep keyboard close behavior for this modal\r\n cssClass: 'ds-modal-base',\r\n },\r\n );\r\n\r\n // console.log('[ChatModal] Modal created, presenting...');\r\n await modal.present();\r\n // console.log('[ChatModal] Modal presented');\r\n }\r\n}\r\n","import { Component, signal, Input, ViewChild, ElementRef, OnInit, AfterViewInit, CUSTOM_ELEMENTS_SCHEMA, inject } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { Capacitor } from '@capacitor/core';\r\nimport { FilePicker } from '@capawesome/capacitor-file-picker';\r\nimport { DsButtonComponent, DsTextareaComponent, DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { DsMobileModalBaseComponent } from '../modal-base/ds-mobile-modal-base';\r\nimport { DsMobileAttachmentPreviewComponent, type AttachmentData, type AttachmentFileType } from '../attachment-preview';\r\nimport { DsMobileSectionComponent } from '../section';\r\n\r\n/**\r\n * Photo interface for inquiry (deprecated - use AttachmentData)\r\n * @deprecated Use AttachmentData from attachment-preview component instead\r\n */\r\nexport interface InquiryPhoto {\r\n id: string;\r\n src: string;\r\n alt?: string;\r\n}\r\n\r\n/**\r\n * New inquiry form data\r\n */\r\nexport interface NewInquiryData {\r\n title: string;\r\n description: string;\r\n attachments: AttachmentData[];\r\n category?: string;\r\n}\r\n\r\n/**\r\n * DsMobileNewInquiryModalComponent\r\n *\r\n * Modal component for creating new inquiries.\r\n * Uses ds-mobile-modal-base for consistent layout and behavior.\r\n *\r\n * Features:\r\n * - Title and description fields\r\n * - Photo upload with preview\r\n * - Submit button at bottom\r\n * - Form validation\r\n * - Camera/photo picker integration\r\n *\r\n * This component is typically not used directly - use DsMobileNewInquiryModalService instead.\r\n *\r\n * @example\r\n * ```typescript\r\n * // Don't instantiate directly - use the service:\r\n * constructor(private inquiryModal: DsMobileNewInquiryModalService) {}\r\n *\r\n * createInquiry() {\r\n * this.inquiryModal.open({\r\n * onSubmit: (data) => console.log('Inquiry created:', data)\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-new-inquiry-modal',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n DsButtonComponent,\r\n DsTextareaComponent,\r\n DsIconButtonComponent,\r\n DsMobileModalBaseComponent,\r\n DsMobileAttachmentPreviewComponent,\r\n DsMobileSectionComponent,\r\n ],\r\n styleUrls: ['../shared/mobile-common.css', './ds-mobile-new-inquiry-modal.css'],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n template: `\r\n <ds-mobile-modal-base [loading]=\"loading\" [error]=\"error\" [showHeader]=\"false\" [hasFixedBottom]=\"true\" [enableKeyboardHandling]=\"true\" [keyboardContentBehavior]=\"'overlay'\" closeButtonLabel=\"Close\">\r\n <!-- Form Content -->\r\n <ds-mobile-section>\r\n <!-- Title Field (Large Ghost Textarea) -->\r\n <ds-textarea\r\n #titleInput\r\n [(ngModel)]=\"title\"\r\n [ghost]=\"true\"\r\n [required]=\"true\"\r\n [rows]=\"1\"\r\n [placeholder]=\"titlePlaceholder\"\r\n class=\"inquiry-title-input ghost-input-clean\"\r\n (valueChange)=\"handleTitleChange($event)\"\r\n />\r\n\r\n <!-- Description Field (Ghost Textarea) -->\r\n <ds-textarea\r\n #descriptionInput\r\n [(ngModel)]=\"description\"\r\n [ghost]=\"true\"\r\n [rows]=\"1\"\r\n [placeholder]=\"descriptionPlaceholder\"\r\n class=\"inquiry-description-input ghost-input-clean\"\r\n (valueChange)=\"handleDescriptionChange($event)\"\r\n />\r\n </ds-mobile-section>\r\n\r\n <!-- Fixed Bottom Container (Slides with keyboard) -->\r\n <div footer class=\"fixed-bottom-container\">\r\n <!-- Attachment Previews (if any) -->\r\n @if (attachments().length > 0) {\r\n <div class=\"attachment-previews-section\">\r\n <div class=\"image-previews\">\r\n @for (attachment of attachments(); track attachment.id) {\r\n <ds-mobile-attachment-preview [attachment]=\"attachment\" (remove)=\"removeAttachment($event)\" />\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Submit Actions Container -->\r\n <div class=\"submit-container\">\r\n <div class=\"submit-content\">\r\n <!-- Upload Actions (Left) -->\r\n <div class=\"upload-actions\">\r\n <ds-icon-button icon=\"remixImageLine\" variant=\"secondary\" size=\"md\" (clicked)=\"addPhoto()\" [disabled]=\"attachments().length >= 6\" aria-label=\"Add photo\">\r\n </ds-icon-button>\r\n <ds-icon-button\r\n icon=\"remixAttachmentLine\"\r\n variant=\"secondary\"\r\n size=\"md\"\r\n (clicked)=\"handleAddAttachment()\"\r\n [disabled]=\"attachments().length >= 6\"\r\n aria-label=\"Add attachment\"\r\n >\r\n </ds-icon-button>\r\n\r\n <!-- Hidden file input for file selection -->\r\n <input #fileInput type=\"file\" accept=\"*/*\" multiple (change)=\"handleFileSelect($event)\" style=\"display: none;\" aria-hidden=\"true\" />\r\n </div>\r\n\r\n <!-- Submit Button (Right) -->\r\n <ds-button class=\"submit-action-button\" variant=\"primary\" size=\"md\" [disabled]=\"!isFormValid() || isSubmitting()\" (clicked)=\"handleSubmit()\">\r\n {{ submitButtonLabel }}\r\n </ds-button>\r\n </div>\r\n </div>\r\n </div>\r\n </ds-mobile-modal-base>\r\n `,\r\n})\r\nexport class DsMobileNewInquiryModalComponent implements OnInit, AfterViewInit {\r\n private modalController = inject(ModalController);\r\n @ViewChild('titleInput', { read: ElementRef }) titleInputRef?: ElementRef<HTMLElement>;\r\n @ViewChild('descriptionInput', { read: ElementRef }) descriptionInputRef?: ElementRef<HTMLElement>;\r\n @ViewChild('titleInput') titleInput?: DsTextareaComponent;\r\n @ViewChild('fileInput') fileInput?: ElementRef<HTMLInputElement>;\r\n\r\n /**\r\n * Loading state for the modal\r\n */\r\n @Input() loading: boolean = false;\r\n\r\n /**\r\n * Error message to display\r\n */\r\n @Input() error?: string;\r\n\r\n /**\r\n * Callback function when form is submitted\r\n */\r\n @Input() onSubmit?: (data: NewInquiryData) => void | Promise<void>;\r\n\r\n /**\r\n * Placeholder for the title field\r\n */\r\n @Input() titlePlaceholder: string = 'Name your inquiry';\r\n\r\n /**\r\n * Placeholder for the description field\r\n */\r\n @Input() descriptionPlaceholder: string = 'Tell us what this inquiry is about...';\r\n\r\n /**\r\n * Label for the submit button\r\n */\r\n @Input() submitButtonLabel: string = 'Submit';\r\n\r\n /**\r\n * Form title field\r\n */\r\n title = '';\r\n\r\n /**\r\n * Form description field\r\n */\r\n description = '';\r\n\r\n /**\r\n * Attachments array (replaces photos)\r\n */\r\n attachments = signal<AttachmentData[]>([]);\r\n\r\n /**\r\n * Form validation state\r\n */\r\n isFormValid = signal<boolean>(false);\r\n\r\n /**\r\n * Submitting state\r\n */\r\n isSubmitting = signal<boolean>(false);\r\n\r\n ngOnInit(): void {\r\n console.log('[NewInquiryModal] Component initialized');\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n // Setup auto-resize for title textarea\r\n setTimeout(() => {\r\n this.autoResizeTitleTextarea();\r\n this.autoResizeDescriptionTextarea();\r\n\r\n // Focus the title textarea after view initialization to trigger keyboard on iOS\r\n if (this.titleInputRef) {\r\n const textareaElement = this.titleInputRef.nativeElement.querySelector('textarea');\r\n if (textareaElement) {\r\n textareaElement.focus();\r\n }\r\n }\r\n }, 300);\r\n }\r\n\r\n /**\r\n * Auto-resize the title textarea based on content\r\n */\r\n private autoResizeTitleTextarea(): void {\r\n if (!this.titleInputRef) return;\r\n\r\n // Access the native textarea element\r\n const textareaElement = this.titleInputRef.nativeElement.querySelector('textarea');\r\n if (textareaElement) {\r\n textareaElement.style.height = 'auto';\r\n textareaElement.style.height = textareaElement.scrollHeight + 'px';\r\n }\r\n }\r\n\r\n /**\r\n * Auto-resize the description textarea based on content\r\n */\r\n private autoResizeDescriptionTextarea(): void {\r\n if (!this.descriptionInputRef) return;\r\n\r\n const textareaElement = this.descriptionInputRef.nativeElement.querySelector('textarea');\r\n if (textareaElement) {\r\n textareaElement.style.height = 'auto';\r\n textareaElement.style.height = textareaElement.scrollHeight + 'px';\r\n }\r\n }\r\n\r\n /**\r\n * Handle title change with auto-resize\r\n */\r\n handleTitleChange(value: string): void {\r\n this.validateForm();\r\n this.autoResizeTitleTextarea();\r\n }\r\n\r\n /**\r\n * Handle description change with auto-resize\r\n */\r\n handleDescriptionChange(value: string): void {\r\n this.validateForm();\r\n this.autoResizeDescriptionTextarea();\r\n }\r\n\r\n /**\r\n * Validate form fields\r\n */\r\n validateForm(): void {\r\n const isValid = this.title.trim().length > 0 && this.description.trim().length > 0;\r\n this.isFormValid.set(isValid);\r\n }\r\n\r\n /**\r\n * Add a new photo from camera/library\r\n */\r\n async addPhoto(): Promise<void> {\r\n if (this.attachments().length >= 6) {\r\n return;\r\n }\r\n\r\n try {\r\n const result = await FilePicker.pickImages({\r\n limit: 1,\r\n });\r\n\r\n const image = result.files?.[0];\r\n if (image) {\r\n const newAttachment: AttachmentData = {\r\n id: `photo-${Date.now()}`,\r\n src: image.path ? Capacitor.convertFileSrc(image.path) : (image.blob ? URL.createObjectURL(image.blob) : ''),\r\n type: 'image',\r\n name: image.name || `Photo ${this.attachments().length + 1}`,\r\n size: this.formatFileSize(image.size ?? 0),\r\n };\r\n\r\n this.attachments.update((attachments) => [...attachments, newAttachment]);\r\n }\r\n } catch (error) {\r\n console.error('[NewInquiryModal] Error adding photo:', error);\r\n // User cancelled or error occurred - just ignore\r\n }\r\n }\r\n\r\n /**\r\n * Remove an attachment\r\n */\r\n removeAttachment(attachmentId: string): void {\r\n this.attachments.update((attachments) => attachments.filter((a) => a.id !== attachmentId));\r\n }\r\n\r\n /**\r\n * Handle attachment button click\r\n */\r\n handleAddAttachment(): void {\r\n if (this.attachments().length >= 6) {\r\n return;\r\n }\r\n\r\n // Trigger the hidden file input\r\n if (this.fileInput) {\r\n this.fileInput.nativeElement.click();\r\n }\r\n }\r\n\r\n /**\r\n * Detect file type from file name or mime type\r\n */\r\n private detectFileType(file: File): AttachmentFileType {\r\n const fileName = file.name.toLowerCase();\r\n const mimeType = file.type.toLowerCase();\r\n\r\n // Check if it's an image\r\n if (mimeType.startsWith('image/')) {\r\n return 'image';\r\n }\r\n\r\n // Check file extension\r\n if (fileName.endsWith('.pdf')) {\r\n return 'pdf';\r\n } else if (fileName.endsWith('.doc')) {\r\n return 'doc';\r\n } else if (fileName.endsWith('.docx')) {\r\n return 'docx';\r\n } else if (fileName.endsWith('.xls')) {\r\n return 'xls';\r\n } else if (fileName.endsWith('.xlsx')) {\r\n return 'xlsx';\r\n }\r\n\r\n return 'other';\r\n }\r\n\r\n /**\r\n * Format file size for display\r\n */\r\n private formatFileSize(bytes: number): string {\r\n if (bytes === 0) return '0 B';\r\n const k = 1024;\r\n const sizes = ['B', 'KB', 'MB', 'GB'];\r\n const i = Math.floor(Math.log(bytes) / Math.log(k));\r\n return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + ' ' + sizes[i];\r\n }\r\n\r\n /**\r\n * Handle file selection from file input\r\n */\r\n handleFileSelect(event: Event): void {\r\n const input = event.target as HTMLInputElement;\r\n const files = input.files;\r\n\r\n if (!files || files.length === 0) {\r\n return;\r\n }\r\n\r\n // Process each selected file (up to the limit)\r\n const remainingSlots = 6 - this.attachments().length;\r\n const filesToProcess = Array.from(files).slice(0, remainingSlots);\r\n\r\n filesToProcess.forEach((file) => {\r\n const fileType = this.detectFileType(file);\r\n\r\n // Create a data URL for preview\r\n const reader = new FileReader();\r\n reader.onload = (e) => {\r\n const result = e.target?.result as string;\r\n if (result) {\r\n const newAttachment: AttachmentData = {\r\n id: `file-${Date.now()}-${Math.random()}`,\r\n src: result,\r\n type: fileType,\r\n name: file.name,\r\n size: this.formatFileSize(file.size),\r\n };\r\n this.attachments.update((attachments) => [...attachments, newAttachment]);\r\n }\r\n };\r\n reader.readAsDataURL(file);\r\n });\r\n\r\n // Reset the input so the same file can be selected again\r\n input.value = '';\r\n }\r\n\r\n /**\r\n * Handle form submission\r\n */\r\n async handleSubmit(): Promise<void> {\r\n if (!this.isFormValid() || this.isSubmitting()) {\r\n return;\r\n }\r\n\r\n this.isSubmitting.set(true);\r\n\r\n try {\r\n const inquiryData: NewInquiryData = {\r\n title: this.title.trim(),\r\n description: this.description.trim(),\r\n attachments: this.attachments(),\r\n };\r\n\r\n console.log('[NewInquiryModal] Submitting inquiry:', inquiryData);\r\n\r\n if (this.onSubmit) {\r\n await this.onSubmit(inquiryData);\r\n }\r\n\r\n // Success - close the modal\r\n this.modalController.dismiss();\r\n } catch (error) {\r\n console.error('[NewInquiryModal] Error submitting inquiry:', error);\r\n this.error = 'Failed to create inquiry. Please try again.';\r\n } finally {\r\n this.isSubmitting.set(false);\r\n }\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { DsMobileNewInquiryModalComponent, NewInquiryData } from './ds-mobile-new-inquiry-modal';\r\nimport { BaseModalService } from '../../services/base-modal.service';\r\n\r\n/**\r\n * Options for opening the new inquiry modal\r\n */\r\nexport interface NewInquiryModalOptions {\r\n /** Callback function when inquiry is submitted */\r\n onSubmit?: (data: NewInquiryData) => void | Promise<void>;\r\n /** Initial loading state */\r\n loading?: boolean;\r\n /** Initial error message */\r\n error?: string;\r\n /** Custom placeholder for title field */\r\n titlePlaceholder?: string;\r\n /** Custom placeholder for description field */\r\n descriptionPlaceholder?: string;\r\n /** Custom label for submit button */\r\n submitButtonLabel?: string;\r\n}\r\n\r\n/**\r\n * DsMobileNewInquiryModalService\r\n *\r\n * Service for displaying the new inquiry creation modal.\r\n * Built on Ionic's modal system with native gestures and animations.\r\n *\r\n * Features:\r\n * - Full-screen modal with form\r\n * - Title and description inputs\r\n * - Photo upload with camera/gallery\r\n * - Form validation\r\n * - Submit handling\r\n * - Loading and error states\r\n *\r\n * @example\r\n * ```typescript\r\n * constructor(private newInquiryModal: DsMobileNewInquiryModalService) {}\r\n *\r\n * async createNewInquiry(): Promise<void> {\r\n * console.log('[InquiriesPage] FAB clicked, opening modal...');\r\n *\r\n * await this.newInquiryModal.open({\r\n * onSubmit: async (data) => {\r\n * console.log('Creating inquiry:', data);\r\n * // Call your API to create the inquiry\r\n * await this.apiService.createInquiry(data);\r\n * // Close the modal\r\n * await this.newInquiryModal.close();\r\n * }\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class DsMobileNewInquiryModalService extends BaseModalService {\r\n constructor(modalController: ModalController) {\r\n super(modalController);\r\n }\r\n\r\n /**\r\n * Open the new inquiry modal\r\n *\r\n * @param options Modal options including onSubmit callback\r\n * @returns Promise that resolves when the modal is presented\r\n */\r\n async open(options?: NewInquiryModalOptions): Promise<void> {\r\n // console.log('[NewInquiryModal] Opening modal with options:', options);\r\n\r\n const modal = await this.createModal(\r\n DsMobileNewInquiryModalComponent,\r\n {\r\n onSubmit: options?.onSubmit,\r\n loading: options?.loading ?? false,\r\n ...(options?.error && { error: options.error }),\r\n ...(options?.titlePlaceholder && { titlePlaceholder: options.titlePlaceholder }),\r\n ...(options?.descriptionPlaceholder && { descriptionPlaceholder: options.descriptionPlaceholder }),\r\n ...(options?.submitButtonLabel && { submitButtonLabel: options.submitButtonLabel }),\r\n },\r\n {\r\n keyboardClose: false, // Don't close on keyboard hide for this modal\r\n },\r\n );\r\n\r\n console.log('[NewInquiryModal] Modal created, presenting...');\r\n await modal.present();\r\n console.log('[NewInquiryModal] Modal presented');\r\n }\r\n}\r\n","import { Component, Input, signal, computed, CUSTOM_ELEMENTS_SCHEMA, ViewChild, AfterViewInit } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { DsIconComponent, DsButtonComponent, DsDatepickerComponent } from '@propbinder/design-system';\r\nimport { DsMobileModalBaseComponent } from '../modal-base/ds-mobile-modal-base';\r\nimport { DsMobileSectionComponent } from '../section';\r\nimport { DsMobileSwiperComponent } from '../swiper/ds-mobile-swiper';\r\n\r\n/**\r\n * Date option interface for date selection\r\n */\r\nexport interface DateOption {\r\n id: string;\r\n dayName: string; // \"Tue\"\r\n date: string; // \"19\"\r\n monthName: string; // \"Nov\"\r\n fullDate: Date;\r\n state: 'default' | 'selected' | 'disabled';\r\n}\r\n\r\n/**\r\n * Time slot interface for time selection\r\n */\r\nexport interface TimeSlot {\r\n id: string;\r\n startTime: string; // \"14:00\"\r\n endTime: string; // \"16:00\"\r\n state: 'default' | 'selected' | 'disabled';\r\n}\r\n\r\n/**\r\n * Booking result returned when user confirms booking\r\n */\r\nexport interface BookingResult {\r\n facilityId: string;\r\n facilityTitle: string;\r\n selectedDate: DateOption;\r\n selectedTimeSlot: TimeSlot;\r\n timestamp: Date;\r\n}\r\n\r\n/**\r\n * DsMobileBookingModalComponent\r\n * \r\n * Full-screen modal for booking facilities with date and time selection.\r\n * Features swipeable date selection and vertical time slot list.\r\n * \r\n * @example\r\n * ```typescript\r\n * const modal = await modalController.create({\r\n * component: DsMobileBookingModalComponent,\r\n * componentProps: {\r\n * facilityId: 'facility-1',\r\n * facilityTitle: 'Boremaskinen'\r\n * }\r\n * });\r\n * await modal.present();\r\n * const result = await modal.onWillDismiss<BookingResult>();\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-booking-modal',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n DsMobileModalBaseComponent,\r\n DsMobileSectionComponent,\r\n DsMobileSwiperComponent,\r\n DsIconComponent,\r\n DsButtonComponent,\r\n DsDatepickerComponent\r\n ],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n styles: [`\r\n /* Date item styles */\r\n .date-item {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n width: 80px;\r\n padding: 12px 8px;\r\n border-radius: 12px;\r\n border: 1px solid var(--color-border, #e5e5e5);\r\n background: var(--color-surface-primary, #ffffff);\r\n cursor: pointer;\r\n transition: all 200ms ease;\r\n -webkit-tap-highlight-color: transparent;\r\n gap: 4px;\r\n }\r\n\r\n .date-item .day-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs, 12px);\r\n font-weight: 400;\r\n color: var(--text-color-default-secondary, #71727a);\r\n text-transform: uppercase;\r\n }\r\n\r\n .date-item .date-number {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xl, 20px);\r\n font-weight: 600;\r\n color: var(--text-color-default-primary, #202227);\r\n }\r\n\r\n .date-item .month-name {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs, 12px);\r\n font-weight: 400;\r\n color: var(--text-color-default-secondary, #71727a);\r\n text-transform: capitalize;\r\n }\r\n\r\n /* Selected state */\r\n .date-item.selected {\r\n background: var(--color-accent, #5d5fef);\r\n border-color: var(--color-accent, #5d5fef);\r\n }\r\n\r\n .date-item.selected .day-name,\r\n .date-item.selected .date-number,\r\n .date-item.selected .month-name {\r\n color: #ffffff;\r\n }\r\n\r\n /* Disabled state */\r\n .date-item.disabled {\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-color: var(--color-border, #e5e5e5);\r\n cursor: not-allowed;\r\n opacity: 0.6;\r\n }\r\n\r\n .date-item.disabled .day-name,\r\n .date-item.disabled .date-number,\r\n .date-item.disabled .month-name {\r\n color: var(--text-color-default-tertiary, #9a9aa2);\r\n }\r\n\r\n /* Hover effect for non-disabled items */\r\n .date-item:not(.disabled):not(.selected):hover {\r\n border-color: var(--color-accent, #5d5fef);\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n }\r\n\r\n /* Time slots list */\r\n .time-slots-list {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n }\r\n\r\n .time-slot-item {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n width: 100%;\r\n padding: 16px 20px;\r\n border-radius: 12px;\r\n border: 1px solid var(--color-border, #e5e5e5);\r\n background: var(--color-surface-primary, #ffffff);\r\n cursor: pointer;\r\n transition: all 200ms ease;\r\n -webkit-tap-highlight-color: transparent;\r\n }\r\n\r\n .time-slot-item span {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base, 16px);\r\n font-weight: 400;\r\n color: var(--text-color-default-primary, #202227);\r\n }\r\n\r\n /* Selected state */\r\n .time-slot-item.selected {\r\n background: var(--color-accent, #5d5fef);\r\n border-color: var(--color-accent, #5d5fef);\r\n }\r\n\r\n .time-slot-item.selected span {\r\n color: #ffffff;\r\n font-weight: 500;\r\n }\r\n\r\n /* Disabled state */\r\n .time-slot-item.disabled {\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-color: var(--color-border, #e5e5e5);\r\n cursor: not-allowed;\r\n opacity: 0.6;\r\n }\r\n\r\n .time-slot-item.disabled span {\r\n color: var(--text-color-default-tertiary, #9a9aa2);\r\n }\r\n\r\n /* Hover effect for non-disabled items */\r\n .time-slot-item:not(.disabled):not(.selected):hover {\r\n border-color: var(--color-accent, #5d5fef);\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n }\r\n\r\n /* Fixed bottom button */\r\n .booking-confirm-action {\r\n width: 100%;\r\n padding: 16px 20px;\r\n background: var(--color-surface-primary, #ffffff);\r\n border-top: 1px solid var(--color-border, #e5e5e5);\r\n box-sizing: border-box;\r\n }\r\n\r\n .booking-confirm-action ::ng-deep ds-button {\r\n display: block;\r\n width: 100%;\r\n }\r\n\r\n .booking-confirm-action ::ng-deep ds-button button {\r\n width: 100%;\r\n border-radius: 100px;\r\n height: 48px;\r\n }\r\n\r\n /* Swiper slide adjustments */\r\n ::ng-deep .date-swiper .swiper-slide {\r\n width: auto !important;\r\n }\r\n\r\n /* Styled to match ds-mobile-section's .section-link */\r\n .calendar-link {\r\n display: flex;\r\n align-items: center;\r\n gap: 2px;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 500;\r\n color: var(--color-accent, #5d5fef);\r\n cursor: pointer;\r\n white-space: nowrap;\r\n user-select: none;\r\n line-height: 1;\r\n }\r\n\r\n /* Ensure the CDK overlay renders above the Ionic modal stack */\r\n ::ng-deep .cdk-overlay-container {\r\n z-index: 20001;\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-modal-base \r\n headerTitle=\"Hvornår skal det være?\"\r\n [showCloseButton]=\"true\"\r\n [hasFixedBottom]=\"true\"\r\n (closeClicked)=\"handleClose()\">\r\n \r\n <!-- Date Section -->\r\n <ds-mobile-section headline=\"Vælg dato\">\r\n <ds-datepicker\r\n header-action\r\n [isDateDisabled]=\"dateDisabledFn()\"\r\n (dateChange)=\"jumpToDate($event)\">\r\n <span class=\"calendar-link\">\r\n {{ selectFromCalendarText }}\r\n <ds-icon name=\"remixArrowRightSLine\" size=\"16px\" />\r\n </span>\r\n </ds-datepicker>\r\n\r\n <ds-mobile-swiper \r\n class=\"date-swiper\"\r\n [slideWidth]=\"'auto'\" \r\n [gap]=\"12\">\r\n @for (date of dateOptions(); track date.id) {\r\n <div class=\"swiper-slide\">\r\n <button \r\n class=\"date-item\" \r\n [class.selected]=\"date.state === 'selected'\" \r\n [class.disabled]=\"date.state === 'disabled'\"\r\n [disabled]=\"date.state === 'disabled'\"\r\n (click)=\"selectDate(date)\">\r\n <span class=\"day-name\">{{ date.dayName }}</span>\r\n <span class=\"date-number\">{{ date.date }}</span>\r\n <span class=\"month-name\">{{ date.monthName }}</span>\r\n </button>\r\n </div>\r\n }\r\n </ds-mobile-swiper>\r\n </ds-mobile-section>\r\n\r\n <!-- Time Section -->\r\n <ds-mobile-section headline=\"Vælg tidspunkt\">\r\n <div class=\"time-slots-list\">\r\n @for (slot of timeSlots(); track slot.id) {\r\n <button \r\n class=\"time-slot-item\" \r\n [class.selected]=\"slot.state === 'selected'\" \r\n [class.disabled]=\"slot.state === 'disabled'\"\r\n [disabled]=\"slot.state === 'disabled'\"\r\n (click)=\"selectTime(slot)\">\r\n <span>{{ slot.startTime }} - {{ slot.endTime }}</span>\r\n @if (slot.state === 'selected') {\r\n <ds-icon name=\"remixCheckLine\" size=\"20px\" color=\"#ffffff\" />\r\n }\r\n </button>\r\n }\r\n </div>\r\n </ds-mobile-section>\r\n\r\n <!-- Fixed Bottom Button -->\r\n <div fixed-bottom class=\"booking-confirm-action\">\r\n <ds-button \r\n size=\"lg\" \r\n variant=\"primary\" \r\n [fullWidth]=\"true\" \r\n [disabled]=\"!canConfirm()\"\r\n [loading]=\"isConfirming()\"\r\n (clicked)=\"handleConfirm()\">\r\n {{ confirmBookingText }}\r\n </ds-button>\r\n </div>\r\n </ds-mobile-modal-base>\r\n `\r\n})\r\nexport class DsMobileBookingModalComponent implements AfterViewInit {\r\n @Input() facilityId!: string;\r\n @Input() facilityTitle!: string;\r\n /**\r\n * Number of days ahead available for booking selection.\r\n * Defaults to 60 (2 months). Override via componentProps when opening the modal.\r\n */\r\n @Input() daysAhead: number = 60;\r\n \r\n @Input() selectFromCalendarText: string = 'Vælg fra kalender';\r\n @Input() confirmBookingText: string = 'Bekræft booking';\r\n @Input() availableDates?: DateOption[];\r\n @Input() availableTimeSlots?: Record<string, TimeSlot[]>;\r\n\r\n @ViewChild(DsMobileSwiperComponent) swiperComponent?: DsMobileSwiperComponent;\r\n\r\n // Signals for reactive state management\r\n dateOptions = signal<DateOption[]>([]);\r\n timeSlots = signal<TimeSlot[]>([]);\r\n \r\n selectedDate = signal<DateOption | null>(null);\r\n selectedTimeSlot = signal<TimeSlot | null>(null);\r\n isConfirming = signal<boolean>(false);\r\n\r\n // Computed property for button state\r\n canConfirm = computed(() => {\r\n return this.selectedDate() !== null && this.selectedTimeSlot() !== null && !this.isConfirming();\r\n });\r\n\r\n constructor(private modalController: ModalController) {\r\n this.generateMockData();\r\n }\r\n\r\n /**\r\n * After view init - force swiper update to fix initial positioning\r\n */\r\n ngAfterViewInit(): void {\r\n // Use a slightly longer timeout to ensure swiper is fully initialized\r\n setTimeout(() => {\r\n if (this.swiperComponent && (this.swiperComponent as any).swiperInstance) {\r\n const swiperInstance = (this.swiperComponent as any).swiperInstance;\r\n // Update swiper to recalculate positions\r\n swiperInstance.update();\r\n // Slide to first slide to ensure proper centering\r\n swiperInstance.slideTo(0, 0);\r\n }\r\n }, 150);\r\n }\r\n\r\n /**\r\n * Returns true if the given date should be disabled in both the swiper and the datepicker.\r\n * Weekends are disabled. Index-based mock disabling (i===3, i===7) is swiper-only and\r\n * not representable as a date rule, so it is intentionally excluded here.\r\n */\r\n private isDateUnavailable(date: Date): boolean {\r\n return date.getDay() === 0 || date.getDay() === 6;\r\n }\r\n\r\n /**\r\n * Computed signal that returns a fresh disabled-date function whenever dateOptions()\r\n * changes. Returning a new function reference causes the datepicker's own isDateDisabled\r\n * input to update, which triggers its internal computed to re-run and re-render all\r\n * calendar cells with the correct disabled state.\r\n * The disabledSet is pre-built once per computation for O(1) per-cell lookups.\r\n */\r\n dateDisabledFn = computed(() => {\r\n const disabledSet = new Set(\r\n this.dateOptions()\r\n .filter(opt => opt.state === 'disabled')\r\n .map(opt => opt.fullDate.toDateString())\r\n );\r\n\r\n return (date: Date): boolean => {\r\n const today = new Date(); today.setHours(0, 0, 0, 0);\r\n const max = new Date(today); max.setDate(today.getDate() + this.daysAhead - 1);\r\n const d = new Date(date); d.setHours(0, 0, 0, 0);\r\n if (d < today || d > max) return true;\r\n return disabledSet.has(date.toDateString());\r\n };\r\n });\r\n\r\n /**\r\n * Generate mock date and time data or use provided available data\r\n */\r\n private generateMockData(): void {\r\n if (this.availableDates && this.availableDates.length > 0) {\r\n this.dateOptions.set(this.availableDates);\r\n \r\n const firstAvailableDate = this.availableDates.find(d => d.state !== 'disabled') || this.availableDates[0];\r\n if (firstAvailableDate) {\r\n // Ensure strictly one selected\r\n const updatedDates = this.availableDates.map(date => ({\r\n ...date,\r\n state: date.id === firstAvailableDate.id ? 'selected' as const : \r\n (date.state === 'disabled' ? 'disabled' as const : 'default' as const)\r\n }));\r\n this.dateOptions.set(updatedDates);\r\n \r\n const selectedRef = updatedDates.find(d => d.id === firstAvailableDate.id);\r\n if (selectedRef) {\r\n this.selectedDate.set(selectedRef);\r\n this.generateTimeSlots(selectedRef.fullDate, selectedRef.date);\r\n }\r\n }\r\n return;\r\n }\r\n\r\n const dates: DateOption[] = [];\r\n const today = new Date();\r\n \r\n const dayNames = ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'];\r\n const monthNames = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];\r\n \r\n let firstAvailableDate: DateOption | null = null;\r\n \r\n for (let i = 0; i < this.daysAhead; i++) {\r\n const date = new Date(today);\r\n date.setDate(today.getDate() + i);\r\n \r\n const isDisabled = this.isDateUnavailable(date) || (i === 3) || (i === 7);\r\n \r\n const dateOption: DateOption = {\r\n id: `date-${i}`,\r\n dayName: dayNames[date.getDay()],\r\n date: date.getDate().toString(),\r\n monthName: monthNames[date.getMonth()],\r\n fullDate: date,\r\n state: isDisabled ? 'disabled' : 'default'\r\n };\r\n \r\n // Track the first available (non-disabled) date\r\n if (!isDisabled && !firstAvailableDate) {\r\n firstAvailableDate = dateOption;\r\n dateOption.state = 'selected'; // Set as selected\r\n }\r\n \r\n dates.push(dateOption);\r\n }\r\n \r\n this.dateOptions.set(dates);\r\n \r\n // Set the first available date as selected and generate time slots for it\r\n if (firstAvailableDate) {\r\n this.selectedDate.set(firstAvailableDate);\r\n this.generateTimeSlots(firstAvailableDate.fullDate, firstAvailableDate.date);\r\n } else {\r\n // Fallback to today if no available dates\r\n this.generateTimeSlots(today);\r\n }\r\n }\r\n\r\n /**\r\n * Generate time slots based on selected date and dynamic available timeslots\r\n */\r\n private generateTimeSlots(date: Date, dateStringKey?: string): void {\r\n if (this.availableTimeSlots && dateStringKey && this.availableTimeSlots[dateStringKey]) {\r\n this.timeSlots.set(this.availableTimeSlots[dateStringKey]);\r\n return;\r\n }\r\n\r\n const slots: TimeSlot[] = [];\r\n const currentHour = new Date().getHours();\r\n const isToday = date.toDateString() === new Date().toDateString();\r\n \r\n // Generate time slots from 08:00 to 20:00 in 2-hour increments\r\n const startHour = 8;\r\n const endHour = 20;\r\n \r\n for (let hour = startHour; hour < endHour; hour += 2) {\r\n const startTime = `${hour.toString().padStart(2, '0')}:00`;\r\n const endTime = `${(hour + 2).toString().padStart(2, '0')}:00`;\r\n \r\n // Disable past times if today is selected\r\n const isPast = isToday && hour < currentHour;\r\n // Randomly disable some slots for demo purposes\r\n const isRandomlyDisabled = Math.random() > 0.7;\r\n const isDisabled = isPast || isRandomlyDisabled;\r\n \r\n slots.push({\r\n id: `slot-${hour}`,\r\n startTime,\r\n endTime,\r\n state: isDisabled ? 'disabled' : 'default'\r\n });\r\n }\r\n \r\n this.timeSlots.set(slots);\r\n }\r\n\r\n /**\r\n * Handle date selection\r\n */\r\n selectDate(selectedDate: DateOption): void {\r\n if (selectedDate.state === 'disabled') return;\r\n \r\n // Update date options\r\n const updatedDates = this.dateOptions().map(date => ({\r\n ...date,\r\n state: date.id === selectedDate.id ? 'selected' as const : \r\n (date.state === 'disabled' ? 'disabled' as const : 'default' as const)\r\n }));\r\n \r\n this.dateOptions.set(updatedDates);\r\n this.selectedDate.set(selectedDate);\r\n \r\n // Regenerate time slots for the selected date\r\n this.generateTimeSlots(selectedDate.fullDate, selectedDate.date);\r\n \r\n // Reset time selection\r\n this.selectedTimeSlot.set(null);\r\n }\r\n\r\n /**\r\n * Handle time slot selection\r\n */\r\n selectTime(selectedSlot: TimeSlot): void {\r\n if (selectedSlot.state === 'disabled') return;\r\n \r\n // Update time slots\r\n const updatedSlots = this.timeSlots().map(slot => ({\r\n ...slot,\r\n state: slot.id === selectedSlot.id ? 'selected' as const : \r\n (slot.state === 'disabled' ? 'disabled' as const : 'default' as const)\r\n }));\r\n \r\n this.timeSlots.set(updatedSlots);\r\n this.selectedTimeSlot.set(selectedSlot);\r\n }\r\n\r\n /**\r\n * Called when the datepicker overlay emits a date selection.\r\n * Finds the matching DateOption in the swiper, selects it, and auto-scrolls to it.\r\n */\r\n jumpToDate(date: Date | null): void {\r\n if (!date) return;\r\n const options = this.dateOptions();\r\n const idx = options.findIndex(\r\n opt => opt.fullDate.toDateString() === date.toDateString()\r\n );\r\n if (idx === -1) return;\r\n const option = options[idx];\r\n if (option.state === 'disabled') return;\r\n this.selectDate(option);\r\n this.swiperComponent?.slideTo(idx);\r\n }\r\n\r\n /**\r\n * Handle confirm button click\r\n */\r\n async handleConfirm(): Promise<void> {\r\n if (!this.canConfirm()) return;\r\n \r\n // Set loading state\r\n this.isConfirming.set(true);\r\n \r\n // Simulate booking API call with 2 second delay\r\n await new Promise(resolve => setTimeout(resolve, 2000));\r\n \r\n const result: BookingResult = {\r\n facilityId: this.facilityId,\r\n facilityTitle: this.facilityTitle,\r\n selectedDate: this.selectedDate()!,\r\n selectedTimeSlot: this.selectedTimeSlot()!,\r\n timestamp: new Date()\r\n };\r\n \r\n await this.modalController.dismiss(result, 'confirm');\r\n }\r\n\r\n /**\r\n * Handle close button click\r\n */\r\n async handleClose(): Promise<void> {\r\n await this.modalController.dismiss(null, 'cancel');\r\n }\r\n}\r\n","import { Component, Input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobileBookingSummaryComponent\r\n * \r\n * Displays a booking summary with facility info, thumbnail, date and time.\r\n * Designed to be used within the generic confirmation sheet.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-booking-summary\r\n * [facilityTitle]=\"'Festlokale på taget'\"\r\n * [facilityThumbnail]=\"'/path/to/image.jpg'\"\r\n * [date]=\"'Tue 19 Nov'\"\r\n * [time]=\"'14:00 - 16:00'\"\r\n * />\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-booking-summary',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent],\r\n styles: [`\r\n .booking-summary {\r\n width: 100%;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-radius: 16px;\r\n padding: 12px;\r\n }\r\n\r\n .summary-item {\r\n display: flex;\r\n gap: 12px;\r\n align-items: flex-start;\r\n }\r\n\r\n .summary-thumbnail {\r\n width: 48px;\r\n height: 48px;\r\n border-radius: 8px;\r\n object-fit: cover;\r\n flex-shrink: 0;\r\n background: var(--color-background-neutral-tertiary, #e5e5e5);\r\n }\r\n\r\n .summary-thumbnail-placeholder {\r\n width: 48px;\r\n height: 48px;\r\n border-radius: 8px;\r\n flex-shrink: 0;\r\n background: var(--color-background-neutral-tertiary, #e5e5e5);\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n\r\n .summary-details {\r\n flex: 1;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n }\r\n\r\n .summary-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base, 16px);\r\n font-weight: 600;\r\n color: var(--text-color-default-primary, #202227);\r\n margin: 0;\r\n }\r\n\r\n .summary-datetime-container {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n flex-wrap: wrap;\r\n }\r\n\r\n .summary-datetime {\r\n display: flex;\r\n align-items: center;\r\n gap: 6px;\r\n }\r\n\r\n .summary-datetime-text {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm, 14px);\r\n font-weight: 400;\r\n color: var(--text-color-default-secondary, #71727a);\r\n }\r\n\r\n .summary-datetime ds-icon {\r\n flex-shrink: 0;\r\n }\r\n `],\r\n template: `\r\n <div class=\"booking-summary\">\r\n <div class=\"summary-item\">\r\n @if (facilityThumbnail) {\r\n <img \r\n [src]=\"facilityThumbnail\" \r\n [alt]=\"facilityTitle\"\r\n class=\"summary-thumbnail\" />\r\n } @else {\r\n <div class=\"summary-thumbnail-placeholder\">\r\n <ds-icon name=\"remixImageLine\" size=\"24px\" />\r\n </div>\r\n }\r\n \r\n <div class=\"summary-details\">\r\n <h3 class=\"summary-title\">{{ facilityTitle }}</h3>\r\n \r\n <div class=\"summary-datetime-container\">\r\n @if (date) {\r\n <div class=\"summary-datetime\">\r\n <ds-icon \r\n name=\"remixCalendarLine\" \r\n size=\"16px\" \r\n color=\"var(--text-color-default-secondary, #71727a)\" />\r\n <span class=\"summary-datetime-text\">{{ date }}</span>\r\n </div>\r\n }\r\n \r\n @if (time) {\r\n <div class=\"summary-datetime\">\r\n <ds-icon \r\n name=\"remixTimeLine\" \r\n size=\"16px\" \r\n color=\"var(--text-color-default-secondary, #71727a)\" />\r\n <span class=\"summary-datetime-text\">{{ time }}</span>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n `\r\n})\r\nexport class DsMobileBookingSummaryComponent {\r\n /**\r\n * Facility title\r\n */\r\n @Input({ required: true }) facilityTitle!: string;\r\n\r\n /**\r\n * Optional facility thumbnail URL\r\n */\r\n @Input() facilityThumbnail?: string;\r\n\r\n /**\r\n * Formatted date string (e.g., \"Tue 19 Nov\")\r\n */\r\n @Input() date?: string;\r\n\r\n /**\r\n * Formatted time string (e.g., \"14:00 - 16:00\")\r\n */\r\n @Input() time?: string;\r\n}\r\n","import { Component, Input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsMobileConfirmationSheetComponent } from '../bottom-sheet/ds-mobile-confirmation-sheet';\r\nimport { DsMobileBookingSummaryComponent } from './ds-mobile-booking-summary';\r\nimport { BookingResult } from './ds-mobile-booking-modal';\r\n\r\n/**\r\n * DsMobileBookingConfirmationWrapperComponent\r\n * \r\n * Wrapper component that uses the generic confirmation sheet\r\n * specifically for booking confirmations.\r\n * \r\n * This component handles the booking-specific formatting and\r\n * uses content projection to pass the booking summary to the generic sheet.\r\n */\r\n@Component({\r\n selector: 'ds-mobile-booking-confirmation-wrapper',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n DsMobileConfirmationSheetComponent,\r\n DsMobileBookingSummaryComponent\r\n ],\r\n template: `\r\n <ds-mobile-confirmation-sheet\r\n [title]=\"'Booking accepteret'\"\r\n [message]=\"confirmationMessage\"\r\n [buttonText]=\"'Luk'\"\r\n [illustrationVariant]=\"'confirmation'\">\r\n <ng-template #summary>\r\n <ds-mobile-booking-summary\r\n [facilityTitle]=\"booking.facilityTitle\"\r\n [facilityThumbnail]=\"facilityThumbnail\"\r\n [date]=\"formattedDate\"\r\n [time]=\"formattedTime\"\r\n />\r\n </ng-template>\r\n </ds-mobile-confirmation-sheet>\r\n `\r\n})\r\nexport class DsMobileBookingConfirmationWrapperComponent {\r\n @Input() booking!: BookingResult;\r\n @Input() facilityThumbnail?: string;\r\n\r\n get confirmationMessage(): string {\r\n const date = this.booking.selectedDate.fullDate;\r\n const dateStr = this.formatFullDate(date);\r\n return `Din booking til den ${dateStr} er bekræftet. Du kan annullere fra startdatoen.`;\r\n }\r\n\r\n get formattedDate(): string {\r\n const { dayName, date, monthName } = this.booking.selectedDate;\r\n return `${dayName} ${date} ${monthName}`;\r\n }\r\n\r\n get formattedTime(): string {\r\n const { startTime, endTime } = this.booking.selectedTimeSlot;\r\n return `${startTime} - ${endTime}`;\r\n }\r\n\r\n private formatFullDate(date: Date): string {\r\n const day = date.getDate();\r\n const monthNames = [\r\n 'januar', 'februar', 'marts', 'april', 'maj', 'juni',\r\n 'juli', 'august', 'september', 'oktober', 'november', 'december'\r\n ];\r\n const month = monthNames[date.getMonth()];\r\n const year = date.getFullYear();\r\n return `${day}. ${month}, ${year}`;\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { BaseModalService } from '../../services/base-modal.service';\r\nimport { DsMobileBookingModalComponent, BookingResult, DateOption, TimeSlot } from './ds-mobile-booking-modal';\r\nimport { DsMobileBookingConfirmationWrapperComponent } from './ds-mobile-booking-confirmation-wrapper';\r\nimport { disableModalShadowPointerEvents } from '../bottom-sheet/modal-shadow-fix';\r\n\r\n/**\r\n * DsMobileBookingModalService\r\n * \r\n * Service for managing the booking modal flow:\r\n * 1. Opens the booking modal for date/time selection\r\n * 2. On confirmation, opens the confirmation bottom sheet\r\n * \r\n * @example\r\n * ```typescript\r\n * constructor(private bookingModalService: DsMobileBookingModalService) {}\r\n * \r\n * async openBooking() {\r\n * await this.bookingModalService.open({\r\n * facilityId: 'facility-1',\r\n * facilityTitle: 'Boremaskinen'\r\n * });\r\n * }\r\n * ```\r\n */\r\nexport interface BookingModalOptions {\r\n facilityId: string;\r\n facilityTitle: string;\r\n facilityThumbnail?: string;\r\n daysAhead?: number;\r\n availableDates?: DateOption[];\r\n availableTimeSlots?: Record<string, TimeSlot[]>;\r\n labels?: {\r\n selectFromCalendar?: string;\r\n confirmBooking?: string;\r\n };\r\n}\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class DsMobileBookingModalService extends BaseModalService {\r\n constructor(modalController: ModalController) {\r\n super(modalController);\r\n }\r\n\r\n /**\r\n * Open the booking modal for a facility\r\n * \r\n * @param options The booking modal options including dynamic data and texts\r\n * @returns Promise that resolves when the booking flow is complete\r\n */\r\n async open(options: BookingModalOptions): Promise<void> {\r\n const componentProps: any = {\r\n facilityId: options.facilityId,\r\n facilityTitle: options.facilityTitle,\r\n };\r\n \r\n if (options.daysAhead !== undefined) componentProps.daysAhead = options.daysAhead;\r\n if (options.availableDates !== undefined) componentProps.availableDates = options.availableDates;\r\n if (options.availableTimeSlots !== undefined) componentProps.availableTimeSlots = options.availableTimeSlots;\r\n if (options.labels?.selectFromCalendar) componentProps.selectFromCalendarText = options.labels.selectFromCalendar;\r\n if (options.labels?.confirmBooking) componentProps.confirmBookingText = options.labels.confirmBooking;\r\n\r\n const modal = await this.createModal(\r\n DsMobileBookingModalComponent,\r\n componentProps,\r\n { keyboardClose: true }\r\n );\r\n \r\n await modal.present();\r\n \r\n const result = await modal.onWillDismiss<BookingResult>();\r\n \r\n // If user confirmed the booking, dismiss all modals and show confirmation sheet\r\n if (result.role === 'confirm' && result.data) {\r\n // Dismiss all open modals (booking modal + facility detail modal)\r\n await this.dismissAllModals();\r\n \r\n // Show confirmation sheet after all modals are dismissed\r\n await this.openConfirmationSheet(result.data, options.facilityThumbnail);\r\n }\r\n }\r\n\r\n /**\r\n * Dismiss all open modals\r\n */\r\n private async dismissAllModals(): Promise<void> {\r\n let topModal = await this.modalController.getTop();\r\n while (topModal) {\r\n await topModal.dismiss();\r\n topModal = await this.modalController.getTop();\r\n }\r\n }\r\n\r\n /**\r\n * Open the confirmation bottom sheet after successful booking\r\n * \r\n * @param booking The booking result data\r\n * @param facilityThumbnail Optional thumbnail image URL\r\n * @returns Promise that resolves when the sheet is dismissed\r\n */\r\n private async openConfirmationSheet(\r\n booking: BookingResult,\r\n facilityThumbnail?: string\r\n ): Promise<void> {\r\n const sheet = await this.modalController.create({\r\n component: DsMobileBookingConfirmationWrapperComponent,\r\n componentProps: {\r\n booking,\r\n facilityThumbnail\r\n },\r\n breakpoints: [0, 1],\r\n initialBreakpoint: 1,\r\n handle: true,\r\n cssClass: ['ds-bottom-sheet', 'auto-height'],\r\n backdropDismiss: true,\r\n showBackdrop: true,\r\n mode: 'ios'\r\n });\r\n\r\n await sheet.present();\r\n disableModalShadowPointerEvents(sheet);\r\n }\r\n}\r\n","import { Component, signal, Input, ViewChild, ElementRef, OnInit, AfterViewInit, CUSTOM_ELEMENTS_SCHEMA, inject } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { Capacitor } from '@capacitor/core';\r\nimport { FilePicker } from '@capawesome/capacitor-file-picker';\r\nimport { DsButtonComponent, DsTextareaComponent, DsIconComponent, DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { DsMobileModalBaseComponent } from '../modal-base/ds-mobile-modal-base';\r\nimport { DsMobileSectionComponent } from '../section';\r\nimport { DsMobileListItemComponent } from '../list-item';\r\nimport { DsMobileBottomSheetService } from '../bottom-sheet';\r\nimport { DsMobileAttachmentPreviewComponent, type AttachmentData, type AttachmentFileType } from '../attachment-preview';\r\n\r\n/**\r\n * New facility form data\r\n */\r\nexport interface NewFacilityData {\r\n title: string;\r\n description: string;\r\n whoCanBook: string;\r\n whenCanBook: string;\r\n price: string;\r\n accessRequirements: string;\r\n attachments: AttachmentData[];\r\n}\r\n\r\n/**\r\n * DsMobileFacilityCreationModalComponent\r\n *\r\n * Modal component for creating new facilities.\r\n * Uses ds-mobile-modal-base for consistent layout and behavior.\r\n *\r\n * Features:\r\n * - Title and description fields\r\n * - Interactive list items for facility options\r\n * - Bottom sheet pickers for selections\r\n * - Photo upload with preview\r\n * - Form validation\r\n *\r\n * This component is typically not used directly - use DsMobileFacilityCreationModalService instead.\r\n */\r\n@Component({\r\n selector: 'ds-mobile-facility-creation-modal',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n DsButtonComponent,\r\n DsTextareaComponent,\r\n DsIconComponent,\r\n DsIconButtonComponent,\r\n DsMobileModalBaseComponent,\r\n DsMobileSectionComponent,\r\n DsMobileListItemComponent,\r\n DsMobileAttachmentPreviewComponent,\r\n ],\r\n styleUrls: ['../shared/mobile-common.css', './ds-mobile-facility-creation-modal.css'],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n template: `\r\n <ds-mobile-modal-base\r\n [loading]=\"loading\"\r\n [error]=\"error\"\r\n [showHeader]=\"false\"\r\n [hasFixedBottom]=\"true\"\r\n [enableKeyboardHandling]=\"true\"\r\n [keyboardContentBehavior]=\"'overlay'\"\r\n closeButtonLabel=\"Close\"\r\n >\r\n <!-- Form Content -->\r\n <ds-mobile-section class=\"form-section\">\r\n <!-- Title Field (Large Ghost Textarea) -->\r\n <ds-textarea\r\n #titleInput\r\n [(ngModel)]=\"title\"\r\n [ghost]=\"true\"\r\n [required]=\"true\"\r\n [rows]=\"1\"\r\n [placeholder]=\"titlePlaceholder\"\r\n class=\"inquiry-title-input ghost-input-clean\"\r\n (valueChange)=\"handleTitleChange($event)\"\r\n />\r\n\r\n <!-- Description Field (Ghost Textarea) -->\r\n <ds-textarea\r\n #descriptionInput\r\n [(ngModel)]=\"description\"\r\n [ghost]=\"true\"\r\n [rows]=\"1\"\r\n [placeholder]=\"descriptionPlaceholder\"\r\n class=\"inquiry-description-input ghost-input-clean\"\r\n (valueChange)=\"handleDescriptionChange($event)\"\r\n />\r\n </ds-mobile-section>\r\n\r\n <!-- List Items Section -->\r\n <ds-mobile-section [contentGap]=\"'0'\">\r\n <!-- Who can book - hidden until Propbinder API supports this field -->\r\n <!-- <ds-mobile-list-item \r\n [leadingSize]=\"'32px'\" \r\n [showDivider]=\"true\" \r\n [interactive]=\"true\"\r\n [showDesktopMoreButton]=\"false\"\r\n [align]=\"'center'\"\r\n (itemClick)=\"openWhoSheet()\">\r\n <ds-icon content-leading name=\"remixGroupLine\" size=\"20px\" color=\"tertiary\" />\r\n <div content-main>\r\n <div class=\"detail-label\">Hvem kan booke</div>\r\n <div class=\"detail-value\">{{ whoCanBook() }}</div>\r\n </div>\r\n <ds-icon content-trailing name=\"remixArrowRightSLine\" size=\"20px\" color=\"tertiary\" />\r\n </ds-mobile-list-item> -->\r\n\r\n <!-- When can it be booked -->\r\n <ds-mobile-list-item \r\n [leadingSize]=\"'32px'\" \r\n [showDivider]=\"true\" \r\n [interactive]=\"true\"\r\n [showDesktopMoreButton]=\"false\"\r\n [align]=\"'center'\"\r\n (itemClick)=\"openWhenSheet()\">\r\n <ds-icon content-leading name=\"remixCalendarLine\" size=\"20px\" color=\"tertiary\" />\r\n <div content-main>\r\n <div class=\"detail-label\">Hvornår kan det bookes</div>\r\n <div class=\"detail-value\">{{ whenCanBook() }}</div>\r\n </div>\r\n <ds-icon content-trailing name=\"remixArrowRightSLine\" size=\"20px\" color=\"tertiary\" />\r\n </ds-mobile-list-item>\r\n\r\n <!-- Price -->\r\n <ds-mobile-list-item \r\n [leadingSize]=\"'32px'\" \r\n [showDivider]=\"false\" \r\n [interactive]=\"true\"\r\n [showDesktopMoreButton]=\"false\"\r\n [align]=\"'center'\"\r\n (itemClick)=\"openPriceSheet()\">\r\n <ds-icon content-leading name=\"remixPriceTag3Line\" size=\"20px\" color=\"tertiary\" />\r\n <div content-main>\r\n <div class=\"detail-label\">Pris</div>\r\n <div class=\"detail-value\">{{ price() }}</div>\r\n </div>\r\n <ds-icon content-trailing name=\"remixArrowRightSLine\" size=\"20px\" color=\"tertiary\" />\r\n </ds-mobile-list-item>\r\n\r\n <!-- Access requirements - hidden until Propbinder API supports this field -->\r\n <!-- <ds-mobile-list-item \r\n [leadingSize]=\"'32px'\" \r\n [showDivider]=\"false\" \r\n [interactive]=\"true\"\r\n [showDesktopMoreButton]=\"false\"\r\n [align]=\"'center'\"\r\n (itemClick)=\"openAccessSheet()\">\r\n <ds-icon content-leading name=\"remixKeyLine\" size=\"20px\" color=\"tertiary\" />\r\n <div content-main>\r\n <div class=\"detail-label\">Adgangskrav</div>\r\n <div class=\"detail-value\">{{ accessRequirements() }}</div>\r\n </div>\r\n <ds-icon content-trailing name=\"remixArrowRightSLine\" size=\"20px\" color=\"tertiary\" />\r\n </ds-mobile-list-item> -->\r\n </ds-mobile-section>\r\n\r\n <!-- Fixed Bottom Container (Slides with keyboard) -->\r\n <div fixed-bottom class=\"fixed-bottom-container\">\r\n <!-- Attachment Previews (if any) -->\r\n @if (attachments().length > 0) {\r\n <div class=\"attachment-previews-section\">\r\n <div class=\"image-previews\">\r\n @for (attachment of attachments(); track attachment.id) {\r\n <ds-mobile-attachment-preview [attachment]=\"attachment\" (remove)=\"removeAttachment($event)\" />\r\n }\r\n </div>\r\n </div>\r\n }\r\n\r\n <!-- Submit Actions Container -->\r\n <div class=\"submit-container\">\r\n <div class=\"submit-content\">\r\n <!-- Upload Actions (Left) -->\r\n <div class=\"upload-actions\">\r\n <ds-icon-button icon=\"remixImageLine\" variant=\"secondary\" size=\"md\" (clicked)=\"addPhoto()\" [disabled]=\"attachments().length >= 6\" aria-label=\"Add photo\">\r\n </ds-icon-button>\r\n <ds-icon-button\r\n icon=\"remixAttachmentLine\"\r\n variant=\"secondary\"\r\n size=\"md\"\r\n (clicked)=\"handleAddAttachment()\"\r\n [disabled]=\"attachments().length >= 6\"\r\n aria-label=\"Add attachment\"\r\n >\r\n </ds-icon-button>\r\n\r\n <!-- Hidden file input for file selection -->\r\n <input #fileInput type=\"file\" accept=\"*/*\" multiple (change)=\"handleFileSelect($event)\" style=\"display: none;\" aria-hidden=\"true\" />\r\n </div>\r\n\r\n <!-- Submit Button (Right) -->\r\n <ds-button class=\"submit-action-button\" variant=\"primary\" size=\"sm\" [disabled]=\"!isFormValid() || isSubmitting()\" (clicked)=\"handleSubmit()\">\r\n {{ submitButtonLabel }}\r\n </ds-button>\r\n </div>\r\n </div>\r\n </div>\r\n </ds-mobile-modal-base>\r\n `\r\n})\r\nexport class DsMobileFacilityCreationModalComponent implements OnInit, AfterViewInit {\r\n private modalController = inject(ModalController);\r\n private bottomSheetService = inject(DsMobileBottomSheetService);\r\n \r\n @ViewChild('titleInput', { read: ElementRef }) titleInputRef?: ElementRef<HTMLElement>;\r\n @ViewChild('descriptionInput', { read: ElementRef }) descriptionInputRef?: ElementRef<HTMLElement>;\r\n @ViewChild('titleInput') titleInput?: DsTextareaComponent;\r\n @ViewChild('fileInput') fileInput?: ElementRef<HTMLInputElement>;\r\n\r\n /**\r\n * Loading state for the modal\r\n */\r\n @Input() loading: boolean = false;\r\n\r\n /**\r\n * Error message to display\r\n */\r\n @Input() error?: string;\r\n\r\n /**\r\n * Callback function when form is submitted\r\n */\r\n @Input() onSubmit?: (data: NewFacilityData) => void | Promise<void>;\r\n\r\n /**\r\n * Placeholder for the title field\r\n */\r\n @Input() titlePlaceholder: string = 'Festlokale på tal';\r\n\r\n /**\r\n * Placeholder for the description field\r\n */\r\n @Input() descriptionPlaceholder: string = 'Beskriv din booking så detaljeret som muligt...';\r\n\r\n /**\r\n * Label for the submit button\r\n */\r\n @Input() submitButtonLabel: string = 'Opret';\r\n\r\n /**\r\n * Form title field\r\n */\r\n title = '';\r\n\r\n /**\r\n * Form description field\r\n */\r\n description = '';\r\n\r\n /**\r\n * Attachments array\r\n */\r\n attachments = signal<AttachmentData[]>([]);\r\n\r\n /**\r\n * Who can book signal\r\n */\r\n whoCanBook = signal<string>('Alle');\r\n\r\n /**\r\n * When can it be booked signal\r\n */\r\n whenCanBook = signal<string>('I weekenden, 09:00 til 17:30');\r\n\r\n /**\r\n * Price signal\r\n */\r\n price = signal<string>('Gratis');\r\n\r\n /**\r\n * Access requirements signal\r\n */\r\n accessRequirements = signal<string>('Ingen adgangskrav');\r\n\r\n /**\r\n * Form validation state\r\n */\r\n isFormValid = signal<boolean>(false);\r\n\r\n /**\r\n * Submitting state\r\n */\r\n isSubmitting = signal<boolean>(false);\r\n\r\n ngOnInit(): void {\r\n console.log('[FacilityCreationModal] Component initialized');\r\n }\r\n\r\n ngAfterViewInit(): void {\r\n // Setup auto-resize for title textarea\r\n setTimeout(() => {\r\n this.autoResizeTitleTextarea();\r\n this.autoResizeDescriptionTextarea();\r\n\r\n // Focus the title textarea after view initialization to trigger keyboard on iOS\r\n if (this.titleInputRef) {\r\n const textareaElement = this.titleInputRef.nativeElement.querySelector('textarea');\r\n if (textareaElement) {\r\n textareaElement.focus();\r\n }\r\n }\r\n }, 300);\r\n }\r\n\r\n /**\r\n * Auto-resize the title textarea based on content\r\n */\r\n private autoResizeTitleTextarea(): void {\r\n if (!this.titleInputRef) return;\r\n\r\n // Access the native textarea element\r\n const textareaElement = this.titleInputRef.nativeElement.querySelector('textarea');\r\n if (textareaElement) {\r\n textareaElement.style.height = 'auto';\r\n textareaElement.style.height = textareaElement.scrollHeight + 'px';\r\n }\r\n }\r\n\r\n /**\r\n * Auto-resize the description textarea based on content\r\n */\r\n private autoResizeDescriptionTextarea(): void {\r\n if (!this.descriptionInputRef) return;\r\n\r\n const textareaElement = this.descriptionInputRef.nativeElement.querySelector('textarea');\r\n if (textareaElement) {\r\n textareaElement.style.height = 'auto';\r\n textareaElement.style.height = textareaElement.scrollHeight + 'px';\r\n }\r\n }\r\n\r\n /**\r\n * Handle title change with auto-resize\r\n */\r\n handleTitleChange(value: string): void {\r\n this.validateForm();\r\n this.autoResizeTitleTextarea();\r\n }\r\n\r\n /**\r\n * Handle description change with auto-resize\r\n */\r\n handleDescriptionChange(value: string): void {\r\n this.validateForm();\r\n this.autoResizeDescriptionTextarea();\r\n }\r\n\r\n /**\r\n * Validate form fields\r\n */\r\n validateForm(): void {\r\n const isValid = this.title.trim().length > 0 && this.description.trim().length > 0;\r\n this.isFormValid.set(isValid);\r\n }\r\n\r\n /**\r\n * Open who can book sheet\r\n */\r\n async openWhoSheet(): Promise<void> {\r\n console.log('[FacilityCreationModal] Opening who can book sheet');\r\n const { DsMobileWhoCanBookSheetComponent } = await import('./sheets/ds-mobile-who-can-book-sheet');\r\n \r\n const modal = await this.bottomSheetService.create({\r\n component: DsMobileWhoCanBookSheetComponent,\r\n componentProps: {},\r\n breakpoints: [0, 1],\r\n initialBreakpoint: 1,\r\n handle: true,\r\n cssClass: ['ds-bottom-sheet', 'auto-height']\r\n });\r\n \r\n const result = await modal.onWillDismiss();\r\n if (result?.data?.value) {\r\n // value is now an array of selected community IDs\r\n const selectedIds = result.data.value as string[];\r\n \r\n // If all non-\"alle\" options are selected, just display \"Alle\"\r\n const allCommunities = ['faelleskab-a', 'faelleskab-b', 'faelleskab-c'];\r\n const allCommunitiesSelected = allCommunities.every(id => selectedIds.includes(id));\r\n \r\n if (allCommunitiesSelected || selectedIds.includes('alle')) {\r\n this.whoCanBook.set('Alle');\r\n } else {\r\n // Otherwise, show individual labels\r\n const labels = selectedIds\r\n .filter(id => id !== 'alle') // Exclude \"alle\" from individual display\r\n .map((id: string) => {\r\n // Convert IDs to display labels\r\n if (id === 'faelleskab-a') return 'Fælleskab A';\r\n if (id === 'faelleskab-b') return 'Fælleskab B';\r\n if (id === 'faelleskab-c') return 'Fælleskab C';\r\n return id;\r\n });\r\n this.whoCanBook.set(labels.join(', '));\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Open when can it be booked sheet\r\n */\r\n async openWhenSheet(): Promise<void> {\r\n console.log('[FacilityCreationModal] Opening when sheet');\r\n const { DsMobileWhenCanBookSheetComponent } = await import('./sheets/ds-mobile-when-can-book-sheet');\r\n \r\n const modal = await this.bottomSheetService.create({\r\n component: DsMobileWhenCanBookSheetComponent,\r\n componentProps: {},\r\n breakpoints: [0, 1],\r\n initialBreakpoint: 1,\r\n handle: true,\r\n cssClass: ['ds-bottom-sheet', 'auto-height']\r\n });\r\n \r\n const result = await modal.onWillDismiss();\r\n if (result?.data?.value) {\r\n // value is now an object with days, timeRange, duration\r\n const { days, timeRange, duration } = result.data.value;\r\n const dayStr = days.join(', ');\r\n const timeStr = `${timeRange.start} til ${timeRange.end}`;\r\n this.whenCanBook.set(`${dayStr}, ${timeStr}, ${duration}`);\r\n }\r\n }\r\n\r\n /**\r\n * Open price sheet\r\n */\r\n async openPriceSheet(): Promise<void> {\r\n console.log('[FacilityCreationModal] Opening price sheet');\r\n const { DsMobilePriceSheetComponent } = await import('./sheets/ds-mobile-price-sheet');\r\n \r\n const modal = await this.bottomSheetService.create({\r\n component: DsMobilePriceSheetComponent,\r\n componentProps: {},\r\n breakpoints: [0, 1],\r\n initialBreakpoint: 1,\r\n handle: true,\r\n cssClass: ['ds-bottom-sheet', 'auto-height']\r\n });\r\n \r\n const result = await modal.onWillDismiss();\r\n if (result?.data?.value) {\r\n this.price.set(result.data.value);\r\n }\r\n }\r\n\r\n /**\r\n * Open access requirements sheet\r\n */\r\n async openAccessSheet(): Promise<void> {\r\n console.log('[FacilityCreationModal] Opening access sheet');\r\n const { DsMobileAccessSheetComponent } = await import('./sheets/ds-mobile-access-sheet');\r\n \r\n const modal = await this.bottomSheetService.create({\r\n component: DsMobileAccessSheetComponent,\r\n componentProps: {},\r\n breakpoints: [0, 1],\r\n initialBreakpoint: 1,\r\n handle: true,\r\n cssClass: ['ds-bottom-sheet', 'auto-height']\r\n });\r\n \r\n const result = await modal.onWillDismiss();\r\n if (result?.data?.value !== undefined) {\r\n // value is now an array of selected restriction IDs\r\n const selectedIds = result.data.value as string[];\r\n \r\n // If no restrictions are selected, show \"Ingen adgangskrav\"\r\n if (selectedIds.length === 0) {\r\n this.accessRequirements.set('Ingen adgangskrav');\r\n } else {\r\n const labels = selectedIds.map((id: string) => {\r\n // Convert IDs to display labels\r\n if (id === 'digital-adgangskode') return 'Digital adgangskode';\r\n if (id === 'depositum') return 'Depositum';\r\n if (id === 'nøglekort') return 'Nøglekort';\r\n return id;\r\n });\r\n this.accessRequirements.set(labels.join(', '));\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Add a new photo from camera/library\r\n */\r\n async addPhoto(): Promise<void> {\r\n if (this.attachments().length >= 6) {\r\n return;\r\n }\r\n\r\n try {\r\n const result = await FilePicker.pickImages({\r\n limit: 1,\r\n });\r\n\r\n const image = result.files?.[0];\r\n if (image) {\r\n const newAttachment: AttachmentData = {\r\n id: `photo-${Date.now()}`,\r\n src: image.path ? Capacitor.convertFileSrc(image.path) : (image.blob ? URL.createObjectURL(image.blob) : ''),\r\n type: 'image',\r\n name: image.name || `Photo ${this.attachments().length + 1}`,\r\n size: this.formatFileSize(image.size ?? 0),\r\n };\r\n\r\n this.attachments.update((attachments) => [...attachments, newAttachment]);\r\n }\r\n } catch (error) {\r\n console.error('[FacilityCreationModal] Error adding photo:', error);\r\n // User cancelled or error occurred - just ignore\r\n }\r\n }\r\n\r\n /**\r\n * Remove an attachment\r\n */\r\n removeAttachment(attachmentId: string): void {\r\n this.attachments.update((attachments) => attachments.filter((a) => a.id !== attachmentId));\r\n }\r\n\r\n /**\r\n * Handle attachment button click\r\n */\r\n handleAddAttachment(): void {\r\n if (this.attachments().length >= 6) {\r\n return;\r\n }\r\n\r\n // Trigger the hidden file input\r\n if (this.fileInput) {\r\n this.fileInput.nativeElement.click();\r\n }\r\n }\r\n\r\n /**\r\n * Detect file type from file name or mime type\r\n */\r\n private detectFileType(file: File): AttachmentFileType {\r\n const fileName = file.name.toLowerCase();\r\n const mimeType = file.type.toLowerCase();\r\n\r\n // Check if it's an image\r\n if (mimeType.startsWith('image/')) {\r\n return 'image';\r\n }\r\n\r\n // Check file extension\r\n if (fileName.endsWith('.pdf')) {\r\n return 'pdf';\r\n } else if (fileName.endsWith('.doc')) {\r\n return 'doc';\r\n } else if (fileName.endsWith('.docx')) {\r\n return 'docx';\r\n } else if (fileName.endsWith('.xls')) {\r\n return 'xls';\r\n } else if (fileName.endsWith('.xlsx')) {\r\n return 'xlsx';\r\n }\r\n\r\n return 'other';\r\n }\r\n\r\n /**\r\n * Format file size for display\r\n */\r\n private formatFileSize(bytes: number): string {\r\n if (bytes === 0) return '0 B';\r\n const k = 1024;\r\n const sizes = ['B', 'KB', 'MB', 'GB'];\r\n const i = Math.floor(Math.log(bytes) / Math.log(k));\r\n return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + ' ' + sizes[i];\r\n }\r\n\r\n /**\r\n * Handle file selection from file input\r\n */\r\n handleFileSelect(event: Event): void {\r\n const input = event.target as HTMLInputElement;\r\n const files = input.files;\r\n\r\n if (!files || files.length === 0) {\r\n return;\r\n }\r\n\r\n // Process each selected file (up to the limit)\r\n const remainingSlots = 6 - this.attachments().length;\r\n const filesToProcess = Array.from(files).slice(0, remainingSlots);\r\n\r\n filesToProcess.forEach((file) => {\r\n const fileType = this.detectFileType(file);\r\n\r\n // Create a data URL for preview\r\n const reader = new FileReader();\r\n reader.onload = (e) => {\r\n const result = e.target?.result as string;\r\n if (result) {\r\n const newAttachment: AttachmentData = {\r\n id: `file-${Date.now()}-${Math.random()}`,\r\n src: result,\r\n type: fileType,\r\n name: file.name,\r\n size: this.formatFileSize(file.size),\r\n };\r\n this.attachments.update((attachments) => [...attachments, newAttachment]);\r\n }\r\n };\r\n reader.readAsDataURL(file);\r\n });\r\n\r\n // Reset the input so the same file can be selected again\r\n input.value = '';\r\n }\r\n\r\n /**\r\n * Handle form submission\r\n */\r\n async handleSubmit(): Promise<void> {\r\n if (!this.isFormValid() || this.isSubmitting()) {\r\n return;\r\n }\r\n\r\n this.isSubmitting.set(true);\r\n\r\n try {\r\n const facilityData: NewFacilityData = {\r\n title: this.title.trim(),\r\n description: this.description.trim(),\r\n whoCanBook: this.whoCanBook(),\r\n whenCanBook: this.whenCanBook(),\r\n price: this.price(),\r\n accessRequirements: this.accessRequirements(),\r\n attachments: this.attachments(),\r\n };\r\n\r\n console.log('[FacilityCreationModal] Submitting facility:', facilityData);\r\n\r\n if (this.onSubmit) {\r\n await this.onSubmit(facilityData);\r\n }\r\n\r\n // Success - close the modal\r\n this.modalController.dismiss();\r\n } catch (error) {\r\n console.error('[FacilityCreationModal] Error submitting facility:', error);\r\n this.error = 'Failed to create facility. Please try again.';\r\n } finally {\r\n this.isSubmitting.set(false);\r\n }\r\n }\r\n}\r\n","import { Component, Input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsMobileConfirmationSheetComponent } from '../bottom-sheet/ds-mobile-confirmation-sheet';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { NewFacilityData } from './ds-mobile-facility-creation-modal';\r\n\r\n/**\r\n * DsMobileFacilityCreationConfirmationWrapperComponent\r\n * \r\n * Wrapper component that uses the generic confirmation sheet\r\n * specifically for facility creation confirmations.\r\n * \r\n * This component displays a summary of the created facility.\r\n */\r\n@Component({\r\n selector: 'ds-mobile-facility-creation-confirmation-wrapper',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n DsMobileConfirmationSheetComponent,\r\n DsIconComponent\r\n ],\r\n template: `\r\n <ds-mobile-confirmation-sheet\r\n [title]=\"'Facilitet oprettet'\"\r\n [message]=\"'Din nye facilitet er nu oprettet og klar til booking.'\"\r\n [buttonText]=\"'Luk'\"\r\n [illustrationVariant]=\"'confirmation'\">\r\n <ng-template #summary>\r\n <div class=\"facility-summary\">\r\n <div class=\"summary-item\">\r\n <div class=\"summary-details\">\r\n <h3 class=\"summary-title\">{{ facilityData.title }}</h3>\r\n <p class=\"summary-description\">{{ facilityData.description }}</p>\r\n \r\n <div class=\"summary-info-list\">\r\n <div class=\"info-row\">\r\n <ds-icon name=\"remixGroupLine\" size=\"16px\" color=\"tertiary\" />\r\n <span class=\"info-label\">{{ facilityData.whoCanBook }}</span>\r\n </div>\r\n <div class=\"info-row\">\r\n <ds-icon name=\"remixCalendarLine\" size=\"16px\" color=\"tertiary\" />\r\n <span class=\"info-label\">{{ facilityData.whenCanBook }}</span>\r\n </div>\r\n <div class=\"info-row\">\r\n <ds-icon name=\"remixPriceTag3Line\" size=\"16px\" color=\"tertiary\" />\r\n <span class=\"info-label\">{{ facilityData.price }}</span>\r\n </div>\r\n <div class=\"info-row\">\r\n <ds-icon name=\"remixKeyLine\" size=\"16px\" color=\"tertiary\" />\r\n <span class=\"info-label\">{{ facilityData.accessRequirements }}</span>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ng-template>\r\n </ds-mobile-confirmation-sheet>\r\n `,\r\n styles: [`\r\n .facility-summary {\r\n width: 100%;\r\n background: var(--color-background-neutral-secondary, #f5f5f5);\r\n border-radius: 16px;\r\n padding: 16px;\r\n }\r\n\r\n .summary-item {\r\n display: flex;\r\n gap: 12px;\r\n align-items: flex-start;\r\n }\r\n\r\n .summary-details {\r\n flex: 1;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n }\r\n\r\n .summary-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base, 16px);\r\n font-weight: 600;\r\n color: var(--text-color-default-primary, #202227);\r\n margin: 0;\r\n }\r\n\r\n .summary-description {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm, 14px);\r\n font-weight: 400;\r\n line-height: 1.5;\r\n color: var(--text-color-default-secondary, #545b66);\r\n margin: 0;\r\n }\r\n\r\n .summary-info-list {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n margin-top: 4px;\r\n }\r\n\r\n .info-row {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n }\r\n\r\n .info-label {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm, 14px);\r\n font-weight: 400;\r\n color: var(--text-color-default-secondary, #545b66);\r\n }\r\n `]\r\n})\r\nexport class DsMobileFacilityCreationConfirmationWrapperComponent {\r\n @Input() facilityData!: NewFacilityData;\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport {\r\n DsMobileFacilityCreationModalComponent,\r\n NewFacilityData,\r\n} from './ds-mobile-facility-creation-modal';\r\nimport { DsMobileFacilityCreationConfirmationWrapperComponent } from './ds-mobile-facility-creation-confirmation-wrapper';\r\nimport { BaseModalService } from '../../services/base-modal.service';\r\nimport { disableModalShadowPointerEvents } from '../bottom-sheet/modal-shadow-fix';\r\n\r\n/**\r\n * Options for opening the facility creation modal\r\n */\r\nexport interface FacilityCreationModalOptions {\r\n /** Callback function when facility is submitted */\r\n onSubmit?: (data: NewFacilityData) => void | Promise<void>;\r\n /** Initial loading state */\r\n loading?: boolean;\r\n /** Initial error message */\r\n error?: string;\r\n /** Custom placeholder for title field */\r\n titlePlaceholder?: string;\r\n /** Custom placeholder for description field */\r\n descriptionPlaceholder?: string;\r\n /** Custom label for submit button */\r\n submitButtonLabel?: string;\r\n}\r\n\r\n/**\r\n * DsMobileFacilityCreationModalService\r\n *\r\n * Service for displaying the facility creation modal.\r\n * Built on Ionic's modal system with native gestures and animations.\r\n *\r\n * Features:\r\n * - Full-screen modal with form\r\n * - Title and description inputs\r\n * - Interactive list items for facility options\r\n * - Bottom sheet pickers\r\n * - Form validation\r\n * - Submit handling with confirmation sheet\r\n * - Loading and error states\r\n *\r\n * @example\r\n * ```typescript\r\n * constructor(private facilityCreationModal: DsMobileFacilityCreationModalService) {}\r\n *\r\n * async createNewFacility(): Promise<void> {\r\n * await this.facilityCreationModal.open({\r\n * onSubmit: async (data) => {\r\n * console.log('Creating facility:', data);\r\n * await this.apiService.createFacility(data);\r\n * await this.facilityCreationModal.close();\r\n * }\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class DsMobileFacilityCreationModalService extends BaseModalService {\r\n constructor(modalController: ModalController) {\r\n super(modalController);\r\n }\r\n\r\n /**\r\n * Open the facility creation modal\r\n *\r\n * @param options Modal options including onSubmit callback\r\n * @returns Promise that resolves when the modal is presented\r\n */\r\n async open(options?: FacilityCreationModalOptions): Promise<void> {\r\n console.log('[FacilityCreationModal] Opening modal with options:', options);\r\n\r\n const modal = await this.createModal(\r\n DsMobileFacilityCreationModalComponent,\r\n {\r\n onSubmit: async (data: NewFacilityData) => {\r\n console.log('[FacilityCreationModal] Facility submitted:', data);\r\n \r\n // Call user's onSubmit callback if provided\r\n if (options?.onSubmit) {\r\n await options.onSubmit(data);\r\n }\r\n \r\n // Close the modal\r\n await this.close();\r\n \r\n // Show confirmation sheet\r\n await this.openConfirmationSheet(data);\r\n },\r\n loading: options?.loading ?? false,\r\n ...(options?.error && { error: options.error }),\r\n ...(options?.titlePlaceholder && { titlePlaceholder: options.titlePlaceholder }),\r\n ...(options?.descriptionPlaceholder && { descriptionPlaceholder: options.descriptionPlaceholder }),\r\n ...(options?.submitButtonLabel && { submitButtonLabel: options.submitButtonLabel }),\r\n },\r\n {\r\n keyboardClose: false, // Don't close on keyboard hide for this modal\r\n cssClass: ['ds-modal-base'],\r\n },\r\n );\r\n\r\n console.log('[FacilityCreationModal] Modal created, presenting...');\r\n await modal.present();\r\n console.log('[FacilityCreationModal] Modal presented');\r\n }\r\n\r\n /**\r\n * Open the confirmation bottom sheet after successful facility creation\r\n * \r\n * @param facilityData The created facility data\r\n * @returns Promise that resolves when the sheet is dismissed\r\n */\r\n private async openConfirmationSheet(facilityData: NewFacilityData): Promise<void> {\r\n const sheet = await this.modalController.create({\r\n component: DsMobileFacilityCreationConfirmationWrapperComponent,\r\n componentProps: {\r\n facilityData\r\n },\r\n breakpoints: [0, 1],\r\n initialBreakpoint: 1,\r\n handle: true,\r\n cssClass: ['ds-bottom-sheet', 'auto-height'],\r\n backdropDismiss: true,\r\n showBackdrop: true,\r\n mode: 'ios',\r\n presentingElement: undefined\r\n });\r\n\r\n await sheet.present();\r\n disableModalShadowPointerEvents(sheet);\r\n }\r\n}\r\n","import { Component, signal, computed, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { DsCheckboxComponent } from '@propbinder/design-system';\r\nimport { DsMobileActionListItemComponent } from '../../action-list-item/ds-mobile-action-list-item';\r\nimport { DsMobileBottomSheetWrapperComponent } from '../../bottom-sheet/ds-mobile-bottom-sheet-wrapper';\r\nimport { DsMobileBottomSheetHeaderComponent } from '../../bottom-sheet/ds-mobile-bottom-sheet-header';\r\n\r\nexport interface WhoCanBookOption {\r\n value: string;\r\n label: string;\r\n isMaster?: boolean;\r\n}\r\n\r\n/**\r\n * DsMobileWhoCanBookSheetComponent\r\n *\r\n * Bottom sheet for selecting who can book a facility (multi-select with checkboxes).\r\n */\r\n@Component({\r\n selector: 'ds-mobile-who-can-book-sheet',\r\n standalone: true,\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n imports: [\r\n CommonModule,\r\n DsCheckboxComponent,\r\n DsMobileActionListItemComponent, \r\n DsMobileBottomSheetWrapperComponent,\r\n DsMobileBottomSheetHeaderComponent\r\n ],\r\n template: `\r\n <ds-mobile-bottom-sheet-wrapper>\r\n <!-- Header with back and done buttons -->\r\n <ds-mobile-bottom-sheet-header\r\n title=\"Hvem kan booke\"\r\n leftButtonLabel=\"Tilbage\"\r\n rightButtonLabel=\"Færdig\"\r\n [rightButtonDisabled]=\"!hasSelectionChanged()\"\r\n (leftButtonClick)=\"dismiss()\"\r\n (rightButtonClick)=\"confirmSelection()\">\r\n </ds-mobile-bottom-sheet-header>\r\n\r\n <!-- Options list -->\r\n <div class=\"options-list\">\r\n @for (option of options; track option.value; let isLast = $last) {\r\n <ds-mobile-action-list-item\r\n [title]=\"option.label\"\r\n [showDivider]=\"!isLast\"\r\n (itemClick)=\"toggleOption(option.value)\">\r\n <div content-trailing>\r\n <ds-checkbox\r\n [checked]=\"selectedOptions().has(option.value)\"\r\n [showLabel]=\"false\"\r\n size=\"md\"\r\n (click)=\"$event.stopPropagation()\"\r\n (checkedChange)=\"toggleOption(option.value)\">\r\n </ds-checkbox>\r\n </div>\r\n </ds-mobile-action-list-item>\r\n }\r\n </div>\r\n </ds-mobile-bottom-sheet-wrapper>\r\n `,\r\n styles: [`\r\n .options-list {\r\n display: flex;\r\n flex-direction: column;\r\n padding: 0 16px;\r\n }\r\n `]\r\n})\r\nexport class DsMobileWhoCanBookSheetComponent {\r\n options: WhoCanBookOption[] = [\r\n { value: 'alle', label: 'Alle', isMaster: true },\r\n { value: 'faelleskab-a', label: 'Fælleskab A' },\r\n { value: 'faelleskab-b', label: 'Fælleskab B' },\r\n { value: 'faelleskab-c', label: 'Fælleskab C' }\r\n ];\r\n\r\n // Signal-based state for selected options - all selected by default\r\n selectedOptions = signal<Set<string>>(new Set(['alle', 'faelleskab-a', 'faelleskab-b', 'faelleskab-c']));\r\n \r\n // Computed signal to check if any selection has been made\r\n hasSelectionChanged = computed(() => this.selectedOptions().size > 0);\r\n\r\n constructor(private modalController: ModalController) {}\r\n\r\n /**\r\n * Toggle an option on/off\r\n * Special logic for 'alle': when toggled on, selects all options; when toggled off, deselects all\r\n */\r\n toggleOption(value: string): void {\r\n const current = new Set(this.selectedOptions());\r\n \r\n if (value === 'alle') {\r\n if (current.has('alle')) {\r\n // Deselect all\r\n current.clear();\r\n } else {\r\n // Select all\r\n this.options.forEach(opt => current.add(opt.value));\r\n }\r\n } else {\r\n if (current.has(value)) {\r\n current.delete(value);\r\n current.delete('alle'); // Uncheck \"Alle\" if any individual item is unchecked\r\n } else {\r\n current.add(value);\r\n // Check if all non-master items are selected\r\n const allSelected = this.options\r\n .filter(o => !o.isMaster)\r\n .every(o => current.has(o.value));\r\n if (allSelected) current.add('alle');\r\n }\r\n }\r\n \r\n this.selectedOptions.set(current);\r\n }\r\n\r\n /**\r\n * Confirm selection and dismiss with selected options\r\n */\r\n confirmSelection(): void {\r\n const selected = Array.from(this.selectedOptions());\r\n this.modalController.dismiss({ value: selected }, 'select');\r\n }\r\n\r\n /**\r\n * Dismiss without saving\r\n */\r\n dismiss(): void {\r\n this.modalController.dismiss(null, 'cancel');\r\n }\r\n}\r\n","import { Component, signal, computed, input, CUSTOM_ELEMENTS_SCHEMA, OnInit, PLATFORM_ID, inject } from '@angular/core';\r\nimport { CommonModule, isPlatformBrowser } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { ModalController, IonPicker, IonPickerColumn, IonPickerColumnOption } from '@ionic/angular/standalone';\r\nimport { DsMobileDropdownComponent } from '../../dropdown';\r\nimport { DsInputTimeComponent, DsLabelComponent } from '@propbinder/design-system';\r\nimport { DsMobileBottomSheetWrapperComponent } from '../../bottom-sheet/ds-mobile-bottom-sheet-wrapper';\r\nimport { DsMobileBottomSheetHeaderComponent } from '../../bottom-sheet/ds-mobile-bottom-sheet-header';\r\n\r\nexport interface WhenCanBookData {\r\n days: string[];\r\n timeRange: { start: string; end: string };\r\n duration: string;\r\n}\r\n\r\n/**\r\n * DsMobileWhenCanBookSheetComponent\r\n *\r\n * Bottom sheet for selecting when a facility can be booked (days, time range, duration).\r\n * \"Vælg selv\" opens a drum-roll IonPopover on mobile, or inline number inputs on desktop.\r\n */\r\n@Component({\r\n selector: 'ds-mobile-when-can-book-sheet',\r\n standalone: true,\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n DsInputTimeComponent,\r\n DsLabelComponent,\r\n DsMobileBottomSheetWrapperComponent,\r\n DsMobileBottomSheetHeaderComponent,\r\n DsMobileDropdownComponent,\r\n IonPicker,\r\n IonPickerColumn,\r\n IonPickerColumnOption,\r\n ],\r\n template: `\r\n <ds-mobile-bottom-sheet-wrapper>\r\n <!-- Header with back and done buttons -->\r\n <ds-mobile-bottom-sheet-header\r\n title=\"Kan bookes\"\r\n leftButtonLabel=\"Annuller\"\r\n rightButtonLabel=\"Gem\"\r\n [rightButtonDisabled]=\"!isValid()\"\r\n (leftButtonClick)=\"dismiss()\"\r\n (rightButtonClick)=\"confirmSelection()\">\r\n </ds-mobile-bottom-sheet-header>\r\n\r\n <div class=\"form-content\">\r\n <!-- Day chips -->\r\n <div class=\"section\">\r\n <ds-label size=\"md\" className=\"form-section-label\">Kan bookes</ds-label>\r\n <div class=\"day-chips\">\r\n @for (day of days; track day) {\r\n <button \r\n type=\"button\"\r\n class=\"day-chip\"\r\n [class.active]=\"selectedDays().has(day)\"\r\n (click)=\"toggleDay(day)\">\r\n {{ day }}\r\n </button>\r\n }\r\n </div>\r\n </div>\r\n\r\n <!-- Time range -->\r\n <div class=\"section\">\r\n <ds-label size=\"md\" className=\"form-section-label\">I tidsrummet</ds-label>\r\n <div class=\"time-inputs\">\r\n <ds-input-time size=\"lg\" [(ngModel)]=\"startTime\"></ds-input-time>\r\n <span class=\"separator\">til</span>\r\n <ds-input-time size=\"lg\" [(ngModel)]=\"endTime\"></ds-input-time>\r\n </div>\r\n </div>\r\n\r\n <!-- Duration chips -->\r\n <div class=\"section\">\r\n <ds-label size=\"md\" className=\"form-section-label\">Varighed</ds-label>\r\n <div class=\"duration-chips\">\r\n @for (duration of durations; track duration.value) {\r\n <button \r\n type=\"button\"\r\n class=\"duration-chip\"\r\n [id]=\"duration.value === 'Vælg selv' ? 'vaelg-selv-chip' : null\"\r\n [class.active]=\"selectedDuration() === duration.value\"\r\n (click)=\"selectDuration(duration.value)\">\r\n @if (duration.value === 'Vælg selv' && selectedDuration() === 'Vælg selv') {\r\n {{ customDurationLabel() || 'Vælg selv' }}\r\n } @else {\r\n {{ duration.label }}\r\n }\r\n </button>\r\n }\r\n </div>\r\n\r\n <!-- Desktop: inline inputs shown when \"Vælg selv\" is active -->\r\n @if (showInlineInputs()) {\r\n <div class=\"custom-duration-inputs\">\r\n <input\r\n type=\"number\"\r\n class=\"duration-number-input\"\r\n min=\"0\"\r\n [ngModel]=\"customHours()\"\r\n (ngModelChange)=\"customHours.set(+$event)\"\r\n (blur)=\"normalize()\"\r\n />\r\n <span class=\"duration-unit\">timer</span>\r\n <input\r\n type=\"number\"\r\n class=\"duration-number-input\"\r\n min=\"0\"\r\n max=\"59\"\r\n [ngModel]=\"customMinutes()\"\r\n (ngModelChange)=\"customMinutes.set(+$event)\"\r\n (blur)=\"normalize()\"\r\n />\r\n <span class=\"duration-unit\">min</span>\r\n </div>\r\n }\r\n\r\n <!-- Mobile: drum-roll popover anchored to the \"Vælg selv\" chip -->\r\n @if (!isDesktop()) {\r\n <ds-mobile-dropdown\r\n trigger=\"vaelg-selv-chip\"\r\n [isOpen]=\"pickerOpen()\"\r\n maxWidth=\"240px\"\r\n position=\"above\"\r\n (closed)=\"onPickerDismiss()\">\r\n <ng-template #customContent>\r\n <ion-picker style=\"--background: transparent; --fade-background-rgb: transparent; --highlight-background: rgba(0, 0, 0, 0.05); --highlight-border-radius: 9999px;\">\r\n <ion-picker-column\r\n [value]=\"customHours()\"\r\n style=\"--padding-start: 4px; --padding-end: 4px;\"\r\n (ionChange)=\"customHours.set(+($event.detail.value ?? customHours()))\">\r\n <div slot=\"suffix\" class=\"picker-suffix\">t</div>\r\n @for (h of hours; track h) {\r\n <ion-picker-column-option [value]=\"h\">{{ h }}</ion-picker-column-option>\r\n }\r\n </ion-picker-column>\r\n <ion-picker-column\r\n [value]=\"customMinutes()\"\r\n style=\"--padding-start: 4px; --padding-end: 4px;\"\r\n (ionChange)=\"customMinutes.set(+($event.detail.value ?? customMinutes()))\">\r\n <div slot=\"suffix\" class=\"picker-suffix\">min</div>\r\n @for (m of minuteOptions; track m) {\r\n <ion-picker-column-option [value]=\"m\">{{ m }}</ion-picker-column-option>\r\n }\r\n </ion-picker-column>\r\n </ion-picker>\r\n </ng-template>\r\n </ds-mobile-dropdown>\r\n }\r\n </div>\r\n </div>\r\n </ds-mobile-bottom-sheet-wrapper>\r\n `,\r\n styles: [`\r\n .form-content {\r\n padding: 16px;\r\n }\r\n\r\n .section {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n margin-bottom: 24px;\r\n }\r\n\r\n .section:last-child {\r\n margin-bottom: 0;\r\n }\r\n\r\n /* Label spacing */\r\n ::ng-deep ds-label.form-section-label {\r\n display: block;\r\n margin-bottom: 12px;\r\n }\r\n\r\n ::ng-deep .form-section-label {\r\n font-weight: 500;\r\n }\r\n\r\n /* Day chips */\r\n .day-chips {\r\n display: flex;\r\n gap: 8px;\r\n flex-wrap: wrap;\r\n width: 100%;\r\n }\r\n\r\n .day-chip {\r\n flex: none;\r\n width: 64px;\r\n padding: 10px 16px;\r\n border: 1px solid var(--border-color-default, #d1d5db);\r\n border-radius: 8px;\r\n background: transparent;\r\n color: var(--color-text-primary);\r\n font-size: 14px;\r\n font-weight: 500;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n outline: none;\r\n }\r\n\r\n .day-chip:hover {\r\n background: var(--color-bg-secondary);\r\n }\r\n\r\n .day-chip.active {\r\n background: var(--color-accent);\r\n color: white;\r\n border-color: var(--color-accent);\r\n }\r\n\r\n /* Time inputs */\r\n .time-inputs {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n }\r\n\r\n .separator {\r\n color: var(--color-text-secondary);\r\n font-size: 14px;\r\n }\r\n\r\n /* Duration chips */\r\n .duration-chips {\r\n display: flex;\r\n gap: 8px;\r\n flex-wrap: wrap;\r\n }\r\n\r\n .duration-chip {\r\n padding: 10px 16px;\r\n border: 1px solid var(--border-color-default, #d1d5db);\r\n border-radius: 8px;\r\n background: transparent;\r\n color: var(--color-text-primary);\r\n font-size: 14px;\r\n font-weight: 500;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n outline: none;\r\n }\r\n\r\n .duration-chip:hover {\r\n background: var(--color-bg-secondary);\r\n }\r\n\r\n .duration-chip.active {\r\n background: var(--color-accent);\r\n color: white;\r\n border-color: var(--color-accent);\r\n }\r\n\r\n /* Desktop inline custom duration inputs */\r\n .custom-duration-inputs {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n margin-top: 12px;\r\n animation: fadeSlideIn 0.15s ease;\r\n }\r\n\r\n @keyframes fadeSlideIn {\r\n from { opacity: 0; transform: translateY(-4px); }\r\n to { opacity: 1; transform: translateY(0); }\r\n }\r\n\r\n .duration-number-input {\r\n width: 64px;\r\n padding: 8px 10px;\r\n border: 1px solid var(--border-color-default, #d1d5db);\r\n border-radius: 8px;\r\n background: transparent;\r\n color: var(--color-text-primary);\r\n font-size: 14px;\r\n font-weight: 500;\r\n text-align: center;\r\n outline: none;\r\n transition: border-color 0.2s ease;\r\n }\r\n\r\n .duration-number-input:focus {\r\n border-color: var(--color-accent);\r\n }\r\n\r\n /* Remove browser spin buttons */\r\n .duration-number-input::-webkit-inner-spin-button,\r\n .duration-number-input::-webkit-outer-spin-button {\r\n -webkit-appearance: none;\r\n margin: 0;\r\n }\r\n .duration-number-input[type=number] {\r\n -moz-appearance: textfield;\r\n }\r\n\r\n .duration-unit {\r\n color: var(--color-text-secondary);\r\n font-size: 14px;\r\n }\r\n\r\n .picker-suffix {\r\n margin-left: -24px;\r\n font-size: 13px;\r\n color: var(--color-text-secondary);\r\n }\r\n\r\n `]\r\n})\r\nexport class DsMobileWhenCanBookSheetComponent implements OnInit {\r\n private platformId = inject(PLATFORM_ID);\r\n\r\n // Platform\r\n isDesktop = signal<boolean>(false);\r\n\r\n // State\r\n selectedDays = signal<Set<string>>(new Set(['Fre', 'Lør', 'Søn']));\r\n startTime = signal('09:00');\r\n endTime = signal('17:30');\r\n selectedDuration = signal('1 time');\r\n\r\n /**\r\n * Maximum number of days available in the \"Vælg selv\" picker/inputs.\r\n * Defaults to 30 (one full month). Override via componentProps when opening the sheet.\r\n */\r\n maxDays = input<number>(30);\r\n\r\n // Custom duration state\r\n pickerOpen = signal<boolean>(false);\r\n customDays = signal<number>(0);\r\n customHours = signal<number>(1);\r\n customMinutes = signal<number>(0);\r\n\r\n customDurationLabel = computed(() => {\r\n const d = this.customDays();\r\n const h = this.customHours();\r\n const m = this.customMinutes();\r\n const parts: string[] = [];\r\n if (d > 0) parts.push(`${d} dage`);\r\n if (h > 0) parts.push(`${h}t`);\r\n if (m > 0) parts.push(`${m}min`);\r\n return parts.join(' ');\r\n });\r\n\r\n showInlineInputs = computed(() =>\r\n this.selectedDuration() === 'Vælg selv' && this.isDesktop()\r\n );\r\n\r\n // Options\r\n days = ['Man', 'Tir', 'Ons', 'Tor', 'Fre', 'Lør', 'Søn'];\r\n durations = [\r\n { value: '30 min', label: '30 min' },\r\n { value: '1 time', label: '1 time' },\r\n { value: '2 timer', label: '2 timer' },\r\n { value: 'Hele dagen', label: 'Hele dagen' },\r\n { value: 'Vælg selv', label: 'Vælg selv' }\r\n ];\r\n daysOptions = computed(() => Array.from({ length: this.maxDays() + 1 }, (_, i) => i));\r\n hours = Array.from({ length: 24 }, (_, i) => i);\r\n minuteOptions = [0, 5, 10, 15, 20, 25, 30, 35, 40, 45, 50, 55];\r\n\r\n // Validation\r\n isValid = computed(() => {\r\n if (this.selectedDuration() === 'Vælg selv' && this.customDurationLabel() === '') {\r\n return false;\r\n }\r\n return this.selectedDays().size > 0 &&\r\n this.startTime() &&\r\n this.endTime();\r\n });\r\n\r\n constructor(private modalController: ModalController) {}\r\n\r\n ngOnInit(): void {\r\n if (isPlatformBrowser(this.platformId)) {\r\n this.isDesktop.set(window.innerWidth >= 768);\r\n window.addEventListener('resize', () => {\r\n this.isDesktop.set(window.innerWidth >= 768);\r\n });\r\n }\r\n }\r\n\r\n /**\r\n * Handle duration chip selection.\r\n * On mobile, opening \"Vælg selv\" triggers the IonPopover via its trigger id.\r\n * On desktop, it shows the inline inputs.\r\n */\r\n selectDuration(value: string): void {\r\n this.selectedDuration.set(value);\r\n if (value === 'Vælg selv' && !this.isDesktop()) {\r\n this.pickerOpen.set(true);\r\n }\r\n }\r\n\r\n /**\r\n * Normalizes days/hours/minutes so values never overflow their units.\r\n * e.g. 0d 48t 0min → 2d 0t 0min; 0d 0t 75min → 0d 1t 15min.\r\n * Caps days at maxDays().\r\n */\r\n normalize(): void {\r\n const totalMinutes = this.customDays() * 24 * 60\r\n + this.customHours() * 60\r\n + this.customMinutes();\r\n\r\n const maxTotalMinutes = this.maxDays() * 24 * 60 + 23 * 60 + 59;\r\n const clamped = Math.max(0, Math.min(totalMinutes, maxTotalMinutes));\r\n\r\n const d = Math.floor(clamped / (24 * 60));\r\n const h = Math.floor((clamped % (24 * 60)) / 60);\r\n const m = clamped % 60;\r\n\r\n this.customDays.set(d);\r\n this.customHours.set(h);\r\n this.customMinutes.set(m);\r\n }\r\n\r\n /**\r\n * Called when the mobile picker popover is dismissed — normalize and commit.\r\n */\r\n onPickerDismiss(): void {\r\n this.normalize();\r\n this.pickerOpen.set(false);\r\n }\r\n\r\n /**\r\n * Toggle day selection\r\n */\r\n toggleDay(day: string): void {\r\n const current = new Set(this.selectedDays());\r\n current.has(day) ? current.delete(day) : current.add(day);\r\n this.selectedDays.set(current);\r\n }\r\n\r\n /**\r\n * Confirm selection and dismiss with data\r\n */\r\n confirmSelection(): void {\r\n const duration = this.selectedDuration() === 'Vælg selv'\r\n ? this.customDurationLabel()\r\n : this.selectedDuration();\r\n\r\n const data: WhenCanBookData = {\r\n days: Array.from(this.selectedDays()),\r\n timeRange: { start: this.startTime(), end: this.endTime() },\r\n duration\r\n };\r\n this.modalController.dismiss({ value: data }, 'select');\r\n }\r\n\r\n /**\r\n * Dismiss without saving\r\n */\r\n dismiss(): void {\r\n this.modalController.dismiss(null, 'cancel');\r\n }\r\n}\r\n","import { Component, signal, computed, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { DsInputComponent, DsLabelComponent } from '@propbinder/design-system';\r\nimport { DsMobileBottomSheetWrapperComponent } from '../../bottom-sheet/ds-mobile-bottom-sheet-wrapper';\r\nimport { DsMobileBottomSheetHeaderComponent } from '../../bottom-sheet/ds-mobile-bottom-sheet-header';\r\n\r\n/**\r\n * DsMobilePriceSheetComponent\r\n *\r\n * Bottom sheet for setting facility booking price with toggle for free and custom price input.\r\n */\r\n@Component({\r\n selector: 'ds-mobile-price-sheet',\r\n standalone: true,\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n DsInputComponent,\r\n DsLabelComponent,\r\n DsMobileBottomSheetWrapperComponent,\r\n DsMobileBottomSheetHeaderComponent\r\n ],\r\n template: `\r\n <ds-mobile-bottom-sheet-wrapper>\r\n <!-- Header with back and done buttons -->\r\n <ds-mobile-bottom-sheet-header\r\n title=\"Pris\"\r\n leftButtonLabel=\"Annuller\"\r\n rightButtonLabel=\"Gem\"\r\n [rightButtonDisabled]=\"!isValid()\"\r\n (leftButtonClick)=\"dismiss()\"\r\n (rightButtonClick)=\"confirmSelection()\">\r\n </ds-mobile-bottom-sheet-header>\r\n\r\n <div class=\"form-content\">\r\n <div class=\"price-toggle-container\">\r\n <!-- Toggle for Gratis -->\r\n <div class=\"toggle-row\" (click)=\"toggleFree()\">\r\n <ds-label size=\"md\" className=\"form-section-label\">Gratis</ds-label>\r\n <div class=\"toggle-switch\" [class.active]=\"isFree()\">\r\n <div class=\"toggle-knob\"></div>\r\n </div>\r\n </div>\r\n\r\n <!-- Custom price input inside same container -->\r\n @if (!isFree()) {\r\n <div class=\"price-input-row\" (click)=\"$event.stopPropagation()\">\r\n <ds-label size=\"md\" className=\"form-section-label\">Hvad skal det koste?</ds-label>\r\n <ds-input\r\n type=\"number\"\r\n size=\"lg\"\r\n [(ngModel)]=\"customPrice\"\r\n placeholder=\"75\"\r\n [suffix]=\"'kr. per booking'\"\r\n class=\"price-input\">\r\n </ds-input>\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n </ds-mobile-bottom-sheet-wrapper>\r\n `,\r\n styles: [`\r\n .form-content {\r\n padding: 16px;\r\n }\r\n\r\n .price-toggle-container {\r\n display: flex;\r\n flex-direction: column;\r\n background: var(--color-background-neutral-primary, #f5f5f5);\r\n border: 1px solid var(--border-color-default);\r\n border-radius: 12px;\r\n margin-bottom: 24px;\r\n overflow: hidden;\r\n }\r\n\r\n /* Toggle row */\r\n .toggle-row {\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n padding: 16px;\r\n cursor: pointer;\r\n transition: background 0.2s ease;\r\n }\r\n\r\n .toggle-row:hover {\r\n background: var(--color-background-neutral-primary-hover, #ebebeb);\r\n }\r\n\r\n /* Label spacing */\r\n ::ng-deep ds-label.form-section-label {\r\n display: block;\r\n margin-bottom: 8px;\r\n }\r\n\r\n ::ng-deep .form-section-label {\r\n font-weight: 500;\r\n }\r\n\r\n .toggle-switch {\r\n width: 51px;\r\n height: 32px;\r\n background: var(--color-background-neutral-tertiary);\r\n border-radius: 16px;\r\n position: relative;\r\n transition: background 0.3s ease;\r\n cursor: pointer;\r\n }\r\n\r\n .toggle-switch.active {\r\n background: var(--color-accent);\r\n }\r\n\r\n .toggle-knob {\r\n width: 27px;\r\n height: 27px;\r\n background: white;\r\n border-radius: 50%;\r\n position: absolute;\r\n top: 2px;\r\n left: 2px;\r\n transition: transform 0.3s ease;\r\n box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);\r\n }\r\n\r\n .toggle-switch.active .toggle-knob {\r\n transform: translateX(20px);\r\n }\r\n\r\n .price-input-row {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 8px;\r\n padding: 16px;\r\n border-top: 1px solid var(--border-color-default);\r\n }\r\n\r\n /* Increase input height to 48px */\r\n ::ng-deep .price-input .ds-input__field {\r\n height: 48px !important;\r\n min-height: 48px !important;\r\n }\r\n `]\r\n})\r\nexport class DsMobilePriceSheetComponent {\r\n // State\r\n isFree = signal(false);\r\n customPrice = signal('0');\r\n\r\n // Validation: if not free, price must be > 0\r\n isValid = computed(() => {\r\n if (this.isFree()) return true;\r\n const price = parseFloat(this.customPrice());\r\n return !isNaN(price) && price > 0;\r\n });\r\n\r\n constructor(private modalController: ModalController) {}\r\n\r\n /**\r\n * Toggle the \"Gratis\" (free) option\r\n */\r\n toggleFree(): void {\r\n this.isFree.set(!this.isFree());\r\n if (this.isFree()) this.customPrice.set('');\r\n }\r\n\r\n /**\r\n * Confirm selection and dismiss with price value\r\n */\r\n confirmSelection(): void {\r\n const value = this.isFree() \r\n ? 'Gratis' \r\n : `${this.customPrice()} kr. per booking`;\r\n this.modalController.dismiss({ value }, 'select');\r\n }\r\n\r\n /**\r\n * Dismiss without saving\r\n */\r\n dismiss(): void {\r\n this.modalController.dismiss(null, 'cancel');\r\n }\r\n}\r\n","import { Component, signal, computed, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { DsCheckboxComponent } from '@propbinder/design-system';\r\nimport { DsMobileActionListItemComponent } from '../../action-list-item/ds-mobile-action-list-item';\r\nimport { DsMobileBottomSheetWrapperComponent } from '../../bottom-sheet/ds-mobile-bottom-sheet-wrapper';\r\nimport { DsMobileBottomSheetHeaderComponent } from '../../bottom-sheet/ds-mobile-bottom-sheet-header';\r\n\r\nexport interface AccessRequirementOption {\r\n value: string;\r\n label: string;\r\n}\r\n\r\n/**\r\n * DsMobileAccessSheetComponent\r\n *\r\n * Bottom sheet for selecting facility access requirements (multi-select with checkboxes).\r\n */\r\n@Component({\r\n selector: 'ds-mobile-access-sheet',\r\n standalone: true,\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n imports: [\r\n CommonModule,\r\n DsCheckboxComponent,\r\n DsMobileActionListItemComponent, \r\n DsMobileBottomSheetWrapperComponent,\r\n DsMobileBottomSheetHeaderComponent\r\n ],\r\n template: `\r\n <ds-mobile-bottom-sheet-wrapper>\r\n <!-- Header with back and done buttons -->\r\n <ds-mobile-bottom-sheet-header\r\n title=\"Adgangskrav\"\r\n leftButtonLabel=\"Tilbage\"\r\n rightButtonLabel=\"Gem\"\r\n (leftButtonClick)=\"dismiss()\"\r\n (rightButtonClick)=\"confirmSelection()\">\r\n </ds-mobile-bottom-sheet-header>\r\n\r\n <!-- Options list -->\r\n <div class=\"options-list\">\r\n @for (option of options; track option.value; let isLast = $last) {\r\n <ds-mobile-action-list-item\r\n [title]=\"option.label\"\r\n [showDivider]=\"!isLast\"\r\n (itemClick)=\"toggleOption(option.value)\">\r\n <div content-trailing>\r\n <ds-checkbox\r\n [checked]=\"selectedRestrictions().has(option.value)\"\r\n [showLabel]=\"false\"\r\n size=\"md\"\r\n (click)=\"$event.stopPropagation()\"\r\n (checkedChange)=\"toggleOption(option.value)\">\r\n </ds-checkbox>\r\n </div>\r\n </ds-mobile-action-list-item>\r\n }\r\n </div>\r\n </ds-mobile-bottom-sheet-wrapper>\r\n `,\r\n styles: [`\r\n .options-list {\r\n display: flex;\r\n flex-direction: column;\r\n padding: 0 16px;\r\n }\r\n `]\r\n})\r\nexport class DsMobileAccessSheetComponent {\r\n options: AccessRequirementOption[] = [\r\n { value: 'digital-adgangskode', label: 'Digital adgangskode' },\r\n { value: 'depositum', label: 'Depositum' },\r\n { value: 'nøglekort', label: 'Nøglekort' }\r\n ];\r\n\r\n // State - no default selection\r\n selectedRestrictions = signal<Set<string>>(new Set());\r\n\r\n constructor(private modalController: ModalController) {}\r\n\r\n /**\r\n * Toggle an option on/off\r\n */\r\n toggleOption(value: string): void {\r\n const current = new Set(this.selectedRestrictions());\r\n current.has(value) ? current.delete(value) : current.add(value);\r\n this.selectedRestrictions.set(current);\r\n }\r\n\r\n /**\r\n * Confirm selection and dismiss with selected restrictions\r\n */\r\n confirmSelection(): void {\r\n const selected = Array.from(this.selectedRestrictions());\r\n this.modalController.dismiss({ value: selected }, 'select');\r\n }\r\n\r\n /**\r\n * Dismiss without saving\r\n */\r\n dismiss(): void {\r\n this.modalController.dismiss(null, 'cancel');\r\n }\r\n}\r\n","import { Component, Input, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { DsButtonComponent } from '@propbinder/design-system';\r\nimport { DsMobileModalBaseComponent } from '../modal-base/ds-mobile-modal-base';\r\nimport { DsMobileSectionComponent } from '../section';\r\nimport { DsMobileSwiperComponent } from '../swiper/ds-mobile-swiper';\r\nimport { DsMobileBookingModalService } from '../booking-modal';\r\n\r\n/**\r\n * Facility data interface for the modal\r\n *\r\n * Represents a facility with its content, images, requirements, and restrictions.\r\n * Use this interface to map your API response data to the component.\r\n *\r\n * @example\r\n * ```typescript\r\n * const facilityData: FacilityDetailData = {\r\n * id: 'facility-1',\r\n * facilityTitle: 'Festlokale på taget',\r\n * heroImage: '/Assets/Dummy-photos/balcony-view.jpg',\r\n * fullDescription: '<p>The rooftop terrace...</p>',\r\n * requirements: ['Kræver nøglekort'],\r\n * bookingType: 'Instant booking',\r\n * expectations: '<p>The terrace is furnished...</p>',\r\n * restrictions: ['No smoking...']\r\n * };\r\n * ```\r\n */\r\nexport interface FacilityDetailData {\r\n /** Unique facility identifier */\r\n id: string;\r\n /** Facility title/name */\r\n facilityTitle: string;\r\n /** Hero image URL for the top of the modal */\r\n heroImage?: string;\r\n /** Full description of the facility (HTML rich text) */\r\n fullDescription: string;\r\n /** List of requirements (e.g., \"Kræver nøglekort\") */\r\n requirements?: string[];\r\n /** Booking type (e.g., \"Instant booking\") */\r\n bookingType?: string;\r\n /** Expectations section content (HTML rich text) */\r\n expectations?: string;\r\n /** List of restrictions */\r\n restrictions?: string[];\r\n /** Availability status for display */\r\n availabilityStatus?: string;\r\n /** Status label text */\r\n statusLabel?: string;\r\n /** Booking date (for active bookings) */\r\n bookingDate?: string;\r\n /** Booking time range (for active bookings) */\r\n bookingTime?: string;\r\n}\r\n\r\n/**\r\n * DsMobileFacilityDetailModalComponent\r\n *\r\n * Modal wrapper for displaying facility details with rich content.\r\n * Follows the same pattern as the post detail modal for consistent behavior.\r\n *\r\n * Features:\r\n * - Hero image with swiper support\r\n * - Requirements and booking type display\r\n * - Rich text description\r\n * - Expectations section\r\n * - Restrictions list\r\n * - Fixed bottom booking button\r\n * - Native modal controls (close, swipe down)\r\n * - Safe area support\r\n *\r\n * This component is typically not used directly - use DsMobileFacilityDetailModalService instead.\r\n *\r\n * @example\r\n * ```typescript\r\n * // Don't instantiate directly - use the service:\r\n * constructor(private facilityModal: DsMobileFacilityDetailModalService) {}\r\n *\r\n * openFacility() {\r\n * this.facilityModal.open({\r\n * id: 'facility-1',\r\n * facilityTitle: 'Festlokale på taget',\r\n * fullDescription: '<p>Description...</p>'\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-facility-detail-modal',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n DsButtonComponent,\r\n DsMobileModalBaseComponent,\r\n DsMobileSectionComponent,\r\n DsMobileSwiperComponent,\r\n ],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n styles: [`\r\n :host {\r\n display: block;\r\n }\r\n \r\n /* Hero image styling */\r\n .facility-image {\r\n width: 100%;\r\n max-width: 100%;\r\n height: 280px;\r\n object-fit: cover;\r\n display: block;\r\n border-radius: 12px;\r\n }\r\n \r\n /* Info items (requirements, booking type) */\r\n .info-item {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n padding: 8px 0;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm, 14px);\r\n color: var(--text-color-default-primary, #202227);\r\n }\r\n \r\n /* Rich text content */\r\n .facility-description,\r\n .facility-expectations {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm, 14px);\r\n line-height: 1.6;\r\n color: var(--text-color-default-primary, #202227);\r\n }\r\n \r\n .facility-description p,\r\n .facility-expectations p {\r\n margin: 0 0 12px 0;\r\n }\r\n \r\n .facility-description p:last-child,\r\n .facility-expectations p:last-child {\r\n margin-bottom: 0;\r\n }\r\n \r\n /* Headings within description - use ::ng-deep to penetrate innerHTML */\r\n ::ng-deep .facility-description h3,\r\n ::ng-deep .facility-description headline,\r\n ::ng-deep .facility-description .section-headline {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base, 16px);\r\n font-weight: 600;\r\n line-height: 1.4;\r\n color: var(--text-color-default-primary, #202227);\r\n margin: 0 !important;\r\n padding: 0 !important;\r\n padding-top: 24px !important;\r\n padding-bottom: 8px !important;\r\n display: block;\r\n }\r\n\r\n /* Headings within description */\r\n .section-headline {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base, 16px);\r\n font-weight: 600;\r\n line-height: 1.4;\r\n color: var(--text-color-default-primary, #202227);\r\n margin: 0 !important;\r\n padding-top: 24px !important;\r\n padding-bottom: 8px !important;\r\n display: block;\r\n }\r\n \r\n \r\n ::ng-deep .facility-description h3:first-child,\r\n ::ng-deep .facility-description headline:first-child,\r\n ::ng-deep .facility-description .section-headline:first-child,\r\n ::ng-deep .facility-description > *:first-child h3:first-child,\r\n ::ng-deep .facility-description > *:first-child headline:first-child {\r\n padding-top: 0 !important;\r\n }\r\n \r\n /* Expectations section headings */\r\n ::ng-deep .facility-expectations headline,\r\n ::ng-deep .facility-expectations h3 {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base, 16px);\r\n font-weight: 600;\r\n line-height: 1.4;\r\n color: var(--text-color-default-primary, #202227);\r\n margin: 0 !important;\r\n padding: 0 !important;\r\n padding-top: 24px !important;\r\n padding-bottom: 8px !important;\r\n display: block;\r\n }\r\n \r\n ::ng-deep .facility-expectations headline:first-child,\r\n ::ng-deep .facility-expectations h3:first-child {\r\n padding-top: 0 !important;\r\n }\r\n \r\n /* Standalone section headline (used for \"Ting, du skal vide\") */\r\n h2.section-headline {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base, 16px);\r\n font-weight: 600;\r\n line-height: 1.4;\r\n color: var(--text-color-default-primary, #202227);\r\n margin: 0;\r\n padding-top: 16px !important;\r\n padding-bottom: 8px;\r\n }\r\n \r\n /* Lists within description */\r\n .facility-description ul {\r\n list-style: disc;\r\n padding-left: 20px;\r\n margin: 0 0 12px 0;\r\n }\r\n \r\n .facility-description ul li {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm, 14px);\r\n line-height: 1.6;\r\n color: var(--text-color-default-primary, #202227);\r\n margin-bottom: 8px;\r\n }\r\n \r\n .facility-description ul li:last-child {\r\n margin-bottom: 0;\r\n }\r\n \r\n /* Restrictions within the same section */\r\n .facility-restrictions {\r\n margin-top: 20px;\r\n }\r\n \r\n .restrictions-heading {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base, 16px);\r\n font-weight: 600;\r\n line-height: 1.4;\r\n color: var(--text-color-default-primary, #202227);\r\n margin: 0 0 12px 0;\r\n }\r\n \r\n /* Restrictions list */\r\n .restrictions-list {\r\n list-style: disc;\r\n padding-left: 20px;\r\n margin: 0;\r\n }\r\n \r\n .restrictions-list li {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm, 14px);\r\n line-height: 1.6;\r\n color: var(--text-color-default-primary, #202227);\r\n margin-bottom: 8px;\r\n }\r\n \r\n .restrictions-list li:last-child {\r\n margin-bottom: 0;\r\n }\r\n \r\n /* Info items container */\r\n .info-items-container {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 0;\r\n }\r\n \r\n /* Fixed bottom button */\r\n .booking-action {\r\n padding: 16px 20px;\r\n background: var(--color-surface-primary, #ffffff);\r\n border-top: 1px solid var(--color-border, #e5e5e5);\r\n }\r\n \r\n .booking-action ds-button {\r\n display: block;\r\n width: 100%;\r\n }\r\n \r\n .booking-action ::ng-deep ds-button button {\r\n width: 100%;\r\n border-radius: 100px;\r\n height: 44px;\r\n min-height: 44px;\r\n max-height: 44px;\r\n padding-left: 16px;\r\n padding-right: 16px;\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-modal-base\r\n [headerTitle]=\"facilityData.facilityTitle\"\r\n [hasFixedBottom]=\"true\"\r\n [keyboardContentBehavior]=\"'overlay'\">\r\n \r\n <!-- Hero Image Section -->\r\n <!-- Hero Image and Things to Know Section -->\r\n @if (facilityData.heroImage) {\r\n <ds-mobile-section contentGap=\"20px\">\r\n <ds-mobile-swiper\r\n [slideWidth]=\"'100%'\"\r\n [gap]=\"16\">\r\n <div class=\"swiper-slide\">\r\n <img [src]=\"facilityData.heroImage\" [alt]=\"facilityData.facilityTitle\" class=\"facility-image\" />\r\n </div>\r\n </ds-mobile-swiper>\r\n \r\n </ds-mobile-section>\r\n }\r\n \r\n <!-- Full Description Section -->\r\n <ds-mobile-section>\r\n <div class=\"facility-description\" [innerHTML]=\"facilityData.fullDescription\"></div>\r\n \r\n @if (facilityData.expectations) {\r\n <div class=\"facility-expectations\" [innerHTML]=\"facilityData.expectations\"></div>\r\n }\r\n \r\n @if (facilityData.restrictions?.length) {\r\n <div class=\"facility-restrictions\">\r\n <h3 class=\"restrictions-heading\">Restriktioner</h3>\r\n <ul class=\"restrictions-list\">\r\n @for (restriction of facilityData.restrictions; track restriction) {\r\n <li>{{ restriction }}</li>\r\n }\r\n </ul>\r\n </div>\r\n }\r\n </ds-mobile-section>\r\n \r\n <!-- Fixed Bottom Button -->\r\n <div fixed-bottom class=\"booking-action\">\r\n <ds-button\r\n size=\"md\"\r\n variant=\"primary\"\r\n [fullWidth]=\"true\"\r\n (clicked)=\"handleBookNow()\">\r\n Book nu\r\n </ds-button>\r\n </div>\r\n </ds-mobile-modal-base>\r\n `\r\n})\r\nexport class DsMobileFacilityDetailModalComponent {\r\n /**\r\n * Facility data to display in the modal\r\n */\r\n @Input() facilityData!: FacilityDetailData;\r\n \r\n constructor(\r\n private modalController: ModalController,\r\n private bookingModalService: DsMobileBookingModalService\r\n ) {}\r\n \r\n /**\r\n * Handle booking button click\r\n * Opens the booking modal for date/time selection\r\n */\r\n async handleBookNow(): Promise<void> {\r\n await this.bookingModalService.open({\r\n facilityId: this.facilityData.id,\r\n facilityTitle: this.facilityData.facilityTitle,\r\n facilityThumbnail: this.facilityData.heroImage\r\n });\r\n }\r\n \r\n /**\r\n * Close the modal\r\n */\r\n close(): void {\r\n this.modalController.dismiss();\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { BaseModalService } from '../../services/base-modal.service';\r\nimport {\r\n DsMobileFacilityDetailModalComponent,\r\n FacilityDetailData,\r\n} from './ds-mobile-facility-detail-modal';\r\n\r\n/**\r\n * DsMobileFacilityDetailModalService\r\n *\r\n * Service for displaying facility details in a full-screen modal.\r\n * Built on Ionic's modal system with native gestures and animations.\r\n * Follows the same pattern as DsMobilePostDetailModalService for consistent behavior.\r\n *\r\n * Features:\r\n * - Full facility information display\r\n * - Hero image with swiper\r\n * - Rich text description support\r\n * - Requirements and booking type display\r\n * - Restrictions list\r\n * - Fixed bottom booking button\r\n * - Native modal animations\r\n * - Safe area support\r\n *\r\n * @example\r\n * ```typescript\r\n * constructor(private facilityModal: DsMobileFacilityDetailModalService) {}\r\n *\r\n * async openFacility() {\r\n * await this.facilityModal.open({\r\n * id: 'facility-1',\r\n * facilityTitle: 'Festlokale på taget',\r\n * heroImage: '/Assets/Dummy-photos/balcony-view.jpg',\r\n * fullDescription: '<p>The rooftop terrace is designed...</p>',\r\n * requirements: ['Kræver nøglekort'],\r\n * bookingType: 'Instant booking',\r\n * expectations: '<p>The terrace is furnished...</p>',\r\n * restrictions: ['No smoking or vaping...']\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class DsMobileFacilityDetailModalService extends BaseModalService {\r\n constructor(modalController: ModalController) {\r\n super(modalController);\r\n }\r\n\r\n /**\r\n * Open the facility detail modal\r\n *\r\n * @param facilityData Facility data to display\r\n * @returns Promise that resolves when the modal is presented\r\n */\r\n async open(facilityData: FacilityDetailData): Promise<void> {\r\n const modal = await this.createModal(\r\n DsMobileFacilityDetailModalComponent,\r\n { facilityData },\r\n {\r\n keyboardClose: true, // Allow keyboard close behavior\r\n }\r\n );\r\n\r\n await modal.present();\r\n }\r\n}\r\n","import { Component, Input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobileHandbookFolderMiniComponent\r\n *\r\n * A minimized folder icon component for use in headers and small spaces.\r\n * Simplified version without animations or page sheets - just folder and icon.\r\n *\r\n * @example\r\n * ```html\r\n * <ds-mobile-handbook-folder-mini\r\n * [variant]=\"'pink'\"\r\n * [iconName]=\"'remixLightbulbLine'\">\r\n * </ds-mobile-handbook-folder-mini>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-handbook-folder-mini',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent],\r\n styles: [\r\n `\r\n :host {\r\n display: inline-block;\r\n width: 32px;\r\n height: 32px;\r\n flex-shrink: 0;\r\n\r\n /* Native support for extended API colors */\r\n --color-red-base: #dc3545;\r\n --color-red-strong: #ae1d3b;\r\n --color-green-base: #28a745;\r\n --color-green-strong: #058057;\r\n --color-yellow-base: #ffc107;\r\n --color-yellow-strong: #e4b200;\r\n --color-purple-base: #6f42c1;\r\n --color-purple-strong: #4204c5;\r\n --color-indigo-base: #6610f2;\r\n --color-indigo-strong: #a527a2;\r\n --color-lime-base: #82c91e;\r\n --color-lime-strong: #58a503;\r\n --color-teal-base: #20c997;\r\n --color-teal-strong: #0ca678;\r\n --color-cyan-base: #17a2b8;\r\n --color-cyan-strong: #1098ad;\r\n --color-brown-base: #795548;\r\n --color-brown-strong: #5c4033;\r\n --color-light-blue-base: #add8e6;\r\n --color-light-blue-strong: #87ceeb;\r\n --color-light-green-base: #90ee90;\r\n --color-light-green-strong: #32cd32;\r\n --color-coral-base: #f08080;\r\n --color-coral-strong: #cd5c5c;\r\n --color-salmon-base: #ffa07a;\r\n --color-salmon-strong: #fa8072;\r\n --color-seagreen-base: #20b2aa;\r\n --color-seagreen-strong: #2e8b57;\r\n }\r\n\r\n .mini-folder-container {\r\n position: relative;\r\n width: 100%;\r\n height: 100%;\r\n display: flex;\r\n flex-direction: column;\r\n }\r\n\r\n .mini-folder-tab {\r\n width: 50%;\r\n height: auto;\r\n display: block;\r\n }\r\n\r\n .mini-folder-back {\r\n height: 28px;\r\n border-radius: 0px 4px 4px 4px;\r\n position: relative;\r\n margin-top: -1px;\r\n }\r\n\r\n .mini-folder-front {\r\n position: absolute;\r\n bottom: 0;\r\n left: 0;\r\n right: 0;\r\n height: 24px;\r\n border-radius: 4px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n z-index: 2;\r\n box-shadow:\r\n inset 0 8px 8px rgba(255, 255, 255, 0.2),\r\n inset 0 0.5px 0.5px rgba(255, 255, 255, 0.3);\r\n }\r\n `,\r\n ],\r\n template: `\r\n <div class=\"mini-folder-container\">\r\n <!-- Folder Tab SVG -->\r\n <svg class=\"mini-folder-tab\" width=\"101\" height=\"24\" viewBox=\"0 0 101 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path\r\n d=\"M100.037 23.9999L100.5 24L0 24.0001V10.7646C0 4.80853 4.91797 -0.0234985 11 -0.0196688L66.4213 -0.0322266C69.3519 -0.0115886 72.197 1.20548 74.2473 3.29947L90.6765 20.0951C93.1218 22.5925 96.5417 23.9999 100.037 23.9999Z\"\r\n [attr.fill]=\"customColor || getColorVar('strong')\"\r\n />\r\n </svg>\r\n\r\n <!-- Folder Back -->\r\n <div class=\"mini-folder-back\" [style.background-color]=\"customColor || getColorVar('strong')\">\r\n <!-- Folder Front -->\r\n <div class=\"mini-folder-front\" [style.background-color]=\"customColor || getColorVar('base')\">\r\n <ds-icon [name]=\"iconName\" [size]=\"'14px'\" [style.color]=\"'white'\" />\r\n </div>\r\n </div>\r\n </div>\r\n `,\r\n})\r\nexport class DsMobileHandbookFolderMiniComponent {\r\n /**\r\n * Color variant for the folder\r\n * Available variants: success, warning, destructive, blue, light-purple, pink, salmon-orange, orange, lime-green, grey\r\n */\r\n @Input() variant: string = 'light-purple';\r\n\r\n /**\r\n * Optional custom hex color for the folder.\r\n * If provided, overrides the variant color.\r\n */\r\n @Input() customColor?: string;\r\n\r\n /**\r\n * Icon name from the design system icon library\r\n */\r\n @Input() iconName: string = 'remixFolder3Line';\r\n\r\n /**\r\n * Get the CSS variable name for the color variant\r\n */\r\n getColorVar(suffix: 'base' | 'strong'): string {\r\n const variantMap: Record<string, string> = {\r\n // Core design system variants\r\n success: 'success',\r\n warning: 'warning',\r\n destructive: 'destructive',\r\n blue: 'blue',\r\n 'light-purple': 'light-purple',\r\n pink: 'pink',\r\n 'salmon-orange': 'salmon-orange',\r\n orange: 'orange',\r\n 'lime-green': 'lime-green',\r\n grey: 'grey',\r\n\r\n // Extended API colors mapping to their native exact counterparts now\r\n red: 'red',\r\n green: 'green',\r\n yellow: 'yellow',\r\n purple: 'purple',\r\n indigo: 'indigo',\r\n lime: 'lime',\r\n teal: 'teal',\r\n cyan: 'cyan',\r\n brown: 'brown',\r\n 'light-blue': 'light-blue',\r\n 'light-green': 'light-green',\r\n coral: 'coral',\r\n salmon: 'salmon',\r\n seagreen: 'seagreen',\r\n };\r\n\r\n const colorName = variantMap[this.variant] || 'light-purple';\r\n return `var(--color-${colorName}-${suffix})`;\r\n }\r\n}\r\n","import { Component, signal, Input, OnInit, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { DsMobileHandbookFolderMiniComponent } from '../handbook-folder/ds-mobile-handbook-folder-mini';\r\nimport { DsMobileCardInlineFileComponent } from '../card-inline-file';\r\nimport { DsMobileCardInlineContactComponent } from '../card-inline-contact';\r\nimport { DsMobileSwiperComponent } from '../swiper';\r\nimport { DsMobileModalBaseComponent } from '../modal-base/ds-mobile-modal-base';\r\nimport { DsMobileSectionComponent } from '../section';\r\nimport { DsMobileActionsBottomSheetComponent, ActionGroup } from '../bottom-sheet/ds-mobile-actions-bottom-sheet';\r\nimport { disableModalShadowPointerEvents } from '../bottom-sheet/modal-shadow-fix';\r\n\r\n/**\r\n * Handbook detail data interface\r\n *\r\n * Represents a handbook category/folder with its sections/items.\r\n * Use this interface to map your API response data to the component.\r\n *\r\n * @example\r\n * ```typescript\r\n * const handbookData: HandbookDetailData = {\r\n * title: 'Access Systems',\r\n * variant: 'blue',\r\n * iconName: 'remixKey2Line',\r\n * itemCount: 5,\r\n * items: [...]\r\n * };\r\n * ```\r\n */\r\nexport interface HandbookDetailData {\r\n /** Category/folder title */\r\n title: string;\r\n /** Color variant: 'success', 'warning', 'destructive', 'blue', 'light-purple', 'pink', 'salmon-orange', 'orange', 'lime-green', 'grey' */\r\n variant: string;\r\n /** Optional custom hex color */\r\n customColor?: string;\r\n /** Icon name from design system (e.g., 'remixKey2Line', 'remixLightbulbLine') */\r\n iconName: string;\r\n /** Total number of items/sections in this category */\r\n itemCount: number;\r\n /** Array of handbook sections/items */\r\n items?: HandbookItem[];\r\n}\r\n\r\n/**\r\n * Handbook section/item interface\r\n *\r\n * Represents a single section within a handbook category.\r\n * Each section can have a title, description, images, contacts, and attachments.\r\n *\r\n * @example\r\n * ```typescript\r\n * const item: HandbookItem = {\r\n * title: 'Key Box Entrance',\r\n * description: 'Key box located at main entrance...',\r\n * images: ['https://api.example.com/images/keybox.jpg'],\r\n * contacts: [{ name: 'Security Co', initials: 'S', phoneNumber: '+45 12345678' }],\r\n * attachments: [{ name: 'Manual.pdf', type: 'pdf', url: 'https://...' }]\r\n * };\r\n * ```\r\n */\r\nexport interface HandbookItem {\r\n /** Section title */\r\n title: string;\r\n /** Optional section description */\r\n description?: string;\r\n /** Array of image URLs to display */\r\n images?: string[];\r\n /** Array of file attachments */\r\n attachments?: AttachmentItem[];\r\n /** Array of contact information */\r\n contacts?: ContactItem[];\r\n}\r\n\r\n/**\r\n * File attachment interface\r\n *\r\n * Represents a file attachment in a handbook section.\r\n *\r\n * @example\r\n * ```typescript\r\n * const attachment: AttachmentItem = {\r\n * name: 'Installation_Manual.pdf',\r\n * type: 'pdf',\r\n * url: 'https://api.example.com/files/manual.pdf'\r\n * };\r\n * ```\r\n */\r\nexport interface AttachmentItem {\r\n /** File name to display */\r\n name: string;\r\n /** File type: 'pdf', 'doc', etc. (used for icon display) */\r\n type?: string;\r\n /** Optional URL for downloading/opening the file */\r\n url?: string;\r\n}\r\n\r\n/**\r\n * Contact information interface\r\n *\r\n * Represents contact information in a handbook section.\r\n *\r\n * @example\r\n * ```typescript\r\n * const contact: ContactItem = {\r\n * name: 'Propbinder ApS',\r\n * initials: 'P',\r\n * contactPerson: 'John Doe',\r\n * phoneNumber: '+45 12345678',\r\n * email: 'support@propbinder.dk'\r\n * };\r\n * ```\r\n */\r\nexport interface ContactItem {\r\n /** Company or contact name */\r\n name: string;\r\n /** Initials for avatar (1-2 letters) */\r\n initials: string;\r\n /** Optional contact person name */\r\n contactPerson?: string;\r\n /** Optional phone number */\r\n phoneNumber?: string;\r\n /** Optional email address */\r\n email?: string;\r\n}\r\n\r\n/**\r\n * DsMobileHandbookDetailModalComponent\r\n *\r\n * Modal wrapper for displaying handbook folder details.\r\n *\r\n * Features:\r\n * - Folder content display\r\n * - Items list with descriptions\r\n * - Images and attachments\r\n * - Contact information\r\n * - Native modal controls (close, swipe down)\r\n * - Safe area support\r\n *\r\n * This component is typically not used directly - use DsMobileHandbookDetailModalService instead.\r\n */\r\n@Component({\r\n selector: 'ds-mobile-handbook-detail-modal',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n DsMobileHandbookFolderMiniComponent,\r\n DsMobileCardInlineFileComponent,\r\n DsMobileCardInlineContactComponent,\r\n DsMobileSwiperComponent,\r\n DsMobileModalBaseComponent,\r\n DsMobileSectionComponent,\r\n ],\r\n styleUrls: ['./ds-mobile-handbook-detail-modal.css'],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n template: `\r\n <ds-mobile-modal-base [loading]=\"loading\" [error]=\"error\" [headerTitle]=\"handbook().title\" [headerMeta]=\"handbook().itemCount + ' emner'\" closeButtonLabel=\"Luk\">\r\n <!-- Header Folder Icon -->\r\n <ds-mobile-handbook-folder-mini header-leading [variant]=\"handbook().variant\" [customColor]=\"handbook().customColor\" [iconName]=\"handbook().iconName\">\r\n </ds-mobile-handbook-folder-mini>\r\n\r\n <!-- Content (main content slot) -->\r\n @if (handbook().items && handbook().items!.length > 0) {\r\n @for (item of getDisplayItems(); track item.title + $index) {\r\n <ds-mobile-section [headline]=\"item.title || ''\" contentGap=\"20px\">\r\n @if (item.description) {\r\n <div class=\"item-description\" [innerHTML]=\"item.description\"></div>\r\n }\r\n\r\n <!-- Images -->\r\n @if (item.images && item.images.length > 0) {\r\n <ds-mobile-swiper [slideWidth]=\"item.images.length === 1 ? '100%' : '85%'\" [gap]=\"16\">\r\n @for (image of item.images; track image) {\r\n <div class=\"swiper-slide\">\r\n <img [src]=\"image\" [alt]=\"item.title\" class=\"item-image\" />\r\n </div>\r\n }\r\n </ds-mobile-swiper>\r\n }\r\n\r\n <!-- Contacts and Attachments (grouped) -->\r\n @if ((item.contacts && item.contacts.length > 0) || (item.attachments && item.attachments.length > 0)) {\r\n <div class=\"contacts-attachments-group\">\r\n @if (item.contacts && item.contacts.length > 0) {\r\n @for (contact of item.contacts; track contact.name) {\r\n <ds-mobile-card-inline-contact\r\n [name]=\"contact.name\"\r\n [initials]=\"contact.initials\"\r\n [contactPerson]=\"contact.contactPerson || ''\"\r\n [phoneNumber]=\"contact.phoneNumber || ''\"\r\n [clickable]=\"true\"\r\n (contactClick)=\"handleContactClick(contact)\"\r\n >\r\n </ds-mobile-card-inline-contact>\r\n }\r\n }\r\n\r\n @if (item.attachments && item.attachments.length > 0) {\r\n @for (attachment of item.attachments; track attachment.name) {\r\n <ds-mobile-card-inline-file\r\n [fileName]=\"attachment.name\"\r\n [variant]=\"attachment.type === 'pdf' ? 'pdf' : 'doc'\"\r\n [fileUrl]=\"attachment.url\"\r\n (fileClick)=\"handleAttachmentClick(attachment)\"\r\n >\r\n </ds-mobile-card-inline-file>\r\n }\r\n }\r\n </div>\r\n }\r\n </ds-mobile-section>\r\n }\r\n } @else {\r\n <!-- Empty State -->\r\n <ds-mobile-section>\r\n <div class=\"handbook-empty-state\">\r\n <img src=\"/Assets/Empty%20state-chat.png\" alt=\"No items yet\" class=\"empty-state-image\" />\r\n <h3 class=\"empty-state-title\">No items yet</h3>\r\n <p class=\"empty-state-description\">This folder is empty</p>\r\n </div>\r\n </ds-mobile-section>\r\n }\r\n </ds-mobile-modal-base>\r\n `,\r\n})\r\nexport class DsMobileHandbookDetailModalComponent implements OnInit {\r\n // Handbook data passed from service\r\n @Input() handbookData!: HandbookDetailData;\r\n\r\n /**\r\n * Loading state - when true, shows loading indicator\r\n */\r\n @Input() loading: boolean = false;\r\n\r\n /**\r\n * Error state - when set, shows error message\r\n */\r\n @Input() error?: string;\r\n\r\n // Signal for reactive handbook data\r\n handbook = signal<HandbookDetailData>({\r\n title: '',\r\n variant: 'light-purple',\r\n iconName: 'remixFolder3Line',\r\n itemCount: 0,\r\n items: [],\r\n });\r\n\r\n constructor(private modalController: ModalController) {}\r\n\r\n ngOnInit(): void {\r\n // Initialize handbook data from input\r\n if (this.handbookData) {\r\n this.handbook.set(this.handbookData);\r\n }\r\n }\r\n\r\n /**\r\n * Split handbook items to enforce content structure rules:\r\n * - Never mix photos and documents (attachments) in the same section\r\n * - Never mix contact persons and attachments together in the same section\r\n *\r\n * This method splits items that violate these rules into multiple display items.\r\n * Each resulting item will have only compatible content types.\r\n */\r\n splitItemsByContentRules(item: HandbookItem): HandbookItem[] {\r\n const displayItems: HandbookItem[] = [];\r\n\r\n const hasImages = item.images && item.images.length > 0;\r\n const hasContacts = item.contacts && item.contacts.length > 0;\r\n const hasAttachments = item.attachments && item.attachments.length > 0;\r\n const hasContent = hasContacts || hasAttachments;\r\n\r\n // Case 1: Images AND other content -> Split Pictures from (Contacts + Attachments)\r\n if (hasImages && hasContent) {\r\n // Part 1: Images\r\n displayItems.push({\r\n title: item.title,\r\n description: item.description,\r\n images: item.images,\r\n });\r\n\r\n // Part 2: Contacts + Attachments\r\n displayItems.push({\r\n title: '', // No title for the continuation\r\n description: undefined,\r\n contacts: item.contacts,\r\n attachments: item.attachments,\r\n });\r\n\r\n return displayItems;\r\n }\r\n\r\n // Case 2: No splitting needed (Images only, or No Images)\r\n // This allows Contacts and Attachments to coexist in one item\r\n return [item];\r\n }\r\n\r\n /**\r\n * Get all display items with enforced content structure rules applied\r\n */\r\n getDisplayItems(): HandbookItem[] {\r\n const items = this.handbook().items || [];\r\n const displayItems: HandbookItem[] = [];\r\n\r\n for (const item of items) {\r\n const splitItems = this.splitItemsByContentRules(item);\r\n displayItems.push(...splitItems);\r\n }\r\n\r\n return displayItems;\r\n }\r\n\r\n /**\r\n * Handle contact click - shows bottom sheet with call and copy actions\r\n */\r\n async handleContactClick(contact: ContactItem): Promise<void> {\r\n // Only show actions if there's a phone number\r\n if (!contact.phoneNumber) {\r\n return;\r\n }\r\n\r\n const actionGroups: ActionGroup[] = [\r\n {\r\n actions: [\r\n {\r\n action: 'call',\r\n title: 'Ring',\r\n icon: 'remixPhoneLine',\r\n },\r\n {\r\n action: 'copy',\r\n title: 'Kopier nummer',\r\n icon: 'remixFileCopyLine',\r\n },\r\n ],\r\n },\r\n ];\r\n\r\n const sheet = await this.modalController.create({\r\n component: DsMobileActionsBottomSheetComponent,\r\n componentProps: {\r\n customActionGroups: actionGroups,\r\n },\r\n breakpoints: [0, 1],\r\n initialBreakpoint: 1,\r\n handle: true,\r\n cssClass: ['ds-bottom-sheet', 'auto-height'],\r\n });\r\n\r\n await sheet.present();\r\n disableModalShadowPointerEvents(sheet);\r\n\r\n const result = await sheet.onWillDismiss();\r\n if (result.data?.action) {\r\n this.handleContactAction(result.data.action, contact);\r\n }\r\n }\r\n\r\n /**\r\n * Handle the selected contact action\r\n */\r\n private async handleContactAction(action: string, contact: ContactItem): Promise<void> {\r\n switch (action) {\r\n case 'call':\r\n // Open phone dialer with the contact's phone number\r\n if (contact.phoneNumber) {\r\n window.location.href = `tel:${contact.phoneNumber}`;\r\n }\r\n break;\r\n\r\n case 'copy':\r\n // Copy phone number to clipboard\r\n if (contact.phoneNumber) {\r\n try {\r\n // Try modern Clipboard API first\r\n await navigator.clipboard.writeText(contact.phoneNumber);\r\n console.log('Phone number copied to clipboard:', contact.phoneNumber);\r\n // TODO: Show toast notification if you have a toast service\r\n } catch (err) {\r\n console.error('Failed to copy phone number:', err);\r\n // Fallback: Try older execCommand method\r\n this.fallbackCopyToClipboard(contact.phoneNumber);\r\n }\r\n }\r\n break;\r\n }\r\n }\r\n\r\n /**\r\n * Fallback method for copying text to clipboard (for older browsers/webviews)\r\n */\r\n private fallbackCopyToClipboard(text: string): void {\r\n const textArea = document.createElement('textarea');\r\n textArea.value = text;\r\n textArea.style.position = 'fixed';\r\n textArea.style.left = '-999999px';\r\n textArea.style.top = '-999999px';\r\n document.body.appendChild(textArea);\r\n textArea.focus();\r\n textArea.select();\r\n\r\n try {\r\n const successful = document.execCommand('copy');\r\n if (successful) {\r\n console.log('Phone number copied to clipboard (fallback):', text);\r\n } else {\r\n console.error('Fallback copy failed');\r\n }\r\n } catch (err) {\r\n console.error('Fallback copy error:', err);\r\n }\r\n\r\n document.body.removeChild(textArea);\r\n }\r\n\r\n /**\r\n * Handle attachment click\r\n */\r\n handleAttachmentClick(attachment: AttachmentItem): void {\r\n console.log('Attachment clicked:', attachment);\r\n // Attachment action is now handled by DsMobileCardInlineFileComponent via fileUrl input\r\n }\r\n}\r\n","import { Injectable } from '@angular/core';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport {\r\n DsMobileHandbookDetailModalComponent,\r\n HandbookDetailData,\r\n} from './ds-mobile-handbook-detail-modal';\r\nimport { BaseModalService } from '../../services/base-modal.service';\r\n\r\n/**\r\n * DsMobileHandbookDetailModalService\r\n *\r\n * Service for displaying handbook folder details in a full-screen modal.\r\n * Built on Ionic's modal system with native gestures and animations.\r\n *\r\n * Features:\r\n * - Full handbook content display\r\n * - Items list with descriptions\r\n * - Images and attachments\r\n * - Contact information\r\n * - Native modal animations\r\n * - Safe area support\r\n *\r\n * @example\r\n * ```typescript\r\n * constructor(private handbookModal: DsMobileHandbookDetailModalService) {}\r\n *\r\n * async openHandbook() {\r\n * await this.handbookModal.open({\r\n * title: 'Utilities',\r\n * variant: 'pink',\r\n * iconName: 'remixLightbulbLine',\r\n * itemCount: 8,\r\n * items: [\r\n * {\r\n * title: 'Hjertestarter',\r\n * description: 'Installed on the 4th floor...',\r\n * images: ['/path/to/image.jpg'],\r\n * contacts: [\r\n * { name: 'Mortensen & Søn ApS', initials: 'M' }\r\n * ]\r\n * }\r\n * ]\r\n * });\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class DsMobileHandbookDetailModalService extends BaseModalService {\r\n constructor(modalController: ModalController) {\r\n super(modalController);\r\n }\r\n\r\n /**\r\n * Open the handbook detail modal\r\n *\r\n * @param handbookData Handbook data to display\r\n * @param options Optional loading and error states\r\n * @returns Promise that resolves when the modal is presented\r\n */\r\n async open(\r\n handbookData: HandbookDetailData,\r\n options?: { loading?: boolean; error?: string }\r\n ): Promise<void> {\r\n // console.log('[HandbookDetailModal] Opening with data:', handbookData);\r\n\r\n const modal = await this.createModal(\r\n DsMobileHandbookDetailModalComponent,\r\n {\r\n handbookData: handbookData,\r\n loading: options?.loading ?? false,\r\n error: options?.error,\r\n },\r\n {\r\n keyboardClose: true, // Keep keyboard close behavior for this modal\r\n }\r\n );\r\n\r\n // console.log('[HandbookDetailModal] Modal created, presenting...');\r\n await modal.present();\r\n // console.log('[HandbookDetailModal] Modal presented');\r\n }\r\n}\r\n","import { Component, Input, signal, HostListener } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\nimport { DsMobileHandbookDetailModalService, HandbookDetailData, HandbookItem } from '../handbook-detail-modal';\r\n\r\n/**\r\n * DsMobileHandbookFolderComponent\r\n *\r\n * A visually rich folder component for displaying handbook categories or sections.\r\n * Features a two-layer folder design with customizable colors, icon, item count, and label.\r\n *\r\n * Design Details:\r\n * - Folder back: 72px height with a decorative notch\r\n * - Folder front: 64px height overlaying the back\r\n * - Item count displayed in bottom-left corner\r\n * - Icon displayed in bottom-right corner\r\n * - Label text centered below the folder\r\n *\r\n * @example\r\n * ```html\r\n * <ds-mobile-handbook-folder\r\n * [colorBase]=\"'#d244cf'\"\r\n * [colorWeak]=\"'#f9e6f9'\"\r\n * [iconName]=\"'remixLightbulbLine'\"\r\n * [itemCount]=\"8\"\r\n * [label]=\"'Utilities'\">\r\n * </ds-mobile-handbook-folder>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-handbook-folder',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent],\r\n styles: [\r\n `\r\n :host {\r\n display: inline-flex;\r\n flex-direction: column;\r\n align-items: center;\r\n gap: 16px;\r\n width: 100%;\r\n min-width: 0;\r\n cursor: pointer;\r\n user-select: none;\r\n -webkit-tap-highlight-color: transparent;\r\n padding: 16px;\r\n border-radius: 16px;\r\n background: var(--color-background-neutral-secondary, #f0f0f0);\r\n transition: background 0.2s ease;\r\n }\r\n\r\n :host:active {\r\n background: var(--color-background-neutral-secondary-hover, #ebebeb);\r\n }\r\n\r\n @media (hover: hover) {\r\n :host:hover {\r\n background: var(--color-background-neutral-secondary-hover, #ebebeb);\r\n }\r\n }\r\n\r\n /* Native support for extended API colors */\r\n :host {\r\n --color-red-base: #dc3545;\r\n --color-red-strong: #ae1d3b;\r\n --color-green-base: #28a745;\r\n --color-green-strong: #058057;\r\n --color-yellow-base: #ffc107;\r\n --color-yellow-strong: #e4b200;\r\n --color-purple-base: #6f42c1;\r\n --color-purple-strong: #4204c5;\r\n --color-indigo-base: #6610f2;\r\n --color-indigo-strong: #a527a2;\r\n --color-lime-base: #82c91e;\r\n --color-lime-strong: #58a503;\r\n --color-teal-base: #20c997;\r\n --color-teal-strong: #0ca678;\r\n --color-cyan-base: #17a2b8;\r\n --color-cyan-strong: #1098ad;\r\n --color-brown-base: #795548;\r\n --color-brown-strong: #5c4033;\r\n --color-light-blue-base: #add8e6;\r\n --color-light-blue-strong: #87ceeb;\r\n --color-light-green-base: #90ee90;\r\n --color-light-green-strong: #32cd32;\r\n --color-coral-base: #f08080;\r\n --color-coral-strong: #cd5c5c;\r\n --color-salmon-base: #ffa07a;\r\n --color-salmon-strong: #fa8072;\r\n --color-seagreen-base: #20b2aa;\r\n --color-seagreen-strong: #2e8b57;\r\n }\r\n\r\n .folder-container {\r\n position: relative;\r\n width: 100%;\r\n display: flex;\r\n flex-direction: column;\r\n perspective: 800px;\r\n -webkit-perspective: 800px;\r\n max-width: 160px;\r\n /* Safari optimization: Ensure proper 3D rendering context */\r\n transform-style: preserve-3d;\r\n -webkit-transform-style: preserve-3d;\r\n }\r\n\r\n .folder-container.open .page-sheet {\r\n -webkit-transform: translateY(-8px);\r\n transform: translateY(-8px);\r\n transition-delay: 0.2s;\r\n }\r\n\r\n .folder-container.open .page-sheet:nth-child(1) {\r\n -webkit-transform: scale(1) translateY(-8px) rotateX(-45deg) translateZ(0.1px);\r\n transform: scale(1) translateY(-8px) rotateX(-45deg) translateZ(0.1px);\r\n }\r\n\r\n .folder-container.open .page-sheet:nth-child(2) {\r\n -webkit-transform: scale(0.98) translateY(-12px) rotateX(-36deg) translateZ(0.1px);\r\n transform: scale(0.98) translateY(-12px) rotateX(-36deg) translateZ(0.1px);\r\n }\r\n\r\n .folder-container.open .page-sheet:nth-child(3) {\r\n -webkit-transform: scale(0.96) translateY(-16px) rotateX(-27deg) translateZ(0.1px);\r\n transform: scale(0.96) translateY(-16px) rotateX(-27deg) translateZ(0.1px);\r\n }\r\n\r\n .folder-container.open .page-sheet:nth-child(4) {\r\n -webkit-transform: scale(0.94) translateY(-20px) rotateX(-18deg) translateZ(0.1px);\r\n transform: scale(0.94) translateY(-20px) rotateX(-18deg) translateZ(0.1px);\r\n }\r\n\r\n .folder-container.open .page-sheet:nth-child(5) {\r\n -webkit-transform: scale(0.92) translateY(-24px) rotateX(-9deg) translateZ(0.1px);\r\n transform: scale(0.92) translateY(-24px) rotateX(-9deg) translateZ(0.1px);\r\n }\r\n\r\n .folder-container.open .page-sheet:nth-child(6) {\r\n -webkit-transform: scale(0.9) translateY(-28px) rotateX(0deg) translateZ(0.1px);\r\n transform: scale(0.9) translateY(-28px) rotateX(0.1px);\r\n }\r\n\r\n .folder-container.open .folder-front {\r\n -webkit-transform: translate3d(0, 0, 0) rotateX(-45deg);\r\n transform: translate3d(0, 0, 0) rotateX(-45deg);\r\n }\r\n\r\n .folder-tab {\r\n width: 50%;\r\n height: auto;\r\n display: block;\r\n }\r\n\r\n .folder-back {\r\n height: 128px;\r\n border-radius: 0px 12px 12px 12px;\r\n position: relative;\r\n margin-top: -1px;\r\n transform-style: preserve-3d;\r\n -webkit-transform-style: preserve-3d;\r\n backface-visibility: hidden;\r\n -webkit-backface-visibility: hidden;\r\n /* Safari optimization: Force GPU acceleration */\r\n -webkit-transform: translateZ(0);\r\n transform: translateZ(0);\r\n }\r\n\r\n .page-sheet {\r\n position: absolute;\r\n width: 80%;\r\n height: 120px;\r\n background: #ffffff;\r\n border-radius: 8px;\r\n box-shadow: 0 -1px 5px rgba(0, 0, 0, 0.1);\r\n border: 1px solid var(--border-color-default);\r\n transition: transform 0.3s ease-out;\r\n -webkit-transition: -webkit-transform 0.3s ease-out;\r\n left: 10%;\r\n /* Safari optimization: Force hardware acceleration and proper 3D rendering */\r\n -webkit-transform: translateZ(0);\r\n transform: translateZ(0);\r\n transform-style: preserve-3d;\r\n -webkit-transform-style: preserve-3d;\r\n backface-visibility: hidden;\r\n -webkit-backface-visibility: hidden;\r\n /* Safari optimization: Prevent subpixel rendering issues */\r\n -webkit-font-smoothing: antialiased;\r\n /* Safari optimization: Ensure proper layer creation */\r\n will-change: transform;\r\n }\r\n\r\n .page-sheet:nth-child(1) {\r\n bottom: 2px;\r\n z-index: 6;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n -webkit-transform: scale(1) translateZ(0.1px);\r\n transform: scale(1) translateZ(0.1px);\r\n }\r\n\r\n .page-sheet:nth-child(2) {\r\n bottom: 8px;\r\n z-index: 5;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n -webkit-transform: scale(0.98) translateZ(0.1px);\r\n transform: scale(0.98) translateZ(0.1px);\r\n }\r\n\r\n .page-sheet:nth-child(3) {\r\n bottom: 14px;\r\n z-index: 4;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n -webkit-transform: scale(0.96) translateZ(0.1px);\r\n transform: scale(0.96) translateZ(0.1px);\r\n }\r\n\r\n .page-sheet:nth-child(4) {\r\n bottom: 20px;\r\n z-index: 3;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n -webkit-transform: scale(0.94) translateZ(0.1px);\r\n transform: scale(0.94) translateZ(0.1px);\r\n }\r\n\r\n .page-sheet:nth-child(5) {\r\n bottom: 26px;\r\n z-index: 2;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n -webkit-transform: scale(0.92) translateZ(0.1px);\r\n transform: scale(0.92) translateZ(0.1px);\r\n }\r\n\r\n .page-sheet:nth-child(6) {\r\n bottom: 32px;\r\n z-index: 1;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n -webkit-transform: scale(0.9) translateZ(0.1px);\r\n transform: scale(0.9) translateZ(0.1px);\r\n }\r\n\r\n .folder-front {\r\n position: absolute;\r\n bottom: 0;\r\n left: 0;\r\n right: 0;\r\n height: 116px;\r\n border-radius: 12px;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 8px;\r\n z-index: 2;\r\n transform-origin: bottom center;\r\n -webkit-transform-origin: bottom center;\r\n transform-style: preserve-3d;\r\n -webkit-transform-style: preserve-3d;\r\n transition:\r\n transform 0.4s ease-in-out,\r\n -webkit-transform 0.4s ease-in-out;\r\n -webkit-transition: -webkit-transform 0.4s ease-in-out;\r\n will-change: transform;\r\n backface-visibility: hidden;\r\n -webkit-backface-visibility: hidden;\r\n -webkit-font-smoothing: antialiased;\r\n /* Safari optimization: Use more specific transform to avoid render glitches */\r\n -webkit-transform: rotateX(-20deg) translateZ(0.1px);\r\n transform: rotateX(-20deg) translateZ(0.1px);\r\n /* Safari optimization: Force layer creation for smoother animations */\r\n -webkit-transform: translate3d(0, 0, 0) rotateX(-20deg);\r\n transform: translate3d(0, 0, 0) rotateX(-20deg);\r\n box-shadow:\r\n inset 0 64px 48px rgba(255, 255, 255, 0.2),\r\n inset 0 2px 4px rgba(255, 255, 255, 0.3),\r\n inset 0 1px 1px rgba(255, 255, 255, 0.3);\r\n }\r\n\r\n .item-count {\r\n display: flex;\r\n align-items: center;\r\n gap: 4px;\r\n }\r\n\r\n .item-count-label {\r\n letter-spacing: 0.5px;\r\n }\r\n\r\n .folder-icon {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n }\r\n\r\n .folder-label-container {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n gap: 4px;\r\n width: 100%;\r\n min-width: 0;\r\n }\r\n\r\n .folder-label {\r\n text-align: center;\r\n width: 100%;\r\n min-width: 0;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n white-space: nowrap;\r\n }\r\n\r\n .loading-indicator,\r\n .error-indicator {\r\n font-size: var(--font-size-xs);\r\n }\r\n `,\r\n ],\r\n template: `\r\n <div class=\"folder-container\" [class.open]=\"isOpen()\">\r\n <!-- Folder Tab SVG -->\r\n <svg class=\"folder-tab\" width=\"101\" height=\"24\" viewBox=\"0 0 101 24\" fill=\"none\" xmlns=\"http://www.w3.org/2000/svg\">\r\n <path\r\n d=\"M100.037 23.9999L100.5 24L0 24.0001V10.7646C0 4.80853 4.91797 -0.0234985 11 -0.0196688L66.4213 -0.0322266C69.3519 -0.0115886 72.197 1.20548 74.2473 3.29947L90.6765 20.0951C93.1218 22.5925 96.5417 23.9999 100.037 23.9999Z\"\r\n [attr.fill]=\"customColor || getColorVar('strong')\"\r\n />\r\n </svg>\r\n\r\n <!-- Folder Back -->\r\n <div class=\"folder-back\" [style.background-color]=\"customColor || getColorVar('strong')\">\r\n <!-- Page Sheets -->\r\n @for (sheet of getPageSheets(); track $index) {\r\n <div class=\"page-sheet\"></div>\r\n }\r\n\r\n <!-- Folder Front -->\r\n <div class=\"folder-front\" [style.--border-color]=\"customColor || getColorVar('strong')\" [style.background-color]=\"customColor || getColorVar('base')\">\r\n <!-- Icon (Centered) -->\r\n <div class=\"folder-icon\">\r\n <ds-icon [name]=\"iconName\" [size]=\"'32px'\" [style.color]=\"'white'\" />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n\r\n <!-- Label and Item Count -->\r\n <div class=\"folder-label-container\">\r\n <div class=\"folder-label ui-sm-semiBold\">{{ label }}</div>\r\n <div class=\"item-count ui-sm-regular\" [style.color]=\"'var(--color-text-secondary, #6b7280)'\">\r\n @if (loading) {\r\n <span class=\"loading-indicator\">Loading...</span>\r\n } @else if (error) {\r\n <span class=\"error-indicator\" [style.color]=\"'var(--color-destructive-base)'\">Error</span>\r\n } @else {\r\n <span>{{ itemCount }}</span>\r\n <span class=\"item-count-label\">emner</span>\r\n }\r\n </div>\r\n </div>\r\n `,\r\n})\r\nexport class DsMobileHandbookFolderComponent {\r\n /**\r\n * Color variant for the folder\r\n * Available variants: success, warning, destructive, blue, light-purple, pink, salmon-orange, orange, lime-green, grey\r\n * Example: 'pink', 'success', 'blue'\r\n */\r\n @Input() variant: string = 'light-purple';\r\n\r\n /**\r\n * Optional custom hex color for the folder.\r\n * If provided, overrides the variant color completely.\r\n */\r\n @Input() customColor?: string;\r\n\r\n /**\r\n * Icon name from the design system icon library\r\n * Example: 'remixLightbulbLine', 'remixFolder3Line'\r\n */\r\n @Input() iconName: string = 'remixFolder3Line';\r\n\r\n /**\r\n * Number of items in the folder\r\n * This should match the length of the items array when data is loaded\r\n */\r\n @Input() itemCount: number = 0;\r\n\r\n /**\r\n * Label text displayed below the folder (category name)\r\n */\r\n @Input() label: string = 'Folder';\r\n\r\n /**\r\n * Optional items data for the handbook folder\r\n * Pass the HandbookItem[] array from your API response here\r\n */\r\n @Input() items?: HandbookItem[];\r\n\r\n /**\r\n * Loading state - when true, shows \"Loading...\" indicator instead of item count\r\n * Set this to true while fetching data from your API\r\n */\r\n @Input() loading: boolean = false;\r\n\r\n /**\r\n * Error state - when set, shows \"Error\" indicator instead of item count\r\n * Set this to an error message string if API call fails\r\n */\r\n @Input() error?: string;\r\n\r\n /**\r\n * Track open/closed state for animation\r\n */\r\n isOpen = signal(false);\r\n\r\n /**\r\n * Get the CSS variable name for the color variant\r\n */\r\n getColorVar(suffix: 'base' | 'strong'): string {\r\n const variantMap: Record<string, string> = {\r\n // Core design system variants\r\n success: 'success',\r\n warning: 'warning',\r\n destructive: 'destructive',\r\n blue: 'blue',\r\n 'light-purple': 'light-purple',\r\n pink: 'pink',\r\n 'salmon-orange': 'salmon-orange',\r\n orange: 'orange',\r\n 'lime-green': 'lime-green',\r\n grey: 'grey',\r\n\r\n // Extended API colors mapping to their native exact counterparts now\r\n red: 'red',\r\n green: 'green',\r\n yellow: 'yellow',\r\n purple: 'purple',\r\n indigo: 'indigo',\r\n lime: 'lime',\r\n teal: 'teal',\r\n cyan: 'cyan',\r\n brown: 'brown',\r\n 'light-blue': 'light-blue',\r\n 'light-green': 'light-green',\r\n coral: 'coral',\r\n salmon: 'salmon',\r\n seagreen: 'seagreen',\r\n };\r\n\r\n const colorName = variantMap[this.variant] || 'light-purple';\r\n return `var(--color-${colorName}-${suffix})`;\r\n }\r\n\r\n /**\r\n * Open folder animation\r\n */\r\n @HostListener('mouseenter')\r\n open(): void {\r\n this.isOpen.set(true);\r\n }\r\n\r\n /**\r\n * Close folder animation\r\n */\r\n @HostListener('mouseleave')\r\n close(): void {\r\n this.isOpen.set(false);\r\n }\r\n\r\n /**\r\n * Handle touch start - open animation\r\n */\r\n @HostListener('touchstart', ['$event'])\r\n onTouchStart(event: TouchEvent): void {\r\n this.isOpen.set(true);\r\n }\r\n\r\n /**\r\n * Handle touch end - close animation\r\n */\r\n @HostListener('touchend')\r\n onTouchEnd(): void {\r\n this.isOpen.set(false);\r\n }\r\n\r\n /**\r\n * Handle touch cancel - close animation\r\n */\r\n @HostListener('touchcancel')\r\n onTouchCancel(): void {\r\n this.isOpen.set(false);\r\n }\r\n\r\n /**\r\n * Handle click - open modal\r\n * Only opens modal if not in loading or error state\r\n */\r\n @HostListener('click')\r\n async onClick(): Promise<void> {\r\n // Don't open modal if loading or in error state\r\n if (this.loading || this.error) {\r\n return;\r\n }\r\n\r\n const handbookData: HandbookDetailData = {\r\n title: this.label,\r\n variant: this.variant,\r\n customColor: this.customColor,\r\n iconName: this.iconName,\r\n itemCount: this.itemCount,\r\n items: this.items,\r\n };\r\n\r\n await this.handbookModal.open(handbookData, {\r\n loading: this.loading,\r\n error: this.error,\r\n });\r\n }\r\n\r\n /**\r\n * Calculate the number of page sheets to display\r\n * Max 6 sheets regardless of item count\r\n */\r\n getPageSheets(): number[] {\r\n const count = Math.min(this.itemCount, 6);\r\n return Array(count).fill(0);\r\n }\r\n\r\n constructor(private handbookModal: DsMobileHandbookDetailModalService) {}\r\n}\r\n","import { Component, input, output, signal, computed, forwardRef } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR, FormsModule } from '@angular/forms';\r\n\r\n/**\r\n * DsTextInputComponent\r\n * \r\n * Mobile-first text input field component following the design system.\r\n * Supports email, phone, text, and other input types.\r\n * \r\n * Features:\r\n * - All design system states (default, hover, focus, error, disabled)\r\n * - Validation error state with destructive border color\r\n * - Automatic error clearing when input becomes valid (configurable)\r\n * - Built-in validation based on input type or custom validator function\r\n * - Accessible with proper ARIA attributes\r\n * - ControlValueAccessor for Angular forms integration\r\n * \r\n * @example\r\n * ```html\r\n * <!-- Basic usage -->\r\n * <ds-text-input\r\n * type=\"email\"\r\n * placeholder=\"Enter your email\"\r\n * [(ngModel)]=\"email\">\r\n * </ds-text-input>\r\n * \r\n * <!-- With validation error and auto-clear -->\r\n * <ds-text-input\r\n * type=\"email\"\r\n * placeholder=\"Enter your email\"\r\n * [hasError]=\"emailInvalid\"\r\n * errorMessage=\"Please enter a valid email\"\r\n * [autoClearError]=\"true\"\r\n * (errorCleared)=\"emailInvalid = false\"\r\n * [(ngModel)]=\"email\">\r\n * </ds-text-input>\r\n * \r\n * <!-- With custom validator -->\r\n * <ds-text-input\r\n * type=\"text\"\r\n * placeholder=\"Enter phone number\"\r\n * [validator]=\"phoneValidator\"\r\n * [hasError]=\"phoneInvalid\"\r\n * (errorCleared)=\"phoneInvalid = false\"\r\n * [(ngModel)]=\"phone\">\r\n * </ds-text-input>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-text-input',\r\n standalone: true,\r\n imports: [CommonModule, FormsModule],\r\n providers: [\r\n {\r\n provide: NG_VALUE_ACCESSOR,\r\n useExisting: forwardRef(() => DsTextInputComponent),\r\n multi: true\r\n }\r\n ],\r\n styles: [`\r\n :host {\r\n display: block;\r\n width: 100%;\r\n }\r\n\r\n .text-input-wrapper {\r\n position: relative;\r\n width: 100%;\r\n }\r\n\r\n .text-input {\r\n width: 100%;\r\n height: 48px;\r\n padding: 0 16px;\r\n box-sizing: border-box;\r\n \r\n /* Typography */\r\n font-family: 'Brockmann', system-ui, -apple-system, sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 400;\r\n line-height: 1.4;\r\n color: var(--text-color-default-primary);\r\n \r\n /* Background & Border */\r\n background-color: var(--color-background-neutral-primary);\r\n border: 1px solid var(--border-color-default);\r\n border-radius: 8px;\r\n \r\n /* Transitions */\r\n transition: \r\n border-color var(--transition-duration-fast) var(--ease-smooth),\r\n background-color var(--transition-duration-fast) var(--ease-smooth),\r\n box-shadow var(--transition-duration-fast) var(--ease-smooth);\r\n \r\n /* Remove default browser styles */\r\n outline: none;\r\n -webkit-appearance: none;\r\n appearance: none;\r\n }\r\n\r\n /* Placeholder styling */\r\n .text-input::placeholder {\r\n color: var(--text-color-default-tertiary);\r\n }\r\n\r\n /* Default state - no additional styles needed */\r\n\r\n /* Hover state */\r\n .text-input:hover:not(:disabled):not(:focus) {\r\n border-color: var(--border-color-default);\r\n background-color: var(--color-background-neutral-primary-hover);\r\n }\r\n\r\n /* Focus state */\r\n .text-input:focus {\r\n border-color: var(--color-accent);\r\n background-color: var(--color-background-neutral-primary);\r\n box-shadow: 0 0 0 3px var(--outline-color-default);\r\n }\r\n\r\n /* Error state */\r\n .text-input.error {\r\n border-color: var(--color-destructive-base);\r\n }\r\n\r\n .text-input.error:focus {\r\n border-color: var(--color-destructive-base);\r\n box-shadow: 0 0 0 3px rgba(220, 38, 38, 0.1);\r\n }\r\n\r\n /* Disabled state */\r\n .text-input:disabled {\r\n background-color: var(--color-background-neutral-disabled);\r\n border-color: var(--border-color-default);\r\n color: var(--text-color-default-disabled);\r\n cursor: not-allowed;\r\n }\r\n\r\n .text-input:disabled::placeholder {\r\n color: var(--text-color-default-disabled);\r\n }\r\n\r\n /* Error message */\r\n .error-message {\r\n margin-top: 8px;\r\n font-family: 'Brockmann', system-ui, -apple-system, sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 400;\r\n line-height: 1.4;\r\n color: var(--color-destructive-base);\r\n }\r\n `],\r\n template: `\r\n <div class=\"text-input-wrapper\">\r\n <input\r\n [type]=\"type()\"\r\n [placeholder]=\"placeholder()\"\r\n [value]=\"value()\"\r\n [disabled]=\"disabled()\"\r\n [readonly]=\"readonly()\"\r\n [required]=\"required()\"\r\n [autocomplete]=\"autocomplete() || null\"\r\n [attr.inputmode]=\"inputmode() || null\"\r\n [class.error]=\"hasError()\"\r\n [attr.aria-invalid]=\"hasError()\"\r\n [attr.aria-describedby]=\"hasError() && errorMessage() ? 'error-' + inputId : null\"\r\n class=\"text-input\"\r\n (input)=\"onInput($event)\"\r\n (blur)=\"onBlur()\"\r\n (focus)=\"onFocus()\"\r\n [id]=\"inputId\">\r\n \r\n @if (hasError() && errorMessage()) {\r\n <div \r\n class=\"error-message\"\r\n [id]=\"'error-' + inputId\"\r\n role=\"alert\">\r\n {{ errorMessage() }}\r\n </div>\r\n }\r\n </div>\r\n `\r\n})\r\nexport class DsTextInputComponent implements ControlValueAccessor {\r\n // Input properties\r\n type = input<'text' | 'email' | 'tel' | 'password' | 'url' | 'search'>('text');\r\n placeholder = input<string>('');\r\n disabled = input<boolean>(false);\r\n readonly = input<boolean>(false);\r\n required = input<boolean>(false);\r\n hasError = input<boolean>(false);\r\n errorMessage = input<string>('');\r\n autocomplete = input<string>('');\r\n inputmode = input<'text' | 'email' | 'tel' | 'numeric' | 'url' | 'search' | undefined>(undefined);\r\n autoClearError = input<boolean>(true);\r\n validator = input<((value: string) => boolean) | null>(null);\r\n\r\n // Output events\r\n valueChange = output<string>();\r\n blur = output<FocusEvent>();\r\n focus = output<FocusEvent>();\r\n errorCleared = output<void>();\r\n\r\n // Internal state\r\n private _value = signal<string>('');\r\n value = computed(() => this._value());\r\n \r\n // Generate unique ID for accessibility\r\n inputId = `ds-text-input-${Math.random().toString(36).substring(2, 9)}`;\r\n\r\n // ControlValueAccessor implementation\r\n private onChange = (value: string) => {};\r\n private onTouched = () => {};\r\n\r\n onInput(event: Event): void {\r\n const target = event.target as HTMLInputElement;\r\n const newValue = target.value;\r\n this._value.set(newValue);\r\n this.onChange(newValue);\r\n this.valueChange.emit(newValue);\r\n \r\n // Auto-clear error if input becomes valid\r\n if (this.autoClearError() && this.hasError()) {\r\n const isValid = this.validateInput(newValue);\r\n if (isValid) {\r\n this.errorCleared.emit();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Validates the input value based on type or custom validator\r\n */\r\n private validateInput(value: string): boolean {\r\n // Use custom validator if provided\r\n const customValidator = this.validator();\r\n if (customValidator) {\r\n return customValidator(value);\r\n }\r\n\r\n // Use built-in validation based on input type\r\n const inputType = this.type();\r\n const inputElement = document.createElement('input');\r\n inputElement.type = inputType;\r\n inputElement.value = value;\r\n \r\n // For email type, use HTML5 validation\r\n if (inputType === 'email') {\r\n return inputElement.validity.valid;\r\n }\r\n \r\n // For required fields, check if value exists\r\n if (this.required() && !value.trim()) {\r\n return false;\r\n }\r\n \r\n // Default: valid if HTML5 validation passes\r\n return inputElement.validity.valid;\r\n }\r\n\r\n onBlur(): void {\r\n this.onTouched();\r\n }\r\n\r\n onFocus(): void {\r\n // Focus event can be emitted if needed\r\n }\r\n\r\n // ControlValueAccessor methods\r\n writeValue(value: string): void {\r\n this._value.set(value || '');\r\n }\r\n\r\n registerOnChange(fn: (value: string) => void): void {\r\n this.onChange = fn;\r\n }\r\n\r\n registerOnTouched(fn: () => void): void {\r\n this.onTouched = fn;\r\n }\r\n\r\n setDisabledState(isDisabled: boolean): void {\r\n // Angular forms will handle this via the disabled input\r\n }\r\n}\r\n\r\n","import { Component, input, output, ElementRef, OnInit, OnDestroy, AfterViewInit, inject } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { Platform } from '@ionic/angular/standalone';\r\n\r\n/**\r\n * DsMobileFabComponent\r\n * \r\n * Floating Action Button component for mobile interfaces.\r\n * A prominent circular button that floats above the content.\r\n * \r\n * Features:\r\n * - Configurable positioning (bottom-right, bottom-left, bottom-center)\r\n * - Uses design system theming variables\r\n * - Dynamically calculates position above tab bar (including safe areas)\r\n * - Maintains consistent 20px gap from tab bar\r\n * - Handles iOS safe areas\r\n * - Accessible with ARIA labels\r\n * - Smooth entrance animation\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-fab\r\n * icon=\"remixAddLine\"\r\n * [position]=\"'bottom-right'\"\r\n * (fabClick)=\"handleAddClick()\"\r\n * ariaLabel=\"Add new inquiry\">\r\n * </ds-mobile-fab>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-fab',\r\n standalone: true,\r\n imports: [CommonModule, DsIconButtonComponent],\r\n host: {\r\n '[class.fab-bottom-right]': 'position() === \"bottom-right\"',\r\n '[class.fab-bottom-left]': 'position() === \"bottom-left\"',\r\n '[class.fab-bottom-center]': 'position() === \"bottom-center\"'\r\n },\r\n template: `\r\n <div class=\"fab-container\">\r\n <ds-icon-button\r\n [icon]=\"icon()\"\r\n variant=\"primary\"\r\n [size]=\"size()\"\r\n [ariaLabel]=\"ariaLabel()\"\r\n [disabled]=\"disabled()\"\r\n (clicked)=\"handleClick()\"\r\n class=\"fab-button\">\r\n </ds-icon-button>\r\n </div>\r\n `,\r\n styles: [`\r\n :host {\r\n display: block;\r\n position: fixed;\r\n z-index: 1000;\r\n pointer-events: none;\r\n }\r\n\r\n .fab-container {\r\n position: relative;\r\n pointer-events: none;\r\n animation: fabEnter 0.3s cubic-bezier(0.4, 0, 0.2, 1) forwards;\r\n }\r\n\r\n @keyframes fabEnter {\r\n from {\r\n opacity: 0;\r\n transform: scale(0.8);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: scale(1);\r\n }\r\n }\r\n\r\n /* Position variants - now applied to :host */\r\n \r\n /* MOBILE: Use dynamically calculated position based on actual tab bar height */\r\n /* The JavaScript calculates the actual tab bar height (including padding) and sets --fab-calculated-bottom */\r\n /* Fallback to 84px (64px base + 20px gap) if calculation hasn't run yet */\r\n :host(.fab-bottom-right) {\r\n bottom: var(--fab-calculated-bottom, 84px);\r\n right: 20px;\r\n }\r\n\r\n :host(.fab-bottom-left) {\r\n bottom: var(--fab-calculated-bottom, 84px);\r\n left: 20px;\r\n }\r\n\r\n :host(.fab-bottom-center) {\r\n bottom: var(--fab-calculated-bottom, 84px);\r\n left: 50%;\r\n transform: translateX(-50%);\r\n }\r\n\r\n /* Horizontal safe area support (all platforms) */\r\n @supports (padding-right: env(safe-area-inset-right)) {\r\n :host(.fab-bottom-right) {\r\n right: calc(20px + env(safe-area-inset-right));\r\n }\r\n }\r\n\r\n @supports (padding-left: env(safe-area-inset-left)) {\r\n :host(.fab-bottom-left) {\r\n left: calc(20px + env(safe-area-inset-left));\r\n }\r\n }\r\n\r\n /* DESKTOP: Larger spacing for desktop screens */\r\n @media (min-width: 768px) {\r\n :host-context(.plt-desktop).fab-bottom-right {\r\n bottom: 40px;\r\n right: 40px;\r\n }\r\n\r\n :host-context(.plt-desktop).fab-bottom-left {\r\n bottom: 40px;\r\n left: 40px;\r\n }\r\n\r\n :host-context(.plt-desktop).fab-bottom-center {\r\n bottom: 40px;\r\n }\r\n \r\n @supports (padding-right: env(safe-area-inset-right)) {\r\n :host-context(.plt-desktop).fab-bottom-right {\r\n right: calc(40px + env(safe-area-inset-right));\r\n }\r\n }\r\n\r\n @supports (padding-left: env(safe-area-inset-left)) {\r\n :host-context(.plt-desktop).fab-bottom-left {\r\n left: calc(40px + env(safe-area-inset-left));\r\n }\r\n }\r\n }\r\n\r\n /* FAB Button Styling */\r\n .fab-button {\r\n pointer-events: auto;\r\n display: block;\r\n }\r\n\r\n /* Override icon button to be circular and use brand colors */\r\n .fab-button::ng-deep button {\r\n width: 56px !important;\r\n height: 56px !important;\r\n min-width: 56px !important;\r\n min-height: 56px !important;\r\n border-radius: 50% !important;\r\n padding: 0 !important;\r\n display: flex !important;\r\n align-items: center !important;\r\n justify-content: center !important;\r\n \r\n /* Use whitelabel theming variables */\r\n background: var(--color-accent) !important;\r\n color: var(--color-on-accent) !important;\r\n border: none !important;\r\n \r\n /* Elevation shadow for prominence */\r\n box-shadow: \r\n 0 3px 5px -1px rgba(0, 0, 0, 0.2),\r\n 0 6px 10px 0 rgba(0, 0, 0, 0.14),\r\n 0 1px 18px 0 rgba(0, 0, 0, 0.12);\r\n \r\n transition: all 0.2s cubic-bezier(0.4, 0, 0.2, 1);\r\n }\r\n\r\n /* Hover state */\r\n .fab-button::ng-deep button:hover:not(:disabled) {\r\n background: var(--color-accent-hover) !important;\r\n box-shadow: \r\n 0 5px 7px -2px rgba(0, 0, 0, 0.2),\r\n 0 8px 14px 0 rgba(0, 0, 0, 0.14),\r\n 0 2px 22px 0 rgba(0, 0, 0, 0.12);\r\n transform: scale(1.05);\r\n }\r\n\r\n /* Active state */\r\n .fab-button::ng-deep button:active:not(:disabled) {\r\n background: var(--color-accent-active) !important;\r\n box-shadow: \r\n 0 2px 4px -1px rgba(0, 0, 0, 0.2),\r\n 0 4px 8px 0 rgba(0, 0, 0, 0.14),\r\n 0 1px 14px 0 rgba(0, 0, 0, 0.12);\r\n transform: scale(0.95);\r\n }\r\n\r\n /* Disabled state */\r\n .fab-button::ng-deep button:disabled {\r\n opacity: 0.5;\r\n cursor: not-allowed;\r\n box-shadow: \r\n 0 2px 4px -1px rgba(0, 0, 0, 0.1),\r\n 0 4px 8px 0 rgba(0, 0, 0, 0.08),\r\n 0 1px 14px 0 rgba(0, 0, 0, 0.06);\r\n }\r\n\r\n /* Icon styling */\r\n .fab-button::ng-deep button .btn__icon,\r\n .fab-button::ng-deep button .btn__icon svg {\r\n color: var(--color-on-accent) !important;\r\n fill: var(--color-on-accent) !important;\r\n }\r\n\r\n /* Ensure icon is centered and sized properly */\r\n .fab-button::ng-deep button .btn__icon {\r\n display: flex !important;\r\n align-items: center !important;\r\n justify-content: center !important;\r\n flex-shrink: 0 !important;\r\n }\r\n\r\n .fab-button::ng-deep button .btn__icon svg {\r\n width: 24px !important;\r\n height: 24px !important;\r\n }\r\n `]\r\n})\r\nexport class DsMobileFabComponent implements AfterViewInit, OnDestroy {\r\n private elementRef = inject(ElementRef);\r\n private platform = inject(Platform);\r\n private resizeObserver?: ResizeObserver;\r\n \r\n /**\r\n * Icon name from the design system icon library\r\n * @default 'remixAddLine'\r\n */\r\n icon = input<string>('remixAddLine');\r\n\r\n /**\r\n * Position of the FAB on the screen\r\n * @default 'bottom-right'\r\n */\r\n position = input<'bottom-right' | 'bottom-left' | 'bottom-center'>('bottom-right');\r\n\r\n /**\r\n * Size of the FAB button\r\n * Note: FAB is always 56px circular, but this affects the icon size\r\n * @default 'md'\r\n */\r\n size = input<'sm' | 'md' | 'lg'>('md');\r\n\r\n /**\r\n * ARIA label for accessibility\r\n * @required - Always provide a descriptive label\r\n */\r\n ariaLabel = input.required<string>();\r\n\r\n /**\r\n * Whether the FAB is disabled\r\n * @default false\r\n */\r\n disabled = input<boolean>(false);\r\n\r\n /**\r\n * Emitted when the FAB is clicked\r\n */\r\n clicked = output<void>();\r\n\r\n ngAfterViewInit(): void {\r\n // Only calculate position on mobile (not desktop)\r\n if (!this.platform.is('desktop')) {\r\n this.calculatePosition();\r\n this.setupResizeObserver();\r\n }\r\n }\r\n\r\n /**\r\n * Calculate the FAB position dynamically based on actual tab bar height\r\n */\r\n private calculatePosition(): void {\r\n const tabBar = document.querySelector('ion-tab-bar[slot=\"bottom\"]');\r\n if (tabBar) {\r\n const rect = tabBar.getBoundingClientRect();\r\n const actualHeight = rect.height;\r\n const gap = 20;\r\n const bottom = actualHeight + gap;\r\n \r\n const host = this.elementRef.nativeElement as HTMLElement;\r\n host.style.setProperty('--fab-calculated-bottom', `${bottom}px`);\r\n }\r\n }\r\n\r\n /**\r\n * Setup ResizeObserver to recalculate position when tab bar size changes\r\n * (e.g., when device rotates or safe area changes)\r\n */\r\n private setupResizeObserver(): void {\r\n const tabBar = document.querySelector('ion-tab-bar[slot=\"bottom\"]');\r\n if (tabBar && 'ResizeObserver' in window) {\r\n this.resizeObserver = new ResizeObserver(() => {\r\n this.calculatePosition();\r\n });\r\n this.resizeObserver.observe(tabBar);\r\n }\r\n }\r\n\r\n /**\r\n * Handle button click\r\n */\r\n handleClick(): void {\r\n if (!this.disabled()) {\r\n this.clicked.emit();\r\n }\r\n }\r\n\r\n ngOnDestroy(): void {\r\n this.resizeObserver?.disconnect();\r\n }\r\n}\r\n","import { Component, input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconComponent } from '@propbinder/design-system';\r\n\r\n/**\r\n * DsMobileOfflineBannerComponent\r\n *\r\n * A compact banner component to indicate offline status.\r\n * Designed to be used in the [offline-indicator] slot of page components.\r\n *\r\n * Features:\r\n * - Amber/yellow warning styling\r\n * - WiFi off icon\r\n * - Customizable message\r\n * - Compact, non-intrusive design\r\n * - Smooth slide-in animation\r\n *\r\n * @example\r\n * ```html\r\n * <ds-mobile-page-main title=\"Community\">\r\n * <ds-mobile-offline-banner \r\n * offline-indicator\r\n * *ngIf=\"pageComponent.isOffline()\">\r\n * </ds-mobile-offline-banner>\r\n * \r\n * <!-- Page content -->\r\n * </ds-mobile-page-main>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-offline-banner',\r\n standalone: true,\r\n imports: [CommonModule, DsIconComponent],\r\n styles: [`\r\n :host {\r\n display: block;\r\n animation: slideDown 0.3s ease-out;\r\n }\r\n\r\n @keyframes slideDown {\r\n from {\r\n opacity: 0;\r\n transform: translateY(-10px);\r\n }\r\n to {\r\n opacity: 1;\r\n transform: translateY(0);\r\n }\r\n }\r\n\r\n .offline-banner {\r\n background: var(--color-warning-surface, #FEF3C7);\r\n border-bottom: 1px solid var(--color-warning-border, #F59E0B);\r\n padding: 12px 20px;\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n position: relative;\r\n z-index: 10;\r\n }\r\n\r\n .offline-banner__icon {\r\n flex-shrink: 0;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n color: var(--color-warning-content, #92400E);\r\n }\r\n\r\n .offline-banner__content {\r\n flex: 1;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 2px;\r\n }\r\n\r\n .offline-banner__title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm, 14px);\r\n font-weight: 600;\r\n line-height: 1.3;\r\n color: var(--color-warning-content, #92400E);\r\n margin: 0;\r\n }\r\n\r\n .offline-banner__message {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-xs, 12px);\r\n font-weight: 400;\r\n line-height: 1.4;\r\n color: var(--color-warning-content-secondary, #B45309);\r\n margin: 0;\r\n }\r\n\r\n /* Desktop - center with max-width */\r\n @media (min-width: 768px) {\r\n .offline-banner {\r\n padding: 12px 40px;\r\n }\r\n }\r\n `],\r\n template: `\r\n <div class=\"offline-banner\">\r\n <div class=\"offline-banner__icon\">\r\n <ds-icon \r\n [name]=\"icon()\" \r\n size=\"20px\" \r\n color=\"var(--color-warning-content, #92400E)\">\r\n </ds-icon>\r\n </div>\r\n <div class=\"offline-banner__content\">\r\n <p class=\"offline-banner__title\">{{ title() }}</p>\r\n @if (message()) {\r\n <p class=\"offline-banner__message\">{{ message() }}</p>\r\n }\r\n </div>\r\n </div>\r\n `\r\n})\r\nexport class DsMobileOfflineBannerComponent {\r\n /**\r\n * Icon to display (default: WiFi off icon)\r\n */\r\n icon = input<string>('remixWifiOffLine');\r\n\r\n /**\r\n * Title text for the banner\r\n */\r\n title = input<string>('No internet connection');\r\n\r\n /**\r\n * Optional secondary message\r\n */\r\n message = input<string>('Some features may be unavailable');\r\n}\r\n","import { Component, input } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\n\r\n/**\r\n * DsMobilePropertyBannerComponent\r\n * \r\n * Compact banner displaying property photo and address.\r\n * Designed for use in page headers to show current property context.\r\n * \r\n * @example\r\n * ```html\r\n * <ds-mobile-property-banner\r\n * address=\"Toftegårds Allé 5A, 2. tv.\"\r\n * photoUrl=\"/Assets/building.jpg\">\r\n * </ds-mobile-property-banner>\r\n * ```\r\n */\r\n@Component({\r\n selector: 'ds-mobile-property-banner',\r\n standalone: true,\r\n imports: [CommonModule],\r\n styles: [`\r\n :host {\r\n display: block;\r\n width: 100%;\r\n }\r\n \r\n .property-banner {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n height: 40px;\r\n padding: 0 8px;\r\n background: rgba(var(--header-content-color-rgb, 255, 255, 255), 0.1);\r\n border: none;\r\n backdrop-filter: blur(10px);\r\n border-radius: 12px;\r\n cursor: pointer;\r\n transition: background 0.2s ease;\r\n -webkit-tap-highlight-color: transparent;\r\n }\r\n \r\n .property-banner:hover {\r\n background: rgba(var(--header-content-color-rgb, 255, 255, 255), 0.12);\r\n }\r\n \r\n .property-banner:active {\r\n background: rgba(var(--header-content-color-rgb, 255, 255, 255), 0.15);\r\n }\r\n \r\n .property-photo {\r\n width: 24px;\r\n height: 24px;\r\n border-radius: 6px;\r\n object-fit: cover;\r\n flex-shrink: 0;\r\n background: rgba(var(--header-content-color-rgb, 255, 255, 255), 0.1);\r\n }\r\n \r\n .property-address {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n font-weight: 500;\r\n color: var(--header-content-color, white);\r\n line-height: 1.4;\r\n flex: 1;\r\n min-width: 0;\r\n white-space: nowrap;\r\n overflow: hidden;\r\n text-overflow: ellipsis;\r\n }\r\n `],\r\n template: `\r\n <div class=\"property-banner\">\r\n <img \r\n [src]=\"photoUrl()\" \r\n [alt]=\"address()\"\r\n class=\"property-photo\"\r\n />\r\n <span class=\"property-address\">{{ address() }}</span>\r\n </div>\r\n `\r\n})\r\nexport class DsMobilePropertyBannerComponent {\r\n /**\r\n * Property address text\r\n */\r\n address = input.required<string>();\r\n \r\n /**\r\n * URL to property photo\r\n */\r\n photoUrl = input.required<string>();\r\n}\r\n\r\n","// Mobile Page Components\r\nexport * from './page-main';\r\nexport * from './page-details';\r\n\r\n// Mobile Content Components\r\nexport * from './content';\r\nexport * from './section';\r\nexport * from './header-content';\r\nexport * from './logo';\r\nexport * from './system-message-banner';\r\nexport * from './file-attachment';\r\n\r\n// Mobile Community Components\r\nexport * from './comment';\r\nexport * from './post-composer';\r\nexport * from './message-composer';\r\nexport * from './message-bubble';\r\n\r\n// Mobile List Components\r\nexport * from './list-item';\r\nexport * from './list-item-static';\r\nexport * from './action-list-item';\r\nexport {\r\n DsMobileInteractiveListItemPostComponent,\r\n PostContentComponent,\r\n PostTextComponent,\r\n PostMediaComponent,\r\n PostAttachmentsComponent,\r\n PostActionsComponent,\r\n ActionLikeComponent,\r\n ActionCommentComponent,\r\n PostPdfAttachmentComponent,\r\n} from './interactive-list-item-post';\r\nexport { DsMobileInteractiveListItemInquiryComponent } from './interactive-list-item-inquiry';\r\nexport { DsMobileInteractiveListItemMessageComponent } from './interactive-list-item-message';\r\nexport { DsMobileContactListItemComponent } from './contact-list-item';\r\nexport * from './interactive-list-item-booking';\r\n\r\n// Mobile Layout Components\r\nexport { DsMobileTabsComponent } from './tabs';\r\nexport { DsMobileTabBarComponent, type TabConfig } from './tab-bar';\r\nexport { DsMobileInlineTabsComponent, type InlineTabItem } from './inline-tabs';\r\nexport * from './swiper';\r\n\r\n// Mobile Bottom Sheet Components\r\nexport * from './bottom-sheet';\r\n\r\n// Mobile Lightbox Components\r\nexport * from './lightbox';\r\n\r\n// Mobile Inline Photo Component\r\nexport * from './inline-photo';\r\n\r\n// Mobile Attachment Preview Component\r\nexport * from './attachment-preview';\r\n\r\n// Mobile Loader Overlay Component\r\nexport * from './loader-overlay';\r\n\r\n// Mobile Modal Service\r\nexport * from './modal';\r\n\r\n// Mobile Modal Base Component\r\nexport * from './modal-base';\r\n\r\n// Mobile Post Detail Modal\r\nexport * from './post-detail-modal';\r\n\r\n// Mobile Card Inline Component\r\nexport * from './card-inline';\r\n\r\n// Mobile Card Inline Banner Content\r\nexport * from './card-inline-banner';\r\n\r\n// Mobile Card Inline Contact\r\nexport * from './card-inline-contact';\r\n\r\n// Mobile Card Inline File\r\nexport * from './card-inline-file';\r\n\r\n// Mobile Chat Modal\r\nexport * from './chat-modal';\r\n\r\n// Mobile New Inquiry Modal\r\nexport * from './new-inquiry-modal';\r\n\r\n// Mobile Booking & Facility Modals\r\nexport * from './booking-modal';\r\nexport * from './facility-creation-modal';\r\nexport * from './facility-detail-modal';\r\n\r\n// Mobile Handbook Components\r\nexport * from './handbook-folder';\r\nexport * from './handbook-detail-modal';\r\n\r\n// Text Input Component\r\nexport * from './text-input';\r\n\r\n// FAB Component\r\nexport * from './fab';\r\n\r\n// Mobile Avatar Component\r\nexport * from './avatar-with-badge';\r\n\r\n// Mobile App Icon Component\r\nexport * from './app-icon';\r\n\r\n// Mobile Empty State Component\r\nexport * from './empty-state';\r\n\r\n// Mobile Offline Banner Component\r\nexport * from './offline-banner';\r\n\r\n// Mobile Illustration Component\r\nexport * from './illustration';\r\n\r\n// Mobile Property Banner Component\r\nexport * from './property-banner';\r\n\r\n// Mobile Dropdown Component\r\nexport * from './dropdown';\r\n\r\n// Shared directives\r\nexport * from './shared';\r\n","import { Injectable, signal, computed } from '@angular/core';\r\nimport { Post, Comment } from '../models/post.model';\r\n\r\n/**\r\n * PostsService\r\n * \r\n * Centralized service for managing community posts.\r\n * Provides a single source of truth for post data, including comments.\r\n * \r\n * Features:\r\n * - CRUD operations for posts\r\n * - Infinite scroll pagination\r\n * - Post search/filter (future)\r\n * - Comment management (future)\r\n */\r\n@Injectable({\r\n providedIn: 'root'\r\n})\r\nexport class PostsService {\r\n // Private signal for internal state management\r\n private postsState = signal<Post[]>(this.getInitialPosts());\r\n \r\n // Public computed signal (read-only)\r\n posts = computed(() => this.postsState());\r\n \r\n // Pagination state for infinite scroll\r\n private currentPage = signal(0);\r\n private hasMore = signal(true);\r\n \r\n constructor() {}\r\n \r\n /**\r\n * Get a post by ID\r\n */\r\n getPostById(id: string): Post | undefined {\r\n return this.postsState().find(post => post.id === id);\r\n }\r\n \r\n /**\r\n * Add a new post (e.g., from post creator)\r\n * Adds to the beginning of the list\r\n */\r\n addPost(post: Post): void {\r\n this.postsState.update(posts => [post, ...posts]);\r\n }\r\n \r\n /**\r\n * Update an existing post\r\n */\r\n updatePost(id: string, updates: Partial<Post>): void {\r\n this.postsState.update(posts =>\r\n posts.map(post => post.id === id ? { ...post, ...updates } : post)\r\n );\r\n }\r\n \r\n /**\r\n * Delete a post by ID\r\n */\r\n deletePost(id: string): void {\r\n this.postsState.update(posts => posts.filter(post => post.id !== id));\r\n }\r\n \r\n /**\r\n * Load more posts for infinite scroll\r\n * Returns true if more posts were loaded, false if no more posts\r\n */\r\n async loadMorePosts(): Promise<boolean> {\r\n const page = this.currentPage();\r\n const itemsPerPage = 2;\r\n const additionalPosts = this.getAdditionalPosts();\r\n const startIndex = page * itemsPerPage;\r\n const endIndex = startIndex + itemsPerPage;\r\n \r\n // Simulate API delay\r\n await new Promise(resolve => setTimeout(resolve, 1000));\r\n \r\n // Get next batch\r\n const newPosts = additionalPosts.slice(startIndex, endIndex);\r\n \r\n if (newPosts.length > 0) {\r\n // Append to existing posts\r\n this.postsState.update(posts => [...posts, ...newPosts]);\r\n this.currentPage.update(p => p + 1);\r\n \r\n // Check if there are more posts\r\n if (endIndex >= additionalPosts.length) {\r\n this.hasMore.set(false);\r\n }\r\n \r\n return true;\r\n }\r\n \r\n this.hasMore.set(false);\r\n return false;\r\n }\r\n \r\n /**\r\n * Check if there are more posts to load\r\n */\r\n hasMorePosts(): boolean {\r\n return this.hasMore();\r\n }\r\n \r\n /**\r\n * Reset pagination (e.g., on pull-to-refresh)\r\n */\r\n resetPagination(): void {\r\n this.currentPage.set(0);\r\n this.hasMore.set(true);\r\n }\r\n \r\n /**\r\n * Get initial posts (shown on page load)\r\n */\r\n private getInitialPosts(): Post[] {\r\n return [\r\n {\r\n id: 'user-post-1',\r\n authorName: 'Lars Mikkelsen',\r\n authorRole: 'Dig',\r\n timestamp: '5m siden',\r\n avatarType: 'initials',\r\n avatarInitials: 'LM',\r\n content: 'Dette er mit første opslag! Ser frem til at forbinde med alle i bygningen. 🏠',\r\n isLiked: false,\r\n likeCount: 3,\r\n commentCount: 1,\r\n comments: []\r\n },\r\n {\r\n id: 'post-1',\r\n authorName: 'Anders Jensen',\r\n authorRole: 'Lejer',\r\n timestamp: '2t siden',\r\n avatarType: 'photo',\r\n avatarSrc: 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=100&h=100&fit=crop&crop=face',\r\n content: 'Lige flyttet ind i min nye lejlighed! Udlejeren var super hjælpsom gennem hele processen. Virkelig begejstret for at være en del af dette fællesskab! 🏠',\r\n isLiked: false,\r\n likeCount: 42,\r\n commentCount: 12,\r\n comments: [\r\n {\r\n id: 'comment-1-1',\r\n authorName: 'Mette Larsen',\r\n authorRole: 'Lejer',\r\n timestamp: '1t siden',\r\n avatarInitials: 'ML',\r\n content: 'Velkommen til fællesskabet!',\r\n likeCount: 1,\r\n isLiked: false,\r\n isOwnComment: false\r\n },\r\n {\r\n id: 'comment-1-2',\r\n authorName: 'Lars Mikkelsen',\r\n authorRole: 'Dig',\r\n timestamp: 'Lige nu',\r\n avatarInitials: 'LM',\r\n content: 'Vxhknbh',\r\n likeCount: 1,\r\n isLiked: false,\r\n isOwnComment: true\r\n }\r\n ]\r\n },\r\n {\r\n id: 'post-2',\r\n authorName: 'Sophie Andersen',\r\n authorRole: 'Lejer',\r\n timestamp: '4t siden',\r\n avatarInitials: 'SA',\r\n avatarType: 'initials',\r\n content: 'Jeg har taget nogle billeder af vores smukke ejendom i løbet af det sidste par måneder. Fra altanudsigten om morgenen til den nye trappe og fællesområderne. Elsker virkelig at bo her! 🏡✨',\r\n hasInlinePhotos: true,\r\n isLiked: true,\r\n likeCount: 156,\r\n commentCount: 34,\r\n comments: [\r\n {\r\n id: 'comment-2-1',\r\n authorName: 'Anders Jensen',\r\n authorRole: 'Lejer',\r\n timestamp: '3t siden',\r\n avatarInitials: 'AJ',\r\n content: 'Wow, den udsigt er fantastisk! Hvilken etage er du på?',\r\n likeCount: 12,\r\n isLiked: false,\r\n isOwnComment: false\r\n },\r\n {\r\n id: 'comment-2-2',\r\n authorName: 'Thomas Hansen',\r\n authorRole: 'Lejer',\r\n timestamp: '3t siden',\r\n avatarInitials: 'TH',\r\n content: 'Smuk! Jeg kan også se byens silhuet fra min lejlighed 🌆',\r\n isLiked: true,\r\n likeCount: 8,\r\n isOwnComment: false\r\n },\r\n {\r\n id: 'comment-2-3',\r\n authorName: 'Lars Mikkelsen',\r\n authorRole: 'Dig',\r\n timestamp: 'Lige nu',\r\n avatarInitials: 'LM',\r\n content: 'Vxhknbh',\r\n likeCount: 1,\r\n isLiked: false,\r\n isOwnComment: true\r\n }\r\n ]\r\n },\r\n {\r\n id: 'post-3',\r\n authorName: 'Thomas Hansen',\r\n authorRole: 'Lejer',\r\n timestamp: '1d siden',\r\n avatarType: 'photo',\r\n avatarSrc: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100&h=100&fit=crop&crop=face',\r\n content: 'Kender nogen et fælles fitnesscenter i nærheden? Leder efter anbefalinger til gode træningscentre i området. 🏋️',\r\n isLiked: false,\r\n likeCount: 23,\r\n commentCount: 45,\r\n comments: []\r\n },\r\n {\r\n id: 'post-3.5',\r\n authorName: 'Karen Nielsen',\r\n authorRole: 'Ejendomsadministrator',\r\n timestamp: '2d siden',\r\n avatarInitials: 'KN',\r\n avatarType: 'initials',\r\n showBadge: true,\r\n isPinned: true,\r\n content: 'Her er et kig på vores nyligt renoverede fællesområder! Vi har opgraderet postkasserne, trappeafsatsen og gårdområdet. Der er også blevet ansat en ny vicevært. Glæd dig over forbedringerne! 🏢✨',\r\n hasInlinePhotos: true,\r\n inlinePhotoCount: 6,\r\n isLiked: false,\r\n likeCount: 234,\r\n commentCount: 89,\r\n comments: []\r\n },\r\n {\r\n id: 'post-4',\r\n authorName: 'Karen Nielsen',\r\n authorRole: 'Ejendomsadministrator',\r\n timestamp: '2d siden',\r\n avatarInitials: 'KN',\r\n avatarType: 'initials',\r\n showBadge: true,\r\n isPinned: true,\r\n content: '📢 Påmindelse: Bygningsvedligeholdelse planlagt til denne lørdag fra kl. 9 til 14. Vandet vil være midlertidigt lukket. Vær venlig at planlægge derefter!',\r\n isLiked: false,\r\n likeCount: 89,\r\n commentCount: 67,\r\n comments: []\r\n },\r\n {\r\n id: 'post-5',\r\n authorName: 'Emma Petersen',\r\n authorRole: 'Lejer',\r\n timestamp: '3d siden',\r\n avatarType: 'photo',\r\n avatarSrc: 'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=100&h=100&fit=crop&crop=face',\r\n content: 'Arrangerer en fælles BBQ næste weekend! Alle er inviteret. Tag din yndlingsret med til at dele. Lad os lære hinanden bedre at kende! 🍔🌭',\r\n isLiked: true,\r\n likeCount: 124,\r\n commentCount: 89,\r\n comments: []\r\n }\r\n ];\r\n }\r\n \r\n /**\r\n * Get additional posts for infinite scroll\r\n */\r\n private getAdditionalPosts(): Post[] {\r\n return [\r\n {\r\n id: 'post-6',\r\n authorName: 'Peter Christensen',\r\n authorRole: 'Lejer',\r\n timestamp: '4d siden',\r\n avatarType: 'photo',\r\n avatarSrc: 'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=100&h=100&fit=crop&crop=face',\r\n content: 'Nogen der ved, hvornår de nye cykelstativer bliver installeret? 🚲',\r\n isLiked: false,\r\n likeCount: 15,\r\n commentCount: 23,\r\n comments: []\r\n },\r\n {\r\n id: 'post-7',\r\n authorName: 'Maria Schmidt',\r\n authorRole: 'Lejer',\r\n timestamp: '5d siden',\r\n avatarInitials: 'MS',\r\n avatarType: 'initials',\r\n content: 'Tak til vores fantastiske vicevært for at holde bygningen så pæn og ren! 🌟',\r\n isLiked: true,\r\n likeCount: 78,\r\n commentCount: 12,\r\n comments: []\r\n },\r\n {\r\n id: 'post-8',\r\n authorName: 'Jens Nielsen',\r\n authorRole: 'Lejer',\r\n timestamp: '6d siden',\r\n avatarType: 'photo',\r\n avatarSrc: 'https://images.unsplash.com/photo-1519345182560-3f2917c472ef?w=100&h=100&fit=crop&crop=face',\r\n content: 'Jeg har fundet en nøgle i gården. Hvis den er din, så kontakt mig! 🔑',\r\n isLiked: false,\r\n likeCount: 8,\r\n commentCount: 3,\r\n comments: []\r\n },\r\n {\r\n id: 'post-9',\r\n authorName: 'Anna Larsen',\r\n authorRole: 'Lejer',\r\n timestamp: '1u siden',\r\n avatarInitials: 'AL',\r\n avatarType: 'initials',\r\n content: 'Glædelig sommer til alle! ☀️ Håber I alle får en vidunderlig ferie!',\r\n isLiked: true,\r\n likeCount: 134,\r\n commentCount: 45,\r\n comments: []\r\n },\r\n {\r\n id: 'post-10',\r\n authorName: 'Michael Andersen',\r\n authorRole: 'Lejer',\r\n timestamp: '1u siden',\r\n avatarType: 'photo',\r\n avatarSrc: 'https://images.unsplash.com/photo-1506794778202-cad84cf45f1d?w=100&h=100&fit=crop&crop=face',\r\n content: 'Er der nogen der kan anbefale en god pizzarestaurant i området? 🍕',\r\n isLiked: false,\r\n likeCount: 32,\r\n commentCount: 67,\r\n comments: []\r\n },\r\n {\r\n id: 'post-11',\r\n authorName: 'Camilla Jensen',\r\n authorRole: 'Lejer',\r\n timestamp: '2u siden',\r\n avatarInitials: 'CJ',\r\n avatarType: 'initials',\r\n content: 'Hej alle! Jeg overvejer at starte en bogklub. Er der nogen interesserede? 📚',\r\n isLiked: false,\r\n likeCount: 42,\r\n commentCount: 28,\r\n comments: []\r\n },\r\n {\r\n id: 'post-12',\r\n authorName: 'Henrik Madsen',\r\n authorRole: 'Lejer',\r\n timestamp: '2u siden',\r\n avatarType: 'photo',\r\n avatarSrc: 'https://images.unsplash.com/photo-1568602471122-7832951cc4c5?w=100&h=100&fit=crop&crop=face',\r\n content: 'Vores fælles have ser fantastisk ud i år! Stor ros til haveudvalget! 🌻🌸',\r\n isLiked: true,\r\n likeCount: 95,\r\n commentCount: 18,\r\n comments: []\r\n },\r\n {\r\n id: 'post-13',\r\n authorName: 'Louise Berg',\r\n authorRole: 'Lejer',\r\n timestamp: '3u siden',\r\n avatarInitials: 'LB',\r\n avatarType: 'initials',\r\n content: 'Påmindelse: Generalforsamling næste mandag kl. 19. Håber at se jer alle! 📋',\r\n isLiked: false,\r\n likeCount: 56,\r\n commentCount: 34,\r\n comments: []\r\n },\r\n {\r\n id: 'post-14',\r\n authorName: 'Martin Olsen',\r\n authorRole: 'Lejer',\r\n timestamp: '3u siden',\r\n avatarType: 'photo',\r\n avatarSrc: 'https://images.unsplash.com/photo-1566492031773-4f4e44671857?w=100&h=100&fit=crop&crop=face',\r\n content: 'Har nogen set min kat? Hun har været væk siden i går aftes. Hun hedder Luna og er grå. 🐱',\r\n isLiked: false,\r\n likeCount: 67,\r\n commentCount: 45,\r\n comments: []\r\n },\r\n {\r\n id: 'post-15',\r\n authorName: 'Sarah Thomsen',\r\n authorRole: 'Lejer',\r\n timestamp: '4u siden',\r\n avatarInitials: 'ST',\r\n avatarType: 'initials',\r\n content: 'Super godt initiativ med de nye genbrugsstationer! Gør det meget nemmere at sortere affald 💚♻️',\r\n isLiked: true,\r\n likeCount: 123,\r\n commentCount: 21,\r\n comments: []\r\n },\r\n {\r\n id: 'post-16',\r\n authorName: 'Nikolaj Hansen',\r\n authorRole: 'Lejer',\r\n timestamp: '5u siden',\r\n avatarType: 'photo',\r\n avatarSrc: 'https://images.unsplash.com/photo-1570295999919-56ceb5ecca61?w=100&h=100&fit=crop&crop=face',\r\n content: 'Leder efter en pålídelig babysitter i bygningen. Kender I nogen? Tak! 👶',\r\n isLiked: false,\r\n likeCount: 12,\r\n commentCount: 9,\r\n comments: []\r\n },\r\n {\r\n id: 'post-17',\r\n authorName: 'Isabella Larsen',\r\n authorRole: 'Lejer',\r\n timestamp: '6u siden',\r\n avatarInitials: 'IL',\r\n avatarType: 'initials',\r\n content: 'Vi holder en lille julemarked i gården på lørdag! Kom og køb håndlavede ting og nyd varm kakao! 🎄☕',\r\n isLiked: true,\r\n likeCount: 187,\r\n commentCount: 56,\r\n comments: []\r\n },\r\n {\r\n id: 'post-18',\r\n authorName: 'Frederik Nielsen',\r\n authorRole: 'Lejer',\r\n timestamp: '7u siden',\r\n avatarType: 'photo',\r\n avatarSrc: 'https://images.unsplash.com/photo-1599566150163-29194dcaad36?w=100&h=100&fit=crop&crop=face',\r\n content: 'Er der nogen der vil være med til at starte en løbeklub? Tænker 2-3 gange om ugen. 🏃♂️',\r\n isLiked: false,\r\n likeCount: 38,\r\n commentCount: 41,\r\n comments: []\r\n },\r\n {\r\n id: 'post-19',\r\n authorName: 'Sofie Petersen',\r\n authorRole: 'Lejer',\r\n timestamp: '1d siden',\r\n avatarInitials: 'SP',\r\n avatarType: 'initials',\r\n content: 'Fantastisk sammenkomst i går aftes! Tusind tak til alle der kom. Vi skal gøre det igen snart! 🎉',\r\n isLiked: true,\r\n likeCount: 156,\r\n commentCount: 72,\r\n comments: []\r\n },\r\n {\r\n id: 'post-20',\r\n authorName: 'Christian Møller',\r\n authorRole: 'Lejer',\r\n timestamp: '1d siden',\r\n avatarType: 'photo',\r\n avatarSrc: 'https://images.unsplash.com/photo-1552058544-f2b08422138a?w=100&h=100&fit=crop&crop=face',\r\n content: 'Nogen der har brug for hjælp med at flytte møbler? Jeg har en stor bil og kan hjælpe i weekenden! 🚐',\r\n isLiked: false,\r\n likeCount: 29,\r\n commentCount: 15,\r\n comments: []\r\n },\r\n {\r\n id: 'post-21',\r\n authorName: 'Laura Andersen',\r\n authorRole: 'Lejer',\r\n timestamp: '2d siden',\r\n avatarInitials: 'LA',\r\n avatarType: 'initials',\r\n content: 'Jeg giver klavertimer hvis nogen er interesserede! Alle niveauer velkomne 🎹🎵',\r\n isLiked: false,\r\n likeCount: 44,\r\n commentCount: 22,\r\n comments: []\r\n },\r\n {\r\n id: 'post-22',\r\n authorName: 'Rasmus Schmidt',\r\n authorRole: 'Lejer',\r\n timestamp: '2d siden',\r\n avatarType: 'photo',\r\n avatarSrc: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100&h=100&fit=crop&crop=face',\r\n content: 'Vi har fået ny belysning i trappeopgangen! Så meget lysere nu om aftenen 💡',\r\n isLiked: true,\r\n likeCount: 89,\r\n commentCount: 13,\r\n comments: []\r\n },\r\n {\r\n id: 'post-23',\r\n authorName: 'Mette Hansen',\r\n authorRole: 'Lejer',\r\n timestamp: '3d siden',\r\n avatarInitials: 'MH',\r\n avatarType: 'initials',\r\n content: 'Nogen der vil dele en Costco-medlemskab? Vi kan tage på indkøb sammen! 🛒',\r\n isLiked: false,\r\n likeCount: 18,\r\n commentCount: 31,\r\n comments: []\r\n },\r\n {\r\n id: 'post-24',\r\n authorName: 'Jonas Berg',\r\n authorRole: 'Lejer',\r\n timestamp: '3d siden',\r\n avatarType: 'photo',\r\n avatarSrc: 'https://images.unsplash.com/photo-1500648767791-00dcc994a43e?w=100&h=100&fit=crop&crop=face',\r\n content: 'Har plantet nye blomster ved indgangen. Håber I kan lide dem! 🌷🌺',\r\n isLiked: true,\r\n likeCount: 142,\r\n commentCount: 38,\r\n comments: []\r\n },\r\n {\r\n id: 'post-25',\r\n authorName: 'Caroline Jensen',\r\n authorRole: 'Lejer',\r\n timestamp: '4d siden',\r\n avatarInitials: 'CJ',\r\n avatarType: 'initials',\r\n content: 'Leder efter en tennismakker. Er der nogen der spiller? 🎾',\r\n isLiked: false,\r\n likeCount: 21,\r\n commentCount: 17,\r\n comments: []\r\n }\r\n ];\r\n }\r\n}\r\n","import { Component, computed, ViewChild } from '@angular/core';\r\nimport { Router, ActivatedRoute } from '@angular/router';\r\nimport { IonInfiniteScroll, IonInfiniteScrollContent } from '@ionic/angular/standalone';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { DsMobilePageMainComponent } from '../components/page-main';\r\nimport { DsMobileSectionComponent } from '../components/section';\r\nimport { DsMobileSwiperComponent } from '../components/swiper/ds-mobile-swiper';\r\nimport { DsMobileInteractiveListItemPostComponent } from '../components/interactive-list-item-post';\r\nimport { DsMobileCardInlineFileComponent } from '../components/card-inline-file';\r\nimport { DsMobileOfflineBannerComponent } from '../components/offline-banner';\r\nimport { \r\n PostContentComponent,\r\n PostTextComponent,\r\n PostMediaComponent,\r\n PostAttachmentsComponent,\r\n PostActionsComponent,\r\n ActionLikeComponent,\r\n ActionCommentComponent\r\n} from '../components/interactive-list-item-post';\r\nimport { DsMobilePostComposerComponent } from '../components/post-composer';\r\nimport { DsMobileBottomSheetService } from '../components/bottom-sheet/ds-mobile-bottom-sheet.service';\r\nimport { DsMobilePostCreateBottomSheetComponent } from '../components/bottom-sheet/ds-mobile-post-create-bottom-sheet';\r\nimport { DsMobilePostActionsBottomSheetComponent, PostActionResult } from '../components/bottom-sheet';\r\nimport { DsMobileLightboxService, LightboxAuthor } from '../components/lightbox';\r\nimport { DsMobilePostDetailModalService } from '../components/post-detail-modal';\r\nimport { DsMobileInlinePhotoComponent } from '../components/inline-photo';\r\nimport { UserService } from '../services/user.service';\r\nimport { PostsService } from '../services/posts.service';\r\nimport { Post } from '../models/post.model';\r\n\r\n@Component({\r\n selector: 'app-mobile-community-page',\r\n standalone: true,\r\n imports: [\r\n DsMobilePageMainComponent,\r\n DsMobileSectionComponent,\r\n DsMobileInteractiveListItemPostComponent,\r\n DsMobilePostComposerComponent,\r\n DsMobileSwiperComponent,\r\n PostContentComponent,\r\n PostTextComponent,\r\n PostMediaComponent,\r\n PostAttachmentsComponent,\r\n PostActionsComponent,\r\n ActionLikeComponent,\r\n ActionCommentComponent,\r\n DsMobileCardInlineFileComponent,\r\n DsIconButtonComponent,\r\n DsMobileInlinePhotoComponent,\r\n DsMobileOfflineBannerComponent,\r\n IonInfiniteScroll,\r\n IonInfiniteScrollContent\r\n ],\r\n styles: [`\r\n /* Pinned posts swiper wrapper */\r\n .pinned-posts-swiper-wrapper {\r\n padding: 0;\r\n position: relative;\r\n }\r\n \r\n /* Navigation buttons */\r\n .swiper-nav-buttons {\r\n display: contents;\r\n }\r\n \r\n .swiper-nav-button {\r\n position: absolute;\r\n top: 50%;\r\n transform: translateY(-50%);\r\n z-index: 10;\r\n }\r\n \r\n .swiper-nav-button:first-child {\r\n left: -48px;\r\n }\r\n \r\n .swiper-nav-button:last-child {\r\n right: -48px;\r\n }\r\n \r\n /* Force buttons to be perfectly round */\r\n ::ng-deep .swiper-nav-button button {\r\n border-radius: 50% !important;\r\n width: 48px !important;\r\n height: 48px !important;\r\n padding: 0 !important;\r\n }\r\n \r\n /* Hide on mobile */\r\n @media (max-width: 767px) {\r\n .swiper-nav-buttons {\r\n display: none;\r\n }\r\n }\r\n \r\n /* Swiper slide styling for pinned posts */\r\n ::ng-deep .pinned-posts-swiper .swiper-slide {\r\n width: 100%;\r\n max-width: 600px;\r\n height: auto;\r\n }\r\n \r\n /* Desktop: Remove max-width constraint */\r\n @media (min-width: 768px) {\r\n ::ng-deep .pinned-posts-swiper .swiper-slide {\r\n max-width: 100%;\r\n }\r\n }\r\n \r\n /* Post item inside swiper slide */\r\n .swiper-post-item {\r\n width: 100%;\r\n height: auto;\r\n }\r\n \r\n /* Ensure post content doesn't get cropped */\r\n ::ng-deep .pinned-posts-swiper .swiper-slide ds-mobile-interactive-list-item-post {\r\n height: auto;\r\n }\r\n \r\n ::ng-deep .pinned-posts-swiper .swiper-wrapper {\r\n height: auto;\r\n align-items: flex-start;\r\n }\r\n \r\n .post-list-wrapper {\r\n display: flex;\r\n flex-direction: column;\r\n }\r\n \r\n .clickable-image {\r\n cursor: pointer;\r\n transition: transform 0.2s ease, opacity 0.2s ease;\r\n border-radius: 8px;\r\n display: block;\r\n width: 100%;\r\n aspect-ratio: 16/9;\r\n object-fit: cover;\r\n }\r\n \r\n .clickable-image:active {\r\n transform: scale(0.98);\r\n opacity: 0.9;\r\n }\r\n \r\n /* Empty State */\r\n .community-empty-state {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 60px 20px;\r\n text-align: center;\r\n }\r\n \r\n .empty-state-image {\r\n width: 96px;\r\n height: 96px;\r\n margin-bottom: 24px;\r\n }\r\n \r\n .empty-state-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n color: var(--color-text-primary);\r\n margin: 16px 0 8px 0;\r\n }\r\n \r\n .empty-state-description {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n color: var(--color-text-secondary);\r\n margin: 0;\r\n }\r\n \r\n /* Infinite Scroll Spinner Styling */\r\n ion-infinite-scroll {\r\n --color: var(--color-primary-surface);\r\n }\r\n \r\n ion-infinite-scroll-content {\r\n --color: var(--color-primary-surface);\r\n }\r\n \r\n /* Target the actual spinner element */\r\n ion-infinite-scroll-content::part(spinner) {\r\n color: var(--color-primary-surface);\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-page-main\r\n #pageComponent\r\n title=\"Fællesskab\"\r\n [avatarInitials]=\"userService.avatarInitials()\"\r\n [avatarType]=\"userService.avatarType()\"\r\n (refresh)=\"handleRefresh($event)\">\r\n \r\n <!-- Offline indicator -->\r\n @if (pageComponent.isOffline()) {\r\n <ds-mobile-offline-banner \r\n offline-indicator\r\n title=\"Ingen internetforbindelse\"\r\n message=\"Nogle funktioner kan være utilgængelige\">\r\n </ds-mobile-offline-banner>\r\n }\r\n \r\n <!-- Post Composer in header-expandable -->\r\n <ds-mobile-post-composer\r\n header-content\r\n [avatarInitials]=\"userService.avatarInitials()\"\r\n [avatarType]=\"userService.avatarType()\"\r\n [avatarSrc]=\"userService.avatarSrc()\"\r\n (composerClick)=\"openPostCreator()\"\r\n />\r\n \r\n <!-- Pinned Posts Section -->\r\n <ds-mobile-section \r\n headline=\"Fastgjorte opslag\"\r\n icon=\"remixPushpinFill\">\r\n <div class=\"pinned-posts-swiper-wrapper\">\r\n <ds-mobile-swiper \r\n #pinnedSwiper\r\n class=\"pinned-posts-swiper\"\r\n [slideWidth]=\"'100%'\" \r\n [gap]=\"32\"\r\n [pagination]=\"true\"\r\n [autoHeight]=\"true\"\r\n [progressiveOpacity]=\"true\"\r\n [progressiveScale]=\"true\">\r\n @for (post of pinnedPosts(); track post.id) {\r\n <div class=\"swiper-slide\">\r\n <ds-mobile-interactive-list-item-post\r\n class=\"swiper-post-item\"\r\n [authorName]=\"post.authorName\"\r\n [authorRole]=\"post.authorRole\"\r\n [timestamp]=\"post.timestamp\"\r\n [avatarInitials]=\"post.avatarInitials || ''\"\r\n [avatarType]=\"post.avatarType\"\r\n [avatarSrc]=\"post.avatarSrc || ''\"\r\n [showBadge]=\"true\"\r\n [clickable]=\"true\"\r\n [moreActions]=\"true\"\r\n (postClick)=\"openPost(post.id)\"\r\n (commentClick)=\"openPost(post.id, true)\"\r\n (longPress)=\"handlePostLongPress(post.id, false)\">\r\n \r\n <post-content>\r\n <post-text>{{ post.content }}</post-text>\r\n \r\n @if (post.id === 'post-4') {\r\n <post-attachments>\r\n <ds-mobile-card-inline-file\r\n [fileName]=\"'Husregler.pdf'\"\r\n [fileSize]=\"'245 KB'\"\r\n [variant]=\"'pdf'\"\r\n [layout]=\"'compact'\"\r\n (fileClick)=\"openHouseRulesPdf()\">\r\n </ds-mobile-card-inline-file>\r\n </post-attachments>\r\n }\r\n </post-content>\r\n \r\n <post-actions>\r\n <action-like [count]=\"post.likeCount\" [active]=\"post.isLiked\" />\r\n <action-comment [count]=\"post.commentCount\" (commentClick)=\"openPost(post.id, true)\" />\r\n </post-actions>\r\n </ds-mobile-interactive-list-item-post>\r\n </div>\r\n }\r\n </ds-mobile-swiper>\r\n \r\n <!-- Navigation Buttons -->\r\n <div class=\"swiper-nav-buttons\">\r\n <ds-icon-button\r\n class=\"swiper-nav-button\"\r\n icon=\"remixArrowLeftSLine\"\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n [disabled]=\"isFirstSlide()\"\r\n (clicked)=\"slidePrev()\"\r\n aria-label=\"Previous post\"\r\n />\r\n <ds-icon-button\r\n class=\"swiper-nav-button\"\r\n icon=\"remixArrowRightSLine\"\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n [disabled]=\"isLastSlide()\"\r\n (clicked)=\"slideNext()\"\r\n aria-label=\"Next post\"\r\n />\r\n </div>\r\n </div>\r\n </ds-mobile-section>\r\n \r\n <!-- All Posts Section -->\r\n <ds-mobile-section\r\n headline=\"Alle opslag\">\r\n @if (hasAnyPosts()) {\r\n <div class=\"post-list-wrapper\">\r\n <!-- All Posts Loop -->\r\n @for (post of allPosts(); track post.id) {\r\n @if (post.hasInlinePhotos && post.id === 'post-2') {\r\n <!-- Post 2: With multiple images (grid layout) -->\r\n <ds-mobile-interactive-list-item-post\r\n [authorName]=\"post.authorName\"\r\n [authorRole]=\"post.authorRole\"\r\n [timestamp]=\"post.timestamp\"\r\n [avatarInitials]=\"post.avatarInitials || ''\"\r\n [avatarType]=\"post.avatarType\"\r\n [clickable]=\"true\"\r\n [moreActions]=\"true\"\r\n (postClick)=\"openPost(post.id)\"\r\n (commentClick)=\"openPost(post.id, true)\"\r\n (longPress)=\"handlePostLongPress(post.id, post.authorRole === 'Dig')\">\r\n \r\n <post-content>\r\n <post-text>{{ post.content }}</post-text>\r\n <ds-mobile-inline-photo\r\n [images]=\"[\r\n '/Assets/Dummy-photos/balcony-view.jpg',\r\n '/Assets/Dummy-photos/staircase.jpg',\r\n '/Assets/Dummy-photos/park.jpg',\r\n '/Assets/Dummy-photos/yard.jpg'\r\n ]\"\r\n [author]=\"{\r\n name: 'Sophie Andersen',\r\n role: 'Lejer',\r\n avatarInitials: 'SA',\r\n avatarType: 'initials',\r\n timestamp: '4t siden'\r\n }\"\r\n />\r\n </post-content>\r\n \r\n <post-actions>\r\n <action-like [active]=\"post.isLiked\" [count]=\"post.likeCount\" />\r\n <action-comment [count]=\"post.commentCount\" (commentClick)=\"openPost(post.id, true)\" />\r\n </post-actions>\r\n </ds-mobile-interactive-list-item-post>\r\n } @else if (post.hasInlinePhotos && post.id === 'post-3.5') {\r\n <!-- Post 3.5: Property Manager showcase with 6+ photos -->\r\n <ds-mobile-interactive-list-item-post\r\n [authorName]=\"post.authorName\"\r\n [authorRole]=\"post.authorRole\"\r\n [timestamp]=\"post.timestamp\"\r\n [avatarInitials]=\"post.avatarInitials || ''\"\r\n [avatarType]=\"post.avatarType\"\r\n [showBadge]=\"post.showBadge || false\"\r\n [clickable]=\"true\"\r\n [moreActions]=\"true\"\r\n (postClick)=\"openPost(post.id)\"\r\n (commentClick)=\"openPost(post.id, true)\"\r\n (longPress)=\"handlePostLongPress(post.id, false)\">\r\n \r\n <post-content>\r\n <post-text>{{ post.content }}</post-text>\r\n <ds-mobile-inline-photo\r\n [images]=\"[\r\n '/Assets/Dummy-photos/mailboxes.jpg',\r\n '/Assets/Dummy-photos/staircase.jpg',\r\n '/Assets/Dummy-photos/yard.jpg',\r\n '/Assets/Dummy-photos/park.jpg',\r\n '/Assets/Dummy-photos/balcony-view.jpg',\r\n '/Assets/Dummy-photos/handyman.jpg'\r\n ]\"\r\n [author]=\"{\r\n name: 'Karen Nielsen',\r\n role: 'Ejendomsadministrator',\r\n avatarInitials: 'KN',\r\n avatarType: 'initials',\r\n timestamp: '2d siden'\r\n }\"\r\n [maxVisible]=\"5\"\r\n />\r\n </post-content>\r\n \r\n <post-actions>\r\n <action-like [count]=\"post.likeCount\" />\r\n <action-comment [count]=\"post.commentCount\" (commentClick)=\"openPost(post.id, true)\" />\r\n </post-actions>\r\n </ds-mobile-interactive-list-item-post>\r\n } @else {\r\n <!-- Regular Post -->\r\n <ds-mobile-interactive-list-item-post\r\n [authorName]=\"post.authorName\"\r\n [authorRole]=\"post.authorRole\"\r\n [timestamp]=\"post.timestamp\"\r\n [avatarType]=\"post.avatarType\"\r\n [avatarSrc]=\"post.avatarSrc || ''\"\r\n [avatarInitials]=\"post.avatarInitials || ''\"\r\n [clickable]=\"true\"\r\n [moreActions]=\"true\"\r\n (postClick)=\"openPost(post.id)\"\r\n (commentClick)=\"openPost(post.id, true)\"\r\n (longPress)=\"handlePostLongPress(post.id, post.authorRole === 'Dig')\">\r\n \r\n <post-content>\r\n @if (post.content) {\r\n <post-text>{{ post.content }}</post-text>\r\n }\r\n @if (post.imageSrc) {\r\n <post-media>\r\n <img \r\n [src]=\"post.imageSrc\" \r\n [alt]=\"post.imageAlt || 'Posted image'\" \r\n class=\"clickable-image\"\r\n (click)=\"openImageLightbox(post.imageSrc, post.imageAlt || 'Posted image', post.content, $event)\"\r\n />\r\n </post-media>\r\n }\r\n </post-content>\r\n \r\n <post-actions>\r\n <action-like [count]=\"post.likeCount\" [active]=\"post.isLiked\" />\r\n <action-comment [count]=\"post.commentCount\" (commentClick)=\"openPost(post.id, true)\" />\r\n </post-actions>\r\n </ds-mobile-interactive-list-item-post>\r\n }\r\n }\r\n </div>\r\n } @else {\r\n <!-- Empty State -->\r\n <div class=\"community-empty-state\">\r\n <img \r\n src=\"/Assets/Empty%20state-chat.png\" \r\n alt=\"Ingen opslag endnu\" \r\n class=\"empty-state-image\"\r\n />\r\n <h3 class=\"empty-state-title\">Ingen opslag endnu</h3>\r\n <p class=\"empty-state-description\">Vær den første til at dele noget med dit fællesskab</p>\r\n </div>\r\n }\r\n \r\n <!-- Infinite Scroll -->\r\n @if (hasAnyPosts()) {\r\n <ion-infinite-scroll\r\n threshold=\"100px\"\r\n [disabled]=\"!hasMorePosts() || pageComponent.isOffline()\"\r\n (ionInfinite)=\"onInfiniteScroll($event)\">\r\n <ion-infinite-scroll-content\r\n loadingSpinner=\"crescent\">\r\n </ion-infinite-scroll-content>\r\n </ion-infinite-scroll>\r\n }\r\n </ds-mobile-section>\r\n </ds-mobile-page-main>\r\n `\r\n})\r\nexport class MobileCommunityPageComponent {\r\n @ViewChild('pageComponent') pageComponent!: DsMobilePageMainComponent;\r\n @ViewChild('pinnedSwiper') pinnedSwiper?: DsMobileSwiperComponent;\r\n \r\n // Get posts from service (using computed for safe initialization)\r\n allPosts = computed(() => this.postsService.posts());\r\n \r\n // Get pinned posts - filter by isPinned flag\r\n // In a real app, these would have a 'pinned' flag in the database\r\n pinnedPosts = computed(() => {\r\n // Get all posts that are explicitly marked as pinned\r\n const allPosts = this.postsService.posts();\r\n return allPosts.filter(post => post.isPinned === true);\r\n });\r\n \r\n // Computed to check if there are any posts to display\r\n hasAnyPosts = computed(() => {\r\n return this.allPosts().length > 0;\r\n });\r\n \r\n // Computed to check if there are more posts to load\r\n hasMorePosts = computed(() => {\r\n return this.postsService.hasMorePosts();\r\n });\r\n \r\n constructor(\r\n private router: Router,\r\n private route: ActivatedRoute,\r\n private bottomSheet: DsMobileBottomSheetService,\r\n private lightbox: DsMobileLightboxService,\r\n private postModal: DsMobilePostDetailModalService,\r\n public userService: UserService,\r\n private postsService: PostsService\r\n ) {}\r\n \r\n /**\r\n * Handle infinite scroll event\r\n * Loads more posts when user scrolls to bottom\r\n */\r\n async onInfiniteScroll(event: any): Promise<void> {\r\n console.log('[Community] Infinite scroll triggered');\r\n \r\n const hasMore = await this.postsService.loadMorePosts();\r\n \r\n if (hasMore) {\r\n console.log('[Community] Loaded more posts');\r\n } else {\r\n console.log('[Community] No more posts to load');\r\n }\r\n \r\n // Complete the infinite scroll\r\n event.target.complete();\r\n }\r\n \r\n handleRefresh(event: any): void {\r\n console.log('Pull-to-refresh triggered');\r\n\r\n // Check if offline and complete immediately\r\n if (this.pageComponent?.isOffline()) {\r\n console.log('Cannot refresh while offline');\r\n event.target.complete();\r\n return;\r\n }\r\n\r\n // Reset infinite scroll state\r\n this.postsService.resetPagination();\r\n\r\n setTimeout(() => {\r\n console.log('Refresh complete');\r\n event.target.complete();\r\n }, 1000);\r\n }\r\n \r\n /**\r\n * Open post detail modal\r\n * Gets post data from service and opens modal\r\n */\r\n async openPost(postId: string, focusComment: boolean = false): Promise<void> {\r\n console.log('[Community] ===== openPost called =====', postId, 'Focus comment:', focusComment);\r\n \r\n const post = this.postsService.getPostById(postId);\r\n \r\n if (post) {\r\n // Convert Post model to modal format (add postId and focusComment)\r\n // Filter out 'icon' avatarType if present, as modal only supports 'photo' | 'initials'\r\n const postData = {\r\n ...post,\r\n postId: post.id,\r\n avatarType: post.avatarType === 'icon' ? undefined : post.avatarType,\r\n focusComment\r\n };\r\n \r\n await this.postModal.open(postData, {\r\n currentUserName: 'Lars Mikkelsen', // Current user name\r\n currentUserInitials: this.userService.avatarInitials()\r\n });\r\n }\r\n }\r\n \r\n async openPostCreator(): Promise<void> {\r\n // Open the post creator as a bottom sheet modal\r\n // Using 95% initial height to maximize keyboard auto-open chances\r\n const sheet = await this.bottomSheet.create({\r\n component: DsMobilePostCreateBottomSheetComponent,\r\n componentProps: {\r\n // This helps the component know it should auto-focus\r\n autoFocus: true\r\n },\r\n breakpoints: [0, 0.95, 1],\r\n initialBreakpoint: 0.95,\r\n handle: true\r\n });\r\n \r\n // Handle the result when the sheet is dismissed\r\n const result = await sheet.onWillDismiss();\r\n if (result.role === 'post' && result.data) {\r\n console.log('New post created:', result.data);\r\n \r\n // Create a new post object\r\n const newPost: Post = {\r\n id: `user-post-${Date.now()}`, // Generate unique ID\r\n authorName: 'Lars Mikkelsen', // Current user name\r\n authorRole: 'Dig',\r\n timestamp: 'Lige nu',\r\n avatarType: this.userService.avatarType() as 'photo' | 'initials' | 'icon',\r\n avatarSrc: this.userService.avatarSrc(),\r\n avatarInitials: this.userService.avatarInitials(),\r\n content: result.data.content,\r\n imageSrc: result.data.images && result.data.images.length > 0 ? result.data.images[0] : undefined,\r\n imageAlt: result.data.images && result.data.images.length > 0 ? 'Slået billede op' : undefined,\r\n isLiked: false,\r\n likeCount: 0,\r\n commentCount: 0,\r\n comments: []\r\n };\r\n \r\n // Add to the beginning of the posts array via service\r\n this.postsService.addPost(newPost);\r\n }\r\n }\r\n \r\n /**\r\n * Open an image in the lightbox viewer\r\n * Prevents the post click event from firing\r\n */\r\n async openImageLightbox(imageSrc: string, title: string, description: string, event: Event): Promise<void> {\r\n console.log('[Community] Opening lightbox for image:', imageSrc);\r\n \r\n // Prevent the post card click event from firing\r\n event.stopPropagation();\r\n \r\n const authorMeta: LightboxAuthor = {\r\n name: 'Sophie Andersen',\r\n role: 'Lejer',\r\n avatarInitials: 'SA',\r\n timestamp: '4t siden'\r\n };\r\n \r\n // Open the lightbox with the image\r\n await this.lightbox.open({\r\n images: [\r\n {\r\n type: 'image',\r\n src: imageSrc,\r\n alt: title,\r\n title: title,\r\n description: description,\r\n isLiked: true,\r\n likeCount: 156,\r\n commentCount: 34\r\n }\r\n ],\r\n author: authorMeta,\r\n enableZoom: true,\r\n showControls: false, // Single image, no need for controls\r\n showActions: true, // Show like & comment actions\r\n showInfo: true\r\n });\r\n }\r\n\r\n async openHouseRulesPdf(): Promise<void> {\r\n console.log('[Community] Opening House Rules PDF');\r\n \r\n // Author metadata\r\n const authorMeta: LightboxAuthor = {\r\n name: 'Karen Nielsen',\r\n role: 'Ejendomsadministrator',\r\n avatarInitials: 'KN',\r\n timestamp: '2d siden'\r\n };\r\n \r\n // Open the PDF lightbox\r\n // Use absolute path for production deployment (Vercel, etc.)\r\n await this.lightbox.openPdf({\r\n pdf: {\r\n type: 'pdf',\r\n src: '/Assets/House_Rules.pdf', // Capital A to match public/Assets folder structure\r\n title: 'House Rules',\r\n description: 'Building regulations and community guidelines',\r\n fileSize: 250880, // 245 KB in bytes\r\n pageCount: 8\r\n },\r\n author: authorMeta\r\n });\r\n }\r\n \r\n /**\r\n * Handle long press on a post to show action sheet\r\n */\r\n async handlePostLongPress(postId: string, isOwnPost: boolean): Promise<void> {\r\n console.log('[Community] Post long pressed:', postId, 'isOwn:', isOwnPost);\r\n \r\n const sheet = await this.bottomSheet.create({\r\n component: DsMobilePostActionsBottomSheetComponent,\r\n componentProps: {\r\n isOwnContent: isOwnPost\r\n },\r\n breakpoints: [0, 1],\r\n initialBreakpoint: 1,\r\n handle: true,\r\n backdropDismiss: true,\r\n cssClass: 'auto-height'\r\n });\r\n \r\n const result = await sheet.onWillDismiss();\r\n \r\n if (result.role === 'select' && result.data) {\r\n const action = (result.data as PostActionResult).action;\r\n \r\n switch (action) {\r\n case 'edit':\r\n console.log('Edit post:', postId);\r\n \r\n // Get post from service\r\n const post = this.postsService.getPostById(postId);\r\n if (!post) {\r\n console.error('Post not found:', postId);\r\n return;\r\n }\r\n \r\n // Open the bottom sheet in edit mode\r\n const editSheet = await this.bottomSheet.create({\r\n component: DsMobilePostCreateBottomSheetComponent,\r\n componentProps: {\r\n autoFocus: true,\r\n isEditMode: true,\r\n postId: postId,\r\n initialContent: post.content\r\n },\r\n breakpoints: [0, 0.95, 1],\r\n initialBreakpoint: 0.95,\r\n handle: true,\r\n backdropBlur: true,\r\n backdropOpacity: 0.6\r\n });\r\n \r\n // Handle the result when the sheet is dismissed\r\n const editResult = await editSheet.onWillDismiss();\r\n if (editResult.role === 'post' && editResult.data) {\r\n console.log('Post updated:', editResult.data);\r\n \r\n // Update the post via service\r\n this.postsService.updatePost(postId, {\r\n content: editResult.data.content,\r\n timestamp: 'Lige nu'\r\n });\r\n }\r\n break;\r\n \r\n case 'delete':\r\n console.log('Delete post:', postId);\r\n if (confirm('Er du sikker på, at du vil slette dette opslag?')) {\r\n this.postsService.deletePost(postId);\r\n }\r\n break;\r\n \r\n case 'like':\r\n console.log('Like post:', postId);\r\n // Toggle like - in a real app, this would call an API\r\n const likePost = this.postsService.getPostById(postId);\r\n if (likePost) {\r\n this.postsService.updatePost(postId, {\r\n isLiked: !likePost.isLiked,\r\n likeCount: likePost.isLiked ? likePost.likeCount - 1 : likePost.likeCount + 1\r\n });\r\n }\r\n break;\r\n \r\n case 'reply':\r\n console.log('Reply to post:', postId);\r\n // Open the post detail modal with comment input focused\r\n await this.openPost(postId, true);\r\n break;\r\n }\r\n }\r\n }\r\n \r\n /**\r\n * Navigate to previous slide in pinned posts\r\n */\r\n slidePrev(): void {\r\n this.pinnedSwiper?.slidePrev();\r\n }\r\n \r\n /**\r\n * Navigate to next slide in pinned posts\r\n */\r\n slideNext(): void {\r\n this.pinnedSwiper?.slideNext();\r\n }\r\n \r\n /**\r\n * Check if currently on first slide\r\n */\r\n isFirstSlide(): boolean {\r\n return this.pinnedSwiper?.isBeginning() ?? true;\r\n }\r\n \r\n /**\r\n * Check if currently on last slide\r\n */\r\n isLastSlide(): boolean {\r\n return this.pinnedSwiper?.isEnd() ?? true;\r\n }\r\n}\r\n\r\n","import { Component, ViewChild } from '@angular/core';\r\nimport { DsMobilePageMainComponent } from '../components/page-main';\r\nimport { DsMobileSectionComponent } from '../components/section';\r\nimport { DsMobileHandbookFolderComponent } from '../components/handbook-folder';\r\nimport { DsMobileOfflineBannerComponent } from '../components/offline-banner';\r\nimport { UserService } from '../services/user.service';\r\nimport { HandbookItem } from '../components/handbook-detail-modal/ds-mobile-handbook-detail-modal';\r\n\r\n@Component({\r\n selector: 'app-mobile-handbook-page',\r\n standalone: true,\r\n imports: [DsMobilePageMainComponent, DsMobileSectionComponent, DsMobileHandbookFolderComponent, DsMobileOfflineBannerComponent],\r\n styles: [\r\n `\r\n .folders-grid {\r\n display: grid;\r\n grid-template-columns: repeat(2, 1fr);\r\n gap: 20px;\r\n justify-items: center;\r\n }\r\n\r\n /* 3 columns at tablet breakpoint (md: 768px) and above\r\n Content area at this breakpoint is ~864px max */\r\n @media (min-width: 768px) {\r\n .folders-grid {\r\n grid-template-columns: repeat(3, 1fr);\r\n }\r\n }\r\n\r\n ds-mobile-handbook-folder {\r\n width: 100%;\r\n min-width: 0;\r\n }\r\n `,\r\n ],\r\n template: `\r\n <ds-mobile-page-main #pageComponent title=\"Håndbog\" [avatarInitials]=\"userService.avatarInitials()\" [avatarType]=\"userService.avatarType()\" (refresh)=\"handleRefresh($event)\">\r\n <!-- Offline indicator -->\r\n @if (pageComponent.isOffline()) {\r\n <ds-mobile-offline-banner offline-indicator title=\"Ingen internetforbindelse\" message=\"Nogle funktioner kan være utilgængelige\"> </ds-mobile-offline-banner>\r\n }\r\n\r\n <ds-mobile-section>\r\n <div class=\"folders-grid\">\r\n <ds-mobile-handbook-folder [variant]=\"'pink'\" [iconName]=\"'remixLightbulbLine'\" [itemCount]=\"8\" [label]=\"'Forsyninger'\" [items]=\"utilitiesItems\">\r\n </ds-mobile-handbook-folder>\r\n\r\n <ds-mobile-handbook-folder [variant]=\"'success'\" [iconName]=\"'remixKey2Line'\" [itemCount]=\"4\" [label]=\"'Sikkerhedsudstyr'\" [items]=\"sikkerhedsudstyrItems\">\r\n </ds-mobile-handbook-folder>\r\n\r\n <ds-mobile-handbook-folder [variant]=\"'blue'\" [iconName]=\"'remixFileList3Line'\" [itemCount]=\"8\" [label]=\"'Servicekontrakter'\" [items]=\"serviceContractsItems\">\r\n </ds-mobile-handbook-folder>\r\n\r\n <ds-mobile-handbook-folder [variant]=\"'warning'\" [iconName]=\"'remixToolsLine'\" [itemCount]=\"5\" [label]=\"'Udstyr'\" [items]=\"equipmentItems\"> </ds-mobile-handbook-folder>\r\n </div>\r\n </ds-mobile-section>\r\n </ds-mobile-page-main>\r\n `,\r\n})\r\nexport class MobileHandbookPageComponent {\r\n @ViewChild('pageComponent') pageComponent!: DsMobilePageMainComponent;\r\n\r\n // Utilities folder data\r\n utilitiesItems: HandbookItem[] = [\r\n {\r\n title: 'El',\r\n description: '<p>Hovedeltavle placeret i <strong>kælderrum B-12</strong>. Nødafbryderknap er ved hovedindgangen. Alle kredsløb er mærket.</p><p><em>Bemærk: Der må ikke foretages ændringer på eltavlen uden tilladelse fra ejendomsadministrationen.</em></p><p>Ved <u>strømsvigt</u> kontakt venligst ElektroTek ApS på nedenstående nummer.</p>',\r\n contacts: [\r\n {\r\n name: 'ElektroTek ApS',\r\n initials: 'E',\r\n contactPerson: 'Lars Nielsen',\r\n phoneNumber: '+45 23 45 67 89',\r\n },\r\n ],\r\n },\r\n {\r\n title: 'Elektrisk diagram',\r\n description: 'Komplet diagram over bygningens elektriske installation med alle kredsløb og afbrydere.',\r\n attachments: [{ name: 'Elektrisk_Diagram.pdf', type: 'pdf' }],\r\n },\r\n {\r\n title: 'Vandforsyning',\r\n description: '<p>Hovedvandhane er placeret i kælderens <strong>tekniske rum</strong>. Individuelle lejlighedsafspærringer er i gangpanelerne.</p><p>Vandtryk overvåges <em>automatisk</em> af bygningens system.</p><p><strong><em>Vigtigt:</em></strong> Ved vandskade, luk <u>straks</u> for hovedvandhanen og kontakt VVS Hansen.</p>',\r\n contacts: [\r\n {\r\n name: 'VVS Hansen',\r\n initials: 'V',\r\n contactPerson: 'Peter Hansen',\r\n phoneNumber: '+45 34 56 78 90',\r\n },\r\n ],\r\n },\r\n {\r\n title: 'Varmesystem',\r\n description: '<p>Fjernvarmetilslutning i kælder. Termostater i hver enhed kan justeres individuelt.</p><p>Systemet vedligeholdes <strong>kvartalsvis</strong> af certificerede teknikere.</p><p><em>Tip: Sæt termostaten til 21°C for optimal komfort og energibesparelse.</em></p>',\r\n contacts: [\r\n {\r\n name: 'Varme Service A/S',\r\n initials: 'V',\r\n contactPerson: 'Maria Jensen',\r\n phoneNumber: '+45 45 67 89 01',\r\n },\r\n ],\r\n },\r\n {\r\n title: 'Varmeanlæg dokumentation',\r\n description: 'Teknisk dokumentation og vedligeholdelseshistorik for bygningens varmesystem.',\r\n attachments: [\r\n { name: 'Varmeplan.pdf', type: 'pdf' },\r\n { name: 'Vedligeholdelseslog.pdf', type: 'pdf' },\r\n ],\r\n },\r\n {\r\n title: 'Internet & TV',\r\n description: 'Fiberforbindelse i bygningen. Distributionspanel er i stueetageteknisk rum. Hver lejlighed har ethernet-stik i stue og soveværelser.',\r\n contacts: [\r\n {\r\n name: 'TeleCom Solutions',\r\n initials: 'T',\r\n contactPerson: 'Anders Petersen',\r\n phoneNumber: '+45 56 78 90 12',\r\n },\r\n ],\r\n },\r\n {\r\n title: 'Netværksopsætning guide',\r\n attachments: [{ name: 'Netværksopsætning.pdf', type: 'pdf' }],\r\n },\r\n {\r\n title: 'Affaldshåndtering',\r\n description: 'Affaldssorteringsstation placeret i gården. Afhentninger: Dagrenovation (man/tor), Genbrug (ons), Organisk (tir/fre). Storskrald kræver booking.',\r\n attachments: [{ name: 'Affaldsretningslinjer.pdf', type: 'pdf' }],\r\n },\r\n ];\r\n\r\n // Safety Equipment folder data\r\n sikkerhedsudstyrItems: HandbookItem[] = [\r\n {\r\n title: 'Fælles områder og sikkerhed',\r\n description: 'Trappeopgange med nødbelysning og brandsikre døre. Postkasser placeret i indgangspartiet. Hold altid flugtveje fri.',\r\n images: ['/Assets/Dummy-photos/staircase.jpg', '/Assets/Dummy-photos/mailboxes.jpg'],\r\n },\r\n {\r\n title: 'Hjertestarter (AED)',\r\n description: 'Automatisk hjertestarter placeret i stueetagen ved hovedindgangen. Tilgængelig 24/7. Ingen særlig uddannelse kræves - enheden guider dig gennem processen.',\r\n contacts: [\r\n {\r\n name: 'MediTech Service',\r\n initials: 'M',\r\n contactPerson: 'John Mortensen',\r\n phoneNumber: '+45 12 34 56 78',\r\n },\r\n ],\r\n attachments: [\r\n {\r\n name: 'Brandplan.pdf',\r\n type: 'pdf',\r\n url: 'https://portal-api.propbinder.com/Handbook/GetFile/50145267-d9a2-448b-a0e1-1af39d344818',\r\n },\r\n ],\r\n },\r\n {\r\n title: 'Brandslukningsudstyr',\r\n description: 'Brandslukkere placeret på hver etage. Eftersyn udføres årligt. Brandalarm aktiveres automatisk ved røg.',\r\n attachments: [{ name: 'Brandplan.pdf', type: 'pdf' }],\r\n },\r\n {\r\n title: 'Alarmsystem',\r\n description: 'Adgangskontrol med kodesystem ved alle indgange. Kode ændres kvartalsvis. Ved indbrud kontakt straks politiet og ejendomsadministrationen.',\r\n contacts: [\r\n {\r\n name: 'SecureHome A/S',\r\n initials: 'S',\r\n contactPerson: 'Henrik Johansen',\r\n phoneNumber: '+45 98 76 54 32',\r\n },\r\n ],\r\n },\r\n ];\r\n\r\n // Service Contracts folder data\r\n serviceContractsItems: HandbookItem[] = [\r\n {\r\n title: 'Rengøringsservice',\r\n description: 'Ugentlig rengøring af fællesarealer inklusiv indgangshal, trapper og elevatorer. Hovedrengøring kvartalsvis. Service leveres mandag-fredag, 6:00-9:00.',\r\n contacts: [\r\n {\r\n name: 'CleanCo Denmark',\r\n initials: 'C',\r\n contactPerson: 'Anne Kristensen',\r\n phoneNumber: '+45 89 01 23 45',\r\n },\r\n ],\r\n },\r\n {\r\n title: 'Rengøringskontrakt',\r\n attachments: [\r\n { name: 'Rengøringskontrakt_2024.pdf', type: 'pdf' },\r\n { name: 'Rengøringsplan.pdf', type: 'pdf' },\r\n ],\r\n },\r\n {\r\n title: 'Udendørs arealer',\r\n 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.',\r\n images: ['/Assets/Dummy-photos/park.jpg', '/Assets/Dummy-photos/yard.jpg'],\r\n },\r\n {\r\n title: 'Havevedligeholdelse',\r\n description: 'Professionel havepleje inklusiv plæneklipning, hækklipning og blomsterbedvedligeholdelse. Vintersnefjerning inkluderet.',\r\n contacts: [\r\n {\r\n name: 'Green Gardens ApS',\r\n initials: 'G',\r\n contactPerson: 'Michael Olsen',\r\n phoneNumber: '+45 90 12 34 56',\r\n },\r\n ],\r\n },\r\n {\r\n title: 'Haveserviceaftale',\r\n attachments: [{ name: 'Haveserviceaftale.pdf', type: 'pdf' }],\r\n },\r\n {\r\n title: 'Vinduespolering',\r\n description: 'Professionel vinduespoleringsservice for alle udvendige vinduer to gange årligt - forår og efterår.',\r\n contacts: [\r\n {\r\n name: 'Crystal Clear Windows',\r\n initials: 'C',\r\n contactPerson: 'Lene Schmidt',\r\n phoneNumber: '+45 01 23 45 67',\r\n },\r\n ],\r\n },\r\n {\r\n title: 'Sikkerhedsservice',\r\n description: '24/7 overvågningsservice med alarmrespons. Direkte forbindelse til politi og brandvæsen.',\r\n contacts: [\r\n {\r\n name: 'SecureHome A/S',\r\n initials: 'S',\r\n contactPerson: 'Henrik Johansen',\r\n phoneNumber: '+45 12 34 56 78',\r\n },\r\n ],\r\n },\r\n {\r\n title: 'Sikkerhedskontrakt og procedurer',\r\n attachments: [\r\n { name: 'Sikkerhedskontrakt.pdf', type: 'pdf' },\r\n { name: 'Nødprocedurer.pdf', type: 'pdf' },\r\n ],\r\n },\r\n ];\r\n\r\n // Equipment folder data\r\n equipmentItems: HandbookItem[] = [\r\n {\r\n title: 'Balkon udsigt',\r\n description: 'Eksempel på udsigt fra øverste etagers balkoner. Flere lejligheder har privat altan med fantastisk udsyn.',\r\n images: ['/Assets/Dummy-photos/balcony-view.jpg'],\r\n },\r\n {\r\n title: 'Vaskerum',\r\n description:\r\n 'Fælles vaskerum med 4 vaskemaskiner og 4 tørretumblere. Bookingsystem tilgængeligt via beboerportal. Maskiner accepterer betalingskort. Åbningstider: 7:00-22:00.',\r\n contacts: [\r\n {\r\n name: 'WashTech Service',\r\n initials: 'W',\r\n contactPerson: 'Kirsten Berg',\r\n phoneNumber: '+45 34 56 78 90',\r\n },\r\n ],\r\n },\r\n {\r\n title: 'Vaskeri instruktioner',\r\n attachments: [\r\n { name: 'Vaskeinstruktioner.pdf', type: 'pdf' },\r\n { name: 'Bookingguide.pdf', type: 'pdf' },\r\n ],\r\n },\r\n {\r\n title: 'Vedligeholdelse og reparationer',\r\n description: 'Ved behov for reparationer eller vedligeholdelse i din lejlighed, kontakt vores hausmeister. Akutte problemer håndteres samme dag.',\r\n images: ['/Assets/Dummy-photos/handyman.jpg'],\r\n contacts: [\r\n {\r\n name: 'Hausmeister Service',\r\n initials: 'H',\r\n contactPerson: 'Erik Sørensen',\r\n phoneNumber: '+45 56 78 90 12',\r\n },\r\n ],\r\n },\r\n {\r\n title: 'Værktøjsudlån',\r\n description: 'Basis håndværktøj tilgængeligt til beboerbrug. Kvittér for værktøj ved receptionen. Returnér inden for 48 timer.',\r\n attachments: [\r\n { name: 'Værktøjsliste.pdf', type: 'pdf' },\r\n { name: 'Udlånspolitik.pdf', type: 'pdf' },\r\n ],\r\n },\r\n ];\r\n\r\n constructor(public userService: UserService) {}\r\n\r\n handleRefresh(event: any): void {\r\n console.log('Pull-to-refresh triggered');\r\n\r\n // Check if offline and complete immediately\r\n if (this.pageComponent?.isOffline()) {\r\n console.log('Cannot refresh while offline');\r\n event.target.complete();\r\n return;\r\n }\r\n\r\n setTimeout(() => {\r\n console.log('Refresh complete');\r\n event.target.complete();\r\n }, 1000);\r\n }\r\n}\r\n","import { Injectable, inject, signal } from '@angular/core';\r\nimport { Platform } from '@ionic/angular/standalone';\r\nimport { AppTrackingStatus, AppTrackingTransparency } from 'capacitor-plugin-app-tracking-transparency';\r\n\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class TrackingPermissionService {\r\n private readonly trackingPromptRequestedKey = 'tracking_prompt_requested_v1';\r\n private readonly platform = inject(Platform);\r\n private readonly trackingSettingsReminder = signal(false);\r\n\r\n readonly showTrackingSettingsReminder = this.trackingSettingsReminder.asReadonly();\r\n\r\n async requestOnFirstHomeEntry(): Promise<void> {\r\n if (!this.isNativeIos()) {\r\n this.trackingSettingsReminder.set(false);\r\n return;\r\n }\r\n\r\n if (this.hasRequestedTrackingPrompt()) {\r\n await this.refreshTrackingStatus();\r\n return;\r\n }\r\n\r\n try {\r\n const { status } = await AppTrackingTransparency.getStatus();\r\n if (status === 'notDetermined') {\r\n await AppTrackingTransparency.requestPermission();\r\n }\r\n } catch (error) {\r\n console.log('Unable to request app tracking permission:', error);\r\n } finally {\r\n this.setTrackingPromptRequested();\r\n await this.refreshTrackingStatus();\r\n }\r\n }\r\n\r\n async getTrackingStatus(): Promise<AppTrackingStatus | null> {\r\n if (!this.isNativeIos()) {\r\n return null;\r\n }\r\n\r\n try {\r\n const { status } = await AppTrackingTransparency.getStatus();\r\n return status;\r\n } catch (error) {\r\n console.log('Unable to read app tracking status:', error);\r\n return null;\r\n }\r\n }\r\n\r\n async openAppSettings(): Promise<void> {\r\n if (!this.isNativeIos()) {\r\n return;\r\n }\r\n\r\n // iOS deep link for opening this app's system settings page.\r\n window.location.href = 'app-settings:';\r\n }\r\n\r\n shouldShowSettingsReminder(): boolean {\r\n return this.trackingSettingsReminder();\r\n }\r\n\r\n async refreshTrackingStatus(): Promise<void> {\r\n if (!this.isNativeIos()) {\r\n this.trackingSettingsReminder.set(false);\r\n return;\r\n }\r\n\r\n const status = await this.getTrackingStatus();\r\n const hasRequested = this.hasRequestedTrackingPrompt();\r\n this.trackingSettingsReminder.set(Boolean(hasRequested && status && status !== 'authorized'));\r\n }\r\n\r\n private isNativeIos(): boolean {\r\n return this.platform.is('ios') && this.platform.is('capacitor');\r\n }\r\n\r\n private hasRequestedTrackingPrompt(): boolean {\r\n return localStorage.getItem(this.trackingPromptRequestedKey) === '1';\r\n }\r\n\r\n private setTrackingPromptRequested(): void {\r\n localStorage.setItem(this.trackingPromptRequestedKey, '1');\r\n }\r\n}\r\n","import { Component, OnInit, computed, signal, ViewChild } from '@angular/core';\r\nimport { Router } from '@angular/router';\r\nimport { DsButtonComponent } from '@propbinder/design-system';\r\nimport { DsMobilePageMainComponent } from '../components/page-main';\r\nimport { DsMobileSectionComponent } from '../components/section';\r\nimport { DsMobileIllustrationComponent } from '../components/illustration';\r\nimport { DsMobilePropertyBannerComponent } from '../components/property-banner';\r\nimport { DsMobileInteractiveListItemPostComponent } from '../components/interactive-list-item-post';\r\nimport { DsMobileOfflineBannerComponent } from '../components/offline-banner';\r\nimport {\r\n PostContentComponent,\r\n PostTextComponent,\r\n PostActionsComponent,\r\n ActionLikeComponent,\r\n ActionCommentComponent\r\n} from '../components/interactive-list-item-post';\r\nimport { DsMobileInteractiveListItemInquiryComponent } from '../components/interactive-list-item-inquiry';\r\nimport { UserService } from '../services/user.service';\r\nimport { PostsService } from '../services/posts.service';\r\nimport { DsMobilePostDetailModalService } from '../components/post-detail-modal/ds-mobile-post-detail-modal.service';\r\nimport { TrackingPermissionService } from '../services/tracking-permission.service';\r\nimport { DsMobileBottomSheetService } from '../components/bottom-sheet/ds-mobile-bottom-sheet.service';\r\nimport { DsMobilePostActionsBottomSheetComponent, PostActionResult } from '../components/bottom-sheet';\r\n\r\n@Component({\r\n selector: 'app-home-page',\r\n standalone: true,\r\n imports: [\r\n DsButtonComponent,\r\n DsMobilePageMainComponent,\r\n DsMobileSectionComponent,\r\n DsMobileIllustrationComponent,\r\n DsMobilePropertyBannerComponent,\r\n DsMobileInteractiveListItemPostComponent,\r\n DsMobileInteractiveListItemInquiryComponent,\r\n DsMobileOfflineBannerComponent,\r\n PostContentComponent,\r\n PostTextComponent,\r\n PostActionsComponent,\r\n ActionLikeComponent,\r\n ActionCommentComponent\r\n ],\r\n styles: [`\r\n /* Posts list wrapper */\r\n .posts-list {\r\n display: flex;\r\n flex-direction: column;\r\n }\r\n \r\n /* Inquiries list wrapper */\r\n .inquiries-list {\r\n display: flex;\r\n flex-direction: column;\r\n }\r\n \r\n /* Empty state */\r\n .empty-state {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 20px;\r\n text-align: center;\r\n }\r\n \r\n .empty-state ds-button {\r\n display: block;\r\n margin-top: 16px;\r\n }\r\n \r\n .empty-state ds-button::ng-deep .btn {\r\n width: 100%;\r\n border-radius: 9999px;\r\n }\r\n \r\n .empty-state-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n color: var(--color-text-primary);\r\n margin-top: -16px;\r\n z-index: 4;\r\n }\r\n \r\n .empty-state-description {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n color: var(--color-text-secondary);\r\n margin: 0;\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-page-main\r\n #pageComponent\r\n title=\"Hjem\"\r\n headerTitle=\"Velkommen, Lars\"\r\n [avatarInitials]=\"userService.avatarInitials()\"\r\n [avatarType]=\"userService.avatarType()\"\r\n (refresh)=\"handleRefresh($event)\"\r\n >\r\n \r\n <!-- Offline indicator -->\r\n @if (pageComponent.isOffline()) {\r\n <ds-mobile-offline-banner \r\n offline-indicator\r\n title=\"Ingen internetforbindelse\"\r\n message=\"Nogle funktioner kan være utilgængelige\">\r\n </ds-mobile-offline-banner>\r\n }\r\n \r\n <!-- Property Banner in Header -->\r\n <ds-mobile-property-banner \r\n header-content\r\n address=\"Toftegårds Allé 5A, 2. tv.\"\r\n photoUrl=\"/Assets/Dummy-photos/building.jpg\">\r\n </ds-mobile-property-banner>\r\n \r\n <!-- Recent Community Posts Section (with content) -->\r\n <ds-mobile-section \r\n headline=\"Seneste opslag\"\r\n linkText=\"Se alle\"\r\n (linkClick)=\"navigateToCommunity()\">\r\n \r\n <div class=\"posts-list\">\r\n @for (post of recentPosts(); track post.id) {\r\n <ds-mobile-interactive-list-item-post\r\n [authorName]=\"post.authorName\"\r\n [authorRole]=\"post.authorRole\"\r\n [timestamp]=\"post.timestamp\"\r\n [avatarType]=\"post.avatarType\"\r\n [avatarSrc]=\"post.avatarSrc || ''\"\r\n [avatarInitials]=\"post.avatarInitials || ''\"\r\n [showBadge]=\"post.showBadge || false\"\r\n [clickable]=\"true\"\r\n [moreActions]=\"true\"\r\n (postClick)=\"openPost(post.id)\"\r\n (commentClick)=\"openPost(post.id, true)\"\r\n (longPress)=\"handlePostLongPress(post.id)\">\r\n \r\n <post-content>\r\n @if (post.content) {\r\n <post-text>{{ post.content }}</post-text>\r\n }\r\n </post-content>\r\n \r\n <post-actions>\r\n <action-like [count]=\"post.likeCount\" [active]=\"post.isLiked\" />\r\n <action-comment [count]=\"post.commentCount\" (commentClick)=\"openPost(post.id, true)\" />\r\n </post-actions>\r\n </ds-mobile-interactive-list-item-post>\r\n }\r\n </div>\r\n </ds-mobile-section>\r\n \r\n <!-- Recent Community Posts Section (empty state) -->\r\n <ds-mobile-section>\r\n <div class=\"empty-state\">\r\n <ds-mobile-illustration variant=\"post\" alt=\"No posts\" />\r\n <h3 class=\"empty-state-title\">Ingen opslag endnu</h3>\r\n <p class=\"empty-state-description\">Der er ingen opslag i fællesområdet i øjeblikket</p>\r\n \r\n <ds-button \r\n variant=\"secondary\" \r\n trailingIcon=\"remixArrowRightSLine\"\r\n (click)=\"navigateToCommunity()\">\r\n Gå til fællesområdet\r\n </ds-button>\r\n </div>\r\n </ds-mobile-section>\r\n \r\n <!-- Open Inquiries Section (with content) -->\r\n <ds-mobile-section \r\n headline=\"Åbne henvendelser\"\r\n linkText=\"Se alle\"\r\n (linkClick)=\"navigateToInquiries()\">\r\n \r\n <div class=\"inquiries-list\">\r\n @for (inquiry of openInquiries(); track inquiry.id) {\r\n <ds-mobile-interactive-list-item-inquiry\r\n [title]=\"inquiry.title\"\r\n [description]=\"inquiry.description\"\r\n [status]=\"inquiry.status\"\r\n [timestamp]=\"inquiry.timestamp\"\r\n [iconName]=\"'remixTodoLine'\"\r\n [clickable]=\"true\"\r\n [showChevron]=\"false\"\r\n [enableLongPress]=\"false\"\r\n (inquiryClick)=\"openInquiryDetail(inquiry.id)\">\r\n </ds-mobile-interactive-list-item-inquiry>\r\n }\r\n </div>\r\n </ds-mobile-section>\r\n \r\n <!-- Open Inquiries Section (empty state) -->\r\n <ds-mobile-section>\r\n <div class=\"empty-state\">\r\n <ds-mobile-illustration variant=\"inquiry\" alt=\"No inquiries\" />\r\n <h3 class=\"empty-state-title\">Ingen åbne henvendelser</h3>\r\n <p class=\"empty-state-description\">Du har ingen åbne henvendelser i øjeblikket</p>\r\n \r\n <ds-button \r\n variant=\"secondary\" \r\n trailingIcon=\"remixArrowRightSLine\"\r\n (click)=\"navigateToInquiries()\">\r\n Gå til henvendelser\r\n </ds-button>\r\n </div>\r\n </ds-mobile-section>\r\n </ds-mobile-page-main>\r\n `\r\n})\r\n\r\nexport class MobileHomePageComponent implements OnInit {\r\n @ViewChild('pageComponent') pageComponent!: DsMobilePageMainComponent;\r\n \r\n // Get recent posts from PostsService - exclude pinned post (post-4) and limit to 3\r\n recentPosts = computed(() => \r\n this.postsService.posts()\r\n .filter(post => post.id !== 'post-4') // Exclude pinned post\r\n .slice(0, 3)\r\n );\r\n \r\n // Mock inquiry data\r\n private allInquiries = signal([\r\n {\r\n id: '1',\r\n title: 'Tørretumbler virker ikke',\r\n description: 'I de sidste tre dage har jeg oplevet vedvarende problemer med tørretumbleren. Den starter, men stopper efter få minutter.',\r\n status: 'open' as const,\r\n timestamp: '12 dage siden'\r\n },\r\n {\r\n id: '2',\r\n title: 'Problem med vandtryk',\r\n description: 'Lavt vandtryk i badeværelseshåndvasken. Det er blevet gradvist værre i løbet af den sidste uge.',\r\n status: 'open' as const,\r\n timestamp: '5 dage siden'\r\n },\r\n {\r\n id: '3',\r\n title: 'Varme virker ikke ordentligt',\r\n description: 'Varmesystemet holder ikke den indstillede temperatur. Lejligheden er meget koldere, end den burde være.',\r\n status: 'closed' as const,\r\n timestamp: '2 måneder siden'\r\n }\r\n ]);\r\n \r\n // Filter for open inquiries and limit to 3\r\n openInquiries = computed(() => \r\n this.allInquiries()\r\n .filter(inquiry => inquiry.status === 'open')\r\n .slice(0, 3)\r\n );\r\n \r\n constructor(\r\n private router: Router,\r\n public userService: UserService,\r\n private postsService: PostsService,\r\n private postModal: DsMobilePostDetailModalService,\r\n private trackingPermissionService: TrackingPermissionService,\r\n private bottomSheet: DsMobileBottomSheetService\r\n ) {\r\n console.log('MobileHomePageComponent constructor');\r\n }\r\n\r\n ngOnInit(): void {\r\n void this.trackingPermissionService.requestOnFirstHomeEntry();\r\n }\r\n\r\n handleRefresh(event: any): void {\r\n console.log('Pull-to-refresh triggered');\r\n setTimeout(() => {\r\n console.log('Refresh complete');\r\n event.target.complete();\r\n }, 1000);\r\n }\r\n\r\n async openPost(postId: string, focusComment: boolean = false): Promise<void> {\r\n console.log('Opening post:', postId, 'Focus comments:', focusComment);\r\n \r\n const post = this.postsService.getPostById(postId);\r\n \r\n if (post) {\r\n // Convert Post model to modal format (add postId and focusComment)\r\n const postData = {\r\n ...post,\r\n postId: post.id,\r\n avatarType: post.avatarType === 'icon' ? undefined : post.avatarType,\r\n focusComment\r\n };\r\n \r\n await this.postModal.open(postData, {\r\n currentUserName: 'Lars Mikkelsen',\r\n currentUserInitials: this.userService.avatarInitials()\r\n });\r\n }\r\n }\r\n \r\n openInquiryDetail(inquiryId: string): void {\r\n console.log('Opening inquiry:', inquiryId);\r\n this.router.navigate(['/inquiry-detail', inquiryId]);\r\n }\r\n \r\n navigateToCommunity(): void {\r\n console.log('Navigating to community page');\r\n this.router.navigate(['/announcements']);\r\n }\r\n \r\n navigateToInquiries(): void {\r\n console.log('Navigating to inquiries page');\r\n this.router.navigate(['/inquiries']);\r\n }\r\n\r\n async handlePostLongPress(postId: string): Promise<void> {\r\n const sheet = await this.bottomSheet.create({\r\n component: DsMobilePostActionsBottomSheetComponent,\r\n componentProps: { isOwnContent: false },\r\n breakpoints: [0, 1],\r\n initialBreakpoint: 1,\r\n handle: true,\r\n backdropDismiss: true,\r\n cssClass: 'auto-height'\r\n });\r\n\r\n const result = await sheet.onWillDismiss();\r\n\r\n if (result.role === 'select' && result.data) {\r\n const action = (result.data as PostActionResult).action;\r\n\r\n switch (action) {\r\n case 'like':\r\n const post = this.postsService.getPostById(postId);\r\n if (post) {\r\n this.postsService.updatePost(postId, {\r\n isLiked: !post.isLiked,\r\n likeCount: post.isLiked ? post.likeCount - 1 : post.likeCount + 1\r\n });\r\n }\r\n break;\r\n case 'reply':\r\n await this.openPost(postId, true);\r\n break;\r\n }\r\n }\r\n }\r\n}\r\n\r\n","import { Component, signal, computed, ViewChild } from '@angular/core';\r\nimport { NavController } from '@ionic/angular/standalone';\r\nimport { DsMobilePageMainComponent } from '../components/page-main';\r\nimport { DsMobileSectionComponent } from '../components/section';\r\nimport { DsMobileIllustrationComponent } from '../components/illustration';\r\nimport { DsMobileInteractiveListItemInquiryComponent } from '../components/interactive-list-item-inquiry';\r\nimport { DsMobileFabComponent } from '../components/fab';\r\nimport { DsMobileOfflineBannerComponent } from '../components/offline-banner';\r\nimport { DsMobileNewInquiryModalService, NewInquiryData } from '../components/new-inquiry-modal';\r\nimport { UserService } from '../services/user.service';\r\nimport { customPageTransition } from '../animations/page-transitions';\r\nimport { DsMobileInlineTabsComponent, type InlineTabItem } from '../components/inline-tabs';\r\n\r\ninterface Inquiry {\r\n id: string;\r\n title: string;\r\n description: string;\r\n status: 'open' | 'closed';\r\n timestamp: string;\r\n category: 'maintenance' | 'plumbing' | 'electrical' | 'heating' | 'security' | 'appliance' | 'other';\r\n}\r\n\r\n@Component({\r\n selector: 'app-mobile-inquiries-page',\r\n standalone: true,\r\n imports: [\r\n DsMobilePageMainComponent,\r\n DsMobileSectionComponent,\r\n DsMobileIllustrationComponent,\r\n DsMobileInteractiveListItemInquiryComponent,\r\n DsMobileInlineTabsComponent,\r\n DsMobileOfflineBannerComponent,\r\n DsMobileFabComponent\r\n ],\r\n host: {\r\n class: 'ion-page'\r\n },\r\n styles: [`\r\n .inquiry-list-wrapper {\r\n display: flex;\r\n flex-direction: column;\r\n margin-top: -12px;\r\n }\r\n \r\n .empty-state {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 60px 20px;\r\n text-align: center;\r\n }\r\n \r\n .empty-state-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n color: var(--color-text-primary);\r\n margin-top: -16px;\r\n z-index: 4;\r\n }\r\n \r\n .empty-state-description {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: var(--font-size-sm);\r\n color: var(--color-text-secondary);\r\n margin: 0;\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-page-main\r\n #pageComponent\r\n title=\"Henvendelser\"\r\n [avatarInitials]=\"userService.avatarInitials()\"\r\n [avatarType]=\"userService.avatarType()\"\r\n (refresh)=\"handleRefresh($event)\">\r\n \r\n <!-- Offline indicator -->\r\n @if (pageComponent.isOffline()) {\r\n <ds-mobile-offline-banner \r\n offline-indicator\r\n title=\"Ingen internetforbindelse\"\r\n message=\"Nogle funktioner kan være utilgængelige\">\r\n </ds-mobile-offline-banner>\r\n }\r\n \r\n <!-- Filter tabs in header -->\r\n <div header-content>\r\n <ds-mobile-inline-tabs\r\n [tabs]=\"tabItems\"\r\n [activeTab]=\"filterStatus()\"\r\n (tabChange)=\"setFilter($any($event))\">\r\n </ds-mobile-inline-tabs>\r\n </div>\r\n \r\n <ds-mobile-section>\r\n @if (filteredInquiries().length > 0) {\r\n <div class=\"inquiry-list-wrapper\">\r\n @for (inquiry of filteredInquiries(); track inquiry.id) {\r\n <ds-mobile-interactive-list-item-inquiry\r\n [title]=\"inquiry.title\"\r\n [description]=\"inquiry.description\"\r\n [status]=\"inquiry.status\"\r\n [timestamp]=\"inquiry.timestamp\"\r\n [iconName]=\"getInquiryIcon(inquiry.category)\"\r\n [clickable]=\"true\"\r\n [showChevron]=\"false\"\r\n [enableLongPress]=\"false\"\r\n (inquiryClick)=\"openInquiryDetail(inquiry.id)\">\r\n </ds-mobile-interactive-list-item-inquiry>\r\n }\r\n </div>\r\n } @else {\r\n <!-- Empty state -->\r\n <div class=\"empty-state\">\r\n <ds-mobile-illustration variant=\"inquiry\" alt=\"No inquiries\" />\r\n <h3 class=\"empty-state-title\">Ingen henvendelser endnu</h3>\r\n <p class=\"empty-state-description\">\r\n @if (filterStatus() === 'open') {\r\n Du har ingen åbne henvendelser\r\n } @else if (filterStatus() === 'closed') {\r\n Du har ingen lukkede henvendelser\r\n } @else {\r\n Du har ikke oprettet nogen henvendelser endnu\r\n }\r\n </p>\r\n </div>\r\n }\r\n </ds-mobile-section>\r\n </ds-mobile-page-main>\r\n\r\n <!-- FAB for creating new inquiry -->\r\n <ds-mobile-fab\r\n icon=\"remixAddLine\"\r\n position=\"bottom-right\"\r\n ariaLabel=\"Create new inquiry\"\r\n (clicked)=\"createNewInquiry()\">\r\n </ds-mobile-fab>\r\n `\r\n})\r\nexport class MobileInquiriesPageComponent {\r\n @ViewChild('pageComponent') pageComponent!: DsMobilePageMainComponent;\r\n \r\n constructor(\r\n public userService: UserService,\r\n private navCtrl: NavController,\r\n private newInquiryModal: DsMobileNewInquiryModalService\r\n ) {}\r\n \r\n filterStatus = signal<'all' | 'open' | 'closed'>('all');\r\n \r\n tabItems: InlineTabItem[] = [\r\n { id: 'all', label: 'Alle' },\r\n { id: 'open', label: 'Åben' },\r\n { id: 'closed', label: 'Lukket' }\r\n ];\r\n \r\n inquiries = signal<Inquiry[]>([\r\n {\r\n id: '1',\r\n title: 'Tørretumbler virker ikke',\r\n description: 'I de sidste tre dage har jeg oplevet vedvarende problemer med tørretumbleren. Den starter, men stopper efter få minutter.',\r\n status: 'open',\r\n timestamp: '12 dage siden',\r\n category: 'appliance'\r\n },\r\n {\r\n id: '2',\r\n title: 'Problem med vandtryk',\r\n description: 'Lavt vandtryk i badeværelseshåndvasken. Det er blevet gradvist værre i løbet af den sidste uge.',\r\n status: 'open',\r\n timestamp: '5 dage siden',\r\n category: 'plumbing'\r\n },\r\n {\r\n id: '3',\r\n title: 'Varme virker ikke ordentligt',\r\n description: 'Varmesystemet holder ikke den indstillede temperatur. Lejligheden er meget koldere, end den burde være.',\r\n status: 'closed',\r\n timestamp: '2 måneder siden',\r\n category: 'heating'\r\n }\r\n ]);\r\n \r\n // Computed signals that automatically update when dependencies change\r\n filteredInquiries = computed(() => {\r\n const all = this.inquiries();\r\n const status = this.filterStatus();\r\n \r\n if (status === 'all') {\r\n return all;\r\n } else if (status === 'open') {\r\n return all.filter(i => i.status === 'open');\r\n } else {\r\n return all.filter(i => i.status === 'closed');\r\n }\r\n });\r\n \r\n openInquiries = computed(() => {\r\n return this.inquiries().filter(i => i.status === 'open');\r\n });\r\n \r\n closedInquiries = computed(() => {\r\n return this.inquiries().filter(i => i.status === 'closed');\r\n });\r\n \r\n setFilter(status: 'all' | 'open' | 'closed'): void {\r\n this.filterStatus.set(status);\r\n }\r\n \r\n getInquiryIcon(category: string): string {\r\n return 'remixTodoLine';\r\n }\r\n \r\n openInquiryDetail(inquiryId: string): void {\r\n console.log('Opening inquiry:', inquiryId);\r\n // Navigate to inquiry detail page with custom transition (absolute path outside tabs for animations)\r\n this.navCtrl.navigateForward([`/inquiry-detail/${inquiryId}`], {\r\n animation: customPageTransition\r\n });\r\n }\r\n \r\n showInquiryActions(inquiryId: string): void {\r\n console.log('Showing actions for inquiry:', inquiryId);\r\n // Show bottom sheet with actions (edit, delete, etc.)\r\n }\r\n \r\n handleRefresh(event: any): void {\r\n console.log('Pull-to-refresh triggered on inquiries page');\r\n \r\n // Check if offline and complete immediately\r\n if (this.pageComponent?.isOffline()) {\r\n console.log('Cannot refresh while offline');\r\n event.target.complete();\r\n return;\r\n }\r\n \r\n // Simulate loading data\r\n setTimeout(() => {\r\n console.log('Refresh complete');\r\n event.target.complete();\r\n }, 1000);\r\n }\r\n \r\n async createNewInquiry(): Promise<void> {\r\n console.log('[InquiriesPage] FAB clicked, opening modal...');\r\n \r\n await this.newInquiryModal.open({\r\n onSubmit: async (data: NewInquiryData) => {\r\n console.log('New inquiry submitted:', data);\r\n \r\n // In a real app, call your API to create the inquiry\r\n // await this.inquiryService.createInquiry(data);\r\n \r\n // Add the new inquiry to the list (mock for now)\r\n const newInquiry: Inquiry = {\r\n id: `inquiry-${Date.now()}`,\r\n title: data.title,\r\n description: data.description,\r\n status: 'open',\r\n timestamp: 'Just now',\r\n category: 'other'\r\n };\r\n \r\n this.inquiries.update(inquiries => [newInquiry, ...inquiries]);\r\n \r\n // Close the modal\r\n await this.newInquiryModal.close();\r\n }\r\n });\r\n }\r\n}\r\n\r\n","import { Component, signal, computed } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { DsIconComponent, DsBadgeComponent } from '@propbinder/design-system';\r\nimport { DsMobilePageDetailsComponent } from '../components/page-details';\r\nimport { DsMobileInteractiveListItemMessageComponent } from '../components/interactive-list-item-message';\r\nimport { DsMobileListItemComponent } from '../components/list-item/ds-mobile-list-item';\r\nimport { DsMobileLightboxService, type LightboxImage } from '../components/lightbox';\r\nimport { DsMobileChatModalService, type ChatModalData } from '../components/chat-modal';\r\nimport { DsAvatarWithBadgeComponent } from '../components/avatar-with-badge';\r\nimport { DsMobileCardInlineBannerComponent } from '../components/card-inline-banner';\r\nimport { DsMobileSectionComponent } from '../components/section';\r\nimport { DsMobileInlinePhotoComponent } from '../components/inline-photo';\r\nimport { UserService } from '../services/user.service';\r\nimport { type InlineTabItem } from '../components/inline-tabs';\r\n\r\ninterface MessageThread {\r\n id: string;\r\n senderName: string;\r\n senderAvatar: string;\r\n senderInitials: string;\r\n message: string;\r\n role: string;\r\n timestamp: string;\r\n unread: boolean;\r\n}\r\n\r\n@Component({\r\n selector: 'app-mobile-inquiry-detail-page',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n DsIconComponent,\r\n DsAvatarWithBadgeComponent,\r\n DsMobilePageDetailsComponent,\r\n DsMobileInteractiveListItemMessageComponent,\r\n DsMobileListItemComponent,\r\n DsBadgeComponent,\r\n DsMobileCardInlineBannerComponent,\r\n DsMobileSectionComponent,\r\n DsMobileInlinePhotoComponent\r\n ],\r\n host: {\r\n class: 'ion-page'\r\n },\r\n styleUrls: [\r\n './inquiry-detail.example.css'\r\n ],\r\n template: `\r\n <ds-mobile-page-details\r\n [title]=\"inquiryTitle\"\r\n [tabs]=\"tabItems\"\r\n [activeTab]=\"activeTab()\"\r\n (tabChange)=\"setActiveTab($event)\"\r\n (back)=\"goBack()\"\r\n (refresh)=\"handleRefresh($event)\">\r\n \r\n <!-- Messages Tab Content -->\r\n @if (activeTab() === 'messages') {\r\n <ds-mobile-section contentGap=\"0\">\r\n @for (message of messageThreads; track message.id) {\r\n <ds-mobile-interactive-list-item-message\r\n [senderName]=\"message.senderName\"\r\n [senderRole]=\"message.role\"\r\n [timestamp]=\"message.timestamp\"\r\n [message]=\"message.message\"\r\n [avatarInitials]=\"message.senderInitials\"\r\n [unread]=\"message.unread\"\r\n (messageClick)=\"openMessage(message.id)\">\r\n </ds-mobile-interactive-list-item-message>\r\n }\r\n </ds-mobile-section>\r\n }\r\n \r\n <!-- Details Tab Content -->\r\n @if (activeTab() === 'details') {\r\n <!-- Unread Messages Banner -->\r\n @if (hasUnreadMessages()) {\r\n <ds-mobile-section>\r\n <ds-mobile-card-inline-banner\r\n [title]=\"'Du har ulæste beskeder'\"\r\n [unreadCount]=\"3\"\r\n [layout]=\"'compact'\"\r\n (bannerClick)=\"navigateToMessagesTab()\">\r\n </ds-mobile-card-inline-banner>\r\n </ds-mobile-section>\r\n }\r\n \r\n <!-- All Details in One Section -->\r\n <ds-mobile-section contentGap=\"0\">\r\n <!-- Assignee -->\r\n <ds-mobile-list-item [leadingSize]=\"'32px'\" [showDivider]=\"true\">\r\n <div content-leading>\r\n <ds-avatar-with-badge\r\n [size]=\"'sm'\"\r\n [type]=\"'initials'\"\r\n [initials]=\"'R'\" />\r\n </div>\r\n <div content-main>\r\n <div class=\"detail-label\">Sagsbehandler</div>\r\n <div class=\"detail-value\">Ricki Meihlen</div>\r\n </div>\r\n </ds-mobile-list-item>\r\n \r\n <!-- Technician -->\r\n <ds-mobile-list-item [leadingSize]=\"'32px'\" [showDivider]=\"true\">\r\n <div content-leading>\r\n <ds-avatar-with-badge\r\n [size]=\"'sm'\"\r\n [type]=\"'initials'\"\r\n [initials]=\"'M'\" />\r\n </div>\r\n <div content-main>\r\n <div class=\"detail-label\">Tekniker</div>\r\n <div class=\"detail-value\">Martin Smith</div>\r\n </div>\r\n </ds-mobile-list-item>\r\n \r\n <!-- Creation Date -->\r\n <ds-mobile-list-item [leadingSize]=\"'32px'\" [showDivider]=\"true\" [align]=\"'center'\">\r\n <ds-icon content-leading name=\"remixTimeLine\" size=\"20px\" color=\"tertiary\" />\r\n <div content-main>\r\n <div class=\"detail-value\">22. feb 2025</div>\r\n </div>\r\n </ds-mobile-list-item>\r\n \r\n <!-- Title -->\r\n <ds-mobile-list-item [leadingSize]=\"'32px'\" [showDivider]=\"true\" [align]=\"'center'\">\r\n <ds-icon content-leading name=\"remixTextBlock\" size=\"20px\" color=\"tertiary\" />\r\n <div content-main>\r\n <div class=\"detail-value\">{{ inquiryTitle }}</div>\r\n </div>\r\n </ds-mobile-list-item>\r\n \r\n <!-- Description -->\r\n <ds-mobile-list-item [leadingSize]=\"'32px'\" [showDivider]=\"true\">\r\n <ds-icon content-leading name=\"remixAlignLeft\" size=\"20px\" color=\"tertiary\" />\r\n <div content-main>\r\n <div class=\"detail-value description-text\">\r\n I de sidste tre dage har vi oplevet vedvarende problemer med tørretumbleren i vores lejlighed. På trods af at vi følger betjeningsvejledningen, fejler maskinen konsekvent i at fuldføre sine tørrecyklusser.\r\n </div>\r\n <ds-badge content=\"Husholdningsapparater\" size=\"sm\"/>\r\n </div>\r\n </ds-mobile-list-item>\r\n \r\n <!-- Photos -->\r\n <ds-mobile-list-item [leadingSize]=\"'32px'\" [showDivider]=\"false\">\r\n <ds-icon content-leading name=\"remixCameraLine\" size=\"20px\" color=\"tertiary\" />\r\n <div content-main>\r\n <ds-mobile-inline-photo \r\n [images]=\"photoUrls\"\r\n [useGrid]=\"false\"\r\n (photoClick)=\"openPhotoLightbox($event.index)\" />\r\n </div>\r\n </ds-mobile-list-item>\r\n </ds-mobile-section>\r\n }\r\n </ds-mobile-page-details>\r\n `\r\n})\r\nexport class MobileInquiryDetailPageComponent {\r\n inquiryTitle = 'Tørretumbler virker ikke';\r\n activeTab = signal<string>('details');\r\n \r\n tabItems: InlineTabItem[] = [\r\n { id: 'details', label: 'Detaljer' },\r\n { id: 'messages', label: 'Beskeder', badge: 0 }\r\n ];\r\n \r\n messageThreads: MessageThread[] = [\r\n {\r\n id: '1',\r\n senderName: 'Ove Hindborg',\r\n senderAvatar: '',\r\n senderInitials: 'OH',\r\n message: 'Dejligt at høre! Jeg venter på din teknikerbesøg tidsplan.',\r\n role: 'Sagsbehandler',\r\n timestamp: '2t siden',\r\n unread: true\r\n },\r\n {\r\n id: '2',\r\n senderName: 'Martin Smith',\r\n senderAvatar: '',\r\n senderInitials: 'MS',\r\n message: 'Martin Smith har overtaget din henvendelse og vil kontakte dig snart.',\r\n role: 'Tekniker',\r\n timestamp: '',\r\n unread: false\r\n }\r\n ];\r\n \r\n unreadMessagesCount = computed(() => {\r\n const count = this.messageThreads.length;\r\n // Update badge in tab items\r\n const messagesTab = this.tabItems.find(t => t.id === 'messages');\r\n if (messagesTab) {\r\n messagesTab.badge = count;\r\n }\r\n return count;\r\n });\r\n \r\n // Photos for lightbox\r\n photos: LightboxImage[] = [\r\n { type: 'image', src: '/Assets/Dummy-photos/handyman.jpg', alt: 'Handyman', title: 'Handyman' },\r\n { type: 'image', src: '/Assets/Dummy-photos/balcony-view.jpg', alt: 'Balcony view', title: 'Balcony view' },\r\n { type: 'image', src: '/Assets/Dummy-photos/staircase.jpg', alt: 'Staircase', title: 'Staircase' },\r\n { type: 'image', src: '/Assets/Dummy-photos/yard.jpg', alt: 'Yard', title: 'Yard' },\r\n { type: 'image', src: '/Assets/Dummy-photos/mailboxes.jpg', alt: 'Mailboxes', title: 'Mailboxes' }\r\n ];\r\n \r\n // Photo URLs for inline-photo component\r\n get photoUrls(): string[] {\r\n return this.photos.map(photo => photo.src);\r\n }\r\n \r\n constructor(\r\n public userService: UserService,\r\n private lightbox: DsMobileLightboxService,\r\n private chatModal: DsMobileChatModalService\r\n ) {\r\n // Trigger initial badge update\r\n this.unreadMessagesCount();\r\n }\r\n \r\n setActiveTab(tabId: string): void {\r\n this.activeTab.set(tabId);\r\n }\r\n \r\n goBack(): void {\r\n // Navigation is handled by ds-mobile-page-details component\r\n // This is just for any custom logic if needed\r\n }\r\n \r\n handleRefresh(event: any): void {\r\n console.log('Pull-to-refresh triggered');\r\n setTimeout(() => {\r\n console.log('Refresh complete');\r\n event.target.complete();\r\n }, 1000);\r\n }\r\n \r\n /**\r\n * Check if there are unread messages\r\n */\r\n hasUnreadMessages(): boolean {\r\n return this.messageThreads.some(m => m.unread);\r\n }\r\n \r\n /**\r\n * Navigate to messages tab when banner is clicked\r\n */\r\n navigateToMessagesTab(): void {\r\n this.setActiveTab('messages');\r\n }\r\n \r\n async openMessage(messageId: string): Promise<void> {\r\n console.log('Opening message:', messageId);\r\n \r\n // Find the message thread\r\n const messageThread = this.messageThreads.find(m => m.id === messageId);\r\n if (!messageThread) {\r\n console.error('Message thread not found:', messageId);\r\n return;\r\n }\r\n \r\n // Check if this is an empty state chat (no timestamp and system message)\r\n const isEmptyChat = messageThread.message.includes('har overtaget din henvendelse') && !messageThread.timestamp;\r\n \r\n // Prepare chat modal data\r\n // In a real app, you would fetch the actual messages from your API\r\n const chatData: ChatModalData = {\r\n participant: {\r\n id: messageId,\r\n name: messageThread.senderName,\r\n role: messageThread.role,\r\n avatarInitials: messageThread.senderInitials,\r\n avatarType: 'initials'\r\n },\r\n messages: isEmptyChat ? [] : [\r\n // Day 1 - Yesterday morning (9:15 AM)\r\n {\r\n id: '1',\r\n content: 'Godmorgen! Jeg ville lige følge op på din henvendelse vedrørende vedligeholdelsesplanen.',\r\n senderId: messageId,\r\n senderName: messageThread.senderName,\r\n senderRole: messageThread.role,\r\n timestamp: new Date(Date.now() - 86400000 - 32700000), // Yesterday 9:15 AM\r\n isOwnMessage: false,\r\n avatarInitials: messageThread.senderInitials,\r\n avatarType: 'initials',\r\n },\r\n {\r\n id: '2',\r\n content: 'Vi har gennemgået din sag og identificeret den grundlæggende årsag til problemet.',\r\n senderId: messageId,\r\n senderName: messageThread.senderName,\r\n senderRole: messageThread.role,\r\n timestamp: new Date(Date.now() - 86400000 - 32520000), // Yesterday 9:18 AM (grouped with previous)\r\n isOwnMessage: false,\r\n avatarInitials: messageThread.senderInitials,\r\n avatarType: 'initials',\r\n },\r\n {\r\n id: '3',\r\n content: 'Tak fordi du kiggede på det! Hvad fandt du?',\r\n senderId: 'current-user',\r\n senderName: 'You',\r\n timestamp: new Date(Date.now() - 86400000 - 32100000), // Yesterday 9:25 AM (new group - 7 min gap)\r\n isOwnMessage: true,\r\n avatarInitials: this.userService.avatarInitials(),\r\n avatarType: 'initials',\r\n },\r\n {\r\n id: '4',\r\n content: 'Kan du også sende mig vedligeholdelsesrapporten?',\r\n senderId: 'current-user',\r\n senderName: 'You',\r\n timestamp: new Date(Date.now() - 86400000 - 31980000), // Yesterday 9:27 AM (grouped with previous)\r\n isOwnMessage: true,\r\n avatarInitials: this.userService.avatarInitials(),\r\n avatarType: 'initials',\r\n },\r\n \r\n // Day 1 - Yesterday afternoon (2:30 PM - large time gap)\r\n {\r\n id: '5',\r\n content: messageThread.message,\r\n senderId: messageId,\r\n senderName: messageThread.senderName,\r\n senderRole: messageThread.role,\r\n timestamp: new Date(Date.now() - 86400000 - 13800000), // Yesterday 2:30 PM (new group - 5 hour gap)\r\n isOwnMessage: false,\r\n avatarInitials: messageThread.senderInitials,\r\n avatarType: 'initials',\r\n },\r\n {\r\n id: '6',\r\n content: 'Jeg har vedhæftet den detaljerede rapport på dit henvendelsesdashboard. Gennemgå den gerne, når du har et øjeblik.',\r\n senderId: messageId,\r\n senderName: messageThread.senderName,\r\n senderRole: messageThread.role,\r\n timestamp: new Date(Date.now() - 86400000 - 13620000), // Yesterday 2:33 PM (grouped with previous)\r\n isOwnMessage: false,\r\n avatarInitials: messageThread.senderInitials,\r\n avatarType: 'initials',\r\n },\r\n \r\n // Day 2 - Today morning (10:45 AM - new day)\r\n {\r\n id: '7',\r\n content: 'Perfekt! Jeg har gennemgået rapporten, og alt ser godt ud.',\r\n senderId: 'current-user',\r\n senderName: 'You',\r\n timestamp: new Date(Date.now() - 7500000), // Today 10:45 AM (new group - new day)\r\n isOwnMessage: true,\r\n avatarInitials: this.userService.avatarInitials(),\r\n avatarType: 'initials',\r\n },\r\n {\r\n id: '8',\r\n content: 'Hvornår kan vi planlægge vedligeholdelsesarbejdet?',\r\n senderId: 'current-user',\r\n senderName: 'You',\r\n timestamp: new Date(Date.now() - 7320000), // Today 10:48 AM (grouped with previous)\r\n isOwnMessage: true,\r\n avatarInitials: this.userService.avatarInitials(),\r\n avatarType: 'initials',\r\n },\r\n \r\n // Day 2 - Today (just now - 2 minutes ago)\r\n {\r\n id: '9',\r\n content: 'Dejligt at høre! Jeg kan planlægge det til næste tirsdag kl. 09.00. Passer det dig?',\r\n senderId: messageId,\r\n senderName: messageThread.senderName,\r\n senderRole: messageThread.role,\r\n timestamp: new Date(Date.now() - 120000), // 2 minutes ago (new group - several hours gap)\r\n isOwnMessage: false,\r\n avatarInitials: messageThread.senderInitials,\r\n avatarType: 'initials',\r\n },\r\n {\r\n id: '10',\r\n content: 'Jeg sender dig en kalenderinvitation med alle detaljerne.',\r\n senderId: messageId,\r\n senderName: messageThread.senderName,\r\n senderRole: messageThread.role,\r\n timestamp: new Date(Date.now() - 60000), // 1 minute ago (grouped with previous)\r\n isOwnMessage: false,\r\n avatarInitials: messageThread.senderInitials,\r\n avatarType: 'initials',\r\n }\r\n ],\r\n currentUserId: 'current-user',\r\n currentUserInitials: this.userService.avatarInitials(),\r\n currentUserAvatarType: 'initials',\r\n autoFocus: false\r\n };\r\n \r\n // Open the chat modal\r\n await this.chatModal.open(chatData);\r\n }\r\n \r\n async openPhotoLightbox(index: number): Promise<void> {\r\n await this.lightbox.openImages({\r\n images: this.photos,\r\n initialIndex: index,\r\n showControls: true,\r\n enableSwipe: true,\r\n enableZoom: true,\r\n showInfo: false\r\n });\r\n }\r\n}\r\n\r\n","import { Component, OnInit, inject, CUSTOM_ELEMENTS_SCHEMA } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { WhitelabelService } from '../services/whitelabel.service';\r\nimport { DsLogoComponent } from '../components/logo/ds-logo';\r\nimport { DsAvatarWithBadgeComponent } from '../components/avatar-with-badge/ds-avatar-with-badge';\r\nimport { DsAppIconComponent } from '../components/app-icon/ds-app-icon';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { IonContent, ModalController } from '@ionic/angular/standalone';\r\n\r\n/**\r\n * Whitelabel Demo Modal Component\r\n * \r\n * Demonstrates the whitelabeling system with theme selection, brand colors, and logo previews.\r\n * Opens as a full-screen modal similar to post details.\r\n */\r\n@Component({\r\n selector: 'ds-whitelabel-demo-modal',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n IonContent,\r\n DsLogoComponent,\r\n DsAvatarWithBadgeComponent,\r\n DsAppIconComponent,\r\n DsIconButtonComponent\r\n ],\r\n schemas: [CUSTOM_ELEMENTS_SCHEMA],\r\n styles: [`\r\n /* Host fills the modal with flex layout */\r\n :host {\r\n display: flex;\r\n flex-direction: column;\r\n height: 100%;\r\n width: 100%;\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n }\r\n \r\n /* Fixed header at top */\r\n .modal-header {\r\n flex-shrink: 0;\r\n background: var(--color-background-neutral-primary, #ffffff);\r\n border-bottom: 1px solid var(--border-color-default, #e0e0e0);\r\n padding: 0 16px;\r\n }\r\n \r\n /* ion-content fills remaining space and scrolls */\r\n ion-content,\r\n .modal-content {\r\n --background: #ffffff;\r\n flex: 1;\r\n width: 100%;\r\n }\r\n \r\n .header-content {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 12px;\r\n min-height: 56px;\r\n }\r\n \r\n .header-title {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: 17px;\r\n font-weight: 600;\r\n color: var(--color-text-primary, #1a1a1a);\r\n flex: 1;\r\n }\r\n \r\n .close-button {\r\n flex-shrink: 0;\r\n border-radius: 50%;\r\n }\r\n \r\n .close-button::ng-deep button {\r\n border-radius: 50% !important;\r\n width: 36px !important;\r\n height: 36px !important;\r\n min-width: 36px !important;\r\n min-height: 36px !important;\r\n padding: 0 !important;\r\n display: flex !important;\r\n align-items: center !important;\r\n justify-content: center !important;\r\n background: var(--color-background-neutral-secondary, #f5f5f5) !important;\r\n color: var(--color-text-primary, #1a1a1a) !important;\r\n }\r\n \r\n .demo-container {\r\n padding: 20px;\r\n max-width: 600px;\r\n margin: 0 auto;\r\n width: 100%;\r\n }\r\n \r\n .demo-section {\r\n margin-bottom: 32px;\r\n }\r\n \r\n .demo-section h2 {\r\n margin-bottom: 16px;\r\n font-size: 18px;\r\n font-weight: 600;\r\n color: #333;\r\n }\r\n \r\n /* Theme Selection */\r\n .theme-buttons {\r\n display: flex;\r\n gap: 12px;\r\n flex-wrap: wrap;\r\n }\r\n \r\n .theme-btn {\r\n padding: 8px 16px;\r\n border-radius: 8px;\r\n font-size: 14px;\r\n font-weight: 500;\r\n border: none;\r\n cursor: pointer;\r\n transition: all 0.2s ease;\r\n background: #e0e0e0;\r\n color: #333;\r\n }\r\n \r\n .theme-btn:active {\r\n transform: scale(0.98);\r\n }\r\n \r\n .theme-btn.active {\r\n background: var(--color-secondary-surface);\r\n color: var(--color-secondary-content);\r\n }\r\n \r\n /* Logo Preview */\r\n .logo-preview {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 24px;\r\n background: var(--color-brand-secondary);\r\n border-radius: 12px;\r\n min-height: 80px;\r\n }\r\n \r\n .logomark-preview {\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n padding: 24px;\r\n background: white;\r\n border: 1px solid #e0e0e0;\r\n border-radius: 12px;\r\n min-height: 80px;\r\n }\r\n \r\n .preview-grid {\r\n display: grid;\r\n grid-template-columns: 1fr 1fr;\r\n gap: 16px;\r\n }\r\n \r\n .preview-tile {\r\n background: white;\r\n border-radius: 12px;\r\n }\r\n \r\n .preview-tile h3 {\r\n font-size: 13px;\r\n font-weight: 600;\r\n color: #666;\r\n margin-top: 0;\r\n margin-bottom: 12px;\r\n }\r\n \r\n /* App Icon Sizes */\r\n .app-icon-sizes {\r\n display: flex;\r\n gap: 24px;\r\n align-items: flex-end;\r\n justify-content: center;\r\n padding: 24px;\r\n background: white;\r\n border-radius: 12px;\r\n border: 1px solid var(--border-color-default, #e0e0e0);\r\n flex-wrap: wrap;\r\n }\r\n \r\n .app-icon-demo {\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n gap: 12px;\r\n /* Use app icon surface color as app icon background */\r\n --app-icon-background: var(--color-app-icon-surface);\r\n }\r\n \r\n .app-icon-demo span {\r\n font-size: 12px;\r\n color: #666;\r\n font-family: monospace;\r\n }\r\n \r\n /* Brand Colors */\r\n .color-section {\r\n background: white;\r\n border-radius: 12px;\r\n }\r\n \r\n .color-swatches {\r\n display: grid;\r\n grid-template-columns: 1fr 1fr;\r\n gap: 16px;\r\n margin-bottom: 24px;\r\n }\r\n \r\n .swatch {\r\n padding: 16px;\r\n border-radius: 8px;\r\n text-align: center;\r\n }\r\n \r\n .swatch-label {\r\n font-size: 12px;\r\n font-weight: 600;\r\n margin-bottom: 4px;\r\n }\r\n \r\n .swatch-value {\r\n font-size: 11px;\r\n opacity: 0.8;\r\n font-family: monospace;\r\n }\r\n \r\n .swatch--app-icon-surface {\r\n background: var(--color-app-icon-surface);\r\n color: var(--color-app-icon-content);\r\n }\r\n \r\n .swatch--app-icon-content {\r\n background: var(--color-app-icon-content);\r\n color: var(--color-app-icon-surface);\r\n border: 1px solid #e0e0e0;\r\n }\r\n \r\n .swatch--accent {\r\n background: var(--color-accent);\r\n color: var(--color-on-accent);\r\n }\r\n \r\n .swatch--on-accent {\r\n background: var(--color-on-accent);\r\n color: var(--color-accent);\r\n border: 1px solid #e0e0e0;\r\n }\r\n \r\n .swatch--header-surface {\r\n background: var(--color-header-surface);\r\n color: var(--color-header-content);\r\n }\r\n \r\n .swatch--header-content {\r\n background: var(--color-header-content);\r\n color: var(--color-header-surface);\r\n border: 1px solid #e0e0e0;\r\n }\r\n \r\n /* Color Inputs */\r\n .color-inputs {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n }\r\n \r\n .color-group-label {\r\n font-size: 13px;\r\n font-weight: 600;\r\n color: #333;\r\n margin-top: 8px;\r\n }\r\n \r\n .color-row {\r\n display: flex;\r\n align-items: center;\r\n gap: 12px;\r\n }\r\n \r\n .color-row label {\r\n min-width: 70px;\r\n font-size: 13px;\r\n color: #666;\r\n }\r\n \r\n .color-row input[type=\"color\"] {\r\n width: 40px;\r\n height: 32px;\r\n border: none;\r\n border-radius: 6px;\r\n cursor: pointer;\r\n padding: 0;\r\n }\r\n \r\n .color-row input[type=\"text\"] {\r\n flex: 1;\r\n padding: 8px 12px;\r\n border: 1px solid #ddd;\r\n border-radius: 6px;\r\n font-family: monospace;\r\n font-size: 13px;\r\n }\r\n\r\n /* Toggle switch styling */\r\n .toggle-row {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 12px;\r\n padding: 12px 0;\r\n }\r\n \r\n .toggle-row label {\r\n font-size: 14px;\r\n color: #333;\r\n font-weight: 500;\r\n }\r\n \r\n .toggle-row input[type=\"checkbox\"] {\r\n width: 48px;\r\n height: 28px;\r\n -webkit-appearance: none;\r\n appearance: none;\r\n background: #ddd;\r\n border-radius: 14px;\r\n position: relative;\r\n cursor: pointer;\r\n transition: background 0.2s ease;\r\n flex-shrink: 0;\r\n }\r\n \r\n .toggle-row input[type=\"checkbox\"]:checked {\r\n background: var(--color-accent);\r\n }\r\n \r\n .toggle-row input[type=\"checkbox\"]::before {\r\n content: '';\r\n position: absolute;\r\n width: 24px;\r\n height: 24px;\r\n border-radius: 50%;\r\n background: white;\r\n top: 2px;\r\n left: 2px;\r\n transition: transform 0.2s ease;\r\n box-shadow: 0 1px 3px rgba(0, 0, 0, 0.2);\r\n }\r\n \r\n .toggle-row input[type=\"checkbox\"]:checked::before {\r\n transform: translateX(20px);\r\n }\r\n\r\n /* Radio button styling */\r\n .radio-group {\r\n display: flex;\r\n gap: 16px;\r\n margin-bottom: 16px;\r\n }\r\n \r\n .radio-option {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n cursor: pointer;\r\n }\r\n \r\n .radio-option input[type=\"radio\"] {\r\n width: 18px;\r\n height: 18px;\r\n cursor: pointer;\r\n accent-color: var(--color-accent);\r\n }\r\n \r\n .radio-option label {\r\n font-size: 14px;\r\n color: #333;\r\n cursor: pointer;\r\n font-weight: 500;\r\n }\r\n\r\n /* Background preview */\r\n .bg-preview {\r\n height: 80px;\r\n border-radius: 8px;\r\n margin-bottom: 16px;\r\n border: 1px solid #e0e0e0;\r\n position: relative;\r\n overflow: hidden;\r\n }\r\n \r\n .bg-preview::after {\r\n content: 'Preview';\r\n position: absolute;\r\n top: 50%;\r\n left: 50%;\r\n transform: translate(-50%, -50%);\r\n font-size: 12px;\r\n font-weight: 600;\r\n color: rgba(0, 0, 0, 0.3);\r\n text-shadow: 0 1px 2px rgba(255, 255, 255, 0.5);\r\n }\r\n\r\n /* Safe area support */\r\n @supports (padding: env(safe-area-inset-bottom)) {\r\n .demo-container {\r\n padding-bottom: calc(20px + env(safe-area-inset-bottom));\r\n }\r\n }\r\n `],\r\n template: `\r\n <!-- Fixed Header -->\r\n <div class=\"modal-header\">\r\n <div class=\"header-content\">\r\n <span class=\"header-title\">Whitelabel</span>\r\n <ds-icon-button\r\n icon=\"remixCloseLine\"\r\n variant=\"secondary\"\r\n size=\"lg\"\r\n (click)=\"close()\"\r\n class=\"close-button\"\r\n aria-label=\"Close\">\r\n </ds-icon-button>\r\n </div>\r\n </div>\r\n \r\n <!-- Scrollable Content -->\r\n <ion-content [scrollY]=\"true\" class=\"modal-content\">\r\n <div class=\"demo-container\">\r\n <!-- Theme Selection -->\r\n <div class=\"demo-section\">\r\n <h2>Theme</h2>\r\n <div class=\"theme-buttons\">\r\n <button class=\"theme-btn\" (click)=\"applyDefaultTheme()\" [class.active]=\"currentTheme === 'default'\">\r\n Propbinder\r\n </button>\r\n <button class=\"theme-btn\" (click)=\"applyCejTheme()\" [class.active]=\"currentTheme === 'cej'\">\r\n CEJ\r\n </button>\r\n <button class=\"theme-btn\" (click)=\"applyPkaTheme()\" [class.active]=\"currentTheme === 'pka'\">\r\n PKA\r\n </button>\r\n <button class=\"theme-btn\" (click)=\"applyClaveTheme()\" [class.active]=\"currentTheme === 'clave'\">\r\n Clave\r\n </button>\r\n <button class=\"theme-btn\" (click)=\"applyFreedomTheme()\" [class.active]=\"currentTheme === 'freedom'\">\r\n Freedom\r\n </button>\r\n <button class=\"theme-btn\" (click)=\"applyCobblestoneTheme()\" [class.active]=\"currentTheme === 'cobblestone'\">\r\n Cobblestone\r\n </button>\r\n </div>\r\n </div>\r\n \r\n <!-- Sign-in Page Options -->\r\n <div class=\"demo-section\">\r\n <h2>Sign-in Page</h2>\r\n <div class=\"color-section\">\r\n <div class=\"toggle-row\">\r\n <label>Show City Illustration</label>\r\n <input\r\n type=\"checkbox\"\r\n [checked]=\"whitelabelService.showCityIllustration()\"\r\n [disabled]=\"currentTheme !== 'default'\"\r\n (change)=\"toggleCityIllustration()\"\r\n [style.opacity]=\"currentTheme !== 'default' ? '0.5' : '1'\"\r\n [style.cursor]=\"currentTheme !== 'default' ? 'not-allowed' : 'pointer'\"\r\n />\r\n </div>\r\n \r\n <div style=\"margin-top: 24px;\">\r\n <h3 style=\"font-size: 14px; font-weight: 600; color: #333; margin: 0 0 12px 0;\">Background</h3>\r\n \r\n <!-- Background type selector -->\r\n <div class=\"radio-group\">\r\n <div class=\"radio-option\">\r\n <input \r\n type=\"radio\" \r\n id=\"bg-solid\"\r\n name=\"bgType\"\r\n value=\"solid\"\r\n [checked]=\"whitelabelService.signInBgType() === 'solid'\"\r\n (change)=\"updateSignInBgType('solid')\"\r\n />\r\n <label for=\"bg-solid\">Solid</label>\r\n </div>\r\n <div class=\"radio-option\">\r\n <input \r\n type=\"radio\" \r\n id=\"bg-gradient\"\r\n name=\"bgType\"\r\n value=\"gradient\"\r\n [checked]=\"whitelabelService.signInBgType() === 'gradient'\"\r\n (change)=\"updateSignInBgType('gradient')\"\r\n />\r\n <label for=\"bg-gradient\">Gradient</label>\r\n </div>\r\n </div>\r\n \r\n <!-- Background preview -->\r\n <div class=\"bg-preview\" [style.background]=\"whitelabelService.signInBgStyle()\"></div>\r\n \r\n <!-- Solid color input -->\r\n @if (whitelabelService.signInBgType() === 'solid') {\r\n <div class=\"color-row\">\r\n <label>Color</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customSignInBgSolid\"\r\n (change)=\"applySignInBackground()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customSignInBgSolid\"\r\n (change)=\"applySignInBackground()\"\r\n />\r\n </div>\r\n }\r\n \r\n <!-- Gradient color inputs -->\r\n @if (whitelabelService.signInBgType() === 'gradient') {\r\n <div class=\"color-row\">\r\n <label>Start</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customSignInBgGradientStart\"\r\n (change)=\"applySignInBackground()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customSignInBgGradientStart\"\r\n (change)=\"applySignInBackground()\"\r\n />\r\n </div>\r\n <div class=\"color-row\">\r\n <label>End</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customSignInBgGradientEnd\"\r\n (change)=\"applySignInBackground()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customSignInBgGradientEnd\"\r\n (change)=\"applySignInBackground()\"\r\n />\r\n </div>\r\n }\r\n \r\n <!-- Sign-in content color -->\r\n <div style=\"margin-top: 24px;\">\r\n <h3 style=\"font-size: 14px; font-weight: 600; color: #333; margin: 0 0 12px 0;\">Content Color</h3>\r\n <div class=\"color-row\">\r\n <label>Text</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customSignInContentColor\"\r\n (change)=\"applySignInContentColor()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customSignInContentColor\"\r\n (change)=\"applySignInContentColor()\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Logo & Logomark Preview -->\r\n <div class=\"demo-section\">\r\n <h2>Logo Preview</h2>\r\n \r\n <!-- Logo Size Selector -->\r\n <div style=\"margin-bottom: 16px;\">\r\n <h3 style=\"font-size: 14px; font-weight: 600; color: #333; margin: 0 0 12px 0;\">Header Logo Size</h3>\r\n <div class=\"theme-buttons\">\r\n <button\r\n class=\"theme-btn\"\r\n (click)=\"updateLogoSize('sm')\"\r\n [class.active]=\"whitelabelService.logoSize() === 'sm'\">\r\n Small (24px)\r\n </button>\r\n <button\r\n class=\"theme-btn\"\r\n (click)=\"updateLogoSize('md')\"\r\n [class.active]=\"whitelabelService.logoSize() === 'md'\">\r\n Medium (28px)\r\n </button>\r\n <button\r\n class=\"theme-btn\"\r\n (click)=\"updateLogoSize('lg')\"\r\n [class.active]=\"whitelabelService.logoSize() === 'lg'\">\r\n Large (32px)\r\n </button>\r\n <button\r\n class=\"theme-btn\"\r\n (click)=\"updateLogoSize('xl')\"\r\n [class.active]=\"whitelabelService.logoSize() === 'xl'\">\r\n XLarge (36px)\r\n </button>\r\n </div>\r\n </div>\r\n \r\n <div class=\"preview-grid\">\r\n <div class=\"preview-tile\">\r\n <h3>Logo</h3>\r\n <div class=\"logo-preview\">\r\n <ds-logo variant=\"full\" />\r\n </div>\r\n </div>\r\n <div class=\"preview-tile\">\r\n <h3>Logomark</h3>\r\n <div class=\"logomark-preview\">\r\n <ds-avatar-with-badge\r\n [type]=\"'initials'\"\r\n [initials]=\"'KN'\"\r\n [size]=\"'md'\"\r\n [badgePosition]=\"'bottom-right'\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- App Icon -->\r\n <div class=\"demo-section\">\r\n <h2>App Icon</h2>\r\n <div class=\"app-icon-sizes\">\r\n <div class=\"app-icon-demo\">\r\n <ds-app-icon size=\"xl\" />\r\n </div>\r\n </div>\r\n </div>\r\n \r\n <!-- Brand Colors -->\r\n <div class=\"demo-section\">\r\n <h2>Brand Colors</h2>\r\n <div class=\"color-section\">\r\n <div class=\"color-swatches\">\r\n <div class=\"swatch swatch--app-icon-surface\">\r\n <div class=\"swatch-label\">App Icon Surface</div>\r\n <div class=\"swatch-value\">{{ whitelabelService.appIconSurface() }}</div>\r\n </div>\r\n <div class=\"swatch swatch--app-icon-content\">\r\n <div class=\"swatch-label\">App Icon Content</div>\r\n <div class=\"swatch-value\">{{ whitelabelService.appIconContent() }}</div>\r\n </div>\r\n <div class=\"swatch swatch--accent\">\r\n <div class=\"swatch-label\">Accent</div>\r\n <div class=\"swatch-value\">{{ whitelabelService.accent() }}</div>\r\n </div>\r\n <div class=\"swatch swatch--on-accent\">\r\n <div class=\"swatch-label\">On Accent</div>\r\n <div class=\"swatch-value\">{{ whitelabelService.onAccent() }}</div>\r\n </div>\r\n <div class=\"swatch swatch--header-surface\">\r\n <div class=\"swatch-label\">Header Surface</div>\r\n <div class=\"swatch-value\">{{ whitelabelService.headerSurface() }}</div>\r\n </div>\r\n <div class=\"swatch swatch--header-content\">\r\n <div class=\"swatch-label\">Header Content</div>\r\n <div class=\"swatch-value\">{{ whitelabelService.headerContent() }}</div>\r\n </div>\r\n </div>\r\n \r\n <div class=\"color-inputs\">\r\n <div class=\"color-group-label\">App Icon</div>\r\n <div class=\"color-row\">\r\n <label>Surface</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customAppIconSurface\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customAppIconSurface\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n </div>\r\n <div class=\"color-row\">\r\n <label>Content</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customAppIconContent\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customAppIconContent\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n </div>\r\n \r\n <div class=\"color-group-label\">Accent</div>\r\n <div class=\"color-row\">\r\n <label>Base</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customAccent\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customAccent\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n </div>\r\n <div class=\"color-row\">\r\n <label>On Accent</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customOnAccent\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customOnAccent\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n </div>\r\n \r\n <div class=\"color-group-label\">Header</div>\r\n <div class=\"color-row\">\r\n <label>Surface</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customHeaderSurface\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customHeaderSurface\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n </div>\r\n <div class=\"color-row\">\r\n <label>Content</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customHeaderContent\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customHeaderContent\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n </div>\r\n <div class=\"color-row\">\r\n <label>Accent</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customHeaderAccent\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customHeaderAccent\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n </div>\r\n <div class=\"color-row\">\r\n <label>On Accent</label>\r\n <input \r\n type=\"color\" \r\n [(ngModel)]=\"customOnHeaderAccent\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n <input \r\n type=\"text\" \r\n [(ngModel)]=\"customOnHeaderAccent\"\r\n (change)=\"applyCustomColors()\"\r\n />\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ion-content>\r\n `\r\n})\r\nexport class WhitelabelDemoModalComponent implements OnInit {\r\n whitelabelService = inject(WhitelabelService);\r\n \r\n private modalController = inject(ModalController);\r\n \r\n // Current active theme\r\n currentTheme = 'default';\r\n \r\n // Custom color inputs\r\n customAppIconSurface = '#6B5FF5';\r\n customAppIconContent = '#FFFFFF';\r\n customAccent = '#6B5FF5';\r\n customOnAccent = '#FFFFFF';\r\n customHeaderSurface = '#221a4c';\r\n customHeaderContent = '#FFFFFF';\r\n customHeaderAccent = 'rgba(255, 255, 255, 0.15)';\r\n customOnHeaderAccent = '#FFFFFF';\r\n \r\n // Sign-in background inputs\r\n customSignInBgSolid = '#D6C7FF';\r\n customSignInBgGradientStart = '#D6C7FF';\r\n customSignInBgGradientEnd = '#8A9BFF';\r\n customSignInContentColor = '#1a1a1a';\r\n \r\n ngOnInit() {\r\n this.updateCustomColorInputs();\r\n this.updateSignInBgInputs();\r\n this.updateSignInContentColorInput();\r\n this.detectCurrentTheme();\r\n }\r\n \r\n /**\r\n * Detect the current active theme based on colors\r\n */\r\n private detectCurrentTheme() {\r\n const headerSurface = this.whitelabelService.headerSurface().toUpperCase();\r\n \r\n if (headerSurface === '#A70923') {\r\n this.currentTheme = 'cej';\r\n } else if (headerSurface === '#660036') {\r\n this.currentTheme = 'pka';\r\n } else if (headerSurface === '#262424') {\r\n this.currentTheme = 'clave';\r\n } else if (headerSurface === '#1D4A49') {\r\n this.currentTheme = 'freedom';\r\n } else if (headerSurface === '#2C3E50') {\r\n this.currentTheme = 'cobblestone';\r\n } else {\r\n this.currentTheme = 'default';\r\n }\r\n }\r\n \r\n /**\r\n * Close the modal\r\n */\r\n close(): void {\r\n this.modalController.dismiss();\r\n }\r\n \r\n applyDefaultTheme() {\r\n this.currentTheme = 'default';\r\n this.whitelabelService.updateConfig({\r\n logoUrl: '/Assets/logos/propbinder-logomark.svg',\r\n logoMarkUrl: '/Assets/logos/propbinder-logomark.svg',\r\n logoAlt: 'Propbinder',\r\n logoSize: 'md',\r\n appIconSurface: '#6B5FF5',\r\n appIconContent: '#FFFFFF',\r\n accent: '#6B5FF5',\r\n onAccent: '#FFFFFF',\r\n headerSurface: '#221a4c',\r\n headerContent: '#FFFFFF',\r\n headerAccent: '#6B5FF5',\r\n onHeaderAccent: '#FFFFFF',\r\n showCityIllustration: true,\r\n signInBgType: 'gradient',\r\n signInBgSolid: '#D6C7FF',\r\n signInBgGradientStart: '#D6C7FF',\r\n signInBgGradientEnd: '#8A9BFF',\r\n signInContentColor: '#1a1a1a',\r\n organizationName: 'Propbinder',\r\n organizationId: 'default'\r\n });\r\n this.updateCustomColorInputs();\r\n this.updateSignInBgInputs();\r\n this.updateSignInContentColorInput();\r\n }\r\n \r\n applyCejTheme() {\r\n this.currentTheme = 'cej';\r\n this.whitelabelService.updateConfig({\r\n logoUrl: '/Assets/logos/cej-logo.png',\r\n logoMarkUrl: '/Assets/logos/cej-logo.png',\r\n logoAlt: 'CEJ',\r\n logoSize: 'xl',\r\n appIconSurface: '#A70923',\r\n appIconContent: '#FFFFFF',\r\n accent: '#dc092c',\r\n onAccent: '#FFFFFF',\r\n headerSurface: '#A70923',\r\n headerContent: '#FFFFFF',\r\n headerAccent: '#dc092c',\r\n onHeaderAccent: '#FFFFFF',\r\n showCityIllustration: false,\r\n signInBgType: 'gradient',\r\n signInBgSolid: '#FFE5E8',\r\n signInBgGradientStart: '#FFE5E8',\r\n signInBgGradientEnd: '#FFC7CE',\r\n signInContentColor: '#1a1a1a',\r\n organizationName: 'CEJ',\r\n organizationId: 'cej'\r\n });\r\n this.updateCustomColorInputs();\r\n this.updateSignInBgInputs();\r\n this.updateSignInContentColorInput();\r\n }\r\n \r\n applyPkaTheme() {\r\n this.currentTheme = 'pka';\r\n this.whitelabelService.updateConfig({\r\n logoUrl: '/Assets/logos/pka-logo.svg',\r\n logoMarkUrl: '/Assets/logos/pka-logo.svg',\r\n logoAlt: 'PKA',\r\n logoSize: 'md',\r\n appIconSurface: '#CC006C',\r\n appIconContent: '#FFFFFF',\r\n accent: '#CC006C',\r\n onAccent: '#FFFFFF',\r\n headerSurface: '#660036',\r\n headerContent: '#FFFFFF',\r\n headerAccent: '#CC006C',\r\n onHeaderAccent: '#FFFFFF',\r\n showCityIllustration: false,\r\n signInBgType: 'gradient',\r\n signInBgSolid: '#FFE0F0',\r\n signInBgGradientStart: '#FFE0F0',\r\n signInBgGradientEnd: '#FFB3D9',\r\n signInContentColor: '#1a1a1a',\r\n organizationName: 'PKA',\r\n organizationId: 'pka'\r\n });\r\n this.updateCustomColorInputs();\r\n this.updateSignInBgInputs();\r\n this.updateSignInContentColorInput();\r\n }\r\n \r\n applyClaveTheme() {\r\n this.currentTheme = 'clave';\r\n this.whitelabelService.updateConfig({\r\n logoUrl: '/Assets/logos/clave-logo.svg',\r\n logoMarkUrl: '/Assets/logos/clave-logo.svg',\r\n logoAlt: 'Clave',\r\n logoSize: 'lg',\r\n appIconSurface: '#262424',\r\n appIconContent: '#FFFFFF',\r\n accent: '#868764',\r\n onAccent: '#FFFFFF',\r\n headerSurface: '#262424',\r\n headerContent: '#FFFFFF',\r\n headerAccent: '#868764',\r\n onHeaderAccent: '#FFFFFF',\r\n showCityIllustration: false,\r\n signInBgType: 'gradient',\r\n signInBgSolid: '#E8E8E0',\r\n signInBgGradientStart: '#E8E8E0',\r\n signInBgGradientEnd: '#D4D4C3',\r\n signInContentColor: '#1a1a1a',\r\n organizationName: 'Clave',\r\n organizationId: 'clave'\r\n });\r\n this.updateCustomColorInputs();\r\n this.updateSignInBgInputs();\r\n this.updateSignInContentColorInput();\r\n }\r\n \r\n applyFreedomTheme() {\r\n this.currentTheme = 'freedom';\r\n this.whitelabelService.updateConfig({\r\n logoUrl: '/Assets/logos/freedom-logo.svg',\r\n logoMarkUrl: '/Assets/logos/freedom-logomark.svg',\r\n logoAlt: 'Freedom',\r\n logoSize: 'md',\r\n appIconSurface: '#1D4A49',\r\n appIconContent: '#FFFFFF',\r\n accent: '#1D4A49',\r\n onAccent: '#FFFFFF',\r\n headerSurface: '#1D4A49',\r\n headerContent: '#FFFFFF',\r\n headerAccent: '#AACFC3',\r\n onHeaderAccent: '#1D4A49',\r\n showCityIllustration: false,\r\n signInBgType: 'gradient',\r\n signInBgSolid: '#D5E8E6',\r\n signInBgGradientStart: '#D5E8E6',\r\n signInBgGradientEnd: '#AACFC3',\r\n signInContentColor: '#FFFFFF',\r\n organizationName: 'Freedom',\r\n organizationId: 'freedom'\r\n });\r\n this.updateCustomColorInputs();\r\n this.updateSignInBgInputs();\r\n this.updateSignInContentColorInput();\r\n }\r\n \r\n applyCobblestoneTheme() {\r\n this.currentTheme = 'cobblestone';\r\n this.whitelabelService.updateConfig({\r\n logoUrl: '/Assets/logos/cobblestone-logo.svg',\r\n logoMarkUrl: '/Assets/logos/cobblestone-logomark.svg',\r\n logoAlt: 'Cobblestone',\r\n logoSize: 'sm',\r\n appIconSurface: '#2C3E50',\r\n appIconContent: '#FFFFFF',\r\n accent: '#3498DB',\r\n onAccent: '#FFFFFF',\r\n headerSurface: '#2C3E50',\r\n headerContent: '#FFFFFF',\r\n headerAccent: '#3498DB',\r\n onHeaderAccent: '#FFFFFF',\r\n showCityIllustration: false,\r\n signInBgType: 'gradient',\r\n signInBgSolid: '#E8EEF2',\r\n signInBgGradientStart: '#E8EEF2',\r\n signInBgGradientEnd: '#BDC3C7',\r\n signInContentColor: '#1a1a1a',\r\n organizationName: 'Cobblestone',\r\n organizationId: 'cobblestone'\r\n });\r\n this.updateCustomColorInputs();\r\n this.updateSignInBgInputs();\r\n this.updateSignInContentColorInput();\r\n }\r\n \r\n applyCustomColors() {\r\n this.whitelabelService.updateColors({\r\n appIconSurface: this.customAppIconSurface,\r\n appIconContent: this.customAppIconContent,\r\n accent: this.customAccent,\r\n onAccent: this.customOnAccent,\r\n headerSurface: this.customHeaderSurface,\r\n headerContent: this.customHeaderContent,\r\n headerAccent: this.customHeaderAccent,\r\n onHeaderAccent: this.customOnHeaderAccent\r\n });\r\n }\r\n \r\n toggleCityIllustration() {\r\n this.whitelabelService.updateConfig({\r\n showCityIllustration: !this.whitelabelService.showCityIllustration()\r\n });\r\n }\r\n \r\n updateSignInBgType(type: 'solid' | 'gradient') {\r\n this.whitelabelService.updateConfig({\r\n signInBgType: type\r\n });\r\n }\r\n \r\n updateLogoSize(size: 'sm' | 'md' | 'lg' | 'xl') {\r\n this.whitelabelService.updateConfig({\r\n logoSize: size,\r\n logoHeight: undefined // Clear custom height to use size-based calculation\r\n });\r\n }\r\n \r\n applySignInBackground() {\r\n this.whitelabelService.updateConfig({\r\n signInBgSolid: this.customSignInBgSolid,\r\n signInBgGradientStart: this.customSignInBgGradientStart,\r\n signInBgGradientEnd: this.customSignInBgGradientEnd\r\n });\r\n }\r\n \r\n applySignInContentColor() {\r\n this.whitelabelService.updateConfig({\r\n signInContentColor: this.customSignInContentColor\r\n });\r\n }\r\n \r\n private updateSignInBgInputs() {\r\n this.customSignInBgSolid = this.whitelabelService.signInBgSolid();\r\n this.customSignInBgGradientStart = this.whitelabelService.signInBgGradientStart();\r\n this.customSignInBgGradientEnd = this.whitelabelService.signInBgGradientEnd();\r\n }\r\n \r\n private updateSignInContentColorInput() {\r\n this.customSignInContentColor = this.whitelabelService.signInContentColor();\r\n }\r\n \r\n private updateCustomColorInputs() {\r\n this.customAppIconSurface = this.whitelabelService.appIconSurface();\r\n this.customAppIconContent = this.whitelabelService.appIconContent();\r\n this.customAccent = this.whitelabelService.accent();\r\n this.customOnAccent = this.whitelabelService.onAccent();\r\n this.customHeaderSurface = this.whitelabelService.headerSurface();\r\n this.customHeaderContent = this.whitelabelService.headerContent();\r\n this.customHeaderAccent = this.whitelabelService.headerAccent();\r\n this.customOnHeaderAccent = this.whitelabelService.onHeaderAccent();\r\n }\r\n}\r\n\r\n","import { Injectable } from '@angular/core';\r\nimport { ModalController } from '@ionic/angular/standalone';\r\nimport { WhitelabelDemoModalComponent } from './whitelabel-demo-modal.component';\r\n\r\n/**\r\n * WhitelabelDemoModalService\r\n *\r\n * Service for displaying the whitelabel demo in a full-screen modal.\r\n * Built on Ionic's modal system with native gestures and animations.\r\n *\r\n * @example\r\n * ```typescript\r\n * constructor(private whitelabelModal: WhitelabelDemoModalService) {}\r\n *\r\n * async openDemo() {\r\n * await this.whitelabelModal.open();\r\n * }\r\n * ```\r\n */\r\n@Injectable({\r\n providedIn: 'root',\r\n})\r\nexport class WhitelabelDemoModalService {\r\n constructor(private modalController: ModalController) {}\r\n\r\n /**\r\n * Open the whitelabel demo modal\r\n *\r\n * @returns Promise that resolves when the modal is presented\r\n */\r\n async open(): Promise<void> {\r\n try {\r\n // console.log('[WhitelabelDemoModal] Opening...');\r\n\r\n const modal = await this.modalController.create({\r\n component: WhitelabelDemoModalComponent,\r\n cssClass: 'ds-whitelabel-demo-modal',\r\n mode: 'ios',\r\n presentingElement:\r\n document.querySelector('ion-router-outlet') || undefined,\r\n backdropDismiss: true,\r\n showBackdrop: true,\r\n animated: true,\r\n keyboardClose: true,\r\n // Control the presenting element animation\r\n enterAnimation: undefined, // Use default\r\n leaveAnimation: undefined, // Use default\r\n });\r\n\r\n // console.log('[WhitelabelDemoModal] Modal created, presenting...');\r\n await modal.present();\r\n // console.log('[WhitelabelDemoModal] Modal presented');\r\n } catch (error) {\r\n // console.error('[WhitelabelDemoModal] Error opening modal:', error);\r\n throw error;\r\n }\r\n }\r\n\r\n /**\r\n * Close the currently open whitelabel demo modal\r\n *\r\n * @param data Optional data to pass back when dismissing\r\n * @returns Promise that resolves when the modal is dismissed\r\n */\r\n async close(data?: any): Promise<boolean> {\r\n return this.modalController.dismiss(data);\r\n }\r\n\r\n /**\r\n * Get the top-most modal if one exists\r\n *\r\n * @returns Promise that resolves to the modal element or undefined\r\n */\r\n async getTop(): Promise<HTMLIonModalElement | undefined> {\r\n return this.modalController.getTop();\r\n }\r\n}\r\n","import { Component, OnInit, computed, effect, inject } from '@angular/core';\r\nimport { Router } from '@angular/router';\r\nimport { CommonModule } from '@angular/common';\r\nimport { IonTabs } from '@ionic/angular/standalone';\r\nimport { UserService } from '../services/user.service';\r\nimport { DsMobileTabBarComponent, TabConfig } from '../components/tab-bar';\r\nimport { ActionResult, ActionGroup } from '../components/bottom-sheet';\r\nimport { WhitelabelDemoModalService } from './whitelabel-demo-modal.service';\r\nimport { TrackingPermissionService } from '../services/tracking-permission.service';\r\n\r\n/**\r\n * MobileTabsExampleComponent\r\n *\r\n * Example page using the TenantApp pattern:\r\n * - Uses ion-tabs as wrapper (required for Angular routing)\r\n * - Uses ds-mobile-tab-bar inside (not ds-mobile-tabs)\r\n *\r\n * This matches the pattern used in TenantApp for consistency.\r\n */\r\n@Component({\r\n selector: 'app-mobile-tabs-example',\r\n standalone: true,\r\n imports: [CommonModule, IonTabs, DsMobileTabBarComponent],\r\n styles: [\r\n `\r\n :host {\r\n display: block;\r\n height: 100dvh;\r\n width: 100vw;\r\n position: relative;\r\n }\r\n `,\r\n ],\r\n template: `\r\n <ion-tabs class=\"ds-tabs-wrapper\">\r\n <!-- Tab bar with slot=\"top\" on desktop, slot=\"bottom\" on mobile -->\r\n <!-- Ionic automatically creates ion-tab elements from child routes -->\r\n <ds-mobile-tab-bar\r\n [tabs]=\"tabs\"\r\n [avatarInitials]=\"userService.avatarInitials()\"\r\n [avatarType]=\"userService.avatarType()\"\r\n [profileMenuItems]=\"profileMenuItems\"\r\n (profileActionSelected)=\"handleProfileAction($event)\"\r\n >\r\n </ds-mobile-tab-bar>\r\n </ion-tabs>\r\n `,\r\n})\r\nexport class MobileTabsExampleComponent implements OnInit {\r\n private whitelabelDemoModal = inject(WhitelabelDemoModalService);\r\n private trackingPermissionService = inject(TrackingPermissionService);\r\n private trackedProfileMenuItems = computed<ActionGroup[]>(() => {\r\n const accountActions = [\r\n {\r\n action: 'profile',\r\n title: 'Min profil',\r\n icon: 'remixUser3Line',\r\n destructive: false,\r\n },\r\n {\r\n action: 'settings',\r\n title: 'Indstillinger',\r\n icon: 'remixSettings3Line',\r\n destructive: false,\r\n },\r\n {\r\n action: 'appearance',\r\n title: 'Udseende',\r\n icon: 'remixPaletteLine',\r\n destructive: false,\r\n },\r\n ];\r\n\r\n if (this.trackingPermissionService.shouldShowSettingsReminder()) {\r\n accountActions.push({\r\n action: 'tracking-settings',\r\n title: 'Sporingsindstillinger',\r\n icon: 'remixSettings3Line',\r\n destructive: false,\r\n });\r\n }\r\n\r\n return [\r\n {\r\n actions: accountActions,\r\n },\r\n {\r\n actions: [\r\n {\r\n action: 'language',\r\n title: 'Sprog',\r\n subtitle: 'Dansk',\r\n flagIcon: '/Assets/country-flags/denmark.svg',\r\n icon: 'remixGlobalLine',\r\n destructive: false,\r\n showChevron: true,\r\n },\r\n ],\r\n },\r\n {\r\n actions: [\r\n {\r\n action: 'logout',\r\n title: 'Log ud',\r\n icon: 'remixLogoutBoxLine',\r\n destructive: true,\r\n },\r\n ],\r\n },\r\n ];\r\n });\r\n\r\n constructor(\r\n public userService: UserService,\r\n private router: Router,\r\n ) {\r\n console.log('MobileTabsExampleComponent constructor');\r\n effect(() => {\r\n this.userService.setProfileMenuItems(this.trackedProfileMenuItems());\r\n });\r\n }\r\n\r\n ngOnInit() {\r\n console.log('MobileTabsExampleComponent ngOnInit');\r\n // Configure user avatar globally - this is now the single source of truth\r\n this.userService.setAvatarInitials('LM');\r\n this.userService.setAvatarType('initials');\r\n\r\n // Initial status refresh ensures menu reflects past ATT choice.\r\n void this.trackingPermissionService.refreshTrackingStatus();\r\n }\r\n\r\n tabs: TabConfig[] = [\r\n {\r\n id: 'home',\r\n label: 'Hjem',\r\n route: 'home',\r\n icon: 'remixHomeSmile2Line',\r\n iconActive: 'remixHomeSmile2Fill',\r\n },\r\n {\r\n id: 'inquiries',\r\n label: 'Henvendelser',\r\n route: 'inquiries',\r\n icon: 'remixFileList3Line',\r\n iconActive: 'remixFileList3Fill',\r\n },\r\n {\r\n id: 'announcements',\r\n label: 'Fællesskab',\r\n route: 'announcements',\r\n icon: 'remixCommunityLine',\r\n iconActive: 'remixCommunityFill',\r\n },\r\n {\r\n id: 'booking',\r\n label: 'Booking',\r\n route: 'booking',\r\n icon: 'remixCalendarCheckLine',\r\n iconActive: 'remixCalendarCheckFill',\r\n },\r\n {\r\n id: 'handbook',\r\n label: 'Håndbog',\r\n route: 'handbook',\r\n icon: 'remixBook2Line',\r\n iconActive: 'remixBook2Fill',\r\n },\r\n ];\r\n\r\n /**\r\n * Profile menu items configuration.\r\n * Define once here - this is set globally in UserService in ngOnInit(),\r\n * so it will be used by both ds-mobile-tab-bar and ds-mobile-page-main components\r\n * throughout the entire application.\r\n */\r\n get profileMenuItems(): ActionGroup[] {\r\n return this.trackedProfileMenuItems();\r\n }\r\n\r\n /**\r\n * Handle profile menu action selection.\r\n * The tab bar component handles the UI (opening/closing menu),\r\n * this method handles the business logic.\r\n *\r\n * NOTE: Desktop only - called directly from tab bar.\r\n * Mobile actions are handled globally in AppComponent via UserService.\r\n */\r\n handleProfileAction(result: ActionResult): void {\r\n console.log('Profile action selected (desktop tab bar):', result.action);\r\n\r\n // Handle appearance action here (opens modal)\r\n if (result.action === 'appearance') {\r\n console.log('Opening whitelabel demo...');\r\n // Small delay to ensure bottom sheet is fully dismissed\r\n setTimeout(async () => {\r\n try {\r\n await this.whitelabelDemoModal.open();\r\n } catch (error) {\r\n console.error('Failed to open whitelabel demo modal:', error);\r\n }\r\n }, 100);\r\n }\r\n\r\n // Notify globally so AppComponent can handle navigation\r\n this.userService.notifyProfileAction(result);\r\n }\r\n}\r\n","import { Component, signal, ViewChild } from '@angular/core';\r\nimport { DsIconButtonComponent } from '@propbinder/design-system';\r\nimport { DsMobilePageMainComponent } from '../components/page-main';\r\nimport { DsMobileSectionComponent } from '../components/section';\r\nimport { DsMobileSwiperComponent } from '../components/swiper/ds-mobile-swiper';\r\nimport { DsMobileInteractiveListItemBookingComponent } from '../components/interactive-list-item-booking';\r\nimport { DsMobileOfflineBannerComponent } from '../components/offline-banner';\r\nimport { DsMobileFacilityDetailModalService } from '../components/facility-detail-modal';\r\nimport { DsMobileFabComponent } from '../components/fab';\r\nimport { DsMobileFacilityCreationModalService } from '../components/facility-creation-modal';\r\nimport { UserService } from '../services/user.service';\r\n\r\ninterface FacilityDetail {\r\n id: string;\r\n thumbnail: string;\r\n facilityTitle: string;\r\n description: string;\r\n availabilityStatus?: 'available-today' | 'available-from' | 'unavailable';\r\n statusLabel?: string;\r\n \r\n // Additional fields for modal\r\n heroImage?: string;\r\n fullDescription: string;\r\n requirements?: string[];\r\n bookingType?: string;\r\n expectations?: string;\r\n restrictions?: string[];\r\n bookingDate?: string;\r\n bookingTime?: string;\r\n}\r\n\r\n@Component({\r\n selector: 'app-mobile-booking-page',\r\n standalone: true,\r\n imports: [\r\n DsMobilePageMainComponent,\r\n DsMobileSectionComponent,\r\n DsMobileInteractiveListItemBookingComponent,\r\n DsMobileSwiperComponent,\r\n DsIconButtonComponent,\r\n DsMobileOfflineBannerComponent,\r\n DsMobileFabComponent\r\n ],\r\n styles: [`\r\n /* Bookings swiper wrapper */\r\n .bookings-swiper-wrapper {\r\n padding: 0;\r\n position: relative;\r\n }\r\n \r\n /* Navigation buttons - position individually to avoid blocking */\r\n .swiper-nav-buttons {\r\n /* Remove all positioning - we'll position buttons individually */\r\n display: contents; /* Use contents to avoid creating a blocking layer */\r\n }\r\n \r\n .swiper-nav-button {\r\n position: absolute;\r\n top: 50%;\r\n transform: translateY(-50%);\r\n z-index: 10;\r\n }\r\n \r\n .swiper-nav-button:first-child {\r\n left: -48px;\r\n }\r\n \r\n .swiper-nav-button:last-child {\r\n right: -48px;\r\n }\r\n \r\n /* Force buttons to be perfectly round */\r\n ::ng-deep .swiper-nav-button button {\r\n border-radius: 50% !important;\r\n width: 48px !important;\r\n height: 48px !important;\r\n padding: 0 !important;\r\n }\r\n \r\n /* Hide on mobile */\r\n @media (max-width: 767px) {\r\n .swiper-nav-buttons {\r\n display: none;\r\n }\r\n }\r\n \r\n /* Swiper slide styling for bookings */\r\n ::ng-deep .bookings-swiper .swiper-slide {\r\n width: 100%;\r\n max-width: 600px;\r\n height: auto;\r\n pointer-events: auto;\r\n }\r\n \r\n /* Desktop: Remove max-width constraint */\r\n @media (min-width: 768px) {\r\n ::ng-deep .bookings-swiper .swiper-slide {\r\n max-width: 100%;\r\n }\r\n }\r\n \r\n /* Ensure list item takes full width within slide */\r\n ::ng-deep .bookings-swiper .swiper-slide ds-mobile-interactive-list-item-booking {\r\n width: 100%;\r\n pointer-events: auto;\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-page-main\r\n #pageComponent\r\n [title]=\"'Bookinger'\"\r\n [avatarInitials]=\"userService.avatarInitials()\"\r\n [avatarType]=\"userService.avatarType()\"\r\n (refresh)=\"handleRefresh($event)\">\r\n \r\n @if (pageComponent.isOffline()) {\r\n <ds-mobile-offline-banner\r\n header-notification\r\n title=\"Ingen internetforbindelse\"\r\n message=\"Nogle funktioner kan være utilgængelige\">\r\n </ds-mobile-offline-banner>\r\n }\r\n \r\n <!-- \"Dine bestillinger\" Section with Swiper -->\r\n <ds-mobile-section \r\n headline=\"Dine bestillinger\"\r\n icon=\"remixCheckboxCircleLine\">\r\n <div class=\"bookings-swiper-wrapper\">\r\n <ds-mobile-swiper \r\n #bookingsSwiper\r\n class=\"bookings-swiper\"\r\n [slideWidth]=\"'100%'\" \r\n [gap]=\"32\"\r\n [pagination]=\"true\"\r\n [autoHeight]=\"true\"\r\n [progressiveOpacity]=\"true\"\r\n [progressiveScale]=\"true\">\r\n @for (booking of activeBookings(); track booking.id) {\r\n <div class=\"swiper-slide\">\r\n <ds-mobile-interactive-list-item-booking\r\n [thumbnail]=\"booking.thumbnail\"\r\n [facilityTitle]=\"booking.facilityTitle\"\r\n [bookingDate]=\"booking.bookingDate || ''\"\r\n [bookingTime]=\"booking.bookingTime || ''\"\r\n [align]=\"'center'\"\r\n [clickable]=\"true\"\r\n [enableLongPress]=\"false\"\r\n [showChevron]=\"false\"\r\n (bookingClick)=\"openFacilityDetail(booking.id)\"\r\n />\r\n </div>\r\n }\r\n </ds-mobile-swiper>\r\n \r\n <!-- Navigation buttons (hidden on mobile or when only 1 item) -->\r\n @if (activeBookings().length > 1) {\r\n <div class=\"swiper-nav-buttons\">\r\n <ds-icon-button\r\n class=\"swiper-nav-button\"\r\n icon=\"remixArrowLeftSLine\"\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n [disabled]=\"isFirstSlide()\"\r\n (clicked)=\"slidePrev()\"\r\n aria-label=\"Previous booking\"\r\n />\r\n <ds-icon-button\r\n class=\"swiper-nav-button\"\r\n icon=\"remixArrowRightSLine\"\r\n variant=\"ghost\"\r\n size=\"sm\"\r\n [disabled]=\"isLastSlide()\"\r\n (clicked)=\"slideNext()\"\r\n aria-label=\"Next booking\"\r\n />\r\n </div>\r\n }\r\n </div>\r\n </ds-mobile-section>\r\n \r\n <!-- Available Facilities Section -->\r\n <ds-mobile-section headline=\"Tilgængelige faciliteter\" contentGap=\"0px\">\r\n @for (facility of availableFacilities(); track facility.id) {\r\n <ds-mobile-interactive-list-item-booking\r\n [thumbnail]=\"facility.thumbnail\"\r\n [facilityTitle]=\"facility.facilityTitle\"\r\n [description]=\"facility.description\"\r\n [availabilityStatus]=\"facility.availabilityStatus\"\r\n [statusLabel]=\"facility.statusLabel || ''\"\r\n [clickable]=\"true\"\r\n [enableLongPress]=\"false\"\r\n [showChevron]=\"false\"\r\n (bookingClick)=\"openFacilityDetail(facility.id)\"\r\n />\r\n }\r\n </ds-mobile-section>\r\n </ds-mobile-page-main>\r\n\r\n <!-- FAB for creating new facility -->\r\n <ds-mobile-fab\r\n icon=\"remixAddLine\"\r\n position=\"bottom-right\"\r\n ariaLabel=\"Opret facilitet\"\r\n (clicked)=\"openFacilityCreationModal()\">\r\n </ds-mobile-fab>\r\n `\r\n})\r\nexport class MobileBookingPageComponent {\r\n @ViewChild('pageComponent') pageComponent!: DsMobilePageMainComponent;\r\n @ViewChild('bookingsSwiper') bookingsSwiper?: DsMobileSwiperComponent;\r\n \r\n constructor(\r\n private facilityModal: DsMobileFacilityDetailModalService,\r\n private facilityCreationModal: DsMobileFacilityCreationModalService,\r\n public userService: UserService\r\n ) {}\r\n \r\n // Active bookings (current and upcoming)\r\n activeBookings = signal<FacilityDetail[]>([\r\n {\r\n id: 'booking-1',\r\n thumbnail: '/Assets/Dummy-photos/rooftop-party.jpg',\r\n facilityTitle: 'Festlokale på taget',\r\n bookingDate: '14. februar, 2026',\r\n bookingTime: '9:00 - 17:00',\r\n description: 'Din aktive booking af festlokalet på taget',\r\n heroImage: '/Assets/Dummy-photos/rooftop-party.jpg',\r\n 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>',\r\n requirements: ['Kræver nøglekort'],\r\n bookingType: 'Øjeblikkelig booking',\r\n expectations: '<p>Lokalet er klargjort med borde og stole ved ankomst. Husk at rydde op efter brug, så området er klar til de næste beboere.</p>',\r\n restrictions: [\r\n 'Maksimal bookingvarighed: 3 timer',\r\n 'Ingen høj musik efter kl. 22',\r\n 'Efterlad lokalet rent og opryddet'\r\n ]\r\n }\r\n ]);\r\n \r\n // Available facilities for booking\r\n availableFacilities = signal<FacilityDetail[]>([\r\n {\r\n id: 'facility-1',\r\n thumbnail: '/Assets/Dummy-photos/handyman.jpg',\r\n facilityTitle: 'Boremaskinen',\r\n description: 'Lån en boremaskine til mindre gør-det-selv-opgaver i boligen.',\r\n availabilityStatus: 'available-today',\r\n statusLabel: 'Ledig i dag',\r\n heroImage: '/Assets/Dummy-photos/handyman.jpg',\r\n fullDescription: '<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>',\r\n requirements: ['Kræver nøglekort'],\r\n bookingType: 'Øjeblikkelig booking',\r\n expectations: '<p>Boremaskinen udleveres med et sæt bor og tilbehør. Den er opladet og klar til brug. Returner værktøjet i rengjort stand efter brug.</p>',\r\n restrictions: [\r\n 'Maksimal bookingvarighed: 48 timer',\r\n 'Skal returneres i samme stand',\r\n 'Skader skal meldes med det samme',\r\n 'Må ikke bruges til kommercielt arbejde'\r\n ]\r\n },\r\n {\r\n id: 'facility-2',\r\n thumbnail: '/Assets/Dummy-photos/rooftop-party.jpg',\r\n facilityTitle: 'Festlokale på taget',\r\n description: 'Book det fælles festlokale på taget til fødselsdage, fejring og mindre arrangementer.',\r\n availabilityStatus: 'available-today',\r\n statusLabel: 'Ledig i dag',\r\n heroImage: '/Assets/Dummy-photos/rooftop-party.jpg',\r\n fullDescription: `\r\n <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>\r\n \r\n <h3 class=\"section-headline\">Hvad du kan forvente</h3>\r\n <p>Terrassen er møbleret med borde, stole og loungeområder, så den egner sig godt til sociale arrangementer, afslappet spisning eller en rolig pause. Sæsonens planter giver en indbydende stemning, og området har belysning til brug om aftenen. Terrassen er ikke en legeplads, og børn skal være under opsyn.</p>\r\n \r\n <h3 class=\"section-headline\">Restriktioner</h3>\r\n <ul>\r\n <li>Rygning og vaping er ikke tilladt på terrassen.</li>\r\n <li>Høj musik og fester over rimeligt lydniveau er ikke tilladt.</li>\r\n <li>Åben ild og stearinlys er ikke tilladt af sikkerhedshensyn.</li>\r\n <li>Private grill eller eget madudstyr må ikke anvendes; brug kun fælles faciliteter.</li>\r\n <li>Kæledyr er ikke tilladt på terrassen, undtaget servicehunde.</li>\r\n </ul>\r\n \r\n <h3 class=\"section-headline\">Sikkerhed og adfærd</h3>\r\n <p>For alles komfort og sikkerhed beder vi dig:</p>\r\n <ul>\r\n <li>Undgå overfyldning; terrassen har plads til maks. 20 personer ad gangen.</li>\r\n <li>Holde børn under opsyn til enhver tid.</li>\r\n <li>Undlade at flytte eller fjerne møbler.</li>\r\n <li>Holde nødudgange og gangarealer fri.</li>\r\n <li>Bortskaffe affald i de opsatte skraldespande.</li>\r\n </ul>\r\n \r\n <h3 class=\"section-headline\">Booking og varighed</h3>\r\n <p>Terrassen skal bookes på forhånd ved private arrangementer:</p>\r\n <ul>\r\n <li>Maksimal varighed: 3 timer pr. booking.</li>\r\n <li>Oprydning: Beboeren har ansvar for at efterlade terrassen ren og klar til næste booking.</li>\r\n </ul>\r\n `,\r\n requirements: ['Kræver nøglekort'],\r\n bookingType: 'Øjeblikkelig booking',\r\n expectations: '',\r\n restrictions: []\r\n },\r\n {\r\n id: 'facility-3',\r\n thumbnail: '/Assets/Dummy-photos/parking.jpg',\r\n facilityTitle: 'Gæsteparkering',\r\n description: 'Book en gæsteparkeringsplads, så dine besøgende nemt kan parkere ved ejendommen.',\r\n availabilityStatus: 'available-from',\r\n statusLabel: 'Ledig fra 28. februar, 2026',\r\n heroImage: '/Assets/Dummy-photos/parking.jpg',\r\n fullDescription: '<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>',\r\n requirements: ['Kræver nøglekort'],\r\n bookingType: 'Forudgående booking påkrævet',\r\n expectations: '<p>Parkeringsområdet er sikkert og velholdt. Gæstetilladelse skal være synlig i forruden under hele parkeringen. Informer gerne dine gæster om placering og regler.</p>',\r\n restrictions: [\r\n 'Forudgående booking påkrævet (minimum 24 timer)',\r\n 'Maksimal bookingvarighed: 12 timer',\r\n 'Gæster skal vise synlig parkeringstilladelse',\r\n 'Ingen erhvervskøretøjer tilladt'\r\n ]\r\n },\r\n {\r\n id: 'facility-4',\r\n thumbnail: '/Assets/Dummy-photos/yard.jpg',\r\n facilityTitle: 'BBQ område',\r\n description: 'Book grillområdet til sommerarrangementer og udendørs spisning med naboer og venner.',\r\n availabilityStatus: 'unavailable',\r\n statusLabel: 'Ikke tilgængelig',\r\n heroImage: '/Assets/Dummy-photos/yard.jpg',\r\n fullDescription: '<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>',\r\n requirements: ['Kræver nøglekort'],\r\n bookingType: 'Sæsonbestemt tilgængelighed',\r\n expectations: '<p>Alt grilludstyr og rengøringsartikler stilles til rådighed. Området har overdækkede siddepladser og borde til forberedelse. Rengør grillen efter brug, og bortskaf kul korrekt i de anviste beholdere.</p>',\r\n restrictions: [\r\n 'Lukket i vintersæsonen',\r\n 'Åbner igen i maj 2026',\r\n 'Maksimal gruppestørrelse: 20 personer',\r\n 'Musik skal stoppe senest kl. 22'\r\n ]\r\n }\r\n ]);\r\n \r\n handleRefresh(event: any): void {\r\n console.log('Pull-to-refresh triggered');\r\n \r\n // Check if offline and complete immediately\r\n if (this.pageComponent?.isOffline()) {\r\n console.log('Cannot refresh while offline');\r\n event.target.complete();\r\n return;\r\n }\r\n \r\n // Simulate data refresh\r\n setTimeout(() => {\r\n console.log('Refresh complete');\r\n event.target.complete();\r\n }, 1000);\r\n }\r\n \r\n /**\r\n * Navigate to previous slide\r\n */\r\n slidePrev(): void {\r\n this.bookingsSwiper?.slidePrev();\r\n }\r\n \r\n /**\r\n * Navigate to next slide\r\n */\r\n slideNext(): void {\r\n this.bookingsSwiper?.slideNext();\r\n }\r\n \r\n /**\r\n * Check if at first slide\r\n */\r\n isFirstSlide(): boolean {\r\n return this.bookingsSwiper?.isBeginning() ?? true;\r\n }\r\n \r\n /**\r\n * Check if at last slide\r\n */\r\n isLastSlide(): boolean {\r\n return this.bookingsSwiper?.isEnd() ?? true;\r\n }\r\n \r\n /**\r\n * Open facility detail modal\r\n */\r\n async openFacilityDetail(facilityId: string): Promise<void> {\r\n // Find facility in either active bookings or available facilities\r\n const allFacilities = [...this.activeBookings(), ...this.availableFacilities()];\r\n const facility = allFacilities.find(f => f.id === facilityId);\r\n \r\n if (facility) {\r\n await this.facilityModal.open({\r\n id: facility.id,\r\n facilityTitle: facility.facilityTitle,\r\n heroImage: facility.heroImage || facility.thumbnail,\r\n fullDescription: facility.fullDescription,\r\n requirements: facility.requirements,\r\n bookingType: facility.bookingType,\r\n expectations: facility.expectations,\r\n restrictions: facility.restrictions,\r\n availabilityStatus: facility.availabilityStatus,\r\n statusLabel: facility.statusLabel,\r\n bookingDate: facility.bookingDate,\r\n bookingTime: facility.bookingTime\r\n });\r\n }\r\n }\r\n \r\n /**\r\n * Open facility creation modal\r\n */\r\n async openFacilityCreationModal(): Promise<void> {\r\n console.log('[BookingPage] FAB clicked, opening facility creation modal...');\r\n \r\n await this.facilityCreationModal.open({\r\n onSubmit: async (data) => {\r\n console.log('[BookingPage] New facility created:', data);\r\n // In a real app, call your API to create the facility\r\n // await this.facilityService.createFacility(data);\r\n \r\n // Optionally add the new facility to the available facilities list\r\n // This is just for demo - in reality you'd refetch from the API\r\n }\r\n });\r\n }\r\n}\r\n","import { Component, signal, ViewChild, ElementRef, AfterViewInit, OnInit } from '@angular/core';\r\nimport { Router, ActivatedRoute } from '@angular/router';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport {\r\n DsAvatarComponent,\r\n DsIconComponent,\r\n DsButtonComponent\r\n} from '@propbinder/design-system';\r\nimport { DsMobilePageDetailsComponent } from '../components/page-details';\r\nimport { UserService } from '../services/user.service';\r\n\r\n/**\r\n * PostCreatePageComponent\r\n * \r\n * Full-screen detail page for creating new posts in the community feed.\r\n * Features Threads-inspired interface with rich text editing capabilities.\r\n */\r\n@Component({\r\n selector: 'app-post-create-page',\r\n standalone: true,\r\n imports: [\r\n CommonModule,\r\n FormsModule,\r\n DsAvatarComponent,\r\n DsIconComponent,\r\n DsButtonComponent,\r\n DsMobilePageDetailsComponent\r\n ],\r\n styles: [`\r\n .post-create-container {\r\n display: flex;\r\n flex-direction: column;\r\n height: 100%;\r\n max-width: 640px;\r\n }\r\n \r\n /* ============================================\r\n CONTENT AREA\r\n ============================================ */\r\n \r\n .content {\r\n flex: 1;\r\n overflow-y: auto;\r\n padding: 16px;\r\n }\r\n \r\n .post-composer {\r\n display: flex;\r\n gap: 12px;\r\n margin-bottom: 24px;\r\n align-items: flex-start;\r\n }\r\n \r\n .post-composer__avatar {\r\n flex-shrink: 0;\r\n padding-top: 2px;\r\n }\r\n \r\n .post-composer__main {\r\n flex: 1;\r\n min-width: 0;\r\n display: flex;\r\n flex-direction: column;\r\n gap: 12px;\r\n }\r\n \r\n .post-composer__header {\r\n display: flex;\r\n align-items: center;\r\n gap: 8px;\r\n height: 32px;\r\n }\r\n \r\n .post-composer__username {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: 15px;\r\n font-weight: 600;\r\n line-height: 20px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n .post-composer__textarea {\r\n width: 100%;\r\n min-height: 120px;\r\n border: none;\r\n outline: none;\r\n resize: none;\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: 15px;\r\n font-weight: 400;\r\n line-height: 22px;\r\n letter-spacing: -0.3px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n background: transparent;\r\n padding: 0;\r\n }\r\n \r\n .post-composer__textarea::placeholder {\r\n color: var(--color-text-tertiary, #999999);\r\n }\r\n \r\n .post-composer__actions {\r\n display: flex;\r\n align-items: center;\r\n justify-content: space-between;\r\n gap: 16px;\r\n }\r\n \r\n .post-composer__action-btns {\r\n display: flex;\r\n align-items: center;\r\n gap: 16px;\r\n }\r\n \r\n .post-composer__action-btn {\r\n background: none;\r\n border: none;\r\n padding: 0;\r\n cursor: pointer;\r\n display: flex;\r\n align-items: center;\r\n justify-content: center;\r\n color: var(--color-text-secondary, #737373);\r\n transition: color 0.2s ease;\r\n }\r\n \r\n .post-composer__action-btn:hover {\r\n color: var(--color-text-primary, #1a1a1a);\r\n }\r\n \r\n /* Thread connector line */\r\n .thread-line {\r\n position: absolute;\r\n left: 35px;\r\n top: 60px;\r\n bottom: 0;\r\n width: 2px;\r\n background: var(--border-color-default);\r\n }\r\n \r\n /* ============================================\r\n MOBILE OPTIMIZATIONS\r\n ============================================ */\r\n \r\n @media (max-width: 768px) {\r\n .content {\r\n padding: 12px 16px;\r\n }\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-page-details\r\n [title]=\"pageTitle()\"\r\n [backRoute]=\"'/mobile-tabs-example/announcements'\"\r\n (back)=\"handleCancel()\">\r\n \r\n <div class=\"post-create-container\">\r\n <div class=\"post-composer\">\r\n <div class=\"post-composer__avatar\">\r\n <ds-avatar \r\n [initials]=\"userService.avatarInitials()\"\r\n [type]=\"userService.avatarType()\"\r\n [src]=\"userService.avatarSrc()\"\r\n size=\"md\" />\r\n </div>\r\n \r\n <div class=\"post-composer__main\">\r\n <div class=\"post-composer__header\">\r\n <span class=\"post-composer__username\">{{ username() }}</span>\r\n </div>\r\n \r\n <textarea\r\n #textareaInput\r\n class=\"post-composer__textarea\"\r\n [(ngModel)]=\"postContent\"\r\n [placeholder]=\"placeholder()\"\r\n (input)=\"handleInput()\">\r\n </textarea>\r\n \r\n <div class=\"post-composer__actions\">\r\n <div class=\"post-composer__action-btns\">\r\n <button class=\"post-composer__action-btn\" (click)=\"handleAddImage()\">\r\n <ds-icon name=\"remixImageLine\" size=\"22px\" />\r\n </button>\r\n <button class=\"post-composer__action-btn\" (click)=\"handleAddEmoji()\">\r\n <ds-icon name=\"remixEmotionLine\" size=\"22px\" />\r\n </button>\r\n </div>\r\n \r\n <ds-button\r\n variant=\"primary\"\r\n size=\"md\"\r\n [disabled]=\"!canPost()\"\r\n (clicked)=\"handlePost()\">\r\n {{ submitButtonLabel() }}\r\n </ds-button>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </ds-mobile-page-details>\r\n `\r\n})\r\nexport class PostCreatePageComponent implements AfterViewInit, OnInit {\r\n @ViewChild('textareaInput') textareaInput?: ElementRef<HTMLTextAreaElement>;\r\n \r\n postContent = '';\r\n username = signal('Lars Mikkelsen');\r\n placeholder = signal(\"What's new?\");\r\n \r\n // Edit mode state\r\n isEditMode = signal(false);\r\n postId = signal<string | null>(null);\r\n pageTitle = signal('New post');\r\n submitButtonLabel = signal('Post');\r\n \r\n constructor(\r\n private router: Router,\r\n private route: ActivatedRoute,\r\n public userService: UserService\r\n ) {}\r\n \r\n ngOnInit(): void {\r\n // Check for edit mode via query parameters\r\n this.route.queryParams.subscribe(params => {\r\n const editMode = params['edit'] === 'true';\r\n const postId = params['id'];\r\n const content = params['content'];\r\n \r\n if (editMode && postId) {\r\n this.isEditMode.set(true);\r\n this.postId.set(postId);\r\n this.pageTitle.set('Edit post');\r\n this.submitButtonLabel.set('Save');\r\n \r\n // Prefill content if provided\r\n if (content) {\r\n this.postContent = decodeURIComponent(content);\r\n }\r\n } else {\r\n // Reset to create mode\r\n this.isEditMode.set(false);\r\n this.postId.set(null);\r\n this.pageTitle.set('New post');\r\n this.submitButtonLabel.set('Post');\r\n this.postContent = '';\r\n }\r\n });\r\n }\r\n \r\n ngAfterViewInit(): void {\r\n // Focus the textarea after view initialization to trigger keyboard on mobile\r\n setTimeout(() => {\r\n this.textareaInput?.nativeElement.focus();\r\n }, 300);\r\n }\r\n \r\n handleInput(): void {\r\n // Handle text input changes\r\n }\r\n \r\n canPost(): boolean {\r\n return this.postContent.trim().length > 0;\r\n }\r\n \r\n handleCancel(): void {\r\n if (this.postContent.trim().length > 0) {\r\n // Show confirmation dialog\r\n const confirmed = confirm('Discard this post?');\r\n if (confirmed) {\r\n this.router.navigate(['/mobile-tabs-example/community']);\r\n }\r\n } else {\r\n this.router.navigate(['/mobile-tabs-example/community']);\r\n }\r\n }\r\n \r\n handlePost(): void {\r\n if (!this.canPost()) return;\r\n \r\n if (this.isEditMode()) {\r\n console.log('Updating post:', this.postId(), this.postContent);\r\n // TODO: Implement post update logic\r\n // this.postService.updatePost(this.postId(), this.postContent).subscribe(() => {\r\n // this.router.navigate(['/mobile-tabs-example/community']);\r\n // });\r\n } else {\r\n console.log('Creating post:', this.postContent);\r\n // TODO: Implement post creation logic\r\n // this.postService.createPost(this.postContent).subscribe(() => {\r\n // this.router.navigate(['/mobile-tabs-example/community']);\r\n // });\r\n }\r\n \r\n // For now, just navigate back\r\n this.router.navigate(['/mobile-tabs-example/community']);\r\n }\r\n \r\n handleAddImage(): void {\r\n console.log('Add image');\r\n // TODO: Open image picker\r\n }\r\n \r\n handleAddEmoji(): void {\r\n console.log('Add emoji');\r\n // TODO: Open emoji picker\r\n }\r\n}\r\n\r\n","import { Component } from '@angular/core';\r\nimport { DsMobilePageDetailsComponent } from '../components/page-details';\r\nimport { \r\n DsMobileInteractiveListItemPostComponent,\r\n PostContentComponent,\r\n PostTextComponent,\r\n PostMediaComponent,\r\n PostActionsComponent,\r\n ActionLikeComponent,\r\n ActionCommentComponent\r\n} from '../components/interactive-list-item-post';\r\nimport { DsMobileCommentComponent } from '../components/comment';\r\nimport { DsMobileLightboxService, LightboxAuthor } from '../components/lightbox';\r\nimport { DsMobileBottomSheetService } from '../components/bottom-sheet/ds-mobile-bottom-sheet.service';\r\nimport { DsMobileCommentActionsBottomSheetComponent, CommentActionResult } from '../components/bottom-sheet';\r\n\r\n@Component({\r\n selector: 'app-mobile-post-detail-page',\r\n standalone: true,\r\n imports: [\r\n DsMobilePageDetailsComponent,\r\n DsMobileInteractiveListItemPostComponent,\r\n PostContentComponent,\r\n PostTextComponent,\r\n PostMediaComponent,\r\n PostActionsComponent,\r\n ActionLikeComponent,\r\n ActionCommentComponent,\r\n DsMobileCommentComponent\r\n ],\r\n styles: [`\r\n .post-detail-container {\r\n display: flex;\r\n flex-direction: column;\r\n gap: 16px;\r\n max-width: 640px;\r\n }\r\n \r\n .post-section {\r\n border-bottom: 1px solid var(--border-color-default);\r\n padding-bottom: 16px;\r\n }\r\n \r\n .clickable-image {\r\n cursor: pointer;\r\n transition: transform 0.2s ease, opacity 0.2s ease;\r\n border-radius: 8px;\r\n display: block;\r\n width: 100%;\r\n aspect-ratio: 16/9;\r\n object-fit: cover;\r\n }\r\n \r\n .clickable-image:active {\r\n transform: scale(0.98);\r\n opacity: 0.9;\r\n }\r\n \r\n .comments-section {\r\n display: flex;\r\n flex-direction: column;\r\n /* Negative margin to pull comments out by 8px on each side */\r\n /* Page has 20px padding, this makes comments effectively 12px from edge */\r\n margin-left: -8px;\r\n margin-right: -8px;\r\n }\r\n \r\n .comments-header {\r\n font-family: 'Brockmann', sans-serif;\r\n font-size: 18px;\r\n font-weight: 600;\r\n line-height: 24px;\r\n color: var(--color-text-primary, #1a1a1a);\r\n margin-bottom: 16px;\r\n /* Add padding to keep header at 20px from edge (8px to offset negative margin) */\r\n padding-left: 8px;\r\n padding-right: 8px;\r\n }\r\n \r\n .comments-list {\r\n display: flex;\r\n flex-direction: column;\r\n }\r\n `],\r\n template: `\r\n <ds-mobile-page-details title=\"Opslag\">\r\n <div class=\"post-detail-container\">\r\n <!-- Post Section -->\r\n <div class=\"post-section\">\r\n <ds-mobile-interactive-list-item-post\r\n [authorName]=\"'Sophie Andersen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'4t siden'\"\r\n [avatarInitials]=\"'SA'\"\r\n [clickable]=\"false\">\r\n \r\n <post-content>\r\n <post-text>Se denne smukke udsigt fra min altan! Morgenkaffe har aldrig smagt så godt ☕️</post-text>\r\n <post-media>\r\n <img \r\n src=\"/Assets/Dummy-photos/balcony-view.jpg\" \r\n alt=\"Altanudsigt\" \r\n class=\"clickable-image\"\r\n (click)=\"openImageLightbox('/Assets/Dummy-photos/balcony-view.jpg', 'Altanudsigt', 'Morgenkaffe har aldrig smagt så godt ☕️')\"\r\n />\r\n </post-media>\r\n </post-content>\r\n \r\n <post-actions>\r\n <action-like [active]=\"true\" [count]=\"156\" />\r\n <action-comment [count]=\"34\" />\r\n </post-actions>\r\n </ds-mobile-interactive-list-item-post>\r\n </div>\r\n \r\n <!-- Comments Section -->\r\n <div class=\"comments-section\">\r\n <h2 class=\"comments-header\">{{ repliesCount }} svar</h2>\r\n \r\n <div class=\"comments-list\">\r\n <ds-mobile-comment\r\n [authorName]=\"'Anders Jensen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'3t siden'\"\r\n [avatarInitials]=\"'AJ'\"\r\n [content]=\"'Wow, den udsigt er fantastisk! Hvilken etage er du på?'\"\r\n [likeCount]=\"12\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"false\"\r\n (longPress)=\"handleCommentLongPress('Anders Jensen', 'Wow, den udsigt er fantastisk! Hvilken etage er du på?', false)\" />\r\n \r\n <ds-mobile-comment\r\n [authorName]=\"'Thomas Hansen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'3t siden'\"\r\n [avatarInitials]=\"'TH'\"\r\n [content]=\"'Smuk! Jeg kan også se byens silhuet fra min lejlighed 🌆'\"\r\n [isLiked]=\"true\"\r\n [likeCount]=\"8\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"true\"\r\n (longPress)=\"handleCommentLongPress('Thomas Hansen', 'Smuk! Jeg kan også se byens silhuet fra min lejlighed 🌆', true)\" />\r\n \r\n <ds-mobile-comment\r\n [authorName]=\"'Emma Petersen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'2t siden'\"\r\n [avatarInitials]=\"'EP'\"\r\n [content]=\"'Dette er præcis derfor jeg elsker at bo her. Godt billede!'\"\r\n [likeCount]=\"15\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"false\"\r\n (longPress)=\"handleCommentLongPress('Emma Petersen', 'Dette er præcis derfor jeg elsker at bo her. Godt billede!', false)\" />\r\n \r\n <ds-mobile-comment\r\n [authorName]=\"'Nikolaj Sørensen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'2t siden'\"\r\n [avatarInitials]=\"'NS'\"\r\n [content]=\"'Solnedgangene fra den vinkel må være utrolige'\"\r\n [likeCount]=\"6\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"false\"\r\n (longPress)=\"handleCommentLongPress('Nikolaj Sørensen', 'Solnedgangene fra den vinkel må være utrolige', false)\" />\r\n \r\n <ds-mobile-comment\r\n [authorName]=\"'Mette Larsen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'1t siden'\"\r\n [avatarInitials]=\"'ML'\"\r\n [content]=\"'Giver mig lyst til at få min morgenkaffe på altanen også! ☕'\"\r\n [likeCount]=\"9\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"false\"\r\n (longPress)=\"handleCommentLongPress('Mette Larsen', 'Giver mig lyst til at få min morgenkaffe på altanen også! ☕', false)\" />\r\n \r\n <ds-mobile-comment\r\n [authorName]=\"'Frederik Nielsen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'1t siden'\"\r\n [avatarInitials]=\"'FN'\"\r\n [content]=\"'Heldig! Min altan vender den anden vej, men stadig pæn'\"\r\n [likeCount]=\"4\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"false\"\r\n (longPress)=\"handleCommentLongPress('Frederik Nielsen', 'Heldig! Min altan vender den anden vej, men stadig pæn', false)\" />\r\n \r\n <ds-mobile-comment\r\n [authorName]=\"'Caroline Jensen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'45m siden'\"\r\n [avatarInitials]=\"'CJ'\"\r\n [content]=\"'Denne bygning har den bedste udsigt i byen, uden tvivl'\"\r\n [likeCount]=\"11\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"false\"\r\n (longPress)=\"handleCommentLongPress('Caroline Jensen', 'Denne bygning har den bedste udsigt i byen, uden tvivl', false)\" />\r\n \r\n <ds-mobile-comment\r\n [authorName]=\"'Anna Hansen'\"\r\n [authorRole]=\"'Lejer'\"\r\n [timestamp]=\"'30m siden'\"\r\n [avatarInitials]=\"'AH'\"\r\n [content]=\"'Jeg skal se din altan en dag! 😍'\"\r\n [clickable]=\"true\"\r\n [isOwnComment]=\"false\"\r\n (longPress)=\"handleCommentLongPress('Anna Hansen', 'Jeg skal se din altan en dag! 😍', false)\" />\r\n </div>\r\n </div>\r\n </div>\r\n </ds-mobile-page-details>\r\n `\r\n})\r\nexport class MobilePostDetailPageComponent {\r\n repliesCount = 6;\r\n \r\n constructor(\r\n private lightbox: DsMobileLightboxService,\r\n private bottomSheet: DsMobileBottomSheetService\r\n ) {}\r\n \r\n /**\r\n * Open an image in the lightbox viewer\r\n */\r\n openImageLightbox(imageSrc: string, title: string, description: string): void {\r\n const authorMeta: LightboxAuthor = {\r\n name: 'Sophie Andersen',\r\n role: 'Lejer',\r\n avatarInitials: 'SA',\r\n timestamp: '4t siden'\r\n };\r\n \r\n this.lightbox.open({\r\n showActions: true, // Show like & comment actions\r\n images: [\r\n {\r\n type: 'image',\r\n src: imageSrc,\r\n alt: title,\r\n title: title,\r\n description: description,\r\n isLiked: true,\r\n likeCount: 156,\r\n commentCount: 34\r\n }\r\n ],\r\n author: authorMeta,\r\n enableZoom: true,\r\n showControls: false, // Single image, no need for controls\r\n showInfo: true\r\n });\r\n }\r\n \r\n /**\r\n * Handle long press on a comment to show action sheet\r\n */\r\n async handleCommentLongPress(authorName: string, content: string, isOwnComment: boolean): Promise<void> {\r\n const sheet = await this.bottomSheet.create({\r\n component: DsMobileCommentActionsBottomSheetComponent,\r\n componentProps: {\r\n isOwnContent: isOwnComment\r\n },\r\n breakpoints: [0, 1],\r\n initialBreakpoint: 1,\r\n handle: true,\r\n backdropDismiss: true,\r\n cssClass: 'auto-height'\r\n });\r\n \r\n const result = await sheet.onWillDismiss();\r\n \r\n if (result.role === 'select' && result.data) {\r\n const action = (result.data as CommentActionResult).action;\r\n \r\n switch (action) {\r\n case 'like':\r\n console.log('Like comment by', authorName);\r\n // Implement like logic\r\n break;\r\n case 'reply':\r\n console.log('Reply to comment by', authorName);\r\n // Implement reply logic\r\n break;\r\n case 'edit':\r\n console.log('Edit comment by', authorName);\r\n // Implement edit logic\r\n break;\r\n case 'delete':\r\n console.log('Delete comment by', authorName);\r\n // Implement delete logic (with confirmation)\r\n break;\r\n }\r\n }\r\n }\r\n}\r\n\r\n","import { Component, signal, inject, ViewChild, ElementRef, AfterViewInit, OnDestroy } from '@angular/core';\r\nimport { CommonModule } from '@angular/common';\r\nimport { FormsModule } from '@angular/forms';\r\nimport { DsTextInputComponent } from '../components/text-input';\r\nimport { DsButtonComponent } from '@propbinder/design-system';\r\nimport { DsAppIconComponent } from '../components/app-icon';\r\nimport { WhitelabelService } from '../services/whitelabel.service';\r\nimport { Keyboard } from '@capacitor/keyboard';\r\nimport { StatusBar, Style } from '@capacitor/status-bar';\r\n\r\n/**\r\n * SignInPageComponent\r\n * \r\n * Sign-in page with email authentication.\r\n * Features logomark, decorative city background, and form validation.\r\n * Auto-focuses email input on iOS to trigger keyboard.\r\n */\r\n@Component({\r\n selector: 'app-sign-in',\r\n standalone: true,\r\n imports: [CommonModule, FormsModule, DsTextInputComponent, DsButtonComponent, DsAppIconComponent],\r\n template: `\r\n <div class=\"tw-relative tw-min-h-screen tw-flex tw-justify-center tw-overflow-hidden\" [style.background]=\"whitelabelService.signInBgStyle()\">\r\n <!-- City background decoration -->\r\n @if (whitelabelService.showCityIllustration()) {\r\n <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\">\r\n <img src=\"/Assets/city.svg\" alt=\"\" class=\"tw-w-full tw-h-full tw-object-cover tw-object-top\" />\r\n </div>\r\n }\r\n\r\n <!-- Main content -->\r\n <div class=\"tw-relative tw-z-[1] tw-w-full tw-pt-24 tw-max-w-[440px] tw-flex tw-flex-col tw-items-center lg:tw-max-w-[480px] lg:tw-pt-24\">\r\n <!-- App Icon -->\r\n <div class=\"tw-flex tw-justify-center tw-items-center app-icon-container\">\r\n <ds-app-icon size=\"xl\" />\r\n </div>\r\n\r\n <!-- Sign in form -->\r\n <div class=\"tw-w-full tw-py-10 tw-px-6 md:tw-px-8 md:tw-py-12 lg:tw-p-12 tw-relative tw-min-h-[400px] tw-box-border\">\r\n <!-- Form view -->\r\n <div class=\"tw-transition-all tw-duration-300 tw-ease-out tw-absolute tw-inset-y-10 tw-inset-x-6 md:tw-inset-y-12 md:tw-inset-x-8 lg:tw-inset-12 tw-box-border\" \r\n [class.tw-opacity-100]=\"!emailSent()\"\r\n [class.tw-translate-y-0]=\"!emailSent()\"\r\n [class.tw-z-10]=\"!emailSent()\"\r\n [class.tw-opacity-0]=\"emailSent()\"\r\n [class.-tw-translate-y-5]=\"emailSent()\"\r\n [class.tw-pointer-events-none]=\"emailSent()\"\r\n [class.tw-z-0]=\"emailSent()\">\r\n <div class=\"tw-w-full tw-h-full tw-flex tw-flex-col\">\r\n <h1 class=\"tw-text-2xl lg:tw-text-3xl tw-font-semibold tw-text-center tw-mt-0 tw-mb-2 signin-text\">Welcome home</h1>\r\n\r\n <p class=\"body-base-regular tw-m-0 tw-mb-8 tw-text-center signin-text\">\r\n Enter your email to continue\r\n </p>\r\n\r\n <form class=\"tw-flex tw-flex-col tw-gap-4\" (ngSubmit)=\"handleSubmit()\">\r\n <ds-text-input\r\n #emailInput\r\n id=\"email-input\"\r\n type=\"email\"\r\n placeholder=\"Enter your email\"\r\n [(ngModel)]=\"email\"\r\n name=\"email\"\r\n [required]=\"true\"\r\n [hasError]=\"emailError()\"\r\n [errorMessage]=\"emailError() ? 'Please enter a valid email address' : ''\"\r\n [autoClearError]=\"true\"\r\n autocomplete=\"email\"\r\n inputmode=\"email\"\r\n (errorCleared)=\"emailError.set(false)\">\r\n </ds-text-input>\r\n\r\n <ds-button\r\n type=\"submit\"\r\n variant=\"primary\"\r\n size=\"lg\"\r\n [loading]=\"isSubmitting()\"\r\n class=\"tw-w-full\">\r\n Continue\r\n </ds-button>\r\n </form>\r\n </div>\r\n </div>\r\n\r\n <!-- Email sent confirmation view -->\r\n <div class=\"tw-transition-all tw-duration-300 tw-ease-out tw-flex tw-flex-col tw-items-center tw-absolute tw-inset-y-10 tw-inset-x-6 md:tw-inset-y-12 md:tw-inset-x-8 lg:tw-inset-12 tw-box-border tw-overflow-hidden\"\r\n [class.tw-opacity-0]=\"!emailSent()\"\r\n [class.tw-translate-y-5]=\"!emailSent()\"\r\n [class.tw-pointer-events-none]=\"!emailSent()\"\r\n [class.tw-z-0]=\"!emailSent()\"\r\n [class.tw-opacity-100]=\"emailSent()\"\r\n [class.tw-translate-y-0]=\"emailSent()\"\r\n [class.tw-pointer-events-auto]=\"emailSent()\"\r\n [class.tw-z-10]=\"emailSent()\">\r\n <div class=\"tw-w-full tw-flex tw-flex-col tw-items-center\">\r\n <h1 class=\"tw-text-lg tw-font-semibold lg:tw-text-xl tw-text-center tw-mt-0 tw-mb-4 signin-text\">Check your email</h1>\r\n\r\n <p class=\"body-base-regular tw-m-0 tw-mb-8 tw-text-center signin-text tw-max-w-[272px]\">\r\n We've sent you a temporary login to <span class=\"body-base-semiBold\">{{ email }}</span>\r\n </p>\r\n\r\n <a\r\n href=\"#\"\r\n (click)=\"handleBackToLogin(); $event.preventDefault()\"\r\n class=\"back-link\">\r\n Back to login\r\n </a>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n </div>\r\n `,\r\n styles: [`\r\n /* Button styling override for full width */\r\n ds-button {\r\n width: 100%;\r\n }\r\n\r\n ds-button::ng-deep button {\r\n width: 100%;\r\n }\r\n\r\n /* Link styling */\r\n .back-link {\r\n display: block;\r\n width: 100%;\r\n text-align: center;\r\n font-family: 'Brockmann', system-ui, -apple-system, sans-serif;\r\n font-size: var(--font-size-base);\r\n font-weight: 600;\r\n color: var(--color-signin-content, var(--text-color-default-primary));\r\n text-decoration: none;\r\n cursor: pointer;\r\n transition: opacity 0.2s ease;\r\n }\r\n\r\n .back-link:hover {\r\n opacity: 0.8;\r\n }\r\n\r\n /* Sign-in page text color override - applies to text elements only, not buttons */\r\n :host ::ng-deep .signin-text,\r\n :host h1,\r\n :host h2,\r\n :host p {\r\n color: var(--color-signin-content, var(--text-color-default-primary));\r\n }\r\n \r\n /* Exclude buttons and their children from sign-in content color */\r\n :host ::ng-deep ds-button,\r\n :host ::ng-deep ds-button * {\r\n color: inherit;\r\n }\r\n `]\r\n})\r\nexport class SignInPageComponent implements AfterViewInit, OnDestroy {\r\n @ViewChild('emailInput', { read: ElementRef }) emailInputRef?: ElementRef;\r\n \r\n whitelabelService = inject(WhitelabelService);\r\n \r\n email = '';\r\n emailError = signal<boolean>(false);\r\n isSubmitting = signal<boolean>(false);\r\n emailSent = signal<boolean>(false);\r\n \r\n ngAfterViewInit(): void {\r\n // Update status bar for sign-in page\r\n this.updateSignInStatusBar();\r\n \r\n // Auto-focus email input to bring up keyboard on iOS\r\n // Longer delay for sign-in page to ensure gradient background is rendered\r\n setTimeout(() => {\r\n // Only focus if we haven't already sent the email\r\n if (!this.emailSent() && this.emailInputRef) {\r\n // The ds-text-input component wraps the actual input element\r\n const inputElement = this.emailInputRef.nativeElement.querySelector('input');\r\n if (inputElement) {\r\n console.log('Found input element, focusing...');\r\n inputElement.focus();\r\n // Explicitly show keyboard on mobile platforms\r\n this.showKeyboard();\r\n } else {\r\n console.error('Input element not found in ds-text-input component');\r\n }\r\n } else if (!this.emailInputRef) {\r\n console.error('emailInputRef not found');\r\n }\r\n }, 500);\r\n }\r\n \r\n /**\r\n * Show the keyboard on mobile platforms\r\n */\r\n private showKeyboard(): void {\r\n Keyboard.show().catch(() => {\r\n // Keyboard API not available (web browser) - focus() is enough\r\n console.log('Keyboard API not available');\r\n });\r\n }\r\n\r\n handleSubmit(): void {\r\n // Basic email validation\r\n const emailRegex = /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/;\r\n \r\n // Always validate on submit\r\n if (!this.email || !emailRegex.test(this.email)) {\r\n this.emailError.set(true);\r\n return;\r\n }\r\n\r\n // Only proceed if email is valid\r\n this.emailError.set(false);\r\n this.isSubmitting.set(true);\r\n \r\n // Simulate API call\r\n setTimeout(() => {\r\n console.log('Sign in with email:', this.email);\r\n this.isSubmitting.set(false);\r\n this.emailSent.set(true);\r\n // TODO: Implement actual sign-in logic and navigation\r\n }, 1500);\r\n }\r\n\r\n handleBackToLogin(): void {\r\n this.emailSent.set(false);\r\n this.email = '';\r\n this.emailError.set(false);\r\n }\r\n \r\n /**\r\n * Update status bar for sign-in page background\r\n * Uses the sign-in background color to determine appropriate status bar style\r\n */\r\n private async updateSignInStatusBar(): Promise<void> {\r\n try {\r\n const config = this.whitelabelService.config();\r\n \r\n // Get the background color based on sign-in page background type\r\n const backgroundColor = config.signInBgType === 'gradient' \r\n ? config.signInBgGradientStart \r\n : config.signInBgSolid;\r\n \r\n // Calculate and set appropriate style\r\n const style = this.whitelabelService.getStatusBarStyleForColor(backgroundColor);\r\n \r\n // Set background color (Android only)\r\n await StatusBar.setBackgroundColor({ color: backgroundColor });\r\n \r\n // Set style (iOS and Android)\r\n await StatusBar.setStyle({ style });\r\n \r\n console.log(`Sign-in status bar updated: color=${backgroundColor}, style=${style === Style.Light ? 'Light' : 'Dark'}`);\r\n } catch (e) {\r\n // StatusBar API not available (web browser)\r\n console.log('StatusBar not available on sign-in page:', e);\r\n }\r\n }\r\n \r\n /**\r\n * Restore status bar to header color when leaving sign-in page\r\n */\r\n ngOnDestroy(): void {\r\n this.restoreHeaderStatusBar();\r\n }\r\n \r\n /**\r\n * Restore status bar to use header surface color\r\n */\r\n private async restoreHeaderStatusBar(): Promise<void> {\r\n try {\r\n const config = this.whitelabelService.config();\r\n const headerColor = config.headerSurface;\r\n \r\n // Calculate and set appropriate style for header\r\n const style = this.whitelabelService.getStatusBarStyleForColor(headerColor);\r\n \r\n // Set background color (Android only)\r\n await StatusBar.setBackgroundColor({ color: headerColor });\r\n \r\n // Set style (iOS and Android)\r\n await StatusBar.setStyle({ style });\r\n \r\n console.log(`Status bar restored to header: color=${headerColor}, style=${style === Style.Light ? 'Light' : 'Dark'}`);\r\n } catch (e) {\r\n // StatusBar API not available (web browser)\r\n console.log('StatusBar restore not available:', e);\r\n }\r\n }\r\n}\r\n\r\n","/**\r\n * Services Barrel File\r\n *\r\n * Export all application services for easy importing\r\n */\r\n\r\nexport * from './base-modal.service';\r\nexport * from './posts.service';\r\nexport * from './tracking-permission.service';\r\nexport * from './user.service';\r\nexport * from './whitelabel.service';\r\n","/**\r\n * Post and Comment Models\r\n * Unified data structures for community posts\r\n */\r\n\r\nexport interface Comment {\r\n id?: string;\r\n authorName: string;\r\n authorRole: string;\r\n timestamp: string;\r\n avatarInitials: string;\r\n avatarSrc?: string;\r\n avatarType?: 'photo' | 'initials' | 'icon';\r\n content: string;\r\n likeCount: number;\r\n isLiked?: boolean;\r\n isOwnComment: boolean;\r\n}\r\n\r\nexport interface Post {\r\n id: string;\r\n authorName: string;\r\n authorRole: string;\r\n timestamp: string;\r\n avatarType: 'photo' | 'initials' | 'icon';\r\n avatarSrc?: string;\r\n avatarInitials?: string;\r\n avatarIconName?: string;\r\n content: string;\r\n imageSrc?: string;\r\n imageAlt?: string;\r\n isLiked: boolean;\r\n likeCount: number;\r\n commentCount: number;\r\n comments?: Comment[];\r\n isPinned?: boolean;\r\n showBadge?: boolean;\r\n hasInlinePhotos?: boolean;\r\n inlinePhotos?: string[];\r\n inlinePhotoCount?: number;\r\n}\r\n","/**\r\n * Models Barrel File\r\n * \r\n * Export all application models for easy importing\r\n */\r\n\r\nexport * from './post.model';","/* Auto-generated. Do not edit. */\nexport * from './components';\nexport * from './examples';\nexport * from './animations/page-transitions';\nexport * from './services';\nexport * from './models';\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './public-api';\n"],"names":["i1.DsMobileLongPressDirective","i1","i2","WhitelabelDemoModalComponent","WhitelabelDemoModalService","i1.DsMobileLightboxService","DsMobileCommentActionsBottomSheetComponent","i2.DsMobileBottomSheetService","i3","i2.DsMobileBookingModalService","i1.DsMobileHandbookDetailModalService","DsMobilePostActionsBottomSheetComponent","i3.DsMobileLightboxService","i4.DsMobilePostDetailModalService","i5.UserService","i6.PostsService","i1.UserService","i2.UserService","i3.PostsService","i5.TrackingPermissionService","i6.DsMobileBottomSheetService","i3.DsMobileNewInquiryModalService","i2.DsMobileLightboxService","i3.DsMobileChatModalService","i1.DsMobileFacilityDetailModalService","i2.DsMobileFacilityCreationModalService","i3.UserService"],"mappings":"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"}
|