@propbinder/mobile-design 0.2.47 → 0.2.50
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/ng-package.json +24 -0
- package/package.json +3 -39
- package/src/animations/page-transitions.ts +165 -0
- package/src/assets/fonts/brockmann-mediumitalic-webfont.woff2 +0 -0
- package/src/assets/fonts/brockmann-regularitalic-webfont.woff2 +0 -0
- package/src/assets/fonts/brockmann-semibolditalic-webfont.woff2 +0 -0
- package/src/components/action-list-item/ds-mobile-action-list-item.ts +102 -0
- package/src/components/action-list-item/index.ts +2 -0
- package/src/components/app-icon/ds-app-icon.ts +133 -0
- package/src/components/app-icon/index.ts +2 -0
- package/src/components/attachment-preview/ds-mobile-attachment-preview.css +139 -0
- package/src/components/attachment-preview/ds-mobile-attachment-preview.ts +164 -0
- package/src/components/attachment-preview/index.ts +1 -0
- package/src/components/avatar-with-badge/ds-avatar-with-badge.ts +142 -0
- package/src/components/avatar-with-badge/index.ts +2 -0
- package/src/components/booking-modal/ds-mobile-booking-confirmation-wrapper.ts +71 -0
- package/src/components/booking-modal/ds-mobile-booking-modal.service.ts +121 -0
- package/src/components/booking-modal/ds-mobile-booking-modal.ts +598 -0
- package/src/components/booking-modal/ds-mobile-booking-summary.ts +161 -0
- package/src/components/booking-modal/index.ts +4 -0
- package/src/components/bottom-sheet/ds-mobile-actions-bottom-sheet.ts +266 -0
- package/src/components/bottom-sheet/ds-mobile-bottom-sheet-header.ts +146 -0
- package/src/components/bottom-sheet/ds-mobile-bottom-sheet-wrapper.ts +156 -0
- package/src/components/bottom-sheet/ds-mobile-bottom-sheet.css +101 -0
- package/src/components/bottom-sheet/ds-mobile-bottom-sheet.service.ts +169 -0
- package/src/components/bottom-sheet/ds-mobile-confirmation-sheet.ts +211 -0
- package/src/components/bottom-sheet/ds-mobile-post-create-bottom-sheet.ts +578 -0
- package/src/components/bottom-sheet/ds-mobile-profile-actions-sheet.ts +614 -0
- package/src/components/bottom-sheet/index.ts +8 -0
- package/src/components/bottom-sheet/modal-shadow-fix.ts +42 -0
- package/src/components/card-inline/ds-mobile-card-inline.ts +301 -0
- package/src/components/card-inline/index.ts +2 -0
- package/src/components/card-inline-banner/ds-mobile-card-inline-banner.ts +118 -0
- package/src/components/card-inline-banner/index.ts +1 -0
- package/src/components/card-inline-contact/ds-mobile-card-inline-contact.ts +120 -0
- package/src/components/card-inline-contact/index.ts +1 -0
- package/src/components/card-inline-file/ds-mobile-card-inline-file.ts +141 -0
- package/src/components/card-inline-file/index.ts +1 -0
- package/src/components/chat-modal/ds-mobile-chat-modal.css +159 -0
- package/src/components/chat-modal/ds-mobile-chat-modal.service.ts +105 -0
- package/src/components/chat-modal/ds-mobile-chat-modal.ts +918 -0
- package/src/components/chat-modal/index.ts +8 -0
- package/src/components/comment/ds-mobile-comment.ts +568 -0
- package/src/components/comment/index.ts +2 -0
- package/src/components/contact-list-item/ds-mobile-contact-list-item.ts +182 -0
- package/src/components/contact-list-item/index.ts +2 -0
- package/src/components/content/ds-mobile-content.ts +139 -0
- package/src/components/content/index.ts +2 -0
- package/src/components/dropdown/ds-mobile-dropdown.css +199 -0
- package/src/components/dropdown/ds-mobile-dropdown.ts +340 -0
- package/src/components/dropdown/index.ts +2 -0
- package/src/components/ds-mobile-tabs.css +407 -0
- package/src/components/ds-mobile-tabs.ts +216 -0
- package/src/components/empty-state/ds-mobile-empty-state.ts +120 -0
- package/src/components/empty-state/index.ts +2 -0
- package/src/components/fab/ds-mobile-fab.ts +315 -0
- package/src/components/fab/index.ts +1 -0
- package/src/components/facility-creation-modal/ds-mobile-facility-creation-confirmation-wrapper.ts +121 -0
- package/src/components/facility-creation-modal/ds-mobile-facility-creation-modal.css +189 -0
- package/src/components/facility-creation-modal/ds-mobile-facility-creation-modal.service.ts +135 -0
- package/src/components/facility-creation-modal/ds-mobile-facility-creation-modal.ts +656 -0
- package/src/components/facility-creation-modal/index.ts +9 -0
- package/src/components/facility-creation-modal/sheets/ds-mobile-access-sheet.ts +105 -0
- package/src/components/facility-creation-modal/sheets/ds-mobile-price-sheet.ts +188 -0
- package/src/components/facility-creation-modal/sheets/ds-mobile-when-can-book-sheet.ts +460 -0
- package/src/components/facility-creation-modal/sheets/ds-mobile-who-can-book-sheet.ts +134 -0
- package/src/components/facility-detail-modal/ds-mobile-facility-detail-modal.service.ts +69 -0
- package/src/components/facility-detail-modal/ds-mobile-facility-detail-modal.ts +379 -0
- package/src/components/facility-detail-modal/index.ts +2 -0
- package/src/components/file-attachment/ds-mobile-file-attachment.ts +164 -0
- package/src/components/file-attachment/index.ts +2 -0
- package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.css +214 -0
- package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.service.ts +84 -0
- package/src/components/handbook-detail-modal/ds-mobile-handbook-detail-modal.ts +424 -0
- package/src/components/handbook-detail-modal/index.ts +3 -0
- package/src/components/handbook-folder/ds-mobile-handbook-folder-mini.ts +175 -0
- package/src/components/handbook-folder/ds-mobile-handbook-folder.ts +533 -0
- package/src/components/handbook-folder/index.ts +4 -0
- package/src/components/header-content/ds-mobile-header-content.ts +222 -0
- package/src/components/header-content/index.ts +2 -0
- package/src/components/illustration/ds-mobile-illustration.ts +124 -0
- package/src/components/illustration/index.ts +2 -0
- package/src/components/index.ts +124 -0
- package/src/components/inline-photo/ds-mobile-inline-photo.ts +361 -0
- package/src/components/inline-photo/index.ts +1 -0
- package/src/components/inline-tabs/ds-mobile-inline-tabs.ts +132 -0
- package/src/components/inline-tabs/index.ts +2 -0
- package/src/components/interactive-list-item-booking/ds-mobile-interactive-list-item-booking.ts +350 -0
- package/src/components/interactive-list-item-booking/index.ts +1 -0
- package/src/components/interactive-list-item-inquiry/ds-mobile-interactive-list-item-inquiry.ts +321 -0
- package/src/components/interactive-list-item-inquiry/index.ts +2 -0
- package/src/components/interactive-list-item-message/ds-mobile-interactive-list-item-message.ts +237 -0
- package/src/components/interactive-list-item-message/index.ts +2 -0
- package/src/components/interactive-list-item-post/ds-mobile-interactive-list-item-post.ts +549 -0
- package/src/components/interactive-list-item-post/ds-mobile-post-pdf-attachment.ts +124 -0
- package/src/components/interactive-list-item-post/index.ts +13 -0
- package/src/components/lightbox/ds-mobile-lightbox-footer.ts +315 -0
- package/src/components/lightbox/ds-mobile-lightbox-header.ts +202 -0
- package/src/components/lightbox/ds-mobile-lightbox-image.ts +484 -0
- package/src/components/lightbox/ds-mobile-lightbox-pdf.css +377 -0
- package/src/components/lightbox/ds-mobile-lightbox-pdf.ts +374 -0
- package/src/components/lightbox/ds-mobile-lightbox.css +587 -0
- package/src/components/lightbox/ds-mobile-lightbox.service.ts +296 -0
- package/src/components/lightbox/ds-mobile-lightbox.ts +529 -0
- package/src/components/lightbox/index.ts +22 -0
- package/src/components/list-item/ds-mobile-list-item.ts +603 -0
- package/src/components/list-item/index.ts +2 -0
- package/src/components/list-item-static/ds-mobile-list-item-static.ts +133 -0
- package/src/components/list-item-static/index.ts +2 -0
- package/src/components/loader-overlay/ds-mobile-loader-overlay.css +49 -0
- package/src/components/loader-overlay/ds-mobile-loader-overlay.ts +77 -0
- package/src/components/loader-overlay/index.ts +1 -0
- package/src/components/logo/ds-logo.ts +95 -0
- package/src/components/logo/index.ts +2 -0
- package/src/components/message-bubble/ds-mobile-message-bubble.ts +633 -0
- package/src/components/message-bubble/index.ts +7 -0
- package/src/components/message-composer/ds-mobile-message-composer.ts +1146 -0
- package/src/components/message-composer/index.ts +7 -0
- package/src/components/modal/ds-mobile-modal.css +163 -0
- package/src/components/modal/ds-mobile-modal.service.ts +329 -0
- package/src/components/modal/index.ts +8 -0
- package/src/components/modal-base/ds-mobile-modal-base.css +378 -0
- package/src/components/modal-base/ds-mobile-modal-base.ts +261 -0
- package/src/components/modal-base/index.ts +2 -0
- package/src/components/new-inquiry-modal/ds-mobile-new-inquiry-modal.css +112 -0
- package/src/components/new-inquiry-modal/ds-mobile-new-inquiry-modal.service.ts +93 -0
- package/src/components/new-inquiry-modal/ds-mobile-new-inquiry-modal.ts +442 -0
- package/src/components/new-inquiry-modal/index.ts +4 -0
- package/src/components/offline-banner/ds-mobile-offline-banner.ts +135 -0
- package/src/components/offline-banner/index.ts +1 -0
- package/src/components/page-details/ds-mobile-page-details.css +83 -0
- package/src/components/page-details/ds-mobile-page-details.ts +282 -0
- package/src/components/page-details/index.ts +2 -0
- package/src/components/page-main/ds-mobile-page-main.css +68 -0
- package/src/components/page-main/ds-mobile-page-main.ts +421 -0
- package/src/components/page-main/index.ts +2 -0
- package/src/components/post-composer/ds-mobile-post-composer.ts +140 -0
- package/src/components/post-composer/index.ts +2 -0
- package/src/components/post-detail-modal/ds-mobile-post-detail-modal.css +390 -0
- package/src/components/post-detail-modal/ds-mobile-post-detail-modal.service.ts +108 -0
- package/src/components/post-detail-modal/ds-mobile-post-detail-modal.ts +722 -0
- package/src/components/post-detail-modal/index.ts +9 -0
- package/src/components/property-banner/ds-mobile-property-banner.ts +95 -0
- package/src/components/property-banner/index.ts +2 -0
- package/src/components/section/ds-mobile-section.ts +263 -0
- package/src/components/section/index.ts +2 -0
- package/src/components/shared/directives/index.ts +2 -0
- package/src/components/shared/directives/long-press.directive.ts +212 -0
- package/src/components/shared/index.ts +3 -0
- package/src/components/shared/mobile-modal-base.ts +457 -0
- package/src/components/shared/mobile-page-base.ts +204 -0
- package/src/components/swiper/ds-mobile-swiper-with-nav.ts +160 -0
- package/src/components/swiper/ds-mobile-swiper.ts +327 -0
- package/src/components/swiper/index.ts +3 -0
- package/src/components/system-message-banner/ds-mobile-system-message-banner.ts +129 -0
- package/src/components/system-message-banner/index.ts +2 -0
- package/src/components/tab-bar/ds-mobile-tab-bar.css +533 -0
- package/src/components/tab-bar/ds-mobile-tab-bar.ts +735 -0
- package/src/components/tab-bar/index.ts +2 -0
- package/src/components/tabs/ds-mobile-tabs.css +25 -0
- package/src/components/tabs/ds-mobile-tabs.ts +89 -0
- package/src/components/tabs/index.ts +2 -0
- package/src/components/text-input/ds-text-input.ts +287 -0
- package/src/components/text-input/index.ts +2 -0
- package/src/examples/booking.page.ts +434 -0
- package/src/examples/community.page.ts +776 -0
- package/src/examples/handbook.page.ts +324 -0
- package/src/examples/home.page.ts +347 -0
- package/src/examples/index.ts +12 -0
- package/src/examples/inquiries.example.ts +273 -0
- package/src/examples/inquiry-detail.example.css +189 -0
- package/src/examples/inquiry-detail.example.ts +415 -0
- package/src/examples/mobile-tabs-example.component.ts +208 -0
- package/src/examples/post-create.page.ts +311 -0
- package/src/examples/post-detail.page.ts +296 -0
- package/src/examples/sign-in.page.ts +291 -0
- package/src/examples/whitelabel-demo-modal.component.ts +1094 -0
- package/src/examples/whitelabel-demo-modal.service.ts +77 -0
- package/src/models/index.ts +7 -0
- package/src/models/post.model.ts +41 -0
- package/src/pages/community.page.ts +769 -0
- package/src/pages/handbook.page.ts +388 -0
- package/src/pages/home.page.ts +303 -0
- package/src/pages/index.ts +11 -0
- package/src/pages/inquiries.example.ts +273 -0
- package/src/pages/inquiry-detail.example.css +189 -0
- package/src/pages/inquiry-detail.example.ts +415 -0
- package/src/pages/mobile-tabs-example.component.ts +179 -0
- package/src/pages/post-create.page.ts +311 -0
- package/src/pages/post-detail.page.ts +296 -0
- package/src/pages/sign-in.page.ts +291 -0
- package/src/pages/whitelabel-demo-modal.component.ts +1094 -0
- package/src/pages/whitelabel-demo-modal.service.ts +77 -0
- package/src/public-api.ts +6 -0
- package/src/services/base-modal.service.ts +101 -0
- package/src/services/index.ts +11 -0
- package/src/services/posts.service.ts +542 -0
- package/src/services/tracking-permission.service.ts +88 -0
- package/src/services/user.service.ts +60 -0
- package/src/services/whitelabel.service.ts +675 -0
- package/{styles → src/styles}/ionic.css +25 -0
- package/tsconfig.lib.json +17 -0
- package/tsconfig.lib.prod.json +9 -0
- package/tsconfig.spec.json +13 -0
- package/fesm2022/propbinder-mobile-design.mjs +0 -26136
- package/fesm2022/propbinder-mobile-design.mjs.map +0 -1
- package/index.d.ts +0 -8154
- /package/{assets → src/assets}/fonts/Brockmann-Bold.otf +0 -0
- /package/{assets → src/assets}/fonts/Brockmann-BoldItalic.otf +0 -0
- /package/{assets → src/assets}/fonts/Brockmann-Medium.otf +0 -0
- /package/{assets → src/assets}/fonts/Brockmann-MediumItalic.otf +0 -0
- /package/{assets → src/assets}/fonts/Brockmann-Regular.otf +0 -0
- /package/{assets → src/assets}/fonts/Brockmann-RegularItalic.otf +0 -0
- /package/{assets → src/assets}/fonts/Brockmann-SemiBold.otf +0 -0
- /package/{assets → src/assets}/fonts/Brockmann-SemiBoldItalic.otf +0 -0
- /package/{assets → src/assets}/fonts/Brockmann_desktop_license.pdf +0 -0
- /package/{assets → src/assets}/fonts/brockmann-medium-webfont.woff2 +0 -0
- /package/{assets → src/assets}/fonts/brockmann-regular-webfont.woff2 +0 -0
- /package/{assets → src/assets}/fonts/brockmann-semibold-webfont.woff2 +0 -0
- /package/{styles → src/components/shared}/mobile-common.css +0 -0
- /package/{styles → src/components/shared}/mobile-page-base.css +0 -0
|
@@ -0,0 +1,656 @@
|
|
|
1
|
+
import { Component, signal, Input, ViewChild, ElementRef, OnInit, AfterViewInit, CUSTOM_ELEMENTS_SCHEMA, inject } from '@angular/core';
|
|
2
|
+
import { CommonModule } from '@angular/common';
|
|
3
|
+
import { FormsModule } from '@angular/forms';
|
|
4
|
+
import { ModalController } from '@ionic/angular/standalone';
|
|
5
|
+
import { Capacitor } from '@capacitor/core';
|
|
6
|
+
import { FilePicker } from '@capawesome/capacitor-file-picker';
|
|
7
|
+
import { DsButtonComponent, DsTextareaComponent, DsIconComponent, DsIconButtonComponent } from '@propbinder/design-system';
|
|
8
|
+
import { DsMobileModalBaseComponent } from '../modal-base/ds-mobile-modal-base';
|
|
9
|
+
import { DsMobileSectionComponent } from '../section';
|
|
10
|
+
import { DsMobileListItemComponent } from '../list-item';
|
|
11
|
+
import { DsMobileBottomSheetService } from '../bottom-sheet';
|
|
12
|
+
import { DsMobileAttachmentPreviewComponent, type AttachmentData, type AttachmentFileType } from '../attachment-preview';
|
|
13
|
+
|
|
14
|
+
/**
|
|
15
|
+
* New facility form data
|
|
16
|
+
*/
|
|
17
|
+
export interface NewFacilityData {
|
|
18
|
+
title: string;
|
|
19
|
+
description: string;
|
|
20
|
+
whoCanBook: string;
|
|
21
|
+
whenCanBook: string;
|
|
22
|
+
price: string;
|
|
23
|
+
accessRequirements: string;
|
|
24
|
+
attachments: AttachmentData[];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* DsMobileFacilityCreationModalComponent
|
|
29
|
+
*
|
|
30
|
+
* Modal component for creating new facilities.
|
|
31
|
+
* Uses ds-mobile-modal-base for consistent layout and behavior.
|
|
32
|
+
*
|
|
33
|
+
* Features:
|
|
34
|
+
* - Title and description fields
|
|
35
|
+
* - Interactive list items for facility options
|
|
36
|
+
* - Bottom sheet pickers for selections
|
|
37
|
+
* - Photo upload with preview
|
|
38
|
+
* - Form validation
|
|
39
|
+
*
|
|
40
|
+
* This component is typically not used directly - use DsMobileFacilityCreationModalService instead.
|
|
41
|
+
*/
|
|
42
|
+
@Component({
|
|
43
|
+
selector: 'ds-mobile-facility-creation-modal',
|
|
44
|
+
standalone: true,
|
|
45
|
+
imports: [
|
|
46
|
+
CommonModule,
|
|
47
|
+
FormsModule,
|
|
48
|
+
DsButtonComponent,
|
|
49
|
+
DsTextareaComponent,
|
|
50
|
+
DsIconComponent,
|
|
51
|
+
DsIconButtonComponent,
|
|
52
|
+
DsMobileModalBaseComponent,
|
|
53
|
+
DsMobileSectionComponent,
|
|
54
|
+
DsMobileListItemComponent,
|
|
55
|
+
DsMobileAttachmentPreviewComponent,
|
|
56
|
+
],
|
|
57
|
+
styleUrls: ['../shared/mobile-common.css', './ds-mobile-facility-creation-modal.css'],
|
|
58
|
+
schemas: [CUSTOM_ELEMENTS_SCHEMA],
|
|
59
|
+
template: `
|
|
60
|
+
<ds-mobile-modal-base
|
|
61
|
+
[loading]="loading"
|
|
62
|
+
[error]="error"
|
|
63
|
+
[showHeader]="false"
|
|
64
|
+
[hasFixedBottom]="true"
|
|
65
|
+
[enableKeyboardHandling]="true"
|
|
66
|
+
[keyboardContentBehavior]="'overlay'"
|
|
67
|
+
closeButtonLabel="Close"
|
|
68
|
+
>
|
|
69
|
+
<!-- Form Content -->
|
|
70
|
+
<ds-mobile-section class="form-section">
|
|
71
|
+
<!-- Title Field (Large Ghost Textarea) -->
|
|
72
|
+
<ds-textarea
|
|
73
|
+
#titleInput
|
|
74
|
+
[(ngModel)]="title"
|
|
75
|
+
[ghost]="true"
|
|
76
|
+
[required]="true"
|
|
77
|
+
[rows]="1"
|
|
78
|
+
[placeholder]="titlePlaceholder"
|
|
79
|
+
class="inquiry-title-input ghost-input-clean"
|
|
80
|
+
(valueChange)="handleTitleChange($event)"
|
|
81
|
+
/>
|
|
82
|
+
|
|
83
|
+
<!-- Description Field (Ghost Textarea) -->
|
|
84
|
+
<ds-textarea
|
|
85
|
+
#descriptionInput
|
|
86
|
+
[(ngModel)]="description"
|
|
87
|
+
[ghost]="true"
|
|
88
|
+
[rows]="1"
|
|
89
|
+
[placeholder]="descriptionPlaceholder"
|
|
90
|
+
class="inquiry-description-input ghost-input-clean"
|
|
91
|
+
(valueChange)="handleDescriptionChange($event)"
|
|
92
|
+
/>
|
|
93
|
+
</ds-mobile-section>
|
|
94
|
+
|
|
95
|
+
<!-- List Items Section -->
|
|
96
|
+
<ds-mobile-section [contentGap]="'0'">
|
|
97
|
+
<!-- Who can book - hidden until Propbinder API supports this field -->
|
|
98
|
+
<!-- <ds-mobile-list-item
|
|
99
|
+
[leadingSize]="'32px'"
|
|
100
|
+
[showDivider]="true"
|
|
101
|
+
[interactive]="true"
|
|
102
|
+
[showDesktopMoreButton]="false"
|
|
103
|
+
[align]="'center'"
|
|
104
|
+
(itemClick)="openWhoSheet()">
|
|
105
|
+
<ds-icon content-leading name="remixGroupLine" size="20px" color="tertiary" />
|
|
106
|
+
<div content-main>
|
|
107
|
+
<div class="detail-label">Hvem kan booke</div>
|
|
108
|
+
<div class="detail-value">{{ whoCanBook() }}</div>
|
|
109
|
+
</div>
|
|
110
|
+
<ds-icon content-trailing name="remixArrowRightSLine" size="20px" color="tertiary" />
|
|
111
|
+
</ds-mobile-list-item> -->
|
|
112
|
+
|
|
113
|
+
<!-- When can it be booked -->
|
|
114
|
+
<ds-mobile-list-item
|
|
115
|
+
[leadingSize]="'32px'"
|
|
116
|
+
[showDivider]="true"
|
|
117
|
+
[interactive]="true"
|
|
118
|
+
[showDesktopMoreButton]="false"
|
|
119
|
+
[align]="'center'"
|
|
120
|
+
(itemClick)="openWhenSheet()">
|
|
121
|
+
<ds-icon content-leading name="remixCalendarLine" size="20px" color="tertiary" />
|
|
122
|
+
<div content-main>
|
|
123
|
+
<div class="detail-label">Hvornår kan det bookes</div>
|
|
124
|
+
<div class="detail-value">{{ whenCanBook() }}</div>
|
|
125
|
+
</div>
|
|
126
|
+
<ds-icon content-trailing name="remixArrowRightSLine" size="20px" color="tertiary" />
|
|
127
|
+
</ds-mobile-list-item>
|
|
128
|
+
|
|
129
|
+
<!-- Price -->
|
|
130
|
+
<ds-mobile-list-item
|
|
131
|
+
[leadingSize]="'32px'"
|
|
132
|
+
[showDivider]="false"
|
|
133
|
+
[interactive]="true"
|
|
134
|
+
[showDesktopMoreButton]="false"
|
|
135
|
+
[align]="'center'"
|
|
136
|
+
(itemClick)="openPriceSheet()">
|
|
137
|
+
<ds-icon content-leading name="remixPriceTag3Line" size="20px" color="tertiary" />
|
|
138
|
+
<div content-main>
|
|
139
|
+
<div class="detail-label">Pris</div>
|
|
140
|
+
<div class="detail-value">{{ price() }}</div>
|
|
141
|
+
</div>
|
|
142
|
+
<ds-icon content-trailing name="remixArrowRightSLine" size="20px" color="tertiary" />
|
|
143
|
+
</ds-mobile-list-item>
|
|
144
|
+
|
|
145
|
+
<!-- Access requirements - hidden until Propbinder API supports this field -->
|
|
146
|
+
<!-- <ds-mobile-list-item
|
|
147
|
+
[leadingSize]="'32px'"
|
|
148
|
+
[showDivider]="false"
|
|
149
|
+
[interactive]="true"
|
|
150
|
+
[showDesktopMoreButton]="false"
|
|
151
|
+
[align]="'center'"
|
|
152
|
+
(itemClick)="openAccessSheet()">
|
|
153
|
+
<ds-icon content-leading name="remixKeyLine" size="20px" color="tertiary" />
|
|
154
|
+
<div content-main>
|
|
155
|
+
<div class="detail-label">Adgangskrav</div>
|
|
156
|
+
<div class="detail-value">{{ accessRequirements() }}</div>
|
|
157
|
+
</div>
|
|
158
|
+
<ds-icon content-trailing name="remixArrowRightSLine" size="20px" color="tertiary" />
|
|
159
|
+
</ds-mobile-list-item> -->
|
|
160
|
+
</ds-mobile-section>
|
|
161
|
+
|
|
162
|
+
<!-- Fixed Bottom Container (Slides with keyboard) -->
|
|
163
|
+
<div fixed-bottom class="fixed-bottom-container">
|
|
164
|
+
<!-- Attachment Previews (if any) -->
|
|
165
|
+
@if (attachments().length > 0) {
|
|
166
|
+
<div class="attachment-previews-section">
|
|
167
|
+
<div class="image-previews">
|
|
168
|
+
@for (attachment of attachments(); track attachment.id) {
|
|
169
|
+
<ds-mobile-attachment-preview [attachment]="attachment" (remove)="removeAttachment($event)" />
|
|
170
|
+
}
|
|
171
|
+
</div>
|
|
172
|
+
</div>
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
<!-- Submit Actions Container -->
|
|
176
|
+
<div class="submit-container">
|
|
177
|
+
<div class="submit-content">
|
|
178
|
+
<!-- Upload Actions (Left) -->
|
|
179
|
+
<div class="upload-actions">
|
|
180
|
+
<ds-icon-button icon="remixImageLine" variant="secondary" size="md" (clicked)="addPhoto()" [disabled]="attachments().length >= 6" aria-label="Add photo">
|
|
181
|
+
</ds-icon-button>
|
|
182
|
+
<ds-icon-button
|
|
183
|
+
icon="remixAttachmentLine"
|
|
184
|
+
variant="secondary"
|
|
185
|
+
size="md"
|
|
186
|
+
(clicked)="handleAddAttachment()"
|
|
187
|
+
[disabled]="attachments().length >= 6"
|
|
188
|
+
aria-label="Add attachment"
|
|
189
|
+
>
|
|
190
|
+
</ds-icon-button>
|
|
191
|
+
|
|
192
|
+
<!-- Hidden file input for file selection -->
|
|
193
|
+
<input #fileInput type="file" accept="*/*" multiple (change)="handleFileSelect($event)" style="display: none;" aria-hidden="true" />
|
|
194
|
+
</div>
|
|
195
|
+
|
|
196
|
+
<!-- Submit Button (Right) -->
|
|
197
|
+
<ds-button class="submit-action-button" variant="primary" size="sm" [disabled]="!isFormValid() || isSubmitting()" (clicked)="handleSubmit()">
|
|
198
|
+
{{ submitButtonLabel }}
|
|
199
|
+
</ds-button>
|
|
200
|
+
</div>
|
|
201
|
+
</div>
|
|
202
|
+
</div>
|
|
203
|
+
</ds-mobile-modal-base>
|
|
204
|
+
`
|
|
205
|
+
})
|
|
206
|
+
export class DsMobileFacilityCreationModalComponent implements OnInit, AfterViewInit {
|
|
207
|
+
private modalController = inject(ModalController);
|
|
208
|
+
private bottomSheetService = inject(DsMobileBottomSheetService);
|
|
209
|
+
|
|
210
|
+
@ViewChild('titleInput', { read: ElementRef }) titleInputRef?: ElementRef<HTMLElement>;
|
|
211
|
+
@ViewChild('descriptionInput', { read: ElementRef }) descriptionInputRef?: ElementRef<HTMLElement>;
|
|
212
|
+
@ViewChild('titleInput') titleInput?: DsTextareaComponent;
|
|
213
|
+
@ViewChild('fileInput') fileInput?: ElementRef<HTMLInputElement>;
|
|
214
|
+
|
|
215
|
+
/**
|
|
216
|
+
* Loading state for the modal
|
|
217
|
+
*/
|
|
218
|
+
@Input() loading: boolean = false;
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* Error message to display
|
|
222
|
+
*/
|
|
223
|
+
@Input() error?: string;
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Callback function when form is submitted
|
|
227
|
+
*/
|
|
228
|
+
@Input() onSubmit?: (data: NewFacilityData) => void | Promise<void>;
|
|
229
|
+
|
|
230
|
+
/**
|
|
231
|
+
* Placeholder for the title field
|
|
232
|
+
*/
|
|
233
|
+
@Input() titlePlaceholder: string = 'Festlokale på tal';
|
|
234
|
+
|
|
235
|
+
/**
|
|
236
|
+
* Placeholder for the description field
|
|
237
|
+
*/
|
|
238
|
+
@Input() descriptionPlaceholder: string = 'Beskriv din booking så detaljeret som muligt...';
|
|
239
|
+
|
|
240
|
+
/**
|
|
241
|
+
* Label for the submit button
|
|
242
|
+
*/
|
|
243
|
+
@Input() submitButtonLabel: string = 'Opret';
|
|
244
|
+
|
|
245
|
+
/**
|
|
246
|
+
* Form title field
|
|
247
|
+
*/
|
|
248
|
+
title = '';
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Form description field
|
|
252
|
+
*/
|
|
253
|
+
description = '';
|
|
254
|
+
|
|
255
|
+
/**
|
|
256
|
+
* Attachments array
|
|
257
|
+
*/
|
|
258
|
+
attachments = signal<AttachmentData[]>([]);
|
|
259
|
+
|
|
260
|
+
/**
|
|
261
|
+
* Who can book signal
|
|
262
|
+
*/
|
|
263
|
+
whoCanBook = signal<string>('Alle');
|
|
264
|
+
|
|
265
|
+
/**
|
|
266
|
+
* When can it be booked signal
|
|
267
|
+
*/
|
|
268
|
+
whenCanBook = signal<string>('I weekenden, 09:00 til 17:30');
|
|
269
|
+
|
|
270
|
+
/**
|
|
271
|
+
* Price signal
|
|
272
|
+
*/
|
|
273
|
+
price = signal<string>('Gratis');
|
|
274
|
+
|
|
275
|
+
/**
|
|
276
|
+
* Access requirements signal
|
|
277
|
+
*/
|
|
278
|
+
accessRequirements = signal<string>('Ingen adgangskrav');
|
|
279
|
+
|
|
280
|
+
/**
|
|
281
|
+
* Form validation state
|
|
282
|
+
*/
|
|
283
|
+
isFormValid = signal<boolean>(false);
|
|
284
|
+
|
|
285
|
+
/**
|
|
286
|
+
* Submitting state
|
|
287
|
+
*/
|
|
288
|
+
isSubmitting = signal<boolean>(false);
|
|
289
|
+
|
|
290
|
+
ngOnInit(): void {
|
|
291
|
+
console.log('[FacilityCreationModal] Component initialized');
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
ngAfterViewInit(): void {
|
|
295
|
+
// Setup auto-resize for title textarea
|
|
296
|
+
setTimeout(() => {
|
|
297
|
+
this.autoResizeTitleTextarea();
|
|
298
|
+
this.autoResizeDescriptionTextarea();
|
|
299
|
+
|
|
300
|
+
// Focus the title textarea after view initialization to trigger keyboard on iOS
|
|
301
|
+
if (this.titleInputRef) {
|
|
302
|
+
const textareaElement = this.titleInputRef.nativeElement.querySelector('textarea');
|
|
303
|
+
if (textareaElement) {
|
|
304
|
+
textareaElement.focus();
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}, 300);
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Auto-resize the title textarea based on content
|
|
312
|
+
*/
|
|
313
|
+
private autoResizeTitleTextarea(): void {
|
|
314
|
+
if (!this.titleInputRef) return;
|
|
315
|
+
|
|
316
|
+
// Access the native textarea element
|
|
317
|
+
const textareaElement = this.titleInputRef.nativeElement.querySelector('textarea');
|
|
318
|
+
if (textareaElement) {
|
|
319
|
+
textareaElement.style.height = 'auto';
|
|
320
|
+
textareaElement.style.height = textareaElement.scrollHeight + 'px';
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
/**
|
|
325
|
+
* Auto-resize the description textarea based on content
|
|
326
|
+
*/
|
|
327
|
+
private autoResizeDescriptionTextarea(): void {
|
|
328
|
+
if (!this.descriptionInputRef) return;
|
|
329
|
+
|
|
330
|
+
const textareaElement = this.descriptionInputRef.nativeElement.querySelector('textarea');
|
|
331
|
+
if (textareaElement) {
|
|
332
|
+
textareaElement.style.height = 'auto';
|
|
333
|
+
textareaElement.style.height = textareaElement.scrollHeight + 'px';
|
|
334
|
+
}
|
|
335
|
+
}
|
|
336
|
+
|
|
337
|
+
/**
|
|
338
|
+
* Handle title change with auto-resize
|
|
339
|
+
*/
|
|
340
|
+
handleTitleChange(value: string): void {
|
|
341
|
+
this.validateForm();
|
|
342
|
+
this.autoResizeTitleTextarea();
|
|
343
|
+
}
|
|
344
|
+
|
|
345
|
+
/**
|
|
346
|
+
* Handle description change with auto-resize
|
|
347
|
+
*/
|
|
348
|
+
handleDescriptionChange(value: string): void {
|
|
349
|
+
this.validateForm();
|
|
350
|
+
this.autoResizeDescriptionTextarea();
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
/**
|
|
354
|
+
* Validate form fields
|
|
355
|
+
*/
|
|
356
|
+
validateForm(): void {
|
|
357
|
+
const isValid = this.title.trim().length > 0 && this.description.trim().length > 0;
|
|
358
|
+
this.isFormValid.set(isValid);
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
/**
|
|
362
|
+
* Open who can book sheet
|
|
363
|
+
*/
|
|
364
|
+
async openWhoSheet(): Promise<void> {
|
|
365
|
+
console.log('[FacilityCreationModal] Opening who can book sheet');
|
|
366
|
+
const { DsMobileWhoCanBookSheetComponent } = await import('./sheets/ds-mobile-who-can-book-sheet');
|
|
367
|
+
|
|
368
|
+
const modal = await this.bottomSheetService.create({
|
|
369
|
+
component: DsMobileWhoCanBookSheetComponent,
|
|
370
|
+
componentProps: {},
|
|
371
|
+
breakpoints: [0, 1],
|
|
372
|
+
initialBreakpoint: 1,
|
|
373
|
+
handle: true,
|
|
374
|
+
cssClass: ['ds-bottom-sheet', 'auto-height']
|
|
375
|
+
});
|
|
376
|
+
|
|
377
|
+
const result = await modal.onWillDismiss();
|
|
378
|
+
if (result?.data?.value) {
|
|
379
|
+
// value is now an array of selected community IDs
|
|
380
|
+
const selectedIds = result.data.value as string[];
|
|
381
|
+
|
|
382
|
+
// If all non-"alle" options are selected, just display "Alle"
|
|
383
|
+
const allCommunities = ['faelleskab-a', 'faelleskab-b', 'faelleskab-c'];
|
|
384
|
+
const allCommunitiesSelected = allCommunities.every(id => selectedIds.includes(id));
|
|
385
|
+
|
|
386
|
+
if (allCommunitiesSelected || selectedIds.includes('alle')) {
|
|
387
|
+
this.whoCanBook.set('Alle');
|
|
388
|
+
} else {
|
|
389
|
+
// Otherwise, show individual labels
|
|
390
|
+
const labels = selectedIds
|
|
391
|
+
.filter(id => id !== 'alle') // Exclude "alle" from individual display
|
|
392
|
+
.map((id: string) => {
|
|
393
|
+
// Convert IDs to display labels
|
|
394
|
+
if (id === 'faelleskab-a') return 'Fælleskab A';
|
|
395
|
+
if (id === 'faelleskab-b') return 'Fælleskab B';
|
|
396
|
+
if (id === 'faelleskab-c') return 'Fælleskab C';
|
|
397
|
+
return id;
|
|
398
|
+
});
|
|
399
|
+
this.whoCanBook.set(labels.join(', '));
|
|
400
|
+
}
|
|
401
|
+
}
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
/**
|
|
405
|
+
* Open when can it be booked sheet
|
|
406
|
+
*/
|
|
407
|
+
async openWhenSheet(): Promise<void> {
|
|
408
|
+
console.log('[FacilityCreationModal] Opening when sheet');
|
|
409
|
+
const { DsMobileWhenCanBookSheetComponent } = await import('./sheets/ds-mobile-when-can-book-sheet');
|
|
410
|
+
|
|
411
|
+
const modal = await this.bottomSheetService.create({
|
|
412
|
+
component: DsMobileWhenCanBookSheetComponent,
|
|
413
|
+
componentProps: {},
|
|
414
|
+
breakpoints: [0, 1],
|
|
415
|
+
initialBreakpoint: 1,
|
|
416
|
+
handle: true,
|
|
417
|
+
cssClass: ['ds-bottom-sheet', 'auto-height']
|
|
418
|
+
});
|
|
419
|
+
|
|
420
|
+
const result = await modal.onWillDismiss();
|
|
421
|
+
if (result?.data?.value) {
|
|
422
|
+
// value is now an object with days, timeRange, duration
|
|
423
|
+
const { days, timeRange, duration } = result.data.value;
|
|
424
|
+
const dayStr = days.join(', ');
|
|
425
|
+
const timeStr = `${timeRange.start} til ${timeRange.end}`;
|
|
426
|
+
this.whenCanBook.set(`${dayStr}, ${timeStr}, ${duration}`);
|
|
427
|
+
}
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
/**
|
|
431
|
+
* Open price sheet
|
|
432
|
+
*/
|
|
433
|
+
async openPriceSheet(): Promise<void> {
|
|
434
|
+
console.log('[FacilityCreationModal] Opening price sheet');
|
|
435
|
+
const { DsMobilePriceSheetComponent } = await import('./sheets/ds-mobile-price-sheet');
|
|
436
|
+
|
|
437
|
+
const modal = await this.bottomSheetService.create({
|
|
438
|
+
component: DsMobilePriceSheetComponent,
|
|
439
|
+
componentProps: {},
|
|
440
|
+
breakpoints: [0, 1],
|
|
441
|
+
initialBreakpoint: 1,
|
|
442
|
+
handle: true,
|
|
443
|
+
cssClass: ['ds-bottom-sheet', 'auto-height']
|
|
444
|
+
});
|
|
445
|
+
|
|
446
|
+
const result = await modal.onWillDismiss();
|
|
447
|
+
if (result?.data?.value) {
|
|
448
|
+
this.price.set(result.data.value);
|
|
449
|
+
}
|
|
450
|
+
}
|
|
451
|
+
|
|
452
|
+
/**
|
|
453
|
+
* Open access requirements sheet
|
|
454
|
+
*/
|
|
455
|
+
async openAccessSheet(): Promise<void> {
|
|
456
|
+
console.log('[FacilityCreationModal] Opening access sheet');
|
|
457
|
+
const { DsMobileAccessSheetComponent } = await import('./sheets/ds-mobile-access-sheet');
|
|
458
|
+
|
|
459
|
+
const modal = await this.bottomSheetService.create({
|
|
460
|
+
component: DsMobileAccessSheetComponent,
|
|
461
|
+
componentProps: {},
|
|
462
|
+
breakpoints: [0, 1],
|
|
463
|
+
initialBreakpoint: 1,
|
|
464
|
+
handle: true,
|
|
465
|
+
cssClass: ['ds-bottom-sheet', 'auto-height']
|
|
466
|
+
});
|
|
467
|
+
|
|
468
|
+
const result = await modal.onWillDismiss();
|
|
469
|
+
if (result?.data?.value !== undefined) {
|
|
470
|
+
// value is now an array of selected restriction IDs
|
|
471
|
+
const selectedIds = result.data.value as string[];
|
|
472
|
+
|
|
473
|
+
// If no restrictions are selected, show "Ingen adgangskrav"
|
|
474
|
+
if (selectedIds.length === 0) {
|
|
475
|
+
this.accessRequirements.set('Ingen adgangskrav');
|
|
476
|
+
} else {
|
|
477
|
+
const labels = selectedIds.map((id: string) => {
|
|
478
|
+
// Convert IDs to display labels
|
|
479
|
+
if (id === 'digital-adgangskode') return 'Digital adgangskode';
|
|
480
|
+
if (id === 'depositum') return 'Depositum';
|
|
481
|
+
if (id === 'nøglekort') return 'Nøglekort';
|
|
482
|
+
return id;
|
|
483
|
+
});
|
|
484
|
+
this.accessRequirements.set(labels.join(', '));
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Add a new photo from camera/library
|
|
491
|
+
*/
|
|
492
|
+
async addPhoto(): Promise<void> {
|
|
493
|
+
if (this.attachments().length >= 6) {
|
|
494
|
+
return;
|
|
495
|
+
}
|
|
496
|
+
|
|
497
|
+
try {
|
|
498
|
+
const result = await FilePicker.pickImages({
|
|
499
|
+
limit: 1,
|
|
500
|
+
});
|
|
501
|
+
|
|
502
|
+
const image = result.files?.[0];
|
|
503
|
+
if (image) {
|
|
504
|
+
const newAttachment: AttachmentData = {
|
|
505
|
+
id: `photo-${Date.now()}`,
|
|
506
|
+
src: image.path ? Capacitor.convertFileSrc(image.path) : (image.blob ? URL.createObjectURL(image.blob) : ''),
|
|
507
|
+
type: 'image',
|
|
508
|
+
name: image.name || `Photo ${this.attachments().length + 1}`,
|
|
509
|
+
size: this.formatFileSize(image.size ?? 0),
|
|
510
|
+
};
|
|
511
|
+
|
|
512
|
+
this.attachments.update((attachments) => [...attachments, newAttachment]);
|
|
513
|
+
}
|
|
514
|
+
} catch (error) {
|
|
515
|
+
console.error('[FacilityCreationModal] Error adding photo:', error);
|
|
516
|
+
// User cancelled or error occurred - just ignore
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
/**
|
|
521
|
+
* Remove an attachment
|
|
522
|
+
*/
|
|
523
|
+
removeAttachment(attachmentId: string): void {
|
|
524
|
+
this.attachments.update((attachments) => attachments.filter((a) => a.id !== attachmentId));
|
|
525
|
+
}
|
|
526
|
+
|
|
527
|
+
/**
|
|
528
|
+
* Handle attachment button click
|
|
529
|
+
*/
|
|
530
|
+
handleAddAttachment(): void {
|
|
531
|
+
if (this.attachments().length >= 6) {
|
|
532
|
+
return;
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
// Trigger the hidden file input
|
|
536
|
+
if (this.fileInput) {
|
|
537
|
+
this.fileInput.nativeElement.click();
|
|
538
|
+
}
|
|
539
|
+
}
|
|
540
|
+
|
|
541
|
+
/**
|
|
542
|
+
* Detect file type from file name or mime type
|
|
543
|
+
*/
|
|
544
|
+
private detectFileType(file: File): AttachmentFileType {
|
|
545
|
+
const fileName = file.name.toLowerCase();
|
|
546
|
+
const mimeType = file.type.toLowerCase();
|
|
547
|
+
|
|
548
|
+
// Check if it's an image
|
|
549
|
+
if (mimeType.startsWith('image/')) {
|
|
550
|
+
return 'image';
|
|
551
|
+
}
|
|
552
|
+
|
|
553
|
+
// Check file extension
|
|
554
|
+
if (fileName.endsWith('.pdf')) {
|
|
555
|
+
return 'pdf';
|
|
556
|
+
} else if (fileName.endsWith('.doc')) {
|
|
557
|
+
return 'doc';
|
|
558
|
+
} else if (fileName.endsWith('.docx')) {
|
|
559
|
+
return 'docx';
|
|
560
|
+
} else if (fileName.endsWith('.xls')) {
|
|
561
|
+
return 'xls';
|
|
562
|
+
} else if (fileName.endsWith('.xlsx')) {
|
|
563
|
+
return 'xlsx';
|
|
564
|
+
}
|
|
565
|
+
|
|
566
|
+
return 'other';
|
|
567
|
+
}
|
|
568
|
+
|
|
569
|
+
/**
|
|
570
|
+
* Format file size for display
|
|
571
|
+
*/
|
|
572
|
+
private formatFileSize(bytes: number): string {
|
|
573
|
+
if (bytes === 0) return '0 B';
|
|
574
|
+
const k = 1024;
|
|
575
|
+
const sizes = ['B', 'KB', 'MB', 'GB'];
|
|
576
|
+
const i = Math.floor(Math.log(bytes) / Math.log(k));
|
|
577
|
+
return Math.round((bytes / Math.pow(k, i)) * 100) / 100 + ' ' + sizes[i];
|
|
578
|
+
}
|
|
579
|
+
|
|
580
|
+
/**
|
|
581
|
+
* Handle file selection from file input
|
|
582
|
+
*/
|
|
583
|
+
handleFileSelect(event: Event): void {
|
|
584
|
+
const input = event.target as HTMLInputElement;
|
|
585
|
+
const files = input.files;
|
|
586
|
+
|
|
587
|
+
if (!files || files.length === 0) {
|
|
588
|
+
return;
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
// Process each selected file (up to the limit)
|
|
592
|
+
const remainingSlots = 6 - this.attachments().length;
|
|
593
|
+
const filesToProcess = Array.from(files).slice(0, remainingSlots);
|
|
594
|
+
|
|
595
|
+
filesToProcess.forEach((file) => {
|
|
596
|
+
const fileType = this.detectFileType(file);
|
|
597
|
+
|
|
598
|
+
// Create a data URL for preview
|
|
599
|
+
const reader = new FileReader();
|
|
600
|
+
reader.onload = (e) => {
|
|
601
|
+
const result = e.target?.result as string;
|
|
602
|
+
if (result) {
|
|
603
|
+
const newAttachment: AttachmentData = {
|
|
604
|
+
id: `file-${Date.now()}-${Math.random()}`,
|
|
605
|
+
src: result,
|
|
606
|
+
type: fileType,
|
|
607
|
+
name: file.name,
|
|
608
|
+
size: this.formatFileSize(file.size),
|
|
609
|
+
};
|
|
610
|
+
this.attachments.update((attachments) => [...attachments, newAttachment]);
|
|
611
|
+
}
|
|
612
|
+
};
|
|
613
|
+
reader.readAsDataURL(file);
|
|
614
|
+
});
|
|
615
|
+
|
|
616
|
+
// Reset the input so the same file can be selected again
|
|
617
|
+
input.value = '';
|
|
618
|
+
}
|
|
619
|
+
|
|
620
|
+
/**
|
|
621
|
+
* Handle form submission
|
|
622
|
+
*/
|
|
623
|
+
async handleSubmit(): Promise<void> {
|
|
624
|
+
if (!this.isFormValid() || this.isSubmitting()) {
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
627
|
+
|
|
628
|
+
this.isSubmitting.set(true);
|
|
629
|
+
|
|
630
|
+
try {
|
|
631
|
+
const facilityData: NewFacilityData = {
|
|
632
|
+
title: this.title.trim(),
|
|
633
|
+
description: this.description.trim(),
|
|
634
|
+
whoCanBook: this.whoCanBook(),
|
|
635
|
+
whenCanBook: this.whenCanBook(),
|
|
636
|
+
price: this.price(),
|
|
637
|
+
accessRequirements: this.accessRequirements(),
|
|
638
|
+
attachments: this.attachments(),
|
|
639
|
+
};
|
|
640
|
+
|
|
641
|
+
console.log('[FacilityCreationModal] Submitting facility:', facilityData);
|
|
642
|
+
|
|
643
|
+
if (this.onSubmit) {
|
|
644
|
+
await this.onSubmit(facilityData);
|
|
645
|
+
}
|
|
646
|
+
|
|
647
|
+
// Success - close the modal
|
|
648
|
+
this.modalController.dismiss();
|
|
649
|
+
} catch (error) {
|
|
650
|
+
console.error('[FacilityCreationModal] Error submitting facility:', error);
|
|
651
|
+
this.error = 'Failed to create facility. Please try again.';
|
|
652
|
+
} finally {
|
|
653
|
+
this.isSubmitting.set(false);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export { DsMobileFacilityCreationModalComponent } from './ds-mobile-facility-creation-modal';
|
|
2
|
+
export type { NewFacilityData } from './ds-mobile-facility-creation-modal';
|
|
3
|
+
export { DsMobileFacilityCreationModalService } from './ds-mobile-facility-creation-modal.service';
|
|
4
|
+
export type { FacilityCreationModalOptions } from './ds-mobile-facility-creation-modal.service';
|
|
5
|
+
export { DsMobileFacilityCreationConfirmationWrapperComponent } from './ds-mobile-facility-creation-confirmation-wrapper';
|
|
6
|
+
export { DsMobileWhoCanBookSheetComponent } from './sheets/ds-mobile-who-can-book-sheet';
|
|
7
|
+
export { DsMobileWhenCanBookSheetComponent } from './sheets/ds-mobile-when-can-book-sheet';
|
|
8
|
+
export { DsMobilePriceSheetComponent } from './sheets/ds-mobile-price-sheet';
|
|
9
|
+
export { DsMobileAccessSheetComponent } from './sheets/ds-mobile-access-sheet';
|