@propbinder/mobile-design 0.2.50 → 0.2.53

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.
Files changed (221) hide show
  1. package/fesm2022/propbinder-mobile-design.mjs +26206 -0
  2. package/fesm2022/propbinder-mobile-design.mjs.map +1 -0
  3. package/index.d.ts +8193 -0
  4. package/package.json +39 -3
  5. package/ng-package.json +0 -24
  6. package/src/animations/page-transitions.ts +0 -165
  7. package/src/components/action-list-item/ds-mobile-action-list-item.ts +0 -102
  8. package/src/components/action-list-item/index.ts +0 -2
  9. package/src/components/app-icon/ds-app-icon.ts +0 -133
  10. package/src/components/app-icon/index.ts +0 -2
  11. package/src/components/attachment-preview/ds-mobile-attachment-preview.css +0 -139
  12. package/src/components/attachment-preview/ds-mobile-attachment-preview.ts +0 -164
  13. package/src/components/attachment-preview/index.ts +0 -1
  14. package/src/components/avatar-with-badge/ds-avatar-with-badge.ts +0 -142
  15. package/src/components/avatar-with-badge/index.ts +0 -2
  16. package/src/components/booking-modal/ds-mobile-booking-confirmation-wrapper.ts +0 -71
  17. package/src/components/booking-modal/ds-mobile-booking-modal.service.ts +0 -121
  18. package/src/components/booking-modal/ds-mobile-booking-modal.ts +0 -598
  19. package/src/components/booking-modal/ds-mobile-booking-summary.ts +0 -161
  20. package/src/components/booking-modal/index.ts +0 -4
  21. package/src/components/bottom-sheet/ds-mobile-actions-bottom-sheet.ts +0 -266
  22. package/src/components/bottom-sheet/ds-mobile-bottom-sheet-header.ts +0 -146
  23. package/src/components/bottom-sheet/ds-mobile-bottom-sheet-wrapper.ts +0 -156
  24. package/src/components/bottom-sheet/ds-mobile-bottom-sheet.css +0 -101
  25. package/src/components/bottom-sheet/ds-mobile-bottom-sheet.service.ts +0 -169
  26. package/src/components/bottom-sheet/ds-mobile-confirmation-sheet.ts +0 -211
  27. package/src/components/bottom-sheet/ds-mobile-post-create-bottom-sheet.ts +0 -578
  28. package/src/components/bottom-sheet/ds-mobile-profile-actions-sheet.ts +0 -614
  29. package/src/components/bottom-sheet/index.ts +0 -8
  30. package/src/components/bottom-sheet/modal-shadow-fix.ts +0 -42
  31. package/src/components/card-inline/ds-mobile-card-inline.ts +0 -301
  32. package/src/components/card-inline/index.ts +0 -2
  33. package/src/components/card-inline-banner/ds-mobile-card-inline-banner.ts +0 -118
  34. package/src/components/card-inline-banner/index.ts +0 -1
  35. package/src/components/card-inline-contact/ds-mobile-card-inline-contact.ts +0 -120
  36. package/src/components/card-inline-contact/index.ts +0 -1
  37. package/src/components/card-inline-file/ds-mobile-card-inline-file.ts +0 -141
  38. package/src/components/card-inline-file/index.ts +0 -1
  39. package/src/components/chat-modal/ds-mobile-chat-modal.css +0 -159
  40. package/src/components/chat-modal/ds-mobile-chat-modal.service.ts +0 -105
  41. package/src/components/chat-modal/ds-mobile-chat-modal.ts +0 -918
  42. package/src/components/chat-modal/index.ts +0 -8
  43. package/src/components/comment/ds-mobile-comment.ts +0 -568
  44. package/src/components/comment/index.ts +0 -2
  45. package/src/components/contact-list-item/ds-mobile-contact-list-item.ts +0 -182
  46. package/src/components/contact-list-item/index.ts +0 -2
  47. package/src/components/content/ds-mobile-content.ts +0 -139
  48. package/src/components/content/index.ts +0 -2
  49. package/src/components/dropdown/ds-mobile-dropdown.css +0 -199
  50. package/src/components/dropdown/ds-mobile-dropdown.ts +0 -340
  51. package/src/components/dropdown/index.ts +0 -2
  52. package/src/components/ds-mobile-tabs.css +0 -407
  53. package/src/components/ds-mobile-tabs.ts +0 -216
  54. package/src/components/empty-state/ds-mobile-empty-state.ts +0 -120
  55. package/src/components/empty-state/index.ts +0 -2
  56. package/src/components/fab/ds-mobile-fab.ts +0 -315
  57. package/src/components/fab/index.ts +0 -1
  58. package/src/components/facility-creation-modal/ds-mobile-facility-creation-confirmation-wrapper.ts +0 -121
  59. package/src/components/facility-creation-modal/ds-mobile-facility-creation-modal.css +0 -189
  60. package/src/components/facility-creation-modal/ds-mobile-facility-creation-modal.service.ts +0 -135
  61. package/src/components/facility-creation-modal/ds-mobile-facility-creation-modal.ts +0 -656
  62. package/src/components/facility-creation-modal/index.ts +0 -9
  63. package/src/components/facility-creation-modal/sheets/ds-mobile-access-sheet.ts +0 -105
  64. package/src/components/facility-creation-modal/sheets/ds-mobile-price-sheet.ts +0 -188
  65. package/src/components/facility-creation-modal/sheets/ds-mobile-when-can-book-sheet.ts +0 -460
  66. package/src/components/facility-creation-modal/sheets/ds-mobile-who-can-book-sheet.ts +0 -134
  67. package/src/components/facility-detail-modal/ds-mobile-facility-detail-modal.service.ts +0 -69
  68. package/src/components/facility-detail-modal/ds-mobile-facility-detail-modal.ts +0 -379
  69. package/src/components/facility-detail-modal/index.ts +0 -2
  70. package/src/components/file-attachment/ds-mobile-file-attachment.ts +0 -164
  71. package/src/components/file-attachment/index.ts +0 -2
  72. package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.css +0 -214
  73. package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.service.ts +0 -84
  74. package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.ts +0 -424
  75. package/src/components/handbook-detail-modal/index.ts +0 -3
  76. package/src/components/handbook-folder/ds-mobile-handbook-folder-mini.ts +0 -175
  77. package/src/components/handbook-folder/ds-mobile-handbook-folder.ts +0 -533
  78. package/src/components/handbook-folder/index.ts +0 -4
  79. package/src/components/header-content/ds-mobile-header-content.ts +0 -222
  80. package/src/components/header-content/index.ts +0 -2
  81. package/src/components/illustration/ds-mobile-illustration.ts +0 -124
  82. package/src/components/illustration/index.ts +0 -2
  83. package/src/components/index.ts +0 -124
  84. package/src/components/inline-photo/ds-mobile-inline-photo.ts +0 -361
  85. package/src/components/inline-photo/index.ts +0 -1
  86. package/src/components/inline-tabs/ds-mobile-inline-tabs.ts +0 -132
  87. package/src/components/inline-tabs/index.ts +0 -2
  88. package/src/components/interactive-list-item-booking/ds-mobile-interactive-list-item-booking.ts +0 -350
  89. package/src/components/interactive-list-item-booking/index.ts +0 -1
  90. package/src/components/interactive-list-item-inquiry/ds-mobile-interactive-list-item-inquiry.ts +0 -321
  91. package/src/components/interactive-list-item-inquiry/index.ts +0 -2
  92. package/src/components/interactive-list-item-message/ds-mobile-interactive-list-item-message.ts +0 -237
  93. package/src/components/interactive-list-item-message/index.ts +0 -2
  94. package/src/components/interactive-list-item-post/ds-mobile-interactive-list-item-post.ts +0 -549
  95. package/src/components/interactive-list-item-post/ds-mobile-post-pdf-attachment.ts +0 -124
  96. package/src/components/interactive-list-item-post/index.ts +0 -13
  97. package/src/components/lightbox/ds-mobile-lightbox-footer.ts +0 -315
  98. package/src/components/lightbox/ds-mobile-lightbox-header.ts +0 -202
  99. package/src/components/lightbox/ds-mobile-lightbox-image.ts +0 -484
  100. package/src/components/lightbox/ds-mobile-lightbox-pdf.css +0 -377
  101. package/src/components/lightbox/ds-mobile-lightbox-pdf.ts +0 -374
  102. package/src/components/lightbox/ds-mobile-lightbox.css +0 -587
  103. package/src/components/lightbox/ds-mobile-lightbox.service.ts +0 -296
  104. package/src/components/lightbox/ds-mobile-lightbox.ts +0 -529
  105. package/src/components/lightbox/index.ts +0 -22
  106. package/src/components/list-item/ds-mobile-list-item.ts +0 -603
  107. package/src/components/list-item/index.ts +0 -2
  108. package/src/components/list-item-static/ds-mobile-list-item-static.ts +0 -133
  109. package/src/components/list-item-static/index.ts +0 -2
  110. package/src/components/loader-overlay/ds-mobile-loader-overlay.css +0 -49
  111. package/src/components/loader-overlay/ds-mobile-loader-overlay.ts +0 -77
  112. package/src/components/loader-overlay/index.ts +0 -1
  113. package/src/components/logo/ds-logo.ts +0 -95
  114. package/src/components/logo/index.ts +0 -2
  115. package/src/components/message-bubble/ds-mobile-message-bubble.ts +0 -633
  116. package/src/components/message-bubble/index.ts +0 -7
  117. package/src/components/message-composer/ds-mobile-message-composer.ts +0 -1146
  118. package/src/components/message-composer/index.ts +0 -7
  119. package/src/components/modal/ds-mobile-modal.css +0 -163
  120. package/src/components/modal/ds-mobile-modal.service.ts +0 -329
  121. package/src/components/modal/index.ts +0 -8
  122. package/src/components/modal-base/ds-mobile-modal-base.css +0 -378
  123. package/src/components/modal-base/ds-mobile-modal-base.ts +0 -261
  124. package/src/components/modal-base/index.ts +0 -2
  125. package/src/components/new-inquiry-modal/ds-mobile-new-inquiry-modal.css +0 -112
  126. package/src/components/new-inquiry-modal/ds-mobile-new-inquiry-modal.service.ts +0 -93
  127. package/src/components/new-inquiry-modal/ds-mobile-new-inquiry-modal.ts +0 -442
  128. package/src/components/new-inquiry-modal/index.ts +0 -4
  129. package/src/components/offline-banner/ds-mobile-offline-banner.ts +0 -135
  130. package/src/components/offline-banner/index.ts +0 -1
  131. package/src/components/page-details/ds-mobile-page-details.css +0 -83
  132. package/src/components/page-details/ds-mobile-page-details.ts +0 -282
  133. package/src/components/page-details/index.ts +0 -2
  134. package/src/components/page-main/ds-mobile-page-main.css +0 -68
  135. package/src/components/page-main/ds-mobile-page-main.ts +0 -421
  136. package/src/components/page-main/index.ts +0 -2
  137. package/src/components/post-composer/ds-mobile-post-composer.ts +0 -140
  138. package/src/components/post-composer/index.ts +0 -2
  139. package/src/components/post-detail-modal/ds-mobile-post-detail-modal.css +0 -390
  140. package/src/components/post-detail-modal/ds-mobile-post-detail-modal.service.ts +0 -108
  141. package/src/components/post-detail-modal/ds-mobile-post-detail-modal.ts +0 -722
  142. package/src/components/post-detail-modal/index.ts +0 -9
  143. package/src/components/property-banner/ds-mobile-property-banner.ts +0 -95
  144. package/src/components/property-banner/index.ts +0 -2
  145. package/src/components/section/ds-mobile-section.ts +0 -263
  146. package/src/components/section/index.ts +0 -2
  147. package/src/components/shared/directives/index.ts +0 -2
  148. package/src/components/shared/directives/long-press.directive.ts +0 -212
  149. package/src/components/shared/index.ts +0 -3
  150. package/src/components/shared/mobile-modal-base.ts +0 -457
  151. package/src/components/shared/mobile-page-base.ts +0 -204
  152. package/src/components/swiper/ds-mobile-swiper-with-nav.ts +0 -160
  153. package/src/components/swiper/ds-mobile-swiper.ts +0 -327
  154. package/src/components/swiper/index.ts +0 -3
  155. package/src/components/system-message-banner/ds-mobile-system-message-banner.ts +0 -129
  156. package/src/components/system-message-banner/index.ts +0 -2
  157. package/src/components/tab-bar/ds-mobile-tab-bar.css +0 -533
  158. package/src/components/tab-bar/ds-mobile-tab-bar.ts +0 -735
  159. package/src/components/tab-bar/index.ts +0 -2
  160. package/src/components/tabs/ds-mobile-tabs.css +0 -25
  161. package/src/components/tabs/ds-mobile-tabs.ts +0 -89
  162. package/src/components/tabs/index.ts +0 -2
  163. package/src/components/text-input/ds-text-input.ts +0 -287
  164. package/src/components/text-input/index.ts +0 -2
  165. package/src/examples/booking.page.ts +0 -434
  166. package/src/examples/community.page.ts +0 -776
  167. package/src/examples/handbook.page.ts +0 -324
  168. package/src/examples/home.page.ts +0 -347
  169. package/src/examples/index.ts +0 -12
  170. package/src/examples/inquiries.example.ts +0 -273
  171. package/src/examples/inquiry-detail.example.css +0 -189
  172. package/src/examples/inquiry-detail.example.ts +0 -415
  173. package/src/examples/mobile-tabs-example.component.ts +0 -208
  174. package/src/examples/post-create.page.ts +0 -311
  175. package/src/examples/post-detail.page.ts +0 -296
  176. package/src/examples/sign-in.page.ts +0 -291
  177. package/src/examples/whitelabel-demo-modal.component.ts +0 -1094
  178. package/src/examples/whitelabel-demo-modal.service.ts +0 -77
  179. package/src/models/index.ts +0 -7
  180. package/src/models/post.model.ts +0 -41
  181. package/src/pages/community.page.ts +0 -769
  182. package/src/pages/handbook.page.ts +0 -388
  183. package/src/pages/home.page.ts +0 -303
  184. package/src/pages/index.ts +0 -11
  185. package/src/pages/inquiries.example.ts +0 -273
  186. package/src/pages/inquiry-detail.example.css +0 -189
  187. package/src/pages/inquiry-detail.example.ts +0 -415
  188. package/src/pages/mobile-tabs-example.component.ts +0 -179
  189. package/src/pages/post-create.page.ts +0 -311
  190. package/src/pages/post-detail.page.ts +0 -296
  191. package/src/pages/sign-in.page.ts +0 -291
  192. package/src/pages/whitelabel-demo-modal.component.ts +0 -1094
  193. package/src/pages/whitelabel-demo-modal.service.ts +0 -77
  194. package/src/public-api.ts +0 -6
  195. package/src/services/base-modal.service.ts +0 -101
  196. package/src/services/index.ts +0 -11
  197. package/src/services/posts.service.ts +0 -542
  198. package/src/services/tracking-permission.service.ts +0 -88
  199. package/src/services/user.service.ts +0 -60
  200. package/src/services/whitelabel.service.ts +0 -675
  201. package/tsconfig.lib.json +0 -17
  202. package/tsconfig.lib.prod.json +0 -9
  203. package/tsconfig.spec.json +0 -13
  204. /package/{src/assets → assets}/fonts/Brockmann-Bold.otf +0 -0
  205. /package/{src/assets → assets}/fonts/Brockmann-BoldItalic.otf +0 -0
  206. /package/{src/assets → assets}/fonts/Brockmann-Medium.otf +0 -0
  207. /package/{src/assets → assets}/fonts/Brockmann-MediumItalic.otf +0 -0
  208. /package/{src/assets → assets}/fonts/Brockmann-Regular.otf +0 -0
  209. /package/{src/assets → assets}/fonts/Brockmann-RegularItalic.otf +0 -0
  210. /package/{src/assets → assets}/fonts/Brockmann-SemiBold.otf +0 -0
  211. /package/{src/assets → assets}/fonts/Brockmann-SemiBoldItalic.otf +0 -0
  212. /package/{src/assets → assets}/fonts/Brockmann_desktop_license.pdf +0 -0
  213. /package/{src/assets → assets}/fonts/brockmann-medium-webfont.woff2 +0 -0
  214. /package/{src/assets → assets}/fonts/brockmann-mediumitalic-webfont.woff2 +0 -0
  215. /package/{src/assets → assets}/fonts/brockmann-regular-webfont.woff2 +0 -0
  216. /package/{src/assets → assets}/fonts/brockmann-regularitalic-webfont.woff2 +0 -0
  217. /package/{src/assets → assets}/fonts/brockmann-semibold-webfont.woff2 +0 -0
  218. /package/{src/assets → assets}/fonts/brockmann-semibolditalic-webfont.woff2 +0 -0
  219. /package/{src/styles → styles}/ionic.css +0 -0
  220. /package/{src/components/shared → styles}/mobile-common.css +0 -0
  221. /package/{src/components/shared → styles}/mobile-page-base.css +0 -0
@@ -1,415 +0,0 @@
1
- import { Component, signal, computed } from '@angular/core';
2
- import { CommonModule } from '@angular/common';
3
- import { DsIconComponent, DsBadgeComponent } from '@propbinder/design-system';
4
- import { DsMobilePageDetailsComponent } from '../components/page-details';
5
- import { DsMobileInteractiveListItemMessageComponent } from '../components/interactive-list-item-message';
6
- import { DsMobileListItemComponent } from '../components/list-item/ds-mobile-list-item';
7
- import { DsMobileLightboxService, type LightboxImage } from '../components/lightbox';
8
- import { DsMobileChatModalService, type ChatModalData } from '../components/chat-modal';
9
- import { DsAvatarWithBadgeComponent } from '../components/avatar-with-badge';
10
- import { DsMobileCardInlineBannerComponent } from '../components/card-inline-banner';
11
- import { DsMobileSectionComponent } from '../components/section';
12
- import { DsMobileInlinePhotoComponent } from '../components/inline-photo';
13
- import { UserService } from '../services/user.service';
14
- import { type InlineTabItem } from '../components/inline-tabs';
15
-
16
- interface MessageThread {
17
- id: string;
18
- senderName: string;
19
- senderAvatar: string;
20
- senderInitials: string;
21
- message: string;
22
- role: string;
23
- timestamp: string;
24
- unread: boolean;
25
- }
26
-
27
- @Component({
28
- selector: 'app-mobile-inquiry-detail-page',
29
- standalone: true,
30
- imports: [
31
- CommonModule,
32
- DsIconComponent,
33
- DsAvatarWithBadgeComponent,
34
- DsMobilePageDetailsComponent,
35
- DsMobileInteractiveListItemMessageComponent,
36
- DsMobileListItemComponent,
37
- DsBadgeComponent,
38
- DsMobileCardInlineBannerComponent,
39
- DsMobileSectionComponent,
40
- DsMobileInlinePhotoComponent
41
- ],
42
- host: {
43
- class: 'ion-page'
44
- },
45
- styleUrls: [
46
- './inquiry-detail.example.css'
47
- ],
48
- template: `
49
- <ds-mobile-page-details
50
- [title]="inquiryTitle"
51
- [tabs]="tabItems"
52
- [activeTab]="activeTab()"
53
- (tabChange)="setActiveTab($event)"
54
- (back)="goBack()"
55
- (refresh)="handleRefresh($event)">
56
-
57
- <!-- Messages Tab Content -->
58
- @if (activeTab() === 'messages') {
59
- <ds-mobile-section contentGap="0">
60
- @for (message of messageThreads; track message.id) {
61
- <ds-mobile-interactive-list-item-message
62
- [senderName]="message.senderName"
63
- [senderRole]="message.role"
64
- [timestamp]="message.timestamp"
65
- [message]="message.message"
66
- [avatarInitials]="message.senderInitials"
67
- [unread]="message.unread"
68
- (messageClick)="openMessage(message.id)">
69
- </ds-mobile-interactive-list-item-message>
70
- }
71
- </ds-mobile-section>
72
- }
73
-
74
- <!-- Details Tab Content -->
75
- @if (activeTab() === 'details') {
76
- <!-- Unread Messages Banner -->
77
- @if (hasUnreadMessages()) {
78
- <ds-mobile-section>
79
- <ds-mobile-card-inline-banner
80
- [title]="'Du har ulæste beskeder'"
81
- [unreadCount]="3"
82
- [layout]="'compact'"
83
- (bannerClick)="navigateToMessagesTab()">
84
- </ds-mobile-card-inline-banner>
85
- </ds-mobile-section>
86
- }
87
-
88
- <!-- All Details in One Section -->
89
- <ds-mobile-section contentGap="0">
90
- <!-- Assignee -->
91
- <ds-mobile-list-item [leadingSize]="'32px'" [showDivider]="true">
92
- <div content-leading>
93
- <ds-avatar-with-badge
94
- [size]="'sm'"
95
- [type]="'initials'"
96
- [initials]="'R'" />
97
- </div>
98
- <div content-main>
99
- <div class="detail-label">Sagsbehandler</div>
100
- <div class="detail-value">Ricki Meihlen</div>
101
- </div>
102
- </ds-mobile-list-item>
103
-
104
- <!-- Technician -->
105
- <ds-mobile-list-item [leadingSize]="'32px'" [showDivider]="true">
106
- <div content-leading>
107
- <ds-avatar-with-badge
108
- [size]="'sm'"
109
- [type]="'initials'"
110
- [initials]="'M'" />
111
- </div>
112
- <div content-main>
113
- <div class="detail-label">Tekniker</div>
114
- <div class="detail-value">Martin Smith</div>
115
- </div>
116
- </ds-mobile-list-item>
117
-
118
- <!-- Creation Date -->
119
- <ds-mobile-list-item [leadingSize]="'32px'" [showDivider]="true" [align]="'center'">
120
- <ds-icon content-leading name="remixTimeLine" size="20px" color="tertiary" />
121
- <div content-main>
122
- <div class="detail-value">22. feb 2025</div>
123
- </div>
124
- </ds-mobile-list-item>
125
-
126
- <!-- Title -->
127
- <ds-mobile-list-item [leadingSize]="'32px'" [showDivider]="true" [align]="'center'">
128
- <ds-icon content-leading name="remixTextBlock" size="20px" color="tertiary" />
129
- <div content-main>
130
- <div class="detail-value">{{ inquiryTitle }}</div>
131
- </div>
132
- </ds-mobile-list-item>
133
-
134
- <!-- Description -->
135
- <ds-mobile-list-item [leadingSize]="'32px'" [showDivider]="true">
136
- <ds-icon content-leading name="remixAlignLeft" size="20px" color="tertiary" />
137
- <div content-main>
138
- <div class="detail-value description-text">
139
- 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.
140
- </div>
141
- <ds-badge content="Husholdningsapparater" size="sm"/>
142
- </div>
143
- </ds-mobile-list-item>
144
-
145
- <!-- Photos -->
146
- <ds-mobile-list-item [leadingSize]="'32px'" [showDivider]="false">
147
- <ds-icon content-leading name="remixCameraLine" size="20px" color="tertiary" />
148
- <div content-main>
149
- <ds-mobile-inline-photo
150
- [images]="photoUrls"
151
- [useGrid]="false"
152
- (photoClick)="openPhotoLightbox($event.index)" />
153
- </div>
154
- </ds-mobile-list-item>
155
- </ds-mobile-section>
156
- }
157
- </ds-mobile-page-details>
158
- `
159
- })
160
- export class MobileInquiryDetailPageComponent {
161
- inquiryTitle = 'Tørretumbler virker ikke';
162
- activeTab = signal<string>('details');
163
-
164
- tabItems: InlineTabItem[] = [
165
- { id: 'details', label: 'Detaljer' },
166
- { id: 'messages', label: 'Beskeder', badge: 0 }
167
- ];
168
-
169
- messageThreads: MessageThread[] = [
170
- {
171
- id: '1',
172
- senderName: 'Ove Hindborg',
173
- senderAvatar: '',
174
- senderInitials: 'OH',
175
- message: 'Dejligt at høre! Jeg venter på din teknikerbesøg tidsplan.',
176
- role: 'Sagsbehandler',
177
- timestamp: '2t siden',
178
- unread: true
179
- },
180
- {
181
- id: '2',
182
- senderName: 'Martin Smith',
183
- senderAvatar: '',
184
- senderInitials: 'MS',
185
- message: 'Martin Smith har overtaget din henvendelse og vil kontakte dig snart.',
186
- role: 'Tekniker',
187
- timestamp: '',
188
- unread: false
189
- }
190
- ];
191
-
192
- unreadMessagesCount = computed(() => {
193
- const count = this.messageThreads.length;
194
- // Update badge in tab items
195
- const messagesTab = this.tabItems.find(t => t.id === 'messages');
196
- if (messagesTab) {
197
- messagesTab.badge = count;
198
- }
199
- return count;
200
- });
201
-
202
- // Photos for lightbox
203
- photos: LightboxImage[] = [
204
- { type: 'image', src: '/Assets/Dummy-photos/handyman.jpg', alt: 'Handyman', title: 'Handyman' },
205
- { type: 'image', src: '/Assets/Dummy-photos/balcony-view.jpg', alt: 'Balcony view', title: 'Balcony view' },
206
- { type: 'image', src: '/Assets/Dummy-photos/staircase.jpg', alt: 'Staircase', title: 'Staircase' },
207
- { type: 'image', src: '/Assets/Dummy-photos/yard.jpg', alt: 'Yard', title: 'Yard' },
208
- { type: 'image', src: '/Assets/Dummy-photos/mailboxes.jpg', alt: 'Mailboxes', title: 'Mailboxes' }
209
- ];
210
-
211
- // Photo URLs for inline-photo component
212
- get photoUrls(): string[] {
213
- return this.photos.map(photo => photo.src);
214
- }
215
-
216
- constructor(
217
- public userService: UserService,
218
- private lightbox: DsMobileLightboxService,
219
- private chatModal: DsMobileChatModalService
220
- ) {
221
- // Trigger initial badge update
222
- this.unreadMessagesCount();
223
- }
224
-
225
- setActiveTab(tabId: string): void {
226
- this.activeTab.set(tabId);
227
- }
228
-
229
- goBack(): void {
230
- // Navigation is handled by ds-mobile-page-details component
231
- // This is just for any custom logic if needed
232
- }
233
-
234
- handleRefresh(event: any): void {
235
- console.log('Pull-to-refresh triggered');
236
- setTimeout(() => {
237
- console.log('Refresh complete');
238
- event.target.complete();
239
- }, 1000);
240
- }
241
-
242
- /**
243
- * Check if there are unread messages
244
- */
245
- hasUnreadMessages(): boolean {
246
- return this.messageThreads.some(m => m.unread);
247
- }
248
-
249
- /**
250
- * Navigate to messages tab when banner is clicked
251
- */
252
- navigateToMessagesTab(): void {
253
- this.setActiveTab('messages');
254
- }
255
-
256
- async openMessage(messageId: string): Promise<void> {
257
- console.log('Opening message:', messageId);
258
-
259
- // Find the message thread
260
- const messageThread = this.messageThreads.find(m => m.id === messageId);
261
- if (!messageThread) {
262
- console.error('Message thread not found:', messageId);
263
- return;
264
- }
265
-
266
- // Check if this is an empty state chat (no timestamp and system message)
267
- const isEmptyChat = messageThread.message.includes('har overtaget din henvendelse') && !messageThread.timestamp;
268
-
269
- // Prepare chat modal data
270
- // In a real app, you would fetch the actual messages from your API
271
- const chatData: ChatModalData = {
272
- participant: {
273
- id: messageId,
274
- name: messageThread.senderName,
275
- role: messageThread.role,
276
- avatarInitials: messageThread.senderInitials,
277
- avatarType: 'initials'
278
- },
279
- messages: isEmptyChat ? [] : [
280
- // Day 1 - Yesterday morning (9:15 AM)
281
- {
282
- id: '1',
283
- content: 'Godmorgen! Jeg ville lige følge op på din henvendelse vedrørende vedligeholdelsesplanen.',
284
- senderId: messageId,
285
- senderName: messageThread.senderName,
286
- senderRole: messageThread.role,
287
- timestamp: new Date(Date.now() - 86400000 - 32700000), // Yesterday 9:15 AM
288
- isOwnMessage: false,
289
- avatarInitials: messageThread.senderInitials,
290
- avatarType: 'initials',
291
- },
292
- {
293
- id: '2',
294
- content: 'Vi har gennemgået din sag og identificeret den grundlæggende årsag til problemet.',
295
- senderId: messageId,
296
- senderName: messageThread.senderName,
297
- senderRole: messageThread.role,
298
- timestamp: new Date(Date.now() - 86400000 - 32520000), // Yesterday 9:18 AM (grouped with previous)
299
- isOwnMessage: false,
300
- avatarInitials: messageThread.senderInitials,
301
- avatarType: 'initials',
302
- },
303
- {
304
- id: '3',
305
- content: 'Tak fordi du kiggede på det! Hvad fandt du?',
306
- senderId: 'current-user',
307
- senderName: 'You',
308
- timestamp: new Date(Date.now() - 86400000 - 32100000), // Yesterday 9:25 AM (new group - 7 min gap)
309
- isOwnMessage: true,
310
- avatarInitials: this.userService.avatarInitials(),
311
- avatarType: 'initials',
312
- },
313
- {
314
- id: '4',
315
- content: 'Kan du også sende mig vedligeholdelsesrapporten?',
316
- senderId: 'current-user',
317
- senderName: 'You',
318
- timestamp: new Date(Date.now() - 86400000 - 31980000), // Yesterday 9:27 AM (grouped with previous)
319
- isOwnMessage: true,
320
- avatarInitials: this.userService.avatarInitials(),
321
- avatarType: 'initials',
322
- },
323
-
324
- // Day 1 - Yesterday afternoon (2:30 PM - large time gap)
325
- {
326
- id: '5',
327
- content: messageThread.message,
328
- senderId: messageId,
329
- senderName: messageThread.senderName,
330
- senderRole: messageThread.role,
331
- timestamp: new Date(Date.now() - 86400000 - 13800000), // Yesterday 2:30 PM (new group - 5 hour gap)
332
- isOwnMessage: false,
333
- avatarInitials: messageThread.senderInitials,
334
- avatarType: 'initials',
335
- },
336
- {
337
- id: '6',
338
- content: 'Jeg har vedhæftet den detaljerede rapport på dit henvendelsesdashboard. Gennemgå den gerne, når du har et øjeblik.',
339
- senderId: messageId,
340
- senderName: messageThread.senderName,
341
- senderRole: messageThread.role,
342
- timestamp: new Date(Date.now() - 86400000 - 13620000), // Yesterday 2:33 PM (grouped with previous)
343
- isOwnMessage: false,
344
- avatarInitials: messageThread.senderInitials,
345
- avatarType: 'initials',
346
- },
347
-
348
- // Day 2 - Today morning (10:45 AM - new day)
349
- {
350
- id: '7',
351
- content: 'Perfekt! Jeg har gennemgået rapporten, og alt ser godt ud.',
352
- senderId: 'current-user',
353
- senderName: 'You',
354
- timestamp: new Date(Date.now() - 7500000), // Today 10:45 AM (new group - new day)
355
- isOwnMessage: true,
356
- avatarInitials: this.userService.avatarInitials(),
357
- avatarType: 'initials',
358
- },
359
- {
360
- id: '8',
361
- content: 'Hvornår kan vi planlægge vedligeholdelsesarbejdet?',
362
- senderId: 'current-user',
363
- senderName: 'You',
364
- timestamp: new Date(Date.now() - 7320000), // Today 10:48 AM (grouped with previous)
365
- isOwnMessage: true,
366
- avatarInitials: this.userService.avatarInitials(),
367
- avatarType: 'initials',
368
- },
369
-
370
- // Day 2 - Today (just now - 2 minutes ago)
371
- {
372
- id: '9',
373
- content: 'Dejligt at høre! Jeg kan planlægge det til næste tirsdag kl. 09.00. Passer det dig?',
374
- senderId: messageId,
375
- senderName: messageThread.senderName,
376
- senderRole: messageThread.role,
377
- timestamp: new Date(Date.now() - 120000), // 2 minutes ago (new group - several hours gap)
378
- isOwnMessage: false,
379
- avatarInitials: messageThread.senderInitials,
380
- avatarType: 'initials',
381
- },
382
- {
383
- id: '10',
384
- content: 'Jeg sender dig en kalenderinvitation med alle detaljerne.',
385
- senderId: messageId,
386
- senderName: messageThread.senderName,
387
- senderRole: messageThread.role,
388
- timestamp: new Date(Date.now() - 60000), // 1 minute ago (grouped with previous)
389
- isOwnMessage: false,
390
- avatarInitials: messageThread.senderInitials,
391
- avatarType: 'initials',
392
- }
393
- ],
394
- currentUserId: 'current-user',
395
- currentUserInitials: this.userService.avatarInitials(),
396
- currentUserAvatarType: 'initials',
397
- autoFocus: false
398
- };
399
-
400
- // Open the chat modal
401
- await this.chatModal.open(chatData);
402
- }
403
-
404
- async openPhotoLightbox(index: number): Promise<void> {
405
- await this.lightbox.openImages({
406
- images: this.photos,
407
- initialIndex: index,
408
- showControls: true,
409
- enableSwipe: true,
410
- enableZoom: true,
411
- showInfo: false
412
- });
413
- }
414
- }
415
-
@@ -1,208 +0,0 @@
1
- import { Component, OnInit, computed, effect, inject } from '@angular/core';
2
- import { Router } from '@angular/router';
3
- import { CommonModule } from '@angular/common';
4
- import { IonTabs } from '@ionic/angular/standalone';
5
- import { UserService } from '../services/user.service';
6
- import { DsMobileTabBarComponent, TabConfig } from '../components/tab-bar';
7
- import { ActionResult, ActionGroup } from '../components/bottom-sheet';
8
- import { WhitelabelDemoModalService } from './whitelabel-demo-modal.service';
9
- import { TrackingPermissionService } from '../services/tracking-permission.service';
10
-
11
- /**
12
- * MobileTabsExampleComponent
13
- *
14
- * Example page using the TenantApp pattern:
15
- * - Uses ion-tabs as wrapper (required for Angular routing)
16
- * - Uses ds-mobile-tab-bar inside (not ds-mobile-tabs)
17
- *
18
- * This matches the pattern used in TenantApp for consistency.
19
- */
20
- @Component({
21
- selector: 'app-mobile-tabs-example',
22
- standalone: true,
23
- imports: [CommonModule, IonTabs, DsMobileTabBarComponent],
24
- styles: [
25
- `
26
- :host {
27
- display: block;
28
- height: 100dvh;
29
- width: 100vw;
30
- position: relative;
31
- }
32
- `,
33
- ],
34
- template: `
35
- <ion-tabs class="ds-tabs-wrapper">
36
- <!-- Tab bar with slot="top" on desktop, slot="bottom" on mobile -->
37
- <!-- Ionic automatically creates ion-tab elements from child routes -->
38
- <ds-mobile-tab-bar
39
- [tabs]="tabs"
40
- [avatarInitials]="userService.avatarInitials()"
41
- [avatarType]="userService.avatarType()"
42
- [profileMenuItems]="profileMenuItems"
43
- (profileActionSelected)="handleProfileAction($event)"
44
- >
45
- </ds-mobile-tab-bar>
46
- </ion-tabs>
47
- `,
48
- })
49
- export class MobileTabsExampleComponent implements OnInit {
50
- private whitelabelDemoModal = inject(WhitelabelDemoModalService);
51
- private trackingPermissionService = inject(TrackingPermissionService);
52
- private trackedProfileMenuItems = computed<ActionGroup[]>(() => {
53
- const accountActions = [
54
- {
55
- action: 'profile',
56
- title: 'Min profil',
57
- icon: 'remixUser3Line',
58
- destructive: false,
59
- },
60
- {
61
- action: 'settings',
62
- title: 'Indstillinger',
63
- icon: 'remixSettings3Line',
64
- destructive: false,
65
- },
66
- {
67
- action: 'appearance',
68
- title: 'Udseende',
69
- icon: 'remixPaletteLine',
70
- destructive: false,
71
- },
72
- ];
73
-
74
- if (this.trackingPermissionService.shouldShowSettingsReminder()) {
75
- accountActions.push({
76
- action: 'tracking-settings',
77
- title: 'Sporingsindstillinger',
78
- icon: 'remixSettings3Line',
79
- destructive: false,
80
- });
81
- }
82
-
83
- return [
84
- {
85
- actions: accountActions,
86
- },
87
- {
88
- actions: [
89
- {
90
- action: 'language',
91
- title: 'Sprog',
92
- subtitle: 'Dansk',
93
- flagIcon: '/Assets/country-flags/denmark.svg',
94
- icon: 'remixGlobalLine',
95
- destructive: false,
96
- showChevron: true,
97
- },
98
- ],
99
- },
100
- {
101
- actions: [
102
- {
103
- action: 'logout',
104
- title: 'Log ud',
105
- icon: 'remixLogoutBoxLine',
106
- destructive: true,
107
- },
108
- ],
109
- },
110
- ];
111
- });
112
-
113
- constructor(
114
- public userService: UserService,
115
- private router: Router,
116
- ) {
117
- console.log('MobileTabsExampleComponent constructor');
118
- effect(() => {
119
- this.userService.setProfileMenuItems(this.trackedProfileMenuItems());
120
- });
121
- }
122
-
123
- ngOnInit() {
124
- console.log('MobileTabsExampleComponent ngOnInit');
125
- // Configure user avatar globally - this is now the single source of truth
126
- this.userService.setAvatarInitials('LM');
127
- this.userService.setAvatarType('initials');
128
-
129
- // Initial status refresh ensures menu reflects past ATT choice.
130
- void this.trackingPermissionService.refreshTrackingStatus();
131
- }
132
-
133
- tabs: TabConfig[] = [
134
- {
135
- id: 'home',
136
- label: 'Hjem',
137
- route: 'home',
138
- icon: 'remixHomeSmile2Line',
139
- iconActive: 'remixHomeSmile2Fill',
140
- },
141
- {
142
- id: 'inquiries',
143
- label: 'Henvendelser',
144
- route: 'inquiries',
145
- icon: 'remixFileList3Line',
146
- iconActive: 'remixFileList3Fill',
147
- },
148
- {
149
- id: 'announcements',
150
- label: 'Fællesskab',
151
- route: 'announcements',
152
- icon: 'remixCommunityLine',
153
- iconActive: 'remixCommunityFill',
154
- },
155
- {
156
- id: 'booking',
157
- label: 'Booking',
158
- route: 'booking',
159
- icon: 'remixCalendarCheckLine',
160
- iconActive: 'remixCalendarCheckFill',
161
- },
162
- {
163
- id: 'handbook',
164
- label: 'Håndbog',
165
- route: 'handbook',
166
- icon: 'remixBook2Line',
167
- iconActive: 'remixBook2Fill',
168
- },
169
- ];
170
-
171
- /**
172
- * Profile menu items configuration.
173
- * Define once here - this is set globally in UserService in ngOnInit(),
174
- * so it will be used by both ds-mobile-tab-bar and ds-mobile-page-main components
175
- * throughout the entire application.
176
- */
177
- get profileMenuItems(): ActionGroup[] {
178
- return this.trackedProfileMenuItems();
179
- }
180
-
181
- /**
182
- * Handle profile menu action selection.
183
- * The tab bar component handles the UI (opening/closing menu),
184
- * this method handles the business logic.
185
- *
186
- * NOTE: Desktop only - called directly from tab bar.
187
- * Mobile actions are handled globally in AppComponent via UserService.
188
- */
189
- handleProfileAction(result: ActionResult): void {
190
- console.log('Profile action selected (desktop tab bar):', result.action);
191
-
192
- // Handle appearance action here (opens modal)
193
- if (result.action === 'appearance') {
194
- console.log('Opening whitelabel demo...');
195
- // Small delay to ensure bottom sheet is fully dismissed
196
- setTimeout(async () => {
197
- try {
198
- await this.whitelabelDemoModal.open();
199
- } catch (error) {
200
- console.error('Failed to open whitelabel demo modal:', error);
201
- }
202
- }, 100);
203
- }
204
-
205
- // Notify globally so AppComponent can handle navigation
206
- this.userService.notifyProfileAction(result);
207
- }
208
- }