@propbinder/mobile-design 0.0.2 → 0.0.22

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 (123) hide show
  1. package/fesm2022/propbinder-mobile-design.mjs +12604 -0
  2. package/fesm2022/propbinder-mobile-design.mjs.map +1 -0
  3. package/index.d.ts +3214 -0
  4. package/package.json +39 -12
  5. package/ng-package.json +0 -7
  6. package/src/animations/page-transitions.ts +0 -86
  7. package/src/assets/fonts/Brockmann-Bold.otf +0 -0
  8. package/src/assets/fonts/Brockmann-BoldItalic.otf +0 -0
  9. package/src/assets/fonts/Brockmann-Medium.otf +0 -0
  10. package/src/assets/fonts/Brockmann-MediumItalic.otf +0 -0
  11. package/src/assets/fonts/Brockmann-Regular.otf +0 -0
  12. package/src/assets/fonts/Brockmann-RegularItalic.otf +0 -0
  13. package/src/assets/fonts/Brockmann-SemiBold.otf +0 -0
  14. package/src/assets/fonts/Brockmann-SemiBoldItalic.otf +0 -0
  15. package/src/assets/fonts/Brockmann_desktop_license.pdf +0 -0
  16. package/src/assets/fonts/brockmann-medium-webfont.woff2 +0 -0
  17. package/src/assets/fonts/brockmann-regular-webfont.woff2 +0 -0
  18. package/src/assets/fonts/brockmann-semibold-webfont.woff2 +0 -0
  19. package/src/components/action-list-item/ds-mobile-action-list-item.ts +0 -83
  20. package/src/components/action-list-item/index.ts +0 -2
  21. package/src/components/app-layout/ds-mobile-app-layout.css +0 -343
  22. package/src/components/app-layout/ds-mobile-app-layout.ts +0 -271
  23. package/src/components/app-layout/index.ts +0 -2
  24. package/src/components/avatar-with-badge/ds-avatar-with-badge.ts +0 -130
  25. package/src/components/avatar-with-badge/index.ts +0 -2
  26. package/src/components/bottom-sheet/ds-mobile-actions-bottom-sheet.ts +0 -273
  27. package/src/components/bottom-sheet/ds-mobile-bottom-sheet.css +0 -110
  28. package/src/components/bottom-sheet/ds-mobile-bottom-sheet.service.ts +0 -167
  29. package/src/components/bottom-sheet/ds-mobile-post-create-bottom-sheet.ts +0 -656
  30. package/src/components/bottom-sheet/index.ts +0 -3
  31. package/src/components/comment/ds-mobile-comment.ts +0 -516
  32. package/src/components/comment/index.ts +0 -2
  33. package/src/components/contact-list-item/ds-mobile-contact-list-item.ts +0 -182
  34. package/src/components/contact-list-item/index.ts +0 -2
  35. package/src/components/content/ds-mobile-content.ts +0 -158
  36. package/src/components/content/index.ts +0 -2
  37. package/src/components/ds-mobile-tabs.css +0 -372
  38. package/src/components/ds-mobile-tabs.ts +0 -217
  39. package/src/components/file-attachment/ds-mobile-file-attachment.ts +0 -164
  40. package/src/components/file-attachment/index.ts +0 -2
  41. package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.service.ts +0 -98
  42. package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.ts +0 -514
  43. package/src/components/handbook-detail-modal/index.ts +0 -3
  44. package/src/components/handbook-folder/ds-mobile-handbook-folder-mini.ts +0 -130
  45. package/src/components/handbook-folder/ds-mobile-handbook-folder.ts +0 -444
  46. package/src/components/handbook-folder/index.ts +0 -4
  47. package/src/components/header-content/ds-mobile-header-content.ts +0 -211
  48. package/src/components/header-content/index.ts +0 -2
  49. package/src/components/index.ts +0 -45
  50. package/src/components/inline-photo/ds-mobile-inline-photo.ts +0 -269
  51. package/src/components/inline-photo/index.ts +0 -1
  52. package/src/components/interactive-list-item-inquiry/ds-mobile-interactive-list-item-inquiry.css +0 -60
  53. package/src/components/interactive-list-item-inquiry/ds-mobile-interactive-list-item-inquiry.ts +0 -280
  54. package/src/components/interactive-list-item-inquiry/index.ts +0 -2
  55. package/src/components/interactive-list-item-message/ds-mobile-interactive-list-item-message.ts +0 -197
  56. package/src/components/interactive-list-item-message/index.ts +0 -2
  57. package/src/components/interactive-list-item-post/ds-mobile-interactive-list-item-post.css +0 -70
  58. package/src/components/interactive-list-item-post/ds-mobile-interactive-list-item-post.ts +0 -594
  59. package/src/components/interactive-list-item-post/ds-mobile-post-pdf-attachment.ts +0 -124
  60. package/src/components/interactive-list-item-post/index.ts +0 -13
  61. package/src/components/lightbox/ds-mobile-lightbox-footer.ts +0 -331
  62. package/src/components/lightbox/ds-mobile-lightbox-header.ts +0 -173
  63. package/src/components/lightbox/ds-mobile-lightbox-image.ts +0 -464
  64. package/src/components/lightbox/ds-mobile-lightbox-pdf.css +0 -375
  65. package/src/components/lightbox/ds-mobile-lightbox-pdf.ts +0 -374
  66. package/src/components/lightbox/ds-mobile-lightbox.css +0 -587
  67. package/src/components/lightbox/ds-mobile-lightbox.service.ts +0 -293
  68. package/src/components/lightbox/ds-mobile-lightbox.ts +0 -529
  69. package/src/components/lightbox/index.ts +0 -22
  70. package/src/components/list-item/ds-mobile-list-item.ts +0 -499
  71. package/src/components/list-item/index.ts +0 -2
  72. package/src/components/list-item-static/ds-mobile-list-item-static.ts +0 -133
  73. package/src/components/list-item-static/index.ts +0 -2
  74. package/src/components/logo/ds-logo.ts +0 -85
  75. package/src/components/logo/index.ts +0 -2
  76. package/src/components/modal/ds-mobile-modal.css +0 -163
  77. package/src/components/modal/ds-mobile-modal.service.ts +0 -329
  78. package/src/components/modal/index.ts +0 -8
  79. package/src/components/page-details/ds-mobile-page-details.css +0 -285
  80. package/src/components/page-details/ds-mobile-page-details.ts +0 -128
  81. package/src/components/page-details/index.ts +0 -2
  82. package/src/components/page-main/ds-mobile-page-main.css +0 -346
  83. package/src/components/page-main/ds-mobile-page-main.ts +0 -331
  84. package/src/components/page-main/index.ts +0 -2
  85. package/src/components/post-card/ds-mobile-post-card.ts +0 -685
  86. package/src/components/post-card/ds-mobile-post-pdf-attachment.ts +0 -124
  87. package/src/components/post-card/index.ts +0 -11
  88. package/src/components/post-composer/ds-mobile-post-composer.ts +0 -140
  89. package/src/components/post-composer/index.ts +0 -2
  90. package/src/components/post-detail-modal/ds-mobile-post-detail-modal.service.ts +0 -104
  91. package/src/components/post-detail-modal/ds-mobile-post-detail-modal.ts +0 -1273
  92. package/src/components/post-detail-modal/index.ts +0 -9
  93. package/src/components/shared/directives/index.ts +0 -2
  94. package/src/components/shared/directives/long-press.directive.ts +0 -208
  95. package/src/components/shared/index.ts +0 -3
  96. package/src/components/shared/mobile-common.css +0 -94
  97. package/src/components/shared/mobile-page-base.css +0 -315
  98. package/src/components/shared/mobile-page-base.ts +0 -70
  99. package/src/components/swiper/ds-mobile-swiper.ts +0 -123
  100. package/src/components/swiper/index.ts +0 -2
  101. package/src/components/tab-bar/ds-mobile-tab-bar.ts +0 -132
  102. package/src/components/tab-bar/index.ts +0 -2
  103. package/src/components/tabs/ds-mobile-tabs.css +0 -405
  104. package/src/components/tabs/ds-mobile-tabs.ts +0 -204
  105. package/src/components/tabs/index.ts +0 -2
  106. package/src/pages/community.page.ts +0 -768
  107. package/src/pages/handbook.page.ts +0 -298
  108. package/src/pages/home.page.ts +0 -192
  109. package/src/pages/index.ts +0 -9
  110. package/src/pages/inquiries.example.ts +0 -212
  111. package/src/pages/inquiry-detail.example.css +0 -434
  112. package/src/pages/inquiry-detail.example.ts +0 -416
  113. package/src/pages/mobile-tabs-example.component.ts +0 -146
  114. package/src/pages/post-create.page.ts +0 -311
  115. package/src/pages/post-detail.page.ts +0 -295
  116. package/src/pages/whitelabel-demo.page.ts +0 -548
  117. package/src/public-api.ts +0 -5
  118. package/src/services/user.service.ts +0 -35
  119. package/src/services/whitelabel.service.ts +0 -171
  120. package/src/styles/ionic.css +0 -673
  121. package/tsconfig.lib.json +0 -17
  122. package/tsconfig.lib.prod.json +0 -9
  123. package/tsconfig.spec.json +0 -13
@@ -1,768 +0,0 @@
1
- import { Component, signal, computed } from '@angular/core';
2
- import { Router, ActivatedRoute } from '@angular/router';
3
- import { DsIconComponent } from '@propbinder/design-system';
4
- import { DsMobilePageMainComponent } from '../components/page-main';
5
- import { DsMobileContentComponent } from '../components/content';
6
- import { DsMobileInteractiveListItemPostComponent, PostPdfAttachmentComponent } from '../components/interactive-list-item-post';
7
- import {
8
- PostContentComponent,
9
- PostTextComponent,
10
- PostMediaComponent,
11
- PostAttachmentsComponent,
12
- PostActionsComponent,
13
- ActionLikeComponent,
14
- ActionCommentComponent
15
- } from '../components/interactive-list-item-post';
16
- import { DsMobilePostComposerComponent } from '../components/post-composer';
17
- import { DsMobileBottomSheetService } from '../components/bottom-sheet/ds-mobile-bottom-sheet.service';
18
- import { DsMobilePostCreateBottomSheetComponent } from '../components/bottom-sheet/ds-mobile-post-create-bottom-sheet';
19
- import { DsMobilePostActionsBottomSheetComponent, PostActionResult } from '../components/bottom-sheet';
20
- import { DsMobileLightboxService, LightboxAuthor } from '../components/lightbox';
21
- import { DsMobilePostDetailModalService } from '../components/post-detail-modal';
22
- import { DsMobileInlinePhotoComponent } from '../components/inline-photo';
23
- import { UserService } from '../services/user.service';
24
-
25
- @Component({
26
- selector: 'app-mobile-community-page',
27
- standalone: true,
28
- imports: [
29
- DsMobilePageMainComponent,
30
- DsMobileContentComponent,
31
- DsMobileInteractiveListItemPostComponent,
32
- DsMobilePostComposerComponent,
33
- PostContentComponent,
34
- PostTextComponent,
35
- PostMediaComponent,
36
- PostAttachmentsComponent,
37
- PostActionsComponent,
38
- ActionLikeComponent,
39
- ActionCommentComponent,
40
- PostPdfAttachmentComponent,
41
- DsIconComponent,
42
- DsMobileInlinePhotoComponent
43
- ],
44
- styles: [`
45
- .post-feed {
46
- display: flex;
47
- flex-direction: column;
48
- max-width: 640px;
49
- }
50
-
51
- .post-list-wrapper {
52
- display: flex;
53
- flex-direction: column;
54
- }
55
-
56
- /* Remove custom dividers - now handled by ds-mobile-list-item */
57
-
58
- .pinned-posts-section {
59
- margin: -12px -12px 12px -12px;
60
- padding: 0 12px 12px 12px;
61
- box-shadow: var(--box-shadow-sm);
62
- border-radius: 16px;
63
- border: 1px solid var(--border-color-default);
64
- }
65
-
66
- .clickable-image {
67
- cursor: pointer;
68
- transition: transform 0.2s ease, opacity 0.2s ease;
69
- border-radius: 8px;
70
- display: block;
71
- width: 100%;
72
- aspect-ratio: 16/9;
73
- object-fit: cover;
74
- }
75
-
76
- .clickable-image:active {
77
- transform: scale(0.98);
78
- opacity: 0.9;
79
- }
80
-
81
- /* Empty State */
82
- .community-empty-state {
83
- display: flex;
84
- flex-direction: column;
85
- align-items: center;
86
- justify-content: center;
87
- padding: 60px 20px;
88
- text-align: center;
89
- }
90
-
91
- .empty-state-image {
92
- width: 96px;
93
- height: 96px;
94
- margin-bottom: 24px;
95
- }
96
- `],
97
- template: `
98
- <ds-mobile-page-main
99
- title="Fællesskab"
100
- [avatarInitials]="userService.avatarInitials()"
101
- [avatarType]="userService.avatarType()"
102
- (refresh)="handleRefresh($event)">
103
-
104
- <!-- Post Composer in header-expandable -->
105
- <ds-mobile-post-composer
106
- header-content
107
- [avatarInitials]="userService.avatarInitials()"
108
- [avatarType]="userService.avatarType()"
109
- [avatarSrc]="userService.avatarSrc()"
110
- (composerClick)="openPostCreator()"
111
- />
112
-
113
- <ds-mobile-content>
114
- <div class="post-feed">
115
- <!-- Pinned Posts Section -->
116
- <div class="pinned-posts-section">
117
- <h2 class="section-headline">
118
- <ds-icon name="remixPushpinFill" size="16px" color="primary" />
119
- Fastgjorte opslag
120
- </h2>
121
-
122
- <!-- Pinned: Maintenance Announcement -->
123
- <ds-mobile-interactive-list-item-post
124
- [authorName]="'Karen Nielsen'"
125
- [authorRole]="'Ejendomsadministrator'"
126
- [timestamp]="'2d siden'"
127
- [avatarInitials]="'KN'"
128
- [showBadge]="true"
129
- [clickable]="true"
130
- (postClick)="openPost('4')"
131
- (commentClick)="openPost('4', true)"
132
- (longPress)="handlePostLongPress('4', false)">
133
-
134
- <post-content>
135
- <post-text>📢 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!</post-text>
136
-
137
- <post-attachments>
138
- <post-pdf-attachment
139
- [fileName]="'Husregler.pdf'"
140
- [fileSize]="'245 KB'"
141
- (pdfClick)="openHouseRulesPdf()">
142
- </post-pdf-attachment>
143
- </post-attachments>
144
- </post-content>
145
-
146
- <post-actions>
147
- <action-like [count]="89" />
148
- <action-comment [count]="67" (commentClick)="openPost('4', true)" />
149
- </post-actions>
150
- </ds-mobile-interactive-list-item-post>
151
- </div>
152
-
153
- <!-- All Posts Section -->
154
- <h2 class="section-headline">Alle opslag</h2>
155
-
156
- @if (hasAnyPosts()) {
157
- <div class="post-list-wrapper">
158
- <!-- User Created Posts -->
159
- @for (post of userPosts(); track $index) {
160
- <ds-mobile-interactive-list-item-post
161
- [authorName]="post.authorName"
162
- [authorRole]="post.authorRole"
163
- [timestamp]="post.timestamp"
164
- [avatarType]="post.avatarType"
165
- [avatarSrc]="post.avatarSrc"
166
- [avatarInitials]="post.avatarInitials"
167
- [clickable]="true"
168
- (postClick)="openUserPost($index)"
169
- (commentClick)="openUserPost($index, true)"
170
- (longPress)="handlePostLongPress($index, post.authorRole === 'Dig')">
171
-
172
- <post-content>
173
- @if (post.content) {
174
- <post-text>{{ post.content }}</post-text>
175
- }
176
- @if (post.imageSrc) {
177
- <post-media>
178
- <img
179
- [src]="post.imageSrc"
180
- [alt]="post.imageAlt || 'Posted image'"
181
- class="clickable-image"
182
- (click)="openImageLightbox(post.imageSrc, post.imageAlt || 'Posted image', post.content, $event)"
183
- />
184
- </post-media>
185
- }
186
- </post-content>
187
-
188
- <post-actions>
189
- <action-like [count]="post.likeCount" [active]="post.isLiked" />
190
- <action-comment [count]="post.commentCount" (commentClick)="openUserPost($index, true)" />
191
- </post-actions>
192
- </ds-mobile-interactive-list-item-post>
193
- }
194
-
195
- <!-- Post 1: Text only -->
196
- <ds-mobile-interactive-list-item-post
197
- [authorName]="'Anders Jensen'"
198
- [authorRole]="'Lejer'"
199
- [timestamp]="'2t siden'"
200
- [avatarType]="'photo'"
201
- [avatarSrc]="'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=100&h=100&fit=crop&crop=face'"
202
- [clickable]="true"
203
- (postClick)="openPost('1')"
204
- (commentClick)="openPost('1', true)"
205
- (longPress)="handlePostLongPress('1', false)">
206
-
207
- <post-content>
208
- <post-text>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! 🏠</post-text>
209
- </post-content>
210
-
211
- <post-actions>
212
- <action-like [count]="42" />
213
- <action-comment [count]="12" (commentClick)="openPost('1', true)" />
214
- </post-actions>
215
- </ds-mobile-interactive-list-item-post>
216
-
217
- <!-- Post 2: With multiple images (grid layout) -->
218
- <ds-mobile-interactive-list-item-post
219
- [authorName]="'Sophie Andersen'"
220
- [authorRole]="'Lejer'"
221
- [timestamp]="'4t siden'"
222
- [avatarInitials]="'SA'"
223
- [clickable]="true"
224
- (postClick)="openPost('2')"
225
- (commentClick)="openPost('2', true)"
226
- (longPress)="handlePostLongPress('2', false)">
227
-
228
- <post-content>
229
- <post-text>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! 🏡✨</post-text>
230
- <ds-mobile-inline-photo
231
- [images]="[
232
- '/Assets/Dummy-photos/balcony-view.jpg',
233
- '/Assets/Dummy-photos/staircase.jpg',
234
- '/Assets/Dummy-photos/park.jpg',
235
- '/Assets/Dummy-photos/yard.jpg'
236
- ]"
237
- [author]="{
238
- name: 'Sophie Andersen',
239
- role: 'Lejer',
240
- avatarInitials: 'SA',
241
- avatarType: 'initials',
242
- timestamp: '4t siden'
243
- }"
244
- />
245
- </post-content>
246
-
247
- <post-actions>
248
- <action-like [active]="true" [count]="156" />
249
- <action-comment [count]="34" (commentClick)="openPost('2', true)" />
250
- </post-actions>
251
- </ds-mobile-interactive-list-item-post>
252
-
253
- <!-- Post 3: Question -->
254
- <ds-mobile-interactive-list-item-post
255
- [authorName]="'Thomas Hansen'"
256
- [authorRole]="'Lejer'"
257
- [timestamp]="'1d siden'"
258
- [avatarType]="'photo'"
259
- [avatarSrc]="'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100&h=100&fit=crop&crop=face'"
260
- [clickable]="true"
261
- (postClick)="openPost('3')"
262
- (commentClick)="openPost('3', true)"
263
- (longPress)="handlePostLongPress('3', false)">
264
-
265
- <post-content>
266
- <post-text>Kender nogen et fælles fitnesscenter i nærheden? Leder efter anbefalinger til gode træningscentre i området. 🏋️</post-text>
267
- </post-content>
268
-
269
- <post-actions>
270
- <action-like [count]="23" />
271
- <action-comment [count]="45" (commentClick)="openPost('3', true)" />
272
- </post-actions>
273
- </ds-mobile-interactive-list-item-post>
274
-
275
- <!-- Post 3.5: Property Manager showcase with 6+ photos -->
276
- <ds-mobile-interactive-list-item-post
277
- [authorName]="'Karen Nielsen'"
278
- [authorRole]="'Ejendomsadministrator'"
279
- [timestamp]="'2d siden'"
280
- [avatarInitials]="'KN'"
281
- [showBadge]="true"
282
- [clickable]="true"
283
- (postClick)="openPost('3.5')"
284
- (commentClick)="openPost('3.5', true)"
285
- (longPress)="handlePostLongPress('3.5', false)">
286
-
287
- <post-content>
288
- <post-text>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! 🏢✨</post-text>
289
- <ds-mobile-inline-photo
290
- [images]="[
291
- '/Assets/Dummy-photos/mailboxes.jpg',
292
- '/Assets/Dummy-photos/staircase.jpg',
293
- '/Assets/Dummy-photos/yard.jpg',
294
- '/Assets/Dummy-photos/park.jpg',
295
- '/Assets/Dummy-photos/balcony-view.jpg',
296
- '/Assets/Dummy-photos/handyman.jpg'
297
- ]"
298
- [author]="{
299
- name: 'Karen Nielsen',
300
- role: 'Ejendomsadministrator',
301
- avatarInitials: 'KN',
302
- avatarType: 'initials',
303
- timestamp: '2d siden'
304
- }"
305
- [maxVisible]="5"
306
- />
307
- </post-content>
308
-
309
- <post-actions>
310
- <action-like [count]="234" />
311
- <action-comment [count]="89" (commentClick)="openPost('3.5', true)" />
312
- </post-actions>
313
- </ds-mobile-interactive-list-item-post>
314
-
315
- <!-- Post 5: Event -->
316
- <ds-mobile-interactive-list-item-post
317
- [authorName]="'Emma Petersen'"
318
- [authorRole]="'Lejer'"
319
- [timestamp]="'3d siden'"
320
- [avatarType]="'photo'"
321
- [avatarSrc]="'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=100&h=100&fit=crop&crop=face'"
322
- [clickable]="true"
323
- (postClick)="openPost('5')"
324
- (commentClick)="openPost('5', true)"
325
- (longPress)="handlePostLongPress('5', false)">
326
-
327
- <post-content>
328
- <post-text>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! 🍔🌭</post-text>
329
- </post-content>
330
-
331
- <post-actions>
332
- <action-like [active]="true" [count]="124" />
333
- <action-comment [count]="89" (commentClick)="openPost('5', true)" />
334
- </post-actions>
335
- </ds-mobile-interactive-list-item-post>
336
- </div>
337
- } @else {
338
- <!-- Empty State -->
339
- <div class="community-empty-state">
340
- <img
341
- src="/Assets/Empty state-chat.png"
342
- alt="Ingen opslag endnu"
343
- class="empty-state-image"
344
- />
345
- <h3 class="empty-state-title">Ingen opslag endnu</h3>
346
- <p class="empty-state-description">Vær den første til at dele noget med dit fællesskab</p>
347
- </div>
348
- }
349
- </div>
350
- </ds-mobile-content>
351
- </ds-mobile-page-main>
352
- `
353
- })
354
- export class MobileCommunityPageComponent {
355
- // Store user-created posts
356
- userPosts = signal<any[]>([
357
- {
358
- id: 'user-post-1',
359
- authorName: 'Lars Mikkelsen',
360
- authorRole: 'Dig',
361
- timestamp: '5m siden',
362
- avatarType: 'initials' as 'photo' | 'initials' | 'icon',
363
- avatarInitials: 'LM',
364
- content: 'Dette er mit første opslag! Ser frem til at forbinde med alle i bygningen. 🏠',
365
- isLiked: false,
366
- likeCount: 3,
367
- commentCount: 1
368
- }
369
- ]);
370
-
371
- // Flag to control whether static demo posts are shown
372
- // Set to false to see the empty state
373
- showStaticPosts = signal(true);
374
-
375
- // Computed to check if there are any posts to display
376
- hasAnyPosts = computed(() => {
377
- return this.userPosts().length > 0 || this.showStaticPosts();
378
- });
379
-
380
- constructor(
381
- private router: Router,
382
- private route: ActivatedRoute,
383
- private bottomSheet: DsMobileBottomSheetService,
384
- private lightbox: DsMobileLightboxService,
385
- private postModal: DsMobilePostDetailModalService,
386
- public userService: UserService
387
- ) {}
388
-
389
- handleRefresh(event: any): void {
390
- console.log('Pull-to-refresh triggered');
391
- setTimeout(() => {
392
- console.log('Refresh complete');
393
- event.target.complete();
394
- }, 1000);
395
- }
396
-
397
- /**
398
- * Open post detail modal
399
- * This provides a better UX than route navigation:
400
- * - Maintains scroll position
401
- * - Native iOS-style modal feel
402
- * - Proper close button that works
403
- */
404
- async openPost(postId: string, focusComment: boolean = false): Promise<void> {
405
- console.log('[Community] ===== openPost called =====', postId, 'Focus comment:', focusComment);
406
-
407
- // Map post ID to post data (in real app, fetch from service)
408
- const postDataMap: Record<string, any> = {
409
- '1': {
410
- postId: '1',
411
- authorName: 'Anders Jensen',
412
- authorRole: 'Lejer',
413
- timestamp: '2t siden',
414
- avatarType: 'photo' as const,
415
- avatarSrc: 'https://images.unsplash.com/photo-1472099645785-5658abf4ff4e?w=100&h=100&fit=crop&crop=face',
416
- 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! 🏠',
417
- isLiked: false,
418
- likeCount: 42,
419
- commentCount: 12,
420
- comments: [
421
- {
422
- authorName: 'Mette Larsen',
423
- authorRole: 'Lejer',
424
- timestamp: '1t siden',
425
- avatarInitials: 'ML',
426
- content: 'Velkommen til fællesskabet!',
427
- likeCount: 5,
428
- isOwnComment: false
429
- },
430
- {
431
- authorName: 'Lars Mikkelsen',
432
- authorRole: 'Dig',
433
- timestamp: 'Lige nu',
434
- avatarInitials: 'LM',
435
- content: 'Vxhknbh',
436
- likeCount: 0,
437
- isOwnComment: true
438
- }
439
- ]
440
- },
441
- '2': {
442
- postId: '2',
443
- authorName: 'Sophie Andersen',
444
- authorRole: 'Lejer',
445
- timestamp: '4t siden',
446
- avatarInitials: 'SA',
447
- content: 'Se denne smukke udsigt fra min altan! Morgenkaffe har aldrig smagt så godt ☕️',
448
- imageSrc: '/Assets/Dummy-photos/balcony-view.jpg',
449
- imageAlt: 'Altanudsigt',
450
- isLiked: true,
451
- likeCount: 156,
452
- commentCount: 34,
453
- comments: [
454
- {
455
- authorName: 'Anders Jensen',
456
- authorRole: 'Lejer',
457
- timestamp: '3t siden',
458
- avatarInitials: 'AJ',
459
- content: 'Wow, den udsigt er fantastisk! Hvilken etage er du på?',
460
- likeCount: 12,
461
- isOwnComment: false
462
- },
463
- {
464
- authorName: 'Thomas Hansen',
465
- authorRole: 'Lejer',
466
- timestamp: '3t siden',
467
- avatarInitials: 'TH',
468
- content: 'Smuk! Jeg kan også se byens silhuet fra min lejlighed 🌆',
469
- isLiked: true,
470
- likeCount: 8,
471
- isOwnComment: false
472
- },
473
- {
474
- authorName: 'Lars Mikkelsen',
475
- authorRole: 'Dig',
476
- timestamp: 'Lige nu',
477
- avatarInitials: 'LM',
478
- content: 'Vxhknbh',
479
- likeCount: 0,
480
- isOwnComment: true
481
- }
482
- ]
483
- },
484
- '3': {
485
- postId: '3',
486
- authorName: 'Thomas Hansen',
487
- authorRole: 'Lejer',
488
- timestamp: '1d siden',
489
- avatarType: 'photo' as const,
490
- avatarSrc: 'https://images.unsplash.com/photo-1507003211169-0a1dd7228f2d?w=100&h=100&fit=crop&crop=face',
491
- content: 'Kender nogen et fælles fitnesscenter i nærheden? Leder efter anbefalinger til gode træningscentre i området. 🏋️',
492
- isLiked: false,
493
- likeCount: 23,
494
- commentCount: 45,
495
- comments: []
496
- },
497
- '4': {
498
- postId: '4',
499
- authorName: 'Karen Nielsen',
500
- authorRole: 'Ejendomsadministrator',
501
- timestamp: '2d siden',
502
- avatarInitials: 'KN',
503
- 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!',
504
- isLiked: false,
505
- likeCount: 89,
506
- commentCount: 67,
507
- comments: []
508
- },
509
- '5': {
510
- postId: '5',
511
- authorName: 'Emma Petersen',
512
- authorRole: 'Lejer',
513
- timestamp: '3d siden',
514
- avatarType: 'photo' as const,
515
- avatarSrc: 'https://images.unsplash.com/photo-1438761681033-6461ffad8d80?w=100&h=100&fit=crop&crop=face',
516
- 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! 🍔🌭',
517
- isLiked: true,
518
- likeCount: 124,
519
- commentCount: 89,
520
- comments: []
521
- }
522
- };
523
-
524
- const postData = postDataMap[postId];
525
-
526
- if (postData) {
527
- // Add focusComment flag to postData
528
- await this.postModal.open({ ...postData, focusComment });
529
- }
530
- }
531
-
532
- /**
533
- * Open user-created post detail modal
534
- */
535
- async openUserPost(index: number, focusComment: boolean = false): Promise<void> {
536
- const posts = this.userPosts();
537
- const post = posts[index];
538
-
539
- if (post) {
540
- console.log('[Community] Opening user post modal:', index, 'Focus comment:', focusComment);
541
-
542
- // Convert user post to modal format with empty comments array
543
- const postData = {
544
- ...post,
545
- postId: `user-${index}`,
546
- comments: [] // User posts don't have comments yet
547
- };
548
-
549
- await this.postModal.open({ ...postData, focusComment });
550
- }
551
- }
552
-
553
- async openPostCreator(): Promise<void> {
554
- // Open the post creator as a bottom sheet modal
555
- // Using 95% initial height to maximize keyboard auto-open chances
556
- const sheet = await this.bottomSheet.create({
557
- component: DsMobilePostCreateBottomSheetComponent,
558
- componentProps: {
559
- // This helps the component know it should auto-focus
560
- autoFocus: true
561
- },
562
- breakpoints: [0, 0.95, 1],
563
- initialBreakpoint: 0.95,
564
- handle: true
565
- });
566
-
567
- // Handle the result when the sheet is dismissed
568
- const result = await sheet.onWillDismiss();
569
- if (result.role === 'post' && result.data) {
570
- console.log('New post created:', result.data);
571
-
572
- // Create a new post object
573
- const newPost = {
574
- id: `user-post-${Date.now()}`, // Generate unique ID
575
- authorName: 'Lars Mikkelsen', // Current user name
576
- authorRole: 'Dig',
577
- timestamp: 'Lige nu',
578
- avatarType: this.userService.avatarType() as 'photo' | 'initials' | 'icon',
579
- avatarSrc: this.userService.avatarSrc(),
580
- avatarInitials: this.userService.avatarInitials(),
581
- content: result.data.content,
582
- imageSrc: result.data.images && result.data.images.length > 0 ? result.data.images[0] : undefined,
583
- imageAlt: result.data.images && result.data.images.length > 0 ? 'Slået billede op' : undefined,
584
- isLiked: false,
585
- likeCount: 0,
586
- commentCount: 0
587
- };
588
-
589
- // Add to the beginning of the posts array
590
- this.userPosts.update(posts => [newPost, ...posts]);
591
- }
592
- }
593
-
594
- /**
595
- * Open an image in the lightbox viewer
596
- * Prevents the post click event from firing
597
- */
598
- async openImageLightbox(imageSrc: string, title: string, description: string, event: Event): Promise<void> {
599
- console.log('[Community] Opening lightbox for image:', imageSrc);
600
-
601
- // Prevent the post card click event from firing
602
- event.stopPropagation();
603
-
604
- const authorMeta: LightboxAuthor = {
605
- name: 'Sophie Andersen',
606
- role: 'Lejer',
607
- avatarInitials: 'SA',
608
- timestamp: '4t siden'
609
- };
610
-
611
- // Open the lightbox with the image
612
- await this.lightbox.open({
613
- images: [
614
- {
615
- type: 'image',
616
- src: imageSrc,
617
- alt: title,
618
- title: title,
619
- description: description,
620
- isLiked: true,
621
- likeCount: 156,
622
- commentCount: 34
623
- }
624
- ],
625
- author: authorMeta,
626
- enableZoom: true,
627
- showControls: false, // Single image, no need for controls
628
- showInfo: true
629
- });
630
- }
631
-
632
- async openHouseRulesPdf(): Promise<void> {
633
- console.log('[Community] Opening House Rules PDF');
634
-
635
- // Author metadata
636
- const authorMeta: LightboxAuthor = {
637
- name: 'Karen Nielsen',
638
- role: 'Ejendomsadministrator',
639
- avatarInitials: 'KN',
640
- timestamp: '2d siden'
641
- };
642
-
643
- // Open the PDF lightbox
644
- // Use absolute path for production deployment (Vercel, etc.)
645
- await this.lightbox.openPdf({
646
- pdf: {
647
- type: 'pdf',
648
- src: '/Assets/House_Rules.pdf', // Capital A to match public/Assets folder structure
649
- title: 'House Rules',
650
- description: 'Building regulations and community guidelines',
651
- fileSize: 250880, // 245 KB in bytes
652
- pageCount: 8
653
- },
654
- author: authorMeta
655
- });
656
- }
657
-
658
- /**
659
- * Handle long press on a post to show action sheet
660
- */
661
- async handlePostLongPress(postIdOrIndex: string | number, isOwnPost: boolean): Promise<void> {
662
- console.log('[Community] Post long pressed:', postIdOrIndex, 'isOwn:', isOwnPost);
663
-
664
- const sheet = await this.bottomSheet.create({
665
- component: DsMobilePostActionsBottomSheetComponent,
666
- componentProps: {
667
- isOwnContent: isOwnPost
668
- },
669
- breakpoints: [0, 1],
670
- initialBreakpoint: 1,
671
- handle: true,
672
- backdropDismiss: true,
673
- cssClass: 'auto-height'
674
- });
675
-
676
- const result = await sheet.onWillDismiss();
677
-
678
- if (result.role === 'select' && result.data) {
679
- const action = (result.data as PostActionResult).action;
680
-
681
- switch (action) {
682
- case 'edit':
683
- console.log('Edit post:', postIdOrIndex);
684
- // Open the post create bottom sheet in edit mode
685
- let postContent = '';
686
- let postId = '';
687
-
688
- // Get post content based on postIdOrIndex
689
- if (typeof postIdOrIndex === 'number') {
690
- const post = this.userPosts()[postIdOrIndex];
691
- if (post) {
692
- postContent = post.content || '';
693
- postId = post.id || postIdOrIndex.toString();
694
- }
695
- } else {
696
- // For static posts, we'll need to determine content
697
- // For now, use a placeholder
698
- postId = postIdOrIndex.toString();
699
- postContent = 'Edit this post...';
700
- }
701
-
702
- // Open the bottom sheet in edit mode
703
- const editSheet = await this.bottomSheet.create({
704
- component: DsMobilePostCreateBottomSheetComponent,
705
- componentProps: {
706
- autoFocus: true,
707
- isEditMode: true,
708
- postId: postId,
709
- initialContent: postContent
710
- },
711
- breakpoints: [0, 0.95, 1],
712
- initialBreakpoint: 0.95,
713
- handle: true,
714
- backdropBlur: true,
715
- backdropOpacity: 0.6
716
- });
717
-
718
- // Handle the result when the sheet is dismissed
719
- const editResult = await editSheet.onWillDismiss();
720
- if (editResult.role === 'post' && editResult.data) {
721
- console.log('Post updated:', editResult.data);
722
-
723
- // Update the post in the array
724
- if (typeof postIdOrIndex === 'number') {
725
- const currentPosts = this.userPosts();
726
- const updatedPosts = currentPosts.map((post, index) =>
727
- index === postIdOrIndex
728
- ? { ...post, content: editResult.data.content, timestamp: 'Just now' }
729
- : post
730
- );
731
- this.userPosts.set(updatedPosts);
732
- }
733
- }
734
- break;
735
- case 'delete':
736
- console.log('Delete post:', postIdOrIndex);
737
- if (confirm('Er du sikker på, at du vil slette dette opslag?')) {
738
- // If it's a user post (number index), remove it from the array
739
- if (typeof postIdOrIndex === 'number') {
740
- const currentPosts = this.userPosts();
741
- const updatedPosts = currentPosts.filter((_, index) => index !== postIdOrIndex);
742
- this.userPosts.set(updatedPosts);
743
- }
744
- // Otherwise it's a static post, just show confirmation
745
- else {
746
- alert('Opslag slettet!');
747
- }
748
- }
749
- break;
750
- case 'like':
751
- console.log('Like post:', postIdOrIndex);
752
- // Toggle like - in a real app, this would call an API
753
- alert('Opslag liket!');
754
- break;
755
- case 'reply':
756
- console.log('Reply to post:', postIdOrIndex);
757
- // Open the post detail modal with comment input focused
758
- if (typeof postIdOrIndex === 'number') {
759
- await this.openUserPost(postIdOrIndex, true);
760
- } else {
761
- await this.openPost(postIdOrIndex, true);
762
- }
763
- break;
764
- }
765
- }
766
- }
767
- }
768
-