@propbinder/mobile-design 0.2.90 → 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 +1671 -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
|
|
@@ -6282,6 +6345,7 @@ class DsMobileInlineTabsComponent {
|
|
|
6282
6345
|
<button
|
|
6283
6346
|
class="filter-tab"
|
|
6284
6347
|
[class.active]="activeTab() === tab.id"
|
|
6348
|
+
[class.has-envelope]="tab.badgeType === 'envelope'"
|
|
6285
6349
|
(click)="handleTabClick(tab.id)"
|
|
6286
6350
|
[attr.aria-label]="tab.label"
|
|
6287
6351
|
[attr.aria-selected]="activeTab() === tab.id">
|
|
@@ -6296,21 +6360,22 @@ class DsMobileInlineTabsComponent {
|
|
|
6296
6360
|
}
|
|
6297
6361
|
</div>
|
|
6298
6362
|
} @else if (tab.badge && tab.badge > 0) {
|
|
6299
|
-
<
|
|
6363
|
+
<ds-mobile-count-badge [count]="tab.badge" variant="muted" />
|
|
6300
6364
|
}
|
|
6301
6365
|
</button>
|
|
6302
6366
|
}
|
|
6303
6367
|
</div>
|
|
6304
|
-
`, 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"] }] });
|
|
6305
6369
|
}
|
|
6306
6370
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileInlineTabsComponent, decorators: [{
|
|
6307
6371
|
type: Component,
|
|
6308
|
-
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: `
|
|
6309
6373
|
<div class="filter-tabs">
|
|
6310
6374
|
@for (tab of tabs(); track tab.id) {
|
|
6311
6375
|
<button
|
|
6312
6376
|
class="filter-tab"
|
|
6313
6377
|
[class.active]="activeTab() === tab.id"
|
|
6378
|
+
[class.has-envelope]="tab.badgeType === 'envelope'"
|
|
6314
6379
|
(click)="handleTabClick(tab.id)"
|
|
6315
6380
|
[attr.aria-label]="tab.label"
|
|
6316
6381
|
[attr.aria-selected]="activeTab() === tab.id">
|
|
@@ -6325,12 +6390,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
6325
6390
|
}
|
|
6326
6391
|
</div>
|
|
6327
6392
|
} @else if (tab.badge && tab.badge > 0) {
|
|
6328
|
-
<
|
|
6393
|
+
<ds-mobile-count-badge [count]="tab.badge" variant="muted" />
|
|
6329
6394
|
}
|
|
6330
6395
|
</button>
|
|
6331
6396
|
}
|
|
6332
6397
|
</div>
|
|
6333
|
-
`, 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"] }]
|
|
6334
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"] }] } });
|
|
6335
6400
|
|
|
6336
6401
|
/**
|
|
@@ -11754,7 +11819,7 @@ class DsMobileModalBaseComponent extends MobileModalBase {
|
|
|
11754
11819
|
this.headerMeta() ||
|
|
11755
11820
|
this.hasContentInSlot(this.headerLeading) ||
|
|
11756
11821
|
this.hasContentInSlot(this.headerMain) ||
|
|
11757
|
-
this.
|
|
11822
|
+
!!this.headerTrailing);
|
|
11758
11823
|
}
|
|
11759
11824
|
/**
|
|
11760
11825
|
* Check whether header-leading slot has actual projected content.
|
|
@@ -11762,6 +11827,9 @@ class DsMobileModalBaseComponent extends MobileModalBase {
|
|
|
11762
11827
|
hasHeaderLeadingContent() {
|
|
11763
11828
|
return this.hasContentInSlot(this.headerLeading);
|
|
11764
11829
|
}
|
|
11830
|
+
hasHeaderTrailingContent() {
|
|
11831
|
+
return !!this.headerTrailing;
|
|
11832
|
+
}
|
|
11765
11833
|
/**
|
|
11766
11834
|
* Check if a content child slot has actual content
|
|
11767
11835
|
*/
|
|
@@ -19244,11 +19312,14 @@ class DsMobileTabBarComponent {
|
|
|
19244
19312
|
* ```
|
|
19245
19313
|
*/
|
|
19246
19314
|
profileMenuItems;
|
|
19315
|
+
// Notification inputs
|
|
19316
|
+
notificationCount = 0;
|
|
19247
19317
|
moreMenuItems = [];
|
|
19248
19318
|
moreMenuLabel = 'Mere';
|
|
19249
19319
|
moreMenuIcon = 'remixGridLine';
|
|
19250
19320
|
moreMenuIconActive = 'remixGridFill';
|
|
19251
19321
|
// Outputs
|
|
19322
|
+
notificationClick = new EventEmitter();
|
|
19252
19323
|
avatarClick = new EventEmitter();
|
|
19253
19324
|
/**
|
|
19254
19325
|
* Emitted when a profile menu action is selected.
|
|
@@ -19834,7 +19905,7 @@ class DsMobileTabBarComponent {
|
|
|
19834
19905
|
}
|
|
19835
19906
|
}
|
|
19836
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 });
|
|
19837
|
-
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: `
|
|
19838
19909
|
<ion-tab-bar [attr.slot]="isDesktop() ? 'top' : 'bottom'" class="ds-tab-bar" [class.ds-tab-bar--desktop]="isDesktop()">
|
|
19839
19910
|
<!-- Logo (desktop only, full logo in header) -->
|
|
19840
19911
|
<div class="ds-tab-bar__logo">
|
|
@@ -19877,16 +19948,20 @@ class DsMobileTabBarComponent {
|
|
|
19877
19948
|
}
|
|
19878
19949
|
</div>
|
|
19879
19950
|
|
|
19880
|
-
<!-- Avatar (desktop only, positioned via CSS) -->
|
|
19951
|
+
<!-- Notification + Avatar (desktop only, positioned via CSS) -->
|
|
19881
19952
|
<div class="ds-tab-bar__actions">
|
|
19953
|
+
<ds-mobile-notification-button
|
|
19954
|
+
[count]="notificationCount"
|
|
19955
|
+
(clicked)="notificationClick.emit()"
|
|
19956
|
+
/>
|
|
19882
19957
|
<ds-avatar [size]="'md'" [type]="avatarType" [initials]="avatarInitials" [src]="avatarSrc" [iconName]="avatarIconName" (click)="handleAvatarClick()" />
|
|
19883
19958
|
</div>
|
|
19884
19959
|
</ion-tab-bar>
|
|
19885
|
-
`, 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"] }] });
|
|
19886
19961
|
}
|
|
19887
19962
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileTabBarComponent, decorators: [{
|
|
19888
19963
|
type: Component,
|
|
19889
|
-
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: `
|
|
19890
19965
|
<ion-tab-bar [attr.slot]="isDesktop() ? 'top' : 'bottom'" class="ds-tab-bar" [class.ds-tab-bar--desktop]="isDesktop()">
|
|
19891
19966
|
<!-- Logo (desktop only, full logo in header) -->
|
|
19892
19967
|
<div class="ds-tab-bar__logo">
|
|
@@ -19929,8 +20004,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
19929
20004
|
}
|
|
19930
20005
|
</div>
|
|
19931
20006
|
|
|
19932
|
-
<!-- Avatar (desktop only, positioned via CSS) -->
|
|
20007
|
+
<!-- Notification + Avatar (desktop only, positioned via CSS) -->
|
|
19933
20008
|
<div class="ds-tab-bar__actions">
|
|
20009
|
+
<ds-mobile-notification-button
|
|
20010
|
+
[count]="notificationCount"
|
|
20011
|
+
(clicked)="notificationClick.emit()"
|
|
20012
|
+
/>
|
|
19934
20013
|
<ds-avatar [size]="'md'" [type]="avatarType" [initials]="avatarInitials" [src]="avatarSrc" [iconName]="avatarIconName" (click)="handleAvatarClick()" />
|
|
19935
20014
|
</div>
|
|
19936
20015
|
</ion-tab-bar>
|
|
@@ -19947,6 +20026,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
19947
20026
|
type: Input
|
|
19948
20027
|
}], profileMenuItems: [{
|
|
19949
20028
|
type: Input
|
|
20029
|
+
}], notificationCount: [{
|
|
20030
|
+
type: Input
|
|
19950
20031
|
}], moreMenuItems: [{
|
|
19951
20032
|
type: Input
|
|
19952
20033
|
}], moreMenuLabel: [{
|
|
@@ -19955,6 +20036,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
19955
20036
|
type: Input
|
|
19956
20037
|
}], moreMenuIconActive: [{
|
|
19957
20038
|
type: Input
|
|
20039
|
+
}], notificationClick: [{
|
|
20040
|
+
type: Output
|
|
19958
20041
|
}], avatarClick: [{
|
|
19959
20042
|
type: Output
|
|
19960
20043
|
}], profileActionSelected: [{
|
|
@@ -20023,7 +20106,7 @@ class DsMobileTabsComponent {
|
|
|
20023
20106
|
(avatarClick)="handleAvatarClick()"
|
|
20024
20107
|
/>
|
|
20025
20108
|
</ion-tabs>
|
|
20026
|
-
`, 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"] }] });
|
|
20027
20110
|
}
|
|
20028
20111
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileTabsComponent, decorators: [{
|
|
20029
20112
|
type: Component,
|
|
@@ -21804,7 +21887,7 @@ class DsMobileEmptyStateComponent {
|
|
|
21804
21887
|
}
|
|
21805
21888
|
</div>
|
|
21806
21889
|
</div>
|
|
21807
|
-
`, 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 }] });
|
|
21808
21891
|
}
|
|
21809
21892
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileEmptyStateComponent, decorators: [{
|
|
21810
21893
|
type: Component,
|
|
@@ -21823,7 +21906,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
21823
21906
|
}
|
|
21824
21907
|
</div>
|
|
21825
21908
|
</div>
|
|
21826
|
-
`, 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"] }]
|
|
21827
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 }] }] } });
|
|
21828
21911
|
|
|
21829
21912
|
/**
|
|
@@ -22700,16 +22783,16 @@ class DsMobileCardInlineBannerComponent {
|
|
|
22700
22783
|
|
|
22701
22784
|
<div content-trailing class="item-trailing">
|
|
22702
22785
|
@if (unreadCount() && unreadCount()! > 0) {
|
|
22703
|
-
<
|
|
22786
|
+
<ds-mobile-count-badge [count]="unreadCount()!" variant="accent" />
|
|
22704
22787
|
}
|
|
22705
22788
|
<ds-icon name="remixArrowRightSLine" size="20px" />
|
|
22706
22789
|
</div>
|
|
22707
22790
|
</ds-mobile-card-inline>
|
|
22708
|
-
`, 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"] }] });
|
|
22709
22792
|
}
|
|
22710
22793
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileCardInlineBannerComponent, decorators: [{
|
|
22711
22794
|
type: Component,
|
|
22712
|
-
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: `
|
|
22713
22796
|
<ds-mobile-card-inline
|
|
22714
22797
|
[variant]="layout()"
|
|
22715
22798
|
(cardClick)="handleBannerClick()">
|
|
@@ -22734,12 +22817,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
22734
22817
|
|
|
22735
22818
|
<div content-trailing class="item-trailing">
|
|
22736
22819
|
@if (unreadCount() && unreadCount()! > 0) {
|
|
22737
|
-
<
|
|
22820
|
+
<ds-mobile-count-badge [count]="unreadCount()!" variant="accent" />
|
|
22738
22821
|
}
|
|
22739
22822
|
<ds-icon name="remixArrowRightSLine" size="20px" />
|
|
22740
22823
|
</div>
|
|
22741
22824
|
</ds-mobile-card-inline>
|
|
22742
|
-
`, styles: ["
|
|
22825
|
+
`, styles: ["ds-mobile-count-badge{margin-right:8px}\n"] }]
|
|
22743
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"] }] } });
|
|
22744
22827
|
|
|
22745
22828
|
/**
|
|
@@ -26090,7 +26173,7 @@ class DsMobilePriceSheetComponent {
|
|
|
26090
26173
|
inputmode="numeric"
|
|
26091
26174
|
pattern="[0-9]*"
|
|
26092
26175
|
maxlength="5"
|
|
26093
|
-
[attr.size]="Math.min(customPrice()
|
|
26176
|
+
[attr.size]="Math.min(customPrice().length || 2, 5)"
|
|
26094
26177
|
[(ngModel)]="customPrice"
|
|
26095
26178
|
placeholder="75"
|
|
26096
26179
|
class="price-input-native"
|
|
@@ -26145,7 +26228,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
26145
26228
|
inputmode="numeric"
|
|
26146
26229
|
pattern="[0-9]*"
|
|
26147
26230
|
maxlength="5"
|
|
26148
|
-
[attr.size]="Math.min(customPrice()
|
|
26231
|
+
[attr.size]="Math.min(customPrice().length || 2, 5)"
|
|
26149
26232
|
[(ngModel)]="customPrice"
|
|
26150
26233
|
placeholder="75"
|
|
26151
26234
|
class="price-input-native"
|
|
@@ -28622,7 +28705,713 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
28622
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"] }]
|
|
28623
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 }] }] } });
|
|
28624
28707
|
|
|
28625
|
-
|
|
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
|
+
}] });
|
|
28626
29415
|
|
|
28627
29416
|
/**
|
|
28628
29417
|
* PostsService
|
|
@@ -29149,6 +29938,614 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
29149
29938
|
}]
|
|
29150
29939
|
}], ctorParameters: () => [] });
|
|
29151
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
|
+
|
|
29152
30549
|
class MobileCommunityPageComponent {
|
|
29153
30550
|
router;
|
|
29154
30551
|
route;
|
|
@@ -29159,6 +30556,8 @@ class MobileCommunityPageComponent {
|
|
|
29159
30556
|
postsService;
|
|
29160
30557
|
pageComponent;
|
|
29161
30558
|
pinnedSwiper;
|
|
30559
|
+
notificationModal = inject(DsMobileNotificationModalService);
|
|
30560
|
+
notificationService = inject(NotificationService);
|
|
29162
30561
|
// Get posts from service (using computed for safe initialization)
|
|
29163
30562
|
allPosts = computed(() => this.postsService.posts(), ...(ngDevMode ? [{ debugName: "allPosts" }] : []));
|
|
29164
30563
|
// Get pinned posts - filter by isPinned flag
|
|
@@ -29201,6 +30600,11 @@ class MobileCommunityPageComponent {
|
|
|
29201
30600
|
// Complete the infinite scroll
|
|
29202
30601
|
event.target.complete();
|
|
29203
30602
|
}
|
|
30603
|
+
async handleNotificationClick() {
|
|
30604
|
+
const tapped = await this.notificationModal.open();
|
|
30605
|
+
if (tapped)
|
|
30606
|
+
console.log('Notification tapped:', tapped.type, tapped.id);
|
|
30607
|
+
}
|
|
29204
30608
|
handleRefresh(event) {
|
|
29205
30609
|
console.log('Pull-to-refresh triggered');
|
|
29206
30610
|
// Check if offline and complete immediately
|
|
@@ -29442,8 +30846,10 @@ class MobileCommunityPageComponent {
|
|
|
29442
30846
|
<ds-mobile-page-main
|
|
29443
30847
|
#pageComponent
|
|
29444
30848
|
title="Fællesskab"
|
|
30849
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
29445
30850
|
[avatarInitials]="userService.avatarInitials()"
|
|
29446
30851
|
[avatarType]="userService.avatarType()"
|
|
30852
|
+
(notificationClick)="handleNotificationClick()"
|
|
29447
30853
|
(refresh)="handleRefresh($event)">
|
|
29448
30854
|
|
|
29449
30855
|
<!-- Offline indicator -->
|
|
@@ -29696,7 +31102,7 @@ class MobileCommunityPageComponent {
|
|
|
29696
31102
|
}
|
|
29697
31103
|
</ds-mobile-section>
|
|
29698
31104
|
</ds-mobile-page-main>
|
|
29699
|
-
`, 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"] }] });
|
|
29700
31106
|
}
|
|
29701
31107
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MobileCommunityPageComponent, decorators: [{
|
|
29702
31108
|
type: Component,
|
|
@@ -29723,8 +31129,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
29723
31129
|
<ds-mobile-page-main
|
|
29724
31130
|
#pageComponent
|
|
29725
31131
|
title="Fællesskab"
|
|
31132
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
29726
31133
|
[avatarInitials]="userService.avatarInitials()"
|
|
29727
31134
|
[avatarType]="userService.avatarType()"
|
|
31135
|
+
(notificationClick)="handleNotificationClick()"
|
|
29728
31136
|
(refresh)="handleRefresh($event)">
|
|
29729
31137
|
|
|
29730
31138
|
<!-- Offline indicator -->
|
|
@@ -29989,6 +31397,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
29989
31397
|
class MobileHandbookPageComponent {
|
|
29990
31398
|
userService;
|
|
29991
31399
|
pageComponent;
|
|
31400
|
+
notificationModal = inject(DsMobileNotificationModalService);
|
|
31401
|
+
notificationService = inject(NotificationService);
|
|
29992
31402
|
// Utilities folder data
|
|
29993
31403
|
utilitiesItems = [
|
|
29994
31404
|
{
|
|
@@ -30231,6 +31641,11 @@ class MobileHandbookPageComponent {
|
|
|
30231
31641
|
constructor(userService) {
|
|
30232
31642
|
this.userService = userService;
|
|
30233
31643
|
}
|
|
31644
|
+
async handleNotificationClick() {
|
|
31645
|
+
const tapped = await this.notificationModal.open();
|
|
31646
|
+
if (tapped)
|
|
31647
|
+
console.log('Notification tapped:', tapped.type, tapped.id);
|
|
31648
|
+
}
|
|
30234
31649
|
handleRefresh(event) {
|
|
30235
31650
|
console.log('Pull-to-refresh triggered');
|
|
30236
31651
|
// Check if offline and complete immediately
|
|
@@ -30246,7 +31661,7 @@ class MobileHandbookPageComponent {
|
|
|
30246
31661
|
}
|
|
30247
31662
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MobileHandbookPageComponent, deps: [{ token: UserService }], target: i0.ɵɵFactoryTarget.Component });
|
|
30248
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: `
|
|
30249
|
-
<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)">
|
|
30250
31665
|
<!-- Offline indicator -->
|
|
30251
31666
|
@if (pageComponent.isOffline()) {
|
|
30252
31667
|
<ds-mobile-offline-banner offline-indicator title="Ingen internetforbindelse" message="Nogle funktioner kan være utilgængelige"> </ds-mobile-offline-banner>
|
|
@@ -30267,12 +31682,12 @@ class MobileHandbookPageComponent {
|
|
|
30267
31682
|
</div>
|
|
30268
31683
|
</ds-mobile-section>
|
|
30269
31684
|
</ds-mobile-page-main>
|
|
30270
|
-
`, 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"] }] });
|
|
30271
31686
|
}
|
|
30272
31687
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MobileHandbookPageComponent, decorators: [{
|
|
30273
31688
|
type: Component,
|
|
30274
31689
|
args: [{ selector: 'app-mobile-handbook-page', standalone: true, imports: [DsMobilePageMainComponent, DsMobileSectionComponent, DsMobileHandbookFolderComponent, DsMobileOfflineBannerComponent], template: `
|
|
30275
|
-
<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)">
|
|
30276
31691
|
<!-- Offline indicator -->
|
|
30277
31692
|
@if (pageComponent.isOffline()) {
|
|
30278
31693
|
<ds-mobile-offline-banner offline-indicator title="Ingen internetforbindelse" message="Nogle funktioner kan være utilgængelige"> </ds-mobile-offline-banner>
|
|
@@ -30864,6 +32279,8 @@ class MobileHomePageComponent {
|
|
|
30864
32279
|
modalCtrl = inject(ModalController);
|
|
30865
32280
|
vendorModal = inject(DsMobileServiceVendorModalService);
|
|
30866
32281
|
newInquiryModal = inject(DsMobileNewInquiryModalService);
|
|
32282
|
+
notificationModal = inject(DsMobileNotificationModalService);
|
|
32283
|
+
notificationService = inject(NotificationService);
|
|
30867
32284
|
constructor(router, navCtrl, userService, postsService, postModal, trackingPermissionService, bottomSheet, familyAccessService, peerMessaging, peerChat, lightboxService) {
|
|
30868
32285
|
this.router = router;
|
|
30869
32286
|
this.navCtrl = navCtrl;
|
|
@@ -30891,6 +32308,11 @@ class MobileHomePageComponent {
|
|
|
30891
32308
|
}, delayMs);
|
|
30892
32309
|
});
|
|
30893
32310
|
}
|
|
32311
|
+
async handleNotificationClick() {
|
|
32312
|
+
const tapped = await this.notificationModal.open();
|
|
32313
|
+
if (tapped)
|
|
32314
|
+
console.log('Notification tapped:', tapped.type, tapped.id);
|
|
32315
|
+
}
|
|
30894
32316
|
handleRefresh(event) {
|
|
30895
32317
|
console.log('Pull-to-refresh triggered');
|
|
30896
32318
|
setTimeout(() => {
|
|
@@ -31035,8 +32457,10 @@ class MobileHomePageComponent {
|
|
|
31035
32457
|
#pageComponent
|
|
31036
32458
|
title="Hjem"
|
|
31037
32459
|
headerTitle="Velkommen, Lars"
|
|
32460
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
31038
32461
|
[avatarInitials]="userService.avatarInitials()"
|
|
31039
32462
|
[avatarType]="userService.avatarType()"
|
|
32463
|
+
(notificationClick)="handleNotificationClick()"
|
|
31040
32464
|
(refresh)="handleRefresh($event)"
|
|
31041
32465
|
>
|
|
31042
32466
|
|
|
@@ -31239,7 +32663,7 @@ class MobileHomePageComponent {
|
|
|
31239
32663
|
</ds-mobile-page-main>
|
|
31240
32664
|
} <!-- end @if (!isCoveringScreen()) -->
|
|
31241
32665
|
|
|
31242
|
-
`, 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"] }] });
|
|
31243
32667
|
}
|
|
31244
32668
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MobileHomePageComponent, decorators: [{
|
|
31245
32669
|
type: Component,
|
|
@@ -31253,7 +32677,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
31253
32677
|
DsMobileInteractiveListItemPostComponent,
|
|
31254
32678
|
DsMobileInteractiveListItemInquiryComponent,
|
|
31255
32679
|
DsMobileInteractiveListItemMessageComponent,
|
|
31256
|
-
DsMobileInteractiveListItemBookingComponent,
|
|
31257
32680
|
DsMobileInteractiveListItemServiceComponent,
|
|
31258
32681
|
DsMobileOfflineBannerComponent,
|
|
31259
32682
|
PostContentComponent,
|
|
@@ -31275,8 +32698,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
31275
32698
|
#pageComponent
|
|
31276
32699
|
title="Hjem"
|
|
31277
32700
|
headerTitle="Velkommen, Lars"
|
|
32701
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
31278
32702
|
[avatarInitials]="userService.avatarInitials()"
|
|
31279
32703
|
[avatarType]="userService.avatarType()"
|
|
32704
|
+
(notificationClick)="handleNotificationClick()"
|
|
31280
32705
|
(refresh)="handleRefresh($event)"
|
|
31281
32706
|
>
|
|
31282
32707
|
|
|
@@ -31491,6 +32916,8 @@ class MobileInquiriesPageComponent {
|
|
|
31491
32916
|
newInquiryModal;
|
|
31492
32917
|
pageComponent;
|
|
31493
32918
|
inquiriesService = inject(InquiriesService);
|
|
32919
|
+
notificationModal = inject(DsMobileNotificationModalService);
|
|
32920
|
+
notificationService = inject(NotificationService);
|
|
31494
32921
|
constructor(userService, navCtrl, newInquiryModal) {
|
|
31495
32922
|
this.userService = userService;
|
|
31496
32923
|
this.navCtrl = navCtrl;
|
|
@@ -31526,6 +32953,11 @@ class MobileInquiriesPageComponent {
|
|
|
31526
32953
|
console.log('Showing actions for inquiry:', inquiryId);
|
|
31527
32954
|
// Show bottom sheet with actions (edit, delete, etc.)
|
|
31528
32955
|
}
|
|
32956
|
+
async handleNotificationClick() {
|
|
32957
|
+
const tapped = await this.notificationModal.open();
|
|
32958
|
+
if (tapped)
|
|
32959
|
+
console.log('Notification tapped:', tapped.type, tapped.id);
|
|
32960
|
+
}
|
|
31529
32961
|
handleRefresh(event) {
|
|
31530
32962
|
console.log('Pull-to-refresh triggered on inquiries page');
|
|
31531
32963
|
// Check if offline and complete immediately
|
|
@@ -31565,8 +32997,10 @@ class MobileInquiriesPageComponent {
|
|
|
31565
32997
|
<ds-mobile-page-main
|
|
31566
32998
|
#pageComponent
|
|
31567
32999
|
title="Henvendelser"
|
|
33000
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
31568
33001
|
[avatarInitials]="userService.avatarInitials()"
|
|
31569
33002
|
[avatarType]="userService.avatarType()"
|
|
33003
|
+
(notificationClick)="handleNotificationClick()"
|
|
31570
33004
|
(refresh)="handleRefresh($event)">
|
|
31571
33005
|
|
|
31572
33006
|
<!-- Offline indicator -->
|
|
@@ -31630,7 +33064,7 @@ class MobileInquiriesPageComponent {
|
|
|
31630
33064
|
ariaLabel="Create new inquiry"
|
|
31631
33065
|
(clicked)="createNewInquiry()">
|
|
31632
33066
|
</ds-mobile-fab>
|
|
31633
|
-
`, 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"] }] });
|
|
31634
33068
|
}
|
|
31635
33069
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MobileInquiriesPageComponent, decorators: [{
|
|
31636
33070
|
type: Component,
|
|
@@ -31648,8 +33082,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
31648
33082
|
<ds-mobile-page-main
|
|
31649
33083
|
#pageComponent
|
|
31650
33084
|
title="Henvendelser"
|
|
33085
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
31651
33086
|
[avatarInitials]="userService.avatarInitials()"
|
|
31652
33087
|
[avatarType]="userService.avatarType()"
|
|
33088
|
+
(notificationClick)="handleNotificationClick()"
|
|
31653
33089
|
(refresh)="handleRefresh($event)">
|
|
31654
33090
|
|
|
31655
33091
|
<!-- Offline indicator -->
|
|
@@ -32321,6 +33757,87 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
32321
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"] }]
|
|
32322
33758
|
}], ctorParameters: () => [{ type: UserService }, { type: DsMobileLightboxService }, { type: DsMobileChatModalService }] });
|
|
32323
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
|
+
|
|
32324
33841
|
/**
|
|
32325
33842
|
* Whitelabel Demo Modal Component
|
|
32326
33843
|
*
|
|
@@ -33460,7 +34977,11 @@ class MobileTabsExampleComponent {
|
|
|
33460
34977
|
navCtrl;
|
|
33461
34978
|
whitelabelDemoModal = inject(WhitelabelDemoModalService);
|
|
33462
34979
|
trackingPermissionService = inject(TrackingPermissionService);
|
|
34980
|
+
notificationModal = inject(DsMobileNotificationModalService);
|
|
34981
|
+
notificationService = inject(NotificationService);
|
|
34982
|
+
notificationPrompt = inject(NotificationPromptService);
|
|
33463
34983
|
pageLoading = inject(PageLoadingService);
|
|
34984
|
+
showNotificationPrompt = signal(false, ...(ngDevMode ? [{ debugName: "showNotificationPrompt" }] : []));
|
|
33464
34985
|
trackedProfileMenuItems = computed(() => {
|
|
33465
34986
|
const accountActions = [
|
|
33466
34987
|
{
|
|
@@ -33540,15 +35061,15 @@ class MobileTabsExampleComponent {
|
|
|
33540
35061
|
this.userService.setProfileMenuItems(this.trackedProfileMenuItems());
|
|
33541
35062
|
});
|
|
33542
35063
|
}
|
|
33543
|
-
ngOnInit() {
|
|
35064
|
+
async ngOnInit() {
|
|
33544
35065
|
console.log('MobileTabsExampleComponent ngOnInit');
|
|
33545
|
-
// Configure user avatar globally - this is now the single source of truth
|
|
33546
35066
|
this.userService.setDisplayName('Lucas Møller');
|
|
33547
35067
|
this.userService.setAddress('Toftegårds Allé 5A, 3. tv.');
|
|
33548
35068
|
this.userService.setAvatarInitials('LM');
|
|
33549
35069
|
this.userService.setAvatarType('initials');
|
|
33550
|
-
// Initial status refresh ensures menu reflects past ATT choice.
|
|
33551
35070
|
void this.trackingPermissionService.refreshTrackingStatus();
|
|
35071
|
+
await this.notificationPrompt.checkPermissions();
|
|
35072
|
+
this.showNotificationPrompt.set(this.notificationPrompt.shouldShowPrompt());
|
|
33552
35073
|
}
|
|
33553
35074
|
tabs = [
|
|
33554
35075
|
{
|
|
@@ -33655,6 +35176,34 @@ class MobileTabsExampleComponent {
|
|
|
33655
35176
|
});
|
|
33656
35177
|
}
|
|
33657
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
|
+
}
|
|
33658
35207
|
/** Called by the error overlay retry button — clears error and re-navigates to home */
|
|
33659
35208
|
handleRetry() {
|
|
33660
35209
|
this.pageLoading.hasError.set(false);
|
|
@@ -33676,26 +35225,35 @@ class MobileTabsExampleComponent {
|
|
|
33676
35225
|
</div>
|
|
33677
35226
|
}
|
|
33678
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
|
+
|
|
33679
35235
|
<ion-tabs class="ds-tabs-wrapper">
|
|
33680
35236
|
<!-- Tab bar is hidden during the loading state -->
|
|
33681
35237
|
@if (!pageLoading.isCoveringScreen()) {
|
|
33682
35238
|
<ds-mobile-tab-bar
|
|
33683
35239
|
[tabs]="tabs"
|
|
33684
35240
|
[moreMenuItems]="moreMenuItems"
|
|
35241
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
33685
35242
|
[avatarInitials]="userService.avatarInitials()"
|
|
33686
35243
|
[avatarType]="userService.avatarType()"
|
|
33687
35244
|
[profileMenuItems]="profileMenuItems"
|
|
35245
|
+
(notificationClick)="handleNotificationClick()"
|
|
33688
35246
|
(profileActionSelected)="handleProfileAction($event)"
|
|
33689
35247
|
(moreMenuItemSelected)="handleMoreMenuAction($event)"
|
|
33690
35248
|
>
|
|
33691
35249
|
</ds-mobile-tab-bar>
|
|
33692
35250
|
}
|
|
33693
35251
|
</ion-tabs>
|
|
33694
|
-
`, 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"] }] });
|
|
33695
35253
|
}
|
|
33696
35254
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MobileTabsExampleComponent, decorators: [{
|
|
33697
35255
|
type: Component,
|
|
33698
|
-
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: `
|
|
33699
35257
|
<!-- Full-screen loading screen rendered at layout level so it covers the tab bar.
|
|
33700
35258
|
Kept in DOM during exiting so the exit animation can play. -->
|
|
33701
35259
|
@if (pageLoading.isLoading() || pageLoading.isExiting()) {
|
|
@@ -33710,15 +35268,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
33710
35268
|
</div>
|
|
33711
35269
|
}
|
|
33712
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
|
+
|
|
33713
35278
|
<ion-tabs class="ds-tabs-wrapper">
|
|
33714
35279
|
<!-- Tab bar is hidden during the loading state -->
|
|
33715
35280
|
@if (!pageLoading.isCoveringScreen()) {
|
|
33716
35281
|
<ds-mobile-tab-bar
|
|
33717
35282
|
[tabs]="tabs"
|
|
33718
35283
|
[moreMenuItems]="moreMenuItems"
|
|
35284
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
33719
35285
|
[avatarInitials]="userService.avatarInitials()"
|
|
33720
35286
|
[avatarType]="userService.avatarType()"
|
|
33721
35287
|
[profileMenuItems]="profileMenuItems"
|
|
35288
|
+
(notificationClick)="handleNotificationClick()"
|
|
33722
35289
|
(profileActionSelected)="handleProfileAction($event)"
|
|
33723
35290
|
(moreMenuItemSelected)="handleMoreMenuAction($event)"
|
|
33724
35291
|
>
|
|
@@ -33728,393 +35295,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
33728
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"] }]
|
|
33729
35296
|
}], ctorParameters: () => [{ type: UserService }, { type: i1$3.Router }, { type: i1.NavController }] });
|
|
33730
35297
|
|
|
33731
|
-
class DsMobileBookingDetailSheetComponent {
|
|
33732
|
-
modalController;
|
|
33733
|
-
/** `sheet` = bottom sheet. `modal` = `ds-modal-base` shell (active + history bookings). */
|
|
33734
|
-
presentation = 'sheet';
|
|
33735
|
-
data;
|
|
33736
|
-
/** When true the modal sizes to its content instead of filling the screen. */
|
|
33737
|
-
autoHeight = false;
|
|
33738
|
-
get isModalPresentation() {
|
|
33739
|
-
return this.presentation === 'modal';
|
|
33740
|
-
}
|
|
33741
|
-
constructor(modalController) {
|
|
33742
|
-
this.modalController = modalController;
|
|
33743
|
-
}
|
|
33744
|
-
close() {
|
|
33745
|
-
this.modalController.dismiss(null, 'backdrop');
|
|
33746
|
-
}
|
|
33747
|
-
cancelBooking() {
|
|
33748
|
-
this.modalController.dismiss(null, 'cancel');
|
|
33749
|
-
}
|
|
33750
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetComponent, deps: [{ token: i1.ModalController }], target: i0.ɵɵFactoryTarget.Component });
|
|
33751
|
-
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: `
|
|
33752
|
-
@if (presentation === 'modal') {
|
|
33753
|
-
<ds-mobile-modal-base
|
|
33754
|
-
[headerTitle]="data.facilityTitle"
|
|
33755
|
-
[closeButtonLabel]="'Luk'"
|
|
33756
|
-
[isAutoHeight]="autoHeight"
|
|
33757
|
-
[keyboardContentBehavior]="'follow'">
|
|
33758
|
-
|
|
33759
|
-
<ds-mobile-section
|
|
33760
|
-
[showBorder]="false"
|
|
33761
|
-
padding="20px 20px 0 20px">
|
|
33762
|
-
<div class="hero-image-container">
|
|
33763
|
-
@if (data.heroImage) {
|
|
33764
|
-
<img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
|
|
33765
|
-
} @else {
|
|
33766
|
-
<div class="hero-image-placeholder">
|
|
33767
|
-
<ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
|
|
33768
|
-
</div>
|
|
33769
|
-
}
|
|
33770
|
-
</div>
|
|
33771
|
-
</ds-mobile-section>
|
|
33772
|
-
|
|
33773
|
-
<ds-mobile-section padding="20px 20px 20px 20px">
|
|
33774
|
-
<div class="booking-summary-card">
|
|
33775
|
-
<div class="details-section">
|
|
33776
|
-
<h3 class="details-heading">Booking detaljer</h3>
|
|
33777
|
-
<div class="info-rows">
|
|
33778
|
-
@if (data.bookingDate) {
|
|
33779
|
-
<div class="info-row">
|
|
33780
|
-
<ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
|
|
33781
|
-
<span>{{ data.bookingDate }}</span>
|
|
33782
|
-
</div>
|
|
33783
|
-
}
|
|
33784
|
-
@if (data.bookingTime) {
|
|
33785
|
-
<div class="info-row">
|
|
33786
|
-
<ds-icon name="remixTimeLine" size="16px" color="tertiary" />
|
|
33787
|
-
<span>{{ data.bookingTime }}</span>
|
|
33788
|
-
</div>
|
|
33789
|
-
}
|
|
33790
|
-
@if (data.price) {
|
|
33791
|
-
<div class="info-row">
|
|
33792
|
-
<ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
|
|
33793
|
-
<span>{{ data.price }}</span>
|
|
33794
|
-
</div>
|
|
33795
|
-
}
|
|
33796
|
-
@if (data.bookingType) {
|
|
33797
|
-
<div class="info-row">
|
|
33798
|
-
<ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
|
|
33799
|
-
<span>{{ data.bookingType }}</span>
|
|
33800
|
-
</div>
|
|
33801
|
-
}
|
|
33802
|
-
@for (req of data.requirements || []; track req) {
|
|
33803
|
-
<div class="info-row">
|
|
33804
|
-
<ds-icon name="remixLockLine" size="16px" color="tertiary" />
|
|
33805
|
-
<span>{{ req }}</span>
|
|
33806
|
-
</div>
|
|
33807
|
-
}
|
|
33808
|
-
</div>
|
|
33809
|
-
</div>
|
|
33810
|
-
</div>
|
|
33811
|
-
</ds-mobile-section>
|
|
33812
|
-
|
|
33813
|
-
@if (data.canCancel) {
|
|
33814
|
-
<div class="booking-action">
|
|
33815
|
-
<div class="booking-actions-row">
|
|
33816
|
-
<ds-button
|
|
33817
|
-
class="cancel-primary"
|
|
33818
|
-
size="md"
|
|
33819
|
-
variant="secondary"
|
|
33820
|
-
(clicked)="cancelBooking()">
|
|
33821
|
-
Annuller booking
|
|
33822
|
-
</ds-button>
|
|
33823
|
-
</div>
|
|
33824
|
-
</div>
|
|
33825
|
-
}
|
|
33826
|
-
</ds-mobile-modal-base>
|
|
33827
|
-
} @else {
|
|
33828
|
-
<ds-mobile-bottom-sheet-wrapper [showDragHandle]="true">
|
|
33829
|
-
<div class="detail-header">
|
|
33830
|
-
<h2 class="detail-title">{{ data.facilityTitle }}</h2>
|
|
33831
|
-
<ds-icon-button
|
|
33832
|
-
icon="remixCloseLine"
|
|
33833
|
-
variant="ghost"
|
|
33834
|
-
size="sm"
|
|
33835
|
-
(clicked)="close()"
|
|
33836
|
-
aria-label="Luk"
|
|
33837
|
-
/>
|
|
33838
|
-
</div>
|
|
33839
|
-
|
|
33840
|
-
<div class="detail-content">
|
|
33841
|
-
<div class="hero-image-container">
|
|
33842
|
-
@if (data.heroImage) {
|
|
33843
|
-
<img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
|
|
33844
|
-
} @else {
|
|
33845
|
-
<div class="hero-image-placeholder">
|
|
33846
|
-
<ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
|
|
33847
|
-
</div>
|
|
33848
|
-
}
|
|
33849
|
-
</div>
|
|
33850
|
-
|
|
33851
|
-
<div class="booking-summary-card">
|
|
33852
|
-
<div class="details-section">
|
|
33853
|
-
<h3 class="details-heading">Booking detaljer</h3>
|
|
33854
|
-
<div class="info-rows">
|
|
33855
|
-
@if (data.bookingDate) {
|
|
33856
|
-
<div class="info-row">
|
|
33857
|
-
<ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
|
|
33858
|
-
<span>{{ data.bookingDate }}</span>
|
|
33859
|
-
</div>
|
|
33860
|
-
}
|
|
33861
|
-
@if (data.bookingTime) {
|
|
33862
|
-
<div class="info-row">
|
|
33863
|
-
<ds-icon name="remixTimeLine" size="16px" color="tertiary" />
|
|
33864
|
-
<span>{{ data.bookingTime }}</span>
|
|
33865
|
-
</div>
|
|
33866
|
-
}
|
|
33867
|
-
@if (data.price) {
|
|
33868
|
-
<div class="info-row">
|
|
33869
|
-
<ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
|
|
33870
|
-
<span>{{ data.price }}</span>
|
|
33871
|
-
</div>
|
|
33872
|
-
}
|
|
33873
|
-
@if (data.bookingType) {
|
|
33874
|
-
<div class="info-row">
|
|
33875
|
-
<ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
|
|
33876
|
-
<span>{{ data.bookingType }}</span>
|
|
33877
|
-
</div>
|
|
33878
|
-
}
|
|
33879
|
-
@for (req of data.requirements || []; track req) {
|
|
33880
|
-
<div class="info-row">
|
|
33881
|
-
<ds-icon name="remixLockLine" size="16px" color="tertiary" />
|
|
33882
|
-
<span>{{ req }}</span>
|
|
33883
|
-
</div>
|
|
33884
|
-
}
|
|
33885
|
-
</div>
|
|
33886
|
-
</div>
|
|
33887
|
-
</div>
|
|
33888
|
-
|
|
33889
|
-
@if (data.canCancel) {
|
|
33890
|
-
<div class="footer-button-container">
|
|
33891
|
-
<div class="booking-actions-column">
|
|
33892
|
-
<ds-button
|
|
33893
|
-
size="md"
|
|
33894
|
-
variant="secondary"
|
|
33895
|
-
(clicked)="cancelBooking()">
|
|
33896
|
-
Annuller booking
|
|
33897
|
-
</ds-button>
|
|
33898
|
-
</div>
|
|
33899
|
-
</div>
|
|
33900
|
-
}
|
|
33901
|
-
</div>
|
|
33902
|
-
</ds-mobile-bottom-sheet-wrapper>
|
|
33903
|
-
}
|
|
33904
|
-
`, 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"] }] });
|
|
33905
|
-
}
|
|
33906
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetComponent, decorators: [{
|
|
33907
|
-
type: Component,
|
|
33908
|
-
args: [{ selector: 'ds-mobile-booking-detail-sheet', standalone: true, imports: [
|
|
33909
|
-
CommonModule,
|
|
33910
|
-
DsMobileBottomSheetWrapperComponent,
|
|
33911
|
-
DsMobileModalBaseComponent,
|
|
33912
|
-
DsMobileSectionComponent,
|
|
33913
|
-
DsButtonComponent,
|
|
33914
|
-
DsIconComponent,
|
|
33915
|
-
DsIconButtonComponent,
|
|
33916
|
-
], template: `
|
|
33917
|
-
@if (presentation === 'modal') {
|
|
33918
|
-
<ds-mobile-modal-base
|
|
33919
|
-
[headerTitle]="data.facilityTitle"
|
|
33920
|
-
[closeButtonLabel]="'Luk'"
|
|
33921
|
-
[isAutoHeight]="autoHeight"
|
|
33922
|
-
[keyboardContentBehavior]="'follow'">
|
|
33923
|
-
|
|
33924
|
-
<ds-mobile-section
|
|
33925
|
-
[showBorder]="false"
|
|
33926
|
-
padding="20px 20px 0 20px">
|
|
33927
|
-
<div class="hero-image-container">
|
|
33928
|
-
@if (data.heroImage) {
|
|
33929
|
-
<img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
|
|
33930
|
-
} @else {
|
|
33931
|
-
<div class="hero-image-placeholder">
|
|
33932
|
-
<ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
|
|
33933
|
-
</div>
|
|
33934
|
-
}
|
|
33935
|
-
</div>
|
|
33936
|
-
</ds-mobile-section>
|
|
33937
|
-
|
|
33938
|
-
<ds-mobile-section padding="20px 20px 20px 20px">
|
|
33939
|
-
<div class="booking-summary-card">
|
|
33940
|
-
<div class="details-section">
|
|
33941
|
-
<h3 class="details-heading">Booking detaljer</h3>
|
|
33942
|
-
<div class="info-rows">
|
|
33943
|
-
@if (data.bookingDate) {
|
|
33944
|
-
<div class="info-row">
|
|
33945
|
-
<ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
|
|
33946
|
-
<span>{{ data.bookingDate }}</span>
|
|
33947
|
-
</div>
|
|
33948
|
-
}
|
|
33949
|
-
@if (data.bookingTime) {
|
|
33950
|
-
<div class="info-row">
|
|
33951
|
-
<ds-icon name="remixTimeLine" size="16px" color="tertiary" />
|
|
33952
|
-
<span>{{ data.bookingTime }}</span>
|
|
33953
|
-
</div>
|
|
33954
|
-
}
|
|
33955
|
-
@if (data.price) {
|
|
33956
|
-
<div class="info-row">
|
|
33957
|
-
<ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
|
|
33958
|
-
<span>{{ data.price }}</span>
|
|
33959
|
-
</div>
|
|
33960
|
-
}
|
|
33961
|
-
@if (data.bookingType) {
|
|
33962
|
-
<div class="info-row">
|
|
33963
|
-
<ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
|
|
33964
|
-
<span>{{ data.bookingType }}</span>
|
|
33965
|
-
</div>
|
|
33966
|
-
}
|
|
33967
|
-
@for (req of data.requirements || []; track req) {
|
|
33968
|
-
<div class="info-row">
|
|
33969
|
-
<ds-icon name="remixLockLine" size="16px" color="tertiary" />
|
|
33970
|
-
<span>{{ req }}</span>
|
|
33971
|
-
</div>
|
|
33972
|
-
}
|
|
33973
|
-
</div>
|
|
33974
|
-
</div>
|
|
33975
|
-
</div>
|
|
33976
|
-
</ds-mobile-section>
|
|
33977
|
-
|
|
33978
|
-
@if (data.canCancel) {
|
|
33979
|
-
<div class="booking-action">
|
|
33980
|
-
<div class="booking-actions-row">
|
|
33981
|
-
<ds-button
|
|
33982
|
-
class="cancel-primary"
|
|
33983
|
-
size="md"
|
|
33984
|
-
variant="secondary"
|
|
33985
|
-
(clicked)="cancelBooking()">
|
|
33986
|
-
Annuller booking
|
|
33987
|
-
</ds-button>
|
|
33988
|
-
</div>
|
|
33989
|
-
</div>
|
|
33990
|
-
}
|
|
33991
|
-
</ds-mobile-modal-base>
|
|
33992
|
-
} @else {
|
|
33993
|
-
<ds-mobile-bottom-sheet-wrapper [showDragHandle]="true">
|
|
33994
|
-
<div class="detail-header">
|
|
33995
|
-
<h2 class="detail-title">{{ data.facilityTitle }}</h2>
|
|
33996
|
-
<ds-icon-button
|
|
33997
|
-
icon="remixCloseLine"
|
|
33998
|
-
variant="ghost"
|
|
33999
|
-
size="sm"
|
|
34000
|
-
(clicked)="close()"
|
|
34001
|
-
aria-label="Luk"
|
|
34002
|
-
/>
|
|
34003
|
-
</div>
|
|
34004
|
-
|
|
34005
|
-
<div class="detail-content">
|
|
34006
|
-
<div class="hero-image-container">
|
|
34007
|
-
@if (data.heroImage) {
|
|
34008
|
-
<img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
|
|
34009
|
-
} @else {
|
|
34010
|
-
<div class="hero-image-placeholder">
|
|
34011
|
-
<ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
|
|
34012
|
-
</div>
|
|
34013
|
-
}
|
|
34014
|
-
</div>
|
|
34015
|
-
|
|
34016
|
-
<div class="booking-summary-card">
|
|
34017
|
-
<div class="details-section">
|
|
34018
|
-
<h3 class="details-heading">Booking detaljer</h3>
|
|
34019
|
-
<div class="info-rows">
|
|
34020
|
-
@if (data.bookingDate) {
|
|
34021
|
-
<div class="info-row">
|
|
34022
|
-
<ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
|
|
34023
|
-
<span>{{ data.bookingDate }}</span>
|
|
34024
|
-
</div>
|
|
34025
|
-
}
|
|
34026
|
-
@if (data.bookingTime) {
|
|
34027
|
-
<div class="info-row">
|
|
34028
|
-
<ds-icon name="remixTimeLine" size="16px" color="tertiary" />
|
|
34029
|
-
<span>{{ data.bookingTime }}</span>
|
|
34030
|
-
</div>
|
|
34031
|
-
}
|
|
34032
|
-
@if (data.price) {
|
|
34033
|
-
<div class="info-row">
|
|
34034
|
-
<ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
|
|
34035
|
-
<span>{{ data.price }}</span>
|
|
34036
|
-
</div>
|
|
34037
|
-
}
|
|
34038
|
-
@if (data.bookingType) {
|
|
34039
|
-
<div class="info-row">
|
|
34040
|
-
<ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
|
|
34041
|
-
<span>{{ data.bookingType }}</span>
|
|
34042
|
-
</div>
|
|
34043
|
-
}
|
|
34044
|
-
@for (req of data.requirements || []; track req) {
|
|
34045
|
-
<div class="info-row">
|
|
34046
|
-
<ds-icon name="remixLockLine" size="16px" color="tertiary" />
|
|
34047
|
-
<span>{{ req }}</span>
|
|
34048
|
-
</div>
|
|
34049
|
-
}
|
|
34050
|
-
</div>
|
|
34051
|
-
</div>
|
|
34052
|
-
</div>
|
|
34053
|
-
|
|
34054
|
-
@if (data.canCancel) {
|
|
34055
|
-
<div class="footer-button-container">
|
|
34056
|
-
<div class="booking-actions-column">
|
|
34057
|
-
<ds-button
|
|
34058
|
-
size="md"
|
|
34059
|
-
variant="secondary"
|
|
34060
|
-
(clicked)="cancelBooking()">
|
|
34061
|
-
Annuller booking
|
|
34062
|
-
</ds-button>
|
|
34063
|
-
</div>
|
|
34064
|
-
</div>
|
|
34065
|
-
}
|
|
34066
|
-
</div>
|
|
34067
|
-
</ds-mobile-bottom-sheet-wrapper>
|
|
34068
|
-
}
|
|
34069
|
-
`, 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"] }]
|
|
34070
|
-
}], ctorParameters: () => [{ type: i1.ModalController }], propDecorators: { presentation: [{
|
|
34071
|
-
type: Input
|
|
34072
|
-
}], data: [{
|
|
34073
|
-
type: Input
|
|
34074
|
-
}], autoHeight: [{
|
|
34075
|
-
type: Input
|
|
34076
|
-
}], isModalPresentation: [{
|
|
34077
|
-
type: HostBinding,
|
|
34078
|
-
args: ['class.presentation-modal']
|
|
34079
|
-
}] } });
|
|
34080
|
-
|
|
34081
|
-
class DsMobileBookingDetailSheetService extends BaseModalService {
|
|
34082
|
-
bottomSheet;
|
|
34083
|
-
constructor(modalController, bottomSheet) {
|
|
34084
|
-
super(modalController);
|
|
34085
|
-
this.bottomSheet = bottomSheet;
|
|
34086
|
-
}
|
|
34087
|
-
/**
|
|
34088
|
-
* Bottom-sheet presentation (draggable breakpoints). Prefer `openAsModal` for booking lists.
|
|
34089
|
-
*/
|
|
34090
|
-
async open(data) {
|
|
34091
|
-
const modal = await this.bottomSheet.create({
|
|
34092
|
-
component: DsMobileBookingDetailSheetComponent,
|
|
34093
|
-
componentProps: { data },
|
|
34094
|
-
autoHeight: true,
|
|
34095
|
-
backdropDismiss: true,
|
|
34096
|
-
backdropBlur: true,
|
|
34097
|
-
});
|
|
34098
|
-
const result = await modal.onWillDismiss();
|
|
34099
|
-
return { role: result.role, data: result.data ?? undefined };
|
|
34100
|
-
}
|
|
34101
|
-
/** `ds-modal-base` shell — used for active and past bookings. Auto-heights to content. */
|
|
34102
|
-
async openAsModal(data) {
|
|
34103
|
-
const modal = await this.createModal(DsMobileBookingDetailSheetComponent, { data, presentation: 'modal', autoHeight: true }, { keyboardClose: true, autoHeight: true });
|
|
34104
|
-
await modal.present();
|
|
34105
|
-
const result = await modal.onWillDismiss();
|
|
34106
|
-
return { role: result.role, data: result.data ?? undefined };
|
|
34107
|
-
}
|
|
34108
|
-
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 });
|
|
34109
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetService, providedIn: 'root' });
|
|
34110
|
-
}
|
|
34111
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetService, decorators: [{
|
|
34112
|
-
type: Injectable,
|
|
34113
|
-
args: [{
|
|
34114
|
-
providedIn: 'root',
|
|
34115
|
-
}]
|
|
34116
|
-
}], ctorParameters: () => [{ type: i1.ModalController }, { type: DsMobileBottomSheetService }] });
|
|
34117
|
-
|
|
34118
35298
|
class DsMobileBookingCancelConfirmationComponent {
|
|
34119
35299
|
facilityTitle;
|
|
34120
35300
|
facilityThumbnail;
|
|
@@ -34215,6 +35395,8 @@ class MobileBookingPageComponent {
|
|
|
34215
35395
|
userService;
|
|
34216
35396
|
pageComponent;
|
|
34217
35397
|
bookingsSwiper;
|
|
35398
|
+
notificationModal = inject(DsMobileNotificationModalService);
|
|
35399
|
+
notificationService = inject(NotificationService);
|
|
34218
35400
|
cancellingBookingId = signal(null, ...(ngDevMode ? [{ debugName: "cancellingBookingId" }] : []));
|
|
34219
35401
|
lang = signal(resolveLanguage(), ...(ngDevMode ? [{ debugName: "lang" }] : []));
|
|
34220
35402
|
historyLinkText = computed(() => HISTORY_LINK[this.lang()] ?? HISTORY_LINK['da'], ...(ngDevMode ? [{ debugName: "historyLinkText" }] : []));
|
|
@@ -34420,6 +35602,11 @@ class MobileBookingPageComponent {
|
|
|
34420
35602
|
}
|
|
34421
35603
|
], ...(ngDevMode ? [{ debugName: "availableFacilities" }] : []));
|
|
34422
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
|
+
}
|
|
34423
35610
|
handleRefresh(event) {
|
|
34424
35611
|
console.log('Pull-to-refresh triggered');
|
|
34425
35612
|
// Check if offline and complete immediately
|
|
@@ -34710,8 +35897,10 @@ class MobileBookingPageComponent {
|
|
|
34710
35897
|
<ds-mobile-page-main
|
|
34711
35898
|
#pageComponent
|
|
34712
35899
|
[title]="'Bookinger'"
|
|
35900
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
34713
35901
|
[avatarInitials]="userService.avatarInitials()"
|
|
34714
35902
|
[avatarType]="userService.avatarType()"
|
|
35903
|
+
(notificationClick)="handleNotificationClick()"
|
|
34715
35904
|
(refresh)="handleRefresh($event)">
|
|
34716
35905
|
|
|
34717
35906
|
@if (pageComponent.isOffline()) {
|
|
@@ -34816,7 +36005,7 @@ class MobileBookingPageComponent {
|
|
|
34816
36005
|
ariaLabel="Opret facilitet"
|
|
34817
36006
|
(clicked)="openFacilityCreationModal()">
|
|
34818
36007
|
</ds-mobile-fab>
|
|
34819
|
-
`, 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"] }] });
|
|
34820
36009
|
}
|
|
34821
36010
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MobileBookingPageComponent, decorators: [{
|
|
34822
36011
|
type: Component,
|
|
@@ -34833,8 +36022,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
34833
36022
|
<ds-mobile-page-main
|
|
34834
36023
|
#pageComponent
|
|
34835
36024
|
[title]="'Bookinger'"
|
|
36025
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
34836
36026
|
[avatarInitials]="userService.avatarInitials()"
|
|
34837
36027
|
[avatarType]="userService.avatarType()"
|
|
36028
|
+
(notificationClick)="handleNotificationClick()"
|
|
34838
36029
|
(refresh)="handleRefresh($event)">
|
|
34839
36030
|
|
|
34840
36031
|
@if (pageComponent.isOffline()) {
|
|
@@ -36724,9 +37915,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
36724
37915
|
class TenantChatPageComponent {
|
|
36725
37916
|
modalCtrl = inject(ModalController);
|
|
36726
37917
|
userService = inject(UserService);
|
|
37918
|
+
notificationModal = inject(DsMobileNotificationModalService);
|
|
37919
|
+
notificationService = inject(NotificationService);
|
|
36727
37920
|
peerMessaging = inject(PeerMessagingService);
|
|
36728
37921
|
peerChat = inject(PeerChatLauncherService);
|
|
36729
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
|
+
}
|
|
36730
37928
|
handleRefresh(event) {
|
|
36731
37929
|
setTimeout(() => event.target.complete(), 1000);
|
|
36732
37930
|
}
|
|
@@ -36753,8 +37951,10 @@ class TenantChatPageComponent {
|
|
|
36753
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: `
|
|
36754
37952
|
<ds-mobile-page-main
|
|
36755
37953
|
title="Beskeder"
|
|
37954
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
36756
37955
|
[avatarInitials]="userService.avatarInitials()"
|
|
36757
37956
|
[avatarType]="userService.avatarType()"
|
|
37957
|
+
(notificationClick)="handleNotificationClick()"
|
|
36758
37958
|
(refresh)="handleRefresh($event)">
|
|
36759
37959
|
|
|
36760
37960
|
<ds-mobile-section contentGap="0px" padding="12px 20px 20px 20px" [showBorder]="false">
|
|
@@ -36813,7 +38013,7 @@ class TenantChatPageComponent {
|
|
|
36813
38013
|
ariaLabel="Vælg beboer at skrive med"
|
|
36814
38014
|
(clicked)="goToTenants()">
|
|
36815
38015
|
</ds-mobile-fab>
|
|
36816
|
-
`, 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"] }] });
|
|
36817
38017
|
}
|
|
36818
38018
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TenantChatPageComponent, decorators: [{
|
|
36819
38019
|
type: Component,
|
|
@@ -36827,8 +38027,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
36827
38027
|
}, template: `
|
|
36828
38028
|
<ds-mobile-page-main
|
|
36829
38029
|
title="Beskeder"
|
|
38030
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
36830
38031
|
[avatarInitials]="userService.avatarInitials()"
|
|
36831
38032
|
[avatarType]="userService.avatarType()"
|
|
38033
|
+
(notificationClick)="handleNotificationClick()"
|
|
36832
38034
|
(refresh)="handleRefresh($event)">
|
|
36833
38035
|
|
|
36834
38036
|
<ds-mobile-section contentGap="0px" padding="12px 20px 20px 20px" [showBorder]="false">
|
|
@@ -36970,6 +38172,8 @@ const MOCK_VENDORS = [
|
|
|
36970
38172
|
class ServicesPageComponent {
|
|
36971
38173
|
pageComponent;
|
|
36972
38174
|
vendorModal = inject(DsMobileServiceVendorModalService);
|
|
38175
|
+
notificationModal = inject(DsMobileNotificationModalService);
|
|
38176
|
+
notificationService = inject(NotificationService);
|
|
36973
38177
|
newInquiryModal = inject(DsMobileNewInquiryModalService);
|
|
36974
38178
|
inquiriesService = inject(InquiriesService);
|
|
36975
38179
|
navCtrl = inject(NavController);
|
|
@@ -37016,6 +38220,11 @@ class ServicesPageComponent {
|
|
|
37016
38220
|
},
|
|
37017
38221
|
});
|
|
37018
38222
|
}
|
|
38223
|
+
async handleNotificationClick() {
|
|
38224
|
+
const tapped = await this.notificationModal.open();
|
|
38225
|
+
if (tapped)
|
|
38226
|
+
console.log('Notification tapped:', tapped.type, tapped.id);
|
|
38227
|
+
}
|
|
37019
38228
|
handleRefresh(event) {
|
|
37020
38229
|
setTimeout(() => {
|
|
37021
38230
|
event.target?.complete?.();
|
|
@@ -37026,8 +38235,10 @@ class ServicesPageComponent {
|
|
|
37026
38235
|
<ds-mobile-page-main
|
|
37027
38236
|
#pageComponent
|
|
37028
38237
|
[title]="lbl.pageTitle"
|
|
38238
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
37029
38239
|
[avatarInitials]="userService.avatarInitials()"
|
|
37030
38240
|
[avatarType]="userService.avatarType()"
|
|
38241
|
+
(notificationClick)="handleNotificationClick()"
|
|
37031
38242
|
(refresh)="handleRefresh($event)"
|
|
37032
38243
|
>
|
|
37033
38244
|
@if (pageComponent.isOffline()) {
|
|
@@ -37059,7 +38270,7 @@ class ServicesPageComponent {
|
|
|
37059
38270
|
</ds-mobile-section>
|
|
37060
38271
|
}
|
|
37061
38272
|
</ds-mobile-page-main>
|
|
37062
|
-
`, 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"] }] });
|
|
37063
38274
|
}
|
|
37064
38275
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ServicesPageComponent, decorators: [{
|
|
37065
38276
|
type: Component,
|
|
@@ -37073,8 +38284,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
37073
38284
|
<ds-mobile-page-main
|
|
37074
38285
|
#pageComponent
|
|
37075
38286
|
[title]="lbl.pageTitle"
|
|
38287
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
37076
38288
|
[avatarInitials]="userService.avatarInitials()"
|
|
37077
38289
|
[avatarType]="userService.avatarType()"
|
|
38290
|
+
(notificationClick)="handleNotificationClick()"
|
|
37078
38291
|
(refresh)="handleRefresh($event)"
|
|
37079
38292
|
>
|
|
37080
38293
|
@if (pageComponent.isOffline()) {
|
|
@@ -37135,5 +38348,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
37135
38348
|
* Generated bundle index. Do not edit.
|
|
37136
38349
|
*/
|
|
37137
38350
|
|
|
37138
|
-
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 };
|
|
37139
38352
|
//# sourceMappingURL=propbinder-mobile-design.mjs.map
|