@propbinder/mobile-design 0.2.91 → 0.2.92
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/fesm2022/propbinder-mobile-design.mjs +1669 -458
- package/fesm2022/propbinder-mobile-design.mjs.map +1 -1
- package/index.d.ts +234 -16
- package/package.json +1 -1
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import * as i0 from '@angular/core';
|
|
2
|
-
import { signal, computed, effect, Injectable, inject, Input, Component, input, Directive, EventEmitter, HostListener, Output, PLATFORM_ID, ElementRef,
|
|
2
|
+
import { signal, computed, effect, Injectable, inject, Input, Component, input, output, Directive, EventEmitter, HostListener, Output, PLATFORM_ID, ElementRef, CUSTOM_ELEMENTS_SCHEMA, TemplateRef, ContentChild, forwardRef, ViewChild, afterNextRender, ViewEncapsulation, model, createComponent, ChangeDetectionStrategy, NgZone, Pipe, HostBinding, InjectionToken } from '@angular/core';
|
|
3
3
|
import * as i1$1 from '@angular/common';
|
|
4
4
|
import { CommonModule, isPlatformBrowser } from '@angular/common';
|
|
5
5
|
import * as i1$3 from '@angular/router';
|
|
@@ -689,39 +689,91 @@ class DsMobileGlassSpinnerComponent {
|
|
|
689
689
|
*/
|
|
690
690
|
borderRadius = input(0, ...(ngDevMode ? [{ debugName: "borderRadius" }] : []));
|
|
691
691
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileGlassSpinnerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
692
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.16", type: DsMobileGlassSpinnerComponent, isStandalone: true, selector: "ds-mobile-glass-spinner", inputs: { spinnerSize: { classPropertyName: "spinnerSize", publicName: "spinnerSize", isSignal: true, isRequired: false, transformFunction: null }, borderRadius: { classPropertyName: "borderRadius", publicName: "borderRadius", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
693
|
-
<div
|
|
694
|
-
class="glass-spinner-overlay"
|
|
695
|
-
[style.border-radius.px]="borderRadius()"
|
|
696
|
-
role="status"
|
|
697
|
-
aria-live="polite"
|
|
698
|
-
aria-label="Loading">
|
|
699
|
-
<div
|
|
700
|
-
class="spinner"
|
|
701
|
-
[style.width.px]="spinnerSize()"
|
|
702
|
-
[style.height.px]="spinnerSize()">
|
|
703
|
-
</div>
|
|
704
|
-
</div>
|
|
692
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.16", type: DsMobileGlassSpinnerComponent, isStandalone: true, selector: "ds-mobile-glass-spinner", inputs: { spinnerSize: { classPropertyName: "spinnerSize", publicName: "spinnerSize", isSignal: true, isRequired: false, transformFunction: null }, borderRadius: { classPropertyName: "borderRadius", publicName: "borderRadius", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: `
|
|
693
|
+
<div
|
|
694
|
+
class="glass-spinner-overlay"
|
|
695
|
+
[style.border-radius.px]="borderRadius()"
|
|
696
|
+
role="status"
|
|
697
|
+
aria-live="polite"
|
|
698
|
+
aria-label="Loading">
|
|
699
|
+
<div
|
|
700
|
+
class="spinner"
|
|
701
|
+
[style.width.px]="spinnerSize()"
|
|
702
|
+
[style.height.px]="spinnerSize()">
|
|
703
|
+
</div>
|
|
704
|
+
</div>
|
|
705
705
|
`, isInline: true, styles: [":host{display:contents}.glass-spinner-overlay{position:absolute;inset:0;background:#fff6;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);display:flex;align-items:center;justify-content:center;z-index:9999;border-radius:inherit}.spinner{border:2px solid var(--color-border-neutral-secondary, #E5E5E5);border-top-color:var(--color-accent, #6B5FF5);border-radius:50%;animation:spin .6s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}@media (prefers-color-scheme: dark){.glass-spinner-overlay{background:#0000004d}.spinner{border-color:#fff3;border-top-color:var(--color-accent, #6B5FF5)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
706
706
|
}
|
|
707
707
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileGlassSpinnerComponent, decorators: [{
|
|
708
708
|
type: Component,
|
|
709
|
-
args: [{ selector: 'ds-mobile-glass-spinner', standalone: true, imports: [CommonModule], template: `
|
|
710
|
-
<div
|
|
711
|
-
class="glass-spinner-overlay"
|
|
712
|
-
[style.border-radius.px]="borderRadius()"
|
|
713
|
-
role="status"
|
|
714
|
-
aria-live="polite"
|
|
715
|
-
aria-label="Loading">
|
|
716
|
-
<div
|
|
717
|
-
class="spinner"
|
|
718
|
-
[style.width.px]="spinnerSize()"
|
|
719
|
-
[style.height.px]="spinnerSize()">
|
|
720
|
-
</div>
|
|
721
|
-
</div>
|
|
709
|
+
args: [{ selector: 'ds-mobile-glass-spinner', standalone: true, imports: [CommonModule], template: `
|
|
710
|
+
<div
|
|
711
|
+
class="glass-spinner-overlay"
|
|
712
|
+
[style.border-radius.px]="borderRadius()"
|
|
713
|
+
role="status"
|
|
714
|
+
aria-live="polite"
|
|
715
|
+
aria-label="Loading">
|
|
716
|
+
<div
|
|
717
|
+
class="spinner"
|
|
718
|
+
[style.width.px]="spinnerSize()"
|
|
719
|
+
[style.height.px]="spinnerSize()">
|
|
720
|
+
</div>
|
|
721
|
+
</div>
|
|
722
722
|
`, styles: [":host{display:contents}.glass-spinner-overlay{position:absolute;inset:0;background:#fff6;backdrop-filter:blur(8px);-webkit-backdrop-filter:blur(8px);display:flex;align-items:center;justify-content:center;z-index:9999;border-radius:inherit}.spinner{border:2px solid var(--color-border-neutral-secondary, #E5E5E5);border-top-color:var(--color-accent, #6B5FF5);border-radius:50%;animation:spin .6s linear infinite}@keyframes spin{to{transform:rotate(360deg)}}@media (prefers-color-scheme: dark){.glass-spinner-overlay{background:#0000004d}.spinner{border-color:#fff3;border-top-color:var(--color-accent, #6B5FF5)}}\n"] }]
|
|
723
723
|
}], propDecorators: { spinnerSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "spinnerSize", required: false }] }], borderRadius: [{ type: i0.Input, args: [{ isSignal: true, alias: "borderRadius", required: false }] }] } });
|
|
724
724
|
|
|
725
|
+
class DsMobileCountBadgeComponent {
|
|
726
|
+
count = input.required(...(ngDevMode ? [{ debugName: "count" }] : []));
|
|
727
|
+
variant = input('accent', ...(ngDevMode ? [{ debugName: "variant" }] : []));
|
|
728
|
+
display = computed(() => {
|
|
729
|
+
const n = this.count();
|
|
730
|
+
return n > 99 ? '99+' : `${n}`;
|
|
731
|
+
}, ...(ngDevMode ? [{ debugName: "display" }] : []));
|
|
732
|
+
label = computed(() => `${this.count()} notifikationer`, ...(ngDevMode ? [{ debugName: "label" }] : []));
|
|
733
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileCountBadgeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
734
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.16", type: DsMobileCountBadgeComponent, isStandalone: true, selector: "ds-mobile-count-badge", inputs: { count: { classPropertyName: "count", publicName: "count", isSignal: true, isRequired: true, transformFunction: null }, variant: { classPropertyName: "variant", publicName: "variant", isSignal: true, isRequired: false, transformFunction: null } }, host: { properties: { "class": "'count-badge count-badge--' + variant()", "attr.aria-label": "label()" } }, ngImport: i0, template: `{{ display() }}`, isInline: true, styles: [":host{display:inline-flex;align-items:center;justify-content:center;min-width:24px;height:16px;padding:0 6px;border-radius:10px;font-family:Brockmann,system-ui,-apple-system,sans-serif;font-weight:600;font-size:var(--font-size-xs);line-height:1;color:var(--color-on-accent, #ffffff);white-space:nowrap;box-sizing:border-box}:host(.count-badge--accent){background:var(--color-accent, #6B5FF5)}:host(.count-badge--notification){width:16px;height:16px;min-width:16px;padding:0;border-radius:4px;background:var(--content-feedback-bold-red, #b91c1c)}:host(.count-badge--muted){background:rgba(var(--header-content-color-rgb, 255, 255, 255),.2);color:var(--header-content-color, white)}\n"] });
|
|
735
|
+
}
|
|
736
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileCountBadgeComponent, decorators: [{
|
|
737
|
+
type: Component,
|
|
738
|
+
args: [{ selector: 'ds-mobile-count-badge', standalone: true, host: {
|
|
739
|
+
'[class]': "'count-badge count-badge--' + variant()",
|
|
740
|
+
'[attr.aria-label]': "label()",
|
|
741
|
+
}, template: `{{ display() }}`, styles: [":host{display:inline-flex;align-items:center;justify-content:center;min-width:24px;height:16px;padding:0 6px;border-radius:10px;font-family:Brockmann,system-ui,-apple-system,sans-serif;font-weight:600;font-size:var(--font-size-xs);line-height:1;color:var(--color-on-accent, #ffffff);white-space:nowrap;box-sizing:border-box}:host(.count-badge--accent){background:var(--color-accent, #6B5FF5)}:host(.count-badge--notification){width:16px;height:16px;min-width:16px;padding:0;border-radius:4px;background:var(--content-feedback-bold-red, #b91c1c)}:host(.count-badge--muted){background:rgba(var(--header-content-color-rgb, 255, 255, 255),.2);color:var(--header-content-color, white)}\n"] }]
|
|
742
|
+
}], propDecorators: { count: [{ type: i0.Input, args: [{ isSignal: true, alias: "count", required: true }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }] } });
|
|
743
|
+
|
|
744
|
+
class DsMobileNotificationButtonComponent {
|
|
745
|
+
count = input(0, ...(ngDevMode ? [{ debugName: "count" }] : []));
|
|
746
|
+
clicked = output();
|
|
747
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileNotificationButtonComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
748
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DsMobileNotificationButtonComponent, isStandalone: true, selector: "ds-mobile-notification-button", inputs: { count: { classPropertyName: "count", publicName: "count", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { clicked: "clicked" }, ngImport: i0, template: `
|
|
749
|
+
<ds-icon-button
|
|
750
|
+
icon="remixNotificationLine"
|
|
751
|
+
variant="secondary"
|
|
752
|
+
size="md"
|
|
753
|
+
(clicked)="clicked.emit()"
|
|
754
|
+
[ariaLabel]="'Notifikationer'"
|
|
755
|
+
/>
|
|
756
|
+
@if (count() > 0) {
|
|
757
|
+
<ds-mobile-count-badge [count]="count()" variant="notification" />
|
|
758
|
+
}
|
|
759
|
+
`, isInline: true, styles: [":host{position:relative;display:inline-flex;align-items:center;justify-content:center}ds-icon-button{--text-color-default-secondary: var(--color-header-content, white);--text-color-default-primary: var(--color-header-content, white);--color-background-neutral-secondary-hover: rgba(var(--color-header-content-rgb, 255, 255, 255), .1);--color-background-neutral-secondary: transparent}ds-icon-button::ng-deep button{border-radius:50%!important}ds-mobile-count-badge{position:absolute;top:0;right:0;pointer-events:none}\n"], dependencies: [{ kind: "component", type: DsIconButtonComponent, selector: "ds-icon-button", inputs: ["variant", "size", "icon", "disabled", "loading", "pressed", "expanded", "ariaLabel", "tooltip", "tooltipDisabled", "tooltipPlacement"], outputs: ["clicked", "focused", "blurred"] }, { kind: "component", type: DsMobileCountBadgeComponent, selector: "ds-mobile-count-badge", inputs: ["count", "variant"] }] });
|
|
760
|
+
}
|
|
761
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileNotificationButtonComponent, decorators: [{
|
|
762
|
+
type: Component,
|
|
763
|
+
args: [{ selector: 'ds-mobile-notification-button', standalone: true, imports: [DsIconButtonComponent, DsMobileCountBadgeComponent], template: `
|
|
764
|
+
<ds-icon-button
|
|
765
|
+
icon="remixNotificationLine"
|
|
766
|
+
variant="secondary"
|
|
767
|
+
size="md"
|
|
768
|
+
(clicked)="clicked.emit()"
|
|
769
|
+
[ariaLabel]="'Notifikationer'"
|
|
770
|
+
/>
|
|
771
|
+
@if (count() > 0) {
|
|
772
|
+
<ds-mobile-count-badge [count]="count()" variant="notification" />
|
|
773
|
+
}
|
|
774
|
+
`, styles: [":host{position:relative;display:inline-flex;align-items:center;justify-content:center}ds-icon-button{--text-color-default-secondary: var(--color-header-content, white);--text-color-default-primary: var(--color-header-content, white);--color-background-neutral-secondary-hover: rgba(var(--color-header-content-rgb, 255, 255, 255), .1);--color-background-neutral-secondary: transparent}ds-icon-button::ng-deep button{border-radius:50%!important}ds-mobile-count-badge{position:absolute;top:0;right:0;pointer-events:none}\n"] }]
|
|
775
|
+
}], propDecorators: { count: [{ type: i0.Input, args: [{ isSignal: true, alias: "count", required: false }] }], clicked: [{ type: i0.Output, args: ["clicked"] }] } });
|
|
776
|
+
|
|
725
777
|
/**
|
|
726
778
|
* MobilePageBase
|
|
727
779
|
*
|
|
@@ -5835,6 +5887,8 @@ class DsMobilePageMainComponent extends MobilePageBase {
|
|
|
5835
5887
|
avatarInitials = input('U', ...(ngDevMode ? [{ debugName: "avatarInitials" }] : []));
|
|
5836
5888
|
avatarSrc = input('', ...(ngDevMode ? [{ debugName: "avatarSrc" }] : []));
|
|
5837
5889
|
avatarIconName = input('remixUser3Line', ...(ngDevMode ? [{ debugName: "avatarIconName" }] : []));
|
|
5890
|
+
// Inputs - Notifications
|
|
5891
|
+
notificationCount = input(0, ...(ngDevMode ? [{ debugName: "notificationCount" }] : []));
|
|
5838
5892
|
// Inputs - Features
|
|
5839
5893
|
showRefresh = input(true, ...(ngDevMode ? [{ debugName: "showRefresh" }] : []));
|
|
5840
5894
|
showCondensedHeader = input(true, ...(ngDevMode ? [{ debugName: "showCondensedHeader" }] : []));
|
|
@@ -5885,6 +5939,7 @@ class DsMobilePageMainComponent extends MobilePageBase {
|
|
|
5885
5939
|
*/
|
|
5886
5940
|
profileMenuItems = input(undefined, ...(ngDevMode ? [{ debugName: "profileMenuItems" }] : []));
|
|
5887
5941
|
// Outputs
|
|
5942
|
+
notificationClick = output();
|
|
5888
5943
|
avatarClick = output();
|
|
5889
5944
|
/**
|
|
5890
5945
|
* Emitted when a profile menu action is selected.
|
|
@@ -6074,7 +6129,7 @@ class DsMobilePageMainComponent extends MobilePageBase {
|
|
|
6074
6129
|
this.refresh.emit(event);
|
|
6075
6130
|
}
|
|
6076
6131
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobilePageMainComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
6077
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DsMobilePageMainComponent, isStandalone: true, selector: "ds-mobile-page-main", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, headerTitle: { classPropertyName: "headerTitle", publicName: "headerTitle", isSignal: true, isRequired: false, transformFunction: null }, headerSubtitle: { classPropertyName: "headerSubtitle", publicName: "headerSubtitle", isSignal: true, isRequired: false, transformFunction: null }, firstEntry: { classPropertyName: "firstEntry", publicName: "firstEntry", isSignal: true, isRequired: false, transformFunction: null }, avatarType: { classPropertyName: "avatarType", publicName: "avatarType", isSignal: true, isRequired: false, transformFunction: null }, avatarInitials: { classPropertyName: "avatarInitials", publicName: "avatarInitials", isSignal: true, isRequired: false, transformFunction: null }, avatarSrc: { classPropertyName: "avatarSrc", publicName: "avatarSrc", isSignal: true, isRequired: false, transformFunction: null }, avatarIconName: { classPropertyName: "avatarIconName", publicName: "avatarIconName", isSignal: true, isRequired: false, transformFunction: null }, showRefresh: { classPropertyName: "showRefresh", publicName: "showRefresh", isSignal: true, isRequired: false, transformFunction: null }, showCondensedHeader: { classPropertyName: "showCondensedHeader", publicName: "showCondensedHeader", isSignal: true, isRequired: false, transformFunction: null }, scrollThreshold: { classPropertyName: "scrollThreshold", publicName: "scrollThreshold", isSignal: true, isRequired: false, transformFunction: null }, headerFadeDistance: { classPropertyName: "headerFadeDistance", publicName: "headerFadeDistance", isSignal: true, isRequired: false, transformFunction: null }, contentPadding: { classPropertyName: "contentPadding", publicName: "contentPadding", isSignal: true, isRequired: false, transformFunction: null }, profileMenuItems: { classPropertyName: "profileMenuItems", publicName: "profileMenuItems", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { avatarClick: "avatarClick", profileActionSelected: "profileActionSelected", refresh: "refresh", scroll: "scroll" }, host: { properties: { "style.--content-wrapper-padding": "contentPadding()" } }, viewQueries: [{ propertyName: "ionContent", first: true, predicate: IonContent, descendants: true }], usesInheritance: true, ngImport: i0, template: `
|
|
6132
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DsMobilePageMainComponent, isStandalone: true, selector: "ds-mobile-page-main", inputs: { title: { classPropertyName: "title", publicName: "title", isSignal: true, isRequired: true, transformFunction: null }, headerTitle: { classPropertyName: "headerTitle", publicName: "headerTitle", isSignal: true, isRequired: false, transformFunction: null }, headerSubtitle: { classPropertyName: "headerSubtitle", publicName: "headerSubtitle", isSignal: true, isRequired: false, transformFunction: null }, firstEntry: { classPropertyName: "firstEntry", publicName: "firstEntry", isSignal: true, isRequired: false, transformFunction: null }, avatarType: { classPropertyName: "avatarType", publicName: "avatarType", isSignal: true, isRequired: false, transformFunction: null }, avatarInitials: { classPropertyName: "avatarInitials", publicName: "avatarInitials", isSignal: true, isRequired: false, transformFunction: null }, avatarSrc: { classPropertyName: "avatarSrc", publicName: "avatarSrc", isSignal: true, isRequired: false, transformFunction: null }, avatarIconName: { classPropertyName: "avatarIconName", publicName: "avatarIconName", isSignal: true, isRequired: false, transformFunction: null }, notificationCount: { classPropertyName: "notificationCount", publicName: "notificationCount", isSignal: true, isRequired: false, transformFunction: null }, showRefresh: { classPropertyName: "showRefresh", publicName: "showRefresh", isSignal: true, isRequired: false, transformFunction: null }, showCondensedHeader: { classPropertyName: "showCondensedHeader", publicName: "showCondensedHeader", isSignal: true, isRequired: false, transformFunction: null }, scrollThreshold: { classPropertyName: "scrollThreshold", publicName: "scrollThreshold", isSignal: true, isRequired: false, transformFunction: null }, headerFadeDistance: { classPropertyName: "headerFadeDistance", publicName: "headerFadeDistance", isSignal: true, isRequired: false, transformFunction: null }, contentPadding: { classPropertyName: "contentPadding", publicName: "contentPadding", isSignal: true, isRequired: false, transformFunction: null }, profileMenuItems: { classPropertyName: "profileMenuItems", publicName: "profileMenuItems", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { notificationClick: "notificationClick", avatarClick: "avatarClick", profileActionSelected: "profileActionSelected", refresh: "refresh", scroll: "scroll" }, host: { properties: { "style.--content-wrapper-padding": "contentPadding()" } }, viewQueries: [{ propertyName: "ionContent", first: true, predicate: IonContent, descendants: true }], usesInheritance: true, ngImport: i0, template: `
|
|
6078
6133
|
<!-- Fixed header at top -->
|
|
6079
6134
|
<ion-header>
|
|
6080
6135
|
<ion-toolbar>
|
|
@@ -6085,8 +6140,12 @@ class DsMobilePageMainComponent extends MobilePageBase {
|
|
|
6085
6140
|
<!-- Title - fades in on scroll -->
|
|
6086
6141
|
<ion-title class="header-main__title">{{ title() }}</ion-title>
|
|
6087
6142
|
|
|
6088
|
-
<!-- Avatar -->
|
|
6143
|
+
<!-- Notification + Avatar -->
|
|
6089
6144
|
<div class="header-main__actions">
|
|
6145
|
+
<ds-mobile-notification-button
|
|
6146
|
+
[count]="notificationCount()"
|
|
6147
|
+
(clicked)="notificationClick.emit()"
|
|
6148
|
+
/>
|
|
6090
6149
|
<ds-avatar
|
|
6091
6150
|
[size]="'md'"
|
|
6092
6151
|
[type]="avatarType()"
|
|
@@ -6151,11 +6210,11 @@ class DsMobilePageMainComponent extends MobilePageBase {
|
|
|
6151
6210
|
</div>
|
|
6152
6211
|
</div>
|
|
6153
6212
|
</ion-content>
|
|
6154
|
-
`, isInline: true, styles: [":host{display:flex;flex-direction:column;align-items:center;height:100%;background:var(--color-header-surface);width:100%}:host ion-header{background:var(--color-header-surface);box-shadow:none;height:72px;min-height:72px;margin-top:var(--app-header-top-offset)}:host ion-header ion-toolbar{--background: var(--color-header-surface);--border-width: 0;--box-shadow: none;--padding-top: 0;--padding-bottom: 0;--padding-start: 0;--padding-end: 0;--min-height: 72px;height:72px;min-height:72px;padding:0}@media (min-width: 768px){:host ion-header{height:88px;min-height:88px}:host ion-header ion-toolbar{--min-height: 88px;height:88px;min-height:88px}}@media (min-width: 768px){:host ion-header{display:none;height:auto}}:host .header-main,:host .header-details,.header-details{display:flex;align-items:center;justify-content:space-between;background:var(--color-header-surface);position:relative}:host .header-main__title,:host .header-details .header-title,.header-details .header-title{position:absolute;left:50%;transform:translate(-50%);font-size:var(--font-size-base);font-weight:600;color:var(--color-header-content);margin:0;padding:0;--color: var(--color-header-content)}.header-details .header-title{transform:translate(-50%) translateY(-100%);opacity:0!important;pointer-events:none;transition:transform .2s ease,opacity .2s ease!important}.header-scrolled .header-details .header-title{opacity:1!important;pointer-events:auto;transform:translate(-50%) translateY(0)}:host .header-details .back-button,.header-details .back-button{background:none;border:none;padding:0;display:flex;align-items:center;justify-content:center;cursor:pointer;color:var(--color-header-content);transition:opacity var(--transition-duration-fast, .2s) var(--ease-smooth, ease);z-index:10;position:relative}:host .header-details .back-button:hover,.header-details .back-button:hover{opacity:.8}:host .header-details .back-button:active,.header-details .back-button:active{opacity:.6}:host ion-content{--background: var(--color-header-surface);--padding-top: 0;--padding-start: 0;--padding-end: 0;--padding-bottom: 0;border-radius:24px 24px 0 0;overflow:hidden}:host ion-content::part(scroll){display:flex;flex-direction:column;min-height:100%;-webkit-overflow-scrolling:touch}.plt-ios :host ion-content{--background: var(--color-background-neutral-primary)}@media (min-width: 768px){:host ion-content{border-radius:24px 24px 0 0}}:host ion-header[collapse=condense]{display:none}@media (min-width: 768px){:host ion-header[collapse=condense]{display:none}}:host ion-refresher{z-index:0}:host ion-refresher-content{--color: var(--color-header-content)}:host .content-wrapper{width:100%;position:relative;z-index:20;flex:1;display:flex;flex-direction:column;background:var(--color-background-neutral-primary);border-radius:24px 24px 0 0;overflow:visible;transform:translateZ(0);will-change:transform;isolation:isolate;box-shadow:0 300px 0 0 var(--color-background-neutral-primary);padding-top:0;padding-left:var(--content-wrapper-padding, 20px);padding-right:var(--content-wrapper-padding, 20px);padding-bottom:calc(var(--mobile-content-spacing) + var(--mobile-tab-bar-height) + var(--app-safe-bottom, 0px))}:host .content-inner{max-width:640px;margin:0 auto;width:100%}@media (min-width: 768px){:host .content-wrapper{padding-top:0;padding-left:var(--content-wrapper-padding, 20px);padding-right:var(--content-wrapper-padding, 20px)}}:host .header-expandable{background:var(--color-header-surface);padding:32px 20px 24px;color:var(--header-content-color, white);position:sticky;top:0;z-index:5;transition:opacity .1s ease-out,transform .1s ease-out;flex:0 0 auto;min-height:-moz-min-content;min-height:min-content}:host .header-expandable-inner{display:flex;flex-direction:column;gap:20px;max-width:640px;margin:0 auto}:host .header-expandable__text{margin-bottom:0;gap:4px;display:flex;flex-direction:column}:host .header-expandable__title{font-size:var(--font-size-2xl);font-weight:600;color:var(--header-content-color, white);margin:0}:host .header-expandable__subtitle{font-size:var(--font-size-sm);font-weight:400;color:var(--header-content-color, white);opacity:.85;margin:0}@media (min-width: 768px){:host .header-expandable{padding:48px 20px 32px}:host .header-expandable__title{font-size:var(--font-size-3xl)}:host .header-expandable__subtitle{font-size:var(--font-size-base)}}@media (min-width: 992px){:host .header-expandable{padding-left:var(--content-padding-lg);padding-right:var(--content-padding-lg)}}@media (min-width: 1440px){:host .header-expandable{padding-left:var(--content-padding-xl);padding-right:var(--content-padding-xl)}}@media (min-width: 1768px){:host .header-expandable{padding-left:var(--content-padding-2xl);padding-right:var(--content-padding-2xl)}}@media (min-width: 1920px){:host .header-expandable{padding-left:var(--content-padding-3xl);padding-right:var(--content-padding-3xl)}}\n", ".header-main{padding:0 20px;height:72px}.header-main__title{transform:translate(-50%) translateY(-100%);opacity:0;transition:transform .6s ease,opacity .6s ease;padding:0;--color: var(--color-header-content)}.header-scrolled .header-main__title{opacity:1;transform:translate(-50%) translateY(0)}.header-main__actions{display:flex;align-items:center;gap:8px}.header-main__actions ds-avatar{cursor:pointer;-webkit-tap-highlight-color:transparent}@keyframes logoSlideIn{0%{transform:translateY(-200%);scale:.75;opacity:0}to{transform:translateY(0);scale:1;opacity:1}}.logo--first-entry{animation:logoSlideIn .75s var(--spring-curve-bouncy) .7s both}@media (min-width: 768px){.header-main{padding:16px 24px;height:88px}.header-main__title{display:none}}ion-refresher{--color: var(--color-header-content)}ion-refresher-content{--color: var(--color-header-content)}ion-refresher-content::part(spinner){color:var(--color-header-content)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: IonRefresher, selector: "ion-refresher", inputs: ["closeDuration", "disabled", "mode", "pullFactor", "pullMax", "pullMin", "snapbackDuration"] }, { kind: "component", type: IonRefresherContent, selector: "ion-refresher-content", inputs: ["pullingIcon", "pullingText", "refreshingSpinner", "refreshingText"] }, { kind: "component", type: DsAvatarComponent, selector: "ds-avatar", inputs: ["type", "size", "initials", "src", "alt", "iconName", "iconColor"] }, { kind: "component", type: DsLogoComponent, selector: "ds-logo", inputs: ["variant", "size", "customHeight", "customWidth"] }, { kind: "component", type: DsMobileGlassSpinnerComponent, selector: "ds-mobile-glass-spinner", inputs: ["spinnerSize", "borderRadius"] }] });
|
|
6213
|
+
`, isInline: true, styles: [":host{display:flex;flex-direction:column;align-items:center;height:100%;background:var(--color-header-surface);width:100%}:host ion-header{background:var(--color-header-surface);box-shadow:none;height:72px;min-height:72px;margin-top:var(--app-header-top-offset)}:host ion-header ion-toolbar{--background: var(--color-header-surface);--border-width: 0;--box-shadow: none;--padding-top: 0;--padding-bottom: 0;--padding-start: 0;--padding-end: 0;--min-height: 72px;height:72px;min-height:72px;padding:0}@media (min-width: 768px){:host ion-header{height:88px;min-height:88px}:host ion-header ion-toolbar{--min-height: 88px;height:88px;min-height:88px}}@media (min-width: 768px){:host ion-header{display:none;height:auto}}:host .header-main,:host .header-details,.header-details{display:flex;align-items:center;justify-content:space-between;background:var(--color-header-surface);position:relative}:host .header-main__title,:host .header-details .header-title,.header-details .header-title{position:absolute;left:50%;transform:translate(-50%);font-size:var(--font-size-base);font-weight:600;color:var(--color-header-content);margin:0;padding:0;--color: var(--color-header-content)}.header-details .header-title{transform:translate(-50%) translateY(-100%);opacity:0!important;pointer-events:none;transition:transform .2s ease,opacity .2s ease!important}.header-scrolled .header-details .header-title{opacity:1!important;pointer-events:auto;transform:translate(-50%) translateY(0)}:host .header-details .back-button,.header-details .back-button{background:none;border:none;padding:0;display:flex;align-items:center;justify-content:center;cursor:pointer;color:var(--color-header-content);transition:opacity var(--transition-duration-fast, .2s) var(--ease-smooth, ease);z-index:10;position:relative}:host .header-details .back-button:hover,.header-details .back-button:hover{opacity:.8}:host .header-details .back-button:active,.header-details .back-button:active{opacity:.6}:host ion-content{--background: var(--color-header-surface);--padding-top: 0;--padding-start: 0;--padding-end: 0;--padding-bottom: 0;border-radius:24px 24px 0 0;overflow:hidden}:host ion-content::part(scroll){display:flex;flex-direction:column;min-height:100%;-webkit-overflow-scrolling:touch}.plt-ios :host ion-content{--background: var(--color-background-neutral-primary)}@media (min-width: 768px){:host ion-content{border-radius:24px 24px 0 0}}:host ion-header[collapse=condense]{display:none}@media (min-width: 768px){:host ion-header[collapse=condense]{display:none}}:host ion-refresher{z-index:0}:host ion-refresher-content{--color: var(--color-header-content)}:host .content-wrapper{width:100%;position:relative;z-index:20;flex:1;display:flex;flex-direction:column;background:var(--color-background-neutral-primary);border-radius:24px 24px 0 0;overflow:visible;transform:translateZ(0);will-change:transform;isolation:isolate;box-shadow:0 300px 0 0 var(--color-background-neutral-primary);padding-top:0;padding-left:var(--content-wrapper-padding, 20px);padding-right:var(--content-wrapper-padding, 20px);padding-bottom:calc(var(--mobile-content-spacing) + var(--mobile-tab-bar-height) + var(--app-safe-bottom, 0px))}:host .content-inner{max-width:640px;margin:0 auto;width:100%}@media (min-width: 768px){:host .content-wrapper{padding-top:0;padding-left:var(--content-wrapper-padding, 20px);padding-right:var(--content-wrapper-padding, 20px)}}:host .header-expandable{background:var(--color-header-surface);padding:32px 20px 24px;color:var(--header-content-color, white);position:sticky;top:0;z-index:5;transition:opacity .1s ease-out,transform .1s ease-out;flex:0 0 auto;min-height:-moz-min-content;min-height:min-content}:host .header-expandable-inner{display:flex;flex-direction:column;gap:20px;max-width:640px;margin:0 auto}:host .header-expandable__text{margin-bottom:0;gap:4px;display:flex;flex-direction:column}:host .header-expandable__title{font-size:var(--font-size-2xl);font-weight:600;color:var(--header-content-color, white);margin:0}:host .header-expandable__subtitle{font-size:var(--font-size-sm);font-weight:400;color:var(--header-content-color, white);opacity:.85;margin:0}@media (min-width: 768px){:host .header-expandable{padding:48px 20px 32px}:host .header-expandable__title{font-size:var(--font-size-3xl)}:host .header-expandable__subtitle{font-size:var(--font-size-base)}}@media (min-width: 992px){:host .header-expandable{padding-left:var(--content-padding-lg);padding-right:var(--content-padding-lg)}}@media (min-width: 1440px){:host .header-expandable{padding-left:var(--content-padding-xl);padding-right:var(--content-padding-xl)}}@media (min-width: 1768px){:host .header-expandable{padding-left:var(--content-padding-2xl);padding-right:var(--content-padding-2xl)}}@media (min-width: 1920px){:host .header-expandable{padding-left:var(--content-padding-3xl);padding-right:var(--content-padding-3xl)}}\n", ".header-main{padding:0 20px;height:72px}.header-main__title{transform:translate(-50%) translateY(-100%);opacity:0;transition:transform .6s ease,opacity .6s ease;padding:0;--color: var(--color-header-content)}.header-scrolled .header-main__title{opacity:1;transform:translate(-50%) translateY(0)}.header-main__actions{display:flex;align-items:center;gap:8px}.header-main__actions ds-avatar{cursor:pointer;-webkit-tap-highlight-color:transparent}@keyframes logoSlideIn{0%{transform:translateY(-200%);scale:.75;opacity:0}to{transform:translateY(0);scale:1;opacity:1}}.logo--first-entry{animation:logoSlideIn .75s var(--spring-curve-bouncy) .7s both}@media (min-width: 768px){.header-main{padding:16px 24px;height:88px}.header-main__title{display:none}}ion-refresher{--color: var(--color-header-content)}ion-refresher-content{--color: var(--color-header-content)}ion-refresher-content::part(spinner){color:var(--color-header-content)}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: IonHeader, selector: "ion-header", inputs: ["collapse", "mode", "translucent"] }, { kind: "component", type: IonToolbar, selector: "ion-toolbar", inputs: ["color", "mode"] }, { kind: "component", type: IonTitle, selector: "ion-title", inputs: ["color", "size"] }, { kind: "component", type: IonContent, selector: "ion-content", inputs: ["color", "fixedSlotPlacement", "forceOverscroll", "fullscreen", "scrollEvents", "scrollX", "scrollY"] }, { kind: "component", type: IonRefresher, selector: "ion-refresher", inputs: ["closeDuration", "disabled", "mode", "pullFactor", "pullMax", "pullMin", "snapbackDuration"] }, { kind: "component", type: IonRefresherContent, selector: "ion-refresher-content", inputs: ["pullingIcon", "pullingText", "refreshingSpinner", "refreshingText"] }, { kind: "component", type: DsAvatarComponent, selector: "ds-avatar", inputs: ["type", "size", "initials", "src", "alt", "iconName", "iconColor"] }, { kind: "component", type: DsLogoComponent, selector: "ds-logo", inputs: ["variant", "size", "customHeight", "customWidth"] }, { kind: "component", type: DsMobileGlassSpinnerComponent, selector: "ds-mobile-glass-spinner", inputs: ["spinnerSize", "borderRadius"] }, { kind: "component", type: DsMobileNotificationButtonComponent, selector: "ds-mobile-notification-button", inputs: ["count"], outputs: ["clicked"] }] });
|
|
6155
6214
|
}
|
|
6156
6215
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobilePageMainComponent, decorators: [{
|
|
6157
6216
|
type: Component,
|
|
6158
|
-
args: [{ selector: 'ds-mobile-page-main', standalone: true, imports: [CommonModule, IonHeader, IonToolbar, IonTitle, IonContent, IonRefresher, IonRefresherContent, DsAvatarComponent, DsLogoComponent, DsMobileGlassSpinnerComponent], host: {
|
|
6217
|
+
args: [{ selector: 'ds-mobile-page-main', standalone: true, imports: [CommonModule, IonHeader, IonToolbar, IonTitle, IonContent, IonRefresher, IonRefresherContent, DsAvatarComponent, DsLogoComponent, DsMobileGlassSpinnerComponent, DsMobileNotificationButtonComponent], host: {
|
|
6159
6218
|
'[style.--content-wrapper-padding]': 'contentPadding()'
|
|
6160
6219
|
}, template: `
|
|
6161
6220
|
<!-- Fixed header at top -->
|
|
@@ -6168,8 +6227,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
6168
6227
|
<!-- Title - fades in on scroll -->
|
|
6169
6228
|
<ion-title class="header-main__title">{{ title() }}</ion-title>
|
|
6170
6229
|
|
|
6171
|
-
<!-- Avatar -->
|
|
6230
|
+
<!-- Notification + Avatar -->
|
|
6172
6231
|
<div class="header-main__actions">
|
|
6232
|
+
<ds-mobile-notification-button
|
|
6233
|
+
[count]="notificationCount()"
|
|
6234
|
+
(clicked)="notificationClick.emit()"
|
|
6235
|
+
/>
|
|
6173
6236
|
<ds-avatar
|
|
6174
6237
|
[size]="'md'"
|
|
6175
6238
|
[type]="avatarType()"
|
|
@@ -6238,7 +6301,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
6238
6301
|
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { ionContent: [{
|
|
6239
6302
|
type: ViewChild,
|
|
6240
6303
|
args: [IonContent]
|
|
6241
|
-
}], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], headerTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerTitle", required: false }] }], headerSubtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerSubtitle", required: false }] }], firstEntry: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstEntry", required: false }] }], avatarType: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarType", required: false }] }], avatarInitials: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarInitials", required: false }] }], avatarSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarSrc", required: false }] }], avatarIconName: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarIconName", required: false }] }], showRefresh: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRefresh", required: false }] }], showCondensedHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCondensedHeader", required: false }] }], scrollThreshold: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollThreshold", required: false }] }], headerFadeDistance: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerFadeDistance", required: false }] }], contentPadding: [{ type: i0.Input, args: [{ isSignal: true, alias: "contentPadding", required: false }] }], profileMenuItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "profileMenuItems", required: false }] }], avatarClick: [{ type: i0.Output, args: ["avatarClick"] }], profileActionSelected: [{ type: i0.Output, args: ["profileActionSelected"] }], refresh: [{ type: i0.Output, args: ["refresh"] }], scroll: [{ type: i0.Output, args: ["scroll"] }] } });
|
|
6304
|
+
}], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], headerTitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerTitle", required: false }] }], headerSubtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerSubtitle", required: false }] }], firstEntry: [{ type: i0.Input, args: [{ isSignal: true, alias: "firstEntry", required: false }] }], avatarType: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarType", required: false }] }], avatarInitials: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarInitials", required: false }] }], avatarSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarSrc", required: false }] }], avatarIconName: [{ type: i0.Input, args: [{ isSignal: true, alias: "avatarIconName", required: false }] }], notificationCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "notificationCount", required: false }] }], showRefresh: [{ type: i0.Input, args: [{ isSignal: true, alias: "showRefresh", required: false }] }], showCondensedHeader: [{ type: i0.Input, args: [{ isSignal: true, alias: "showCondensedHeader", required: false }] }], scrollThreshold: [{ type: i0.Input, args: [{ isSignal: true, alias: "scrollThreshold", required: false }] }], headerFadeDistance: [{ type: i0.Input, args: [{ isSignal: true, alias: "headerFadeDistance", required: false }] }], contentPadding: [{ type: i0.Input, args: [{ isSignal: true, alias: "contentPadding", required: false }] }], profileMenuItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "profileMenuItems", required: false }] }], notificationClick: [{ type: i0.Output, args: ["notificationClick"] }], avatarClick: [{ type: i0.Output, args: ["avatarClick"] }], profileActionSelected: [{ type: i0.Output, args: ["profileActionSelected"] }], refresh: [{ type: i0.Output, args: ["refresh"] }], scroll: [{ type: i0.Output, args: ["scroll"] }] } });
|
|
6242
6305
|
|
|
6243
6306
|
/**
|
|
6244
6307
|
* DsMobileInlineTabsComponent
|
|
@@ -6297,16 +6360,16 @@ class DsMobileInlineTabsComponent {
|
|
|
6297
6360
|
}
|
|
6298
6361
|
</div>
|
|
6299
6362
|
} @else if (tab.badge && tab.badge > 0) {
|
|
6300
|
-
<
|
|
6363
|
+
<ds-mobile-count-badge [count]="tab.badge" variant="muted" />
|
|
6301
6364
|
}
|
|
6302
6365
|
</button>
|
|
6303
6366
|
}
|
|
6304
6367
|
</div>
|
|
6305
|
-
`, isInline: true, styles: [".filter-tabs{display:flex;align-items:center;gap:8px;flex-wrap:wrap;height:40px}.filter-tab{min-width:48px;justify-content:center;padding:0 12px;height:32px;border-radius:20px;background:transparent;border:none;font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;color:rgba(var(--header-content-color-rgb, 255, 255, 255),.6);cursor:pointer;transition:all .2s ease;display:flex;align-items:center;gap:6px;white-space:nowrap}.filter-tab.active{background:var(--color-header-accent, #5d5fef);color:var(--color-on-header-accent, white)}.filter-tab:hover:not(.active){background:rgba(var(--header-content-color-rgb, 255, 255, 255),.1)}.tab-badge{
|
|
6368
|
+
`, isInline: true, styles: [".filter-tabs{display:flex;align-items:center;gap:8px;flex-wrap:wrap;height:40px}.filter-tab{min-width:48px;justify-content:center;padding:0 12px;height:32px;border-radius:20px;background:transparent;border:none;font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;color:rgba(var(--header-content-color-rgb, 255, 255, 255),.6);cursor:pointer;transition:all .2s ease;display:flex;align-items:center;gap:6px;white-space:nowrap}.filter-tab.active{background:var(--color-header-accent, #5d5fef);color:var(--color-on-header-accent, white)}.filter-tab:hover:not(.active){background:rgba(var(--header-content-color-rgb, 255, 255, 255),.1)}.filter-tab.active ds-mobile-count-badge{--header-content-color-rgb: var(--color-on-header-accent-rgb, 255, 255, 255);--header-content-color: var(--color-on-header-accent, white)}.filter-tab.has-envelope{gap:0}.envelope-wrapper{position:relative;display:inline-flex;align-items:center;justify-content:center;margin-left:4px}.envelope-badge{position:absolute;top:-3px;right:-5px;background-color:#ff3b30;color:#fff;font-size:10px;font-weight:700;border-radius:9999px;min-width:12px;height:12px;display:flex;align-items:center;justify-content:center;padding:0;line-height:1;box-shadow:0 1px 2px #00000026;z-index:10}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsMobileCountBadgeComponent, selector: "ds-mobile-count-badge", inputs: ["count", "variant"] }] });
|
|
6306
6369
|
}
|
|
6307
6370
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileInlineTabsComponent, decorators: [{
|
|
6308
6371
|
type: Component,
|
|
6309
|
-
args: [{ selector: 'ds-mobile-inline-tabs', standalone: true, imports: [CommonModule, DsIconComponent], template: `
|
|
6372
|
+
args: [{ selector: 'ds-mobile-inline-tabs', standalone: true, imports: [CommonModule, DsIconComponent, DsMobileCountBadgeComponent], template: `
|
|
6310
6373
|
<div class="filter-tabs">
|
|
6311
6374
|
@for (tab of tabs(); track tab.id) {
|
|
6312
6375
|
<button
|
|
@@ -6327,12 +6390,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
6327
6390
|
}
|
|
6328
6391
|
</div>
|
|
6329
6392
|
} @else if (tab.badge && tab.badge > 0) {
|
|
6330
|
-
<
|
|
6393
|
+
<ds-mobile-count-badge [count]="tab.badge" variant="muted" />
|
|
6331
6394
|
}
|
|
6332
6395
|
</button>
|
|
6333
6396
|
}
|
|
6334
6397
|
</div>
|
|
6335
|
-
`, styles: [".filter-tabs{display:flex;align-items:center;gap:8px;flex-wrap:wrap;height:40px}.filter-tab{min-width:48px;justify-content:center;padding:0 12px;height:32px;border-radius:20px;background:transparent;border:none;font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;color:rgba(var(--header-content-color-rgb, 255, 255, 255),.6);cursor:pointer;transition:all .2s ease;display:flex;align-items:center;gap:6px;white-space:nowrap}.filter-tab.active{background:var(--color-header-accent, #5d5fef);color:var(--color-on-header-accent, white)}.filter-tab:hover:not(.active){background:rgba(var(--header-content-color-rgb, 255, 255, 255),.1)}.tab-badge{
|
|
6398
|
+
`, styles: [".filter-tabs{display:flex;align-items:center;gap:8px;flex-wrap:wrap;height:40px}.filter-tab{min-width:48px;justify-content:center;padding:0 12px;height:32px;border-radius:20px;background:transparent;border:none;font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;color:rgba(var(--header-content-color-rgb, 255, 255, 255),.6);cursor:pointer;transition:all .2s ease;display:flex;align-items:center;gap:6px;white-space:nowrap}.filter-tab.active{background:var(--color-header-accent, #5d5fef);color:var(--color-on-header-accent, white)}.filter-tab:hover:not(.active){background:rgba(var(--header-content-color-rgb, 255, 255, 255),.1)}.filter-tab.active ds-mobile-count-badge{--header-content-color-rgb: var(--color-on-header-accent-rgb, 255, 255, 255);--header-content-color: var(--color-on-header-accent, white)}.filter-tab.has-envelope{gap:0}.envelope-wrapper{position:relative;display:inline-flex;align-items:center;justify-content:center;margin-left:4px}.envelope-badge{position:absolute;top:-3px;right:-5px;background-color:#ff3b30;color:#fff;font-size:10px;font-weight:700;border-radius:9999px;min-width:12px;height:12px;display:flex;align-items:center;justify-content:center;padding:0;line-height:1;box-shadow:0 1px 2px #00000026;z-index:10}\n"] }]
|
|
6336
6399
|
}], propDecorators: { tabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabs", required: true }] }], activeTab: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeTab", required: true }] }], tabChange: [{ type: i0.Output, args: ["tabChange"] }] } });
|
|
6337
6400
|
|
|
6338
6401
|
/**
|
|
@@ -11756,7 +11819,7 @@ class DsMobileModalBaseComponent extends MobileModalBase {
|
|
|
11756
11819
|
this.headerMeta() ||
|
|
11757
11820
|
this.hasContentInSlot(this.headerLeading) ||
|
|
11758
11821
|
this.hasContentInSlot(this.headerMain) ||
|
|
11759
|
-
this.
|
|
11822
|
+
!!this.headerTrailing);
|
|
11760
11823
|
}
|
|
11761
11824
|
/**
|
|
11762
11825
|
* Check whether header-leading slot has actual projected content.
|
|
@@ -11764,6 +11827,9 @@ class DsMobileModalBaseComponent extends MobileModalBase {
|
|
|
11764
11827
|
hasHeaderLeadingContent() {
|
|
11765
11828
|
return this.hasContentInSlot(this.headerLeading);
|
|
11766
11829
|
}
|
|
11830
|
+
hasHeaderTrailingContent() {
|
|
11831
|
+
return !!this.headerTrailing;
|
|
11832
|
+
}
|
|
11767
11833
|
/**
|
|
11768
11834
|
* Check if a content child slot has actual content
|
|
11769
11835
|
*/
|
|
@@ -19246,11 +19312,14 @@ class DsMobileTabBarComponent {
|
|
|
19246
19312
|
* ```
|
|
19247
19313
|
*/
|
|
19248
19314
|
profileMenuItems;
|
|
19315
|
+
// Notification inputs
|
|
19316
|
+
notificationCount = 0;
|
|
19249
19317
|
moreMenuItems = [];
|
|
19250
19318
|
moreMenuLabel = 'Mere';
|
|
19251
19319
|
moreMenuIcon = 'remixGridLine';
|
|
19252
19320
|
moreMenuIconActive = 'remixGridFill';
|
|
19253
19321
|
// Outputs
|
|
19322
|
+
notificationClick = new EventEmitter();
|
|
19254
19323
|
avatarClick = new EventEmitter();
|
|
19255
19324
|
/**
|
|
19256
19325
|
* Emitted when a profile menu action is selected.
|
|
@@ -19836,7 +19905,7 @@ class DsMobileTabBarComponent {
|
|
|
19836
19905
|
}
|
|
19837
19906
|
}
|
|
19838
19907
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileTabBarComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
19839
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DsMobileTabBarComponent, isStandalone: true, selector: "ds-mobile-tab-bar", inputs: { tabs: "tabs", avatarType: "avatarType", avatarInitials: "avatarInitials", avatarSrc: "avatarSrc", avatarIconName: "avatarIconName", profileMenuItems: "profileMenuItems", moreMenuItems: "moreMenuItems", moreMenuLabel: "moreMenuLabel", moreMenuIcon: "moreMenuIcon", moreMenuIconActive: "moreMenuIconActive" }, outputs: { avatarClick: "avatarClick", profileActionSelected: "profileActionSelected", moreMenuItemSelected: "moreMenuItemSelected" }, ngImport: i0, template: `
|
|
19908
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DsMobileTabBarComponent, isStandalone: true, selector: "ds-mobile-tab-bar", inputs: { tabs: "tabs", avatarType: "avatarType", avatarInitials: "avatarInitials", avatarSrc: "avatarSrc", avatarIconName: "avatarIconName", profileMenuItems: "profileMenuItems", notificationCount: "notificationCount", moreMenuItems: "moreMenuItems", moreMenuLabel: "moreMenuLabel", moreMenuIcon: "moreMenuIcon", moreMenuIconActive: "moreMenuIconActive" }, outputs: { notificationClick: "notificationClick", avatarClick: "avatarClick", profileActionSelected: "profileActionSelected", moreMenuItemSelected: "moreMenuItemSelected" }, ngImport: i0, template: `
|
|
19840
19909
|
<ion-tab-bar [attr.slot]="isDesktop() ? 'top' : 'bottom'" class="ds-tab-bar" [class.ds-tab-bar--desktop]="isDesktop()">
|
|
19841
19910
|
<!-- Logo (desktop only, full logo in header) -->
|
|
19842
19911
|
<div class="ds-tab-bar__logo">
|
|
@@ -19879,16 +19948,20 @@ class DsMobileTabBarComponent {
|
|
|
19879
19948
|
}
|
|
19880
19949
|
</div>
|
|
19881
19950
|
|
|
19882
|
-
<!-- Avatar (desktop only, positioned via CSS) -->
|
|
19951
|
+
<!-- Notification + Avatar (desktop only, positioned via CSS) -->
|
|
19883
19952
|
<div class="ds-tab-bar__actions">
|
|
19953
|
+
<ds-mobile-notification-button
|
|
19954
|
+
[count]="notificationCount"
|
|
19955
|
+
(clicked)="notificationClick.emit()"
|
|
19956
|
+
/>
|
|
19884
19957
|
<ds-avatar [size]="'md'" [type]="avatarType" [initials]="avatarInitials" [src]="avatarSrc" [iconName]="avatarIconName" (click)="handleAvatarClick()" />
|
|
19885
19958
|
</div>
|
|
19886
19959
|
</ion-tab-bar>
|
|
19887
|
-
`, isInline: true, styles: [":host{--ds-tab-bar-height: 64px}@media (min-width: 768px){:host{display:block;--ds-tab-bar-height: 64px}}@media (max-width: 767px){:host{display:contents}}ion-tabs.ds-tabs-wrapper{height:100%;background:var(--color-header-surface)}ion-tab-button:before,ion-tab-button:after{content:none!important;display:none!important}ion-tab-button[title]:before,ion-tab-button[title]:after{display:none!important}ion-tab-button::part(native):before,ion-tab-button::part(native):after{display:none!important}.ds-tab-bar{--background: var(--color-background-neutral-primary);transition:transform .2s ease-in-out}ion-tab-bar[slot=bottom]{border-top:1px solid var(--border-color-default);padding-top:8px;padding-bottom:max(8px,calc(var(--app-safe-bottom, 0px) - 16px));padding-left:12px;padding-right:12px}@media (max-width: 767px){ion-tab-bar[slot=bottom]{position:fixed;bottom:0;left:0;right:0;z-index:100}}@media (max-width: 767px){:host-context(.plt-android) ion-tab-bar[slot=bottom]{padding-bottom:max(8px,var(--app-safe-bottom, 0px))!important}}@media (max-width: 767px){:host-context(ion-tabs:has(ds-mobile-page-details)) .ds-tab-bar{transform:translateY(100%);transition:transform .3s ease}}.ds-tab-bar__logo,.ds-tab-bar__actions{display:none}.ds-tab-bar__tabs{display:flex;width:100%;justify-content:space-around;align-items:center}@media (min-width: 769px){ion-tab-bar[slot=bottom]{padding-bottom:var(--app-safe-bottom, 0px)}}@media (display-mode: standalone){ion-tab-bar[slot=bottom]{padding-bottom:var(--app-safe-bottom, 0px)!important}}@media (min-width: 768px){:host[slot=top]{order:-1!important}:host ion-tab-bar{position:relative!important;bottom:auto!important;top:0!important}ion-tab-bar[slot=top]{--background: var(--color-header-surface);position:relative!important;display:flex!important;align-items:center;padding:12px 24px;height:64px;max-width:none;bottom:auto!important;top:0!important}ion-tab-bar[slot=bottom]{position:relative!important;bottom:auto!important}ion-tabs>div:not([slot]){order:1!important}.ds-tab-bar__logo{display:flex;position:absolute;left:24px;align-items:center;color:var(--header-content-color, white)}.ds-tab-bar__actions{display:flex;position:absolute;right:24px;align-items:center;gap:12px}.ds-tab-bar__tabs{display:flex;gap:8px;align-items:center;max-width:640px;width:100%;margin:0 auto;justify-content:center;padding-left:var(--content-padding-md);padding-right:var(--content-padding-md)}.logomark{height:28px;width:auto;flex-shrink:0}}@media (min-width: 992px){.ds-tab-bar__tabs{max-width:640px;padding-left:var(--content-padding-lg);padding-right:var(--content-padding-lg);justify-content:center}}@media (min-width: 1440px){.ds-tab-bar__tabs{max-width:640px;padding-left:var(--content-padding-xl);padding-right:var(--content-padding-xl)}}@media (min-width: 1768px){.ds-tab-bar__tabs{max-width:640px;padding-left:var(--content-padding-2xl);padding-right:var(--content-padding-2xl)}}@media (min-width: 1920px){.ds-tab-bar__tabs{max-width:640px;padding-left:var(--content-padding-3xl);padding-right:var(--content-padding-3xl)}}ion-tab-button{--color: var(--text-color-default-tertiary);--color-selected: var(--color-accent);--padding-start: 0;--padding-end: 0;--ripple-color: transparent;display:flex;flex-direction:column;align-items:center;justify-content:center;position:relative;overflow:visible;pointer-events:auto}ion-tab-button[title]:before{content:attr(title);position:absolute;opacity:0;pointer-events:none}.tab-icon-ripple{position:absolute;left:50%;top:50%;width:40px;height:40px;border-radius:50%;background:var(--color-accent);transform:translate(-50%,-50%) scale(0);opacity:0;pointer-events:none;transition:all .6s cubic-bezier(.36,1.2,.04,1.4);z-index:0}.tab-selected .tab-icon-ripple{transform:translate(-50%,-50%) scale(2);opacity:.05;animation:ripple-fade .6s cubic-bezier(.36,.5,.04,1.8) forwards}@keyframes ripple-fade{0%{opacity:0;transform:translate(-50%,-50%) scale(0)}30%{opacity:.1}to{opacity:0;transform:translate(-50%,-50%) scale(2)}}ion-tab-button::part(native){overflow:visible}ion-tab-button ion-ripple-effect{color:var(--color-accent);border-radius:1000px}ion-tab-button ion-label{font-size:11px;font-weight:500;letter-spacing:-.5px;margin-top:0}.tab-icon-wrapper{position:relative;width:24px;height:24px;display:flex;align-items:center;justify-content:center;z-index:1;margin-bottom:4px}.tab-icon-inactive,.tab-icon-active{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);transition:all .8s cubic-bezier(.36,1,.04,1)}.tab-icon-inactive{opacity:1;transform:translate(-50%,-50%) scale(1)}.tab-icon-active{opacity:0;transform:translate(-50%,calc(-50% - 12px)) scale(.5)}.tab-selected .tab-icon-inactive{opacity:0;transform:translate(-50%,-50%) scale(.5)}.tab-selected .tab-icon-active{opacity:1;transform:translate(-50%,-50%) scale(1)}@media (min-width: 768px){.ds-tab-button{flex-direction:row;height:40px;padding:0 16px!important;border-radius:40px;transition:all .2s ease;width:-moz-fit-content;width:fit-content;min-width:-moz-fit-content;min-width:fit-content;flex:0 0 auto;--color: rgba(var(--color-header-content-rgb, 255, 255, 255), .7);--color-selected: var(--color-header-content, white);color:rgba(var(--color-header-content-rgb, 255, 255, 255),.7);background:transparent;position:relative;overflow:hidden}.tab-icon-wrapper,.tab-icon-ripple{width:20px;height:20px}.ds-tab-button::part(native){border-radius:40px}.ds-tab-button:hover:not(.tab-selected){--color: var(--color-header-content, white);--color-selected: var(--color-header-content, white);color:var(--color-header-content, white);background:rgba(var(--color-header-content-rgb, 255, 255, 255),.1)}.ds-tab-button:hover:not(.tab-selected) ion-label{color:var(--color-header-content, white)}.ds-tab-button:hover:not(.tab-selected) ds-icon{--icon-color: var(--color-header-content, white);color:var(--color-header-content, white)}.ds-tab-button:hover:not(.tab-selected) ds-icon svg{fill:var(--color-header-content, white)}.ds-tab-button.tab-selected,.ds-tab-button.tab-selected:hover{background:var(--color-header-accent);--color-selected: var(--color-on-header-accent, white);--color: var(--color-on-header-accent, white);color:var(--color-on-header-accent, white)}.ds-tab-button.tab-selected:hover ion-label{color:var(--color-on-header-accent, white)}.ds-tab-button.tab-selected:hover ds-icon{--icon-color: var(--color-on-header-accent, white);color:var(--color-on-header-accent, white)}.ds-tab-button.tab-selected:hover ds-icon svg{fill:var(--color-on-header-accent, white)}.ds-tab-button.tab-selected:hover .tab-icon-active{opacity:1!important;visibility:visible!important}.ds-tab-button.tab-selected:hover .tab-icon-inactive{opacity:0!important}.ds-tab-button.tab-selected ion-label{color:var(--color-on-header-accent, white)}.ds-tab-button.tab-selected ds-icon{--icon-color: var(--color-on-header-accent, white);color:var(--color-on-header-accent, white)}.ds-tab-button.tab-selected ds-icon svg{fill:var(--color-on-header-accent, white)}.ds-tab-button .button-native{width:auto;padding:0}.ds-tab-button ion-label{font-size:var(--font-size-sm);font-weight:500;margin:0;color:inherit}.ds-tab-button .tab-icon-wrapper{margin-right:4px;margin-bottom:0}.ds-tab-button ion-ripple-effect{color:rgba(var(--header-content-color-rgb, 255, 255, 255),.3);border-radius:1000px;transform:scale(1.5)}}@media (min-width: 768px){.ds-tab-bar__actions ds-avatar{cursor:pointer;transition:transform .2s ease}.ds-tab-bar__actions ds-avatar:hover{transform:scale(1.05)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: IonTabBar, selector: "ion-tab-bar", inputs: ["color", "mode", "selectedTab", "translucent"] }, { kind: "component", type: IonTabButton, selector: "ion-tab-button", inputs: ["disabled", "download", "href", "layout", "mode", "rel", "selected", "tab", "target"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsAvatarComponent, selector: "ds-avatar", inputs: ["type", "size", "initials", "src", "alt", "iconName", "iconColor"] }, { kind: "component", type: DsLogoComponent, selector: "ds-logo", inputs: ["variant", "size", "customHeight", "customWidth"] }] });
|
|
19960
|
+
`, isInline: true, styles: [":host{--ds-tab-bar-height: 64px}@media (min-width: 768px){:host{display:block;--ds-tab-bar-height: 64px}}@media (max-width: 767px){:host{display:contents}}ion-tabs.ds-tabs-wrapper{height:100%;background:var(--color-header-surface)}ion-tab-button:before,ion-tab-button:after{content:none!important;display:none!important}ion-tab-button[title]:before,ion-tab-button[title]:after{display:none!important}ion-tab-button::part(native):before,ion-tab-button::part(native):after{display:none!important}.ds-tab-bar{--background: var(--color-background-neutral-primary);transition:transform .2s ease-in-out}ion-tab-bar[slot=bottom]{border-top:1px solid var(--border-color-default);padding-top:8px;padding-bottom:max(8px,calc(var(--app-safe-bottom, 0px) - 16px));padding-left:12px;padding-right:12px}@media (max-width: 767px){ion-tab-bar[slot=bottom]{position:fixed;bottom:0;left:0;right:0;z-index:100}}@media (max-width: 767px){:host-context(.plt-android) ion-tab-bar[slot=bottom]{padding-bottom:max(8px,var(--app-safe-bottom, 0px))!important}}@media (max-width: 767px){:host-context(ion-tabs:has(ds-mobile-page-details)) .ds-tab-bar{transform:translateY(100%);transition:transform .3s ease}}.ds-tab-bar__logo,.ds-tab-bar__actions{display:none}.ds-tab-bar__tabs{display:flex;width:100%;justify-content:space-around;align-items:center}@media (min-width: 769px){ion-tab-bar[slot=bottom]{padding-bottom:var(--app-safe-bottom, 0px)}}@media (display-mode: standalone){ion-tab-bar[slot=bottom]{padding-bottom:var(--app-safe-bottom, 0px)!important}}@media (min-width: 768px){:host[slot=top]{order:-1!important}:host ion-tab-bar{position:relative!important;bottom:auto!important;top:0!important}ion-tab-bar[slot=top]{--background: var(--color-header-surface);position:relative!important;display:flex!important;align-items:center;padding:12px 24px;height:64px;max-width:none;bottom:auto!important;top:0!important}ion-tab-bar[slot=bottom]{position:relative!important;bottom:auto!important}ion-tabs>div:not([slot]){order:1!important}.ds-tab-bar__logo{display:flex;position:absolute;left:24px;align-items:center;color:var(--header-content-color, white)}.ds-tab-bar__actions{display:flex;position:absolute;right:24px;align-items:center;gap:12px}.ds-tab-bar__tabs{display:flex;gap:8px;align-items:center;max-width:640px;width:100%;margin:0 auto;justify-content:center;padding-left:var(--content-padding-md);padding-right:var(--content-padding-md)}.logomark{height:28px;width:auto;flex-shrink:0}}@media (min-width: 992px){.ds-tab-bar__tabs{max-width:640px;padding-left:var(--content-padding-lg);padding-right:var(--content-padding-lg);justify-content:center}}@media (min-width: 1440px){.ds-tab-bar__tabs{max-width:640px;padding-left:var(--content-padding-xl);padding-right:var(--content-padding-xl)}}@media (min-width: 1768px){.ds-tab-bar__tabs{max-width:640px;padding-left:var(--content-padding-2xl);padding-right:var(--content-padding-2xl)}}@media (min-width: 1920px){.ds-tab-bar__tabs{max-width:640px;padding-left:var(--content-padding-3xl);padding-right:var(--content-padding-3xl)}}ion-tab-button{--color: var(--text-color-default-tertiary);--color-selected: var(--color-accent);--padding-start: 0;--padding-end: 0;--ripple-color: transparent;display:flex;flex-direction:column;align-items:center;justify-content:center;position:relative;overflow:visible;pointer-events:auto}ion-tab-button[title]:before{content:attr(title);position:absolute;opacity:0;pointer-events:none}.tab-icon-ripple{position:absolute;left:50%;top:50%;width:40px;height:40px;border-radius:50%;background:var(--color-accent);transform:translate(-50%,-50%) scale(0);opacity:0;pointer-events:none;transition:all .6s cubic-bezier(.36,1.2,.04,1.4);z-index:0}.tab-selected .tab-icon-ripple{transform:translate(-50%,-50%) scale(2);opacity:.05;animation:ripple-fade .6s cubic-bezier(.36,.5,.04,1.8) forwards}@keyframes ripple-fade{0%{opacity:0;transform:translate(-50%,-50%) scale(0)}30%{opacity:.1}to{opacity:0;transform:translate(-50%,-50%) scale(2)}}ion-tab-button::part(native){overflow:visible}ion-tab-button ion-ripple-effect{color:var(--color-accent);border-radius:1000px}ion-tab-button ion-label{font-size:11px;font-weight:500;letter-spacing:-.5px;margin-top:0}.tab-icon-wrapper{position:relative;width:24px;height:24px;display:flex;align-items:center;justify-content:center;z-index:1;margin-bottom:4px}.tab-icon-inactive,.tab-icon-active{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);transition:all .8s cubic-bezier(.36,1,.04,1)}.tab-icon-inactive{opacity:1;transform:translate(-50%,-50%) scale(1)}.tab-icon-active{opacity:0;transform:translate(-50%,calc(-50% - 12px)) scale(.5)}.tab-selected .tab-icon-inactive{opacity:0;transform:translate(-50%,-50%) scale(.5)}.tab-selected .tab-icon-active{opacity:1;transform:translate(-50%,-50%) scale(1)}@media (min-width: 768px){.ds-tab-button{flex-direction:row;height:40px;padding:0 16px!important;border-radius:40px;transition:all .2s ease;width:-moz-fit-content;width:fit-content;min-width:-moz-fit-content;min-width:fit-content;flex:0 0 auto;--color: rgba(var(--color-header-content-rgb, 255, 255, 255), .7);--color-selected: var(--color-header-content, white);color:rgba(var(--color-header-content-rgb, 255, 255, 255),.7);background:transparent;position:relative;overflow:hidden}.tab-icon-wrapper,.tab-icon-ripple{width:20px;height:20px}.ds-tab-button::part(native){border-radius:40px}.ds-tab-button:hover:not(.tab-selected){--color: var(--color-header-content, white);--color-selected: var(--color-header-content, white);color:var(--color-header-content, white);background:rgba(var(--color-header-content-rgb, 255, 255, 255),.1)}.ds-tab-button:hover:not(.tab-selected) ion-label{color:var(--color-header-content, white)}.ds-tab-button:hover:not(.tab-selected) ds-icon{--icon-color: var(--color-header-content, white);color:var(--color-header-content, white)}.ds-tab-button:hover:not(.tab-selected) ds-icon svg{fill:var(--color-header-content, white)}.ds-tab-button.tab-selected,.ds-tab-button.tab-selected:hover{background:var(--color-header-accent);--color-selected: var(--color-on-header-accent, white);--color: var(--color-on-header-accent, white);color:var(--color-on-header-accent, white)}.ds-tab-button.tab-selected:hover ion-label{color:var(--color-on-header-accent, white)}.ds-tab-button.tab-selected:hover ds-icon{--icon-color: var(--color-on-header-accent, white);color:var(--color-on-header-accent, white)}.ds-tab-button.tab-selected:hover ds-icon svg{fill:var(--color-on-header-accent, white)}.ds-tab-button.tab-selected:hover .tab-icon-active{opacity:1!important;visibility:visible!important}.ds-tab-button.tab-selected:hover .tab-icon-inactive{opacity:0!important}.ds-tab-button.tab-selected ion-label{color:var(--color-on-header-accent, white)}.ds-tab-button.tab-selected ds-icon{--icon-color: var(--color-on-header-accent, white);color:var(--color-on-header-accent, white)}.ds-tab-button.tab-selected ds-icon svg{fill:var(--color-on-header-accent, white)}.ds-tab-button .button-native{width:auto;padding:0}.ds-tab-button ion-label{font-size:var(--font-size-sm);font-weight:500;margin:0;color:inherit}.ds-tab-button .tab-icon-wrapper{margin-right:4px;margin-bottom:0}.ds-tab-button ion-ripple-effect{color:rgba(var(--header-content-color-rgb, 255, 255, 255),.3);border-radius:1000px;transform:scale(1.5)}}@media (min-width: 768px){.ds-tab-bar__actions ds-avatar{cursor:pointer;transition:transform .2s ease}.ds-tab-bar__actions ds-avatar:hover{transform:scale(1.05)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: IonTabBar, selector: "ion-tab-bar", inputs: ["color", "mode", "selectedTab", "translucent"] }, { kind: "component", type: IonTabButton, selector: "ion-tab-button", inputs: ["disabled", "download", "href", "layout", "mode", "rel", "selected", "tab", "target"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsAvatarComponent, selector: "ds-avatar", inputs: ["type", "size", "initials", "src", "alt", "iconName", "iconColor"] }, { kind: "component", type: DsLogoComponent, selector: "ds-logo", inputs: ["variant", "size", "customHeight", "customWidth"] }, { kind: "component", type: DsMobileNotificationButtonComponent, selector: "ds-mobile-notification-button", inputs: ["count"], outputs: ["clicked"] }] });
|
|
19888
19961
|
}
|
|
19889
19962
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileTabBarComponent, decorators: [{
|
|
19890
19963
|
type: Component,
|
|
19891
|
-
args: [{ selector: 'ds-mobile-tab-bar', standalone: true, imports: [CommonModule, IonTabBar, IonTabButton, IonLabel, DsIconComponent, DsAvatarComponent, DsLogoComponent], template: `
|
|
19964
|
+
args: [{ selector: 'ds-mobile-tab-bar', standalone: true, imports: [CommonModule, IonTabBar, IonTabButton, IonLabel, DsIconComponent, DsAvatarComponent, DsLogoComponent, DsMobileNotificationButtonComponent], template: `
|
|
19892
19965
|
<ion-tab-bar [attr.slot]="isDesktop() ? 'top' : 'bottom'" class="ds-tab-bar" [class.ds-tab-bar--desktop]="isDesktop()">
|
|
19893
19966
|
<!-- Logo (desktop only, full logo in header) -->
|
|
19894
19967
|
<div class="ds-tab-bar__logo">
|
|
@@ -19931,8 +20004,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
19931
20004
|
}
|
|
19932
20005
|
</div>
|
|
19933
20006
|
|
|
19934
|
-
<!-- Avatar (desktop only, positioned via CSS) -->
|
|
20007
|
+
<!-- Notification + Avatar (desktop only, positioned via CSS) -->
|
|
19935
20008
|
<div class="ds-tab-bar__actions">
|
|
20009
|
+
<ds-mobile-notification-button
|
|
20010
|
+
[count]="notificationCount"
|
|
20011
|
+
(clicked)="notificationClick.emit()"
|
|
20012
|
+
/>
|
|
19936
20013
|
<ds-avatar [size]="'md'" [type]="avatarType" [initials]="avatarInitials" [src]="avatarSrc" [iconName]="avatarIconName" (click)="handleAvatarClick()" />
|
|
19937
20014
|
</div>
|
|
19938
20015
|
</ion-tab-bar>
|
|
@@ -19949,6 +20026,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
19949
20026
|
type: Input
|
|
19950
20027
|
}], profileMenuItems: [{
|
|
19951
20028
|
type: Input
|
|
20029
|
+
}], notificationCount: [{
|
|
20030
|
+
type: Input
|
|
19952
20031
|
}], moreMenuItems: [{
|
|
19953
20032
|
type: Input
|
|
19954
20033
|
}], moreMenuLabel: [{
|
|
@@ -19957,6 +20036,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
19957
20036
|
type: Input
|
|
19958
20037
|
}], moreMenuIconActive: [{
|
|
19959
20038
|
type: Input
|
|
20039
|
+
}], notificationClick: [{
|
|
20040
|
+
type: Output
|
|
19960
20041
|
}], avatarClick: [{
|
|
19961
20042
|
type: Output
|
|
19962
20043
|
}], profileActionSelected: [{
|
|
@@ -20025,7 +20106,7 @@ class DsMobileTabsComponent {
|
|
|
20025
20106
|
(avatarClick)="handleAvatarClick()"
|
|
20026
20107
|
/>
|
|
20027
20108
|
</ion-tabs>
|
|
20028
|
-
`, isInline: true, styles: [":host{display:block;height:100vh;height:100dvh}ion-tabs{height:100%;background:var(--color-header-surface)}@media (max-width: 767px){ion-tabs:has(ds-mobile-page-details) ds-mobile-tab-bar{--tab-bar-transform: translateY(100%)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: IonTabs, selector: "ion-tabs" }, { kind: "component", type: IonTab, selector: "ion-tab", inputs: ["component", "tab"] }, { kind: "component", type: DsMobileTabBarComponent, selector: "ds-mobile-tab-bar", inputs: ["tabs", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "profileMenuItems", "moreMenuItems", "moreMenuLabel", "moreMenuIcon", "moreMenuIconActive"], outputs: ["avatarClick", "profileActionSelected", "moreMenuItemSelected"] }] });
|
|
20109
|
+
`, isInline: true, styles: [":host{display:block;height:100vh;height:100dvh}ion-tabs{height:100%;background:var(--color-header-surface)}@media (max-width: 767px){ion-tabs:has(ds-mobile-page-details) ds-mobile-tab-bar{--tab-bar-transform: translateY(100%)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: IonTabs, selector: "ion-tabs" }, { kind: "component", type: IonTab, selector: "ion-tab", inputs: ["component", "tab"] }, { kind: "component", type: DsMobileTabBarComponent, selector: "ds-mobile-tab-bar", inputs: ["tabs", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "profileMenuItems", "notificationCount", "moreMenuItems", "moreMenuLabel", "moreMenuIcon", "moreMenuIconActive"], outputs: ["notificationClick", "avatarClick", "profileActionSelected", "moreMenuItemSelected"] }] });
|
|
20029
20110
|
}
|
|
20030
20111
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileTabsComponent, decorators: [{
|
|
20031
20112
|
type: Component,
|
|
@@ -21806,7 +21887,7 @@ class DsMobileEmptyStateComponent {
|
|
|
21806
21887
|
}
|
|
21807
21888
|
</div>
|
|
21808
21889
|
</div>
|
|
21809
|
-
`, isInline: true, styles: [":host{display:block}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;text-align:center;gap:24px}.empty-state-image{width:
|
|
21890
|
+
`, isInline: true, styles: [":host{display:block}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;text-align:center;gap:24px}.empty-state-image{width:120px;height:120px;margin:0 auto}.empty-state-text{display:flex;flex-direction:column;gap:8px}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;line-height:1.3;color:var(--color-text-primary, #1a1a1a);margin:0}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:400;line-height:1.4;color:var(--color-text-secondary, #737373);margin:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
21810
21891
|
}
|
|
21811
21892
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileEmptyStateComponent, decorators: [{
|
|
21812
21893
|
type: Component,
|
|
@@ -21825,7 +21906,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
21825
21906
|
}
|
|
21826
21907
|
</div>
|
|
21827
21908
|
</div>
|
|
21828
|
-
`, styles: [":host{display:block}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;text-align:center;gap:24px}.empty-state-image{width:
|
|
21909
|
+
`, styles: [":host{display:block}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;text-align:center;gap:24px}.empty-state-image{width:120px;height:120px;margin:0 auto}.empty-state-text{display:flex;flex-direction:column;gap:8px}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;line-height:1.3;color:var(--color-text-primary, #1a1a1a);margin:0}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:400;line-height:1.4;color:var(--color-text-secondary, #737373);margin:0}\n"] }]
|
|
21829
21910
|
}], propDecorators: { imageSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "imageSrc", required: false }] }], imageAlt: [{ type: i0.Input, args: [{ isSignal: true, alias: "imageAlt", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }] } });
|
|
21830
21911
|
|
|
21831
21912
|
/**
|
|
@@ -22702,16 +22783,16 @@ class DsMobileCardInlineBannerComponent {
|
|
|
22702
22783
|
|
|
22703
22784
|
<div content-trailing class="item-trailing">
|
|
22704
22785
|
@if (unreadCount() && unreadCount()! > 0) {
|
|
22705
|
-
<
|
|
22786
|
+
<ds-mobile-count-badge [count]="unreadCount()!" variant="accent" />
|
|
22706
22787
|
}
|
|
22707
22788
|
<ds-icon name="remixArrowRightSLine" size="20px" />
|
|
22708
22789
|
</div>
|
|
22709
22790
|
</ds-mobile-card-inline>
|
|
22710
|
-
`, isInline: true, styles: ["
|
|
22791
|
+
`, isInline: true, styles: ["ds-mobile-count-badge{margin-right:8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsAvatarComponent, selector: "ds-avatar", inputs: ["type", "size", "initials", "src", "alt", "iconName", "iconColor"] }, { kind: "component", type: DsMobileCardInlineComponent, selector: "ds-mobile-card-inline", inputs: ["variant", "disabled"], outputs: ["cardClick"] }, { kind: "component", type: DsMobileCountBadgeComponent, selector: "ds-mobile-count-badge", inputs: ["count", "variant"] }] });
|
|
22711
22792
|
}
|
|
22712
22793
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileCardInlineBannerComponent, decorators: [{
|
|
22713
22794
|
type: Component,
|
|
22714
|
-
args: [{ selector: 'ds-mobile-card-inline-banner', standalone: true, imports: [CommonModule, DsIconComponent, DsAvatarComponent, DsMobileCardInlineComponent], template: `
|
|
22795
|
+
args: [{ selector: 'ds-mobile-card-inline-banner', standalone: true, imports: [CommonModule, DsIconComponent, DsAvatarComponent, DsMobileCardInlineComponent, DsMobileCountBadgeComponent], template: `
|
|
22715
22796
|
<ds-mobile-card-inline
|
|
22716
22797
|
[variant]="layout()"
|
|
22717
22798
|
(cardClick)="handleBannerClick()">
|
|
@@ -22736,12 +22817,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
22736
22817
|
|
|
22737
22818
|
<div content-trailing class="item-trailing">
|
|
22738
22819
|
@if (unreadCount() && unreadCount()! > 0) {
|
|
22739
|
-
<
|
|
22820
|
+
<ds-mobile-count-badge [count]="unreadCount()!" variant="accent" />
|
|
22740
22821
|
}
|
|
22741
22822
|
<ds-icon name="remixArrowRightSLine" size="20px" />
|
|
22742
22823
|
</div>
|
|
22743
22824
|
</ds-mobile-card-inline>
|
|
22744
|
-
`, styles: ["
|
|
22825
|
+
`, styles: ["ds-mobile-count-badge{margin-right:8px}\n"] }]
|
|
22745
22826
|
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], timestamp: [{ type: i0.Input, args: [{ isSignal: true, alias: "timestamp", required: false }] }], unreadCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "unreadCount", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: false }] }], bannerClick: [{ type: i0.Output, args: ["bannerClick"] }] } });
|
|
22746
22827
|
|
|
22747
22828
|
/**
|
|
@@ -26092,7 +26173,7 @@ class DsMobilePriceSheetComponent {
|
|
|
26092
26173
|
inputmode="numeric"
|
|
26093
26174
|
pattern="[0-9]*"
|
|
26094
26175
|
maxlength="5"
|
|
26095
|
-
[attr.size]="Math.min(customPrice()
|
|
26176
|
+
[attr.size]="Math.min(customPrice().length || 2, 5)"
|
|
26096
26177
|
[(ngModel)]="customPrice"
|
|
26097
26178
|
placeholder="75"
|
|
26098
26179
|
class="price-input-native"
|
|
@@ -26147,7 +26228,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
26147
26228
|
inputmode="numeric"
|
|
26148
26229
|
pattern="[0-9]*"
|
|
26149
26230
|
maxlength="5"
|
|
26150
|
-
[attr.size]="Math.min(customPrice()
|
|
26231
|
+
[attr.size]="Math.min(customPrice().length || 2, 5)"
|
|
26151
26232
|
[(ngModel)]="customPrice"
|
|
26152
26233
|
placeholder="75"
|
|
26153
26234
|
class="price-input-native"
|
|
@@ -28624,7 +28705,713 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
28624
28705
|
`, styles: [":host{display:block;width:100%}.property-banner{display:flex;align-items:center;gap:8px;height:44px;padding:4px 10px 4px 6px;background:rgba(var(--header-content-color-rgb, 255, 255, 255),.1);border:none;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border-radius:12px;cursor:pointer;transition:background .2s ease;-webkit-tap-highlight-color:transparent}.property-banner:hover{background:rgba(var(--header-content-color-rgb, 255, 255, 255),.12)}.property-banner:active{background:rgba(var(--header-content-color-rgb, 255, 255, 255),.15)}.property-photo{width:32px;height:32px;border-radius:8px;object-fit:cover;flex-shrink:0;background:rgba(var(--header-content-color-rgb, 255, 255, 255),.1)}.property-text{display:flex;flex-direction:column;flex:1;min-width:0}.property-address{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;color:var(--header-content-color, white);line-height:1.4;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.property-meta{font-family:Brockmann,sans-serif;font-size:var(--font-size-xs);font-weight:400;line-height:1.2;letter-spacing:-.26px;color:rgba(var(--header-content-color-rgb, 255, 255, 255),.65);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.property-chevron{flex-shrink:0;width:16px;height:16px;color:rgba(var(--header-content-color-rgb, 255, 255, 255),.5)}\n"] }]
|
|
28625
28706
|
}], propDecorators: { address: [{ type: i0.Input, args: [{ isSignal: true, alias: "address", required: true }] }], photoUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "photoUrl", required: true }] }], tenantCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "tenantCount", required: false }] }] } });
|
|
28626
28707
|
|
|
28627
|
-
|
|
28708
|
+
class DsMobileNotificationPromptComponent {
|
|
28709
|
+
whitelabel = inject(WhitelabelService);
|
|
28710
|
+
dismissing = signal(false, ...(ngDevMode ? [{ debugName: "dismissing" }] : []));
|
|
28711
|
+
heading = input('Vær den første til at vide det', ...(ngDevMode ? [{ debugName: "heading" }] : []));
|
|
28712
|
+
subtitle = input('Hold dig opdateret med henvendelser, bookinger, nyheder og alt derimellem.', ...(ngDevMode ? [{ debugName: "subtitle" }] : []));
|
|
28713
|
+
allowLabel = input('Slå notifikationer til', ...(ngDevMode ? [{ debugName: "allowLabel" }] : []));
|
|
28714
|
+
dismissLabel = input('Ikke lige nu', ...(ngDevMode ? [{ debugName: "dismissLabel" }] : []));
|
|
28715
|
+
allow = output();
|
|
28716
|
+
dismiss = output();
|
|
28717
|
+
static EXIT_DURATION = 800;
|
|
28718
|
+
handleAllow() {
|
|
28719
|
+
if (this.dismissing())
|
|
28720
|
+
return;
|
|
28721
|
+
this.dismissing.set(true);
|
|
28722
|
+
setTimeout(() => this.allow.emit(), DsMobileNotificationPromptComponent.EXIT_DURATION);
|
|
28723
|
+
}
|
|
28724
|
+
handleDismiss() {
|
|
28725
|
+
if (this.dismissing())
|
|
28726
|
+
return;
|
|
28727
|
+
this.dismissing.set(true);
|
|
28728
|
+
setTimeout(() => this.dismiss.emit(), DsMobileNotificationPromptComponent.EXIT_DURATION);
|
|
28729
|
+
}
|
|
28730
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileNotificationPromptComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
28731
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.16", type: DsMobileNotificationPromptComponent, isStandalone: true, selector: "ds-mobile-notification-prompt", inputs: { heading: { classPropertyName: "heading", publicName: "heading", isSignal: true, isRequired: false, transformFunction: null }, subtitle: { classPropertyName: "subtitle", publicName: "subtitle", isSignal: true, isRequired: false, transformFunction: null }, allowLabel: { classPropertyName: "allowLabel", publicName: "allowLabel", isSignal: true, isRequired: false, transformFunction: null }, dismissLabel: { classPropertyName: "dismissLabel", publicName: "dismissLabel", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { allow: "allow", dismiss: "dismiss" }, ngImport: i0, template: `
|
|
28732
|
+
<div class="notification-prompt" [class.is-dismissing]="dismissing()">
|
|
28733
|
+
<div
|
|
28734
|
+
class="notification-prompt__backdrop"
|
|
28735
|
+
[style.background]="whitelabel.headerSurface()">
|
|
28736
|
+
</div>
|
|
28737
|
+
|
|
28738
|
+
<!-- Illustration: floating icon tiles -->
|
|
28739
|
+
<div class="notification-prompt__illustration">
|
|
28740
|
+
<div class="icon-tiles">
|
|
28741
|
+
|
|
28742
|
+
<!-- Tile 1: service/heart-handshake (top-center, small 72px) -->
|
|
28743
|
+
<div class="tile-entry tile-entry--1">
|
|
28744
|
+
<div class="icon-tile icon-tile--1">
|
|
28745
|
+
<div class="icon-tile__icon">
|
|
28746
|
+
<svg viewBox="0 0 45 45" fill="none">
|
|
28747
|
+
<path d="M5.928 8.379c4.545-4.545 11.787-4.75 16.575-.615 4.785-4.135 12.026-3.93 16.571.615 4.537 4.537 4.749 11.76.637 16.549L25.153 39.536a3.75 3.75 0 0 1-5.098.19l-.206-.19L5.291 24.928c-4.112-4.789-3.9-12.012.637-16.549zm2.652 2.651c-3.2 3.201-3.292 8.334-.274 11.645l.274.288L22.5 36.884l9.943-9.945-6.628-6.628-1.988 1.989a4.688 4.688 0 0 1-6.628-6.628l3.94-3.943c-3.212-2.57-7.866-2.453-10.945.245l-.287.275zm15.91 5.303a1.875 1.875 0 0 1 2.651 0l7.954 7.954 1.327-1.325c3.295-3.295 3.295-8.637 0-11.932-3.2-3.201-8.333-3.292-11.645-.274l-.287.274-5.967 5.967a1.875 1.875 0 0 0-.146 2.497l.146.164a1.875 1.875 0 0 0 2.497.145l.164-.145 3.314-3.315z" fill="currentColor"/>
|
|
28748
|
+
</svg>
|
|
28749
|
+
</div>
|
|
28750
|
+
</div>
|
|
28751
|
+
</div>
|
|
28752
|
+
|
|
28753
|
+
<!-- Tile 2: calendar (right-bottom, medium 88px) -->
|
|
28754
|
+
<div class="tile-entry tile-entry--2">
|
|
28755
|
+
<div class="icon-tile icon-tile--medium icon-tile--2">
|
|
28756
|
+
<div class="icon-tile__icon">
|
|
28757
|
+
<svg viewBox="0 0 24 24" fill="none">
|
|
28758
|
+
<path d="M9 1v2h6V1h2v2h4a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h4V1h2zm11 9H4v9h16v-9zm-4.964 1.136l1.414 1.414-4.95 4.95-3.536-3.536L9.38 12.55l2.121 2.122 3.536-3.536zM7 5H4v3h16V5h-3v1h-2V5H9v1H7V5z" fill="currentColor"/>
|
|
28759
|
+
</svg>
|
|
28760
|
+
</div>
|
|
28761
|
+
</div>
|
|
28762
|
+
</div>
|
|
28763
|
+
|
|
28764
|
+
<!-- Tile 3: documents (bottom-left, small 72px) -->
|
|
28765
|
+
<div class="tile-entry tile-entry--3">
|
|
28766
|
+
<div class="icon-tile icon-tile--3">
|
|
28767
|
+
<div class="icon-tile__icon">
|
|
28768
|
+
<svg viewBox="0 0 24 24" fill="none">
|
|
28769
|
+
<path d="M20 22H4a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1h16a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1zM19 4H5v16h14V4zM7 6h4v4H7V6zm0 6h10v2H7v-2zm0 4h10v2H7v-2zm6-9h4v2h-4V7z" fill="currentColor"/>
|
|
28770
|
+
</svg>
|
|
28771
|
+
</div>
|
|
28772
|
+
</div>
|
|
28773
|
+
</div>
|
|
28774
|
+
|
|
28775
|
+
<!-- Tile 4: messages (right-upper, medium 88px) -->
|
|
28776
|
+
<div class="tile-entry tile-entry--4">
|
|
28777
|
+
<div class="icon-tile icon-tile--medium icon-tile--4">
|
|
28778
|
+
<div class="icon-tile__icon">
|
|
28779
|
+
<svg viewBox="0 0 24 24" fill="none">
|
|
28780
|
+
<path d="M7.291 20.824L2 22l1.176-5.291A9.956 9.956 0 0 1 2 12C2 6.477 6.477 2 12 2s10 4.477 10 10-4.477 10-10 10a9.956 9.956 0 0 1-4.709-1.176zM7.581 18.71l.29.158A7.956 7.956 0 0 0 12 20c4.418 0 8-3.582 8-8s-3.582-8-8-8-8 3.582-8 8c0 1.458.39 2.823 1.131 4.13l.159.288-.69 3.1 3.1-.69z" fill="currentColor"/>
|
|
28781
|
+
</svg>
|
|
28782
|
+
</div>
|
|
28783
|
+
</div>
|
|
28784
|
+
</div>
|
|
28785
|
+
|
|
28786
|
+
<!-- Tile 5: home (left-middle, medium 88px) -->
|
|
28787
|
+
<div class="tile-entry tile-entry--5">
|
|
28788
|
+
<div class="icon-tile icon-tile--medium icon-tile--5">
|
|
28789
|
+
<div class="icon-tile__icon">
|
|
28790
|
+
<svg viewBox="0 0 24 24" fill="none">
|
|
28791
|
+
<path d="M19 21H5a1 1 0 0 1-1-1v-9H1l10.327-9.388a1 1 0 0 1 1.346 0L23 11h-3v9a1 1 0 0 1-1 1zM6 19h12v-9.157l-6-5.454-6 5.454V19zm2-4h8v2H8v-2z" fill="currentColor"/>
|
|
28792
|
+
</svg>
|
|
28793
|
+
</div>
|
|
28794
|
+
</div>
|
|
28795
|
+
</div>
|
|
28796
|
+
|
|
28797
|
+
<!-- Hero: bell icon (center, 120px) -->
|
|
28798
|
+
<div class="tile-entry tile-entry--hero">
|
|
28799
|
+
<div class="icon-tile icon-tile--hero">
|
|
28800
|
+
<div class="icon-tile__icon">
|
|
28801
|
+
<svg viewBox="0 0 24 24" fill="none">
|
|
28802
|
+
<path d="M20 17h2v2H2v-2h2v-7a8 8 0 1 1 16 0v7zm-2 0v-7a6 6 0 1 0-12 0v7h12zm-9 4h6v2H9v-2z" fill="currentColor"/>
|
|
28803
|
+
</svg>
|
|
28804
|
+
</div>
|
|
28805
|
+
<span class="icon-tile__badge">18</span>
|
|
28806
|
+
</div>
|
|
28807
|
+
</div>
|
|
28808
|
+
|
|
28809
|
+
</div>
|
|
28810
|
+
</div>
|
|
28811
|
+
|
|
28812
|
+
<!-- Heading + subtitle -->
|
|
28813
|
+
<div class="notification-prompt__texts">
|
|
28814
|
+
<h1 class="notification-prompt__heading">{{ heading() }}</h1>
|
|
28815
|
+
<p class="notification-prompt__subtitle">{{ subtitle() }}</p>
|
|
28816
|
+
</div>
|
|
28817
|
+
|
|
28818
|
+
<!-- CTA buttons -->
|
|
28819
|
+
<div class="notification-prompt__actions">
|
|
28820
|
+
<ds-button
|
|
28821
|
+
variant="primary"
|
|
28822
|
+
size="md"
|
|
28823
|
+
(clicked)="handleAllow()">
|
|
28824
|
+
{{ allowLabel() }}
|
|
28825
|
+
</ds-button>
|
|
28826
|
+
<ds-button
|
|
28827
|
+
class="dismiss-btn"
|
|
28828
|
+
variant="ghost"
|
|
28829
|
+
size="md"
|
|
28830
|
+
(clicked)="handleDismiss()">
|
|
28831
|
+
{{ dismissLabel() }}
|
|
28832
|
+
</ds-button>
|
|
28833
|
+
</div>
|
|
28834
|
+
</div>
|
|
28835
|
+
`, isInline: true, styles: ["@keyframes fadeSlideUp{0%{opacity:0;transform:translateY(32px)}to{opacity:1;transform:translateY(0)}}@keyframes tileEntry{0%{opacity:0;transform:translateY(40px) scale(.85)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes float1{0%{transform:var(--tile-transform) translate(0) rotate(0)}11%{transform:var(--tile-transform) translate(1.4px,-3px) rotate(.9deg)}23%{transform:var(--tile-transform) translate(2.2px,-6.5px) rotate(1.8deg)}37%{transform:var(--tile-transform) translate(.6px,-8.5px) rotate(.4deg)}50%{transform:var(--tile-transform) translate(-1.2px,-7px) rotate(-.8deg)}63%{transform:var(--tile-transform) translate(-1.8px,-4px) rotate(-1.6deg)}76%{transform:var(--tile-transform) translate(-.4px,-1.5px) rotate(-.5deg)}88%{transform:var(--tile-transform) translate(.8px,-.5px) rotate(.3deg)}to{transform:var(--tile-transform) translate(0) rotate(0)}}@keyframes float2{0%{transform:var(--tile-transform) translate(0) rotate(0)}12%{transform:var(--tile-transform) translate(-1px,-2.5px) rotate(-.7deg)}25%{transform:var(--tile-transform) translate(-2px,-5.5px) rotate(-1.5deg)}38%{transform:var(--tile-transform) translate(-.8px,-7px) rotate(-.3deg)}50%{transform:var(--tile-transform) translate(1px,-6px) rotate(1deg)}62%{transform:var(--tile-transform) translate(1.6px,-3.5px) rotate(1.6deg)}75%{transform:var(--tile-transform) translate(.5px,-1.5px) rotate(.6deg)}87%{transform:var(--tile-transform) translate(-.5px,-.3px) rotate(-.2deg)}to{transform:var(--tile-transform) translate(0) rotate(0)}}@keyframes float3{0%{transform:var(--tile-transform) translate(0) rotate(0)}10%{transform:var(--tile-transform) translate(.8px,-3px) rotate(1.2deg)}22%{transform:var(--tile-transform) translate(1.5px,-7px) rotate(2deg)}35%{transform:var(--tile-transform) translate(.3px,-10px) rotate(.8deg)}48%{transform:var(--tile-transform) translate(-1.5px,-9.5px) rotate(-.6deg)}60%{transform:var(--tile-transform) translate(-2px,-6px) rotate(-1.5deg)}72%{transform:var(--tile-transform) translate(-1px,-3px) rotate(-.8deg)}85%{transform:var(--tile-transform) translate(.3px,-1px) rotate(.3deg)}to{transform:var(--tile-transform) translate(0) rotate(0)}}@keyframes float4{0%{transform:var(--tile-transform) translate(0) rotate(0)}13%{transform:var(--tile-transform) translate(-.8px,-2px) rotate(-.8deg)}26%{transform:var(--tile-transform) translate(-1.5px,-5px) rotate(-1.6deg)}40%{transform:var(--tile-transform) translate(.2px,-7.5px) rotate(-.2deg)}52%{transform:var(--tile-transform) translate(1.8px,-6.5px) rotate(1.2deg)}65%{transform:var(--tile-transform) translate(1.2px,-4px) rotate(.8deg)}78%{transform:var(--tile-transform) translate(-.3px,-1.8px) rotate(-.4deg)}90%{transform:var(--tile-transform) translate(-.6px,-.4px) rotate(-.1deg)}to{transform:var(--tile-transform) translate(0) rotate(0)}}@keyframes float5{0%{transform:var(--tile-transform) translate(0) rotate(0)}9%{transform:var(--tile-transform) translate(1.2px,-2px) rotate(.6deg)}20%{transform:var(--tile-transform) translate(2px,-5px) rotate(1.5deg)}33%{transform:var(--tile-transform) translate(.8px,-8.5px) rotate(.5deg)}45%{transform:var(--tile-transform) translate(-1px,-9.5px) rotate(-1deg)}58%{transform:var(--tile-transform) translate(-1.8px,-7px) rotate(-1.8deg)}70%{transform:var(--tile-transform) translate(-.8px,-4px) rotate(-.8deg)}82%{transform:var(--tile-transform) translate(.4px,-1.5px) rotate(.2deg)}92%{transform:var(--tile-transform) translate(.6px,-.3px) rotate(.1deg)}to{transform:var(--tile-transform) translate(0) rotate(0)}}@keyframes floatHero{0%{transform:translate(-50%) translate(0) rotate(0) scale(1)}10%{transform:translate(-50%) translate(.8px,-4px) rotate(.7deg) scale(1.006)}22%{transform:translate(-50%) translate(1.5px,-9px) rotate(1.4deg) scale(1.014)}35%{transform:translate(-50%) translate(.2px,-13px) rotate(.3deg) scale(1.02)}48%{transform:translate(-50%) translate(-1.5px,-12px) rotate(-1deg) scale(1.016)}60%{transform:translate(-50%) translate(-2px,-8px) rotate(-1.6deg) scale(1.01)}72%{transform:translate(-50%) translate(-.6px,-4px) rotate(-.5deg) scale(1.005)}85%{transform:translate(-50%) translate(.5px,-1.5px) rotate(.3deg) scale(1.002)}94%{transform:translate(-50%) translate(.3px,-.3px) rotate(.1deg) scale(1.001)}to{transform:translate(-50%) translate(0) rotate(0) scale(1)}}:host{display:flex;align-items:center;justify-content:center;position:fixed;inset:0;z-index:9999}.notification-prompt{width:100%;max-width:390px;height:100%;display:flex;flex-direction:column;gap:48px;overflow:clip;position:relative}.notification-prompt__backdrop{position:fixed;inset:0;z-index:-1}.notification-prompt__illustration{position:relative;flex:1 0 0;min-height:0;display:flex;align-items:center;justify-content:center;padding:0 24px}.icon-tiles{position:relative;width:100%;max-width:342px;height:100%}.tile-entry{position:absolute;opacity:0;animation:tileEntry .7s cubic-bezier(.22,1,.36,1) forwards;will-change:transform,opacity}.tile-entry--hero{inset:0;animation-delay:.2s;animation-duration:.8s}.tile-entry--1{inset:0;animation-delay:.35s}.tile-entry--4{inset:0;animation-delay:.3s}.tile-entry--5{inset:0;animation-delay:.4s}.tile-entry--3{inset:0;animation-delay:.45s}.tile-entry--2{inset:0;animation-delay:.5s}.icon-tile{position:absolute;display:flex;align-items:center;justify-content:center;border-radius:20%;background:linear-gradient(180deg,#0000 95%,#00000026),linear-gradient(180deg,#fff6,#fff0 4.5%),linear-gradient(180deg,#ffffff26,#fff0),linear-gradient(180deg,#0000,#0000001a),var(--color-accent, #6B5FF5);will-change:transform}.icon-tile__icon{width:62.5%;height:62.5%;display:flex;align-items:center;justify-content:center}.icon-tile__icon svg{width:100%;height:100%;color:#fff;display:block}.icon-tile--1{--tile-transform: translate(-50%, 0) rotate(7.74deg);width:72px;height:72px;top:22%;left:50%;filter:blur(2px);animation:float1 6.8s linear infinite}.icon-tile--2{--tile-transform: rotate(9.27deg);width:88px;height:88px;bottom:6%;right:0;filter:blur(1px);animation:float2 7.4s linear infinite}.icon-tile--3{--tile-transform: rotate(-6.18deg);width:72px;height:72px;bottom:0;left:0;filter:blur(2px);animation:float3 8.6s linear infinite}.icon-tile--4{--tile-transform: rotate(20.57deg);width:88px;height:88px;top:36%;right:0;filter:blur(1px);animation:float4 7.1s linear infinite}.icon-tile--5{--tile-transform: rotate(-8.24deg);width:88px;height:88px;top:44%;left:0;filter:blur(1px);animation:float5 9.2s linear infinite}.icon-tile--hero{width:120px;height:120px;left:50%;bottom:14%;filter:none;border-radius:30px;z-index:2;animation:floatHero 6.2s linear infinite}.icon-tile__badge{position:absolute;top:12.5%;right:12%;min-width:26px;height:26px;padding:0 7px;border-radius:8px;background:var(--content-feedback-bold-red, #b91c1c);display:flex;align-items:center;justify-content:center;font-family:Brockmann,system-ui,-apple-system,sans-serif;font-weight:600;font-size:18px;line-height:1;letter-spacing:-.04em;color:#fff;white-space:nowrap;box-sizing:border-box}.notification-prompt__texts{position:relative;z-index:1;text-align:center;padding:0 16px;flex-shrink:0;opacity:0;animation:fadeSlideUp .6s .6s cubic-bezier(.22,1,.36,1) forwards}.notification-prompt__heading{font-family:Brockmann,system-ui,-apple-system,sans-serif;font-weight:600;font-size:32px;line-height:1.15;letter-spacing:-.02em;color:#fff;margin:0 0 4px}.notification-prompt__subtitle{font-family:Brockmann,system-ui,-apple-system,sans-serif;font-weight:400;font-size:18px;line-height:1.4;letter-spacing:-.02em;color:#eef0ff;margin:0}.notification-prompt__actions{position:relative;z-index:1;display:flex;flex-direction:column;gap:8px;padding:0 24px 24px;padding-bottom:max(24px,env(safe-area-inset-bottom,24px));flex-shrink:0;opacity:0;animation:fadeSlideUp .6s .75s cubic-bezier(.22,1,.36,1) forwards}.notification-prompt__actions ds-button{display:block;width:100%}.notification-prompt__actions ds-button::ng-deep button{width:100%;border-radius:8px}.notification-prompt__actions ds-button.dismiss-btn::ng-deep button{color:#fff;background:transparent}@keyframes exitUp{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-48px)}}@keyframes exitFade{0%{opacity:1}to{opacity:0}}.is-dismissing .notification-prompt__illustration{animation:exitUp .5s cubic-bezier(.55,0,1,.45) forwards}.is-dismissing .notification-prompt__texts{animation:exitUp .45s .15s cubic-bezier(.55,0,1,.45) forwards}.is-dismissing .notification-prompt__actions{animation:exitUp .45s .3s cubic-bezier(.55,0,1,.45) forwards}.is-dismissing .notification-prompt__backdrop{animation:exitFade .35s .45s cubic-bezier(.55,0,1,.45) forwards}@media (prefers-reduced-motion: reduce){.tile-entry,.icon-tile,.icon-tile--hero,.notification-prompt__texts,.notification-prompt__actions{animation:none!important;opacity:1!important}}\n"], dependencies: [{ kind: "component", type: DsButtonComponent, selector: "ds-button", inputs: ["variant", "size", "disabled", "loading", "pressed", "expanded", "leadingIcon", "trailingIcon", "ariaLabel", "iconOnly"], outputs: ["clicked", "focused", "blurred"] }] });
|
|
28836
|
+
}
|
|
28837
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileNotificationPromptComponent, decorators: [{
|
|
28838
|
+
type: Component,
|
|
28839
|
+
args: [{ selector: 'ds-mobile-notification-prompt', standalone: true, imports: [DsButtonComponent], template: `
|
|
28840
|
+
<div class="notification-prompt" [class.is-dismissing]="dismissing()">
|
|
28841
|
+
<div
|
|
28842
|
+
class="notification-prompt__backdrop"
|
|
28843
|
+
[style.background]="whitelabel.headerSurface()">
|
|
28844
|
+
</div>
|
|
28845
|
+
|
|
28846
|
+
<!-- Illustration: floating icon tiles -->
|
|
28847
|
+
<div class="notification-prompt__illustration">
|
|
28848
|
+
<div class="icon-tiles">
|
|
28849
|
+
|
|
28850
|
+
<!-- Tile 1: service/heart-handshake (top-center, small 72px) -->
|
|
28851
|
+
<div class="tile-entry tile-entry--1">
|
|
28852
|
+
<div class="icon-tile icon-tile--1">
|
|
28853
|
+
<div class="icon-tile__icon">
|
|
28854
|
+
<svg viewBox="0 0 45 45" fill="none">
|
|
28855
|
+
<path d="M5.928 8.379c4.545-4.545 11.787-4.75 16.575-.615 4.785-4.135 12.026-3.93 16.571.615 4.537 4.537 4.749 11.76.637 16.549L25.153 39.536a3.75 3.75 0 0 1-5.098.19l-.206-.19L5.291 24.928c-4.112-4.789-3.9-12.012.637-16.549zm2.652 2.651c-3.2 3.201-3.292 8.334-.274 11.645l.274.288L22.5 36.884l9.943-9.945-6.628-6.628-1.988 1.989a4.688 4.688 0 0 1-6.628-6.628l3.94-3.943c-3.212-2.57-7.866-2.453-10.945.245l-.287.275zm15.91 5.303a1.875 1.875 0 0 1 2.651 0l7.954 7.954 1.327-1.325c3.295-3.295 3.295-8.637 0-11.932-3.2-3.201-8.333-3.292-11.645-.274l-.287.274-5.967 5.967a1.875 1.875 0 0 0-.146 2.497l.146.164a1.875 1.875 0 0 0 2.497.145l.164-.145 3.314-3.315z" fill="currentColor"/>
|
|
28856
|
+
</svg>
|
|
28857
|
+
</div>
|
|
28858
|
+
</div>
|
|
28859
|
+
</div>
|
|
28860
|
+
|
|
28861
|
+
<!-- Tile 2: calendar (right-bottom, medium 88px) -->
|
|
28862
|
+
<div class="tile-entry tile-entry--2">
|
|
28863
|
+
<div class="icon-tile icon-tile--medium icon-tile--2">
|
|
28864
|
+
<div class="icon-tile__icon">
|
|
28865
|
+
<svg viewBox="0 0 24 24" fill="none">
|
|
28866
|
+
<path d="M9 1v2h6V1h2v2h4a1 1 0 0 1 1 1v16a1 1 0 0 1-1 1H3a1 1 0 0 1-1-1V4a1 1 0 0 1 1-1h4V1h2zm11 9H4v9h16v-9zm-4.964 1.136l1.414 1.414-4.95 4.95-3.536-3.536L9.38 12.55l2.121 2.122 3.536-3.536zM7 5H4v3h16V5h-3v1h-2V5H9v1H7V5z" fill="currentColor"/>
|
|
28867
|
+
</svg>
|
|
28868
|
+
</div>
|
|
28869
|
+
</div>
|
|
28870
|
+
</div>
|
|
28871
|
+
|
|
28872
|
+
<!-- Tile 3: documents (bottom-left, small 72px) -->
|
|
28873
|
+
<div class="tile-entry tile-entry--3">
|
|
28874
|
+
<div class="icon-tile icon-tile--3">
|
|
28875
|
+
<div class="icon-tile__icon">
|
|
28876
|
+
<svg viewBox="0 0 24 24" fill="none">
|
|
28877
|
+
<path d="M20 22H4a1 1 0 0 1-1-1V3a1 1 0 0 1 1-1h16a1 1 0 0 1 1 1v18a1 1 0 0 1-1 1zM19 4H5v16h14V4zM7 6h4v4H7V6zm0 6h10v2H7v-2zm0 4h10v2H7v-2zm6-9h4v2h-4V7z" fill="currentColor"/>
|
|
28878
|
+
</svg>
|
|
28879
|
+
</div>
|
|
28880
|
+
</div>
|
|
28881
|
+
</div>
|
|
28882
|
+
|
|
28883
|
+
<!-- Tile 4: messages (right-upper, medium 88px) -->
|
|
28884
|
+
<div class="tile-entry tile-entry--4">
|
|
28885
|
+
<div class="icon-tile icon-tile--medium icon-tile--4">
|
|
28886
|
+
<div class="icon-tile__icon">
|
|
28887
|
+
<svg viewBox="0 0 24 24" fill="none">
|
|
28888
|
+
<path d="M7.291 20.824L2 22l1.176-5.291A9.956 9.956 0 0 1 2 12C2 6.477 6.477 2 12 2s10 4.477 10 10-4.477 10-10 10a9.956 9.956 0 0 1-4.709-1.176zM7.581 18.71l.29.158A7.956 7.956 0 0 0 12 20c4.418 0 8-3.582 8-8s-3.582-8-8-8-8 3.582-8 8c0 1.458.39 2.823 1.131 4.13l.159.288-.69 3.1 3.1-.69z" fill="currentColor"/>
|
|
28889
|
+
</svg>
|
|
28890
|
+
</div>
|
|
28891
|
+
</div>
|
|
28892
|
+
</div>
|
|
28893
|
+
|
|
28894
|
+
<!-- Tile 5: home (left-middle, medium 88px) -->
|
|
28895
|
+
<div class="tile-entry tile-entry--5">
|
|
28896
|
+
<div class="icon-tile icon-tile--medium icon-tile--5">
|
|
28897
|
+
<div class="icon-tile__icon">
|
|
28898
|
+
<svg viewBox="0 0 24 24" fill="none">
|
|
28899
|
+
<path d="M19 21H5a1 1 0 0 1-1-1v-9H1l10.327-9.388a1 1 0 0 1 1.346 0L23 11h-3v9a1 1 0 0 1-1 1zM6 19h12v-9.157l-6-5.454-6 5.454V19zm2-4h8v2H8v-2z" fill="currentColor"/>
|
|
28900
|
+
</svg>
|
|
28901
|
+
</div>
|
|
28902
|
+
</div>
|
|
28903
|
+
</div>
|
|
28904
|
+
|
|
28905
|
+
<!-- Hero: bell icon (center, 120px) -->
|
|
28906
|
+
<div class="tile-entry tile-entry--hero">
|
|
28907
|
+
<div class="icon-tile icon-tile--hero">
|
|
28908
|
+
<div class="icon-tile__icon">
|
|
28909
|
+
<svg viewBox="0 0 24 24" fill="none">
|
|
28910
|
+
<path d="M20 17h2v2H2v-2h2v-7a8 8 0 1 1 16 0v7zm-2 0v-7a6 6 0 1 0-12 0v7h12zm-9 4h6v2H9v-2z" fill="currentColor"/>
|
|
28911
|
+
</svg>
|
|
28912
|
+
</div>
|
|
28913
|
+
<span class="icon-tile__badge">18</span>
|
|
28914
|
+
</div>
|
|
28915
|
+
</div>
|
|
28916
|
+
|
|
28917
|
+
</div>
|
|
28918
|
+
</div>
|
|
28919
|
+
|
|
28920
|
+
<!-- Heading + subtitle -->
|
|
28921
|
+
<div class="notification-prompt__texts">
|
|
28922
|
+
<h1 class="notification-prompt__heading">{{ heading() }}</h1>
|
|
28923
|
+
<p class="notification-prompt__subtitle">{{ subtitle() }}</p>
|
|
28924
|
+
</div>
|
|
28925
|
+
|
|
28926
|
+
<!-- CTA buttons -->
|
|
28927
|
+
<div class="notification-prompt__actions">
|
|
28928
|
+
<ds-button
|
|
28929
|
+
variant="primary"
|
|
28930
|
+
size="md"
|
|
28931
|
+
(clicked)="handleAllow()">
|
|
28932
|
+
{{ allowLabel() }}
|
|
28933
|
+
</ds-button>
|
|
28934
|
+
<ds-button
|
|
28935
|
+
class="dismiss-btn"
|
|
28936
|
+
variant="ghost"
|
|
28937
|
+
size="md"
|
|
28938
|
+
(clicked)="handleDismiss()">
|
|
28939
|
+
{{ dismissLabel() }}
|
|
28940
|
+
</ds-button>
|
|
28941
|
+
</div>
|
|
28942
|
+
</div>
|
|
28943
|
+
`, styles: ["@keyframes fadeSlideUp{0%{opacity:0;transform:translateY(32px)}to{opacity:1;transform:translateY(0)}}@keyframes tileEntry{0%{opacity:0;transform:translateY(40px) scale(.85)}to{opacity:1;transform:translateY(0) scale(1)}}@keyframes float1{0%{transform:var(--tile-transform) translate(0) rotate(0)}11%{transform:var(--tile-transform) translate(1.4px,-3px) rotate(.9deg)}23%{transform:var(--tile-transform) translate(2.2px,-6.5px) rotate(1.8deg)}37%{transform:var(--tile-transform) translate(.6px,-8.5px) rotate(.4deg)}50%{transform:var(--tile-transform) translate(-1.2px,-7px) rotate(-.8deg)}63%{transform:var(--tile-transform) translate(-1.8px,-4px) rotate(-1.6deg)}76%{transform:var(--tile-transform) translate(-.4px,-1.5px) rotate(-.5deg)}88%{transform:var(--tile-transform) translate(.8px,-.5px) rotate(.3deg)}to{transform:var(--tile-transform) translate(0) rotate(0)}}@keyframes float2{0%{transform:var(--tile-transform) translate(0) rotate(0)}12%{transform:var(--tile-transform) translate(-1px,-2.5px) rotate(-.7deg)}25%{transform:var(--tile-transform) translate(-2px,-5.5px) rotate(-1.5deg)}38%{transform:var(--tile-transform) translate(-.8px,-7px) rotate(-.3deg)}50%{transform:var(--tile-transform) translate(1px,-6px) rotate(1deg)}62%{transform:var(--tile-transform) translate(1.6px,-3.5px) rotate(1.6deg)}75%{transform:var(--tile-transform) translate(.5px,-1.5px) rotate(.6deg)}87%{transform:var(--tile-transform) translate(-.5px,-.3px) rotate(-.2deg)}to{transform:var(--tile-transform) translate(0) rotate(0)}}@keyframes float3{0%{transform:var(--tile-transform) translate(0) rotate(0)}10%{transform:var(--tile-transform) translate(.8px,-3px) rotate(1.2deg)}22%{transform:var(--tile-transform) translate(1.5px,-7px) rotate(2deg)}35%{transform:var(--tile-transform) translate(.3px,-10px) rotate(.8deg)}48%{transform:var(--tile-transform) translate(-1.5px,-9.5px) rotate(-.6deg)}60%{transform:var(--tile-transform) translate(-2px,-6px) rotate(-1.5deg)}72%{transform:var(--tile-transform) translate(-1px,-3px) rotate(-.8deg)}85%{transform:var(--tile-transform) translate(.3px,-1px) rotate(.3deg)}to{transform:var(--tile-transform) translate(0) rotate(0)}}@keyframes float4{0%{transform:var(--tile-transform) translate(0) rotate(0)}13%{transform:var(--tile-transform) translate(-.8px,-2px) rotate(-.8deg)}26%{transform:var(--tile-transform) translate(-1.5px,-5px) rotate(-1.6deg)}40%{transform:var(--tile-transform) translate(.2px,-7.5px) rotate(-.2deg)}52%{transform:var(--tile-transform) translate(1.8px,-6.5px) rotate(1.2deg)}65%{transform:var(--tile-transform) translate(1.2px,-4px) rotate(.8deg)}78%{transform:var(--tile-transform) translate(-.3px,-1.8px) rotate(-.4deg)}90%{transform:var(--tile-transform) translate(-.6px,-.4px) rotate(-.1deg)}to{transform:var(--tile-transform) translate(0) rotate(0)}}@keyframes float5{0%{transform:var(--tile-transform) translate(0) rotate(0)}9%{transform:var(--tile-transform) translate(1.2px,-2px) rotate(.6deg)}20%{transform:var(--tile-transform) translate(2px,-5px) rotate(1.5deg)}33%{transform:var(--tile-transform) translate(.8px,-8.5px) rotate(.5deg)}45%{transform:var(--tile-transform) translate(-1px,-9.5px) rotate(-1deg)}58%{transform:var(--tile-transform) translate(-1.8px,-7px) rotate(-1.8deg)}70%{transform:var(--tile-transform) translate(-.8px,-4px) rotate(-.8deg)}82%{transform:var(--tile-transform) translate(.4px,-1.5px) rotate(.2deg)}92%{transform:var(--tile-transform) translate(.6px,-.3px) rotate(.1deg)}to{transform:var(--tile-transform) translate(0) rotate(0)}}@keyframes floatHero{0%{transform:translate(-50%) translate(0) rotate(0) scale(1)}10%{transform:translate(-50%) translate(.8px,-4px) rotate(.7deg) scale(1.006)}22%{transform:translate(-50%) translate(1.5px,-9px) rotate(1.4deg) scale(1.014)}35%{transform:translate(-50%) translate(.2px,-13px) rotate(.3deg) scale(1.02)}48%{transform:translate(-50%) translate(-1.5px,-12px) rotate(-1deg) scale(1.016)}60%{transform:translate(-50%) translate(-2px,-8px) rotate(-1.6deg) scale(1.01)}72%{transform:translate(-50%) translate(-.6px,-4px) rotate(-.5deg) scale(1.005)}85%{transform:translate(-50%) translate(.5px,-1.5px) rotate(.3deg) scale(1.002)}94%{transform:translate(-50%) translate(.3px,-.3px) rotate(.1deg) scale(1.001)}to{transform:translate(-50%) translate(0) rotate(0) scale(1)}}:host{display:flex;align-items:center;justify-content:center;position:fixed;inset:0;z-index:9999}.notification-prompt{width:100%;max-width:390px;height:100%;display:flex;flex-direction:column;gap:48px;overflow:clip;position:relative}.notification-prompt__backdrop{position:fixed;inset:0;z-index:-1}.notification-prompt__illustration{position:relative;flex:1 0 0;min-height:0;display:flex;align-items:center;justify-content:center;padding:0 24px}.icon-tiles{position:relative;width:100%;max-width:342px;height:100%}.tile-entry{position:absolute;opacity:0;animation:tileEntry .7s cubic-bezier(.22,1,.36,1) forwards;will-change:transform,opacity}.tile-entry--hero{inset:0;animation-delay:.2s;animation-duration:.8s}.tile-entry--1{inset:0;animation-delay:.35s}.tile-entry--4{inset:0;animation-delay:.3s}.tile-entry--5{inset:0;animation-delay:.4s}.tile-entry--3{inset:0;animation-delay:.45s}.tile-entry--2{inset:0;animation-delay:.5s}.icon-tile{position:absolute;display:flex;align-items:center;justify-content:center;border-radius:20%;background:linear-gradient(180deg,#0000 95%,#00000026),linear-gradient(180deg,#fff6,#fff0 4.5%),linear-gradient(180deg,#ffffff26,#fff0),linear-gradient(180deg,#0000,#0000001a),var(--color-accent, #6B5FF5);will-change:transform}.icon-tile__icon{width:62.5%;height:62.5%;display:flex;align-items:center;justify-content:center}.icon-tile__icon svg{width:100%;height:100%;color:#fff;display:block}.icon-tile--1{--tile-transform: translate(-50%, 0) rotate(7.74deg);width:72px;height:72px;top:22%;left:50%;filter:blur(2px);animation:float1 6.8s linear infinite}.icon-tile--2{--tile-transform: rotate(9.27deg);width:88px;height:88px;bottom:6%;right:0;filter:blur(1px);animation:float2 7.4s linear infinite}.icon-tile--3{--tile-transform: rotate(-6.18deg);width:72px;height:72px;bottom:0;left:0;filter:blur(2px);animation:float3 8.6s linear infinite}.icon-tile--4{--tile-transform: rotate(20.57deg);width:88px;height:88px;top:36%;right:0;filter:blur(1px);animation:float4 7.1s linear infinite}.icon-tile--5{--tile-transform: rotate(-8.24deg);width:88px;height:88px;top:44%;left:0;filter:blur(1px);animation:float5 9.2s linear infinite}.icon-tile--hero{width:120px;height:120px;left:50%;bottom:14%;filter:none;border-radius:30px;z-index:2;animation:floatHero 6.2s linear infinite}.icon-tile__badge{position:absolute;top:12.5%;right:12%;min-width:26px;height:26px;padding:0 7px;border-radius:8px;background:var(--content-feedback-bold-red, #b91c1c);display:flex;align-items:center;justify-content:center;font-family:Brockmann,system-ui,-apple-system,sans-serif;font-weight:600;font-size:18px;line-height:1;letter-spacing:-.04em;color:#fff;white-space:nowrap;box-sizing:border-box}.notification-prompt__texts{position:relative;z-index:1;text-align:center;padding:0 16px;flex-shrink:0;opacity:0;animation:fadeSlideUp .6s .6s cubic-bezier(.22,1,.36,1) forwards}.notification-prompt__heading{font-family:Brockmann,system-ui,-apple-system,sans-serif;font-weight:600;font-size:32px;line-height:1.15;letter-spacing:-.02em;color:#fff;margin:0 0 4px}.notification-prompt__subtitle{font-family:Brockmann,system-ui,-apple-system,sans-serif;font-weight:400;font-size:18px;line-height:1.4;letter-spacing:-.02em;color:#eef0ff;margin:0}.notification-prompt__actions{position:relative;z-index:1;display:flex;flex-direction:column;gap:8px;padding:0 24px 24px;padding-bottom:max(24px,env(safe-area-inset-bottom,24px));flex-shrink:0;opacity:0;animation:fadeSlideUp .6s .75s cubic-bezier(.22,1,.36,1) forwards}.notification-prompt__actions ds-button{display:block;width:100%}.notification-prompt__actions ds-button::ng-deep button{width:100%;border-radius:8px}.notification-prompt__actions ds-button.dismiss-btn::ng-deep button{color:#fff;background:transparent}@keyframes exitUp{0%{opacity:1;transform:translateY(0)}to{opacity:0;transform:translateY(-48px)}}@keyframes exitFade{0%{opacity:1}to{opacity:0}}.is-dismissing .notification-prompt__illustration{animation:exitUp .5s cubic-bezier(.55,0,1,.45) forwards}.is-dismissing .notification-prompt__texts{animation:exitUp .45s .15s cubic-bezier(.55,0,1,.45) forwards}.is-dismissing .notification-prompt__actions{animation:exitUp .45s .3s cubic-bezier(.55,0,1,.45) forwards}.is-dismissing .notification-prompt__backdrop{animation:exitFade .35s .45s cubic-bezier(.55,0,1,.45) forwards}@media (prefers-reduced-motion: reduce){.tile-entry,.icon-tile,.icon-tile--hero,.notification-prompt__texts,.notification-prompt__actions{animation:none!important;opacity:1!important}}\n"] }]
|
|
28944
|
+
}], propDecorators: { heading: [{ type: i0.Input, args: [{ isSignal: true, alias: "heading", required: false }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], allowLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "allowLabel", required: false }] }], dismissLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "dismissLabel", required: false }] }], allow: [{ type: i0.Output, args: ["allow"] }], dismiss: [{ type: i0.Output, args: ["dismiss"] }] } });
|
|
28945
|
+
|
|
28946
|
+
const NOTIFICATION_ICON_MAP = {
|
|
28947
|
+
inquiry_update: 'remixFileList3Line',
|
|
28948
|
+
inquiry_assigned: 'remixFileList3Line',
|
|
28949
|
+
inquiry_resolved: 'remixFileList3Line',
|
|
28950
|
+
community_post: 'remixCommunityLine',
|
|
28951
|
+
community_comment: 'remixCommunityLine',
|
|
28952
|
+
community_like: 'remixCommunityLine',
|
|
28953
|
+
community_mention: 'remixCommunityLine',
|
|
28954
|
+
booking_confirmed: 'remixCalendarCheckLine',
|
|
28955
|
+
booking_cancelled: 'remixCalendarCheckLine',
|
|
28956
|
+
booking_reminder: 'remixCalendarCheckLine',
|
|
28957
|
+
facility_available: 'remixCalendarCheckLine',
|
|
28958
|
+
message_new: 'remixMessage3Line',
|
|
28959
|
+
message_group: 'remixMessage3Line',
|
|
28960
|
+
service_update: 'remixServiceLine',
|
|
28961
|
+
handbook_update: 'remixBook2Line',
|
|
28962
|
+
system_announcement: 'remixHomeSmile2Line',
|
|
28963
|
+
system_welcome: 'remixHomeSmile2Line',
|
|
28964
|
+
invite_received: 'remixHomeSmile2Line',
|
|
28965
|
+
family_access: 'remixGroupLine',
|
|
28966
|
+
};
|
|
28967
|
+
|
|
28968
|
+
function minutesAgo(m) { return new Date(Date.now() - m * 60_000); }
|
|
28969
|
+
function hoursAgo(h) { return new Date(Date.now() - h * 3_600_000); }
|
|
28970
|
+
function daysAgo(d, hour = 12, minute = 0) {
|
|
28971
|
+
const date = new Date();
|
|
28972
|
+
date.setDate(date.getDate() - d);
|
|
28973
|
+
date.setHours(hour, minute, 0, 0);
|
|
28974
|
+
return date;
|
|
28975
|
+
}
|
|
28976
|
+
const SAMPLE_NOTIFICATIONS = [
|
|
28977
|
+
// Today — inquiry #2 "Problem med vandtryk"
|
|
28978
|
+
{ id: '1', type: 'inquiry_update', leading: 'icon', targetId: '2', title: 'Problem med vandtryk', message: 'Din henvendelse er blevet opdateret af ejendomskontoret.', createdAt: minutesAgo(5), read: false },
|
|
28979
|
+
// Today — Mette Larsen commented on post-1
|
|
28980
|
+
{ id: '2', type: 'community_comment', leading: 'avatar', targetId: 'post-1', avatarInitials: 'ML', title: 'Mette Larsen', message: 'Kommenterede: "Velkommen til fællesskabet!"', createdAt: minutesAgo(23), read: false },
|
|
28981
|
+
// Today — Marcus Lindqvist sent message in conv-2
|
|
28982
|
+
{ id: '3', type: 'message_new', leading: 'avatar', targetId: 'conv-2', avatarInitials: 'ML', title: 'Marcus Lindqvist', message: 'Kan du tjekke støjproblemet igen?', createdAt: minutesAgo(10), read: false },
|
|
28983
|
+
// Today — booking-1 "Festlokale på taget" confirmed
|
|
28984
|
+
{ id: '4', type: 'booking_confirmed', leading: 'image', targetId: 'booking-1', imageSrc: '/Assets/Dummy-photos/rooftop-party.jpg', title: 'Festlokale på taget', message: 'Din booking d. 14. feb kl. 9:00–17:00 er bekræftet.', createdAt: hoursAgo(2), read: true },
|
|
28985
|
+
// Today — Anders Jensen commented on post-2
|
|
28986
|
+
{ id: '5', type: 'community_comment', leading: 'avatar', targetId: 'post-2', avatarInitials: 'AJ', title: 'Anders Jensen', message: 'Kommenterede: "Wow, den udsigt er fantastisk!"', createdAt: hoursAgo(3), read: true },
|
|
28987
|
+
// Yesterday — Blik Partner A/S assigned to inquiry #2
|
|
28988
|
+
{ id: '6', type: 'inquiry_assigned', leading: 'avatar', targetId: '2', avatarInitials: 'BP', title: 'Blik Partner A/S', message: 'Er blevet tildelt din henvendelse om VVS.', createdAt: daysAgo(1, 16, 45), read: true },
|
|
28989
|
+
// Yesterday — Sophie Andersen posted in community (post-2)
|
|
28990
|
+
{ id: '7', type: 'community_post', leading: 'avatar', targetId: 'post-2', avatarInitials: 'SA', title: 'Sophie Andersen', message: 'Nyt opslag med billeder fra ejendommen.', createdAt: daysAgo(1, 14, 20), read: true },
|
|
28991
|
+
// Yesterday — booking-3 "Boremaskinen" reminder
|
|
28992
|
+
{ id: '8', type: 'booking_reminder', leading: 'image', targetId: 'booking-3', imageSrc: '/Assets/Dummy-photos/handyman.jpg', title: 'Boremaskinen', message: 'Du har en booking d. 25. mar kl. 10:00–14:00.', createdAt: daysAgo(1, 9, 0), read: true },
|
|
28993
|
+
// Yesterday — facility-1 "Boremaskinen" available
|
|
28994
|
+
{ id: '9', type: 'facility_available', leading: 'image', targetId: 'facility-1', imageSrc: '/Assets/Dummy-photos/handyman.jpg', title: 'Boremaskinen', message: 'Boremaskinen er nu ledig til booking.', createdAt: daysAgo(1, 8, 15), read: true },
|
|
28995
|
+
// Yesterday — group "Vaskeri & møde" message
|
|
28996
|
+
{ id: '10', type: 'message_group', leading: 'avatar', targetId: 'conv-group-demo', avatarInitials: 'VM', title: 'Vaskeri & møde', message: 'Anna Berg: "Vi mødes kl. 19 i fællesrummet."', createdAt: daysAgo(1, 19, 30), read: true },
|
|
28997
|
+
// Earlier — inquiry #3 resolved
|
|
28998
|
+
{ id: '11', type: 'inquiry_resolved', leading: 'icon', targetId: '3', title: 'Varme virker ikke ordentligt', message: 'Din henvendelse er nu markeret som løst.', createdAt: daysAgo(3), read: true },
|
|
28999
|
+
// Earlier — handbook updated
|
|
29000
|
+
{ id: '12', type: 'handbook_update', leading: 'logo', title: 'Håndbog opdateret', message: 'Afsnittet "Forsyninger" er blevet opdateret med ny information.', createdAt: daysAgo(4), read: true },
|
|
29001
|
+
// Earlier — ElektroTek ApS service update
|
|
29002
|
+
{ id: '13', type: 'service_update', leading: 'image', targetId: 'v-4', imageSrc: '/Assets/dummy-logos/electrician-logo.svg', title: 'ElektroTek ApS', message: 'El-service er nu tilgængelig via Services.', createdAt: daysAgo(5), read: true },
|
|
29003
|
+
// Earlier — Thomas Hansen commented on post-2
|
|
29004
|
+
{ id: '14', type: 'community_comment', leading: 'avatar', targetId: 'post-2', avatarInitials: 'TH', title: 'Thomas Hansen', message: 'Kommenterede: "Smuk! Jeg kan også se byens silhuet fra min lejlighed 🌆"', createdAt: daysAgo(6), read: true },
|
|
29005
|
+
// Earlier — booking-2 "Gæsteparkering" cancelled
|
|
29006
|
+
{ id: '15', type: 'booking_cancelled', leading: 'image', targetId: 'booking-2', imageSrc: '/Assets/Dummy-photos/parking.jpg', title: 'Gæsteparkering', message: 'Din booking d. 20. mar kl. 8:00–20:00 er blevet annulleret.', createdAt: daysAgo(7), read: true },
|
|
29007
|
+
// Earlier — system announcement
|
|
29008
|
+
{ id: '16', type: 'system_announcement', leading: 'logo', title: 'Systemmeddelelse', message: 'Planlagt vedligeholdelse d. 1. maj kl. 02:00–04:00.', createdAt: daysAgo(8), read: true },
|
|
29009
|
+
// Earlier — Karl Johansson message in conv-4
|
|
29010
|
+
{ id: '17', type: 'message_new', leading: 'avatar', targetId: 'conv-4', avatarInitials: 'KJ', title: 'Karl Johansson', message: 'Hej! Er vaskerummet ledigt i morgen kl. 10?', createdAt: daysAgo(9), read: true },
|
|
29011
|
+
// Earlier — Sara Lindqvist family access
|
|
29012
|
+
{ id: '18', type: 'family_access', leading: 'avatar', title: 'Sara Lindqvist', avatarInitials: 'SL', message: 'Sara Lindqvist har fået adgang til din konto.', createdAt: daysAgo(10), read: true },
|
|
29013
|
+
// Earlier — system welcome
|
|
29014
|
+
{ id: '19', type: 'system_welcome', leading: 'logo', title: 'Velkommen!', message: 'Velkommen til Propbinder – vi glæder os til at hjælpe dig.', createdAt: daysAgo(11), read: true },
|
|
29015
|
+
];
|
|
29016
|
+
|
|
29017
|
+
class NotificationService {
|
|
29018
|
+
notifications = signal(SAMPLE_NOTIFICATIONS, ...(ngDevMode ? [{ debugName: "notifications" }] : []));
|
|
29019
|
+
unreadCount = computed(() => this.notifications().filter(n => !n.read).length, ...(ngDevMode ? [{ debugName: "unreadCount" }] : []));
|
|
29020
|
+
/**
|
|
29021
|
+
* Add a new notification to the top of the list.
|
|
29022
|
+
* Intended for downstream push integration — call this when a
|
|
29023
|
+
* real push payload arrives via Capacitor's `pushNotificationReceived` listener.
|
|
29024
|
+
*/
|
|
29025
|
+
addNotification(item) {
|
|
29026
|
+
this.notifications.update(list => [item, ...list]);
|
|
29027
|
+
}
|
|
29028
|
+
markAsRead(id) {
|
|
29029
|
+
this.notifications.update(list => list.map(n => n.id === id ? { ...n, read: true } : n));
|
|
29030
|
+
}
|
|
29031
|
+
markAllAsRead() {
|
|
29032
|
+
this.notifications.update(list => list.map(n => ({ ...n, read: true })));
|
|
29033
|
+
}
|
|
29034
|
+
/**
|
|
29035
|
+
* Remove a single notification from the list permanently.
|
|
29036
|
+
*/
|
|
29037
|
+
removeNotification(id) {
|
|
29038
|
+
this.notifications.update(list => list.filter(n => n.id !== id));
|
|
29039
|
+
}
|
|
29040
|
+
/**
|
|
29041
|
+
* Remove all notifications from the list permanently.
|
|
29042
|
+
*/
|
|
29043
|
+
clearAll() {
|
|
29044
|
+
this.notifications.set([]);
|
|
29045
|
+
}
|
|
29046
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NotificationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
29047
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NotificationService, providedIn: 'root' });
|
|
29048
|
+
}
|
|
29049
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NotificationService, decorators: [{
|
|
29050
|
+
type: Injectable,
|
|
29051
|
+
args: [{ providedIn: 'root' }]
|
|
29052
|
+
}] });
|
|
29053
|
+
|
|
29054
|
+
class RelativeTimePipe {
|
|
29055
|
+
transform(date) {
|
|
29056
|
+
if (!date)
|
|
29057
|
+
return '';
|
|
29058
|
+
const now = Date.now();
|
|
29059
|
+
const diffMs = now - date.getTime();
|
|
29060
|
+
const diffSec = Math.floor(diffMs / 1000);
|
|
29061
|
+
const diffMin = Math.floor(diffSec / 60);
|
|
29062
|
+
const diffHr = Math.floor(diffMin / 60);
|
|
29063
|
+
const diffDays = Math.floor(diffHr / 24);
|
|
29064
|
+
if (diffSec < 60)
|
|
29065
|
+
return 'Nu';
|
|
29066
|
+
if (diffMin < 60)
|
|
29067
|
+
return `${diffMin} min siden`;
|
|
29068
|
+
if (diffHr < 24)
|
|
29069
|
+
return `${diffHr} ${diffHr === 1 ? 'time' : 'timer'} siden`;
|
|
29070
|
+
const today = new Date();
|
|
29071
|
+
today.setHours(0, 0, 0, 0);
|
|
29072
|
+
const yesterday = new Date(today.getTime() - 86_400_000);
|
|
29073
|
+
if (date.getTime() >= yesterday.getTime() && date.getTime() < today.getTime()) {
|
|
29074
|
+
return `I går, ${pad(date.getHours())}:${pad(date.getMinutes())}`;
|
|
29075
|
+
}
|
|
29076
|
+
if (diffDays < 7)
|
|
29077
|
+
return `${diffDays} dage siden`;
|
|
29078
|
+
const day = date.getDate();
|
|
29079
|
+
const monthNames = ['jan', 'feb', 'mar', 'apr', 'maj', 'jun', 'jul', 'aug', 'sep', 'okt', 'nov', 'dec'];
|
|
29080
|
+
return `${day}. ${monthNames[date.getMonth()]}`;
|
|
29081
|
+
}
|
|
29082
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: RelativeTimePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
29083
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.16", ngImport: i0, type: RelativeTimePipe, isStandalone: true, name: "relativeTime" });
|
|
29084
|
+
}
|
|
29085
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: RelativeTimePipe, decorators: [{
|
|
29086
|
+
type: Pipe,
|
|
29087
|
+
args: [{ name: 'relativeTime', standalone: true, pure: true }]
|
|
29088
|
+
}] });
|
|
29089
|
+
function pad(n) {
|
|
29090
|
+
return n < 10 ? `0${n}` : `${n}`;
|
|
29091
|
+
}
|
|
29092
|
+
/**
|
|
29093
|
+
* Bucket a date into 'today' | 'yesterday' | 'earlier' for grouping notifications.
|
|
29094
|
+
*/
|
|
29095
|
+
function dateBucket(date) {
|
|
29096
|
+
const now = new Date();
|
|
29097
|
+
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
29098
|
+
const yesterday = new Date(today.getTime() - 86_400_000);
|
|
29099
|
+
if (date.getTime() >= today.getTime())
|
|
29100
|
+
return 'today';
|
|
29101
|
+
if (date.getTime() >= yesterday.getTime())
|
|
29102
|
+
return 'yesterday';
|
|
29103
|
+
return 'earlier';
|
|
29104
|
+
}
|
|
29105
|
+
|
|
29106
|
+
class DsMobileNotificationModalComponent {
|
|
29107
|
+
modalController = inject(ModalController);
|
|
29108
|
+
notificationService = inject(NotificationService);
|
|
29109
|
+
bottomSheet = inject(DsMobileBottomSheetService);
|
|
29110
|
+
groups = computed(() => {
|
|
29111
|
+
const items = this.notificationService.notifications();
|
|
29112
|
+
if (!items || items.length === 0)
|
|
29113
|
+
return [];
|
|
29114
|
+
const todayItems = [];
|
|
29115
|
+
const yesterdayItems = [];
|
|
29116
|
+
const earlierItems = [];
|
|
29117
|
+
for (const item of items) {
|
|
29118
|
+
const bucket = dateBucket(item.createdAt);
|
|
29119
|
+
if (bucket === 'today')
|
|
29120
|
+
todayItems.push(item);
|
|
29121
|
+
else if (bucket === 'yesterday')
|
|
29122
|
+
yesterdayItems.push(item);
|
|
29123
|
+
else
|
|
29124
|
+
earlierItems.push(item);
|
|
29125
|
+
}
|
|
29126
|
+
const groups = [];
|
|
29127
|
+
if (todayItems.length > 0)
|
|
29128
|
+
groups.push({ label: 'I dag', items: todayItems });
|
|
29129
|
+
if (yesterdayItems.length > 0)
|
|
29130
|
+
groups.push({ label: 'I går', items: yesterdayItems });
|
|
29131
|
+
if (earlierItems.length > 0)
|
|
29132
|
+
groups.push({ label: 'Tidligere', items: earlierItems });
|
|
29133
|
+
return groups;
|
|
29134
|
+
}, ...(ngDevMode ? [{ debugName: "groups" }] : []));
|
|
29135
|
+
iconFor(type) {
|
|
29136
|
+
return NOTIFICATION_ICON_MAP[type] ?? 'remixNotificationLine';
|
|
29137
|
+
}
|
|
29138
|
+
TYPE_LABELS = {
|
|
29139
|
+
inquiry_update: 'Henvendelse',
|
|
29140
|
+
inquiry_assigned: 'Henvendelse',
|
|
29141
|
+
inquiry_resolved: 'Henvendelse',
|
|
29142
|
+
community_post: 'Fællesskab',
|
|
29143
|
+
community_comment: 'Kommentar',
|
|
29144
|
+
community_like: 'Fællesskab',
|
|
29145
|
+
community_mention: 'Omtale',
|
|
29146
|
+
booking_confirmed: 'Booking',
|
|
29147
|
+
booking_cancelled: 'Booking',
|
|
29148
|
+
booking_reminder: 'Booking',
|
|
29149
|
+
facility_available: 'Facilitet',
|
|
29150
|
+
message_new: 'Besked',
|
|
29151
|
+
message_group: 'Gruppebesked',
|
|
29152
|
+
service_update: 'Service',
|
|
29153
|
+
handbook_update: 'Håndbog',
|
|
29154
|
+
system_announcement: 'System',
|
|
29155
|
+
system_welcome: 'System',
|
|
29156
|
+
invite_received: 'Invitation',
|
|
29157
|
+
family_access: 'Familie',
|
|
29158
|
+
};
|
|
29159
|
+
labelFor(type) {
|
|
29160
|
+
return this.TYPE_LABELS[type] ?? '';
|
|
29161
|
+
}
|
|
29162
|
+
handleNotificationClick(item) {
|
|
29163
|
+
this.modalController.dismiss(item);
|
|
29164
|
+
}
|
|
29165
|
+
async handleLongPress(item) {
|
|
29166
|
+
const actions = [
|
|
29167
|
+
{ action: 'mark_read', title: item.read ? 'Marker som ulæst' : 'Marker som læst', icon: item.read ? 'remixMailUnreadLine' : 'remixMailOpenLine', destructive: false },
|
|
29168
|
+
{ action: 'remove', title: 'Fjern notifikation', icon: 'remixDeleteBinLine', destructive: true },
|
|
29169
|
+
];
|
|
29170
|
+
const sheet = await this.bottomSheet.create({
|
|
29171
|
+
component: DsMobileActionsBottomSheetComponent,
|
|
29172
|
+
componentProps: { customActionGroups: [{ actions }] },
|
|
29173
|
+
breakpoints: [0, 1],
|
|
29174
|
+
initialBreakpoint: 1,
|
|
29175
|
+
handle: true,
|
|
29176
|
+
backdropDismiss: true,
|
|
29177
|
+
cssClass: 'auto-height',
|
|
29178
|
+
});
|
|
29179
|
+
const result = await sheet.onWillDismiss();
|
|
29180
|
+
if (result.role === 'select' && result.data) {
|
|
29181
|
+
const action = result.data.action;
|
|
29182
|
+
if (action === 'mark_read') {
|
|
29183
|
+
if (item.read) {
|
|
29184
|
+
this.notificationService.notifications.update(list => list.map(n => n.id === item.id ? { ...n, read: false } : n));
|
|
29185
|
+
}
|
|
29186
|
+
else {
|
|
29187
|
+
this.notificationService.markAsRead(item.id);
|
|
29188
|
+
}
|
|
29189
|
+
}
|
|
29190
|
+
else if (action === 'remove') {
|
|
29191
|
+
this.notificationService.removeNotification(item.id);
|
|
29192
|
+
}
|
|
29193
|
+
}
|
|
29194
|
+
}
|
|
29195
|
+
async openBulkActions() {
|
|
29196
|
+
const actions = [
|
|
29197
|
+
{ action: 'mark_all_read', title: 'Marker alle som læst', icon: 'remixMailOpenLine', destructive: false },
|
|
29198
|
+
{ action: 'clear_all', title: 'Ryd alle notifikationer', icon: 'remixDeleteBinLine', destructive: true },
|
|
29199
|
+
];
|
|
29200
|
+
const sheet = await this.bottomSheet.create({
|
|
29201
|
+
component: DsMobileActionsBottomSheetComponent,
|
|
29202
|
+
componentProps: { customActionGroups: [{ actions }] },
|
|
29203
|
+
breakpoints: [0, 1],
|
|
29204
|
+
initialBreakpoint: 1,
|
|
29205
|
+
handle: true,
|
|
29206
|
+
backdropDismiss: true,
|
|
29207
|
+
cssClass: 'auto-height',
|
|
29208
|
+
});
|
|
29209
|
+
const result = await sheet.onWillDismiss();
|
|
29210
|
+
if (result.role === 'select' && result.data) {
|
|
29211
|
+
const action = result.data.action;
|
|
29212
|
+
if (action === 'mark_all_read') {
|
|
29213
|
+
this.notificationService.markAllAsRead();
|
|
29214
|
+
}
|
|
29215
|
+
else if (action === 'clear_all') {
|
|
29216
|
+
this.notificationService.clearAll();
|
|
29217
|
+
}
|
|
29218
|
+
}
|
|
29219
|
+
}
|
|
29220
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileNotificationModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
29221
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DsMobileNotificationModalComponent, isStandalone: true, selector: "ds-mobile-notification-modal", ngImport: i0, template: `
|
|
29222
|
+
<ds-mobile-modal-base
|
|
29223
|
+
headerTitle="Notifikationer"
|
|
29224
|
+
[showHeader]="true"
|
|
29225
|
+
closeButtonLabel="Luk">
|
|
29226
|
+
|
|
29227
|
+
<ds-icon-button
|
|
29228
|
+
header-trailing
|
|
29229
|
+
class="more-button"
|
|
29230
|
+
icon="remixMoreFill"
|
|
29231
|
+
variant="secondary"
|
|
29232
|
+
size="lg"
|
|
29233
|
+
(clicked)="openBulkActions()"
|
|
29234
|
+
aria-label="Flere handlinger"
|
|
29235
|
+
/>
|
|
29236
|
+
|
|
29237
|
+
@if (groups().length > 0) {
|
|
29238
|
+
@for (group of groups(); track group.label) {
|
|
29239
|
+
<div class="notification-group">
|
|
29240
|
+
<div class="notification-group__label">{{ group.label }}</div>
|
|
29241
|
+
|
|
29242
|
+
@for (item of group.items; track item.id) {
|
|
29243
|
+
<ds-mobile-list-item
|
|
29244
|
+
[interactive]="true"
|
|
29245
|
+
[showDivider]="!$last"
|
|
29246
|
+
[enableLongPress]="true"
|
|
29247
|
+
[showDesktopMoreButton]="false"
|
|
29248
|
+
align="top"
|
|
29249
|
+
(itemClick)="handleNotificationClick(item)"
|
|
29250
|
+
(longPress)="handleLongPress(item)">
|
|
29251
|
+
|
|
29252
|
+
@if (item.leading === 'icon') {
|
|
29253
|
+
<ds-avatar
|
|
29254
|
+
content-leading
|
|
29255
|
+
type="icon"
|
|
29256
|
+
[iconName]="item.iconName || iconFor(item.type)"
|
|
29257
|
+
size="md"
|
|
29258
|
+
/>
|
|
29259
|
+
}
|
|
29260
|
+
|
|
29261
|
+
@if (item.leading === 'avatar') {
|
|
29262
|
+
<ds-avatar
|
|
29263
|
+
content-leading
|
|
29264
|
+
[type]="item.avatarSrc ? 'photo' : 'initials'"
|
|
29265
|
+
[initials]="item.avatarInitials || ''"
|
|
29266
|
+
[src]="item.avatarSrc || ''"
|
|
29267
|
+
size="md"
|
|
29268
|
+
/>
|
|
29269
|
+
}
|
|
29270
|
+
|
|
29271
|
+
@if (item.leading === 'image') {
|
|
29272
|
+
<div content-leading class="notification-image">
|
|
29273
|
+
<img [src]="item.imageSrc" [alt]="item.title" />
|
|
29274
|
+
</div>
|
|
29275
|
+
}
|
|
29276
|
+
|
|
29277
|
+
@if (item.leading === 'logo') {
|
|
29278
|
+
<div content-leading class="notification-logo">
|
|
29279
|
+
<ds-app-icon size="lg" />
|
|
29280
|
+
</div>
|
|
29281
|
+
}
|
|
29282
|
+
|
|
29283
|
+
<div content-main class="notification-content">
|
|
29284
|
+
<div class="notification-header">
|
|
29285
|
+
<div class="notification-header__details">
|
|
29286
|
+
<span class="notification-header__name" [class.notification-header__name--unread]="!item.read">
|
|
29287
|
+
{{ item.title }}
|
|
29288
|
+
</span>
|
|
29289
|
+
<span class="notification-header__meta">
|
|
29290
|
+
{{ labelFor(item.type) }}
|
|
29291
|
+
<span class="notification-header__separator">·</span>
|
|
29292
|
+
{{ item.createdAt | relativeTime }}
|
|
29293
|
+
</span>
|
|
29294
|
+
</div>
|
|
29295
|
+
</div>
|
|
29296
|
+
<p class="notification-message">{{ item.message }}</p>
|
|
29297
|
+
</div>
|
|
29298
|
+
|
|
29299
|
+
@if (!item.read) {
|
|
29300
|
+
<div content-trailing class="notification-unread-dot"></div>
|
|
29301
|
+
}
|
|
29302
|
+
</ds-mobile-list-item>
|
|
29303
|
+
}
|
|
29304
|
+
</div>
|
|
29305
|
+
}
|
|
29306
|
+
} @else {
|
|
29307
|
+
<ds-mobile-empty-state
|
|
29308
|
+
imageSrc="/Assets/empty-state-notification.svg"
|
|
29309
|
+
imageAlt="Ingen notifikationer"
|
|
29310
|
+
title="Alt er stille herinde"
|
|
29311
|
+
description="Når der sker noget nyt, finder du det her."
|
|
29312
|
+
/>
|
|
29313
|
+
}
|
|
29314
|
+
</ds-mobile-modal-base>
|
|
29315
|
+
`, isInline: true, styles: [":host ::ng-deep .header-content{gap:8px!important}.more-button{flex-shrink:0;border-radius:50%}.more-button::ng-deep button{border-radius:50%!important;width:36px!important;height:36px!important;min-width:36px!important;min-height:36px!important;padding:0!important;display:flex!important;align-items:center!important;justify-content:center!important}.notification-group{padding:0 20px}.notification-group+.notification-group{margin-top:8px;border-top:1px solid var(--color-border-default-secondary, #E5E7EB)}.notification-group__label{font-family:Brockmann,system-ui,-apple-system,sans-serif;font-weight:600;font-size:13px;line-height:1;letter-spacing:-.02em;color:var(--text-color-default-tertiary, #999);text-transform:none;padding:16px 0 4px}.notification-content{display:flex;flex-direction:column;gap:2px;min-width:0}.notification-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:4px}.notification-header__details{display:flex;flex-direction:column;align-items:flex-start;gap:2px;flex:1;min-width:0}.notification-header__name{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm, 14px);font-weight:600;line-height:20px;letter-spacing:-.3px;color:var(--text-color-default-primary, #202227);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.notification-header__name--unread{font-weight:600}.notification-header__meta{font-family:Brockmann,sans-serif;font-size:var(--font-size-xs, 12px);font-weight:400;line-height:1.2;letter-spacing:-.26px;color:var(--text-color-default-tertiary, #737373);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;align-items:center;gap:4px}.notification-header__separator{color:var(--text-color-default-tertiary, #737373);opacity:.5}.notification-message{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm, 14px);font-weight:400;line-height:20px;letter-spacing:-.3px;color:var(--text-color-default-secondary, #545B66);margin:0;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}.notification-image{width:32px;height:32px;border-radius:8px;overflow:hidden;flex-shrink:0}.notification-image img{width:100%;height:100%;-o-object-fit:cover;object-fit:cover;display:block}.notification-logo{flex-shrink:0}.notification-unread-dot{width:8px;height:8px;border-radius:50%;background:var(--color-accent, #6B5FF5);flex-shrink:0;margin-top:6px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsMobileModalBaseComponent, selector: "ds-mobile-modal-base", inputs: ["headerTitleInteractive", "showHeader"], outputs: ["titleClick"] }, { kind: "component", type: DsMobileListItemComponent, selector: "ds-mobile-list-item", inputs: ["leadingSize", "variant", "align", "flushTop", "interactive", "disabled", "loading", "enableLongPress", "showDesktopMoreButton", "moreActions", "moreButtonAriaLabel", "interactiveOffset", "title", "subtitle", "showDivider", "dividerSpacing"], outputs: ["itemClick", "moreButtonClick"] }, { kind: "component", type: DsAvatarComponent, selector: "ds-avatar", inputs: ["type", "size", "initials", "src", "alt", "iconName", "iconColor"] }, { kind: "component", type: DsAppIconComponent, selector: "ds-app-icon", inputs: ["size"] }, { kind: "component", type: DsMobileEmptyStateComponent, selector: "ds-mobile-empty-state", inputs: ["imageSrc", "imageAlt", "title", "description"] }, { kind: "component", type: DsIconButtonComponent, selector: "ds-icon-button", inputs: ["variant", "size", "icon", "disabled", "loading", "pressed", "expanded", "ariaLabel", "tooltip", "tooltipDisabled", "tooltipPlacement"], outputs: ["clicked", "focused", "blurred"] }, { kind: "pipe", type: RelativeTimePipe, name: "relativeTime" }] });
|
|
29316
|
+
}
|
|
29317
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileNotificationModalComponent, decorators: [{
|
|
29318
|
+
type: Component,
|
|
29319
|
+
args: [{ selector: 'ds-mobile-notification-modal', standalone: true, imports: [CommonModule, DsMobileModalBaseComponent, DsMobileListItemComponent, DsAvatarComponent, DsAppIconComponent, DsMobileEmptyStateComponent, DsIconButtonComponent, RelativeTimePipe], template: `
|
|
29320
|
+
<ds-mobile-modal-base
|
|
29321
|
+
headerTitle="Notifikationer"
|
|
29322
|
+
[showHeader]="true"
|
|
29323
|
+
closeButtonLabel="Luk">
|
|
29324
|
+
|
|
29325
|
+
<ds-icon-button
|
|
29326
|
+
header-trailing
|
|
29327
|
+
class="more-button"
|
|
29328
|
+
icon="remixMoreFill"
|
|
29329
|
+
variant="secondary"
|
|
29330
|
+
size="lg"
|
|
29331
|
+
(clicked)="openBulkActions()"
|
|
29332
|
+
aria-label="Flere handlinger"
|
|
29333
|
+
/>
|
|
29334
|
+
|
|
29335
|
+
@if (groups().length > 0) {
|
|
29336
|
+
@for (group of groups(); track group.label) {
|
|
29337
|
+
<div class="notification-group">
|
|
29338
|
+
<div class="notification-group__label">{{ group.label }}</div>
|
|
29339
|
+
|
|
29340
|
+
@for (item of group.items; track item.id) {
|
|
29341
|
+
<ds-mobile-list-item
|
|
29342
|
+
[interactive]="true"
|
|
29343
|
+
[showDivider]="!$last"
|
|
29344
|
+
[enableLongPress]="true"
|
|
29345
|
+
[showDesktopMoreButton]="false"
|
|
29346
|
+
align="top"
|
|
29347
|
+
(itemClick)="handleNotificationClick(item)"
|
|
29348
|
+
(longPress)="handleLongPress(item)">
|
|
29349
|
+
|
|
29350
|
+
@if (item.leading === 'icon') {
|
|
29351
|
+
<ds-avatar
|
|
29352
|
+
content-leading
|
|
29353
|
+
type="icon"
|
|
29354
|
+
[iconName]="item.iconName || iconFor(item.type)"
|
|
29355
|
+
size="md"
|
|
29356
|
+
/>
|
|
29357
|
+
}
|
|
29358
|
+
|
|
29359
|
+
@if (item.leading === 'avatar') {
|
|
29360
|
+
<ds-avatar
|
|
29361
|
+
content-leading
|
|
29362
|
+
[type]="item.avatarSrc ? 'photo' : 'initials'"
|
|
29363
|
+
[initials]="item.avatarInitials || ''"
|
|
29364
|
+
[src]="item.avatarSrc || ''"
|
|
29365
|
+
size="md"
|
|
29366
|
+
/>
|
|
29367
|
+
}
|
|
29368
|
+
|
|
29369
|
+
@if (item.leading === 'image') {
|
|
29370
|
+
<div content-leading class="notification-image">
|
|
29371
|
+
<img [src]="item.imageSrc" [alt]="item.title" />
|
|
29372
|
+
</div>
|
|
29373
|
+
}
|
|
29374
|
+
|
|
29375
|
+
@if (item.leading === 'logo') {
|
|
29376
|
+
<div content-leading class="notification-logo">
|
|
29377
|
+
<ds-app-icon size="lg" />
|
|
29378
|
+
</div>
|
|
29379
|
+
}
|
|
29380
|
+
|
|
29381
|
+
<div content-main class="notification-content">
|
|
29382
|
+
<div class="notification-header">
|
|
29383
|
+
<div class="notification-header__details">
|
|
29384
|
+
<span class="notification-header__name" [class.notification-header__name--unread]="!item.read">
|
|
29385
|
+
{{ item.title }}
|
|
29386
|
+
</span>
|
|
29387
|
+
<span class="notification-header__meta">
|
|
29388
|
+
{{ labelFor(item.type) }}
|
|
29389
|
+
<span class="notification-header__separator">·</span>
|
|
29390
|
+
{{ item.createdAt | relativeTime }}
|
|
29391
|
+
</span>
|
|
29392
|
+
</div>
|
|
29393
|
+
</div>
|
|
29394
|
+
<p class="notification-message">{{ item.message }}</p>
|
|
29395
|
+
</div>
|
|
29396
|
+
|
|
29397
|
+
@if (!item.read) {
|
|
29398
|
+
<div content-trailing class="notification-unread-dot"></div>
|
|
29399
|
+
}
|
|
29400
|
+
</ds-mobile-list-item>
|
|
29401
|
+
}
|
|
29402
|
+
</div>
|
|
29403
|
+
}
|
|
29404
|
+
} @else {
|
|
29405
|
+
<ds-mobile-empty-state
|
|
29406
|
+
imageSrc="/Assets/empty-state-notification.svg"
|
|
29407
|
+
imageAlt="Ingen notifikationer"
|
|
29408
|
+
title="Alt er stille herinde"
|
|
29409
|
+
description="Når der sker noget nyt, finder du det her."
|
|
29410
|
+
/>
|
|
29411
|
+
}
|
|
29412
|
+
</ds-mobile-modal-base>
|
|
29413
|
+
`, styles: [":host ::ng-deep .header-content{gap:8px!important}.more-button{flex-shrink:0;border-radius:50%}.more-button::ng-deep button{border-radius:50%!important;width:36px!important;height:36px!important;min-width:36px!important;min-height:36px!important;padding:0!important;display:flex!important;align-items:center!important;justify-content:center!important}.notification-group{padding:0 20px}.notification-group+.notification-group{margin-top:8px;border-top:1px solid var(--color-border-default-secondary, #E5E7EB)}.notification-group__label{font-family:Brockmann,system-ui,-apple-system,sans-serif;font-weight:600;font-size:13px;line-height:1;letter-spacing:-.02em;color:var(--text-color-default-tertiary, #999);text-transform:none;padding:16px 0 4px}.notification-content{display:flex;flex-direction:column;gap:2px;min-width:0}.notification-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:4px}.notification-header__details{display:flex;flex-direction:column;align-items:flex-start;gap:2px;flex:1;min-width:0}.notification-header__name{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm, 14px);font-weight:600;line-height:20px;letter-spacing:-.3px;color:var(--text-color-default-primary, #202227);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.notification-header__name--unread{font-weight:600}.notification-header__meta{font-family:Brockmann,sans-serif;font-size:var(--font-size-xs, 12px);font-weight:400;line-height:1.2;letter-spacing:-.26px;color:var(--text-color-default-tertiary, #737373);white-space:nowrap;overflow:hidden;text-overflow:ellipsis;display:flex;align-items:center;gap:4px}.notification-header__separator{color:var(--text-color-default-tertiary, #737373);opacity:.5}.notification-message{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm, 14px);font-weight:400;line-height:20px;letter-spacing:-.3px;color:var(--text-color-default-secondary, #545B66);margin:0;display:-webkit-box;-webkit-line-clamp:2;-webkit-box-orient:vertical;overflow:hidden;text-overflow:ellipsis}.notification-image{width:32px;height:32px;border-radius:8px;overflow:hidden;flex-shrink:0}.notification-image img{width:100%;height:100%;-o-object-fit:cover;object-fit:cover;display:block}.notification-logo{flex-shrink:0}.notification-unread-dot{width:8px;height:8px;border-radius:50%;background:var(--color-accent, #6B5FF5);flex-shrink:0;margin-top:6px}\n"] }]
|
|
29414
|
+
}] });
|
|
28628
29415
|
|
|
28629
29416
|
/**
|
|
28630
29417
|
* PostsService
|
|
@@ -29151,6 +29938,614 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
29151
29938
|
}]
|
|
29152
29939
|
}], ctorParameters: () => [] });
|
|
29153
29940
|
|
|
29941
|
+
class DsMobileBookingDetailSheetComponent {
|
|
29942
|
+
modalController;
|
|
29943
|
+
/** `sheet` = bottom sheet. `modal` = `ds-modal-base` shell (active + history bookings). */
|
|
29944
|
+
presentation = 'sheet';
|
|
29945
|
+
data;
|
|
29946
|
+
/** When true the modal sizes to its content instead of filling the screen. */
|
|
29947
|
+
autoHeight = false;
|
|
29948
|
+
get isModalPresentation() {
|
|
29949
|
+
return this.presentation === 'modal';
|
|
29950
|
+
}
|
|
29951
|
+
constructor(modalController) {
|
|
29952
|
+
this.modalController = modalController;
|
|
29953
|
+
}
|
|
29954
|
+
close() {
|
|
29955
|
+
this.modalController.dismiss(null, 'backdrop');
|
|
29956
|
+
}
|
|
29957
|
+
cancelBooking() {
|
|
29958
|
+
this.modalController.dismiss(null, 'cancel');
|
|
29959
|
+
}
|
|
29960
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetComponent, deps: [{ token: i1.ModalController }], target: i0.ɵɵFactoryTarget.Component });
|
|
29961
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DsMobileBookingDetailSheetComponent, isStandalone: true, selector: "ds-mobile-booking-detail-sheet", inputs: { presentation: "presentation", data: "data", autoHeight: "autoHeight" }, host: { properties: { "class.presentation-modal": "this.isModalPresentation" } }, ngImport: i0, template: `
|
|
29962
|
+
@if (presentation === 'modal') {
|
|
29963
|
+
<ds-mobile-modal-base
|
|
29964
|
+
[headerTitle]="data.facilityTitle"
|
|
29965
|
+
[closeButtonLabel]="'Luk'"
|
|
29966
|
+
[isAutoHeight]="autoHeight"
|
|
29967
|
+
[keyboardContentBehavior]="'follow'">
|
|
29968
|
+
|
|
29969
|
+
<ds-mobile-section
|
|
29970
|
+
[showBorder]="false"
|
|
29971
|
+
padding="20px 20px 0 20px">
|
|
29972
|
+
<div class="hero-image-container">
|
|
29973
|
+
@if (data.heroImage) {
|
|
29974
|
+
<img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
|
|
29975
|
+
} @else {
|
|
29976
|
+
<div class="hero-image-placeholder">
|
|
29977
|
+
<ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
|
|
29978
|
+
</div>
|
|
29979
|
+
}
|
|
29980
|
+
</div>
|
|
29981
|
+
</ds-mobile-section>
|
|
29982
|
+
|
|
29983
|
+
<ds-mobile-section padding="20px 20px 20px 20px">
|
|
29984
|
+
<div class="booking-summary-card">
|
|
29985
|
+
<div class="details-section">
|
|
29986
|
+
<h3 class="details-heading">Booking detaljer</h3>
|
|
29987
|
+
<div class="info-rows">
|
|
29988
|
+
@if (data.bookingDate) {
|
|
29989
|
+
<div class="info-row">
|
|
29990
|
+
<ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
|
|
29991
|
+
<span>{{ data.bookingDate }}</span>
|
|
29992
|
+
</div>
|
|
29993
|
+
}
|
|
29994
|
+
@if (data.bookingTime) {
|
|
29995
|
+
<div class="info-row">
|
|
29996
|
+
<ds-icon name="remixTimeLine" size="16px" color="tertiary" />
|
|
29997
|
+
<span>{{ data.bookingTime }}</span>
|
|
29998
|
+
</div>
|
|
29999
|
+
}
|
|
30000
|
+
@if (data.price) {
|
|
30001
|
+
<div class="info-row">
|
|
30002
|
+
<ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
|
|
30003
|
+
<span>{{ data.price }}</span>
|
|
30004
|
+
</div>
|
|
30005
|
+
}
|
|
30006
|
+
@if (data.bookingType) {
|
|
30007
|
+
<div class="info-row">
|
|
30008
|
+
<ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
|
|
30009
|
+
<span>{{ data.bookingType }}</span>
|
|
30010
|
+
</div>
|
|
30011
|
+
}
|
|
30012
|
+
@for (req of data.requirements || []; track req) {
|
|
30013
|
+
<div class="info-row">
|
|
30014
|
+
<ds-icon name="remixLockLine" size="16px" color="tertiary" />
|
|
30015
|
+
<span>{{ req }}</span>
|
|
30016
|
+
</div>
|
|
30017
|
+
}
|
|
30018
|
+
</div>
|
|
30019
|
+
</div>
|
|
30020
|
+
</div>
|
|
30021
|
+
</ds-mobile-section>
|
|
30022
|
+
|
|
30023
|
+
@if (data.canCancel) {
|
|
30024
|
+
<div class="booking-action">
|
|
30025
|
+
<div class="booking-actions-row">
|
|
30026
|
+
<ds-button
|
|
30027
|
+
class="cancel-primary"
|
|
30028
|
+
size="md"
|
|
30029
|
+
variant="secondary"
|
|
30030
|
+
(clicked)="cancelBooking()">
|
|
30031
|
+
Annuller booking
|
|
30032
|
+
</ds-button>
|
|
30033
|
+
</div>
|
|
30034
|
+
</div>
|
|
30035
|
+
}
|
|
30036
|
+
</ds-mobile-modal-base>
|
|
30037
|
+
} @else {
|
|
30038
|
+
<ds-mobile-bottom-sheet-wrapper [showDragHandle]="true">
|
|
30039
|
+
<div class="detail-header">
|
|
30040
|
+
<h2 class="detail-title">{{ data.facilityTitle }}</h2>
|
|
30041
|
+
<ds-icon-button
|
|
30042
|
+
icon="remixCloseLine"
|
|
30043
|
+
variant="ghost"
|
|
30044
|
+
size="sm"
|
|
30045
|
+
(clicked)="close()"
|
|
30046
|
+
aria-label="Luk"
|
|
30047
|
+
/>
|
|
30048
|
+
</div>
|
|
30049
|
+
|
|
30050
|
+
<div class="detail-content">
|
|
30051
|
+
<div class="hero-image-container">
|
|
30052
|
+
@if (data.heroImage) {
|
|
30053
|
+
<img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
|
|
30054
|
+
} @else {
|
|
30055
|
+
<div class="hero-image-placeholder">
|
|
30056
|
+
<ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
|
|
30057
|
+
</div>
|
|
30058
|
+
}
|
|
30059
|
+
</div>
|
|
30060
|
+
|
|
30061
|
+
<div class="booking-summary-card">
|
|
30062
|
+
<div class="details-section">
|
|
30063
|
+
<h3 class="details-heading">Booking detaljer</h3>
|
|
30064
|
+
<div class="info-rows">
|
|
30065
|
+
@if (data.bookingDate) {
|
|
30066
|
+
<div class="info-row">
|
|
30067
|
+
<ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
|
|
30068
|
+
<span>{{ data.bookingDate }}</span>
|
|
30069
|
+
</div>
|
|
30070
|
+
}
|
|
30071
|
+
@if (data.bookingTime) {
|
|
30072
|
+
<div class="info-row">
|
|
30073
|
+
<ds-icon name="remixTimeLine" size="16px" color="tertiary" />
|
|
30074
|
+
<span>{{ data.bookingTime }}</span>
|
|
30075
|
+
</div>
|
|
30076
|
+
}
|
|
30077
|
+
@if (data.price) {
|
|
30078
|
+
<div class="info-row">
|
|
30079
|
+
<ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
|
|
30080
|
+
<span>{{ data.price }}</span>
|
|
30081
|
+
</div>
|
|
30082
|
+
}
|
|
30083
|
+
@if (data.bookingType) {
|
|
30084
|
+
<div class="info-row">
|
|
30085
|
+
<ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
|
|
30086
|
+
<span>{{ data.bookingType }}</span>
|
|
30087
|
+
</div>
|
|
30088
|
+
}
|
|
30089
|
+
@for (req of data.requirements || []; track req) {
|
|
30090
|
+
<div class="info-row">
|
|
30091
|
+
<ds-icon name="remixLockLine" size="16px" color="tertiary" />
|
|
30092
|
+
<span>{{ req }}</span>
|
|
30093
|
+
</div>
|
|
30094
|
+
}
|
|
30095
|
+
</div>
|
|
30096
|
+
</div>
|
|
30097
|
+
</div>
|
|
30098
|
+
|
|
30099
|
+
@if (data.canCancel) {
|
|
30100
|
+
<div class="footer-button-container">
|
|
30101
|
+
<div class="booking-actions-column">
|
|
30102
|
+
<ds-button
|
|
30103
|
+
size="md"
|
|
30104
|
+
variant="secondary"
|
|
30105
|
+
(clicked)="cancelBooking()">
|
|
30106
|
+
Annuller booking
|
|
30107
|
+
</ds-button>
|
|
30108
|
+
</div>
|
|
30109
|
+
</div>
|
|
30110
|
+
}
|
|
30111
|
+
</div>
|
|
30112
|
+
</ds-mobile-bottom-sheet-wrapper>
|
|
30113
|
+
}
|
|
30114
|
+
`, isInline: true, styles: [":host{display:block;height:auto;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;box-sizing:border-box}.detail-header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px 8px}.detail-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-lg, 18px);font-weight:600;color:var(--text-color-default-primary, #202227);margin:0;flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding-right:12px}.detail-content{padding:8px 20px 24px;display:flex;flex-direction:column;gap:20px}.hero-image-container{width:100%;aspect-ratio:16 / 9;border-radius:12px;overflow:hidden;background:var(--color-surface-secondary, #f5f5f5)}.hero-image{width:100%;height:100%;object-fit:cover;display:block}.hero-image-placeholder{width:100%;height:100%;min-height:0;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,color-mix(in srgb,var(--color-accent, #6B5FF5) 30%,transparent),color-mix(in srgb,var(--color-accent, #6B5FF5) 60%,transparent))}.booking-summary-card{background:var(--color-background-neutral-secondary, #f5f5f5);border-radius:16px;padding:16px}.details-section{display:flex;flex-direction:column;gap:12px}.details-heading{font-family:Brockmann,sans-serif;font-size:var(--font-size-base, 16px);font-weight:600;color:var(--text-color-default-primary, #202227);margin:0}.info-rows{display:flex;flex-direction:column;gap:8px}.info-row{display:flex;align-items:center;gap:10px;font-family:Brockmann,sans-serif;font-size:var(--font-size-sm, 14px);color:var(--text-color-default-secondary, #545B66);line-height:1.4}.info-row ds-icon{flex-shrink:0}.footer-button-container{width:100%;padding:16px 20px 0}.footer-button-container ::ng-deep ds-button{display:block;width:100%}.footer-button-container ::ng-deep ds-button button{width:100%;border-radius:100px;height:44px;min-height:44px;max-height:44px}.booking-action{padding:16px 20px;padding-bottom:calc(16px + max(8px,env(safe-area-inset-bottom,0px) - 24px));background:var(--color-surface-primary, #ffffff)}.booking-actions-row{display:flex;flex-direction:row;align-items:center;gap:12px;width:100%}.booking-action .cancel-primary{flex:1;min-width:0;display:block}.booking-action .cancel-primary ::ng-deep button{width:100%;border-radius:100px;height:44px;min-height:44px;max-height:44px;padding-left:16px;padding-right:16px}:host.presentation-modal{display:block;height:auto;width:100%;min-height:0;overflow:hidden}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsMobileBottomSheetWrapperComponent, selector: "ds-mobile-bottom-sheet-wrapper", inputs: ["showDragHandle"] }, { kind: "component", type: DsMobileModalBaseComponent, selector: "ds-mobile-modal-base", inputs: ["headerTitleInteractive", "showHeader"], outputs: ["titleClick"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsButtonComponent, selector: "ds-button", inputs: ["variant", "size", "disabled", "loading", "pressed", "expanded", "leadingIcon", "trailingIcon", "ariaLabel", "iconOnly"], outputs: ["clicked", "focused", "blurred"] }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsIconButtonComponent, selector: "ds-icon-button", inputs: ["variant", "size", "icon", "disabled", "loading", "pressed", "expanded", "ariaLabel", "tooltip", "tooltipDisabled", "tooltipPlacement"], outputs: ["clicked", "focused", "blurred"] }] });
|
|
30115
|
+
}
|
|
30116
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetComponent, decorators: [{
|
|
30117
|
+
type: Component,
|
|
30118
|
+
args: [{ selector: 'ds-mobile-booking-detail-sheet', standalone: true, imports: [
|
|
30119
|
+
CommonModule,
|
|
30120
|
+
DsMobileBottomSheetWrapperComponent,
|
|
30121
|
+
DsMobileModalBaseComponent,
|
|
30122
|
+
DsMobileSectionComponent,
|
|
30123
|
+
DsButtonComponent,
|
|
30124
|
+
DsIconComponent,
|
|
30125
|
+
DsIconButtonComponent,
|
|
30126
|
+
], template: `
|
|
30127
|
+
@if (presentation === 'modal') {
|
|
30128
|
+
<ds-mobile-modal-base
|
|
30129
|
+
[headerTitle]="data.facilityTitle"
|
|
30130
|
+
[closeButtonLabel]="'Luk'"
|
|
30131
|
+
[isAutoHeight]="autoHeight"
|
|
30132
|
+
[keyboardContentBehavior]="'follow'">
|
|
30133
|
+
|
|
30134
|
+
<ds-mobile-section
|
|
30135
|
+
[showBorder]="false"
|
|
30136
|
+
padding="20px 20px 0 20px">
|
|
30137
|
+
<div class="hero-image-container">
|
|
30138
|
+
@if (data.heroImage) {
|
|
30139
|
+
<img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
|
|
30140
|
+
} @else {
|
|
30141
|
+
<div class="hero-image-placeholder">
|
|
30142
|
+
<ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
|
|
30143
|
+
</div>
|
|
30144
|
+
}
|
|
30145
|
+
</div>
|
|
30146
|
+
</ds-mobile-section>
|
|
30147
|
+
|
|
30148
|
+
<ds-mobile-section padding="20px 20px 20px 20px">
|
|
30149
|
+
<div class="booking-summary-card">
|
|
30150
|
+
<div class="details-section">
|
|
30151
|
+
<h3 class="details-heading">Booking detaljer</h3>
|
|
30152
|
+
<div class="info-rows">
|
|
30153
|
+
@if (data.bookingDate) {
|
|
30154
|
+
<div class="info-row">
|
|
30155
|
+
<ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
|
|
30156
|
+
<span>{{ data.bookingDate }}</span>
|
|
30157
|
+
</div>
|
|
30158
|
+
}
|
|
30159
|
+
@if (data.bookingTime) {
|
|
30160
|
+
<div class="info-row">
|
|
30161
|
+
<ds-icon name="remixTimeLine" size="16px" color="tertiary" />
|
|
30162
|
+
<span>{{ data.bookingTime }}</span>
|
|
30163
|
+
</div>
|
|
30164
|
+
}
|
|
30165
|
+
@if (data.price) {
|
|
30166
|
+
<div class="info-row">
|
|
30167
|
+
<ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
|
|
30168
|
+
<span>{{ data.price }}</span>
|
|
30169
|
+
</div>
|
|
30170
|
+
}
|
|
30171
|
+
@if (data.bookingType) {
|
|
30172
|
+
<div class="info-row">
|
|
30173
|
+
<ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
|
|
30174
|
+
<span>{{ data.bookingType }}</span>
|
|
30175
|
+
</div>
|
|
30176
|
+
}
|
|
30177
|
+
@for (req of data.requirements || []; track req) {
|
|
30178
|
+
<div class="info-row">
|
|
30179
|
+
<ds-icon name="remixLockLine" size="16px" color="tertiary" />
|
|
30180
|
+
<span>{{ req }}</span>
|
|
30181
|
+
</div>
|
|
30182
|
+
}
|
|
30183
|
+
</div>
|
|
30184
|
+
</div>
|
|
30185
|
+
</div>
|
|
30186
|
+
</ds-mobile-section>
|
|
30187
|
+
|
|
30188
|
+
@if (data.canCancel) {
|
|
30189
|
+
<div class="booking-action">
|
|
30190
|
+
<div class="booking-actions-row">
|
|
30191
|
+
<ds-button
|
|
30192
|
+
class="cancel-primary"
|
|
30193
|
+
size="md"
|
|
30194
|
+
variant="secondary"
|
|
30195
|
+
(clicked)="cancelBooking()">
|
|
30196
|
+
Annuller booking
|
|
30197
|
+
</ds-button>
|
|
30198
|
+
</div>
|
|
30199
|
+
</div>
|
|
30200
|
+
}
|
|
30201
|
+
</ds-mobile-modal-base>
|
|
30202
|
+
} @else {
|
|
30203
|
+
<ds-mobile-bottom-sheet-wrapper [showDragHandle]="true">
|
|
30204
|
+
<div class="detail-header">
|
|
30205
|
+
<h2 class="detail-title">{{ data.facilityTitle }}</h2>
|
|
30206
|
+
<ds-icon-button
|
|
30207
|
+
icon="remixCloseLine"
|
|
30208
|
+
variant="ghost"
|
|
30209
|
+
size="sm"
|
|
30210
|
+
(clicked)="close()"
|
|
30211
|
+
aria-label="Luk"
|
|
30212
|
+
/>
|
|
30213
|
+
</div>
|
|
30214
|
+
|
|
30215
|
+
<div class="detail-content">
|
|
30216
|
+
<div class="hero-image-container">
|
|
30217
|
+
@if (data.heroImage) {
|
|
30218
|
+
<img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
|
|
30219
|
+
} @else {
|
|
30220
|
+
<div class="hero-image-placeholder">
|
|
30221
|
+
<ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
|
|
30222
|
+
</div>
|
|
30223
|
+
}
|
|
30224
|
+
</div>
|
|
30225
|
+
|
|
30226
|
+
<div class="booking-summary-card">
|
|
30227
|
+
<div class="details-section">
|
|
30228
|
+
<h3 class="details-heading">Booking detaljer</h3>
|
|
30229
|
+
<div class="info-rows">
|
|
30230
|
+
@if (data.bookingDate) {
|
|
30231
|
+
<div class="info-row">
|
|
30232
|
+
<ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
|
|
30233
|
+
<span>{{ data.bookingDate }}</span>
|
|
30234
|
+
</div>
|
|
30235
|
+
}
|
|
30236
|
+
@if (data.bookingTime) {
|
|
30237
|
+
<div class="info-row">
|
|
30238
|
+
<ds-icon name="remixTimeLine" size="16px" color="tertiary" />
|
|
30239
|
+
<span>{{ data.bookingTime }}</span>
|
|
30240
|
+
</div>
|
|
30241
|
+
}
|
|
30242
|
+
@if (data.price) {
|
|
30243
|
+
<div class="info-row">
|
|
30244
|
+
<ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
|
|
30245
|
+
<span>{{ data.price }}</span>
|
|
30246
|
+
</div>
|
|
30247
|
+
}
|
|
30248
|
+
@if (data.bookingType) {
|
|
30249
|
+
<div class="info-row">
|
|
30250
|
+
<ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
|
|
30251
|
+
<span>{{ data.bookingType }}</span>
|
|
30252
|
+
</div>
|
|
30253
|
+
}
|
|
30254
|
+
@for (req of data.requirements || []; track req) {
|
|
30255
|
+
<div class="info-row">
|
|
30256
|
+
<ds-icon name="remixLockLine" size="16px" color="tertiary" />
|
|
30257
|
+
<span>{{ req }}</span>
|
|
30258
|
+
</div>
|
|
30259
|
+
}
|
|
30260
|
+
</div>
|
|
30261
|
+
</div>
|
|
30262
|
+
</div>
|
|
30263
|
+
|
|
30264
|
+
@if (data.canCancel) {
|
|
30265
|
+
<div class="footer-button-container">
|
|
30266
|
+
<div class="booking-actions-column">
|
|
30267
|
+
<ds-button
|
|
30268
|
+
size="md"
|
|
30269
|
+
variant="secondary"
|
|
30270
|
+
(clicked)="cancelBooking()">
|
|
30271
|
+
Annuller booking
|
|
30272
|
+
</ds-button>
|
|
30273
|
+
</div>
|
|
30274
|
+
</div>
|
|
30275
|
+
}
|
|
30276
|
+
</div>
|
|
30277
|
+
</ds-mobile-bottom-sheet-wrapper>
|
|
30278
|
+
}
|
|
30279
|
+
`, styles: [":host{display:block;height:auto;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;box-sizing:border-box}.detail-header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px 8px}.detail-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-lg, 18px);font-weight:600;color:var(--text-color-default-primary, #202227);margin:0;flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding-right:12px}.detail-content{padding:8px 20px 24px;display:flex;flex-direction:column;gap:20px}.hero-image-container{width:100%;aspect-ratio:16 / 9;border-radius:12px;overflow:hidden;background:var(--color-surface-secondary, #f5f5f5)}.hero-image{width:100%;height:100%;object-fit:cover;display:block}.hero-image-placeholder{width:100%;height:100%;min-height:0;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,color-mix(in srgb,var(--color-accent, #6B5FF5) 30%,transparent),color-mix(in srgb,var(--color-accent, #6B5FF5) 60%,transparent))}.booking-summary-card{background:var(--color-background-neutral-secondary, #f5f5f5);border-radius:16px;padding:16px}.details-section{display:flex;flex-direction:column;gap:12px}.details-heading{font-family:Brockmann,sans-serif;font-size:var(--font-size-base, 16px);font-weight:600;color:var(--text-color-default-primary, #202227);margin:0}.info-rows{display:flex;flex-direction:column;gap:8px}.info-row{display:flex;align-items:center;gap:10px;font-family:Brockmann,sans-serif;font-size:var(--font-size-sm, 14px);color:var(--text-color-default-secondary, #545B66);line-height:1.4}.info-row ds-icon{flex-shrink:0}.footer-button-container{width:100%;padding:16px 20px 0}.footer-button-container ::ng-deep ds-button{display:block;width:100%}.footer-button-container ::ng-deep ds-button button{width:100%;border-radius:100px;height:44px;min-height:44px;max-height:44px}.booking-action{padding:16px 20px;padding-bottom:calc(16px + max(8px,env(safe-area-inset-bottom,0px) - 24px));background:var(--color-surface-primary, #ffffff)}.booking-actions-row{display:flex;flex-direction:row;align-items:center;gap:12px;width:100%}.booking-action .cancel-primary{flex:1;min-width:0;display:block}.booking-action .cancel-primary ::ng-deep button{width:100%;border-radius:100px;height:44px;min-height:44px;max-height:44px;padding-left:16px;padding-right:16px}:host.presentation-modal{display:block;height:auto;width:100%;min-height:0;overflow:hidden}\n"] }]
|
|
30280
|
+
}], ctorParameters: () => [{ type: i1.ModalController }], propDecorators: { presentation: [{
|
|
30281
|
+
type: Input
|
|
30282
|
+
}], data: [{
|
|
30283
|
+
type: Input
|
|
30284
|
+
}], autoHeight: [{
|
|
30285
|
+
type: Input
|
|
30286
|
+
}], isModalPresentation: [{
|
|
30287
|
+
type: HostBinding,
|
|
30288
|
+
args: ['class.presentation-modal']
|
|
30289
|
+
}] } });
|
|
30290
|
+
|
|
30291
|
+
class DsMobileBookingDetailSheetService extends BaseModalService {
|
|
30292
|
+
bottomSheet;
|
|
30293
|
+
constructor(modalController, bottomSheet) {
|
|
30294
|
+
super(modalController);
|
|
30295
|
+
this.bottomSheet = bottomSheet;
|
|
30296
|
+
}
|
|
30297
|
+
/**
|
|
30298
|
+
* Bottom-sheet presentation (draggable breakpoints). Prefer `openAsModal` for booking lists.
|
|
30299
|
+
*/
|
|
30300
|
+
async open(data) {
|
|
30301
|
+
const modal = await this.bottomSheet.create({
|
|
30302
|
+
component: DsMobileBookingDetailSheetComponent,
|
|
30303
|
+
componentProps: { data },
|
|
30304
|
+
autoHeight: true,
|
|
30305
|
+
backdropDismiss: true,
|
|
30306
|
+
backdropBlur: true,
|
|
30307
|
+
});
|
|
30308
|
+
const result = await modal.onWillDismiss();
|
|
30309
|
+
return { role: result.role, data: result.data ?? undefined };
|
|
30310
|
+
}
|
|
30311
|
+
/** `ds-modal-base` shell — used for active and past bookings. Auto-heights to content. */
|
|
30312
|
+
async openAsModal(data) {
|
|
30313
|
+
const modal = await this.createModal(DsMobileBookingDetailSheetComponent, { data, presentation: 'modal', autoHeight: true }, { keyboardClose: true, autoHeight: true });
|
|
30314
|
+
await modal.present();
|
|
30315
|
+
const result = await modal.onWillDismiss();
|
|
30316
|
+
return { role: result.role, data: result.data ?? undefined };
|
|
30317
|
+
}
|
|
30318
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetService, deps: [{ token: i1.ModalController }, { token: DsMobileBottomSheetService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
30319
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetService, providedIn: 'root' });
|
|
30320
|
+
}
|
|
30321
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetService, decorators: [{
|
|
30322
|
+
type: Injectable,
|
|
30323
|
+
args: [{
|
|
30324
|
+
providedIn: 'root',
|
|
30325
|
+
}]
|
|
30326
|
+
}], ctorParameters: () => [{ type: i1.ModalController }, { type: DsMobileBottomSheetService }] });
|
|
30327
|
+
|
|
30328
|
+
const VENDOR_MODAL_SERVICE = new InjectionToken('VendorModalService');
|
|
30329
|
+
const BOOKING_DETAIL_MAP = {
|
|
30330
|
+
'booking-1': {
|
|
30331
|
+
id: 'booking-1',
|
|
30332
|
+
facilityTitle: 'Festlokale på taget',
|
|
30333
|
+
heroImage: '/Assets/Dummy-photos/rooftop-party.jpg',
|
|
30334
|
+
bookingDate: '14. februar',
|
|
30335
|
+
bookingTime: '9:00 - 17:00',
|
|
30336
|
+
price: '200 kr. per booking',
|
|
30337
|
+
canCancel: true,
|
|
30338
|
+
},
|
|
30339
|
+
'booking-2': {
|
|
30340
|
+
id: 'booking-2',
|
|
30341
|
+
facilityTitle: 'Gæsteparkering',
|
|
30342
|
+
heroImage: '/Assets/Dummy-photos/parking.jpg',
|
|
30343
|
+
bookingDate: '20. marts',
|
|
30344
|
+
bookingTime: '8:00 - 20:00',
|
|
30345
|
+
price: '50 kr. per booking',
|
|
30346
|
+
canCancel: true,
|
|
30347
|
+
},
|
|
30348
|
+
'booking-3': {
|
|
30349
|
+
id: 'booking-3',
|
|
30350
|
+
facilityTitle: 'Boremaskinen',
|
|
30351
|
+
heroImage: '/Assets/Dummy-photos/handyman.jpg',
|
|
30352
|
+
bookingDate: '25. marts',
|
|
30353
|
+
bookingTime: '10:00 - 14:00',
|
|
30354
|
+
price: 'Gratis',
|
|
30355
|
+
canCancel: true,
|
|
30356
|
+
},
|
|
30357
|
+
};
|
|
30358
|
+
const VENDOR_DETAIL_MAP = {
|
|
30359
|
+
'v-1': {
|
|
30360
|
+
vendorName: 'CleanTeam ApS',
|
|
30361
|
+
vendorDescription: '<h3>Rengøring</h3><p>CleanTeam ApS tilbyder professionel trappevask og vinduespolering for ejendommen. Servicen udføres ugentligt og kan tilpasses jeres behov.</p><h3>Pris</h3><p>350 kr. per besøg</p>',
|
|
30362
|
+
vendorImage: '/Assets/Dummy-photos/clean-team.jpg',
|
|
30363
|
+
vendorLogo: '/Assets/dummy-logos/cleanteam-logo.svg',
|
|
30364
|
+
},
|
|
30365
|
+
'v-2': {
|
|
30366
|
+
vendorName: 'Nordisk Rengøring',
|
|
30367
|
+
vendorDescription: '<h3>Rengøring</h3><p>Nordisk Rengøring leverer fleksibel erhvervs- og boligrengøring. Vi tilpasser rengøringen til jeres specifikke behov.</p><h3>Pris</h3><p>275 kr. per time</p>',
|
|
30368
|
+
vendorImage: '/Assets/Dummy-photos/nordic-cleaning.jpg',
|
|
30369
|
+
vendorLogo: '/Assets/dummy-logos/nordiccleaning-logo.svg',
|
|
30370
|
+
},
|
|
30371
|
+
'v-3': {
|
|
30372
|
+
vendorName: 'Blik Partner A/S',
|
|
30373
|
+
vendorDescription: '<h3>VVS</h3><p>BlikPartner A/S er jeres VVS-partner til alt fra løbende vedligeholdelse til akutte udkald. Vi dækker reparation af vandrør, afløb, radiatorer og blandingsbatterier.</p><h3>Pris</h3><p>450 kr. per udkald + tid</p>',
|
|
30374
|
+
vendorImage: '/Assets/Dummy-photos/plumbing.jpg',
|
|
30375
|
+
},
|
|
30376
|
+
'v-4': {
|
|
30377
|
+
vendorName: 'ElektroTek ApS',
|
|
30378
|
+
vendorDescription: '<h3>Elektriker</h3><p>ElektroTek ApS varetager el-installationer, fejlsøgning og lovpligtige eftersyn for ejendommen. Vi udfører også småopgaver som udskiftning af kontakter og lampeudtag.</p><h3>Pris</h3><p>395 kr. per time</p>',
|
|
30379
|
+
vendorImage: '/Assets/Dummy-photos/electrician.jpg',
|
|
30380
|
+
vendorLogo: '/Assets/dummy-logos/electrician-logo.svg',
|
|
30381
|
+
},
|
|
30382
|
+
'v-5': {
|
|
30383
|
+
vendorName: 'HaveService Danmark',
|
|
30384
|
+
vendorDescription: '<h3>Have & Grønne arealer</h3><p>HaveService Danmark står for den løbende pleje af fællesarealer og haver — herunder græsslåning, hækklipning, ukrudtsbekæmpelse og sæsonbeplantning.</p><h3>Pris</h3><p>500 kr. per besøg</p>',
|
|
30385
|
+
vendorImage: '/Assets/Dummy-photos/gardener.jpg',
|
|
30386
|
+
vendorLogo: '/Assets/dummy-logos/gardener-logo.svg',
|
|
30387
|
+
},
|
|
30388
|
+
};
|
|
30389
|
+
class DsMobileNotificationModalService extends BaseModalService {
|
|
30390
|
+
router = inject(Router);
|
|
30391
|
+
notificationService = inject(NotificationService);
|
|
30392
|
+
postsService = inject(PostsService);
|
|
30393
|
+
userService = inject(UserService);
|
|
30394
|
+
postModal = inject(DsMobilePostDetailModalService);
|
|
30395
|
+
peerMessaging = inject(PeerMessagingService);
|
|
30396
|
+
peerChat = inject(PeerChatLauncherService);
|
|
30397
|
+
bookingDetailSheet = inject(DsMobileBookingDetailSheetService);
|
|
30398
|
+
vendorModal = inject(VENDOR_MODAL_SERVICE, { optional: true });
|
|
30399
|
+
constructor(modalController) {
|
|
30400
|
+
super(modalController);
|
|
30401
|
+
}
|
|
30402
|
+
/**
|
|
30403
|
+
* Open the notification modal. The modal reads notifications reactively
|
|
30404
|
+
* from NotificationService, so it updates live when items are marked
|
|
30405
|
+
* read or removed via long-press actions.
|
|
30406
|
+
*
|
|
30407
|
+
* Returns the tapped notification (if the user navigated to one), or null.
|
|
30408
|
+
*/
|
|
30409
|
+
async open() {
|
|
30410
|
+
const modal = await this.createModal(DsMobileNotificationModalComponent, {});
|
|
30411
|
+
await modal.present();
|
|
30412
|
+
const result = await modal.onWillDismiss();
|
|
30413
|
+
const tapped = result.data ?? null;
|
|
30414
|
+
if (tapped) {
|
|
30415
|
+
this.notificationService.markAsRead(tapped.id);
|
|
30416
|
+
await this.routeTo(tapped);
|
|
30417
|
+
}
|
|
30418
|
+
return tapped;
|
|
30419
|
+
}
|
|
30420
|
+
/**
|
|
30421
|
+
* Navigate to the screen associated with a notification item.
|
|
30422
|
+
* Public so downstream devs can call it from a Capacitor
|
|
30423
|
+
* `pushNotificationActionPerformed` listener for deep-link handling.
|
|
30424
|
+
*/
|
|
30425
|
+
async routeTo(item) {
|
|
30426
|
+
const id = item.targetId;
|
|
30427
|
+
switch (item.type) {
|
|
30428
|
+
case 'inquiry_update':
|
|
30429
|
+
case 'inquiry_assigned':
|
|
30430
|
+
case 'inquiry_resolved':
|
|
30431
|
+
await this.router.navigate(['/inquiry-detail', id ?? '1']);
|
|
30432
|
+
break;
|
|
30433
|
+
case 'community_post':
|
|
30434
|
+
case 'community_comment':
|
|
30435
|
+
case 'community_like':
|
|
30436
|
+
case 'community_mention':
|
|
30437
|
+
if (id) {
|
|
30438
|
+
await this.openPostModal(id);
|
|
30439
|
+
}
|
|
30440
|
+
else {
|
|
30441
|
+
await this.router.navigate(['/announcements']);
|
|
30442
|
+
}
|
|
30443
|
+
break;
|
|
30444
|
+
case 'booking_confirmed':
|
|
30445
|
+
case 'booking_cancelled':
|
|
30446
|
+
case 'booking_reminder':
|
|
30447
|
+
case 'facility_available':
|
|
30448
|
+
if (id) {
|
|
30449
|
+
await this.openBookingDetail(item);
|
|
30450
|
+
}
|
|
30451
|
+
else {
|
|
30452
|
+
await this.router.navigate(['/booking']);
|
|
30453
|
+
}
|
|
30454
|
+
break;
|
|
30455
|
+
case 'message_new':
|
|
30456
|
+
case 'message_group':
|
|
30457
|
+
if (id) {
|
|
30458
|
+
await this.openChat(id);
|
|
30459
|
+
}
|
|
30460
|
+
else {
|
|
30461
|
+
await this.router.navigate(['/messages']);
|
|
30462
|
+
}
|
|
30463
|
+
break;
|
|
30464
|
+
case 'service_update':
|
|
30465
|
+
if (id) {
|
|
30466
|
+
await this.openVendorModal(id);
|
|
30467
|
+
}
|
|
30468
|
+
else {
|
|
30469
|
+
await this.router.navigate(['/services']);
|
|
30470
|
+
}
|
|
30471
|
+
break;
|
|
30472
|
+
case 'handbook_update':
|
|
30473
|
+
await this.router.navigate(['/handbook']);
|
|
30474
|
+
break;
|
|
30475
|
+
case 'family_access':
|
|
30476
|
+
await this.router.navigate(['/family-access']);
|
|
30477
|
+
break;
|
|
30478
|
+
default:
|
|
30479
|
+
await this.router.navigate(['/home']);
|
|
30480
|
+
break;
|
|
30481
|
+
}
|
|
30482
|
+
}
|
|
30483
|
+
async openChat(conversationId) {
|
|
30484
|
+
const conv = this.peerMessaging.conversations().find(c => c.id === conversationId);
|
|
30485
|
+
if (conv) {
|
|
30486
|
+
await this.peerChat.openConversation(conv);
|
|
30487
|
+
}
|
|
30488
|
+
else {
|
|
30489
|
+
await this.router.navigate(['/messages']);
|
|
30490
|
+
}
|
|
30491
|
+
}
|
|
30492
|
+
async openVendorModal(vendorId) {
|
|
30493
|
+
const vendor = VENDOR_DETAIL_MAP[vendorId];
|
|
30494
|
+
if (vendor && this.vendorModal) {
|
|
30495
|
+
await this.vendorModal.open(vendor);
|
|
30496
|
+
}
|
|
30497
|
+
else {
|
|
30498
|
+
await this.router.navigate(['/services']);
|
|
30499
|
+
}
|
|
30500
|
+
}
|
|
30501
|
+
async openBookingDetail(item) {
|
|
30502
|
+
const booking = BOOKING_DETAIL_MAP[item.targetId];
|
|
30503
|
+
if (booking) {
|
|
30504
|
+
await this.bookingDetailSheet.openAsModal(booking);
|
|
30505
|
+
}
|
|
30506
|
+
else {
|
|
30507
|
+
await this.router.navigate(['/booking']);
|
|
30508
|
+
}
|
|
30509
|
+
}
|
|
30510
|
+
async openPostModal(postId) {
|
|
30511
|
+
const post = this.postsService.getPostById(postId);
|
|
30512
|
+
if (!post) {
|
|
30513
|
+
await this.router.navigate(['/announcements']);
|
|
30514
|
+
return;
|
|
30515
|
+
}
|
|
30516
|
+
const data = {
|
|
30517
|
+
postId: post.id,
|
|
30518
|
+
authorName: post.authorName,
|
|
30519
|
+
authorRole: post.authorRole,
|
|
30520
|
+
timestamp: post.timestamp,
|
|
30521
|
+
content: post.content,
|
|
30522
|
+
avatarInitials: post.avatarInitials,
|
|
30523
|
+
avatarType: post.avatarType === 'icon' ? undefined : post.avatarType,
|
|
30524
|
+
avatarSrc: post.avatarSrc,
|
|
30525
|
+
imageSrc: post.imageSrc,
|
|
30526
|
+
imageAlt: post.imageAlt,
|
|
30527
|
+
isLiked: post.isLiked,
|
|
30528
|
+
likeCount: post.likeCount,
|
|
30529
|
+
commentCount: post.commentCount,
|
|
30530
|
+
comments: post.comments,
|
|
30531
|
+
};
|
|
30532
|
+
await this.postModal.open(data, {
|
|
30533
|
+
currentUserName: this.userService.displayName(),
|
|
30534
|
+
currentUserInitials: this.userService.avatarInitials(),
|
|
30535
|
+
});
|
|
30536
|
+
}
|
|
30537
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileNotificationModalService, deps: [{ token: i1.ModalController }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
30538
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileNotificationModalService, providedIn: 'root' });
|
|
30539
|
+
}
|
|
30540
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileNotificationModalService, decorators: [{
|
|
30541
|
+
type: Injectable,
|
|
30542
|
+
args: [{
|
|
30543
|
+
providedIn: 'root',
|
|
30544
|
+
}]
|
|
30545
|
+
}], ctorParameters: () => [{ type: i1.ModalController }] });
|
|
30546
|
+
|
|
30547
|
+
// Mobile Page Components
|
|
30548
|
+
|
|
29154
30549
|
class MobileCommunityPageComponent {
|
|
29155
30550
|
router;
|
|
29156
30551
|
route;
|
|
@@ -29161,6 +30556,8 @@ class MobileCommunityPageComponent {
|
|
|
29161
30556
|
postsService;
|
|
29162
30557
|
pageComponent;
|
|
29163
30558
|
pinnedSwiper;
|
|
30559
|
+
notificationModal = inject(DsMobileNotificationModalService);
|
|
30560
|
+
notificationService = inject(NotificationService);
|
|
29164
30561
|
// Get posts from service (using computed for safe initialization)
|
|
29165
30562
|
allPosts = computed(() => this.postsService.posts(), ...(ngDevMode ? [{ debugName: "allPosts" }] : []));
|
|
29166
30563
|
// Get pinned posts - filter by isPinned flag
|
|
@@ -29203,6 +30600,11 @@ class MobileCommunityPageComponent {
|
|
|
29203
30600
|
// Complete the infinite scroll
|
|
29204
30601
|
event.target.complete();
|
|
29205
30602
|
}
|
|
30603
|
+
async handleNotificationClick() {
|
|
30604
|
+
const tapped = await this.notificationModal.open();
|
|
30605
|
+
if (tapped)
|
|
30606
|
+
console.log('Notification tapped:', tapped.type, tapped.id);
|
|
30607
|
+
}
|
|
29206
30608
|
handleRefresh(event) {
|
|
29207
30609
|
console.log('Pull-to-refresh triggered');
|
|
29208
30610
|
// Check if offline and complete immediately
|
|
@@ -29444,8 +30846,10 @@ class MobileCommunityPageComponent {
|
|
|
29444
30846
|
<ds-mobile-page-main
|
|
29445
30847
|
#pageComponent
|
|
29446
30848
|
title="Fællesskab"
|
|
30849
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
29447
30850
|
[avatarInitials]="userService.avatarInitials()"
|
|
29448
30851
|
[avatarType]="userService.avatarType()"
|
|
30852
|
+
(notificationClick)="handleNotificationClick()"
|
|
29449
30853
|
(refresh)="handleRefresh($event)">
|
|
29450
30854
|
|
|
29451
30855
|
<!-- Offline indicator -->
|
|
@@ -29698,7 +31102,7 @@ class MobileCommunityPageComponent {
|
|
|
29698
31102
|
}
|
|
29699
31103
|
</ds-mobile-section>
|
|
29700
31104
|
</ds-mobile-page-main>
|
|
29701
|
-
`, isInline: true, styles: [".pinned-posts-swiper-wrapper{padding:0;position:relative}.swiper-nav-buttons{display:contents}.swiper-nav-button{position:absolute;top:50%;transform:translateY(-50%);z-index:10}.swiper-nav-button:first-child{left:-48px}.swiper-nav-button:last-child{right:-48px}::ng-deep .swiper-nav-button button{border-radius:50%!important;width:48px!important;height:48px!important;padding:0!important}@media (max-width: 767px){.swiper-nav-buttons{display:none}}::ng-deep .pinned-posts-swiper .swiper-slide{width:100%;max-width:600px;height:auto}@media (min-width: 768px){::ng-deep .pinned-posts-swiper .swiper-slide{max-width:100%}}.swiper-post-item{width:100%;height:auto}::ng-deep .pinned-posts-swiper .swiper-slide ds-mobile-interactive-list-item-post{height:auto}::ng-deep .pinned-posts-swiper .swiper-wrapper{height:auto;align-items:flex-start}.post-list-wrapper{display:flex;flex-direction:column}.clickable-image{cursor:pointer;transition:transform .2s ease,opacity .2s ease;border-radius:8px;display:block;width:100%;aspect-ratio:16/9;object-fit:cover}.clickable-image:active{transform:scale(.98);opacity:.9}.community-empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;text-align:center}.empty-state-image{width:96px;height:96px;margin-bottom:24px}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;color:var(--color-text-primary);margin:16px 0 8px}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);color:var(--color-text-secondary);margin:0}ion-infinite-scroll{--color: var(--color-primary-surface)}ion-infinite-scroll-content{--color: var(--color-primary-surface)}ion-infinite-scroll-content::part(spinner){color:var(--color-primary-surface)}\n"], dependencies: [{ kind: "component", type: DsMobilePageMainComponent, selector: "ds-mobile-page-main", inputs: ["title", "headerTitle", "headerSubtitle", "firstEntry", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileInteractiveListItemPostComponent, selector: "ds-mobile-interactive-list-item-post", inputs: ["authorName", "authorRole", "timestamp", "avatarInitials", "avatarType", "avatarSrc", "avatarIconName", "showBadge", "variant", "align", "clickable", "enableLongPress", "moreActions"], outputs: ["postClick", "commentClick", "longPress"] }, { kind: "component", type: DsMobilePostComposerComponent, selector: "ds-mobile-post-composer", inputs: ["avatarInitials", "avatarType", "avatarSrc", "avatarIconName", "placeholder", "buttonText"], outputs: ["composerClick"] }, { kind: "component", type: DsMobileSwiperComponent, selector: "ds-mobile-swiper", inputs: ["slideWidth", "gap", "pagination", "autoHeight", "progressiveOpacity", "progressiveScale"] }, { kind: "component", type: PostContentComponent, selector: "post-content" }, { kind: "component", type: PostTextComponent, selector: "post-text" }, { kind: "component", type: PostMediaComponent, selector: "post-media" }, { kind: "component", type: PostAttachmentsComponent, selector: "post-attachments" }, { kind: "component", type: PostActionsComponent, selector: "post-actions" }, { kind: "component", type: ActionLikeComponent, selector: "action-like", inputs: ["active", "count"], outputs: ["activeChange", "countChange", "likeClick"] }, { kind: "component", type: ActionCommentComponent, selector: "action-comment", inputs: ["count"], outputs: ["commentClick"] }, { kind: "component", type: DsMobileCardInlineFileComponent, selector: "ds-mobile-card-inline-file", inputs: ["fileName", "fileSize", "variant", "layout", "fileUrl"], outputs: ["fileClick"] }, { kind: "component", type: DsIconButtonComponent, selector: "ds-icon-button", inputs: ["variant", "size", "icon", "disabled", "loading", "pressed", "expanded", "ariaLabel", "tooltip", "tooltipDisabled", "tooltipPlacement"], outputs: ["clicked", "focused", "blurred"] }, { kind: "component", type: DsMobileInlinePhotoComponent, selector: "ds-mobile-inline-photo", inputs: ["images", "loadingStates", "author", "maxVisible", "useGrid"], outputs: ["photoClick"] }, { kind: "component", type: DsMobileOfflineBannerComponent, selector: "ds-mobile-offline-banner", inputs: ["icon", "title", "message"] }, { kind: "component", type: IonInfiniteScroll, selector: "ion-infinite-scroll", inputs: ["disabled", "position", "threshold"] }, { kind: "component", type: IonInfiniteScrollContent, selector: "ion-infinite-scroll-content", inputs: ["loadingSpinner", "loadingText"] }] });
|
|
31105
|
+
`, isInline: true, styles: [".pinned-posts-swiper-wrapper{padding:0;position:relative}.swiper-nav-buttons{display:contents}.swiper-nav-button{position:absolute;top:50%;transform:translateY(-50%);z-index:10}.swiper-nav-button:first-child{left:-48px}.swiper-nav-button:last-child{right:-48px}::ng-deep .swiper-nav-button button{border-radius:50%!important;width:48px!important;height:48px!important;padding:0!important}@media (max-width: 767px){.swiper-nav-buttons{display:none}}::ng-deep .pinned-posts-swiper .swiper-slide{width:100%;max-width:600px;height:auto}@media (min-width: 768px){::ng-deep .pinned-posts-swiper .swiper-slide{max-width:100%}}.swiper-post-item{width:100%;height:auto}::ng-deep .pinned-posts-swiper .swiper-slide ds-mobile-interactive-list-item-post{height:auto}::ng-deep .pinned-posts-swiper .swiper-wrapper{height:auto;align-items:flex-start}.post-list-wrapper{display:flex;flex-direction:column}.clickable-image{cursor:pointer;transition:transform .2s ease,opacity .2s ease;border-radius:8px;display:block;width:100%;aspect-ratio:16/9;object-fit:cover}.clickable-image:active{transform:scale(.98);opacity:.9}.community-empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;text-align:center}.empty-state-image{width:96px;height:96px;margin-bottom:24px}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;color:var(--color-text-primary);margin:16px 0 8px}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);color:var(--color-text-secondary);margin:0}ion-infinite-scroll{--color: var(--color-primary-surface)}ion-infinite-scroll-content{--color: var(--color-primary-surface)}ion-infinite-scroll-content::part(spinner){color:var(--color-primary-surface)}\n"], dependencies: [{ kind: "component", type: DsMobilePageMainComponent, selector: "ds-mobile-page-main", inputs: ["title", "headerTitle", "headerSubtitle", "firstEntry", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "notificationCount", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["notificationClick", "avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileInteractiveListItemPostComponent, selector: "ds-mobile-interactive-list-item-post", inputs: ["authorName", "authorRole", "timestamp", "avatarInitials", "avatarType", "avatarSrc", "avatarIconName", "showBadge", "variant", "align", "clickable", "enableLongPress", "moreActions"], outputs: ["postClick", "commentClick", "longPress"] }, { kind: "component", type: DsMobilePostComposerComponent, selector: "ds-mobile-post-composer", inputs: ["avatarInitials", "avatarType", "avatarSrc", "avatarIconName", "placeholder", "buttonText"], outputs: ["composerClick"] }, { kind: "component", type: DsMobileSwiperComponent, selector: "ds-mobile-swiper", inputs: ["slideWidth", "gap", "pagination", "autoHeight", "progressiveOpacity", "progressiveScale"] }, { kind: "component", type: PostContentComponent, selector: "post-content" }, { kind: "component", type: PostTextComponent, selector: "post-text" }, { kind: "component", type: PostMediaComponent, selector: "post-media" }, { kind: "component", type: PostAttachmentsComponent, selector: "post-attachments" }, { kind: "component", type: PostActionsComponent, selector: "post-actions" }, { kind: "component", type: ActionLikeComponent, selector: "action-like", inputs: ["active", "count"], outputs: ["activeChange", "countChange", "likeClick"] }, { kind: "component", type: ActionCommentComponent, selector: "action-comment", inputs: ["count"], outputs: ["commentClick"] }, { kind: "component", type: DsMobileCardInlineFileComponent, selector: "ds-mobile-card-inline-file", inputs: ["fileName", "fileSize", "variant", "layout", "fileUrl"], outputs: ["fileClick"] }, { kind: "component", type: DsIconButtonComponent, selector: "ds-icon-button", inputs: ["variant", "size", "icon", "disabled", "loading", "pressed", "expanded", "ariaLabel", "tooltip", "tooltipDisabled", "tooltipPlacement"], outputs: ["clicked", "focused", "blurred"] }, { kind: "component", type: DsMobileInlinePhotoComponent, selector: "ds-mobile-inline-photo", inputs: ["images", "loadingStates", "author", "maxVisible", "useGrid"], outputs: ["photoClick"] }, { kind: "component", type: DsMobileOfflineBannerComponent, selector: "ds-mobile-offline-banner", inputs: ["icon", "title", "message"] }, { kind: "component", type: IonInfiniteScroll, selector: "ion-infinite-scroll", inputs: ["disabled", "position", "threshold"] }, { kind: "component", type: IonInfiniteScrollContent, selector: "ion-infinite-scroll-content", inputs: ["loadingSpinner", "loadingText"] }] });
|
|
29702
31106
|
}
|
|
29703
31107
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MobileCommunityPageComponent, decorators: [{
|
|
29704
31108
|
type: Component,
|
|
@@ -29725,8 +31129,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
29725
31129
|
<ds-mobile-page-main
|
|
29726
31130
|
#pageComponent
|
|
29727
31131
|
title="Fællesskab"
|
|
31132
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
29728
31133
|
[avatarInitials]="userService.avatarInitials()"
|
|
29729
31134
|
[avatarType]="userService.avatarType()"
|
|
31135
|
+
(notificationClick)="handleNotificationClick()"
|
|
29730
31136
|
(refresh)="handleRefresh($event)">
|
|
29731
31137
|
|
|
29732
31138
|
<!-- Offline indicator -->
|
|
@@ -29991,6 +31397,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
29991
31397
|
class MobileHandbookPageComponent {
|
|
29992
31398
|
userService;
|
|
29993
31399
|
pageComponent;
|
|
31400
|
+
notificationModal = inject(DsMobileNotificationModalService);
|
|
31401
|
+
notificationService = inject(NotificationService);
|
|
29994
31402
|
// Utilities folder data
|
|
29995
31403
|
utilitiesItems = [
|
|
29996
31404
|
{
|
|
@@ -30233,6 +31641,11 @@ class MobileHandbookPageComponent {
|
|
|
30233
31641
|
constructor(userService) {
|
|
30234
31642
|
this.userService = userService;
|
|
30235
31643
|
}
|
|
31644
|
+
async handleNotificationClick() {
|
|
31645
|
+
const tapped = await this.notificationModal.open();
|
|
31646
|
+
if (tapped)
|
|
31647
|
+
console.log('Notification tapped:', tapped.type, tapped.id);
|
|
31648
|
+
}
|
|
30236
31649
|
handleRefresh(event) {
|
|
30237
31650
|
console.log('Pull-to-refresh triggered');
|
|
30238
31651
|
// Check if offline and complete immediately
|
|
@@ -30248,7 +31661,7 @@ class MobileHandbookPageComponent {
|
|
|
30248
31661
|
}
|
|
30249
31662
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MobileHandbookPageComponent, deps: [{ token: UserService }], target: i0.ɵɵFactoryTarget.Component });
|
|
30250
31663
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: MobileHandbookPageComponent, isStandalone: true, selector: "app-mobile-handbook-page", viewQueries: [{ propertyName: "pageComponent", first: true, predicate: ["pageComponent"], descendants: true }], ngImport: i0, template: `
|
|
30251
|
-
<ds-mobile-page-main #pageComponent title="Håndbog" [avatarInitials]="userService.avatarInitials()" [avatarType]="userService.avatarType()" (refresh)="handleRefresh($event)">
|
|
31664
|
+
<ds-mobile-page-main #pageComponent title="Håndbog" [notificationCount]="notificationService.unreadCount()" [avatarInitials]="userService.avatarInitials()" [avatarType]="userService.avatarType()" (notificationClick)="handleNotificationClick()" (refresh)="handleRefresh($event)">
|
|
30252
31665
|
<!-- Offline indicator -->
|
|
30253
31666
|
@if (pageComponent.isOffline()) {
|
|
30254
31667
|
<ds-mobile-offline-banner offline-indicator title="Ingen internetforbindelse" message="Nogle funktioner kan være utilgængelige"> </ds-mobile-offline-banner>
|
|
@@ -30269,12 +31682,12 @@ class MobileHandbookPageComponent {
|
|
|
30269
31682
|
</div>
|
|
30270
31683
|
</ds-mobile-section>
|
|
30271
31684
|
</ds-mobile-page-main>
|
|
30272
|
-
`, isInline: true, styles: [".folders-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:20px;justify-items:center}@media (min-width: 768px){.folders-grid{grid-template-columns:repeat(3,1fr)}}ds-mobile-handbook-folder{width:100%;min-width:0}\n"], dependencies: [{ kind: "component", type: DsMobilePageMainComponent, selector: "ds-mobile-page-main", inputs: ["title", "headerTitle", "headerSubtitle", "firstEntry", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileHandbookFolderComponent, selector: "ds-mobile-handbook-folder", inputs: ["variant", "customColor", "iconName", "itemCount", "label", "items", "loading", "error"] }, { kind: "component", type: DsMobileOfflineBannerComponent, selector: "ds-mobile-offline-banner", inputs: ["icon", "title", "message"] }] });
|
|
31685
|
+
`, isInline: true, styles: [".folders-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:20px;justify-items:center}@media (min-width: 768px){.folders-grid{grid-template-columns:repeat(3,1fr)}}ds-mobile-handbook-folder{width:100%;min-width:0}\n"], dependencies: [{ kind: "component", type: DsMobilePageMainComponent, selector: "ds-mobile-page-main", inputs: ["title", "headerTitle", "headerSubtitle", "firstEntry", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "notificationCount", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["notificationClick", "avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileHandbookFolderComponent, selector: "ds-mobile-handbook-folder", inputs: ["variant", "customColor", "iconName", "itemCount", "label", "items", "loading", "error"] }, { kind: "component", type: DsMobileOfflineBannerComponent, selector: "ds-mobile-offline-banner", inputs: ["icon", "title", "message"] }] });
|
|
30273
31686
|
}
|
|
30274
31687
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MobileHandbookPageComponent, decorators: [{
|
|
30275
31688
|
type: Component,
|
|
30276
31689
|
args: [{ selector: 'app-mobile-handbook-page', standalone: true, imports: [DsMobilePageMainComponent, DsMobileSectionComponent, DsMobileHandbookFolderComponent, DsMobileOfflineBannerComponent], template: `
|
|
30277
|
-
<ds-mobile-page-main #pageComponent title="Håndbog" [avatarInitials]="userService.avatarInitials()" [avatarType]="userService.avatarType()" (refresh)="handleRefresh($event)">
|
|
31690
|
+
<ds-mobile-page-main #pageComponent title="Håndbog" [notificationCount]="notificationService.unreadCount()" [avatarInitials]="userService.avatarInitials()" [avatarType]="userService.avatarType()" (notificationClick)="handleNotificationClick()" (refresh)="handleRefresh($event)">
|
|
30278
31691
|
<!-- Offline indicator -->
|
|
30279
31692
|
@if (pageComponent.isOffline()) {
|
|
30280
31693
|
<ds-mobile-offline-banner offline-indicator title="Ingen internetforbindelse" message="Nogle funktioner kan være utilgængelige"> </ds-mobile-offline-banner>
|
|
@@ -30866,6 +32279,8 @@ class MobileHomePageComponent {
|
|
|
30866
32279
|
modalCtrl = inject(ModalController);
|
|
30867
32280
|
vendorModal = inject(DsMobileServiceVendorModalService);
|
|
30868
32281
|
newInquiryModal = inject(DsMobileNewInquiryModalService);
|
|
32282
|
+
notificationModal = inject(DsMobileNotificationModalService);
|
|
32283
|
+
notificationService = inject(NotificationService);
|
|
30869
32284
|
constructor(router, navCtrl, userService, postsService, postModal, trackingPermissionService, bottomSheet, familyAccessService, peerMessaging, peerChat, lightboxService) {
|
|
30870
32285
|
this.router = router;
|
|
30871
32286
|
this.navCtrl = navCtrl;
|
|
@@ -30893,6 +32308,11 @@ class MobileHomePageComponent {
|
|
|
30893
32308
|
}, delayMs);
|
|
30894
32309
|
});
|
|
30895
32310
|
}
|
|
32311
|
+
async handleNotificationClick() {
|
|
32312
|
+
const tapped = await this.notificationModal.open();
|
|
32313
|
+
if (tapped)
|
|
32314
|
+
console.log('Notification tapped:', tapped.type, tapped.id);
|
|
32315
|
+
}
|
|
30896
32316
|
handleRefresh(event) {
|
|
30897
32317
|
console.log('Pull-to-refresh triggered');
|
|
30898
32318
|
setTimeout(() => {
|
|
@@ -31037,8 +32457,10 @@ class MobileHomePageComponent {
|
|
|
31037
32457
|
#pageComponent
|
|
31038
32458
|
title="Hjem"
|
|
31039
32459
|
headerTitle="Velkommen, Lars"
|
|
32460
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
31040
32461
|
[avatarInitials]="userService.avatarInitials()"
|
|
31041
32462
|
[avatarType]="userService.avatarType()"
|
|
32463
|
+
(notificationClick)="handleNotificationClick()"
|
|
31042
32464
|
(refresh)="handleRefresh($event)"
|
|
31043
32465
|
>
|
|
31044
32466
|
|
|
@@ -31241,7 +32663,7 @@ class MobileHomePageComponent {
|
|
|
31241
32663
|
</ds-mobile-page-main>
|
|
31242
32664
|
} <!-- end @if (!isCoveringScreen()) -->
|
|
31243
32665
|
|
|
31244
|
-
`, isInline: true, styles: [".posts-list,.messages-preview-list{display:flex;flex-direction:column}.property-banner-nav{display:block;width:100%;border-radius:12px;cursor:pointer;-webkit-tap-highlight-color:transparent}.property-banner-nav:focus-visible{outline:2px solid var(--color-accent, #6B5FF5);outline-offset:2px}.inquiries-list,.services-preview-list{display:flex;flex-direction:column}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:20px;text-align:center}.empty-state ds-button{display:block;margin-top:16px}.empty-state ds-button::ng-deep .btn{width:100%;border-radius:9999px}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;color:var(--color-text-primary);margin-top:-16px;z-index:4}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);color:var(--color-text-secondary);margin:0}@keyframes slideDown{0%{transform:translateY(-100%);opacity:0}to{transform:translateY(0);opacity:1}}.welcome-toast{padding:10px 14px;border-radius:12px;background:var(--color-background-brand-secondary, #EEF0FF);display:flex;align-items:flex-start;gap:10px;font-size:14px;font-weight:500;color:var(--color-accent, #6B5FF5);animation:slideDown .2s ease-out}.toast-icon{width:20px;height:20px;border-radius:50%;background:var(--color-accent, #6B5FF5);display:flex;align-items:center;justify-content:center;flex-shrink:0;color:#fff;margin-top:1px}.welcome-toast-content{flex:1;display:flex;flex-direction:column;gap:2px}.welcome-toast-heading{font-family:Brockmann,sans-serif;font-size:14px;font-weight:600;color:var(--color-brand-content, #3B3691);margin:0}.welcome-toast-text{font-family:Brockmann,sans-serif;font-size:13px;line-height:1.4;color:var(--color-brand-content, #3B3691);margin:0;opacity:.8}.welcome-toast-text strong{font-weight:600;opacity:1}.toast-dismiss{margin-left:auto;background:none;border:none;cursor:pointer;flex-shrink:0;color:var(--color-accent, #6B5FF5);display:flex;align-items:center;justify-content:center}.home-content--animating{animation:homeReveal .3s var(--spring-curve-smooth) both}@keyframes homeReveal{0%{opacity:0;transform:translateY(128px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "component", type: DsButtonComponent, selector: "ds-button", inputs: ["variant", "size", "disabled", "loading", "pressed", "expanded", "leadingIcon", "trailingIcon", "ariaLabel", "iconOnly"], outputs: ["clicked", "focused", "blurred"] }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsMobilePageMainComponent, selector: "ds-mobile-page-main", inputs: ["title", "headerTitle", "headerSubtitle", "firstEntry", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileIllustrationComponent, selector: "ds-mobile-illustration", inputs: ["variant", "size", "alt"] }, { kind: "component", type: DsMobilePropertyBannerComponent, selector: "ds-mobile-property-banner", inputs: ["address", "photoUrl", "tenantCount"] }, { kind: "component", type: DsMobileInteractiveListItemPostComponent, selector: "ds-mobile-interactive-list-item-post", inputs: ["authorName", "authorRole", "timestamp", "avatarInitials", "avatarType", "avatarSrc", "avatarIconName", "showBadge", "variant", "align", "clickable", "enableLongPress", "moreActions"], outputs: ["postClick", "commentClick", "longPress"] }, { kind: "component", type: DsMobileInteractiveListItemInquiryComponent, selector: "ds-mobile-interactive-list-item-inquiry", inputs: ["title", "description", "status", "statusLabel", "timestamp", "iconName", "iconColor", "variant", "align", "clickable", "showChevron", "enableLongPress", "moreActions"], outputs: ["inquiryClick", "longPress"] }, { kind: "component", type: DsMobileInteractiveListItemMessageComponent, selector: "ds-mobile-interactive-list-item-message", inputs: ["senderName", "senderRole", "timestamp", "message", "avatarInitials", "avatarType", "avatarSrc", "unread", "unreadStyle", "clickable", "align", "showAvatarBadge", "groupStackMembers", "groupCustomAvatarUrl", "groupStackExcludeParticipantId"], outputs: ["messageClick", "longPress"] }, { kind: "component", type: DsMobileInteractiveListItemServiceComponent, selector: "ds-mobile-interactive-list-item-service", inputs: ["title", "description", "logo", "showChevron"], outputs: ["serviceClick"] }, { kind: "component", type: DsMobileOfflineBannerComponent, selector: "ds-mobile-offline-banner", inputs: ["icon", "title", "message"] }, { kind: "component", type: PostContentComponent, selector: "post-content" }, { kind: "component", type: PostTextComponent, selector: "post-text" }, { kind: "component", type: PostActionsComponent, selector: "post-actions" }, { kind: "component", type: ActionLikeComponent, selector: "action-like", inputs: ["active", "count"], outputs: ["activeChange", "countChange", "likeClick"] }, { kind: "component", type: ActionCommentComponent, selector: "action-comment", inputs: ["count"], outputs: ["commentClick"] }] });
|
|
32666
|
+
`, isInline: true, styles: [".posts-list,.messages-preview-list{display:flex;flex-direction:column}.property-banner-nav{display:block;width:100%;border-radius:12px;cursor:pointer;-webkit-tap-highlight-color:transparent}.property-banner-nav:focus-visible{outline:2px solid var(--color-accent, #6B5FF5);outline-offset:2px}.inquiries-list,.services-preview-list{display:flex;flex-direction:column}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:20px;text-align:center}.empty-state ds-button{display:block;margin-top:16px}.empty-state ds-button::ng-deep .btn{width:100%;border-radius:9999px}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;color:var(--color-text-primary);margin-top:-16px;z-index:4}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);color:var(--color-text-secondary);margin:0}@keyframes slideDown{0%{transform:translateY(-100%);opacity:0}to{transform:translateY(0);opacity:1}}.welcome-toast{padding:10px 14px;border-radius:12px;background:var(--color-background-brand-secondary, #EEF0FF);display:flex;align-items:flex-start;gap:10px;font-size:14px;font-weight:500;color:var(--color-accent, #6B5FF5);animation:slideDown .2s ease-out}.toast-icon{width:20px;height:20px;border-radius:50%;background:var(--color-accent, #6B5FF5);display:flex;align-items:center;justify-content:center;flex-shrink:0;color:#fff;margin-top:1px}.welcome-toast-content{flex:1;display:flex;flex-direction:column;gap:2px}.welcome-toast-heading{font-family:Brockmann,sans-serif;font-size:14px;font-weight:600;color:var(--color-brand-content, #3B3691);margin:0}.welcome-toast-text{font-family:Brockmann,sans-serif;font-size:13px;line-height:1.4;color:var(--color-brand-content, #3B3691);margin:0;opacity:.8}.welcome-toast-text strong{font-weight:600;opacity:1}.toast-dismiss{margin-left:auto;background:none;border:none;cursor:pointer;flex-shrink:0;color:var(--color-accent, #6B5FF5);display:flex;align-items:center;justify-content:center}.home-content--animating{animation:homeReveal .3s var(--spring-curve-smooth) both}@keyframes homeReveal{0%{opacity:0;transform:translateY(128px)}to{opacity:1;transform:translateY(0)}}\n"], dependencies: [{ kind: "component", type: DsButtonComponent, selector: "ds-button", inputs: ["variant", "size", "disabled", "loading", "pressed", "expanded", "leadingIcon", "trailingIcon", "ariaLabel", "iconOnly"], outputs: ["clicked", "focused", "blurred"] }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsMobilePageMainComponent, selector: "ds-mobile-page-main", inputs: ["title", "headerTitle", "headerSubtitle", "firstEntry", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "notificationCount", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["notificationClick", "avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileIllustrationComponent, selector: "ds-mobile-illustration", inputs: ["variant", "size", "alt"] }, { kind: "component", type: DsMobilePropertyBannerComponent, selector: "ds-mobile-property-banner", inputs: ["address", "photoUrl", "tenantCount"] }, { kind: "component", type: DsMobileInteractiveListItemPostComponent, selector: "ds-mobile-interactive-list-item-post", inputs: ["authorName", "authorRole", "timestamp", "avatarInitials", "avatarType", "avatarSrc", "avatarIconName", "showBadge", "variant", "align", "clickable", "enableLongPress", "moreActions"], outputs: ["postClick", "commentClick", "longPress"] }, { kind: "component", type: DsMobileInteractiveListItemInquiryComponent, selector: "ds-mobile-interactive-list-item-inquiry", inputs: ["title", "description", "status", "statusLabel", "timestamp", "iconName", "iconColor", "variant", "align", "clickable", "showChevron", "enableLongPress", "moreActions"], outputs: ["inquiryClick", "longPress"] }, { kind: "component", type: DsMobileInteractiveListItemMessageComponent, selector: "ds-mobile-interactive-list-item-message", inputs: ["senderName", "senderRole", "timestamp", "message", "avatarInitials", "avatarType", "avatarSrc", "unread", "unreadStyle", "clickable", "align", "showAvatarBadge", "groupStackMembers", "groupCustomAvatarUrl", "groupStackExcludeParticipantId"], outputs: ["messageClick", "longPress"] }, { kind: "component", type: DsMobileInteractiveListItemServiceComponent, selector: "ds-mobile-interactive-list-item-service", inputs: ["title", "description", "logo", "showChevron"], outputs: ["serviceClick"] }, { kind: "component", type: DsMobileOfflineBannerComponent, selector: "ds-mobile-offline-banner", inputs: ["icon", "title", "message"] }, { kind: "component", type: PostContentComponent, selector: "post-content" }, { kind: "component", type: PostTextComponent, selector: "post-text" }, { kind: "component", type: PostActionsComponent, selector: "post-actions" }, { kind: "component", type: ActionLikeComponent, selector: "action-like", inputs: ["active", "count"], outputs: ["activeChange", "countChange", "likeClick"] }, { kind: "component", type: ActionCommentComponent, selector: "action-comment", inputs: ["count"], outputs: ["commentClick"] }] });
|
|
31245
32667
|
}
|
|
31246
32668
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MobileHomePageComponent, decorators: [{
|
|
31247
32669
|
type: Component,
|
|
@@ -31255,7 +32677,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
31255
32677
|
DsMobileInteractiveListItemPostComponent,
|
|
31256
32678
|
DsMobileInteractiveListItemInquiryComponent,
|
|
31257
32679
|
DsMobileInteractiveListItemMessageComponent,
|
|
31258
|
-
DsMobileInteractiveListItemBookingComponent,
|
|
31259
32680
|
DsMobileInteractiveListItemServiceComponent,
|
|
31260
32681
|
DsMobileOfflineBannerComponent,
|
|
31261
32682
|
PostContentComponent,
|
|
@@ -31277,8 +32698,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
31277
32698
|
#pageComponent
|
|
31278
32699
|
title="Hjem"
|
|
31279
32700
|
headerTitle="Velkommen, Lars"
|
|
32701
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
31280
32702
|
[avatarInitials]="userService.avatarInitials()"
|
|
31281
32703
|
[avatarType]="userService.avatarType()"
|
|
32704
|
+
(notificationClick)="handleNotificationClick()"
|
|
31282
32705
|
(refresh)="handleRefresh($event)"
|
|
31283
32706
|
>
|
|
31284
32707
|
|
|
@@ -31493,6 +32916,8 @@ class MobileInquiriesPageComponent {
|
|
|
31493
32916
|
newInquiryModal;
|
|
31494
32917
|
pageComponent;
|
|
31495
32918
|
inquiriesService = inject(InquiriesService);
|
|
32919
|
+
notificationModal = inject(DsMobileNotificationModalService);
|
|
32920
|
+
notificationService = inject(NotificationService);
|
|
31496
32921
|
constructor(userService, navCtrl, newInquiryModal) {
|
|
31497
32922
|
this.userService = userService;
|
|
31498
32923
|
this.navCtrl = navCtrl;
|
|
@@ -31528,6 +32953,11 @@ class MobileInquiriesPageComponent {
|
|
|
31528
32953
|
console.log('Showing actions for inquiry:', inquiryId);
|
|
31529
32954
|
// Show bottom sheet with actions (edit, delete, etc.)
|
|
31530
32955
|
}
|
|
32956
|
+
async handleNotificationClick() {
|
|
32957
|
+
const tapped = await this.notificationModal.open();
|
|
32958
|
+
if (tapped)
|
|
32959
|
+
console.log('Notification tapped:', tapped.type, tapped.id);
|
|
32960
|
+
}
|
|
31531
32961
|
handleRefresh(event) {
|
|
31532
32962
|
console.log('Pull-to-refresh triggered on inquiries page');
|
|
31533
32963
|
// Check if offline and complete immediately
|
|
@@ -31567,8 +32997,10 @@ class MobileInquiriesPageComponent {
|
|
|
31567
32997
|
<ds-mobile-page-main
|
|
31568
32998
|
#pageComponent
|
|
31569
32999
|
title="Henvendelser"
|
|
33000
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
31570
33001
|
[avatarInitials]="userService.avatarInitials()"
|
|
31571
33002
|
[avatarType]="userService.avatarType()"
|
|
33003
|
+
(notificationClick)="handleNotificationClick()"
|
|
31572
33004
|
(refresh)="handleRefresh($event)">
|
|
31573
33005
|
|
|
31574
33006
|
<!-- Offline indicator -->
|
|
@@ -31632,7 +33064,7 @@ class MobileInquiriesPageComponent {
|
|
|
31632
33064
|
ariaLabel="Create new inquiry"
|
|
31633
33065
|
(clicked)="createNewInquiry()">
|
|
31634
33066
|
</ds-mobile-fab>
|
|
31635
|
-
`, isInline: true, styles: [".inquiry-list-wrapper{display:flex;flex-direction:column;margin-top:-12px}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;text-align:center}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;color:var(--color-text-primary);margin-top:-16px;z-index:4}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);color:var(--color-text-secondary);margin:0}\n"], dependencies: [{ kind: "component", type: DsMobilePageMainComponent, selector: "ds-mobile-page-main", inputs: ["title", "headerTitle", "headerSubtitle", "firstEntry", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileIllustrationComponent, selector: "ds-mobile-illustration", inputs: ["variant", "size", "alt"] }, { kind: "component", type: DsMobileInteractiveListItemInquiryComponent, selector: "ds-mobile-interactive-list-item-inquiry", inputs: ["title", "description", "status", "statusLabel", "timestamp", "iconName", "iconColor", "variant", "align", "clickable", "showChevron", "enableLongPress", "moreActions"], outputs: ["inquiryClick", "longPress"] }, { kind: "component", type: DsMobileInlineTabsComponent, selector: "ds-mobile-inline-tabs", inputs: ["tabs", "activeTab"], outputs: ["tabChange"] }, { kind: "component", type: DsMobileOfflineBannerComponent, selector: "ds-mobile-offline-banner", inputs: ["icon", "title", "message"] }, { kind: "component", type: DsMobileFabComponent, selector: "ds-mobile-fab", inputs: ["icon", "position", "size", "ariaLabel", "disabled"], outputs: ["clicked"] }] });
|
|
33067
|
+
`, isInline: true, styles: [".inquiry-list-wrapper{display:flex;flex-direction:column;margin-top:-12px}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;text-align:center}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;color:var(--color-text-primary);margin-top:-16px;z-index:4}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);color:var(--color-text-secondary);margin:0}\n"], dependencies: [{ kind: "component", type: DsMobilePageMainComponent, selector: "ds-mobile-page-main", inputs: ["title", "headerTitle", "headerSubtitle", "firstEntry", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "notificationCount", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["notificationClick", "avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileIllustrationComponent, selector: "ds-mobile-illustration", inputs: ["variant", "size", "alt"] }, { kind: "component", type: DsMobileInteractiveListItemInquiryComponent, selector: "ds-mobile-interactive-list-item-inquiry", inputs: ["title", "description", "status", "statusLabel", "timestamp", "iconName", "iconColor", "variant", "align", "clickable", "showChevron", "enableLongPress", "moreActions"], outputs: ["inquiryClick", "longPress"] }, { kind: "component", type: DsMobileInlineTabsComponent, selector: "ds-mobile-inline-tabs", inputs: ["tabs", "activeTab"], outputs: ["tabChange"] }, { kind: "component", type: DsMobileOfflineBannerComponent, selector: "ds-mobile-offline-banner", inputs: ["icon", "title", "message"] }, { kind: "component", type: DsMobileFabComponent, selector: "ds-mobile-fab", inputs: ["icon", "position", "size", "ariaLabel", "disabled"], outputs: ["clicked"] }] });
|
|
31636
33068
|
}
|
|
31637
33069
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MobileInquiriesPageComponent, decorators: [{
|
|
31638
33070
|
type: Component,
|
|
@@ -31650,8 +33082,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
31650
33082
|
<ds-mobile-page-main
|
|
31651
33083
|
#pageComponent
|
|
31652
33084
|
title="Henvendelser"
|
|
33085
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
31653
33086
|
[avatarInitials]="userService.avatarInitials()"
|
|
31654
33087
|
[avatarType]="userService.avatarType()"
|
|
33088
|
+
(notificationClick)="handleNotificationClick()"
|
|
31655
33089
|
(refresh)="handleRefresh($event)">
|
|
31656
33090
|
|
|
31657
33091
|
<!-- Offline indicator -->
|
|
@@ -32323,6 +33757,87 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
32323
33757
|
`, styles: [".activity-list{display:flex;flex-direction:column;gap:12px;position:relative}.activity-list ds-mobile-list-item:not(:last-child) [content-leading]:after{content:\"\";position:absolute;top:40px;left:50%;transform:translate(-50%);width:1px;height:calc(100% - 2px);background:var(--border-color-default, #e5e5e5);z-index:0}.activity-icon-wrapper{width:100%;height:100%;border-radius:8px;background:var(--color-background-neutral-secondary, #f5f5f5);display:flex;align-items:center;justify-content:center;flex-shrink:0;position:relative;z-index:1}.avatar-wrapper{position:relative;display:flex;align-items:start;justify-content:center;flex-shrink:0;width:100%;height:100%;z-index:1}.avatar-badge{position:absolute;bottom:-6px;right:-6px;width:20px;height:20px;border-radius:8px;background:var(--color-brand-secondary, #5d5fef);display:flex;align-items:center;justify-content:center;border:2px solid var(--color-background-primary, #ffffff)}.avatar-badge svg{width:10px;position:relative;top:1px;fill:#fff}.activity-content{display:flex;flex-direction:column;gap:4px}.activity-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;line-height:20px;letter-spacing:-.3px;color:var(--text-color-default-primary, #202227);margin:0}.activity-title .actor-name{font-weight:600;color:var(--text-color-default-primary, #202227)}.activity-title .activity-text{color:var(--text-color-default-secondary, #545B66);font-weight:400}.activity-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:400;line-height:20px;letter-spacing:-.3px;color:var(--text-color-default-secondary, #545B66);margin:0}.activity-timestamp{font-family:Brockmann,sans-serif;font-size:var(--font-size-xs);font-weight:400;line-height:1.2;letter-spacing:-.26px;color:var(--text-color-default-tertiary, #737373);display:flex;align-items:center;gap:4px;margin-top:2px}.detail-label{font-family:Brockmann,sans-serif;font-size:var(--font-size-xs);font-weight:400;line-height:1.2;letter-spacing:-.26px;color:var(--text-color-default-tertiary, #737373)}.detail-value{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:400;line-height:24px;letter-spacing:-.3px;color:var(--text-color-default-primary, #202227)}.detail-tag{display:inline-flex;align-items:center;padding:4px 12px;border-radius:12px;background:var(--color-background-neutral-secondary, #f5f5f5);font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;color:var(--text-color-default-secondary, #525866);margin-top:4px;margin-bottom:10px;width:-moz-fit-content;width:fit-content}.photo-grid{display:grid;grid-template-columns:repeat(6,1fr);gap:8px}.photo-add{width:100%;aspect-ratio:1;border-radius:12px;border:1px dashed var(--border-color-default, #e5e5e5);background:var(--color-background-neutral-secondary, #f5f5f5);display:flex;align-items:center;justify-content:center;cursor:pointer}.photo-item{width:100%;aspect-ratio:1;border-radius:12px;-o-object-fit:cover;object-fit:cover}.empty-messages{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;gap:12px}.empty-messages-image{width:96px;height:96px;-o-object-fit:contain;object-fit:contain}.empty-messages-text{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm, 14px);color:var(--text-color-default-secondary, #71727a);margin:0}\n"] }]
|
|
32324
33758
|
}], ctorParameters: () => [{ type: UserService }, { type: DsMobileLightboxService }, { type: DsMobileChatModalService }] });
|
|
32325
33759
|
|
|
33760
|
+
const STORAGE_KEY = 'ds-notification-prompt-dismissed';
|
|
33761
|
+
const COOLDOWN_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
33762
|
+
/**
|
|
33763
|
+
* Manages the notification permission prompt lifecycle.
|
|
33764
|
+
*
|
|
33765
|
+
* - Stores the user's "Not now" dismissal timestamp in localStorage
|
|
33766
|
+
* - Re-shows the prompt after a 24-hour cooldown
|
|
33767
|
+
* - Skips the prompt entirely if native permissions are already granted
|
|
33768
|
+
*
|
|
33769
|
+
* Downstream integration: call `checkPermissions()` before checking
|
|
33770
|
+
* `shouldShowPrompt()` to incorporate native permission status.
|
|
33771
|
+
*/
|
|
33772
|
+
class NotificationPromptService {
|
|
33773
|
+
permissionGranted = false;
|
|
33774
|
+
/**
|
|
33775
|
+
* Record that the user dismissed the prompt. Stores the current
|
|
33776
|
+
* timestamp so the prompt can be suppressed for 24 hours.
|
|
33777
|
+
*/
|
|
33778
|
+
dismiss() {
|
|
33779
|
+
try {
|
|
33780
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify({ dismissedAt: Date.now() }));
|
|
33781
|
+
}
|
|
33782
|
+
catch {
|
|
33783
|
+
// localStorage unavailable (SSR, private browsing quota)
|
|
33784
|
+
}
|
|
33785
|
+
}
|
|
33786
|
+
/**
|
|
33787
|
+
* Whether the prompt should be displayed right now.
|
|
33788
|
+
* Returns false if:
|
|
33789
|
+
* - Native permission is already granted
|
|
33790
|
+
* - The user dismissed less than 24 hours ago
|
|
33791
|
+
*/
|
|
33792
|
+
shouldShowPrompt() {
|
|
33793
|
+
if (this.permissionGranted)
|
|
33794
|
+
return false;
|
|
33795
|
+
try {
|
|
33796
|
+
const raw = localStorage.getItem(STORAGE_KEY);
|
|
33797
|
+
if (!raw)
|
|
33798
|
+
return true;
|
|
33799
|
+
const { dismissedAt } = JSON.parse(raw);
|
|
33800
|
+
return Date.now() - dismissedAt >= COOLDOWN_MS;
|
|
33801
|
+
}
|
|
33802
|
+
catch {
|
|
33803
|
+
return true;
|
|
33804
|
+
}
|
|
33805
|
+
}
|
|
33806
|
+
/**
|
|
33807
|
+
* Call this on app launch to check native notification permission status.
|
|
33808
|
+
* If already granted, the prompt will never be shown.
|
|
33809
|
+
*/
|
|
33810
|
+
async checkPermissions() {
|
|
33811
|
+
try {
|
|
33812
|
+
const { PushNotifications } = await import('@capacitor/push-notifications');
|
|
33813
|
+
const result = await PushNotifications.checkPermissions();
|
|
33814
|
+
this.permissionGranted = result.receive === 'granted';
|
|
33815
|
+
}
|
|
33816
|
+
catch {
|
|
33817
|
+
// Not on native — leave as false so the prompt can still show
|
|
33818
|
+
}
|
|
33819
|
+
}
|
|
33820
|
+
/**
|
|
33821
|
+
* Mark that the user has granted permission (called after a successful
|
|
33822
|
+
* allow flow so the prompt is permanently hidden for this session).
|
|
33823
|
+
*/
|
|
33824
|
+
markGranted() {
|
|
33825
|
+
this.permissionGranted = true;
|
|
33826
|
+
try {
|
|
33827
|
+
localStorage.removeItem(STORAGE_KEY);
|
|
33828
|
+
}
|
|
33829
|
+
catch {
|
|
33830
|
+
// noop
|
|
33831
|
+
}
|
|
33832
|
+
}
|
|
33833
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NotificationPromptService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
33834
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NotificationPromptService, providedIn: 'root' });
|
|
33835
|
+
}
|
|
33836
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NotificationPromptService, decorators: [{
|
|
33837
|
+
type: Injectable,
|
|
33838
|
+
args: [{ providedIn: 'root' }]
|
|
33839
|
+
}] });
|
|
33840
|
+
|
|
32326
33841
|
/**
|
|
32327
33842
|
* Whitelabel Demo Modal Component
|
|
32328
33843
|
*
|
|
@@ -33462,7 +34977,11 @@ class MobileTabsExampleComponent {
|
|
|
33462
34977
|
navCtrl;
|
|
33463
34978
|
whitelabelDemoModal = inject(WhitelabelDemoModalService);
|
|
33464
34979
|
trackingPermissionService = inject(TrackingPermissionService);
|
|
34980
|
+
notificationModal = inject(DsMobileNotificationModalService);
|
|
34981
|
+
notificationService = inject(NotificationService);
|
|
34982
|
+
notificationPrompt = inject(NotificationPromptService);
|
|
33465
34983
|
pageLoading = inject(PageLoadingService);
|
|
34984
|
+
showNotificationPrompt = signal(false, ...(ngDevMode ? [{ debugName: "showNotificationPrompt" }] : []));
|
|
33466
34985
|
trackedProfileMenuItems = computed(() => {
|
|
33467
34986
|
const accountActions = [
|
|
33468
34987
|
{
|
|
@@ -33542,15 +35061,15 @@ class MobileTabsExampleComponent {
|
|
|
33542
35061
|
this.userService.setProfileMenuItems(this.trackedProfileMenuItems());
|
|
33543
35062
|
});
|
|
33544
35063
|
}
|
|
33545
|
-
ngOnInit() {
|
|
35064
|
+
async ngOnInit() {
|
|
33546
35065
|
console.log('MobileTabsExampleComponent ngOnInit');
|
|
33547
|
-
// Configure user avatar globally - this is now the single source of truth
|
|
33548
35066
|
this.userService.setDisplayName('Lucas Møller');
|
|
33549
35067
|
this.userService.setAddress('Toftegårds Allé 5A, 3. tv.');
|
|
33550
35068
|
this.userService.setAvatarInitials('LM');
|
|
33551
35069
|
this.userService.setAvatarType('initials');
|
|
33552
|
-
// Initial status refresh ensures menu reflects past ATT choice.
|
|
33553
35070
|
void this.trackingPermissionService.refreshTrackingStatus();
|
|
35071
|
+
await this.notificationPrompt.checkPermissions();
|
|
35072
|
+
this.showNotificationPrompt.set(this.notificationPrompt.shouldShowPrompt());
|
|
33554
35073
|
}
|
|
33555
35074
|
tabs = [
|
|
33556
35075
|
{
|
|
@@ -33657,6 +35176,34 @@ class MobileTabsExampleComponent {
|
|
|
33657
35176
|
});
|
|
33658
35177
|
}
|
|
33659
35178
|
}
|
|
35179
|
+
async handleNotificationAllow() {
|
|
35180
|
+
console.log('Notification permission: requesting native dialog...');
|
|
35181
|
+
this.showNotificationPrompt.set(false);
|
|
35182
|
+
try {
|
|
35183
|
+
const { PushNotifications } = await import('@capacitor/push-notifications');
|
|
35184
|
+
const permission = await PushNotifications.requestPermissions();
|
|
35185
|
+
console.log('Push permission result:', permission.receive);
|
|
35186
|
+
if (permission.receive === 'granted') {
|
|
35187
|
+
await PushNotifications.register();
|
|
35188
|
+
this.notificationPrompt.markGranted();
|
|
35189
|
+
console.log('Push notifications registered');
|
|
35190
|
+
}
|
|
35191
|
+
}
|
|
35192
|
+
catch (err) {
|
|
35193
|
+
console.warn('Push notifications not available (web/simulator):', err);
|
|
35194
|
+
}
|
|
35195
|
+
}
|
|
35196
|
+
handleNotificationDismiss() {
|
|
35197
|
+
console.log('Notification permission: dismissed (24hr cooldown)');
|
|
35198
|
+
this.notificationPrompt.dismiss();
|
|
35199
|
+
this.showNotificationPrompt.set(false);
|
|
35200
|
+
}
|
|
35201
|
+
async handleNotificationClick() {
|
|
35202
|
+
const tapped = await this.notificationModal.open();
|
|
35203
|
+
if (tapped) {
|
|
35204
|
+
console.log('Notification tapped:', tapped.type, tapped.id);
|
|
35205
|
+
}
|
|
35206
|
+
}
|
|
33660
35207
|
/** Called by the error overlay retry button — clears error and re-navigates to home */
|
|
33661
35208
|
handleRetry() {
|
|
33662
35209
|
this.pageLoading.hasError.set(false);
|
|
@@ -33678,26 +35225,35 @@ class MobileTabsExampleComponent {
|
|
|
33678
35225
|
</div>
|
|
33679
35226
|
}
|
|
33680
35227
|
|
|
35228
|
+
<!-- Notification permission prompt (session-only, reappears on next launch) -->
|
|
35229
|
+
@if (showNotificationPrompt() && !pageLoading.isCoveringScreen()) {
|
|
35230
|
+
<ds-mobile-notification-prompt
|
|
35231
|
+
(allow)="handleNotificationAllow()"
|
|
35232
|
+
(dismiss)="handleNotificationDismiss()" />
|
|
35233
|
+
}
|
|
35234
|
+
|
|
33681
35235
|
<ion-tabs class="ds-tabs-wrapper">
|
|
33682
35236
|
<!-- Tab bar is hidden during the loading state -->
|
|
33683
35237
|
@if (!pageLoading.isCoveringScreen()) {
|
|
33684
35238
|
<ds-mobile-tab-bar
|
|
33685
35239
|
[tabs]="tabs"
|
|
33686
35240
|
[moreMenuItems]="moreMenuItems"
|
|
35241
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
33687
35242
|
[avatarInitials]="userService.avatarInitials()"
|
|
33688
35243
|
[avatarType]="userService.avatarType()"
|
|
33689
35244
|
[profileMenuItems]="profileMenuItems"
|
|
35245
|
+
(notificationClick)="handleNotificationClick()"
|
|
33690
35246
|
(profileActionSelected)="handleProfileAction($event)"
|
|
33691
35247
|
(moreMenuItemSelected)="handleMoreMenuAction($event)"
|
|
33692
35248
|
>
|
|
33693
35249
|
</ds-mobile-tab-bar>
|
|
33694
35250
|
}
|
|
33695
35251
|
</ion-tabs>
|
|
33696
|
-
`, isInline: true, styles: [":host{display:block;height:100dvh;width:100vw;position:relative}.app-error{position:fixed;inset:0;z-index:9999;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;padding:40px 32px;background:var(--color-header-surface, #2D2356)}.app-error__title{font-family:Brockmann,sans-serif;font-size:var(--font-size-lg, 18px);font-weight:600;color:var(--color-header-content, #fff);text-align:center;margin:0}.app-error__description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);color:#ffffffa6;text-align:center;margin:0 0 8px}.app-error ds-button::ng-deep .btn{border-radius:9999px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: IonTabs, selector: "ion-tabs" }, { kind: "component", type: DsMobileTabBarComponent, selector: "ds-mobile-tab-bar", inputs: ["tabs", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "profileMenuItems", "moreMenuItems", "moreMenuLabel", "moreMenuIcon", "moreMenuIconActive"], outputs: ["avatarClick", "profileActionSelected", "moreMenuItemSelected"] }, { kind: "component", type: DsMobileAppLoadingComponent, selector: "ds-mobile-app-loading", inputs: ["isExiting"], outputs: ["exitComplete"] }, { kind: "component", type: DsButtonComponent, selector: "ds-button", inputs: ["variant", "size", "disabled", "loading", "pressed", "expanded", "leadingIcon", "trailingIcon", "ariaLabel", "iconOnly"], outputs: ["clicked", "focused", "blurred"] }] });
|
|
35252
|
+
`, isInline: true, styles: [":host{display:block;height:100dvh;width:100vw;position:relative}.app-error{position:fixed;inset:0;z-index:9999;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;padding:40px 32px;background:var(--color-header-surface, #2D2356)}.app-error__title{font-family:Brockmann,sans-serif;font-size:var(--font-size-lg, 18px);font-weight:600;color:var(--color-header-content, #fff);text-align:center;margin:0}.app-error__description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);color:#ffffffa6;text-align:center;margin:0 0 8px}.app-error ds-button::ng-deep .btn{border-radius:9999px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: IonTabs, selector: "ion-tabs" }, { kind: "component", type: DsMobileTabBarComponent, selector: "ds-mobile-tab-bar", inputs: ["tabs", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "profileMenuItems", "notificationCount", "moreMenuItems", "moreMenuLabel", "moreMenuIcon", "moreMenuIconActive"], outputs: ["notificationClick", "avatarClick", "profileActionSelected", "moreMenuItemSelected"] }, { kind: "component", type: DsMobileAppLoadingComponent, selector: "ds-mobile-app-loading", inputs: ["isExiting"], outputs: ["exitComplete"] }, { kind: "component", type: DsMobileNotificationPromptComponent, selector: "ds-mobile-notification-prompt", inputs: ["heading", "subtitle", "allowLabel", "dismissLabel"], outputs: ["allow", "dismiss"] }, { kind: "component", type: DsButtonComponent, selector: "ds-button", inputs: ["variant", "size", "disabled", "loading", "pressed", "expanded", "leadingIcon", "trailingIcon", "ariaLabel", "iconOnly"], outputs: ["clicked", "focused", "blurred"] }] });
|
|
33697
35253
|
}
|
|
33698
35254
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MobileTabsExampleComponent, decorators: [{
|
|
33699
35255
|
type: Component,
|
|
33700
|
-
args: [{ selector: 'app-mobile-tabs-example', standalone: true, imports: [CommonModule, IonTabs, DsMobileTabBarComponent, DsMobileAppLoadingComponent, DsButtonComponent], template: `
|
|
35256
|
+
args: [{ selector: 'app-mobile-tabs-example', standalone: true, imports: [CommonModule, IonTabs, DsMobileTabBarComponent, DsMobileAppLoadingComponent, DsMobileNotificationPromptComponent, DsButtonComponent], template: `
|
|
33701
35257
|
<!-- Full-screen loading screen rendered at layout level so it covers the tab bar.
|
|
33702
35258
|
Kept in DOM during exiting so the exit animation can play. -->
|
|
33703
35259
|
@if (pageLoading.isLoading() || pageLoading.isExiting()) {
|
|
@@ -33712,15 +35268,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
33712
35268
|
</div>
|
|
33713
35269
|
}
|
|
33714
35270
|
|
|
35271
|
+
<!-- Notification permission prompt (session-only, reappears on next launch) -->
|
|
35272
|
+
@if (showNotificationPrompt() && !pageLoading.isCoveringScreen()) {
|
|
35273
|
+
<ds-mobile-notification-prompt
|
|
35274
|
+
(allow)="handleNotificationAllow()"
|
|
35275
|
+
(dismiss)="handleNotificationDismiss()" />
|
|
35276
|
+
}
|
|
35277
|
+
|
|
33715
35278
|
<ion-tabs class="ds-tabs-wrapper">
|
|
33716
35279
|
<!-- Tab bar is hidden during the loading state -->
|
|
33717
35280
|
@if (!pageLoading.isCoveringScreen()) {
|
|
33718
35281
|
<ds-mobile-tab-bar
|
|
33719
35282
|
[tabs]="tabs"
|
|
33720
35283
|
[moreMenuItems]="moreMenuItems"
|
|
35284
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
33721
35285
|
[avatarInitials]="userService.avatarInitials()"
|
|
33722
35286
|
[avatarType]="userService.avatarType()"
|
|
33723
35287
|
[profileMenuItems]="profileMenuItems"
|
|
35288
|
+
(notificationClick)="handleNotificationClick()"
|
|
33724
35289
|
(profileActionSelected)="handleProfileAction($event)"
|
|
33725
35290
|
(moreMenuItemSelected)="handleMoreMenuAction($event)"
|
|
33726
35291
|
>
|
|
@@ -33730,393 +35295,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
33730
35295
|
`, styles: [":host{display:block;height:100dvh;width:100vw;position:relative}.app-error{position:fixed;inset:0;z-index:9999;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;padding:40px 32px;background:var(--color-header-surface, #2D2356)}.app-error__title{font-family:Brockmann,sans-serif;font-size:var(--font-size-lg, 18px);font-weight:600;color:var(--color-header-content, #fff);text-align:center;margin:0}.app-error__description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);color:#ffffffa6;text-align:center;margin:0 0 8px}.app-error ds-button::ng-deep .btn{border-radius:9999px}\n"] }]
|
|
33731
35296
|
}], ctorParameters: () => [{ type: UserService }, { type: i1$3.Router }, { type: i1.NavController }] });
|
|
33732
35297
|
|
|
33733
|
-
class DsMobileBookingDetailSheetComponent {
|
|
33734
|
-
modalController;
|
|
33735
|
-
/** `sheet` = bottom sheet. `modal` = `ds-modal-base` shell (active + history bookings). */
|
|
33736
|
-
presentation = 'sheet';
|
|
33737
|
-
data;
|
|
33738
|
-
/** When true the modal sizes to its content instead of filling the screen. */
|
|
33739
|
-
autoHeight = false;
|
|
33740
|
-
get isModalPresentation() {
|
|
33741
|
-
return this.presentation === 'modal';
|
|
33742
|
-
}
|
|
33743
|
-
constructor(modalController) {
|
|
33744
|
-
this.modalController = modalController;
|
|
33745
|
-
}
|
|
33746
|
-
close() {
|
|
33747
|
-
this.modalController.dismiss(null, 'backdrop');
|
|
33748
|
-
}
|
|
33749
|
-
cancelBooking() {
|
|
33750
|
-
this.modalController.dismiss(null, 'cancel');
|
|
33751
|
-
}
|
|
33752
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetComponent, deps: [{ token: i1.ModalController }], target: i0.ɵɵFactoryTarget.Component });
|
|
33753
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DsMobileBookingDetailSheetComponent, isStandalone: true, selector: "ds-mobile-booking-detail-sheet", inputs: { presentation: "presentation", data: "data", autoHeight: "autoHeight" }, host: { properties: { "class.presentation-modal": "this.isModalPresentation" } }, ngImport: i0, template: `
|
|
33754
|
-
@if (presentation === 'modal') {
|
|
33755
|
-
<ds-mobile-modal-base
|
|
33756
|
-
[headerTitle]="data.facilityTitle"
|
|
33757
|
-
[closeButtonLabel]="'Luk'"
|
|
33758
|
-
[isAutoHeight]="autoHeight"
|
|
33759
|
-
[keyboardContentBehavior]="'follow'">
|
|
33760
|
-
|
|
33761
|
-
<ds-mobile-section
|
|
33762
|
-
[showBorder]="false"
|
|
33763
|
-
padding="20px 20px 0 20px">
|
|
33764
|
-
<div class="hero-image-container">
|
|
33765
|
-
@if (data.heroImage) {
|
|
33766
|
-
<img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
|
|
33767
|
-
} @else {
|
|
33768
|
-
<div class="hero-image-placeholder">
|
|
33769
|
-
<ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
|
|
33770
|
-
</div>
|
|
33771
|
-
}
|
|
33772
|
-
</div>
|
|
33773
|
-
</ds-mobile-section>
|
|
33774
|
-
|
|
33775
|
-
<ds-mobile-section padding="20px 20px 20px 20px">
|
|
33776
|
-
<div class="booking-summary-card">
|
|
33777
|
-
<div class="details-section">
|
|
33778
|
-
<h3 class="details-heading">Booking detaljer</h3>
|
|
33779
|
-
<div class="info-rows">
|
|
33780
|
-
@if (data.bookingDate) {
|
|
33781
|
-
<div class="info-row">
|
|
33782
|
-
<ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
|
|
33783
|
-
<span>{{ data.bookingDate }}</span>
|
|
33784
|
-
</div>
|
|
33785
|
-
}
|
|
33786
|
-
@if (data.bookingTime) {
|
|
33787
|
-
<div class="info-row">
|
|
33788
|
-
<ds-icon name="remixTimeLine" size="16px" color="tertiary" />
|
|
33789
|
-
<span>{{ data.bookingTime }}</span>
|
|
33790
|
-
</div>
|
|
33791
|
-
}
|
|
33792
|
-
@if (data.price) {
|
|
33793
|
-
<div class="info-row">
|
|
33794
|
-
<ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
|
|
33795
|
-
<span>{{ data.price }}</span>
|
|
33796
|
-
</div>
|
|
33797
|
-
}
|
|
33798
|
-
@if (data.bookingType) {
|
|
33799
|
-
<div class="info-row">
|
|
33800
|
-
<ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
|
|
33801
|
-
<span>{{ data.bookingType }}</span>
|
|
33802
|
-
</div>
|
|
33803
|
-
}
|
|
33804
|
-
@for (req of data.requirements || []; track req) {
|
|
33805
|
-
<div class="info-row">
|
|
33806
|
-
<ds-icon name="remixLockLine" size="16px" color="tertiary" />
|
|
33807
|
-
<span>{{ req }}</span>
|
|
33808
|
-
</div>
|
|
33809
|
-
}
|
|
33810
|
-
</div>
|
|
33811
|
-
</div>
|
|
33812
|
-
</div>
|
|
33813
|
-
</ds-mobile-section>
|
|
33814
|
-
|
|
33815
|
-
@if (data.canCancel) {
|
|
33816
|
-
<div class="booking-action">
|
|
33817
|
-
<div class="booking-actions-row">
|
|
33818
|
-
<ds-button
|
|
33819
|
-
class="cancel-primary"
|
|
33820
|
-
size="md"
|
|
33821
|
-
variant="secondary"
|
|
33822
|
-
(clicked)="cancelBooking()">
|
|
33823
|
-
Annuller booking
|
|
33824
|
-
</ds-button>
|
|
33825
|
-
</div>
|
|
33826
|
-
</div>
|
|
33827
|
-
}
|
|
33828
|
-
</ds-mobile-modal-base>
|
|
33829
|
-
} @else {
|
|
33830
|
-
<ds-mobile-bottom-sheet-wrapper [showDragHandle]="true">
|
|
33831
|
-
<div class="detail-header">
|
|
33832
|
-
<h2 class="detail-title">{{ data.facilityTitle }}</h2>
|
|
33833
|
-
<ds-icon-button
|
|
33834
|
-
icon="remixCloseLine"
|
|
33835
|
-
variant="ghost"
|
|
33836
|
-
size="sm"
|
|
33837
|
-
(clicked)="close()"
|
|
33838
|
-
aria-label="Luk"
|
|
33839
|
-
/>
|
|
33840
|
-
</div>
|
|
33841
|
-
|
|
33842
|
-
<div class="detail-content">
|
|
33843
|
-
<div class="hero-image-container">
|
|
33844
|
-
@if (data.heroImage) {
|
|
33845
|
-
<img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
|
|
33846
|
-
} @else {
|
|
33847
|
-
<div class="hero-image-placeholder">
|
|
33848
|
-
<ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
|
|
33849
|
-
</div>
|
|
33850
|
-
}
|
|
33851
|
-
</div>
|
|
33852
|
-
|
|
33853
|
-
<div class="booking-summary-card">
|
|
33854
|
-
<div class="details-section">
|
|
33855
|
-
<h3 class="details-heading">Booking detaljer</h3>
|
|
33856
|
-
<div class="info-rows">
|
|
33857
|
-
@if (data.bookingDate) {
|
|
33858
|
-
<div class="info-row">
|
|
33859
|
-
<ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
|
|
33860
|
-
<span>{{ data.bookingDate }}</span>
|
|
33861
|
-
</div>
|
|
33862
|
-
}
|
|
33863
|
-
@if (data.bookingTime) {
|
|
33864
|
-
<div class="info-row">
|
|
33865
|
-
<ds-icon name="remixTimeLine" size="16px" color="tertiary" />
|
|
33866
|
-
<span>{{ data.bookingTime }}</span>
|
|
33867
|
-
</div>
|
|
33868
|
-
}
|
|
33869
|
-
@if (data.price) {
|
|
33870
|
-
<div class="info-row">
|
|
33871
|
-
<ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
|
|
33872
|
-
<span>{{ data.price }}</span>
|
|
33873
|
-
</div>
|
|
33874
|
-
}
|
|
33875
|
-
@if (data.bookingType) {
|
|
33876
|
-
<div class="info-row">
|
|
33877
|
-
<ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
|
|
33878
|
-
<span>{{ data.bookingType }}</span>
|
|
33879
|
-
</div>
|
|
33880
|
-
}
|
|
33881
|
-
@for (req of data.requirements || []; track req) {
|
|
33882
|
-
<div class="info-row">
|
|
33883
|
-
<ds-icon name="remixLockLine" size="16px" color="tertiary" />
|
|
33884
|
-
<span>{{ req }}</span>
|
|
33885
|
-
</div>
|
|
33886
|
-
}
|
|
33887
|
-
</div>
|
|
33888
|
-
</div>
|
|
33889
|
-
</div>
|
|
33890
|
-
|
|
33891
|
-
@if (data.canCancel) {
|
|
33892
|
-
<div class="footer-button-container">
|
|
33893
|
-
<div class="booking-actions-column">
|
|
33894
|
-
<ds-button
|
|
33895
|
-
size="md"
|
|
33896
|
-
variant="secondary"
|
|
33897
|
-
(clicked)="cancelBooking()">
|
|
33898
|
-
Annuller booking
|
|
33899
|
-
</ds-button>
|
|
33900
|
-
</div>
|
|
33901
|
-
</div>
|
|
33902
|
-
}
|
|
33903
|
-
</div>
|
|
33904
|
-
</ds-mobile-bottom-sheet-wrapper>
|
|
33905
|
-
}
|
|
33906
|
-
`, isInline: true, styles: [":host{display:block;height:auto;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;box-sizing:border-box}.detail-header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px 8px}.detail-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-lg, 18px);font-weight:600;color:var(--text-color-default-primary, #202227);margin:0;flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding-right:12px}.detail-content{padding:8px 20px 24px;display:flex;flex-direction:column;gap:20px}.hero-image-container{width:100%;aspect-ratio:16 / 9;border-radius:12px;overflow:hidden;background:var(--color-surface-secondary, #f5f5f5)}.hero-image{width:100%;height:100%;object-fit:cover;display:block}.hero-image-placeholder{width:100%;height:100%;min-height:0;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,color-mix(in srgb,var(--color-accent, #6B5FF5) 30%,transparent),color-mix(in srgb,var(--color-accent, #6B5FF5) 60%,transparent))}.booking-summary-card{background:var(--color-background-neutral-secondary, #f5f5f5);border-radius:16px;padding:16px}.details-section{display:flex;flex-direction:column;gap:12px}.details-heading{font-family:Brockmann,sans-serif;font-size:var(--font-size-base, 16px);font-weight:600;color:var(--text-color-default-primary, #202227);margin:0}.info-rows{display:flex;flex-direction:column;gap:8px}.info-row{display:flex;align-items:center;gap:10px;font-family:Brockmann,sans-serif;font-size:var(--font-size-sm, 14px);color:var(--text-color-default-secondary, #545B66);line-height:1.4}.info-row ds-icon{flex-shrink:0}.footer-button-container{width:100%;padding:16px 20px 0}.footer-button-container ::ng-deep ds-button{display:block;width:100%}.footer-button-container ::ng-deep ds-button button{width:100%;border-radius:100px;height:44px;min-height:44px;max-height:44px}.booking-action{padding:16px 20px;padding-bottom:calc(16px + max(8px,env(safe-area-inset-bottom,0px) - 24px));background:var(--color-surface-primary, #ffffff)}.booking-actions-row{display:flex;flex-direction:row;align-items:center;gap:12px;width:100%}.booking-action .cancel-primary{flex:1;min-width:0;display:block}.booking-action .cancel-primary ::ng-deep button{width:100%;border-radius:100px;height:44px;min-height:44px;max-height:44px;padding-left:16px;padding-right:16px}:host.presentation-modal{display:block;height:auto;width:100%;min-height:0;overflow:hidden}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsMobileBottomSheetWrapperComponent, selector: "ds-mobile-bottom-sheet-wrapper", inputs: ["showDragHandle"] }, { kind: "component", type: DsMobileModalBaseComponent, selector: "ds-mobile-modal-base", inputs: ["headerTitleInteractive", "showHeader"], outputs: ["titleClick"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsButtonComponent, selector: "ds-button", inputs: ["variant", "size", "disabled", "loading", "pressed", "expanded", "leadingIcon", "trailingIcon", "ariaLabel", "iconOnly"], outputs: ["clicked", "focused", "blurred"] }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsIconButtonComponent, selector: "ds-icon-button", inputs: ["variant", "size", "icon", "disabled", "loading", "pressed", "expanded", "ariaLabel", "tooltip", "tooltipDisabled", "tooltipPlacement"], outputs: ["clicked", "focused", "blurred"] }] });
|
|
33907
|
-
}
|
|
33908
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetComponent, decorators: [{
|
|
33909
|
-
type: Component,
|
|
33910
|
-
args: [{ selector: 'ds-mobile-booking-detail-sheet', standalone: true, imports: [
|
|
33911
|
-
CommonModule,
|
|
33912
|
-
DsMobileBottomSheetWrapperComponent,
|
|
33913
|
-
DsMobileModalBaseComponent,
|
|
33914
|
-
DsMobileSectionComponent,
|
|
33915
|
-
DsButtonComponent,
|
|
33916
|
-
DsIconComponent,
|
|
33917
|
-
DsIconButtonComponent,
|
|
33918
|
-
], template: `
|
|
33919
|
-
@if (presentation === 'modal') {
|
|
33920
|
-
<ds-mobile-modal-base
|
|
33921
|
-
[headerTitle]="data.facilityTitle"
|
|
33922
|
-
[closeButtonLabel]="'Luk'"
|
|
33923
|
-
[isAutoHeight]="autoHeight"
|
|
33924
|
-
[keyboardContentBehavior]="'follow'">
|
|
33925
|
-
|
|
33926
|
-
<ds-mobile-section
|
|
33927
|
-
[showBorder]="false"
|
|
33928
|
-
padding="20px 20px 0 20px">
|
|
33929
|
-
<div class="hero-image-container">
|
|
33930
|
-
@if (data.heroImage) {
|
|
33931
|
-
<img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
|
|
33932
|
-
} @else {
|
|
33933
|
-
<div class="hero-image-placeholder">
|
|
33934
|
-
<ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
|
|
33935
|
-
</div>
|
|
33936
|
-
}
|
|
33937
|
-
</div>
|
|
33938
|
-
</ds-mobile-section>
|
|
33939
|
-
|
|
33940
|
-
<ds-mobile-section padding="20px 20px 20px 20px">
|
|
33941
|
-
<div class="booking-summary-card">
|
|
33942
|
-
<div class="details-section">
|
|
33943
|
-
<h3 class="details-heading">Booking detaljer</h3>
|
|
33944
|
-
<div class="info-rows">
|
|
33945
|
-
@if (data.bookingDate) {
|
|
33946
|
-
<div class="info-row">
|
|
33947
|
-
<ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
|
|
33948
|
-
<span>{{ data.bookingDate }}</span>
|
|
33949
|
-
</div>
|
|
33950
|
-
}
|
|
33951
|
-
@if (data.bookingTime) {
|
|
33952
|
-
<div class="info-row">
|
|
33953
|
-
<ds-icon name="remixTimeLine" size="16px" color="tertiary" />
|
|
33954
|
-
<span>{{ data.bookingTime }}</span>
|
|
33955
|
-
</div>
|
|
33956
|
-
}
|
|
33957
|
-
@if (data.price) {
|
|
33958
|
-
<div class="info-row">
|
|
33959
|
-
<ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
|
|
33960
|
-
<span>{{ data.price }}</span>
|
|
33961
|
-
</div>
|
|
33962
|
-
}
|
|
33963
|
-
@if (data.bookingType) {
|
|
33964
|
-
<div class="info-row">
|
|
33965
|
-
<ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
|
|
33966
|
-
<span>{{ data.bookingType }}</span>
|
|
33967
|
-
</div>
|
|
33968
|
-
}
|
|
33969
|
-
@for (req of data.requirements || []; track req) {
|
|
33970
|
-
<div class="info-row">
|
|
33971
|
-
<ds-icon name="remixLockLine" size="16px" color="tertiary" />
|
|
33972
|
-
<span>{{ req }}</span>
|
|
33973
|
-
</div>
|
|
33974
|
-
}
|
|
33975
|
-
</div>
|
|
33976
|
-
</div>
|
|
33977
|
-
</div>
|
|
33978
|
-
</ds-mobile-section>
|
|
33979
|
-
|
|
33980
|
-
@if (data.canCancel) {
|
|
33981
|
-
<div class="booking-action">
|
|
33982
|
-
<div class="booking-actions-row">
|
|
33983
|
-
<ds-button
|
|
33984
|
-
class="cancel-primary"
|
|
33985
|
-
size="md"
|
|
33986
|
-
variant="secondary"
|
|
33987
|
-
(clicked)="cancelBooking()">
|
|
33988
|
-
Annuller booking
|
|
33989
|
-
</ds-button>
|
|
33990
|
-
</div>
|
|
33991
|
-
</div>
|
|
33992
|
-
}
|
|
33993
|
-
</ds-mobile-modal-base>
|
|
33994
|
-
} @else {
|
|
33995
|
-
<ds-mobile-bottom-sheet-wrapper [showDragHandle]="true">
|
|
33996
|
-
<div class="detail-header">
|
|
33997
|
-
<h2 class="detail-title">{{ data.facilityTitle }}</h2>
|
|
33998
|
-
<ds-icon-button
|
|
33999
|
-
icon="remixCloseLine"
|
|
34000
|
-
variant="ghost"
|
|
34001
|
-
size="sm"
|
|
34002
|
-
(clicked)="close()"
|
|
34003
|
-
aria-label="Luk"
|
|
34004
|
-
/>
|
|
34005
|
-
</div>
|
|
34006
|
-
|
|
34007
|
-
<div class="detail-content">
|
|
34008
|
-
<div class="hero-image-container">
|
|
34009
|
-
@if (data.heroImage) {
|
|
34010
|
-
<img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
|
|
34011
|
-
} @else {
|
|
34012
|
-
<div class="hero-image-placeholder">
|
|
34013
|
-
<ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
|
|
34014
|
-
</div>
|
|
34015
|
-
}
|
|
34016
|
-
</div>
|
|
34017
|
-
|
|
34018
|
-
<div class="booking-summary-card">
|
|
34019
|
-
<div class="details-section">
|
|
34020
|
-
<h3 class="details-heading">Booking detaljer</h3>
|
|
34021
|
-
<div class="info-rows">
|
|
34022
|
-
@if (data.bookingDate) {
|
|
34023
|
-
<div class="info-row">
|
|
34024
|
-
<ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
|
|
34025
|
-
<span>{{ data.bookingDate }}</span>
|
|
34026
|
-
</div>
|
|
34027
|
-
}
|
|
34028
|
-
@if (data.bookingTime) {
|
|
34029
|
-
<div class="info-row">
|
|
34030
|
-
<ds-icon name="remixTimeLine" size="16px" color="tertiary" />
|
|
34031
|
-
<span>{{ data.bookingTime }}</span>
|
|
34032
|
-
</div>
|
|
34033
|
-
}
|
|
34034
|
-
@if (data.price) {
|
|
34035
|
-
<div class="info-row">
|
|
34036
|
-
<ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
|
|
34037
|
-
<span>{{ data.price }}</span>
|
|
34038
|
-
</div>
|
|
34039
|
-
}
|
|
34040
|
-
@if (data.bookingType) {
|
|
34041
|
-
<div class="info-row">
|
|
34042
|
-
<ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
|
|
34043
|
-
<span>{{ data.bookingType }}</span>
|
|
34044
|
-
</div>
|
|
34045
|
-
}
|
|
34046
|
-
@for (req of data.requirements || []; track req) {
|
|
34047
|
-
<div class="info-row">
|
|
34048
|
-
<ds-icon name="remixLockLine" size="16px" color="tertiary" />
|
|
34049
|
-
<span>{{ req }}</span>
|
|
34050
|
-
</div>
|
|
34051
|
-
}
|
|
34052
|
-
</div>
|
|
34053
|
-
</div>
|
|
34054
|
-
</div>
|
|
34055
|
-
|
|
34056
|
-
@if (data.canCancel) {
|
|
34057
|
-
<div class="footer-button-container">
|
|
34058
|
-
<div class="booking-actions-column">
|
|
34059
|
-
<ds-button
|
|
34060
|
-
size="md"
|
|
34061
|
-
variant="secondary"
|
|
34062
|
-
(clicked)="cancelBooking()">
|
|
34063
|
-
Annuller booking
|
|
34064
|
-
</ds-button>
|
|
34065
|
-
</div>
|
|
34066
|
-
</div>
|
|
34067
|
-
}
|
|
34068
|
-
</div>
|
|
34069
|
-
</ds-mobile-bottom-sheet-wrapper>
|
|
34070
|
-
}
|
|
34071
|
-
`, styles: [":host{display:block;height:auto;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;box-sizing:border-box}.detail-header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px 8px}.detail-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-lg, 18px);font-weight:600;color:var(--text-color-default-primary, #202227);margin:0;flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding-right:12px}.detail-content{padding:8px 20px 24px;display:flex;flex-direction:column;gap:20px}.hero-image-container{width:100%;aspect-ratio:16 / 9;border-radius:12px;overflow:hidden;background:var(--color-surface-secondary, #f5f5f5)}.hero-image{width:100%;height:100%;object-fit:cover;display:block}.hero-image-placeholder{width:100%;height:100%;min-height:0;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,color-mix(in srgb,var(--color-accent, #6B5FF5) 30%,transparent),color-mix(in srgb,var(--color-accent, #6B5FF5) 60%,transparent))}.booking-summary-card{background:var(--color-background-neutral-secondary, #f5f5f5);border-radius:16px;padding:16px}.details-section{display:flex;flex-direction:column;gap:12px}.details-heading{font-family:Brockmann,sans-serif;font-size:var(--font-size-base, 16px);font-weight:600;color:var(--text-color-default-primary, #202227);margin:0}.info-rows{display:flex;flex-direction:column;gap:8px}.info-row{display:flex;align-items:center;gap:10px;font-family:Brockmann,sans-serif;font-size:var(--font-size-sm, 14px);color:var(--text-color-default-secondary, #545B66);line-height:1.4}.info-row ds-icon{flex-shrink:0}.footer-button-container{width:100%;padding:16px 20px 0}.footer-button-container ::ng-deep ds-button{display:block;width:100%}.footer-button-container ::ng-deep ds-button button{width:100%;border-radius:100px;height:44px;min-height:44px;max-height:44px}.booking-action{padding:16px 20px;padding-bottom:calc(16px + max(8px,env(safe-area-inset-bottom,0px) - 24px));background:var(--color-surface-primary, #ffffff)}.booking-actions-row{display:flex;flex-direction:row;align-items:center;gap:12px;width:100%}.booking-action .cancel-primary{flex:1;min-width:0;display:block}.booking-action .cancel-primary ::ng-deep button{width:100%;border-radius:100px;height:44px;min-height:44px;max-height:44px;padding-left:16px;padding-right:16px}:host.presentation-modal{display:block;height:auto;width:100%;min-height:0;overflow:hidden}\n"] }]
|
|
34072
|
-
}], ctorParameters: () => [{ type: i1.ModalController }], propDecorators: { presentation: [{
|
|
34073
|
-
type: Input
|
|
34074
|
-
}], data: [{
|
|
34075
|
-
type: Input
|
|
34076
|
-
}], autoHeight: [{
|
|
34077
|
-
type: Input
|
|
34078
|
-
}], isModalPresentation: [{
|
|
34079
|
-
type: HostBinding,
|
|
34080
|
-
args: ['class.presentation-modal']
|
|
34081
|
-
}] } });
|
|
34082
|
-
|
|
34083
|
-
class DsMobileBookingDetailSheetService extends BaseModalService {
|
|
34084
|
-
bottomSheet;
|
|
34085
|
-
constructor(modalController, bottomSheet) {
|
|
34086
|
-
super(modalController);
|
|
34087
|
-
this.bottomSheet = bottomSheet;
|
|
34088
|
-
}
|
|
34089
|
-
/**
|
|
34090
|
-
* Bottom-sheet presentation (draggable breakpoints). Prefer `openAsModal` for booking lists.
|
|
34091
|
-
*/
|
|
34092
|
-
async open(data) {
|
|
34093
|
-
const modal = await this.bottomSheet.create({
|
|
34094
|
-
component: DsMobileBookingDetailSheetComponent,
|
|
34095
|
-
componentProps: { data },
|
|
34096
|
-
autoHeight: true,
|
|
34097
|
-
backdropDismiss: true,
|
|
34098
|
-
backdropBlur: true,
|
|
34099
|
-
});
|
|
34100
|
-
const result = await modal.onWillDismiss();
|
|
34101
|
-
return { role: result.role, data: result.data ?? undefined };
|
|
34102
|
-
}
|
|
34103
|
-
/** `ds-modal-base` shell — used for active and past bookings. Auto-heights to content. */
|
|
34104
|
-
async openAsModal(data) {
|
|
34105
|
-
const modal = await this.createModal(DsMobileBookingDetailSheetComponent, { data, presentation: 'modal', autoHeight: true }, { keyboardClose: true, autoHeight: true });
|
|
34106
|
-
await modal.present();
|
|
34107
|
-
const result = await modal.onWillDismiss();
|
|
34108
|
-
return { role: result.role, data: result.data ?? undefined };
|
|
34109
|
-
}
|
|
34110
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetService, deps: [{ token: i1.ModalController }, { token: DsMobileBottomSheetService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
34111
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetService, providedIn: 'root' });
|
|
34112
|
-
}
|
|
34113
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetService, decorators: [{
|
|
34114
|
-
type: Injectable,
|
|
34115
|
-
args: [{
|
|
34116
|
-
providedIn: 'root',
|
|
34117
|
-
}]
|
|
34118
|
-
}], ctorParameters: () => [{ type: i1.ModalController }, { type: DsMobileBottomSheetService }] });
|
|
34119
|
-
|
|
34120
35298
|
class DsMobileBookingCancelConfirmationComponent {
|
|
34121
35299
|
facilityTitle;
|
|
34122
35300
|
facilityThumbnail;
|
|
@@ -34217,6 +35395,8 @@ class MobileBookingPageComponent {
|
|
|
34217
35395
|
userService;
|
|
34218
35396
|
pageComponent;
|
|
34219
35397
|
bookingsSwiper;
|
|
35398
|
+
notificationModal = inject(DsMobileNotificationModalService);
|
|
35399
|
+
notificationService = inject(NotificationService);
|
|
34220
35400
|
cancellingBookingId = signal(null, ...(ngDevMode ? [{ debugName: "cancellingBookingId" }] : []));
|
|
34221
35401
|
lang = signal(resolveLanguage(), ...(ngDevMode ? [{ debugName: "lang" }] : []));
|
|
34222
35402
|
historyLinkText = computed(() => HISTORY_LINK[this.lang()] ?? HISTORY_LINK['da'], ...(ngDevMode ? [{ debugName: "historyLinkText" }] : []));
|
|
@@ -34422,6 +35602,11 @@ class MobileBookingPageComponent {
|
|
|
34422
35602
|
}
|
|
34423
35603
|
], ...(ngDevMode ? [{ debugName: "availableFacilities" }] : []));
|
|
34424
35604
|
visibleFacilities = computed(() => this.availableFacilities().filter((f) => !f.archived), ...(ngDevMode ? [{ debugName: "visibleFacilities" }] : []));
|
|
35605
|
+
async handleNotificationClick() {
|
|
35606
|
+
const tapped = await this.notificationModal.open();
|
|
35607
|
+
if (tapped)
|
|
35608
|
+
console.log('Notification tapped:', tapped.type, tapped.id);
|
|
35609
|
+
}
|
|
34425
35610
|
handleRefresh(event) {
|
|
34426
35611
|
console.log('Pull-to-refresh triggered');
|
|
34427
35612
|
// Check if offline and complete immediately
|
|
@@ -34712,8 +35897,10 @@ class MobileBookingPageComponent {
|
|
|
34712
35897
|
<ds-mobile-page-main
|
|
34713
35898
|
#pageComponent
|
|
34714
35899
|
[title]="'Bookinger'"
|
|
35900
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
34715
35901
|
[avatarInitials]="userService.avatarInitials()"
|
|
34716
35902
|
[avatarType]="userService.avatarType()"
|
|
35903
|
+
(notificationClick)="handleNotificationClick()"
|
|
34717
35904
|
(refresh)="handleRefresh($event)">
|
|
34718
35905
|
|
|
34719
35906
|
@if (pageComponent.isOffline()) {
|
|
@@ -34818,7 +36005,7 @@ class MobileBookingPageComponent {
|
|
|
34818
36005
|
ariaLabel="Opret facilitet"
|
|
34819
36006
|
(clicked)="openFacilityCreationModal()">
|
|
34820
36007
|
</ds-mobile-fab>
|
|
34821
|
-
`, isInline: true, styles: [".bookings-swiper-wrapper{padding:0;position:relative}.swiper-nav-buttons{display:contents}.swiper-nav-button{position:absolute;top:50%;transform:translateY(-50%);z-index:10}.swiper-nav-button:first-child{left:-48px}.swiper-nav-button:last-child{right:-48px}::ng-deep .swiper-nav-button button{border-radius:50%!important;width:48px!important;height:48px!important;padding:0!important}@media (max-width: 767px){.swiper-nav-buttons{display:none}}::ng-deep .bookings-swiper .swiper-slide{width:100%;max-width:600px;height:auto;pointer-events:auto}@media (min-width: 768px){::ng-deep .bookings-swiper .swiper-slide{max-width:100%}}::ng-deep .bookings-swiper .swiper-slide ds-mobile-interactive-list-item-booking{width:100%;pointer-events:auto}.booking-slide-content{position:relative;width:100%}\n"], dependencies: [{ kind: "component", type: DsMobilePageMainComponent, selector: "ds-mobile-page-main", inputs: ["title", "headerTitle", "headerSubtitle", "firstEntry", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileInteractiveListItemBookingComponent, selector: "ds-mobile-interactive-list-item-booking", inputs: ["thumbnail", "facilityTitle", "description", "bookingDate", "bookingTime", "availabilityStatus", "statusLabel", "variant", "align", "clickable", "showChevron", "enableLongPress", "moreActions"], outputs: ["bookingClick", "longPress"] }, { kind: "component", type: DsMobileSwiperComponent, selector: "ds-mobile-swiper", inputs: ["slideWidth", "gap", "pagination", "autoHeight", "progressiveOpacity", "progressiveScale"] }, { kind: "component", type: DsIconButtonComponent, selector: "ds-icon-button", inputs: ["variant", "size", "icon", "disabled", "loading", "pressed", "expanded", "ariaLabel", "tooltip", "tooltipDisabled", "tooltipPlacement"], outputs: ["clicked", "focused", "blurred"] }, { kind: "component", type: DsMobileOfflineBannerComponent, selector: "ds-mobile-offline-banner", inputs: ["icon", "title", "message"] }, { kind: "component", type: DsMobileFabComponent, selector: "ds-mobile-fab", inputs: ["icon", "position", "size", "ariaLabel", "disabled"], outputs: ["clicked"] }, { kind: "component", type: DsMobileLoaderOverlayComponent, selector: "ds-mobile-loader-overlay", inputs: ["spinnerSize", "borderRadius"] }] });
|
|
36008
|
+
`, isInline: true, styles: [".bookings-swiper-wrapper{padding:0;position:relative}.swiper-nav-buttons{display:contents}.swiper-nav-button{position:absolute;top:50%;transform:translateY(-50%);z-index:10}.swiper-nav-button:first-child{left:-48px}.swiper-nav-button:last-child{right:-48px}::ng-deep .swiper-nav-button button{border-radius:50%!important;width:48px!important;height:48px!important;padding:0!important}@media (max-width: 767px){.swiper-nav-buttons{display:none}}::ng-deep .bookings-swiper .swiper-slide{width:100%;max-width:600px;height:auto;pointer-events:auto}@media (min-width: 768px){::ng-deep .bookings-swiper .swiper-slide{max-width:100%}}::ng-deep .bookings-swiper .swiper-slide ds-mobile-interactive-list-item-booking{width:100%;pointer-events:auto}.booking-slide-content{position:relative;width:100%}\n"], dependencies: [{ kind: "component", type: DsMobilePageMainComponent, selector: "ds-mobile-page-main", inputs: ["title", "headerTitle", "headerSubtitle", "firstEntry", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "notificationCount", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["notificationClick", "avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileInteractiveListItemBookingComponent, selector: "ds-mobile-interactive-list-item-booking", inputs: ["thumbnail", "facilityTitle", "description", "bookingDate", "bookingTime", "availabilityStatus", "statusLabel", "variant", "align", "clickable", "showChevron", "enableLongPress", "moreActions"], outputs: ["bookingClick", "longPress"] }, { kind: "component", type: DsMobileSwiperComponent, selector: "ds-mobile-swiper", inputs: ["slideWidth", "gap", "pagination", "autoHeight", "progressiveOpacity", "progressiveScale"] }, { kind: "component", type: DsIconButtonComponent, selector: "ds-icon-button", inputs: ["variant", "size", "icon", "disabled", "loading", "pressed", "expanded", "ariaLabel", "tooltip", "tooltipDisabled", "tooltipPlacement"], outputs: ["clicked", "focused", "blurred"] }, { kind: "component", type: DsMobileOfflineBannerComponent, selector: "ds-mobile-offline-banner", inputs: ["icon", "title", "message"] }, { kind: "component", type: DsMobileFabComponent, selector: "ds-mobile-fab", inputs: ["icon", "position", "size", "ariaLabel", "disabled"], outputs: ["clicked"] }, { kind: "component", type: DsMobileLoaderOverlayComponent, selector: "ds-mobile-loader-overlay", inputs: ["spinnerSize", "borderRadius"] }] });
|
|
34822
36009
|
}
|
|
34823
36010
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MobileBookingPageComponent, decorators: [{
|
|
34824
36011
|
type: Component,
|
|
@@ -34835,8 +36022,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
34835
36022
|
<ds-mobile-page-main
|
|
34836
36023
|
#pageComponent
|
|
34837
36024
|
[title]="'Bookinger'"
|
|
36025
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
34838
36026
|
[avatarInitials]="userService.avatarInitials()"
|
|
34839
36027
|
[avatarType]="userService.avatarType()"
|
|
36028
|
+
(notificationClick)="handleNotificationClick()"
|
|
34840
36029
|
(refresh)="handleRefresh($event)">
|
|
34841
36030
|
|
|
34842
36031
|
@if (pageComponent.isOffline()) {
|
|
@@ -36726,9 +37915,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
36726
37915
|
class TenantChatPageComponent {
|
|
36727
37916
|
modalCtrl = inject(ModalController);
|
|
36728
37917
|
userService = inject(UserService);
|
|
37918
|
+
notificationModal = inject(DsMobileNotificationModalService);
|
|
37919
|
+
notificationService = inject(NotificationService);
|
|
36729
37920
|
peerMessaging = inject(PeerMessagingService);
|
|
36730
37921
|
peerChat = inject(PeerChatLauncherService);
|
|
36731
37922
|
isPeerGroupConversation = isPeerGroupConversation;
|
|
37923
|
+
async handleNotificationClick() {
|
|
37924
|
+
const tapped = await this.notificationModal.open();
|
|
37925
|
+
if (tapped)
|
|
37926
|
+
console.log('Notification tapped:', tapped.type, tapped.id);
|
|
37927
|
+
}
|
|
36732
37928
|
handleRefresh(event) {
|
|
36733
37929
|
setTimeout(() => event.target.complete(), 1000);
|
|
36734
37930
|
}
|
|
@@ -36755,8 +37951,10 @@ class TenantChatPageComponent {
|
|
|
36755
37951
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: TenantChatPageComponent, isStandalone: true, selector: "app-tenant-chat-page", host: { classAttribute: "ion-page" }, ngImport: i0, template: `
|
|
36756
37952
|
<ds-mobile-page-main
|
|
36757
37953
|
title="Beskeder"
|
|
37954
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
36758
37955
|
[avatarInitials]="userService.avatarInitials()"
|
|
36759
37956
|
[avatarType]="userService.avatarType()"
|
|
37957
|
+
(notificationClick)="handleNotificationClick()"
|
|
36760
37958
|
(refresh)="handleRefresh($event)">
|
|
36761
37959
|
|
|
36762
37960
|
<ds-mobile-section contentGap="0px" padding="12px 20px 20px 20px" [showBorder]="false">
|
|
@@ -36815,7 +38013,7 @@ class TenantChatPageComponent {
|
|
|
36815
38013
|
ariaLabel="Vælg beboer at skrive med"
|
|
36816
38014
|
(clicked)="goToTenants()">
|
|
36817
38015
|
</ds-mobile-fab>
|
|
36818
|
-
`, isInline: true, styles: [".empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:64px 20px;text-align:center}.empty-state-image{width:96px;height:96px;margin-bottom:24px;opacity:.4}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;color:var(--color-text-primary);margin:0 0 8px}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);color:var(--color-text-secondary);margin:0}\n"], dependencies: [{ kind: "component", type: DsMobilePageMainComponent, selector: "ds-mobile-page-main", inputs: ["title", "headerTitle", "headerSubtitle", "firstEntry", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileInteractiveListItemMessageComponent, selector: "ds-mobile-interactive-list-item-message", inputs: ["senderName", "senderRole", "timestamp", "message", "avatarInitials", "avatarType", "avatarSrc", "unread", "unreadStyle", "clickable", "align", "showAvatarBadge", "groupStackMembers", "groupCustomAvatarUrl", "groupStackExcludeParticipantId"], outputs: ["messageClick", "longPress"] }, { kind: "component", type: DsMobileFabComponent, selector: "ds-mobile-fab", inputs: ["icon", "position", "size", "ariaLabel", "disabled"], outputs: ["clicked"] }] });
|
|
38016
|
+
`, isInline: true, styles: [".empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:64px 20px;text-align:center}.empty-state-image{width:96px;height:96px;margin-bottom:24px;opacity:.4}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;color:var(--color-text-primary);margin:0 0 8px}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);color:var(--color-text-secondary);margin:0}\n"], dependencies: [{ kind: "component", type: DsMobilePageMainComponent, selector: "ds-mobile-page-main", inputs: ["title", "headerTitle", "headerSubtitle", "firstEntry", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "notificationCount", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["notificationClick", "avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileInteractiveListItemMessageComponent, selector: "ds-mobile-interactive-list-item-message", inputs: ["senderName", "senderRole", "timestamp", "message", "avatarInitials", "avatarType", "avatarSrc", "unread", "unreadStyle", "clickable", "align", "showAvatarBadge", "groupStackMembers", "groupCustomAvatarUrl", "groupStackExcludeParticipantId"], outputs: ["messageClick", "longPress"] }, { kind: "component", type: DsMobileFabComponent, selector: "ds-mobile-fab", inputs: ["icon", "position", "size", "ariaLabel", "disabled"], outputs: ["clicked"] }] });
|
|
36819
38017
|
}
|
|
36820
38018
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TenantChatPageComponent, decorators: [{
|
|
36821
38019
|
type: Component,
|
|
@@ -36829,8 +38027,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
36829
38027
|
}, template: `
|
|
36830
38028
|
<ds-mobile-page-main
|
|
36831
38029
|
title="Beskeder"
|
|
38030
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
36832
38031
|
[avatarInitials]="userService.avatarInitials()"
|
|
36833
38032
|
[avatarType]="userService.avatarType()"
|
|
38033
|
+
(notificationClick)="handleNotificationClick()"
|
|
36834
38034
|
(refresh)="handleRefresh($event)">
|
|
36835
38035
|
|
|
36836
38036
|
<ds-mobile-section contentGap="0px" padding="12px 20px 20px 20px" [showBorder]="false">
|
|
@@ -36972,6 +38172,8 @@ const MOCK_VENDORS = [
|
|
|
36972
38172
|
class ServicesPageComponent {
|
|
36973
38173
|
pageComponent;
|
|
36974
38174
|
vendorModal = inject(DsMobileServiceVendorModalService);
|
|
38175
|
+
notificationModal = inject(DsMobileNotificationModalService);
|
|
38176
|
+
notificationService = inject(NotificationService);
|
|
36975
38177
|
newInquiryModal = inject(DsMobileNewInquiryModalService);
|
|
36976
38178
|
inquiriesService = inject(InquiriesService);
|
|
36977
38179
|
navCtrl = inject(NavController);
|
|
@@ -37018,6 +38220,11 @@ class ServicesPageComponent {
|
|
|
37018
38220
|
},
|
|
37019
38221
|
});
|
|
37020
38222
|
}
|
|
38223
|
+
async handleNotificationClick() {
|
|
38224
|
+
const tapped = await this.notificationModal.open();
|
|
38225
|
+
if (tapped)
|
|
38226
|
+
console.log('Notification tapped:', tapped.type, tapped.id);
|
|
38227
|
+
}
|
|
37021
38228
|
handleRefresh(event) {
|
|
37022
38229
|
setTimeout(() => {
|
|
37023
38230
|
event.target?.complete?.();
|
|
@@ -37028,8 +38235,10 @@ class ServicesPageComponent {
|
|
|
37028
38235
|
<ds-mobile-page-main
|
|
37029
38236
|
#pageComponent
|
|
37030
38237
|
[title]="lbl.pageTitle"
|
|
38238
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
37031
38239
|
[avatarInitials]="userService.avatarInitials()"
|
|
37032
38240
|
[avatarType]="userService.avatarType()"
|
|
38241
|
+
(notificationClick)="handleNotificationClick()"
|
|
37033
38242
|
(refresh)="handleRefresh($event)"
|
|
37034
38243
|
>
|
|
37035
38244
|
@if (pageComponent.isOffline()) {
|
|
@@ -37061,7 +38270,7 @@ class ServicesPageComponent {
|
|
|
37061
38270
|
</ds-mobile-section>
|
|
37062
38271
|
}
|
|
37063
38272
|
</ds-mobile-page-main>
|
|
37064
|
-
`, isInline: true, styles: [".empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 20px;text-align:center}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;color:var(--color-text-primary);margin-top:-16px;z-index:4}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);color:var(--color-text-secondary);margin:0}\n"], dependencies: [{ kind: "component", type: DsMobilePageMainComponent, selector: "ds-mobile-page-main", inputs: ["title", "headerTitle", "headerSubtitle", "firstEntry", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileIllustrationComponent, selector: "ds-mobile-illustration", inputs: ["variant", "size", "alt"] }, { kind: "component", type: DsMobileInteractiveListItemServiceComponent, selector: "ds-mobile-interactive-list-item-service", inputs: ["title", "description", "logo", "showChevron"], outputs: ["serviceClick"] }, { kind: "component", type: DsMobileOfflineBannerComponent, selector: "ds-mobile-offline-banner", inputs: ["icon", "title", "message"] }] });
|
|
38273
|
+
`, isInline: true, styles: [".empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 20px;text-align:center}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;color:var(--color-text-primary);margin-top:-16px;z-index:4}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);color:var(--color-text-secondary);margin:0}\n"], dependencies: [{ kind: "component", type: DsMobilePageMainComponent, selector: "ds-mobile-page-main", inputs: ["title", "headerTitle", "headerSubtitle", "firstEntry", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "notificationCount", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["notificationClick", "avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileIllustrationComponent, selector: "ds-mobile-illustration", inputs: ["variant", "size", "alt"] }, { kind: "component", type: DsMobileInteractiveListItemServiceComponent, selector: "ds-mobile-interactive-list-item-service", inputs: ["title", "description", "logo", "showChevron"], outputs: ["serviceClick"] }, { kind: "component", type: DsMobileOfflineBannerComponent, selector: "ds-mobile-offline-banner", inputs: ["icon", "title", "message"] }] });
|
|
37065
38274
|
}
|
|
37066
38275
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ServicesPageComponent, decorators: [{
|
|
37067
38276
|
type: Component,
|
|
@@ -37075,8 +38284,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
37075
38284
|
<ds-mobile-page-main
|
|
37076
38285
|
#pageComponent
|
|
37077
38286
|
[title]="lbl.pageTitle"
|
|
38287
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
37078
38288
|
[avatarInitials]="userService.avatarInitials()"
|
|
37079
38289
|
[avatarType]="userService.avatarType()"
|
|
38290
|
+
(notificationClick)="handleNotificationClick()"
|
|
37080
38291
|
(refresh)="handleRefresh($event)"
|
|
37081
38292
|
>
|
|
37082
38293
|
@if (pageComponent.isOffline()) {
|
|
@@ -37137,5 +38348,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
37137
38348
|
* Generated bundle index. Do not edit.
|
|
37138
38349
|
*/
|
|
37139
38350
|
|
|
37140
|
-
export { AcceptInvitePageComponent, ActionCommentComponent, ActionLikeComponent, AvatarUploadPageComponent, BaseModalService, ContentRowComponent, CreateAccountPageComponent, DEFAULT_SERVICE_PAGE_LABELS, DsAppIconComponent, DsAvatarWithBadgeComponent, DsLogoComponent, DsMobileAccessSheetComponent, DsMobileActionListItemComponent, DsMobileActionsBottomSheetComponent, DsMobileAddGroupTenantsModalComponent, DsMobileAppLoadingComponent, DsMobileAttachmentPreviewComponent, DsMobileBookingConfirmationWrapperComponent, DsMobileBookingModalComponent, DsMobileBookingModalService, DsMobileBookingSummaryComponent, DsMobileBottomSheetHeaderComponent, DsMobileBottomSheetService, DsMobileBottomSheetWrapperComponent, DsMobileCapacitySheetComponent, DsMobileCardInlineBannerComponent, DsMobileCardInlineComponent, DsMobileCardInlineContactComponent, DsMobileCardInlineFileComponent, DsMobileChatModalComponent, DsMobileChatModalService, DsMobileActionsBottomSheetComponent as DsMobileCommentActionsBottomSheetComponent, DsMobileCommentComponent, DsMobileCommunityAdminPickerComponent, DsMobileCommunityAdminsModalComponent, DsMobileConfirmationSheetComponent, DsMobileContactListItemComponent, DsMobileContentComponent, DsMobileCreateGroupModalComponent, DsMobileDropdownComponent, DsMobileEditGroupModalComponent, DsMobileEmptyStateComponent, DsMobileFabComponent, DsMobileFacilityArchiveConfirmationComponent, DsMobileFacilityCreationConfirmationWrapperComponent, DsMobileFacilityCreationModalComponent, DsMobileFacilityCreationModalService, DsMobileFacilityDeleteConfirmationComponent, DsMobileFacilityDetailModalComponent, DsMobileFacilityDetailModalService, DsMobileFileAttachmentComponent, DsMobileGlassSpinnerComponent, DsMobileGroupAvatarStackComponent, DsMobileGroupMembersModalComponent, DsMobileHandbookDetailModalComponent, DsMobileHandbookDetailModalService, DsMobileHandbookFolderComponent, DsMobileHandbookFolderMiniComponent, DsMobileHeaderContentComponent, DsMobileHeaderContentTileComponent, DsMobileIllustrationComponent, DsMobileImagePlaceholderComponent, DsMobileInlinePhotoComponent, DsMobileInlineTabsComponent, DsMobileInteractiveListItemBookingComponent, DsMobileInteractiveListItemInquiryComponent, DsMobileInteractiveListItemMessageComponent, DsMobileInteractiveListItemPostComponent, DsMobileLightboxImageComponent as DsMobileLightboxComponent, DsMobileLightboxFooterComponent, DsMobileLightboxHeaderComponent, DsMobileLightboxImageComponent, DsMobileLightboxImageWithDescriptionComponent, DsMobileLightboxPdfComponent, DsMobileLightboxService, DsMobileListItemComponent, DsMobileListItemStaticComponent, DsMobileListSearchComponent, DsMobileLoaderOverlayComponent, DsMobileLongPressDirective, DsMobileMediaActionsPanelComponent, DsMobileMessageBubbleComponent, DsMobileMessageComposerComponent, DsMobileModalBaseComponent, DsMobileModalService, DsMobileNewInquiryModalComponent, DsMobileNewInquiryModalService, DsMobileOfflineBannerComponent, DsMobilePageDetailsComponent, DsMobilePageMainComponent, DsMobilePillComponent, DsMobileActionsBottomSheetComponent as DsMobilePostActionsBottomSheetComponent, DsMobilePostComposerComponent, DsMobilePostCreateBottomSheetComponent, DsMobilePostDetailModalComponent, DsMobilePostDetailModalService, DsMobilePriceSheetComponent, DsMobileProfileActionsSheetComponent, DsMobilePromptBottomSheetComponent, DsMobilePropertyBannerComponent, DsMobileRichTextEditorComponent, DsMobileSectionComponent, DsMobileServiceVendorModalService, DsMobileServiceVendorSheetComponent, DsMobileSwiperComponent, DsMobileSwiperWithNavComponent, DsMobileSystemMessageBannerComponent, DsMobileTabBarComponent, DsMobileTabsComponent, DsMobileTenantPickerModalComponent, DsMobileWhenCanBookSheetComponent, DsMobileWhoCanBookSheetComponent, DsTextInputComponent, FamilyAccessPageComponent, FamilyAccessService, InquiriesService, InviteSuccessPageComponent, MediaPickerService, MobileBookingPageComponent, MobileCommunityPageComponent, MobileHandbookPageComponent, MobileHomePageComponent, MobileInquiriesPageComponent, MobileInquiryDetailPageComponent, MobileModalBase, MobilePageBase, MobilePostDetailPageComponent, MobileTabsExampleComponent, PageLoadingService, PostActionsComponent, PostAttachmentsComponent, PostContentComponent, PostCreatePageComponent, PostMediaComponent, PostPdfAttachmentComponent, PostTextComponent, PostsService, SectionHeaderComponent, ServicesPageComponent, SignInPageComponent, SignInToAcceptPageComponent, TenantChatPageComponent, TileContentComponent, TileIconComponent, TileLabelComponent, TileValueComponent, TrackingPermissionService, UserService, WhitelabelDemoModalComponent, WhitelabelDemoModalService, WhitelabelService, customBackTransition, customPageTransition };
|
|
38351
|
+
export { AcceptInvitePageComponent, ActionCommentComponent, ActionLikeComponent, AvatarUploadPageComponent, BaseModalService, ContentRowComponent, CreateAccountPageComponent, DEFAULT_SERVICE_PAGE_LABELS, DsAppIconComponent, DsAvatarWithBadgeComponent, DsLogoComponent, DsMobileAccessSheetComponent, DsMobileActionListItemComponent, DsMobileActionsBottomSheetComponent, DsMobileAddGroupTenantsModalComponent, DsMobileAppLoadingComponent, DsMobileAttachmentPreviewComponent, DsMobileBookingConfirmationWrapperComponent, DsMobileBookingModalComponent, DsMobileBookingModalService, DsMobileBookingSummaryComponent, DsMobileBottomSheetHeaderComponent, DsMobileBottomSheetService, DsMobileBottomSheetWrapperComponent, DsMobileCapacitySheetComponent, DsMobileCardInlineBannerComponent, DsMobileCardInlineComponent, DsMobileCardInlineContactComponent, DsMobileCardInlineFileComponent, DsMobileChatModalComponent, DsMobileChatModalService, DsMobileActionsBottomSheetComponent as DsMobileCommentActionsBottomSheetComponent, DsMobileCommentComponent, DsMobileCommunityAdminPickerComponent, DsMobileCommunityAdminsModalComponent, DsMobileConfirmationSheetComponent, DsMobileContactListItemComponent, DsMobileContentComponent, DsMobileCountBadgeComponent, DsMobileCreateGroupModalComponent, DsMobileDropdownComponent, DsMobileEditGroupModalComponent, DsMobileEmptyStateComponent, DsMobileFabComponent, DsMobileFacilityArchiveConfirmationComponent, DsMobileFacilityCreationConfirmationWrapperComponent, DsMobileFacilityCreationModalComponent, DsMobileFacilityCreationModalService, DsMobileFacilityDeleteConfirmationComponent, DsMobileFacilityDetailModalComponent, DsMobileFacilityDetailModalService, DsMobileFileAttachmentComponent, DsMobileGlassSpinnerComponent, DsMobileGroupAvatarStackComponent, DsMobileGroupMembersModalComponent, DsMobileHandbookDetailModalComponent, DsMobileHandbookDetailModalService, DsMobileHandbookFolderComponent, DsMobileHandbookFolderMiniComponent, DsMobileHeaderContentComponent, DsMobileHeaderContentTileComponent, DsMobileIllustrationComponent, DsMobileImagePlaceholderComponent, DsMobileInlinePhotoComponent, DsMobileInlineTabsComponent, DsMobileInteractiveListItemBookingComponent, DsMobileInteractiveListItemInquiryComponent, DsMobileInteractiveListItemMessageComponent, DsMobileInteractiveListItemPostComponent, DsMobileLightboxImageComponent as DsMobileLightboxComponent, DsMobileLightboxFooterComponent, DsMobileLightboxHeaderComponent, DsMobileLightboxImageComponent, DsMobileLightboxImageWithDescriptionComponent, DsMobileLightboxPdfComponent, DsMobileLightboxService, DsMobileListItemComponent, DsMobileListItemStaticComponent, DsMobileListSearchComponent, DsMobileLoaderOverlayComponent, DsMobileLongPressDirective, DsMobileMediaActionsPanelComponent, DsMobileMessageBubbleComponent, DsMobileMessageComposerComponent, DsMobileModalBaseComponent, DsMobileModalService, DsMobileNewInquiryModalComponent, DsMobileNewInquiryModalService, DsMobileNotificationButtonComponent, DsMobileNotificationModalComponent, DsMobileNotificationModalService, DsMobileNotificationPromptComponent, DsMobileOfflineBannerComponent, DsMobilePageDetailsComponent, DsMobilePageMainComponent, DsMobilePillComponent, DsMobileActionsBottomSheetComponent as DsMobilePostActionsBottomSheetComponent, DsMobilePostComposerComponent, DsMobilePostCreateBottomSheetComponent, DsMobilePostDetailModalComponent, DsMobilePostDetailModalService, DsMobilePriceSheetComponent, DsMobileProfileActionsSheetComponent, DsMobilePromptBottomSheetComponent, DsMobilePropertyBannerComponent, DsMobileRichTextEditorComponent, DsMobileSectionComponent, DsMobileServiceVendorModalService, DsMobileServiceVendorSheetComponent, DsMobileSwiperComponent, DsMobileSwiperWithNavComponent, DsMobileSystemMessageBannerComponent, DsMobileTabBarComponent, DsMobileTabsComponent, DsMobileTenantPickerModalComponent, DsMobileWhenCanBookSheetComponent, DsMobileWhoCanBookSheetComponent, DsTextInputComponent, FamilyAccessPageComponent, FamilyAccessService, InquiriesService, InviteSuccessPageComponent, MediaPickerService, MobileBookingPageComponent, MobileCommunityPageComponent, MobileHandbookPageComponent, MobileHomePageComponent, MobileInquiriesPageComponent, MobileInquiryDetailPageComponent, MobileModalBase, MobilePageBase, MobilePostDetailPageComponent, MobileTabsExampleComponent, NOTIFICATION_ICON_MAP, NotificationPromptService, NotificationService, PageLoadingService, PostActionsComponent, PostAttachmentsComponent, PostContentComponent, PostCreatePageComponent, PostMediaComponent, PostPdfAttachmentComponent, PostTextComponent, PostsService, RelativeTimePipe, SAMPLE_NOTIFICATIONS, SectionHeaderComponent, ServicesPageComponent, SignInPageComponent, SignInToAcceptPageComponent, TenantChatPageComponent, TileContentComponent, TileIconComponent, TileLabelComponent, TileValueComponent, TrackingPermissionService, UserService, VENDOR_MODAL_SERVICE, WhitelabelDemoModalComponent, WhitelabelDemoModalService, WhitelabelService, customBackTransition, customPageTransition, dateBucket };
|
|
37141
38352
|
//# sourceMappingURL=propbinder-mobile-design.mjs.map
|