@propbinder/mobile-design 0.2.91 → 0.2.97
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 +2258 -864
- package/fesm2022/propbinder-mobile-design.mjs.map +1 -1
- package/index.d.ts +267 -20
- 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
|
*
|
|
@@ -1415,10 +1467,15 @@ class DsMobileListItemComponent {
|
|
|
1415
1467
|
}
|
|
1416
1468
|
|
|
1417
1469
|
<div class="content-main">
|
|
1418
|
-
@if (title()) {
|
|
1419
|
-
<
|
|
1420
|
-
|
|
1421
|
-
|
|
1470
|
+
@if (title() || subtitle()) {
|
|
1471
|
+
<div class="structured-text">
|
|
1472
|
+
@if (title()) {
|
|
1473
|
+
<h3 class="structured-title">{{ title() }}</h3>
|
|
1474
|
+
}
|
|
1475
|
+
@if (subtitle()) {
|
|
1476
|
+
<p class="structured-subtitle">{{ subtitle() }}</p>
|
|
1477
|
+
}
|
|
1478
|
+
</div>
|
|
1422
1479
|
}
|
|
1423
1480
|
|
|
1424
1481
|
<ng-content select="[content-main]" />
|
|
@@ -1440,7 +1497,7 @@ class DsMobileListItemComponent {
|
|
|
1440
1497
|
<ng-content select="[content-trailing]" />
|
|
1441
1498
|
</div>
|
|
1442
1499
|
</div>
|
|
1443
|
-
`, isInline: true, styles: [":host{display:block;position:relative;padding:var(--item-padding-top, 12px) 0 var(--item-padding-bottom, 12px) 0;box-sizing:border-box;--leading-size: 32px;--content-gap: 12px;--interactive-offset: 8px}:host(.flush-top){padding-top:0}:host:after{content:\"\";position:absolute;bottom:0;left:calc(var(--leading-size) + var(--content-gap));right:0;height:1px;background:var(--border-color-default, #e5e5e5);z-index:1;display:var(--divider-display, block)}:host(.no-divider):after{display:none}:host(.no-leading-content):after{left:0}.list-item-inner{display:flex;flex-direction:row;align-items:flex-start;gap:var(--content-gap);position:relative}:host(.align-center) .list-item-inner{align-items:center}:host(.align-bottom) .list-item-inner{align-items:flex-end}:host(.interactive) .list-item-inner:before{content:\"\";position:absolute;top:calc(-1 * var(--interactive-offset));left:calc(-1 * var(--interactive-offset));right:calc(-1 * var(--interactive-offset));bottom:calc(-1 * var(--interactive-offset));background:transparent;border-radius:16px;z-index:0;pointer-events:none}:host(.interactive){cursor:pointer;-webkit-tap-highlight-color:transparent}@media (hover: hover) and (pointer: fine){:host(.interactive):hover .list-item-inner:before{background:var(--color-background-neutral-primary-hover, #f5f5f5)}}:host(.interactive):active .list-item-inner:before{background:var(--color-background-neutral-primary-hover, #f5f5f5)}:host(.interactive):focus-visible{outline:none}:host(.interactive):focus-visible .list-item-inner:before{outline:2px solid var(--color-brand-primary, #5d5fef);outline-offset:2px}:host(.disabled){opacity:.5;pointer-events:none}:host(.loading){pointer-events:none}:host(.variant-compact) .list-item-inner{gap:8px}.content-leading{flex-shrink:0;width:var(--leading-size);height:var(--leading-size);display:flex;align-items:flex-start;justify-content:center;position:relative;z-index:1}:host(.align-center) .content-leading{align-items:center}:host(.align-bottom) .content-leading{align-items:flex-end}.content-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:8px;position:relative;z-index:1;justify-content:flex-start}:host(.align-center) .content-main{justify-content:center}:host(.align-bottom) .content-main{justify-content:flex-end}.content-trailing{flex-shrink:0;display:flex;align-items:flex-start;position:relative;z-index:1}.structured-title{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);margin:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.structured-subtitle{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;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.desktop-more-button::ng-deep button{border-radius:50%!important;box-sizing:border-box!important;width:32px!important;height:32px!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsIconButtonComponent, selector: "ds-icon-button", inputs: ["variant", "size", "icon", "disabled", "loading", "pressed", "expanded", "ariaLabel", "tooltip", "tooltipDisabled", "tooltipPlacement"], outputs: ["clicked", "focused", "blurred"] }] });
|
|
1500
|
+
`, isInline: true, styles: [":host{display:block;position:relative;padding:var(--item-padding-top, 12px) 0 var(--item-padding-bottom, 12px) 0;box-sizing:border-box;--leading-size: 32px;--content-gap: 12px;--interactive-offset: 8px}:host(.flush-top){padding-top:0}:host:after{content:\"\";position:absolute;bottom:0;left:calc(var(--leading-size) + var(--content-gap));right:0;height:1px;background:var(--border-color-default, #e5e5e5);z-index:1;display:var(--divider-display, block)}:host(.no-divider):after{display:none}:host(.no-leading-content):after{left:0}.list-item-inner{display:flex;flex-direction:row;align-items:flex-start;gap:var(--content-gap);position:relative}:host(.align-center) .list-item-inner{align-items:center}:host(.align-bottom) .list-item-inner{align-items:flex-end}:host(.interactive) .list-item-inner:before{content:\"\";position:absolute;top:calc(-1 * var(--interactive-offset));left:calc(-1 * var(--interactive-offset));right:calc(-1 * var(--interactive-offset));bottom:calc(-1 * var(--interactive-offset));background:transparent;border-radius:16px;z-index:0;pointer-events:none}:host(.interactive){cursor:pointer;-webkit-tap-highlight-color:transparent}@media (hover: hover) and (pointer: fine){:host(.interactive):hover .list-item-inner:before{background:var(--color-background-neutral-primary-hover, #f5f5f5)}}:host(.interactive):active .list-item-inner:before{background:var(--color-background-neutral-primary-hover, #f5f5f5)}:host(.interactive):focus-visible{outline:none}:host(.interactive):focus-visible .list-item-inner:before{outline:2px solid var(--color-brand-primary, #5d5fef);outline-offset:2px}:host(.disabled){opacity:.5;pointer-events:none}:host(.loading){pointer-events:none}:host(.variant-compact) .list-item-inner{gap:8px}.content-leading{flex-shrink:0;width:var(--leading-size);height:var(--leading-size);display:flex;align-items:flex-start;justify-content:center;position:relative;z-index:1}:host(.align-center) .content-leading{align-items:center}:host(.align-bottom) .content-leading{align-items:flex-end}.content-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:8px;position:relative;z-index:1;justify-content:flex-start}:host(.align-center) .content-main{justify-content:center}:host(.align-bottom) .content-main{justify-content:flex-end}.content-trailing{flex-shrink:0;display:flex;align-items:flex-start;position:relative;z-index:1}.structured-text{display:flex;flex-direction:column;gap:2px}.structured-title{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);margin:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.structured-subtitle{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;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.desktop-more-button::ng-deep button{border-radius:50%!important;box-sizing:border-box!important;width:32px!important;height:32px!important}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsIconButtonComponent, selector: "ds-icon-button", inputs: ["variant", "size", "icon", "disabled", "loading", "pressed", "expanded", "ariaLabel", "tooltip", "tooltipDisabled", "tooltipPlacement"], outputs: ["clicked", "focused", "blurred"] }] });
|
|
1444
1501
|
}
|
|
1445
1502
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileListItemComponent, decorators: [{
|
|
1446
1503
|
type: Component,
|
|
@@ -1479,10 +1536,15 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
1479
1536
|
}
|
|
1480
1537
|
|
|
1481
1538
|
<div class="content-main">
|
|
1482
|
-
@if (title()) {
|
|
1483
|
-
<
|
|
1484
|
-
|
|
1485
|
-
|
|
1539
|
+
@if (title() || subtitle()) {
|
|
1540
|
+
<div class="structured-text">
|
|
1541
|
+
@if (title()) {
|
|
1542
|
+
<h3 class="structured-title">{{ title() }}</h3>
|
|
1543
|
+
}
|
|
1544
|
+
@if (subtitle()) {
|
|
1545
|
+
<p class="structured-subtitle">{{ subtitle() }}</p>
|
|
1546
|
+
}
|
|
1547
|
+
</div>
|
|
1486
1548
|
}
|
|
1487
1549
|
|
|
1488
1550
|
<ng-content select="[content-main]" />
|
|
@@ -1504,7 +1566,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
1504
1566
|
<ng-content select="[content-trailing]" />
|
|
1505
1567
|
</div>
|
|
1506
1568
|
</div>
|
|
1507
|
-
`, styles: [":host{display:block;position:relative;padding:var(--item-padding-top, 12px) 0 var(--item-padding-bottom, 12px) 0;box-sizing:border-box;--leading-size: 32px;--content-gap: 12px;--interactive-offset: 8px}:host(.flush-top){padding-top:0}:host:after{content:\"\";position:absolute;bottom:0;left:calc(var(--leading-size) + var(--content-gap));right:0;height:1px;background:var(--border-color-default, #e5e5e5);z-index:1;display:var(--divider-display, block)}:host(.no-divider):after{display:none}:host(.no-leading-content):after{left:0}.list-item-inner{display:flex;flex-direction:row;align-items:flex-start;gap:var(--content-gap);position:relative}:host(.align-center) .list-item-inner{align-items:center}:host(.align-bottom) .list-item-inner{align-items:flex-end}:host(.interactive) .list-item-inner:before{content:\"\";position:absolute;top:calc(-1 * var(--interactive-offset));left:calc(-1 * var(--interactive-offset));right:calc(-1 * var(--interactive-offset));bottom:calc(-1 * var(--interactive-offset));background:transparent;border-radius:16px;z-index:0;pointer-events:none}:host(.interactive){cursor:pointer;-webkit-tap-highlight-color:transparent}@media (hover: hover) and (pointer: fine){:host(.interactive):hover .list-item-inner:before{background:var(--color-background-neutral-primary-hover, #f5f5f5)}}:host(.interactive):active .list-item-inner:before{background:var(--color-background-neutral-primary-hover, #f5f5f5)}:host(.interactive):focus-visible{outline:none}:host(.interactive):focus-visible .list-item-inner:before{outline:2px solid var(--color-brand-primary, #5d5fef);outline-offset:2px}:host(.disabled){opacity:.5;pointer-events:none}:host(.loading){pointer-events:none}:host(.variant-compact) .list-item-inner{gap:8px}.content-leading{flex-shrink:0;width:var(--leading-size);height:var(--leading-size);display:flex;align-items:flex-start;justify-content:center;position:relative;z-index:1}:host(.align-center) .content-leading{align-items:center}:host(.align-bottom) .content-leading{align-items:flex-end}.content-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:8px;position:relative;z-index:1;justify-content:flex-start}:host(.align-center) .content-main{justify-content:center}:host(.align-bottom) .content-main{justify-content:flex-end}.content-trailing{flex-shrink:0;display:flex;align-items:flex-start;position:relative;z-index:1}.structured-title{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);margin:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.structured-subtitle{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;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.desktop-more-button::ng-deep button{border-radius:50%!important;box-sizing:border-box!important;width:32px!important;height:32px!important}\n"] }]
|
|
1569
|
+
`, styles: [":host{display:block;position:relative;padding:var(--item-padding-top, 12px) 0 var(--item-padding-bottom, 12px) 0;box-sizing:border-box;--leading-size: 32px;--content-gap: 12px;--interactive-offset: 8px}:host(.flush-top){padding-top:0}:host:after{content:\"\";position:absolute;bottom:0;left:calc(var(--leading-size) + var(--content-gap));right:0;height:1px;background:var(--border-color-default, #e5e5e5);z-index:1;display:var(--divider-display, block)}:host(.no-divider):after{display:none}:host(.no-leading-content):after{left:0}.list-item-inner{display:flex;flex-direction:row;align-items:flex-start;gap:var(--content-gap);position:relative}:host(.align-center) .list-item-inner{align-items:center}:host(.align-bottom) .list-item-inner{align-items:flex-end}:host(.interactive) .list-item-inner:before{content:\"\";position:absolute;top:calc(-1 * var(--interactive-offset));left:calc(-1 * var(--interactive-offset));right:calc(-1 * var(--interactive-offset));bottom:calc(-1 * var(--interactive-offset));background:transparent;border-radius:16px;z-index:0;pointer-events:none}:host(.interactive){cursor:pointer;-webkit-tap-highlight-color:transparent}@media (hover: hover) and (pointer: fine){:host(.interactive):hover .list-item-inner:before{background:var(--color-background-neutral-primary-hover, #f5f5f5)}}:host(.interactive):active .list-item-inner:before{background:var(--color-background-neutral-primary-hover, #f5f5f5)}:host(.interactive):focus-visible{outline:none}:host(.interactive):focus-visible .list-item-inner:before{outline:2px solid var(--color-brand-primary, #5d5fef);outline-offset:2px}:host(.disabled){opacity:.5;pointer-events:none}:host(.loading){pointer-events:none}:host(.variant-compact) .list-item-inner{gap:8px}.content-leading{flex-shrink:0;width:var(--leading-size);height:var(--leading-size);display:flex;align-items:flex-start;justify-content:center;position:relative;z-index:1}:host(.align-center) .content-leading{align-items:center}:host(.align-bottom) .content-leading{align-items:flex-end}.content-main{flex:1;min-width:0;display:flex;flex-direction:column;gap:8px;position:relative;z-index:1;justify-content:flex-start}:host(.align-center) .content-main{justify-content:center}:host(.align-bottom) .content-main{justify-content:flex-end}.content-trailing{flex-shrink:0;display:flex;align-items:flex-start;position:relative;z-index:1}.structured-text{display:flex;flex-direction:column;gap:2px}.structured-title{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);margin:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.structured-subtitle{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;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.desktop-more-button::ng-deep button{border-radius:50%!important;box-sizing:border-box!important;width:32px!important;height:32px!important}\n"] }]
|
|
1508
1570
|
}], ctorParameters: () => [], propDecorators: { leadingSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "leadingSize", required: false }] }], variant: [{ type: i0.Input, args: [{ isSignal: true, alias: "variant", required: false }] }], align: [{ type: i0.Input, args: [{ isSignal: true, alias: "align", required: false }] }], flushTop: [{ type: i0.Input, args: [{ isSignal: true, alias: "flushTop", required: false }] }], interactive: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactive", required: false }] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], loading: [{ type: i0.Input, args: [{ isSignal: true, alias: "loading", required: false }] }], enableLongPress: [{ type: i0.Input, args: [{ isSignal: true, alias: "enableLongPress", required: false }] }], showDesktopMoreButton: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDesktopMoreButton", required: false }] }], moreActions: [{ type: i0.Input, args: [{ isSignal: true, alias: "moreActions", required: false }] }], moreButtonAriaLabel: [{ type: i0.Input, args: [{ isSignal: true, alias: "moreButtonAriaLabel", required: false }] }], interactiveOffset: [{ type: i0.Input, args: [{ isSignal: true, alias: "interactiveOffset", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: false }] }], subtitle: [{ type: i0.Input, args: [{ isSignal: true, alias: "subtitle", required: false }] }], showDivider: [{ type: i0.Input, args: [{ isSignal: true, alias: "showDivider", required: false }] }], dividerSpacing: [{ type: i0.Input, args: [{ isSignal: true, alias: "dividerSpacing", required: false }] }], itemClick: [{ type: i0.Output, args: ["itemClick"] }], moreButtonClick: [{ type: i0.Output, args: ["moreButtonClick"] }] } });
|
|
1509
1571
|
|
|
1510
1572
|
/**
|
|
@@ -5835,6 +5897,9 @@ class DsMobilePageMainComponent extends MobilePageBase {
|
|
|
5835
5897
|
avatarInitials = input('U', ...(ngDevMode ? [{ debugName: "avatarInitials" }] : []));
|
|
5836
5898
|
avatarSrc = input('', ...(ngDevMode ? [{ debugName: "avatarSrc" }] : []));
|
|
5837
5899
|
avatarIconName = input('remixUser3Line', ...(ngDevMode ? [{ debugName: "avatarIconName" }] : []));
|
|
5900
|
+
// Inputs - Notifications
|
|
5901
|
+
showNotification = input(true, ...(ngDevMode ? [{ debugName: "showNotification" }] : []));
|
|
5902
|
+
notificationCount = input(0, ...(ngDevMode ? [{ debugName: "notificationCount" }] : []));
|
|
5838
5903
|
// Inputs - Features
|
|
5839
5904
|
showRefresh = input(true, ...(ngDevMode ? [{ debugName: "showRefresh" }] : []));
|
|
5840
5905
|
showCondensedHeader = input(true, ...(ngDevMode ? [{ debugName: "showCondensedHeader" }] : []));
|
|
@@ -5872,7 +5937,7 @@ class DsMobilePageMainComponent extends MobilePageBase {
|
|
|
5872
5937
|
* {
|
|
5873
5938
|
* actions: [
|
|
5874
5939
|
* { action: 'profile', title: 'Min profil', icon: 'remixUser3Line' },
|
|
5875
|
-
* { action: 'settings', title: '
|
|
5940
|
+
* { action: 'settings', title: 'Notifikationer', icon: 'remixNotificationLine' }
|
|
5876
5941
|
* ]
|
|
5877
5942
|
* },
|
|
5878
5943
|
* {
|
|
@@ -5885,6 +5950,7 @@ class DsMobilePageMainComponent extends MobilePageBase {
|
|
|
5885
5950
|
*/
|
|
5886
5951
|
profileMenuItems = input(undefined, ...(ngDevMode ? [{ debugName: "profileMenuItems" }] : []));
|
|
5887
5952
|
// Outputs
|
|
5953
|
+
notificationClick = output();
|
|
5888
5954
|
avatarClick = output();
|
|
5889
5955
|
/**
|
|
5890
5956
|
* Emitted when a profile menu action is selected.
|
|
@@ -5920,8 +5986,8 @@ class DsMobilePageMainComponent extends MobilePageBase {
|
|
|
5920
5986
|
},
|
|
5921
5987
|
{
|
|
5922
5988
|
action: 'settings',
|
|
5923
|
-
title: '
|
|
5924
|
-
icon: '
|
|
5989
|
+
title: 'Notifikationer',
|
|
5990
|
+
icon: 'remixNotificationLine',
|
|
5925
5991
|
destructive: false,
|
|
5926
5992
|
},
|
|
5927
5993
|
{
|
|
@@ -6074,7 +6140,7 @@ class DsMobilePageMainComponent extends MobilePageBase {
|
|
|
6074
6140
|
this.refresh.emit(event);
|
|
6075
6141
|
}
|
|
6076
6142
|
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: `
|
|
6143
|
+
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 }, showNotification: { classPropertyName: "showNotification", publicName: "showNotification", 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
6144
|
<!-- Fixed header at top -->
|
|
6079
6145
|
<ion-header>
|
|
6080
6146
|
<ion-toolbar>
|
|
@@ -6085,8 +6151,14 @@ class DsMobilePageMainComponent extends MobilePageBase {
|
|
|
6085
6151
|
<!-- Title - fades in on scroll -->
|
|
6086
6152
|
<ion-title class="header-main__title">{{ title() }}</ion-title>
|
|
6087
6153
|
|
|
6088
|
-
<!-- Avatar -->
|
|
6154
|
+
<!-- Notification + Avatar -->
|
|
6089
6155
|
<div class="header-main__actions">
|
|
6156
|
+
@if (showNotification()) {
|
|
6157
|
+
<ds-mobile-notification-button
|
|
6158
|
+
[count]="notificationCount()"
|
|
6159
|
+
(clicked)="notificationClick.emit()"
|
|
6160
|
+
/>
|
|
6161
|
+
}
|
|
6090
6162
|
<ds-avatar
|
|
6091
6163
|
[size]="'md'"
|
|
6092
6164
|
[type]="avatarType()"
|
|
@@ -6151,11 +6223,11 @@ class DsMobilePageMainComponent extends MobilePageBase {
|
|
|
6151
6223
|
</div>
|
|
6152
6224
|
</div>
|
|
6153
6225
|
</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"] }] });
|
|
6226
|
+
`, 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
6227
|
}
|
|
6156
6228
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobilePageMainComponent, decorators: [{
|
|
6157
6229
|
type: Component,
|
|
6158
|
-
args: [{ selector: 'ds-mobile-page-main', standalone: true, imports: [CommonModule, IonHeader, IonToolbar, IonTitle, IonContent, IonRefresher, IonRefresherContent, DsAvatarComponent, DsLogoComponent, DsMobileGlassSpinnerComponent], host: {
|
|
6230
|
+
args: [{ selector: 'ds-mobile-page-main', standalone: true, imports: [CommonModule, IonHeader, IonToolbar, IonTitle, IonContent, IonRefresher, IonRefresherContent, DsAvatarComponent, DsLogoComponent, DsMobileGlassSpinnerComponent, DsMobileNotificationButtonComponent], host: {
|
|
6159
6231
|
'[style.--content-wrapper-padding]': 'contentPadding()'
|
|
6160
6232
|
}, template: `
|
|
6161
6233
|
<!-- Fixed header at top -->
|
|
@@ -6168,8 +6240,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
6168
6240
|
<!-- Title - fades in on scroll -->
|
|
6169
6241
|
<ion-title class="header-main__title">{{ title() }}</ion-title>
|
|
6170
6242
|
|
|
6171
|
-
<!-- Avatar -->
|
|
6243
|
+
<!-- Notification + Avatar -->
|
|
6172
6244
|
<div class="header-main__actions">
|
|
6245
|
+
@if (showNotification()) {
|
|
6246
|
+
<ds-mobile-notification-button
|
|
6247
|
+
[count]="notificationCount()"
|
|
6248
|
+
(clicked)="notificationClick.emit()"
|
|
6249
|
+
/>
|
|
6250
|
+
}
|
|
6173
6251
|
<ds-avatar
|
|
6174
6252
|
[size]="'md'"
|
|
6175
6253
|
[type]="avatarType()"
|
|
@@ -6238,7 +6316,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
6238
6316
|
}], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { ionContent: [{
|
|
6239
6317
|
type: ViewChild,
|
|
6240
6318
|
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"] }] } });
|
|
6319
|
+
}], 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 }] }], showNotification: [{ type: i0.Input, args: [{ isSignal: true, alias: "showNotification", 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
6320
|
|
|
6243
6321
|
/**
|
|
6244
6322
|
* DsMobileInlineTabsComponent
|
|
@@ -6297,16 +6375,16 @@ class DsMobileInlineTabsComponent {
|
|
|
6297
6375
|
}
|
|
6298
6376
|
</div>
|
|
6299
6377
|
} @else if (tab.badge && tab.badge > 0) {
|
|
6300
|
-
<
|
|
6378
|
+
<ds-mobile-count-badge [count]="tab.badge" variant="muted" />
|
|
6301
6379
|
}
|
|
6302
6380
|
</button>
|
|
6303
6381
|
}
|
|
6304
6382
|
</div>
|
|
6305
|
-
`, isInline: true, styles: [".filter-tabs{display:flex;align-items:center;gap:8px;flex-wrap:wrap;height:40px}.filter-tab{min-width:48px;justify-content:center;padding:0 12px;height:32px;border-radius:20px;background:transparent;border:none;font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;color:rgba(var(--header-content-color-rgb, 255, 255, 255),.6);cursor:pointer;transition:all .2s ease;display:flex;align-items:center;gap:6px;white-space:nowrap}.filter-tab.active{background:var(--color-header-accent, #5d5fef);color:var(--color-on-header-accent, white)}.filter-tab:hover:not(.active){background:rgba(var(--header-content-color-rgb, 255, 255, 255),.1)}.tab-badge{
|
|
6383
|
+
`, isInline: true, styles: [".filter-tabs{display:flex;align-items:center;gap:8px;flex-wrap:wrap;height:40px}.filter-tab{min-width:48px;justify-content:center;padding:0 12px;height:32px;border-radius:20px;background:transparent;border:none;font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;color:rgba(var(--header-content-color-rgb, 255, 255, 255),.6);cursor:pointer;transition:all .2s ease;display:flex;align-items:center;gap:6px;white-space:nowrap}.filter-tab.active{background:var(--color-header-accent, #5d5fef);color:var(--color-on-header-accent, white)}.filter-tab:hover:not(.active){background:rgba(var(--header-content-color-rgb, 255, 255, 255),.1)}.filter-tab.active ds-mobile-count-badge{--header-content-color-rgb: var(--color-on-header-accent-rgb, 255, 255, 255);--header-content-color: var(--color-on-header-accent, white)}.filter-tab.has-envelope{gap:0}.envelope-wrapper{position:relative;display:inline-flex;align-items:center;justify-content:center;margin-left:4px}.envelope-badge{position:absolute;top:-3px;right:-5px;background-color:#ff3b30;color:#fff;font-size:10px;font-weight:700;border-radius:9999px;min-width:12px;height:12px;display:flex;align-items:center;justify-content:center;padding:0;line-height:1;box-shadow:0 1px 2px #00000026;z-index:10}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsMobileCountBadgeComponent, selector: "ds-mobile-count-badge", inputs: ["count", "variant"] }] });
|
|
6306
6384
|
}
|
|
6307
6385
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileInlineTabsComponent, decorators: [{
|
|
6308
6386
|
type: Component,
|
|
6309
|
-
args: [{ selector: 'ds-mobile-inline-tabs', standalone: true, imports: [CommonModule, DsIconComponent], template: `
|
|
6387
|
+
args: [{ selector: 'ds-mobile-inline-tabs', standalone: true, imports: [CommonModule, DsIconComponent, DsMobileCountBadgeComponent], template: `
|
|
6310
6388
|
<div class="filter-tabs">
|
|
6311
6389
|
@for (tab of tabs(); track tab.id) {
|
|
6312
6390
|
<button
|
|
@@ -6327,12 +6405,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
6327
6405
|
}
|
|
6328
6406
|
</div>
|
|
6329
6407
|
} @else if (tab.badge && tab.badge > 0) {
|
|
6330
|
-
<
|
|
6408
|
+
<ds-mobile-count-badge [count]="tab.badge" variant="muted" />
|
|
6331
6409
|
}
|
|
6332
6410
|
</button>
|
|
6333
6411
|
}
|
|
6334
6412
|
</div>
|
|
6335
|
-
`, styles: [".filter-tabs{display:flex;align-items:center;gap:8px;flex-wrap:wrap;height:40px}.filter-tab{min-width:48px;justify-content:center;padding:0 12px;height:32px;border-radius:20px;background:transparent;border:none;font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;color:rgba(var(--header-content-color-rgb, 255, 255, 255),.6);cursor:pointer;transition:all .2s ease;display:flex;align-items:center;gap:6px;white-space:nowrap}.filter-tab.active{background:var(--color-header-accent, #5d5fef);color:var(--color-on-header-accent, white)}.filter-tab:hover:not(.active){background:rgba(var(--header-content-color-rgb, 255, 255, 255),.1)}.tab-badge{
|
|
6413
|
+
`, styles: [".filter-tabs{display:flex;align-items:center;gap:8px;flex-wrap:wrap;height:40px}.filter-tab{min-width:48px;justify-content:center;padding:0 12px;height:32px;border-radius:20px;background:transparent;border:none;font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;color:rgba(var(--header-content-color-rgb, 255, 255, 255),.6);cursor:pointer;transition:all .2s ease;display:flex;align-items:center;gap:6px;white-space:nowrap}.filter-tab.active{background:var(--color-header-accent, #5d5fef);color:var(--color-on-header-accent, white)}.filter-tab:hover:not(.active){background:rgba(var(--header-content-color-rgb, 255, 255, 255),.1)}.filter-tab.active ds-mobile-count-badge{--header-content-color-rgb: var(--color-on-header-accent-rgb, 255, 255, 255);--header-content-color: var(--color-on-header-accent, white)}.filter-tab.has-envelope{gap:0}.envelope-wrapper{position:relative;display:inline-flex;align-items:center;justify-content:center;margin-left:4px}.envelope-badge{position:absolute;top:-3px;right:-5px;background-color:#ff3b30;color:#fff;font-size:10px;font-weight:700;border-radius:9999px;min-width:12px;height:12px;display:flex;align-items:center;justify-content:center;padding:0;line-height:1;box-shadow:0 1px 2px #00000026;z-index:10}\n"] }]
|
|
6336
6414
|
}], propDecorators: { tabs: [{ type: i0.Input, args: [{ isSignal: true, alias: "tabs", required: true }] }], activeTab: [{ type: i0.Input, args: [{ isSignal: true, alias: "activeTab", required: true }] }], tabChange: [{ type: i0.Output, args: ["tabChange"] }] } });
|
|
6337
6415
|
|
|
6338
6416
|
/**
|
|
@@ -11756,7 +11834,7 @@ class DsMobileModalBaseComponent extends MobileModalBase {
|
|
|
11756
11834
|
this.headerMeta() ||
|
|
11757
11835
|
this.hasContentInSlot(this.headerLeading) ||
|
|
11758
11836
|
this.hasContentInSlot(this.headerMain) ||
|
|
11759
|
-
this.
|
|
11837
|
+
!!this.headerTrailing);
|
|
11760
11838
|
}
|
|
11761
11839
|
/**
|
|
11762
11840
|
* Check whether header-leading slot has actual projected content.
|
|
@@ -11764,6 +11842,9 @@ class DsMobileModalBaseComponent extends MobileModalBase {
|
|
|
11764
11842
|
hasHeaderLeadingContent() {
|
|
11765
11843
|
return this.hasContentInSlot(this.headerLeading);
|
|
11766
11844
|
}
|
|
11845
|
+
hasHeaderTrailingContent() {
|
|
11846
|
+
return !!this.headerTrailing;
|
|
11847
|
+
}
|
|
11767
11848
|
/**
|
|
11768
11849
|
* Check if a content child slot has actual content
|
|
11769
11850
|
*/
|
|
@@ -19246,11 +19327,14 @@ class DsMobileTabBarComponent {
|
|
|
19246
19327
|
* ```
|
|
19247
19328
|
*/
|
|
19248
19329
|
profileMenuItems;
|
|
19330
|
+
// Notification inputs
|
|
19331
|
+
notificationCount = 0;
|
|
19249
19332
|
moreMenuItems = [];
|
|
19250
19333
|
moreMenuLabel = 'Mere';
|
|
19251
19334
|
moreMenuIcon = 'remixGridLine';
|
|
19252
19335
|
moreMenuIconActive = 'remixGridFill';
|
|
19253
19336
|
// Outputs
|
|
19337
|
+
notificationClick = new EventEmitter();
|
|
19254
19338
|
avatarClick = new EventEmitter();
|
|
19255
19339
|
/**
|
|
19256
19340
|
* Emitted when a profile menu action is selected.
|
|
@@ -19836,7 +19920,7 @@ class DsMobileTabBarComponent {
|
|
|
19836
19920
|
}
|
|
19837
19921
|
}
|
|
19838
19922
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileTabBarComponent, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Component });
|
|
19839
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DsMobileTabBarComponent, isStandalone: true, selector: "ds-mobile-tab-bar", inputs: { tabs: "tabs", avatarType: "avatarType", avatarInitials: "avatarInitials", avatarSrc: "avatarSrc", avatarIconName: "avatarIconName", profileMenuItems: "profileMenuItems", moreMenuItems: "moreMenuItems", moreMenuLabel: "moreMenuLabel", moreMenuIcon: "moreMenuIcon", moreMenuIconActive: "moreMenuIconActive" }, outputs: { avatarClick: "avatarClick", profileActionSelected: "profileActionSelected", moreMenuItemSelected: "moreMenuItemSelected" }, ngImport: i0, template: `
|
|
19923
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DsMobileTabBarComponent, isStandalone: true, selector: "ds-mobile-tab-bar", inputs: { tabs: "tabs", avatarType: "avatarType", avatarInitials: "avatarInitials", avatarSrc: "avatarSrc", avatarIconName: "avatarIconName", profileMenuItems: "profileMenuItems", notificationCount: "notificationCount", moreMenuItems: "moreMenuItems", moreMenuLabel: "moreMenuLabel", moreMenuIcon: "moreMenuIcon", moreMenuIconActive: "moreMenuIconActive" }, outputs: { notificationClick: "notificationClick", avatarClick: "avatarClick", profileActionSelected: "profileActionSelected", moreMenuItemSelected: "moreMenuItemSelected" }, ngImport: i0, template: `
|
|
19840
19924
|
<ion-tab-bar [attr.slot]="isDesktop() ? 'top' : 'bottom'" class="ds-tab-bar" [class.ds-tab-bar--desktop]="isDesktop()">
|
|
19841
19925
|
<!-- Logo (desktop only, full logo in header) -->
|
|
19842
19926
|
<div class="ds-tab-bar__logo">
|
|
@@ -19879,16 +19963,20 @@ class DsMobileTabBarComponent {
|
|
|
19879
19963
|
}
|
|
19880
19964
|
</div>
|
|
19881
19965
|
|
|
19882
|
-
<!-- Avatar (desktop only, positioned via CSS) -->
|
|
19966
|
+
<!-- Notification + Avatar (desktop only, positioned via CSS) -->
|
|
19883
19967
|
<div class="ds-tab-bar__actions">
|
|
19968
|
+
<ds-mobile-notification-button
|
|
19969
|
+
[count]="notificationCount"
|
|
19970
|
+
(clicked)="notificationClick.emit()"
|
|
19971
|
+
/>
|
|
19884
19972
|
<ds-avatar [size]="'md'" [type]="avatarType" [initials]="avatarInitials" [src]="avatarSrc" [iconName]="avatarIconName" (click)="handleAvatarClick()" />
|
|
19885
19973
|
</div>
|
|
19886
19974
|
</ion-tab-bar>
|
|
19887
|
-
`, isInline: true, styles: [":host{--ds-tab-bar-height: 64px}@media (min-width: 768px){:host{display:block;--ds-tab-bar-height: 64px}}@media (max-width: 767px){:host{display:contents}}ion-tabs.ds-tabs-wrapper{height:100%;background:var(--color-header-surface)}ion-tab-button:before,ion-tab-button:after{content:none!important;display:none!important}ion-tab-button[title]:before,ion-tab-button[title]:after{display:none!important}ion-tab-button::part(native):before,ion-tab-button::part(native):after{display:none!important}.ds-tab-bar{--background: var(--color-background-neutral-primary);transition:transform .2s ease-in-out}ion-tab-bar[slot=bottom]{border-top:1px solid var(--border-color-default);padding-top:8px;padding-bottom:max(8px,calc(var(--app-safe-bottom, 0px) - 16px));padding-left:12px;padding-right:12px}@media (max-width: 767px){ion-tab-bar[slot=bottom]{position:fixed;bottom:0;left:0;right:0;z-index:100}}@media (max-width: 767px){:host-context(.plt-android) ion-tab-bar[slot=bottom]{padding-bottom:max(8px,var(--app-safe-bottom, 0px))!important}}@media (max-width: 767px){:host-context(ion-tabs:has(ds-mobile-page-details)) .ds-tab-bar{transform:translateY(100%);transition:transform .3s ease}}.ds-tab-bar__logo,.ds-tab-bar__actions{display:none}.ds-tab-bar__tabs{display:flex;width:100%;justify-content:space-around;align-items:center}@media (min-width: 769px){ion-tab-bar[slot=bottom]{padding-bottom:var(--app-safe-bottom, 0px)}}@media (display-mode: standalone){ion-tab-bar[slot=bottom]{padding-bottom:var(--app-safe-bottom, 0px)!important}}@media (min-width: 768px){:host[slot=top]{order:-1!important}:host ion-tab-bar{position:relative!important;bottom:auto!important;top:0!important}ion-tab-bar[slot=top]{--background: var(--color-header-surface);position:relative!important;display:flex!important;align-items:center;padding:12px 24px;height:64px;max-width:none;bottom:auto!important;top:0!important}ion-tab-bar[slot=bottom]{position:relative!important;bottom:auto!important}ion-tabs>div:not([slot]){order:1!important}.ds-tab-bar__logo{display:flex;position:absolute;left:24px;align-items:center;color:var(--header-content-color, white)}.ds-tab-bar__actions{display:flex;position:absolute;right:24px;align-items:center;gap:12px}.ds-tab-bar__tabs{display:flex;gap:8px;align-items:center;max-width:640px;width:100%;margin:0 auto;justify-content:center;padding-left:var(--content-padding-md);padding-right:var(--content-padding-md)}.logomark{height:28px;width:auto;flex-shrink:0}}@media (min-width: 992px){.ds-tab-bar__tabs{max-width:640px;padding-left:var(--content-padding-lg);padding-right:var(--content-padding-lg);justify-content:center}}@media (min-width: 1440px){.ds-tab-bar__tabs{max-width:640px;padding-left:var(--content-padding-xl);padding-right:var(--content-padding-xl)}}@media (min-width: 1768px){.ds-tab-bar__tabs{max-width:640px;padding-left:var(--content-padding-2xl);padding-right:var(--content-padding-2xl)}}@media (min-width: 1920px){.ds-tab-bar__tabs{max-width:640px;padding-left:var(--content-padding-3xl);padding-right:var(--content-padding-3xl)}}ion-tab-button{--color: var(--text-color-default-tertiary);--color-selected: var(--color-accent);--padding-start: 0;--padding-end: 0;--ripple-color: transparent;display:flex;flex-direction:column;align-items:center;justify-content:center;position:relative;overflow:visible;pointer-events:auto}ion-tab-button[title]:before{content:attr(title);position:absolute;opacity:0;pointer-events:none}.tab-icon-ripple{position:absolute;left:50%;top:50%;width:40px;height:40px;border-radius:50%;background:var(--color-accent);transform:translate(-50%,-50%) scale(0);opacity:0;pointer-events:none;transition:all .6s cubic-bezier(.36,1.2,.04,1.4);z-index:0}.tab-selected .tab-icon-ripple{transform:translate(-50%,-50%) scale(2);opacity:.05;animation:ripple-fade .6s cubic-bezier(.36,.5,.04,1.8) forwards}@keyframes ripple-fade{0%{opacity:0;transform:translate(-50%,-50%) scale(0)}30%{opacity:.1}to{opacity:0;transform:translate(-50%,-50%) scale(2)}}ion-tab-button::part(native){overflow:visible}ion-tab-button ion-ripple-effect{color:var(--color-accent);border-radius:1000px}ion-tab-button ion-label{font-size:11px;font-weight:500;letter-spacing:-.5px;margin-top:0}.tab-icon-wrapper{position:relative;width:24px;height:24px;display:flex;align-items:center;justify-content:center;z-index:1;margin-bottom:4px}.tab-icon-inactive,.tab-icon-active{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);transition:all .8s cubic-bezier(.36,1,.04,1)}.tab-icon-inactive{opacity:1;transform:translate(-50%,-50%) scale(1)}.tab-icon-active{opacity:0;transform:translate(-50%,calc(-50% - 12px)) scale(.5)}.tab-selected .tab-icon-inactive{opacity:0;transform:translate(-50%,-50%) scale(.5)}.tab-selected .tab-icon-active{opacity:1;transform:translate(-50%,-50%) scale(1)}@media (min-width: 768px){.ds-tab-button{flex-direction:row;height:40px;padding:0 16px!important;border-radius:40px;transition:all .2s ease;width:-moz-fit-content;width:fit-content;min-width:-moz-fit-content;min-width:fit-content;flex:0 0 auto;--color: rgba(var(--color-header-content-rgb, 255, 255, 255), .7);--color-selected: var(--color-header-content, white);color:rgba(var(--color-header-content-rgb, 255, 255, 255),.7);background:transparent;position:relative;overflow:hidden}.tab-icon-wrapper,.tab-icon-ripple{width:20px;height:20px}.ds-tab-button::part(native){border-radius:40px}.ds-tab-button:hover:not(.tab-selected){--color: var(--color-header-content, white);--color-selected: var(--color-header-content, white);color:var(--color-header-content, white);background:rgba(var(--color-header-content-rgb, 255, 255, 255),.1)}.ds-tab-button:hover:not(.tab-selected) ion-label{color:var(--color-header-content, white)}.ds-tab-button:hover:not(.tab-selected) ds-icon{--icon-color: var(--color-header-content, white);color:var(--color-header-content, white)}.ds-tab-button:hover:not(.tab-selected) ds-icon svg{fill:var(--color-header-content, white)}.ds-tab-button.tab-selected,.ds-tab-button.tab-selected:hover{background:var(--color-header-accent);--color-selected: var(--color-on-header-accent, white);--color: var(--color-on-header-accent, white);color:var(--color-on-header-accent, white)}.ds-tab-button.tab-selected:hover ion-label{color:var(--color-on-header-accent, white)}.ds-tab-button.tab-selected:hover ds-icon{--icon-color: var(--color-on-header-accent, white);color:var(--color-on-header-accent, white)}.ds-tab-button.tab-selected:hover ds-icon svg{fill:var(--color-on-header-accent, white)}.ds-tab-button.tab-selected:hover .tab-icon-active{opacity:1!important;visibility:visible!important}.ds-tab-button.tab-selected:hover .tab-icon-inactive{opacity:0!important}.ds-tab-button.tab-selected ion-label{color:var(--color-on-header-accent, white)}.ds-tab-button.tab-selected ds-icon{--icon-color: var(--color-on-header-accent, white);color:var(--color-on-header-accent, white)}.ds-tab-button.tab-selected ds-icon svg{fill:var(--color-on-header-accent, white)}.ds-tab-button .button-native{width:auto;padding:0}.ds-tab-button ion-label{font-size:var(--font-size-sm);font-weight:500;margin:0;color:inherit}.ds-tab-button .tab-icon-wrapper{margin-right:4px;margin-bottom:0}.ds-tab-button ion-ripple-effect{color:rgba(var(--header-content-color-rgb, 255, 255, 255),.3);border-radius:1000px;transform:scale(1.5)}}@media (min-width: 768px){.ds-tab-bar__actions ds-avatar{cursor:pointer;transition:transform .2s ease}.ds-tab-bar__actions ds-avatar:hover{transform:scale(1.05)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: IonTabBar, selector: "ion-tab-bar", inputs: ["color", "mode", "selectedTab", "translucent"] }, { kind: "component", type: IonTabButton, selector: "ion-tab-button", inputs: ["disabled", "download", "href", "layout", "mode", "rel", "selected", "tab", "target"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsAvatarComponent, selector: "ds-avatar", inputs: ["type", "size", "initials", "src", "alt", "iconName", "iconColor"] }, { kind: "component", type: DsLogoComponent, selector: "ds-logo", inputs: ["variant", "size", "customHeight", "customWidth"] }] });
|
|
19975
|
+
`, isInline: true, styles: [":host{--ds-tab-bar-height: 64px}@media (min-width: 768px){:host{display:block;--ds-tab-bar-height: 64px}}@media (max-width: 767px){:host{display:contents}}ion-tabs.ds-tabs-wrapper{height:100%;background:var(--color-header-surface)}ion-tab-button:before,ion-tab-button:after{content:none!important;display:none!important}ion-tab-button[title]:before,ion-tab-button[title]:after{display:none!important}ion-tab-button::part(native):before,ion-tab-button::part(native):after{display:none!important}.ds-tab-bar{--background: var(--color-background-neutral-primary);transition:transform .2s ease-in-out}ion-tab-bar[slot=bottom]{border-top:1px solid var(--border-color-default);padding-top:8px;padding-bottom:max(8px,calc(var(--app-safe-bottom, 0px) - 16px));padding-left:12px;padding-right:12px}@media (max-width: 767px){ion-tab-bar[slot=bottom]{position:fixed;bottom:0;left:0;right:0;z-index:100}}@media (max-width: 767px){:host-context(.plt-android) ion-tab-bar[slot=bottom]{padding-bottom:max(8px,var(--app-safe-bottom, 0px))!important}}@media (max-width: 767px){:host-context(ion-tabs:has(ds-mobile-page-details)) .ds-tab-bar{transform:translateY(100%);transition:transform .3s ease}}.ds-tab-bar__logo,.ds-tab-bar__actions{display:none}.ds-tab-bar__tabs{display:flex;width:100%;justify-content:space-around;align-items:center}@media (min-width: 769px){ion-tab-bar[slot=bottom]{padding-bottom:var(--app-safe-bottom, 0px)}}@media (display-mode: standalone){ion-tab-bar[slot=bottom]{padding-bottom:var(--app-safe-bottom, 0px)!important}}@media (min-width: 768px){:host[slot=top]{order:-1!important}:host ion-tab-bar{position:relative!important;bottom:auto!important;top:0!important}ion-tab-bar[slot=top]{--background: var(--color-header-surface);position:relative!important;display:flex!important;align-items:center;padding:12px 24px;height:64px;max-width:none;bottom:auto!important;top:0!important}ion-tab-bar[slot=bottom]{position:relative!important;bottom:auto!important}ion-tabs>div:not([slot]){order:1!important}.ds-tab-bar__logo{display:flex;position:absolute;left:24px;align-items:center;color:var(--header-content-color, white)}.ds-tab-bar__actions{display:flex;position:absolute;right:24px;align-items:center;gap:12px}.ds-tab-bar__tabs{display:flex;gap:8px;align-items:center;max-width:640px;width:100%;margin:0 auto;justify-content:center;padding-left:var(--content-padding-md);padding-right:var(--content-padding-md)}.logomark{height:28px;width:auto;flex-shrink:0}}@media (min-width: 992px){.ds-tab-bar__tabs{max-width:640px;padding-left:var(--content-padding-lg);padding-right:var(--content-padding-lg);justify-content:center}}@media (min-width: 1440px){.ds-tab-bar__tabs{max-width:640px;padding-left:var(--content-padding-xl);padding-right:var(--content-padding-xl)}}@media (min-width: 1768px){.ds-tab-bar__tabs{max-width:640px;padding-left:var(--content-padding-2xl);padding-right:var(--content-padding-2xl)}}@media (min-width: 1920px){.ds-tab-bar__tabs{max-width:640px;padding-left:var(--content-padding-3xl);padding-right:var(--content-padding-3xl)}}ion-tab-button{--color: var(--text-color-default-tertiary);--color-selected: var(--color-accent);--padding-start: 0;--padding-end: 0;--ripple-color: transparent;display:flex;flex-direction:column;align-items:center;justify-content:center;position:relative;overflow:visible;pointer-events:auto}ion-tab-button[title]:before{content:attr(title);position:absolute;opacity:0;pointer-events:none}.tab-icon-ripple{position:absolute;left:50%;top:50%;width:40px;height:40px;border-radius:50%;background:var(--color-accent);transform:translate(-50%,-50%) scale(0);opacity:0;pointer-events:none;transition:all .6s cubic-bezier(.36,1.2,.04,1.4);z-index:0}.tab-selected .tab-icon-ripple{transform:translate(-50%,-50%) scale(2);opacity:.05;animation:ripple-fade .6s cubic-bezier(.36,.5,.04,1.8) forwards}@keyframes ripple-fade{0%{opacity:0;transform:translate(-50%,-50%) scale(0)}30%{opacity:.1}to{opacity:0;transform:translate(-50%,-50%) scale(2)}}ion-tab-button::part(native){overflow:visible}ion-tab-button ion-ripple-effect{color:var(--color-accent);border-radius:1000px}ion-tab-button ion-label{font-size:11px;font-weight:500;letter-spacing:-.5px;margin-top:0}.tab-icon-wrapper{position:relative;width:24px;height:24px;display:flex;align-items:center;justify-content:center;z-index:1;margin-bottom:4px}.tab-icon-inactive,.tab-icon-active{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);transition:all .8s cubic-bezier(.36,1,.04,1)}.tab-icon-inactive{opacity:1;transform:translate(-50%,-50%) scale(1)}.tab-icon-active{opacity:0;transform:translate(-50%,calc(-50% - 12px)) scale(.5)}.tab-selected .tab-icon-inactive{opacity:0;transform:translate(-50%,-50%) scale(.5)}.tab-selected .tab-icon-active{opacity:1;transform:translate(-50%,-50%) scale(1)}@media (min-width: 768px){.ds-tab-button{flex-direction:row;height:40px;padding:0 16px!important;border-radius:40px;transition:all .2s ease;width:-moz-fit-content;width:fit-content;min-width:-moz-fit-content;min-width:fit-content;flex:0 0 auto;--color: rgba(var(--color-header-content-rgb, 255, 255, 255), .7);--color-selected: var(--color-header-content, white);color:rgba(var(--color-header-content-rgb, 255, 255, 255),.7);background:transparent;position:relative;overflow:hidden}.tab-icon-wrapper,.tab-icon-ripple{width:20px;height:20px}.ds-tab-button::part(native){border-radius:40px}.ds-tab-button:hover:not(.tab-selected){--color: var(--color-header-content, white);--color-selected: var(--color-header-content, white);color:var(--color-header-content, white);background:rgba(var(--color-header-content-rgb, 255, 255, 255),.1)}.ds-tab-button:hover:not(.tab-selected) ion-label{color:var(--color-header-content, white)}.ds-tab-button:hover:not(.tab-selected) ds-icon{--icon-color: var(--color-header-content, white);color:var(--color-header-content, white)}.ds-tab-button:hover:not(.tab-selected) ds-icon svg{fill:var(--color-header-content, white)}.ds-tab-button.tab-selected,.ds-tab-button.tab-selected:hover{background:var(--color-header-accent);--color-selected: var(--color-on-header-accent, white);--color: var(--color-on-header-accent, white);color:var(--color-on-header-accent, white)}.ds-tab-button.tab-selected:hover ion-label{color:var(--color-on-header-accent, white)}.ds-tab-button.tab-selected:hover ds-icon{--icon-color: var(--color-on-header-accent, white);color:var(--color-on-header-accent, white)}.ds-tab-button.tab-selected:hover ds-icon svg{fill:var(--color-on-header-accent, white)}.ds-tab-button.tab-selected:hover .tab-icon-active{opacity:1!important;visibility:visible!important}.ds-tab-button.tab-selected:hover .tab-icon-inactive{opacity:0!important}.ds-tab-button.tab-selected ion-label{color:var(--color-on-header-accent, white)}.ds-tab-button.tab-selected ds-icon{--icon-color: var(--color-on-header-accent, white);color:var(--color-on-header-accent, white)}.ds-tab-button.tab-selected ds-icon svg{fill:var(--color-on-header-accent, white)}.ds-tab-button .button-native{width:auto;padding:0}.ds-tab-button ion-label{font-size:var(--font-size-sm);font-weight:500;margin:0;color:inherit}.ds-tab-button .tab-icon-wrapper{margin-right:4px;margin-bottom:0}.ds-tab-button ion-ripple-effect{color:rgba(var(--header-content-color-rgb, 255, 255, 255),.3);border-radius:1000px;transform:scale(1.5)}}@media (min-width: 768px){.ds-tab-bar__actions ds-avatar{cursor:pointer;transition:transform .2s ease}.ds-tab-bar__actions ds-avatar:hover{transform:scale(1.05)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: IonTabBar, selector: "ion-tab-bar", inputs: ["color", "mode", "selectedTab", "translucent"] }, { kind: "component", type: IonTabButton, selector: "ion-tab-button", inputs: ["disabled", "download", "href", "layout", "mode", "rel", "selected", "tab", "target"] }, { kind: "component", type: IonLabel, selector: "ion-label", inputs: ["color", "mode", "position"] }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsAvatarComponent, selector: "ds-avatar", inputs: ["type", "size", "initials", "src", "alt", "iconName", "iconColor"] }, { kind: "component", type: DsLogoComponent, selector: "ds-logo", inputs: ["variant", "size", "customHeight", "customWidth"] }, { kind: "component", type: DsMobileNotificationButtonComponent, selector: "ds-mobile-notification-button", inputs: ["count"], outputs: ["clicked"] }] });
|
|
19888
19976
|
}
|
|
19889
19977
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileTabBarComponent, decorators: [{
|
|
19890
19978
|
type: Component,
|
|
19891
|
-
args: [{ selector: 'ds-mobile-tab-bar', standalone: true, imports: [CommonModule, IonTabBar, IonTabButton, IonLabel, DsIconComponent, DsAvatarComponent, DsLogoComponent], template: `
|
|
19979
|
+
args: [{ selector: 'ds-mobile-tab-bar', standalone: true, imports: [CommonModule, IonTabBar, IonTabButton, IonLabel, DsIconComponent, DsAvatarComponent, DsLogoComponent, DsMobileNotificationButtonComponent], template: `
|
|
19892
19980
|
<ion-tab-bar [attr.slot]="isDesktop() ? 'top' : 'bottom'" class="ds-tab-bar" [class.ds-tab-bar--desktop]="isDesktop()">
|
|
19893
19981
|
<!-- Logo (desktop only, full logo in header) -->
|
|
19894
19982
|
<div class="ds-tab-bar__logo">
|
|
@@ -19931,8 +20019,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
19931
20019
|
}
|
|
19932
20020
|
</div>
|
|
19933
20021
|
|
|
19934
|
-
<!-- Avatar (desktop only, positioned via CSS) -->
|
|
20022
|
+
<!-- Notification + Avatar (desktop only, positioned via CSS) -->
|
|
19935
20023
|
<div class="ds-tab-bar__actions">
|
|
20024
|
+
<ds-mobile-notification-button
|
|
20025
|
+
[count]="notificationCount"
|
|
20026
|
+
(clicked)="notificationClick.emit()"
|
|
20027
|
+
/>
|
|
19936
20028
|
<ds-avatar [size]="'md'" [type]="avatarType" [initials]="avatarInitials" [src]="avatarSrc" [iconName]="avatarIconName" (click)="handleAvatarClick()" />
|
|
19937
20029
|
</div>
|
|
19938
20030
|
</ion-tab-bar>
|
|
@@ -19949,6 +20041,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
19949
20041
|
type: Input
|
|
19950
20042
|
}], profileMenuItems: [{
|
|
19951
20043
|
type: Input
|
|
20044
|
+
}], notificationCount: [{
|
|
20045
|
+
type: Input
|
|
19952
20046
|
}], moreMenuItems: [{
|
|
19953
20047
|
type: Input
|
|
19954
20048
|
}], moreMenuLabel: [{
|
|
@@ -19957,6 +20051,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
19957
20051
|
type: Input
|
|
19958
20052
|
}], moreMenuIconActive: [{
|
|
19959
20053
|
type: Input
|
|
20054
|
+
}], notificationClick: [{
|
|
20055
|
+
type: Output
|
|
19960
20056
|
}], avatarClick: [{
|
|
19961
20057
|
type: Output
|
|
19962
20058
|
}], profileActionSelected: [{
|
|
@@ -20025,7 +20121,7 @@ class DsMobileTabsComponent {
|
|
|
20025
20121
|
(avatarClick)="handleAvatarClick()"
|
|
20026
20122
|
/>
|
|
20027
20123
|
</ion-tabs>
|
|
20028
|
-
`, isInline: true, styles: [":host{display:block;height:100vh;height:100dvh}ion-tabs{height:100%;background:var(--color-header-surface)}@media (max-width: 767px){ion-tabs:has(ds-mobile-page-details) ds-mobile-tab-bar{--tab-bar-transform: translateY(100%)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: IonTabs, selector: "ion-tabs" }, { kind: "component", type: IonTab, selector: "ion-tab", inputs: ["component", "tab"] }, { kind: "component", type: DsMobileTabBarComponent, selector: "ds-mobile-tab-bar", inputs: ["tabs", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "profileMenuItems", "moreMenuItems", "moreMenuLabel", "moreMenuIcon", "moreMenuIconActive"], outputs: ["avatarClick", "profileActionSelected", "moreMenuItemSelected"] }] });
|
|
20124
|
+
`, isInline: true, styles: [":host{display:block;height:100vh;height:100dvh}ion-tabs{height:100%;background:var(--color-header-surface)}@media (max-width: 767px){ion-tabs:has(ds-mobile-page-details) ds-mobile-tab-bar{--tab-bar-transform: translateY(100%)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i1$1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "component", type: IonTabs, selector: "ion-tabs" }, { kind: "component", type: IonTab, selector: "ion-tab", inputs: ["component", "tab"] }, { kind: "component", type: DsMobileTabBarComponent, selector: "ds-mobile-tab-bar", inputs: ["tabs", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "profileMenuItems", "notificationCount", "moreMenuItems", "moreMenuLabel", "moreMenuIcon", "moreMenuIconActive"], outputs: ["notificationClick", "avatarClick", "profileActionSelected", "moreMenuItemSelected"] }] });
|
|
20029
20125
|
}
|
|
20030
20126
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileTabsComponent, decorators: [{
|
|
20031
20127
|
type: Component,
|
|
@@ -21806,7 +21902,7 @@ class DsMobileEmptyStateComponent {
|
|
|
21806
21902
|
}
|
|
21807
21903
|
</div>
|
|
21808
21904
|
</div>
|
|
21809
|
-
`, isInline: true, styles: [":host{display:block}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;text-align:center;gap:24px}.empty-state-image{width:
|
|
21905
|
+
`, isInline: true, styles: [":host{display:block}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;text-align:center;gap:24px}.empty-state-image{width:120px;height:120px;margin:0 auto}.empty-state-text{display:flex;flex-direction:column;gap:8px}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;line-height:1.3;color:var(--color-text-primary, #1a1a1a);margin:0}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:400;line-height:1.4;color:var(--color-text-secondary, #737373);margin:0}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }] });
|
|
21810
21906
|
}
|
|
21811
21907
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileEmptyStateComponent, decorators: [{
|
|
21812
21908
|
type: Component,
|
|
@@ -21825,7 +21921,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
21825
21921
|
}
|
|
21826
21922
|
</div>
|
|
21827
21923
|
</div>
|
|
21828
|
-
`, styles: [":host{display:block}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;text-align:center;gap:24px}.empty-state-image{width:
|
|
21924
|
+
`, styles: [":host{display:block}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;text-align:center;gap:24px}.empty-state-image{width:120px;height:120px;margin:0 auto}.empty-state-text{display:flex;flex-direction:column;gap:8px}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;line-height:1.3;color:var(--color-text-primary, #1a1a1a);margin:0}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:400;line-height:1.4;color:var(--color-text-secondary, #737373);margin:0}\n"] }]
|
|
21829
21925
|
}], propDecorators: { imageSrc: [{ type: i0.Input, args: [{ isSignal: true, alias: "imageSrc", required: false }] }], imageAlt: [{ type: i0.Input, args: [{ isSignal: true, alias: "imageAlt", required: false }] }], title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], description: [{ type: i0.Input, args: [{ isSignal: true, alias: "description", required: false }] }] } });
|
|
21830
21926
|
|
|
21831
21927
|
/**
|
|
@@ -22702,16 +22798,16 @@ class DsMobileCardInlineBannerComponent {
|
|
|
22702
22798
|
|
|
22703
22799
|
<div content-trailing class="item-trailing">
|
|
22704
22800
|
@if (unreadCount() && unreadCount()! > 0) {
|
|
22705
|
-
<
|
|
22801
|
+
<ds-mobile-count-badge [count]="unreadCount()!" variant="accent" />
|
|
22706
22802
|
}
|
|
22707
22803
|
<ds-icon name="remixArrowRightSLine" size="20px" />
|
|
22708
22804
|
</div>
|
|
22709
22805
|
</ds-mobile-card-inline>
|
|
22710
|
-
`, isInline: true, styles: ["
|
|
22806
|
+
`, isInline: true, styles: ["ds-mobile-count-badge{margin-right:8px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsAvatarComponent, selector: "ds-avatar", inputs: ["type", "size", "initials", "src", "alt", "iconName", "iconColor"] }, { kind: "component", type: DsMobileCardInlineComponent, selector: "ds-mobile-card-inline", inputs: ["variant", "disabled"], outputs: ["cardClick"] }, { kind: "component", type: DsMobileCountBadgeComponent, selector: "ds-mobile-count-badge", inputs: ["count", "variant"] }] });
|
|
22711
22807
|
}
|
|
22712
22808
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileCardInlineBannerComponent, decorators: [{
|
|
22713
22809
|
type: Component,
|
|
22714
|
-
args: [{ selector: 'ds-mobile-card-inline-banner', standalone: true, imports: [CommonModule, DsIconComponent, DsAvatarComponent, DsMobileCardInlineComponent], template: `
|
|
22810
|
+
args: [{ selector: 'ds-mobile-card-inline-banner', standalone: true, imports: [CommonModule, DsIconComponent, DsAvatarComponent, DsMobileCardInlineComponent, DsMobileCountBadgeComponent], template: `
|
|
22715
22811
|
<ds-mobile-card-inline
|
|
22716
22812
|
[variant]="layout()"
|
|
22717
22813
|
(cardClick)="handleBannerClick()">
|
|
@@ -22736,12 +22832,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
22736
22832
|
|
|
22737
22833
|
<div content-trailing class="item-trailing">
|
|
22738
22834
|
@if (unreadCount() && unreadCount()! > 0) {
|
|
22739
|
-
<
|
|
22835
|
+
<ds-mobile-count-badge [count]="unreadCount()!" variant="accent" />
|
|
22740
22836
|
}
|
|
22741
22837
|
<ds-icon name="remixArrowRightSLine" size="20px" />
|
|
22742
22838
|
</div>
|
|
22743
22839
|
</ds-mobile-card-inline>
|
|
22744
|
-
`, styles: ["
|
|
22840
|
+
`, styles: ["ds-mobile-count-badge{margin-right:8px}\n"] }]
|
|
22745
22841
|
}], propDecorators: { title: [{ type: i0.Input, args: [{ isSignal: true, alias: "title", required: true }] }], timestamp: [{ type: i0.Input, args: [{ isSignal: true, alias: "timestamp", required: false }] }], unreadCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "unreadCount", required: false }] }], layout: [{ type: i0.Input, args: [{ isSignal: true, alias: "layout", required: false }] }], bannerClick: [{ type: i0.Output, args: ["bannerClick"] }] } });
|
|
22746
22842
|
|
|
22747
22843
|
/**
|
|
@@ -26092,7 +26188,7 @@ class DsMobilePriceSheetComponent {
|
|
|
26092
26188
|
inputmode="numeric"
|
|
26093
26189
|
pattern="[0-9]*"
|
|
26094
26190
|
maxlength="5"
|
|
26095
|
-
[attr.size]="Math.min(customPrice()
|
|
26191
|
+
[attr.size]="Math.min(customPrice().length || 2, 5)"
|
|
26096
26192
|
[(ngModel)]="customPrice"
|
|
26097
26193
|
placeholder="75"
|
|
26098
26194
|
class="price-input-native"
|
|
@@ -26147,7 +26243,7 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
26147
26243
|
inputmode="numeric"
|
|
26148
26244
|
pattern="[0-9]*"
|
|
26149
26245
|
maxlength="5"
|
|
26150
|
-
[attr.size]="Math.min(customPrice()
|
|
26246
|
+
[attr.size]="Math.min(customPrice().length || 2, 5)"
|
|
26151
26247
|
[(ngModel)]="customPrice"
|
|
26152
26248
|
placeholder="75"
|
|
26153
26249
|
class="price-input-native"
|
|
@@ -28624,7 +28720,755 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
28624
28720
|
`, styles: [":host{display:block;width:100%}.property-banner{display:flex;align-items:center;gap:8px;height:44px;padding:4px 10px 4px 6px;background:rgba(var(--header-content-color-rgb, 255, 255, 255),.1);border:none;-webkit-backdrop-filter:blur(10px);backdrop-filter:blur(10px);border-radius:12px;cursor:pointer;transition:background .2s ease;-webkit-tap-highlight-color:transparent}.property-banner:hover{background:rgba(var(--header-content-color-rgb, 255, 255, 255),.12)}.property-banner:active{background:rgba(var(--header-content-color-rgb, 255, 255, 255),.15)}.property-photo{width:32px;height:32px;border-radius:8px;object-fit:cover;flex-shrink:0;background:rgba(var(--header-content-color-rgb, 255, 255, 255),.1)}.property-text{display:flex;flex-direction:column;flex:1;min-width:0}.property-address{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;color:var(--header-content-color, white);line-height:1.4;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.property-meta{font-family:Brockmann,sans-serif;font-size:var(--font-size-xs);font-weight:400;line-height:1.2;letter-spacing:-.26px;color:rgba(var(--header-content-color-rgb, 255, 255, 255),.65);white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.property-chevron{flex-shrink:0;width:16px;height:16px;color:rgba(var(--header-content-color-rgb, 255, 255, 255),.5)}\n"] }]
|
|
28625
28721
|
}], propDecorators: { address: [{ type: i0.Input, args: [{ isSignal: true, alias: "address", required: true }] }], photoUrl: [{ type: i0.Input, args: [{ isSignal: true, alias: "photoUrl", required: true }] }], tenantCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "tenantCount", required: false }] }] } });
|
|
28626
28722
|
|
|
28627
|
-
|
|
28723
|
+
class DsMobileNotificationPromptComponent {
|
|
28724
|
+
whitelabel = inject(WhitelabelService);
|
|
28725
|
+
dismissing = signal(false, ...(ngDevMode ? [{ debugName: "dismissing" }] : []));
|
|
28726
|
+
heading = input('Vær den første til at vide det', ...(ngDevMode ? [{ debugName: "heading" }] : []));
|
|
28727
|
+
subtitle = input('Hold dig opdateret med henvendelser, bookinger, nyheder og alt derimellem.', ...(ngDevMode ? [{ debugName: "subtitle" }] : []));
|
|
28728
|
+
allowLabel = input('Slå notifikationer til', ...(ngDevMode ? [{ debugName: "allowLabel" }] : []));
|
|
28729
|
+
dismissLabel = input('Ikke lige nu', ...(ngDevMode ? [{ debugName: "dismissLabel" }] : []));
|
|
28730
|
+
allow = output();
|
|
28731
|
+
dismiss = output();
|
|
28732
|
+
static EXIT_DURATION = 800;
|
|
28733
|
+
handleAllow() {
|
|
28734
|
+
if (this.dismissing())
|
|
28735
|
+
return;
|
|
28736
|
+
this.dismissing.set(true);
|
|
28737
|
+
setTimeout(() => this.allow.emit(), DsMobileNotificationPromptComponent.EXIT_DURATION);
|
|
28738
|
+
}
|
|
28739
|
+
handleDismiss() {
|
|
28740
|
+
if (this.dismissing())
|
|
28741
|
+
return;
|
|
28742
|
+
this.dismissing.set(true);
|
|
28743
|
+
setTimeout(() => this.dismiss.emit(), DsMobileNotificationPromptComponent.EXIT_DURATION);
|
|
28744
|
+
}
|
|
28745
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileNotificationPromptComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
28746
|
+
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: `
|
|
28747
|
+
<div class="notification-prompt" [class.is-dismissing]="dismissing()">
|
|
28748
|
+
<div
|
|
28749
|
+
class="notification-prompt__backdrop"
|
|
28750
|
+
[style.background]="whitelabel.headerSurface()">
|
|
28751
|
+
</div>
|
|
28752
|
+
|
|
28753
|
+
<!-- Illustration: floating icon tiles -->
|
|
28754
|
+
<div class="notification-prompt__illustration">
|
|
28755
|
+
<div class="icon-tiles">
|
|
28756
|
+
|
|
28757
|
+
<!-- Tile 1: service/heart-handshake (top-center, small 72px) -->
|
|
28758
|
+
<div class="tile-entry tile-entry--1">
|
|
28759
|
+
<div class="icon-tile icon-tile--1">
|
|
28760
|
+
<div class="icon-tile__icon">
|
|
28761
|
+
<svg viewBox="0 0 45 45" fill="none">
|
|
28762
|
+
<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"/>
|
|
28763
|
+
</svg>
|
|
28764
|
+
</div>
|
|
28765
|
+
</div>
|
|
28766
|
+
</div>
|
|
28767
|
+
|
|
28768
|
+
<!-- Tile 2: calendar (right-bottom, medium 88px) -->
|
|
28769
|
+
<div class="tile-entry tile-entry--2">
|
|
28770
|
+
<div class="icon-tile icon-tile--medium icon-tile--2">
|
|
28771
|
+
<div class="icon-tile__icon">
|
|
28772
|
+
<svg viewBox="0 0 24 24" fill="none">
|
|
28773
|
+
<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"/>
|
|
28774
|
+
</svg>
|
|
28775
|
+
</div>
|
|
28776
|
+
</div>
|
|
28777
|
+
</div>
|
|
28778
|
+
|
|
28779
|
+
<!-- Tile 3: documents (bottom-left, small 72px) -->
|
|
28780
|
+
<div class="tile-entry tile-entry--3">
|
|
28781
|
+
<div class="icon-tile icon-tile--3">
|
|
28782
|
+
<div class="icon-tile__icon">
|
|
28783
|
+
<svg viewBox="0 0 24 24" fill="none">
|
|
28784
|
+
<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"/>
|
|
28785
|
+
</svg>
|
|
28786
|
+
</div>
|
|
28787
|
+
</div>
|
|
28788
|
+
</div>
|
|
28789
|
+
|
|
28790
|
+
<!-- Tile 4: messages (right-upper, medium 88px) -->
|
|
28791
|
+
<div class="tile-entry tile-entry--4">
|
|
28792
|
+
<div class="icon-tile icon-tile--medium icon-tile--4">
|
|
28793
|
+
<div class="icon-tile__icon">
|
|
28794
|
+
<svg viewBox="0 0 24 24" fill="none">
|
|
28795
|
+
<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"/>
|
|
28796
|
+
</svg>
|
|
28797
|
+
</div>
|
|
28798
|
+
</div>
|
|
28799
|
+
</div>
|
|
28800
|
+
|
|
28801
|
+
<!-- Tile 5: home (left-middle, medium 88px) -->
|
|
28802
|
+
<div class="tile-entry tile-entry--5">
|
|
28803
|
+
<div class="icon-tile icon-tile--medium icon-tile--5">
|
|
28804
|
+
<div class="icon-tile__icon">
|
|
28805
|
+
<svg viewBox="0 0 24 24" fill="none">
|
|
28806
|
+
<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"/>
|
|
28807
|
+
</svg>
|
|
28808
|
+
</div>
|
|
28809
|
+
</div>
|
|
28810
|
+
</div>
|
|
28811
|
+
|
|
28812
|
+
<!-- Hero: bell icon (center, 120px) -->
|
|
28813
|
+
<div class="tile-entry tile-entry--hero">
|
|
28814
|
+
<div class="icon-tile icon-tile--hero">
|
|
28815
|
+
<div class="icon-tile__icon">
|
|
28816
|
+
<svg viewBox="0 0 24 24" fill="none">
|
|
28817
|
+
<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"/>
|
|
28818
|
+
</svg>
|
|
28819
|
+
</div>
|
|
28820
|
+
<span class="icon-tile__badge">18</span>
|
|
28821
|
+
</div>
|
|
28822
|
+
</div>
|
|
28823
|
+
|
|
28824
|
+
</div>
|
|
28825
|
+
</div>
|
|
28826
|
+
|
|
28827
|
+
<!-- Heading + subtitle -->
|
|
28828
|
+
<div class="notification-prompt__texts">
|
|
28829
|
+
<h1 class="notification-prompt__heading">{{ heading() }}</h1>
|
|
28830
|
+
<p class="notification-prompt__subtitle">{{ subtitle() }}</p>
|
|
28831
|
+
</div>
|
|
28832
|
+
|
|
28833
|
+
<!-- CTA buttons -->
|
|
28834
|
+
<div class="notification-prompt__actions">
|
|
28835
|
+
<ds-button
|
|
28836
|
+
variant="primary"
|
|
28837
|
+
size="md"
|
|
28838
|
+
(clicked)="handleAllow()">
|
|
28839
|
+
{{ allowLabel() }}
|
|
28840
|
+
</ds-button>
|
|
28841
|
+
<ds-button
|
|
28842
|
+
class="dismiss-btn"
|
|
28843
|
+
variant="ghost"
|
|
28844
|
+
size="md"
|
|
28845
|
+
(clicked)="handleDismiss()">
|
|
28846
|
+
{{ dismissLabel() }}
|
|
28847
|
+
</ds-button>
|
|
28848
|
+
</div>
|
|
28849
|
+
</div>
|
|
28850
|
+
`, 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"] }] });
|
|
28851
|
+
}
|
|
28852
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileNotificationPromptComponent, decorators: [{
|
|
28853
|
+
type: Component,
|
|
28854
|
+
args: [{ selector: 'ds-mobile-notification-prompt', standalone: true, imports: [DsButtonComponent], template: `
|
|
28855
|
+
<div class="notification-prompt" [class.is-dismissing]="dismissing()">
|
|
28856
|
+
<div
|
|
28857
|
+
class="notification-prompt__backdrop"
|
|
28858
|
+
[style.background]="whitelabel.headerSurface()">
|
|
28859
|
+
</div>
|
|
28860
|
+
|
|
28861
|
+
<!-- Illustration: floating icon tiles -->
|
|
28862
|
+
<div class="notification-prompt__illustration">
|
|
28863
|
+
<div class="icon-tiles">
|
|
28864
|
+
|
|
28865
|
+
<!-- Tile 1: service/heart-handshake (top-center, small 72px) -->
|
|
28866
|
+
<div class="tile-entry tile-entry--1">
|
|
28867
|
+
<div class="icon-tile icon-tile--1">
|
|
28868
|
+
<div class="icon-tile__icon">
|
|
28869
|
+
<svg viewBox="0 0 45 45" fill="none">
|
|
28870
|
+
<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"/>
|
|
28871
|
+
</svg>
|
|
28872
|
+
</div>
|
|
28873
|
+
</div>
|
|
28874
|
+
</div>
|
|
28875
|
+
|
|
28876
|
+
<!-- Tile 2: calendar (right-bottom, medium 88px) -->
|
|
28877
|
+
<div class="tile-entry tile-entry--2">
|
|
28878
|
+
<div class="icon-tile icon-tile--medium icon-tile--2">
|
|
28879
|
+
<div class="icon-tile__icon">
|
|
28880
|
+
<svg viewBox="0 0 24 24" fill="none">
|
|
28881
|
+
<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"/>
|
|
28882
|
+
</svg>
|
|
28883
|
+
</div>
|
|
28884
|
+
</div>
|
|
28885
|
+
</div>
|
|
28886
|
+
|
|
28887
|
+
<!-- Tile 3: documents (bottom-left, small 72px) -->
|
|
28888
|
+
<div class="tile-entry tile-entry--3">
|
|
28889
|
+
<div class="icon-tile icon-tile--3">
|
|
28890
|
+
<div class="icon-tile__icon">
|
|
28891
|
+
<svg viewBox="0 0 24 24" fill="none">
|
|
28892
|
+
<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"/>
|
|
28893
|
+
</svg>
|
|
28894
|
+
</div>
|
|
28895
|
+
</div>
|
|
28896
|
+
</div>
|
|
28897
|
+
|
|
28898
|
+
<!-- Tile 4: messages (right-upper, medium 88px) -->
|
|
28899
|
+
<div class="tile-entry tile-entry--4">
|
|
28900
|
+
<div class="icon-tile icon-tile--medium icon-tile--4">
|
|
28901
|
+
<div class="icon-tile__icon">
|
|
28902
|
+
<svg viewBox="0 0 24 24" fill="none">
|
|
28903
|
+
<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"/>
|
|
28904
|
+
</svg>
|
|
28905
|
+
</div>
|
|
28906
|
+
</div>
|
|
28907
|
+
</div>
|
|
28908
|
+
|
|
28909
|
+
<!-- Tile 5: home (left-middle, medium 88px) -->
|
|
28910
|
+
<div class="tile-entry tile-entry--5">
|
|
28911
|
+
<div class="icon-tile icon-tile--medium icon-tile--5">
|
|
28912
|
+
<div class="icon-tile__icon">
|
|
28913
|
+
<svg viewBox="0 0 24 24" fill="none">
|
|
28914
|
+
<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"/>
|
|
28915
|
+
</svg>
|
|
28916
|
+
</div>
|
|
28917
|
+
</div>
|
|
28918
|
+
</div>
|
|
28919
|
+
|
|
28920
|
+
<!-- Hero: bell icon (center, 120px) -->
|
|
28921
|
+
<div class="tile-entry tile-entry--hero">
|
|
28922
|
+
<div class="icon-tile icon-tile--hero">
|
|
28923
|
+
<div class="icon-tile__icon">
|
|
28924
|
+
<svg viewBox="0 0 24 24" fill="none">
|
|
28925
|
+
<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"/>
|
|
28926
|
+
</svg>
|
|
28927
|
+
</div>
|
|
28928
|
+
<span class="icon-tile__badge">18</span>
|
|
28929
|
+
</div>
|
|
28930
|
+
</div>
|
|
28931
|
+
|
|
28932
|
+
</div>
|
|
28933
|
+
</div>
|
|
28934
|
+
|
|
28935
|
+
<!-- Heading + subtitle -->
|
|
28936
|
+
<div class="notification-prompt__texts">
|
|
28937
|
+
<h1 class="notification-prompt__heading">{{ heading() }}</h1>
|
|
28938
|
+
<p class="notification-prompt__subtitle">{{ subtitle() }}</p>
|
|
28939
|
+
</div>
|
|
28940
|
+
|
|
28941
|
+
<!-- CTA buttons -->
|
|
28942
|
+
<div class="notification-prompt__actions">
|
|
28943
|
+
<ds-button
|
|
28944
|
+
variant="primary"
|
|
28945
|
+
size="md"
|
|
28946
|
+
(clicked)="handleAllow()">
|
|
28947
|
+
{{ allowLabel() }}
|
|
28948
|
+
</ds-button>
|
|
28949
|
+
<ds-button
|
|
28950
|
+
class="dismiss-btn"
|
|
28951
|
+
variant="ghost"
|
|
28952
|
+
size="md"
|
|
28953
|
+
(clicked)="handleDismiss()">
|
|
28954
|
+
{{ dismissLabel() }}
|
|
28955
|
+
</ds-button>
|
|
28956
|
+
</div>
|
|
28957
|
+
</div>
|
|
28958
|
+
`, 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"] }]
|
|
28959
|
+
}], 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"] }] } });
|
|
28960
|
+
|
|
28961
|
+
const NOTIFICATION_ICON_MAP = {
|
|
28962
|
+
inquiry_update: 'remixFileList3Line',
|
|
28963
|
+
inquiry_assigned: 'remixFileList3Line',
|
|
28964
|
+
inquiry_resolved: 'remixFileList3Line',
|
|
28965
|
+
community_post: 'remixCommunityLine',
|
|
28966
|
+
community_comment: 'remixCommunityLine',
|
|
28967
|
+
community_like: 'remixCommunityLine',
|
|
28968
|
+
community_mention: 'remixCommunityLine',
|
|
28969
|
+
booking_confirmed: 'remixCalendarCheckLine',
|
|
28970
|
+
booking_cancelled: 'remixCalendarCheckLine',
|
|
28971
|
+
booking_reminder: 'remixCalendarCheckLine',
|
|
28972
|
+
facility_available: 'remixCalendarCheckLine',
|
|
28973
|
+
message_new: 'remixMessage3Line',
|
|
28974
|
+
message_group: 'remixMessage3Line',
|
|
28975
|
+
service_update: 'remixServiceLine',
|
|
28976
|
+
handbook_update: 'remixBook2Line',
|
|
28977
|
+
system_announcement: 'remixHomeSmile2Line',
|
|
28978
|
+
system_welcome: 'remixHomeSmile2Line',
|
|
28979
|
+
invite_received: 'remixHomeSmile2Line',
|
|
28980
|
+
family_access: 'remixGroupLine',
|
|
28981
|
+
};
|
|
28982
|
+
|
|
28983
|
+
function minutesAgo(m) { return new Date(Date.now() - m * 60_000); }
|
|
28984
|
+
function hoursAgo(h) { return new Date(Date.now() - h * 3_600_000); }
|
|
28985
|
+
function daysAgo(d, hour = 12, minute = 0) {
|
|
28986
|
+
const date = new Date();
|
|
28987
|
+
date.setDate(date.getDate() - d);
|
|
28988
|
+
date.setHours(hour, minute, 0, 0);
|
|
28989
|
+
return date;
|
|
28990
|
+
}
|
|
28991
|
+
const SAMPLE_NOTIFICATIONS = [
|
|
28992
|
+
// Today — inquiry #2 "Problem med vandtryk"
|
|
28993
|
+
{ 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 },
|
|
28994
|
+
// Today — Mette Larsen commented on post-1
|
|
28995
|
+
{ 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 },
|
|
28996
|
+
// Today — Marcus Lindqvist sent message in conv-2
|
|
28997
|
+
{ 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 },
|
|
28998
|
+
// Today — booking-1 "Festlokale på taget" confirmed
|
|
28999
|
+
{ 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 },
|
|
29000
|
+
// Today — Anders Jensen commented on post-2
|
|
29001
|
+
{ 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 },
|
|
29002
|
+
// Yesterday — Blik Partner A/S assigned to inquiry #2
|
|
29003
|
+
{ 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 },
|
|
29004
|
+
// Yesterday — Sophie Andersen posted in community (post-2)
|
|
29005
|
+
{ 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 },
|
|
29006
|
+
// Yesterday — booking-3 "Boremaskinen" reminder
|
|
29007
|
+
{ 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 },
|
|
29008
|
+
// Yesterday — facility-1 "Boremaskinen" available
|
|
29009
|
+
{ 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 },
|
|
29010
|
+
// Yesterday — group "Vaskeri & møde" message
|
|
29011
|
+
{ 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 },
|
|
29012
|
+
// Earlier — inquiry #3 resolved
|
|
29013
|
+
{ 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 },
|
|
29014
|
+
// Earlier — handbook updated
|
|
29015
|
+
{ 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 },
|
|
29016
|
+
// Earlier — ElektroTek ApS service update
|
|
29017
|
+
{ 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 },
|
|
29018
|
+
// Earlier — Thomas Hansen commented on post-2
|
|
29019
|
+
{ 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 },
|
|
29020
|
+
// Earlier — booking-2 "Gæsteparkering" cancelled
|
|
29021
|
+
{ 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 },
|
|
29022
|
+
// Earlier — system announcement
|
|
29023
|
+
{ 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 },
|
|
29024
|
+
// Earlier — Karl Johansson message in conv-4
|
|
29025
|
+
{ 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 },
|
|
29026
|
+
// Earlier — Sara Lindqvist family access
|
|
29027
|
+
{ 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 },
|
|
29028
|
+
// Earlier — system welcome
|
|
29029
|
+
{ 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 },
|
|
29030
|
+
];
|
|
29031
|
+
|
|
29032
|
+
const TYPE_TO_CATEGORY = {
|
|
29033
|
+
inquiry_update: 'inquiries',
|
|
29034
|
+
inquiry_assigned: 'inquiries',
|
|
29035
|
+
inquiry_resolved: 'inquiries',
|
|
29036
|
+
community_post: 'community',
|
|
29037
|
+
community_comment: 'community',
|
|
29038
|
+
community_like: 'community',
|
|
29039
|
+
community_mention: 'community',
|
|
29040
|
+
booking_confirmed: 'bookings',
|
|
29041
|
+
booking_cancelled: 'bookings',
|
|
29042
|
+
booking_reminder: 'bookings',
|
|
29043
|
+
facility_available: 'bookings',
|
|
29044
|
+
message_new: 'messages',
|
|
29045
|
+
message_group: 'messages',
|
|
29046
|
+
service_update: 'services',
|
|
29047
|
+
handbook_update: 'handbook',
|
|
29048
|
+
system_announcement: 'system',
|
|
29049
|
+
system_welcome: 'system',
|
|
29050
|
+
invite_received: 'system',
|
|
29051
|
+
family_access: 'system',
|
|
29052
|
+
};
|
|
29053
|
+
class NotificationService {
|
|
29054
|
+
notifications = signal(SAMPLE_NOTIFICATIONS, ...(ngDevMode ? [{ debugName: "notifications" }] : []));
|
|
29055
|
+
unreadCount = computed(() => this.notifications().filter(n => !n.read).length, ...(ngDevMode ? [{ debugName: "unreadCount" }] : []));
|
|
29056
|
+
/**
|
|
29057
|
+
* Push notification delivery preferences per category.
|
|
29058
|
+
* Controls which types of push notifications the device receives —
|
|
29059
|
+
* does NOT filter the in-app notification list.
|
|
29060
|
+
*/
|
|
29061
|
+
disabledPushCategories = signal(new Set(), ...(ngDevMode ? [{ debugName: "disabledPushCategories" }] : []));
|
|
29062
|
+
isPushEnabled(category) {
|
|
29063
|
+
return !this.disabledPushCategories().has(category);
|
|
29064
|
+
}
|
|
29065
|
+
setPushEnabled(category, enabled) {
|
|
29066
|
+
this.disabledPushCategories.update(set => {
|
|
29067
|
+
const next = new Set(set);
|
|
29068
|
+
if (enabled) {
|
|
29069
|
+
next.delete(category);
|
|
29070
|
+
}
|
|
29071
|
+
else {
|
|
29072
|
+
next.add(category);
|
|
29073
|
+
}
|
|
29074
|
+
return next;
|
|
29075
|
+
});
|
|
29076
|
+
}
|
|
29077
|
+
/**
|
|
29078
|
+
* Add a new notification to the top of the list.
|
|
29079
|
+
* Intended for downstream push integration — call this when a
|
|
29080
|
+
* real push payload arrives via Capacitor's `pushNotificationReceived` listener.
|
|
29081
|
+
*/
|
|
29082
|
+
addNotification(item) {
|
|
29083
|
+
this.notifications.update(list => [item, ...list]);
|
|
29084
|
+
}
|
|
29085
|
+
markAsRead(id) {
|
|
29086
|
+
this.notifications.update(list => list.map(n => n.id === id ? { ...n, read: true } : n));
|
|
29087
|
+
}
|
|
29088
|
+
markAllAsRead() {
|
|
29089
|
+
this.notifications.update(list => list.map(n => ({ ...n, read: true })));
|
|
29090
|
+
}
|
|
29091
|
+
/**
|
|
29092
|
+
* Remove a single notification from the list permanently.
|
|
29093
|
+
*/
|
|
29094
|
+
removeNotification(id) {
|
|
29095
|
+
this.notifications.update(list => list.filter(n => n.id !== id));
|
|
29096
|
+
}
|
|
29097
|
+
/**
|
|
29098
|
+
* Remove all notifications from the list permanently.
|
|
29099
|
+
*/
|
|
29100
|
+
clearAll() {
|
|
29101
|
+
this.notifications.set([]);
|
|
29102
|
+
}
|
|
29103
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NotificationService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
29104
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NotificationService, providedIn: 'root' });
|
|
29105
|
+
}
|
|
29106
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NotificationService, decorators: [{
|
|
29107
|
+
type: Injectable,
|
|
29108
|
+
args: [{ providedIn: 'root' }]
|
|
29109
|
+
}] });
|
|
29110
|
+
|
|
29111
|
+
class RelativeTimePipe {
|
|
29112
|
+
transform(date) {
|
|
29113
|
+
if (!date)
|
|
29114
|
+
return '';
|
|
29115
|
+
const now = Date.now();
|
|
29116
|
+
const diffMs = now - date.getTime();
|
|
29117
|
+
const diffSec = Math.floor(diffMs / 1000);
|
|
29118
|
+
const diffMin = Math.floor(diffSec / 60);
|
|
29119
|
+
const diffHr = Math.floor(diffMin / 60);
|
|
29120
|
+
const diffDays = Math.floor(diffHr / 24);
|
|
29121
|
+
if (diffSec < 60)
|
|
29122
|
+
return 'Nu';
|
|
29123
|
+
if (diffMin < 60)
|
|
29124
|
+
return `${diffMin} min siden`;
|
|
29125
|
+
if (diffHr < 24)
|
|
29126
|
+
return `${diffHr} ${diffHr === 1 ? 'time' : 'timer'} siden`;
|
|
29127
|
+
const today = new Date();
|
|
29128
|
+
today.setHours(0, 0, 0, 0);
|
|
29129
|
+
const yesterday = new Date(today.getTime() - 86_400_000);
|
|
29130
|
+
if (date.getTime() >= yesterday.getTime() && date.getTime() < today.getTime()) {
|
|
29131
|
+
return `I går, ${pad(date.getHours())}:${pad(date.getMinutes())}`;
|
|
29132
|
+
}
|
|
29133
|
+
if (diffDays < 7)
|
|
29134
|
+
return `${diffDays} dage siden`;
|
|
29135
|
+
const day = date.getDate();
|
|
29136
|
+
const monthNames = ['jan', 'feb', 'mar', 'apr', 'maj', 'jun', 'jul', 'aug', 'sep', 'okt', 'nov', 'dec'];
|
|
29137
|
+
return `${day}. ${monthNames[date.getMonth()]}`;
|
|
29138
|
+
}
|
|
29139
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: RelativeTimePipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
|
|
29140
|
+
static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.3.16", ngImport: i0, type: RelativeTimePipe, isStandalone: true, name: "relativeTime" });
|
|
29141
|
+
}
|
|
29142
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: RelativeTimePipe, decorators: [{
|
|
29143
|
+
type: Pipe,
|
|
29144
|
+
args: [{ name: 'relativeTime', standalone: true, pure: true }]
|
|
29145
|
+
}] });
|
|
29146
|
+
function pad(n) {
|
|
29147
|
+
return n < 10 ? `0${n}` : `${n}`;
|
|
29148
|
+
}
|
|
29149
|
+
/**
|
|
29150
|
+
* Bucket a date into 'today' | 'yesterday' | 'earlier' for grouping notifications.
|
|
29151
|
+
*/
|
|
29152
|
+
function dateBucket(date) {
|
|
29153
|
+
const now = new Date();
|
|
29154
|
+
const today = new Date(now.getFullYear(), now.getMonth(), now.getDate());
|
|
29155
|
+
const yesterday = new Date(today.getTime() - 86_400_000);
|
|
29156
|
+
if (date.getTime() >= today.getTime())
|
|
29157
|
+
return 'today';
|
|
29158
|
+
if (date.getTime() >= yesterday.getTime())
|
|
29159
|
+
return 'yesterday';
|
|
29160
|
+
return 'earlier';
|
|
29161
|
+
}
|
|
29162
|
+
|
|
29163
|
+
class DsMobileNotificationModalComponent {
|
|
29164
|
+
modalController = inject(ModalController);
|
|
29165
|
+
notificationService = inject(NotificationService);
|
|
29166
|
+
bottomSheet = inject(DsMobileBottomSheetService);
|
|
29167
|
+
groups = computed(() => {
|
|
29168
|
+
const items = this.notificationService.notifications();
|
|
29169
|
+
if (!items || items.length === 0)
|
|
29170
|
+
return [];
|
|
29171
|
+
const todayItems = [];
|
|
29172
|
+
const yesterdayItems = [];
|
|
29173
|
+
const earlierItems = [];
|
|
29174
|
+
for (const item of items) {
|
|
29175
|
+
const bucket = dateBucket(item.createdAt);
|
|
29176
|
+
if (bucket === 'today')
|
|
29177
|
+
todayItems.push(item);
|
|
29178
|
+
else if (bucket === 'yesterday')
|
|
29179
|
+
yesterdayItems.push(item);
|
|
29180
|
+
else
|
|
29181
|
+
earlierItems.push(item);
|
|
29182
|
+
}
|
|
29183
|
+
const groups = [];
|
|
29184
|
+
if (todayItems.length > 0)
|
|
29185
|
+
groups.push({ label: 'I dag', items: todayItems });
|
|
29186
|
+
if (yesterdayItems.length > 0)
|
|
29187
|
+
groups.push({ label: 'I går', items: yesterdayItems });
|
|
29188
|
+
if (earlierItems.length > 0)
|
|
29189
|
+
groups.push({ label: 'Tidligere', items: earlierItems });
|
|
29190
|
+
return groups;
|
|
29191
|
+
}, ...(ngDevMode ? [{ debugName: "groups" }] : []));
|
|
29192
|
+
iconFor(type) {
|
|
29193
|
+
return NOTIFICATION_ICON_MAP[type] ?? 'remixNotificationLine';
|
|
29194
|
+
}
|
|
29195
|
+
TYPE_LABELS = {
|
|
29196
|
+
inquiry_update: 'Henvendelse',
|
|
29197
|
+
inquiry_assigned: 'Henvendelse',
|
|
29198
|
+
inquiry_resolved: 'Henvendelse',
|
|
29199
|
+
community_post: 'Fællesskab',
|
|
29200
|
+
community_comment: 'Kommentar',
|
|
29201
|
+
community_like: 'Fællesskab',
|
|
29202
|
+
community_mention: 'Omtale',
|
|
29203
|
+
booking_confirmed: 'Booking',
|
|
29204
|
+
booking_cancelled: 'Booking',
|
|
29205
|
+
booking_reminder: 'Booking',
|
|
29206
|
+
facility_available: 'Facilitet',
|
|
29207
|
+
message_new: 'Besked',
|
|
29208
|
+
message_group: 'Gruppebesked',
|
|
29209
|
+
service_update: 'Service',
|
|
29210
|
+
handbook_update: 'Håndbog',
|
|
29211
|
+
system_announcement: 'System',
|
|
29212
|
+
system_welcome: 'System',
|
|
29213
|
+
invite_received: 'Invitation',
|
|
29214
|
+
family_access: 'Familie',
|
|
29215
|
+
};
|
|
29216
|
+
labelFor(type) {
|
|
29217
|
+
return this.TYPE_LABELS[type] ?? '';
|
|
29218
|
+
}
|
|
29219
|
+
handleNotificationClick(item) {
|
|
29220
|
+
this.modalController.dismiss(item);
|
|
29221
|
+
}
|
|
29222
|
+
async handleLongPress(item) {
|
|
29223
|
+
const actions = [
|
|
29224
|
+
{ action: 'mark_read', title: item.read ? 'Marker som ulæst' : 'Marker som læst', icon: item.read ? 'remixMailUnreadLine' : 'remixMailOpenLine', destructive: false },
|
|
29225
|
+
{ action: 'remove', title: 'Fjern notifikation', icon: 'remixDeleteBinLine', destructive: true },
|
|
29226
|
+
];
|
|
29227
|
+
const sheet = await this.bottomSheet.create({
|
|
29228
|
+
component: DsMobileActionsBottomSheetComponent,
|
|
29229
|
+
componentProps: { customActionGroups: [{ actions }] },
|
|
29230
|
+
breakpoints: [0, 1],
|
|
29231
|
+
initialBreakpoint: 1,
|
|
29232
|
+
handle: true,
|
|
29233
|
+
backdropDismiss: true,
|
|
29234
|
+
cssClass: 'auto-height',
|
|
29235
|
+
});
|
|
29236
|
+
const result = await sheet.onWillDismiss();
|
|
29237
|
+
if (result.role === 'select' && result.data) {
|
|
29238
|
+
const action = result.data.action;
|
|
29239
|
+
if (action === 'mark_read') {
|
|
29240
|
+
if (item.read) {
|
|
29241
|
+
this.notificationService.notifications.update(list => list.map(n => n.id === item.id ? { ...n, read: false } : n));
|
|
29242
|
+
}
|
|
29243
|
+
else {
|
|
29244
|
+
this.notificationService.markAsRead(item.id);
|
|
29245
|
+
}
|
|
29246
|
+
}
|
|
29247
|
+
else if (action === 'remove') {
|
|
29248
|
+
this.notificationService.removeNotification(item.id);
|
|
29249
|
+
}
|
|
29250
|
+
}
|
|
29251
|
+
}
|
|
29252
|
+
async openBulkActions() {
|
|
29253
|
+
const actions = [
|
|
29254
|
+
{ action: 'mark_all_read', title: 'Marker alle som læst', icon: 'remixMailOpenLine', destructive: false },
|
|
29255
|
+
{ action: 'clear_all', title: 'Ryd alle notifikationer', icon: 'remixDeleteBinLine', destructive: true },
|
|
29256
|
+
];
|
|
29257
|
+
const sheet = await this.bottomSheet.create({
|
|
29258
|
+
component: DsMobileActionsBottomSheetComponent,
|
|
29259
|
+
componentProps: { customActionGroups: [{ actions }] },
|
|
29260
|
+
breakpoints: [0, 1],
|
|
29261
|
+
initialBreakpoint: 1,
|
|
29262
|
+
handle: true,
|
|
29263
|
+
backdropDismiss: true,
|
|
29264
|
+
cssClass: 'auto-height',
|
|
29265
|
+
});
|
|
29266
|
+
const result = await sheet.onWillDismiss();
|
|
29267
|
+
if (result.role === 'select' && result.data) {
|
|
29268
|
+
const action = result.data.action;
|
|
29269
|
+
if (action === 'mark_all_read') {
|
|
29270
|
+
this.notificationService.markAllAsRead();
|
|
29271
|
+
}
|
|
29272
|
+
else if (action === 'clear_all') {
|
|
29273
|
+
this.notificationService.clearAll();
|
|
29274
|
+
}
|
|
29275
|
+
}
|
|
29276
|
+
}
|
|
29277
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileNotificationModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
29278
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DsMobileNotificationModalComponent, isStandalone: true, selector: "ds-mobile-notification-modal", ngImport: i0, template: `
|
|
29279
|
+
<ds-mobile-modal-base
|
|
29280
|
+
headerTitle="Notifikationer"
|
|
29281
|
+
[showHeader]="true"
|
|
29282
|
+
closeButtonLabel="Luk">
|
|
29283
|
+
|
|
29284
|
+
<ds-icon-button
|
|
29285
|
+
header-trailing
|
|
29286
|
+
class="more-button"
|
|
29287
|
+
icon="remixMoreFill"
|
|
29288
|
+
variant="secondary"
|
|
29289
|
+
size="lg"
|
|
29290
|
+
(clicked)="openBulkActions()"
|
|
29291
|
+
aria-label="Flere handlinger"
|
|
29292
|
+
/>
|
|
29293
|
+
|
|
29294
|
+
@if (groups().length > 0) {
|
|
29295
|
+
@for (group of groups(); track group.label) {
|
|
29296
|
+
<div class="notification-group">
|
|
29297
|
+
<div class="notification-group__label">{{ group.label }}</div>
|
|
29298
|
+
|
|
29299
|
+
@for (item of group.items; track item.id) {
|
|
29300
|
+
<ds-mobile-list-item
|
|
29301
|
+
[interactive]="true"
|
|
29302
|
+
[showDivider]="!$last"
|
|
29303
|
+
[enableLongPress]="true"
|
|
29304
|
+
[showDesktopMoreButton]="false"
|
|
29305
|
+
align="top"
|
|
29306
|
+
(itemClick)="handleNotificationClick(item)"
|
|
29307
|
+
(longPress)="handleLongPress(item)">
|
|
29308
|
+
|
|
29309
|
+
@if (item.leading === 'icon') {
|
|
29310
|
+
<ds-avatar
|
|
29311
|
+
content-leading
|
|
29312
|
+
type="icon"
|
|
29313
|
+
[iconName]="item.iconName || iconFor(item.type)"
|
|
29314
|
+
size="md"
|
|
29315
|
+
/>
|
|
29316
|
+
}
|
|
29317
|
+
|
|
29318
|
+
@if (item.leading === 'avatar') {
|
|
29319
|
+
<ds-avatar
|
|
29320
|
+
content-leading
|
|
29321
|
+
[type]="item.avatarSrc ? 'photo' : 'initials'"
|
|
29322
|
+
[initials]="item.avatarInitials || ''"
|
|
29323
|
+
[src]="item.avatarSrc || ''"
|
|
29324
|
+
size="md"
|
|
29325
|
+
/>
|
|
29326
|
+
}
|
|
29327
|
+
|
|
29328
|
+
@if (item.leading === 'image') {
|
|
29329
|
+
<div content-leading class="notification-image">
|
|
29330
|
+
<img [src]="item.imageSrc" [alt]="item.title" />
|
|
29331
|
+
</div>
|
|
29332
|
+
}
|
|
29333
|
+
|
|
29334
|
+
@if (item.leading === 'logo') {
|
|
29335
|
+
<div content-leading class="notification-logo">
|
|
29336
|
+
<ds-app-icon size="lg" />
|
|
29337
|
+
</div>
|
|
29338
|
+
}
|
|
29339
|
+
|
|
29340
|
+
<div content-main class="notification-content">
|
|
29341
|
+
<div class="notification-header">
|
|
29342
|
+
<div class="notification-header__details">
|
|
29343
|
+
<span class="notification-header__name" [class.notification-header__name--unread]="!item.read">
|
|
29344
|
+
{{ item.title }}
|
|
29345
|
+
</span>
|
|
29346
|
+
<span class="notification-header__meta">
|
|
29347
|
+
{{ labelFor(item.type) }}
|
|
29348
|
+
<span class="notification-header__separator">·</span>
|
|
29349
|
+
{{ item.createdAt | relativeTime }}
|
|
29350
|
+
</span>
|
|
29351
|
+
</div>
|
|
29352
|
+
</div>
|
|
29353
|
+
<p class="notification-message">{{ item.message }}</p>
|
|
29354
|
+
</div>
|
|
29355
|
+
|
|
29356
|
+
@if (!item.read) {
|
|
29357
|
+
<div content-trailing class="notification-unread-dot"></div>
|
|
29358
|
+
}
|
|
29359
|
+
</ds-mobile-list-item>
|
|
29360
|
+
}
|
|
29361
|
+
</div>
|
|
29362
|
+
}
|
|
29363
|
+
} @else {
|
|
29364
|
+
<ds-mobile-empty-state
|
|
29365
|
+
imageSrc="/Assets/empty-state-notification.svg"
|
|
29366
|
+
imageAlt="Ingen notifikationer"
|
|
29367
|
+
title="Alt er stille herinde"
|
|
29368
|
+
description="Når der sker noget nyt, finder du det her."
|
|
29369
|
+
/>
|
|
29370
|
+
}
|
|
29371
|
+
</ds-mobile-modal-base>
|
|
29372
|
+
`, 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" }] });
|
|
29373
|
+
}
|
|
29374
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileNotificationModalComponent, decorators: [{
|
|
29375
|
+
type: Component,
|
|
29376
|
+
args: [{ selector: 'ds-mobile-notification-modal', standalone: true, imports: [CommonModule, DsMobileModalBaseComponent, DsMobileListItemComponent, DsAvatarComponent, DsAppIconComponent, DsMobileEmptyStateComponent, DsIconButtonComponent, RelativeTimePipe], template: `
|
|
29377
|
+
<ds-mobile-modal-base
|
|
29378
|
+
headerTitle="Notifikationer"
|
|
29379
|
+
[showHeader]="true"
|
|
29380
|
+
closeButtonLabel="Luk">
|
|
29381
|
+
|
|
29382
|
+
<ds-icon-button
|
|
29383
|
+
header-trailing
|
|
29384
|
+
class="more-button"
|
|
29385
|
+
icon="remixMoreFill"
|
|
29386
|
+
variant="secondary"
|
|
29387
|
+
size="lg"
|
|
29388
|
+
(clicked)="openBulkActions()"
|
|
29389
|
+
aria-label="Flere handlinger"
|
|
29390
|
+
/>
|
|
29391
|
+
|
|
29392
|
+
@if (groups().length > 0) {
|
|
29393
|
+
@for (group of groups(); track group.label) {
|
|
29394
|
+
<div class="notification-group">
|
|
29395
|
+
<div class="notification-group__label">{{ group.label }}</div>
|
|
29396
|
+
|
|
29397
|
+
@for (item of group.items; track item.id) {
|
|
29398
|
+
<ds-mobile-list-item
|
|
29399
|
+
[interactive]="true"
|
|
29400
|
+
[showDivider]="!$last"
|
|
29401
|
+
[enableLongPress]="true"
|
|
29402
|
+
[showDesktopMoreButton]="false"
|
|
29403
|
+
align="top"
|
|
29404
|
+
(itemClick)="handleNotificationClick(item)"
|
|
29405
|
+
(longPress)="handleLongPress(item)">
|
|
29406
|
+
|
|
29407
|
+
@if (item.leading === 'icon') {
|
|
29408
|
+
<ds-avatar
|
|
29409
|
+
content-leading
|
|
29410
|
+
type="icon"
|
|
29411
|
+
[iconName]="item.iconName || iconFor(item.type)"
|
|
29412
|
+
size="md"
|
|
29413
|
+
/>
|
|
29414
|
+
}
|
|
29415
|
+
|
|
29416
|
+
@if (item.leading === 'avatar') {
|
|
29417
|
+
<ds-avatar
|
|
29418
|
+
content-leading
|
|
29419
|
+
[type]="item.avatarSrc ? 'photo' : 'initials'"
|
|
29420
|
+
[initials]="item.avatarInitials || ''"
|
|
29421
|
+
[src]="item.avatarSrc || ''"
|
|
29422
|
+
size="md"
|
|
29423
|
+
/>
|
|
29424
|
+
}
|
|
29425
|
+
|
|
29426
|
+
@if (item.leading === 'image') {
|
|
29427
|
+
<div content-leading class="notification-image">
|
|
29428
|
+
<img [src]="item.imageSrc" [alt]="item.title" />
|
|
29429
|
+
</div>
|
|
29430
|
+
}
|
|
29431
|
+
|
|
29432
|
+
@if (item.leading === 'logo') {
|
|
29433
|
+
<div content-leading class="notification-logo">
|
|
29434
|
+
<ds-app-icon size="lg" />
|
|
29435
|
+
</div>
|
|
29436
|
+
}
|
|
29437
|
+
|
|
29438
|
+
<div content-main class="notification-content">
|
|
29439
|
+
<div class="notification-header">
|
|
29440
|
+
<div class="notification-header__details">
|
|
29441
|
+
<span class="notification-header__name" [class.notification-header__name--unread]="!item.read">
|
|
29442
|
+
{{ item.title }}
|
|
29443
|
+
</span>
|
|
29444
|
+
<span class="notification-header__meta">
|
|
29445
|
+
{{ labelFor(item.type) }}
|
|
29446
|
+
<span class="notification-header__separator">·</span>
|
|
29447
|
+
{{ item.createdAt | relativeTime }}
|
|
29448
|
+
</span>
|
|
29449
|
+
</div>
|
|
29450
|
+
</div>
|
|
29451
|
+
<p class="notification-message">{{ item.message }}</p>
|
|
29452
|
+
</div>
|
|
29453
|
+
|
|
29454
|
+
@if (!item.read) {
|
|
29455
|
+
<div content-trailing class="notification-unread-dot"></div>
|
|
29456
|
+
}
|
|
29457
|
+
</ds-mobile-list-item>
|
|
29458
|
+
}
|
|
29459
|
+
</div>
|
|
29460
|
+
}
|
|
29461
|
+
} @else {
|
|
29462
|
+
<ds-mobile-empty-state
|
|
29463
|
+
imageSrc="/Assets/empty-state-notification.svg"
|
|
29464
|
+
imageAlt="Ingen notifikationer"
|
|
29465
|
+
title="Alt er stille herinde"
|
|
29466
|
+
description="Når der sker noget nyt, finder du det her."
|
|
29467
|
+
/>
|
|
29468
|
+
}
|
|
29469
|
+
</ds-mobile-modal-base>
|
|
29470
|
+
`, 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"] }]
|
|
29471
|
+
}] });
|
|
28628
29472
|
|
|
28629
29473
|
/**
|
|
28630
29474
|
* PostsService
|
|
@@ -29151,6 +29995,654 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
29151
29995
|
}]
|
|
29152
29996
|
}], ctorParameters: () => [] });
|
|
29153
29997
|
|
|
29998
|
+
class DsMobileBookingDetailSheetComponent {
|
|
29999
|
+
modalController;
|
|
30000
|
+
/** `sheet` = bottom sheet. `modal` = `ds-modal-base` shell (active + history bookings). */
|
|
30001
|
+
presentation = 'sheet';
|
|
30002
|
+
data;
|
|
30003
|
+
/** When true the modal sizes to its content instead of filling the screen. */
|
|
30004
|
+
autoHeight = false;
|
|
30005
|
+
get isModalPresentation() {
|
|
30006
|
+
return this.presentation === 'modal';
|
|
30007
|
+
}
|
|
30008
|
+
constructor(modalController) {
|
|
30009
|
+
this.modalController = modalController;
|
|
30010
|
+
}
|
|
30011
|
+
close() {
|
|
30012
|
+
this.modalController.dismiss(null, 'backdrop');
|
|
30013
|
+
}
|
|
30014
|
+
cancelBooking() {
|
|
30015
|
+
this.modalController.dismiss(null, 'cancel');
|
|
30016
|
+
}
|
|
30017
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetComponent, deps: [{ token: i1.ModalController }], target: i0.ɵɵFactoryTarget.Component });
|
|
30018
|
+
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: `
|
|
30019
|
+
@if (presentation === 'modal') {
|
|
30020
|
+
<ds-mobile-modal-base
|
|
30021
|
+
[headerTitle]="data.facilityTitle"
|
|
30022
|
+
[closeButtonLabel]="'Luk'"
|
|
30023
|
+
[isAutoHeight]="autoHeight"
|
|
30024
|
+
[keyboardContentBehavior]="'follow'">
|
|
30025
|
+
|
|
30026
|
+
<ds-mobile-section
|
|
30027
|
+
[showBorder]="false"
|
|
30028
|
+
padding="20px 20px 0 20px">
|
|
30029
|
+
<div class="hero-image-container">
|
|
30030
|
+
@if (data.heroImage) {
|
|
30031
|
+
<img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
|
|
30032
|
+
} @else {
|
|
30033
|
+
<div class="hero-image-placeholder">
|
|
30034
|
+
<ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
|
|
30035
|
+
</div>
|
|
30036
|
+
}
|
|
30037
|
+
</div>
|
|
30038
|
+
</ds-mobile-section>
|
|
30039
|
+
|
|
30040
|
+
<ds-mobile-section padding="20px 20px 20px 20px">
|
|
30041
|
+
<div class="booking-summary-card">
|
|
30042
|
+
<div class="details-section">
|
|
30043
|
+
<h3 class="details-heading">Booking detaljer</h3>
|
|
30044
|
+
<div class="info-rows">
|
|
30045
|
+
@if (data.bookingDate) {
|
|
30046
|
+
<div class="info-row">
|
|
30047
|
+
<ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
|
|
30048
|
+
<span>{{ data.bookingDate }}</span>
|
|
30049
|
+
</div>
|
|
30050
|
+
}
|
|
30051
|
+
@if (data.bookingTime) {
|
|
30052
|
+
<div class="info-row">
|
|
30053
|
+
<ds-icon name="remixTimeLine" size="16px" color="tertiary" />
|
|
30054
|
+
<span>{{ data.bookingTime }}</span>
|
|
30055
|
+
</div>
|
|
30056
|
+
}
|
|
30057
|
+
@if (data.price) {
|
|
30058
|
+
<div class="info-row">
|
|
30059
|
+
<ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
|
|
30060
|
+
<span>{{ data.price }}</span>
|
|
30061
|
+
</div>
|
|
30062
|
+
}
|
|
30063
|
+
@if (data.bookingType) {
|
|
30064
|
+
<div class="info-row">
|
|
30065
|
+
<ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
|
|
30066
|
+
<span>{{ data.bookingType }}</span>
|
|
30067
|
+
</div>
|
|
30068
|
+
}
|
|
30069
|
+
@for (req of data.requirements || []; track req) {
|
|
30070
|
+
<div class="info-row">
|
|
30071
|
+
<ds-icon name="remixLockLine" size="16px" color="tertiary" />
|
|
30072
|
+
<span>{{ req }}</span>
|
|
30073
|
+
</div>
|
|
30074
|
+
}
|
|
30075
|
+
</div>
|
|
30076
|
+
</div>
|
|
30077
|
+
</div>
|
|
30078
|
+
</ds-mobile-section>
|
|
30079
|
+
|
|
30080
|
+
@if (data.canCancel) {
|
|
30081
|
+
<div class="booking-action">
|
|
30082
|
+
<div class="booking-actions-row">
|
|
30083
|
+
<ds-button
|
|
30084
|
+
class="cancel-primary"
|
|
30085
|
+
size="md"
|
|
30086
|
+
variant="secondary"
|
|
30087
|
+
(clicked)="cancelBooking()">
|
|
30088
|
+
Annuller booking
|
|
30089
|
+
</ds-button>
|
|
30090
|
+
</div>
|
|
30091
|
+
</div>
|
|
30092
|
+
}
|
|
30093
|
+
</ds-mobile-modal-base>
|
|
30094
|
+
} @else {
|
|
30095
|
+
<ds-mobile-bottom-sheet-wrapper [showDragHandle]="true">
|
|
30096
|
+
<div class="detail-header">
|
|
30097
|
+
<h2 class="detail-title">{{ data.facilityTitle }}</h2>
|
|
30098
|
+
<ds-icon-button
|
|
30099
|
+
icon="remixCloseLine"
|
|
30100
|
+
variant="ghost"
|
|
30101
|
+
size="sm"
|
|
30102
|
+
(clicked)="close()"
|
|
30103
|
+
aria-label="Luk"
|
|
30104
|
+
/>
|
|
30105
|
+
</div>
|
|
30106
|
+
|
|
30107
|
+
<div class="detail-content">
|
|
30108
|
+
<div class="hero-image-container">
|
|
30109
|
+
@if (data.heroImage) {
|
|
30110
|
+
<img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
|
|
30111
|
+
} @else {
|
|
30112
|
+
<div class="hero-image-placeholder">
|
|
30113
|
+
<ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
|
|
30114
|
+
</div>
|
|
30115
|
+
}
|
|
30116
|
+
</div>
|
|
30117
|
+
|
|
30118
|
+
<div class="booking-summary-card">
|
|
30119
|
+
<div class="details-section">
|
|
30120
|
+
<h3 class="details-heading">Booking detaljer</h3>
|
|
30121
|
+
<div class="info-rows">
|
|
30122
|
+
@if (data.bookingDate) {
|
|
30123
|
+
<div class="info-row">
|
|
30124
|
+
<ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
|
|
30125
|
+
<span>{{ data.bookingDate }}</span>
|
|
30126
|
+
</div>
|
|
30127
|
+
}
|
|
30128
|
+
@if (data.bookingTime) {
|
|
30129
|
+
<div class="info-row">
|
|
30130
|
+
<ds-icon name="remixTimeLine" size="16px" color="tertiary" />
|
|
30131
|
+
<span>{{ data.bookingTime }}</span>
|
|
30132
|
+
</div>
|
|
30133
|
+
}
|
|
30134
|
+
@if (data.price) {
|
|
30135
|
+
<div class="info-row">
|
|
30136
|
+
<ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
|
|
30137
|
+
<span>{{ data.price }}</span>
|
|
30138
|
+
</div>
|
|
30139
|
+
}
|
|
30140
|
+
@if (data.bookingType) {
|
|
30141
|
+
<div class="info-row">
|
|
30142
|
+
<ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
|
|
30143
|
+
<span>{{ data.bookingType }}</span>
|
|
30144
|
+
</div>
|
|
30145
|
+
}
|
|
30146
|
+
@for (req of data.requirements || []; track req) {
|
|
30147
|
+
<div class="info-row">
|
|
30148
|
+
<ds-icon name="remixLockLine" size="16px" color="tertiary" />
|
|
30149
|
+
<span>{{ req }}</span>
|
|
30150
|
+
</div>
|
|
30151
|
+
}
|
|
30152
|
+
</div>
|
|
30153
|
+
</div>
|
|
30154
|
+
</div>
|
|
30155
|
+
|
|
30156
|
+
@if (data.canCancel) {
|
|
30157
|
+
<div class="footer-button-container">
|
|
30158
|
+
<div class="booking-actions-column">
|
|
30159
|
+
<ds-button
|
|
30160
|
+
size="md"
|
|
30161
|
+
variant="secondary"
|
|
30162
|
+
(clicked)="cancelBooking()">
|
|
30163
|
+
Annuller booking
|
|
30164
|
+
</ds-button>
|
|
30165
|
+
</div>
|
|
30166
|
+
</div>
|
|
30167
|
+
}
|
|
30168
|
+
</div>
|
|
30169
|
+
</ds-mobile-bottom-sheet-wrapper>
|
|
30170
|
+
}
|
|
30171
|
+
`, 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"] }] });
|
|
30172
|
+
}
|
|
30173
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetComponent, decorators: [{
|
|
30174
|
+
type: Component,
|
|
30175
|
+
args: [{ selector: 'ds-mobile-booking-detail-sheet', standalone: true, imports: [
|
|
30176
|
+
CommonModule,
|
|
30177
|
+
DsMobileBottomSheetWrapperComponent,
|
|
30178
|
+
DsMobileModalBaseComponent,
|
|
30179
|
+
DsMobileSectionComponent,
|
|
30180
|
+
DsButtonComponent,
|
|
30181
|
+
DsIconComponent,
|
|
30182
|
+
DsIconButtonComponent,
|
|
30183
|
+
], template: `
|
|
30184
|
+
@if (presentation === 'modal') {
|
|
30185
|
+
<ds-mobile-modal-base
|
|
30186
|
+
[headerTitle]="data.facilityTitle"
|
|
30187
|
+
[closeButtonLabel]="'Luk'"
|
|
30188
|
+
[isAutoHeight]="autoHeight"
|
|
30189
|
+
[keyboardContentBehavior]="'follow'">
|
|
30190
|
+
|
|
30191
|
+
<ds-mobile-section
|
|
30192
|
+
[showBorder]="false"
|
|
30193
|
+
padding="20px 20px 0 20px">
|
|
30194
|
+
<div class="hero-image-container">
|
|
30195
|
+
@if (data.heroImage) {
|
|
30196
|
+
<img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
|
|
30197
|
+
} @else {
|
|
30198
|
+
<div class="hero-image-placeholder">
|
|
30199
|
+
<ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
|
|
30200
|
+
</div>
|
|
30201
|
+
}
|
|
30202
|
+
</div>
|
|
30203
|
+
</ds-mobile-section>
|
|
30204
|
+
|
|
30205
|
+
<ds-mobile-section padding="20px 20px 20px 20px">
|
|
30206
|
+
<div class="booking-summary-card">
|
|
30207
|
+
<div class="details-section">
|
|
30208
|
+
<h3 class="details-heading">Booking detaljer</h3>
|
|
30209
|
+
<div class="info-rows">
|
|
30210
|
+
@if (data.bookingDate) {
|
|
30211
|
+
<div class="info-row">
|
|
30212
|
+
<ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
|
|
30213
|
+
<span>{{ data.bookingDate }}</span>
|
|
30214
|
+
</div>
|
|
30215
|
+
}
|
|
30216
|
+
@if (data.bookingTime) {
|
|
30217
|
+
<div class="info-row">
|
|
30218
|
+
<ds-icon name="remixTimeLine" size="16px" color="tertiary" />
|
|
30219
|
+
<span>{{ data.bookingTime }}</span>
|
|
30220
|
+
</div>
|
|
30221
|
+
}
|
|
30222
|
+
@if (data.price) {
|
|
30223
|
+
<div class="info-row">
|
|
30224
|
+
<ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
|
|
30225
|
+
<span>{{ data.price }}</span>
|
|
30226
|
+
</div>
|
|
30227
|
+
}
|
|
30228
|
+
@if (data.bookingType) {
|
|
30229
|
+
<div class="info-row">
|
|
30230
|
+
<ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
|
|
30231
|
+
<span>{{ data.bookingType }}</span>
|
|
30232
|
+
</div>
|
|
30233
|
+
}
|
|
30234
|
+
@for (req of data.requirements || []; track req) {
|
|
30235
|
+
<div class="info-row">
|
|
30236
|
+
<ds-icon name="remixLockLine" size="16px" color="tertiary" />
|
|
30237
|
+
<span>{{ req }}</span>
|
|
30238
|
+
</div>
|
|
30239
|
+
}
|
|
30240
|
+
</div>
|
|
30241
|
+
</div>
|
|
30242
|
+
</div>
|
|
30243
|
+
</ds-mobile-section>
|
|
30244
|
+
|
|
30245
|
+
@if (data.canCancel) {
|
|
30246
|
+
<div class="booking-action">
|
|
30247
|
+
<div class="booking-actions-row">
|
|
30248
|
+
<ds-button
|
|
30249
|
+
class="cancel-primary"
|
|
30250
|
+
size="md"
|
|
30251
|
+
variant="secondary"
|
|
30252
|
+
(clicked)="cancelBooking()">
|
|
30253
|
+
Annuller booking
|
|
30254
|
+
</ds-button>
|
|
30255
|
+
</div>
|
|
30256
|
+
</div>
|
|
30257
|
+
}
|
|
30258
|
+
</ds-mobile-modal-base>
|
|
30259
|
+
} @else {
|
|
30260
|
+
<ds-mobile-bottom-sheet-wrapper [showDragHandle]="true">
|
|
30261
|
+
<div class="detail-header">
|
|
30262
|
+
<h2 class="detail-title">{{ data.facilityTitle }}</h2>
|
|
30263
|
+
<ds-icon-button
|
|
30264
|
+
icon="remixCloseLine"
|
|
30265
|
+
variant="ghost"
|
|
30266
|
+
size="sm"
|
|
30267
|
+
(clicked)="close()"
|
|
30268
|
+
aria-label="Luk"
|
|
30269
|
+
/>
|
|
30270
|
+
</div>
|
|
30271
|
+
|
|
30272
|
+
<div class="detail-content">
|
|
30273
|
+
<div class="hero-image-container">
|
|
30274
|
+
@if (data.heroImage) {
|
|
30275
|
+
<img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
|
|
30276
|
+
} @else {
|
|
30277
|
+
<div class="hero-image-placeholder">
|
|
30278
|
+
<ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
|
|
30279
|
+
</div>
|
|
30280
|
+
}
|
|
30281
|
+
</div>
|
|
30282
|
+
|
|
30283
|
+
<div class="booking-summary-card">
|
|
30284
|
+
<div class="details-section">
|
|
30285
|
+
<h3 class="details-heading">Booking detaljer</h3>
|
|
30286
|
+
<div class="info-rows">
|
|
30287
|
+
@if (data.bookingDate) {
|
|
30288
|
+
<div class="info-row">
|
|
30289
|
+
<ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
|
|
30290
|
+
<span>{{ data.bookingDate }}</span>
|
|
30291
|
+
</div>
|
|
30292
|
+
}
|
|
30293
|
+
@if (data.bookingTime) {
|
|
30294
|
+
<div class="info-row">
|
|
30295
|
+
<ds-icon name="remixTimeLine" size="16px" color="tertiary" />
|
|
30296
|
+
<span>{{ data.bookingTime }}</span>
|
|
30297
|
+
</div>
|
|
30298
|
+
}
|
|
30299
|
+
@if (data.price) {
|
|
30300
|
+
<div class="info-row">
|
|
30301
|
+
<ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
|
|
30302
|
+
<span>{{ data.price }}</span>
|
|
30303
|
+
</div>
|
|
30304
|
+
}
|
|
30305
|
+
@if (data.bookingType) {
|
|
30306
|
+
<div class="info-row">
|
|
30307
|
+
<ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
|
|
30308
|
+
<span>{{ data.bookingType }}</span>
|
|
30309
|
+
</div>
|
|
30310
|
+
}
|
|
30311
|
+
@for (req of data.requirements || []; track req) {
|
|
30312
|
+
<div class="info-row">
|
|
30313
|
+
<ds-icon name="remixLockLine" size="16px" color="tertiary" />
|
|
30314
|
+
<span>{{ req }}</span>
|
|
30315
|
+
</div>
|
|
30316
|
+
}
|
|
30317
|
+
</div>
|
|
30318
|
+
</div>
|
|
30319
|
+
</div>
|
|
30320
|
+
|
|
30321
|
+
@if (data.canCancel) {
|
|
30322
|
+
<div class="footer-button-container">
|
|
30323
|
+
<div class="booking-actions-column">
|
|
30324
|
+
<ds-button
|
|
30325
|
+
size="md"
|
|
30326
|
+
variant="secondary"
|
|
30327
|
+
(clicked)="cancelBooking()">
|
|
30328
|
+
Annuller booking
|
|
30329
|
+
</ds-button>
|
|
30330
|
+
</div>
|
|
30331
|
+
</div>
|
|
30332
|
+
}
|
|
30333
|
+
</div>
|
|
30334
|
+
</ds-mobile-bottom-sheet-wrapper>
|
|
30335
|
+
}
|
|
30336
|
+
`, 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"] }]
|
|
30337
|
+
}], ctorParameters: () => [{ type: i1.ModalController }], propDecorators: { presentation: [{
|
|
30338
|
+
type: Input
|
|
30339
|
+
}], data: [{
|
|
30340
|
+
type: Input
|
|
30341
|
+
}], autoHeight: [{
|
|
30342
|
+
type: Input
|
|
30343
|
+
}], isModalPresentation: [{
|
|
30344
|
+
type: HostBinding,
|
|
30345
|
+
args: ['class.presentation-modal']
|
|
30346
|
+
}] } });
|
|
30347
|
+
|
|
30348
|
+
class DsMobileBookingDetailSheetService extends BaseModalService {
|
|
30349
|
+
bottomSheet;
|
|
30350
|
+
constructor(modalController, bottomSheet) {
|
|
30351
|
+
super(modalController);
|
|
30352
|
+
this.bottomSheet = bottomSheet;
|
|
30353
|
+
}
|
|
30354
|
+
/**
|
|
30355
|
+
* Bottom-sheet presentation (draggable breakpoints). Prefer `openAsModal` for booking lists.
|
|
30356
|
+
*/
|
|
30357
|
+
async open(data) {
|
|
30358
|
+
const modal = await this.bottomSheet.create({
|
|
30359
|
+
component: DsMobileBookingDetailSheetComponent,
|
|
30360
|
+
componentProps: { data },
|
|
30361
|
+
autoHeight: true,
|
|
30362
|
+
backdropDismiss: true,
|
|
30363
|
+
backdropBlur: true,
|
|
30364
|
+
});
|
|
30365
|
+
const result = await modal.onWillDismiss();
|
|
30366
|
+
return { role: result.role, data: result.data ?? undefined };
|
|
30367
|
+
}
|
|
30368
|
+
/** `ds-modal-base` shell — used for active and past bookings. Auto-heights to content. */
|
|
30369
|
+
async openAsModal(data) {
|
|
30370
|
+
const modal = await this.createModal(DsMobileBookingDetailSheetComponent, { data, presentation: 'modal', autoHeight: true }, { keyboardClose: true, autoHeight: true });
|
|
30371
|
+
await modal.present();
|
|
30372
|
+
const result = await modal.onWillDismiss();
|
|
30373
|
+
return { role: result.role, data: result.data ?? undefined };
|
|
30374
|
+
}
|
|
30375
|
+
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 });
|
|
30376
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetService, providedIn: 'root' });
|
|
30377
|
+
}
|
|
30378
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetService, decorators: [{
|
|
30379
|
+
type: Injectable,
|
|
30380
|
+
args: [{
|
|
30381
|
+
providedIn: 'root',
|
|
30382
|
+
}]
|
|
30383
|
+
}], ctorParameters: () => [{ type: i1.ModalController }, { type: DsMobileBottomSheetService }] });
|
|
30384
|
+
|
|
30385
|
+
const VENDOR_MODAL_SERVICE = new InjectionToken('VendorModalService');
|
|
30386
|
+
const BOOKING_DETAIL_MAP = {
|
|
30387
|
+
'booking-1': {
|
|
30388
|
+
id: 'booking-1',
|
|
30389
|
+
facilityTitle: 'Festlokale på taget',
|
|
30390
|
+
heroImage: '/Assets/Dummy-photos/rooftop-party.jpg',
|
|
30391
|
+
bookingDate: '14. februar',
|
|
30392
|
+
bookingTime: '9:00 - 17:00',
|
|
30393
|
+
price: '200 kr. per booking',
|
|
30394
|
+
canCancel: true,
|
|
30395
|
+
},
|
|
30396
|
+
'booking-2': {
|
|
30397
|
+
id: 'booking-2',
|
|
30398
|
+
facilityTitle: 'Gæsteparkering',
|
|
30399
|
+
heroImage: '/Assets/Dummy-photos/parking.jpg',
|
|
30400
|
+
bookingDate: '20. marts',
|
|
30401
|
+
bookingTime: '8:00 - 20:00',
|
|
30402
|
+
price: '50 kr. per booking',
|
|
30403
|
+
canCancel: true,
|
|
30404
|
+
},
|
|
30405
|
+
'booking-3': {
|
|
30406
|
+
id: 'booking-3',
|
|
30407
|
+
facilityTitle: 'Boremaskinen',
|
|
30408
|
+
heroImage: '/Assets/Dummy-photos/handyman.jpg',
|
|
30409
|
+
bookingDate: '25. marts',
|
|
30410
|
+
bookingTime: '10:00 - 14:00',
|
|
30411
|
+
price: 'Gratis',
|
|
30412
|
+
canCancel: true,
|
|
30413
|
+
},
|
|
30414
|
+
};
|
|
30415
|
+
const VENDOR_DETAIL_MAP = {
|
|
30416
|
+
'v-1': {
|
|
30417
|
+
vendorName: 'CleanTeam ApS',
|
|
30418
|
+
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>',
|
|
30419
|
+
vendorImage: '/Assets/Dummy-photos/clean-team.jpg',
|
|
30420
|
+
vendorLogo: '/Assets/dummy-logos/cleanteam-logo.svg',
|
|
30421
|
+
},
|
|
30422
|
+
'v-2': {
|
|
30423
|
+
vendorName: 'Nordisk Rengøring',
|
|
30424
|
+
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>',
|
|
30425
|
+
vendorImage: '/Assets/Dummy-photos/nordic-cleaning.jpg',
|
|
30426
|
+
vendorLogo: '/Assets/dummy-logos/nordiccleaning-logo.svg',
|
|
30427
|
+
},
|
|
30428
|
+
'v-3': {
|
|
30429
|
+
vendorName: 'Blik Partner A/S',
|
|
30430
|
+
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>',
|
|
30431
|
+
vendorImage: '/Assets/Dummy-photos/plumbing.jpg',
|
|
30432
|
+
},
|
|
30433
|
+
'v-4': {
|
|
30434
|
+
vendorName: 'ElektroTek ApS',
|
|
30435
|
+
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>',
|
|
30436
|
+
vendorImage: '/Assets/Dummy-photos/electrician.jpg',
|
|
30437
|
+
vendorLogo: '/Assets/dummy-logos/electrician-logo.svg',
|
|
30438
|
+
},
|
|
30439
|
+
'v-5': {
|
|
30440
|
+
vendorName: 'HaveService Danmark',
|
|
30441
|
+
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>',
|
|
30442
|
+
vendorImage: '/Assets/Dummy-photos/gardener.jpg',
|
|
30443
|
+
vendorLogo: '/Assets/dummy-logos/gardener-logo.svg',
|
|
30444
|
+
},
|
|
30445
|
+
};
|
|
30446
|
+
class DsMobileNotificationModalService extends BaseModalService {
|
|
30447
|
+
router = inject(Router);
|
|
30448
|
+
notificationService = inject(NotificationService);
|
|
30449
|
+
postsService = inject(PostsService);
|
|
30450
|
+
userService = inject(UserService);
|
|
30451
|
+
postModal = inject(DsMobilePostDetailModalService);
|
|
30452
|
+
peerMessaging = inject(PeerMessagingService);
|
|
30453
|
+
peerChat = inject(PeerChatLauncherService);
|
|
30454
|
+
bookingDetailSheet = inject(DsMobileBookingDetailSheetService);
|
|
30455
|
+
vendorModal = inject(VENDOR_MODAL_SERVICE, { optional: true });
|
|
30456
|
+
constructor(modalController) {
|
|
30457
|
+
super(modalController);
|
|
30458
|
+
}
|
|
30459
|
+
/**
|
|
30460
|
+
* Open the notification modal. The modal reads notifications reactively
|
|
30461
|
+
* from NotificationService, so it updates live when items are marked
|
|
30462
|
+
* read or removed via long-press actions.
|
|
30463
|
+
*
|
|
30464
|
+
* Returns the tapped notification (if the user navigated to one), or null.
|
|
30465
|
+
*/
|
|
30466
|
+
async open() {
|
|
30467
|
+
const modal = await this.createModal(DsMobileNotificationModalComponent, {});
|
|
30468
|
+
await modal.present();
|
|
30469
|
+
const result = await modal.onWillDismiss();
|
|
30470
|
+
const tapped = result.data ?? null;
|
|
30471
|
+
if (tapped) {
|
|
30472
|
+
this.notificationService.markAsRead(tapped.id);
|
|
30473
|
+
await this.routeTo(tapped);
|
|
30474
|
+
}
|
|
30475
|
+
return tapped;
|
|
30476
|
+
}
|
|
30477
|
+
/**
|
|
30478
|
+
* Navigate to the screen associated with a notification item.
|
|
30479
|
+
* Public so downstream devs can call it from a Capacitor
|
|
30480
|
+
* `pushNotificationActionPerformed` listener for deep-link handling.
|
|
30481
|
+
*/
|
|
30482
|
+
async routeTo(item) {
|
|
30483
|
+
const id = item.targetId;
|
|
30484
|
+
switch (item.type) {
|
|
30485
|
+
case 'inquiry_update':
|
|
30486
|
+
case 'inquiry_assigned':
|
|
30487
|
+
case 'inquiry_resolved':
|
|
30488
|
+
await this.router.navigate(['/inquiry-detail', id ?? '1']);
|
|
30489
|
+
break;
|
|
30490
|
+
case 'community_post':
|
|
30491
|
+
case 'community_comment':
|
|
30492
|
+
case 'community_like':
|
|
30493
|
+
case 'community_mention':
|
|
30494
|
+
if (id) {
|
|
30495
|
+
await this.openPostModal(id);
|
|
30496
|
+
}
|
|
30497
|
+
else {
|
|
30498
|
+
await this.router.navigate(['/announcements']);
|
|
30499
|
+
}
|
|
30500
|
+
break;
|
|
30501
|
+
case 'booking_confirmed':
|
|
30502
|
+
case 'booking_cancelled':
|
|
30503
|
+
case 'booking_reminder':
|
|
30504
|
+
case 'facility_available':
|
|
30505
|
+
if (id) {
|
|
30506
|
+
await this.openBookingDetail(item);
|
|
30507
|
+
}
|
|
30508
|
+
else {
|
|
30509
|
+
await this.router.navigate(['/booking']);
|
|
30510
|
+
}
|
|
30511
|
+
break;
|
|
30512
|
+
case 'message_new':
|
|
30513
|
+
case 'message_group':
|
|
30514
|
+
if (id) {
|
|
30515
|
+
await this.openChat(id);
|
|
30516
|
+
}
|
|
30517
|
+
else {
|
|
30518
|
+
await this.router.navigate(['/messages']);
|
|
30519
|
+
}
|
|
30520
|
+
break;
|
|
30521
|
+
case 'service_update':
|
|
30522
|
+
if (id) {
|
|
30523
|
+
await this.openVendorModal(id);
|
|
30524
|
+
}
|
|
30525
|
+
else {
|
|
30526
|
+
await this.router.navigate(['/services']);
|
|
30527
|
+
}
|
|
30528
|
+
break;
|
|
30529
|
+
case 'handbook_update':
|
|
30530
|
+
await this.router.navigate(['/handbook']);
|
|
30531
|
+
break;
|
|
30532
|
+
case 'family_access':
|
|
30533
|
+
await this.router.navigate(['/family-access']);
|
|
30534
|
+
break;
|
|
30535
|
+
default:
|
|
30536
|
+
await this.router.navigate(['/home']);
|
|
30537
|
+
break;
|
|
30538
|
+
}
|
|
30539
|
+
}
|
|
30540
|
+
async openChat(conversationId) {
|
|
30541
|
+
const conv = this.peerMessaging.conversations().find(c => c.id === conversationId);
|
|
30542
|
+
if (conv) {
|
|
30543
|
+
await this.peerChat.openConversation(conv);
|
|
30544
|
+
}
|
|
30545
|
+
else {
|
|
30546
|
+
await this.router.navigate(['/messages']);
|
|
30547
|
+
}
|
|
30548
|
+
}
|
|
30549
|
+
async openVendorModal(vendorId) {
|
|
30550
|
+
const vendor = VENDOR_DETAIL_MAP[vendorId];
|
|
30551
|
+
if (vendor && this.vendorModal) {
|
|
30552
|
+
await this.vendorModal.open(vendor);
|
|
30553
|
+
}
|
|
30554
|
+
else {
|
|
30555
|
+
await this.router.navigate(['/services']);
|
|
30556
|
+
}
|
|
30557
|
+
}
|
|
30558
|
+
async openBookingDetail(item) {
|
|
30559
|
+
const booking = BOOKING_DETAIL_MAP[item.targetId];
|
|
30560
|
+
if (booking) {
|
|
30561
|
+
await this.bookingDetailSheet.openAsModal(booking);
|
|
30562
|
+
}
|
|
30563
|
+
else {
|
|
30564
|
+
await this.router.navigate(['/booking']);
|
|
30565
|
+
}
|
|
30566
|
+
}
|
|
30567
|
+
async openPostModal(postId) {
|
|
30568
|
+
const post = this.postsService.getPostById(postId);
|
|
30569
|
+
if (!post) {
|
|
30570
|
+
await this.router.navigate(['/announcements']);
|
|
30571
|
+
return;
|
|
30572
|
+
}
|
|
30573
|
+
const data = {
|
|
30574
|
+
postId: post.id,
|
|
30575
|
+
authorName: post.authorName,
|
|
30576
|
+
authorRole: post.authorRole,
|
|
30577
|
+
timestamp: post.timestamp,
|
|
30578
|
+
content: post.content,
|
|
30579
|
+
avatarInitials: post.avatarInitials,
|
|
30580
|
+
avatarType: post.avatarType === 'icon' ? undefined : post.avatarType,
|
|
30581
|
+
avatarSrc: post.avatarSrc,
|
|
30582
|
+
imageSrc: post.imageSrc,
|
|
30583
|
+
imageAlt: post.imageAlt,
|
|
30584
|
+
isLiked: post.isLiked,
|
|
30585
|
+
likeCount: post.likeCount,
|
|
30586
|
+
commentCount: post.commentCount,
|
|
30587
|
+
comments: post.comments,
|
|
30588
|
+
};
|
|
30589
|
+
await this.postModal.open(data, {
|
|
30590
|
+
currentUserName: this.userService.displayName(),
|
|
30591
|
+
currentUserInitials: this.userService.avatarInitials(),
|
|
30592
|
+
});
|
|
30593
|
+
}
|
|
30594
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileNotificationModalService, deps: [{ token: i1.ModalController }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
30595
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileNotificationModalService, providedIn: 'root' });
|
|
30596
|
+
}
|
|
30597
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileNotificationModalService, decorators: [{
|
|
30598
|
+
type: Injectable,
|
|
30599
|
+
args: [{
|
|
30600
|
+
providedIn: 'root',
|
|
30601
|
+
}]
|
|
30602
|
+
}], ctorParameters: () => [{ type: i1.ModalController }] });
|
|
30603
|
+
|
|
30604
|
+
class DsMobileToggleComponent {
|
|
30605
|
+
checked = model(false, ...(ngDevMode ? [{ debugName: "checked" }] : []));
|
|
30606
|
+
disabled = input(false, ...(ngDevMode ? [{ debugName: "disabled" }] : []));
|
|
30607
|
+
changed = output();
|
|
30608
|
+
handleClick(event) {
|
|
30609
|
+
event.stopPropagation();
|
|
30610
|
+
this.toggle();
|
|
30611
|
+
}
|
|
30612
|
+
toggle() {
|
|
30613
|
+
if (this.disabled())
|
|
30614
|
+
return;
|
|
30615
|
+
const next = !this.checked();
|
|
30616
|
+
this.checked.set(next);
|
|
30617
|
+
this.changed.emit(next);
|
|
30618
|
+
}
|
|
30619
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileToggleComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
30620
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.3.16", type: DsMobileToggleComponent, isStandalone: true, selector: "ds-mobile-toggle", inputs: { checked: { classPropertyName: "checked", publicName: "checked", isSignal: true, isRequired: false, transformFunction: null }, disabled: { classPropertyName: "disabled", publicName: "disabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { checked: "checkedChange", changed: "changed" }, host: { listeners: { "click": "handleClick($event)", "keydown.enter": "toggle()", "keydown.space": "$event.preventDefault(); toggle()" }, properties: { "class.disabled": "disabled()", "attr.role": "\"switch\"", "attr.aria-checked": "checked()", "attr.aria-disabled": "disabled() || null", "attr.tabindex": "disabled() ? -1 : 0" } }, ngImport: i0, template: `
|
|
30621
|
+
<div class="track" [class.active]="checked()">
|
|
30622
|
+
<div class="knob"></div>
|
|
30623
|
+
</div>
|
|
30624
|
+
`, isInline: true, styles: [":host{display:inline-flex;cursor:pointer;-webkit-tap-highlight-color:transparent;flex-shrink:0;outline:none}:host(.disabled){opacity:.4;pointer-events:none}:host:focus-visible .track{outline:2px solid var(--color-brand-primary, #5d5fef);outline-offset:2px}.track{width:40px;height:24px;background:var(--color-background-neutral-tertiary, #e3e6eb);border-radius:var(--border-radius-round, 1000px);padding:4px;box-sizing:border-box;transition:background .2s ease}.track.active{background:var(--color-accent, #6b5ff5)}.knob{width:16px;height:16px;background:var(--color-background-neutral-primary, white);border-radius:var(--border-radius-round, 1000px);transition:transform .2s ease}.track.active .knob{transform:translate(16px)}\n"] });
|
|
30625
|
+
}
|
|
30626
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileToggleComponent, decorators: [{
|
|
30627
|
+
type: Component,
|
|
30628
|
+
args: [{ selector: 'ds-mobile-toggle', standalone: true, host: {
|
|
30629
|
+
'(click)': 'handleClick($event)',
|
|
30630
|
+
'[class.disabled]': 'disabled()',
|
|
30631
|
+
'[attr.role]': '"switch"',
|
|
30632
|
+
'[attr.aria-checked]': 'checked()',
|
|
30633
|
+
'[attr.aria-disabled]': 'disabled() || null',
|
|
30634
|
+
'[attr.tabindex]': 'disabled() ? -1 : 0',
|
|
30635
|
+
'(keydown.enter)': 'toggle()',
|
|
30636
|
+
'(keydown.space)': '$event.preventDefault(); toggle()',
|
|
30637
|
+
}, template: `
|
|
30638
|
+
<div class="track" [class.active]="checked()">
|
|
30639
|
+
<div class="knob"></div>
|
|
30640
|
+
</div>
|
|
30641
|
+
`, styles: [":host{display:inline-flex;cursor:pointer;-webkit-tap-highlight-color:transparent;flex-shrink:0;outline:none}:host(.disabled){opacity:.4;pointer-events:none}:host:focus-visible .track{outline:2px solid var(--color-brand-primary, #5d5fef);outline-offset:2px}.track{width:40px;height:24px;background:var(--color-background-neutral-tertiary, #e3e6eb);border-radius:var(--border-radius-round, 1000px);padding:4px;box-sizing:border-box;transition:background .2s ease}.track.active{background:var(--color-accent, #6b5ff5)}.knob{width:16px;height:16px;background:var(--color-background-neutral-primary, white);border-radius:var(--border-radius-round, 1000px);transition:transform .2s ease}.track.active .knob{transform:translate(16px)}\n"] }]
|
|
30642
|
+
}], propDecorators: { checked: [{ type: i0.Input, args: [{ isSignal: true, alias: "checked", required: false }] }, { type: i0.Output, args: ["checkedChange"] }], disabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "disabled", required: false }] }], changed: [{ type: i0.Output, args: ["changed"] }] } });
|
|
30643
|
+
|
|
30644
|
+
// Mobile Page Components
|
|
30645
|
+
|
|
29154
30646
|
class MobileCommunityPageComponent {
|
|
29155
30647
|
router;
|
|
29156
30648
|
route;
|
|
@@ -29161,6 +30653,8 @@ class MobileCommunityPageComponent {
|
|
|
29161
30653
|
postsService;
|
|
29162
30654
|
pageComponent;
|
|
29163
30655
|
pinnedSwiper;
|
|
30656
|
+
notificationModal = inject(DsMobileNotificationModalService);
|
|
30657
|
+
notificationService = inject(NotificationService);
|
|
29164
30658
|
// Get posts from service (using computed for safe initialization)
|
|
29165
30659
|
allPosts = computed(() => this.postsService.posts(), ...(ngDevMode ? [{ debugName: "allPosts" }] : []));
|
|
29166
30660
|
// Get pinned posts - filter by isPinned flag
|
|
@@ -29203,6 +30697,11 @@ class MobileCommunityPageComponent {
|
|
|
29203
30697
|
// Complete the infinite scroll
|
|
29204
30698
|
event.target.complete();
|
|
29205
30699
|
}
|
|
30700
|
+
async handleNotificationClick() {
|
|
30701
|
+
const tapped = await this.notificationModal.open();
|
|
30702
|
+
if (tapped)
|
|
30703
|
+
console.log('Notification tapped:', tapped.type, tapped.id);
|
|
30704
|
+
}
|
|
29206
30705
|
handleRefresh(event) {
|
|
29207
30706
|
console.log('Pull-to-refresh triggered');
|
|
29208
30707
|
// Check if offline and complete immediately
|
|
@@ -29444,8 +30943,10 @@ class MobileCommunityPageComponent {
|
|
|
29444
30943
|
<ds-mobile-page-main
|
|
29445
30944
|
#pageComponent
|
|
29446
30945
|
title="Fællesskab"
|
|
30946
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
29447
30947
|
[avatarInitials]="userService.avatarInitials()"
|
|
29448
30948
|
[avatarType]="userService.avatarType()"
|
|
30949
|
+
(notificationClick)="handleNotificationClick()"
|
|
29449
30950
|
(refresh)="handleRefresh($event)">
|
|
29450
30951
|
|
|
29451
30952
|
<!-- Offline indicator -->
|
|
@@ -29698,7 +31199,7 @@ class MobileCommunityPageComponent {
|
|
|
29698
31199
|
}
|
|
29699
31200
|
</ds-mobile-section>
|
|
29700
31201
|
</ds-mobile-page-main>
|
|
29701
|
-
`, isInline: true, styles: [".pinned-posts-swiper-wrapper{padding:0;position:relative}.swiper-nav-buttons{display:contents}.swiper-nav-button{position:absolute;top:50%;transform:translateY(-50%);z-index:10}.swiper-nav-button:first-child{left:-48px}.swiper-nav-button:last-child{right:-48px}::ng-deep .swiper-nav-button button{border-radius:50%!important;width:48px!important;height:48px!important;padding:0!important}@media (max-width: 767px){.swiper-nav-buttons{display:none}}::ng-deep .pinned-posts-swiper .swiper-slide{width:100%;max-width:600px;height:auto}@media (min-width: 768px){::ng-deep .pinned-posts-swiper .swiper-slide{max-width:100%}}.swiper-post-item{width:100%;height:auto}::ng-deep .pinned-posts-swiper .swiper-slide ds-mobile-interactive-list-item-post{height:auto}::ng-deep .pinned-posts-swiper .swiper-wrapper{height:auto;align-items:flex-start}.post-list-wrapper{display:flex;flex-direction:column}.clickable-image{cursor:pointer;transition:transform .2s ease,opacity .2s ease;border-radius:8px;display:block;width:100%;aspect-ratio:16/9;object-fit:cover}.clickable-image:active{transform:scale(.98);opacity:.9}.community-empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;text-align:center}.empty-state-image{width:96px;height:96px;margin-bottom:24px}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;color:var(--color-text-primary);margin:16px 0 8px}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);color:var(--color-text-secondary);margin:0}ion-infinite-scroll{--color: var(--color-primary-surface)}ion-infinite-scroll-content{--color: var(--color-primary-surface)}ion-infinite-scroll-content::part(spinner){color:var(--color-primary-surface)}\n"], dependencies: [{ kind: "component", type: DsMobilePageMainComponent, selector: "ds-mobile-page-main", inputs: ["title", "headerTitle", "headerSubtitle", "firstEntry", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileInteractiveListItemPostComponent, selector: "ds-mobile-interactive-list-item-post", inputs: ["authorName", "authorRole", "timestamp", "avatarInitials", "avatarType", "avatarSrc", "avatarIconName", "showBadge", "variant", "align", "clickable", "enableLongPress", "moreActions"], outputs: ["postClick", "commentClick", "longPress"] }, { kind: "component", type: DsMobilePostComposerComponent, selector: "ds-mobile-post-composer", inputs: ["avatarInitials", "avatarType", "avatarSrc", "avatarIconName", "placeholder", "buttonText"], outputs: ["composerClick"] }, { kind: "component", type: DsMobileSwiperComponent, selector: "ds-mobile-swiper", inputs: ["slideWidth", "gap", "pagination", "autoHeight", "progressiveOpacity", "progressiveScale"] }, { kind: "component", type: PostContentComponent, selector: "post-content" }, { kind: "component", type: PostTextComponent, selector: "post-text" }, { kind: "component", type: PostMediaComponent, selector: "post-media" }, { kind: "component", type: PostAttachmentsComponent, selector: "post-attachments" }, { kind: "component", type: PostActionsComponent, selector: "post-actions" }, { kind: "component", type: ActionLikeComponent, selector: "action-like", inputs: ["active", "count"], outputs: ["activeChange", "countChange", "likeClick"] }, { kind: "component", type: ActionCommentComponent, selector: "action-comment", inputs: ["count"], outputs: ["commentClick"] }, { kind: "component", type: DsMobileCardInlineFileComponent, selector: "ds-mobile-card-inline-file", inputs: ["fileName", "fileSize", "variant", "layout", "fileUrl"], outputs: ["fileClick"] }, { kind: "component", type: DsIconButtonComponent, selector: "ds-icon-button", inputs: ["variant", "size", "icon", "disabled", "loading", "pressed", "expanded", "ariaLabel", "tooltip", "tooltipDisabled", "tooltipPlacement"], outputs: ["clicked", "focused", "blurred"] }, { kind: "component", type: DsMobileInlinePhotoComponent, selector: "ds-mobile-inline-photo", inputs: ["images", "loadingStates", "author", "maxVisible", "useGrid"], outputs: ["photoClick"] }, { kind: "component", type: DsMobileOfflineBannerComponent, selector: "ds-mobile-offline-banner", inputs: ["icon", "title", "message"] }, { kind: "component", type: IonInfiniteScroll, selector: "ion-infinite-scroll", inputs: ["disabled", "position", "threshold"] }, { kind: "component", type: IonInfiniteScrollContent, selector: "ion-infinite-scroll-content", inputs: ["loadingSpinner", "loadingText"] }] });
|
|
31202
|
+
`, 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", "showNotification", "notificationCount", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["notificationClick", "avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileInteractiveListItemPostComponent, selector: "ds-mobile-interactive-list-item-post", inputs: ["authorName", "authorRole", "timestamp", "avatarInitials", "avatarType", "avatarSrc", "avatarIconName", "showBadge", "variant", "align", "clickable", "enableLongPress", "moreActions"], outputs: ["postClick", "commentClick", "longPress"] }, { kind: "component", type: DsMobilePostComposerComponent, selector: "ds-mobile-post-composer", inputs: ["avatarInitials", "avatarType", "avatarSrc", "avatarIconName", "placeholder", "buttonText"], outputs: ["composerClick"] }, { kind: "component", type: DsMobileSwiperComponent, selector: "ds-mobile-swiper", inputs: ["slideWidth", "gap", "pagination", "autoHeight", "progressiveOpacity", "progressiveScale"] }, { kind: "component", type: PostContentComponent, selector: "post-content" }, { kind: "component", type: PostTextComponent, selector: "post-text" }, { kind: "component", type: PostMediaComponent, selector: "post-media" }, { kind: "component", type: PostAttachmentsComponent, selector: "post-attachments" }, { kind: "component", type: PostActionsComponent, selector: "post-actions" }, { kind: "component", type: ActionLikeComponent, selector: "action-like", inputs: ["active", "count"], outputs: ["activeChange", "countChange", "likeClick"] }, { kind: "component", type: ActionCommentComponent, selector: "action-comment", inputs: ["count"], outputs: ["commentClick"] }, { kind: "component", type: DsMobileCardInlineFileComponent, selector: "ds-mobile-card-inline-file", inputs: ["fileName", "fileSize", "variant", "layout", "fileUrl"], outputs: ["fileClick"] }, { kind: "component", type: DsIconButtonComponent, selector: "ds-icon-button", inputs: ["variant", "size", "icon", "disabled", "loading", "pressed", "expanded", "ariaLabel", "tooltip", "tooltipDisabled", "tooltipPlacement"], outputs: ["clicked", "focused", "blurred"] }, { kind: "component", type: DsMobileInlinePhotoComponent, selector: "ds-mobile-inline-photo", inputs: ["images", "loadingStates", "author", "maxVisible", "useGrid"], outputs: ["photoClick"] }, { kind: "component", type: DsMobileOfflineBannerComponent, selector: "ds-mobile-offline-banner", inputs: ["icon", "title", "message"] }, { kind: "component", type: IonInfiniteScroll, selector: "ion-infinite-scroll", inputs: ["disabled", "position", "threshold"] }, { kind: "component", type: IonInfiniteScrollContent, selector: "ion-infinite-scroll-content", inputs: ["loadingSpinner", "loadingText"] }] });
|
|
29702
31203
|
}
|
|
29703
31204
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MobileCommunityPageComponent, decorators: [{
|
|
29704
31205
|
type: Component,
|
|
@@ -29725,8 +31226,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
29725
31226
|
<ds-mobile-page-main
|
|
29726
31227
|
#pageComponent
|
|
29727
31228
|
title="Fællesskab"
|
|
31229
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
29728
31230
|
[avatarInitials]="userService.avatarInitials()"
|
|
29729
31231
|
[avatarType]="userService.avatarType()"
|
|
31232
|
+
(notificationClick)="handleNotificationClick()"
|
|
29730
31233
|
(refresh)="handleRefresh($event)">
|
|
29731
31234
|
|
|
29732
31235
|
<!-- Offline indicator -->
|
|
@@ -29991,6 +31494,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
29991
31494
|
class MobileHandbookPageComponent {
|
|
29992
31495
|
userService;
|
|
29993
31496
|
pageComponent;
|
|
31497
|
+
notificationModal = inject(DsMobileNotificationModalService);
|
|
31498
|
+
notificationService = inject(NotificationService);
|
|
29994
31499
|
// Utilities folder data
|
|
29995
31500
|
utilitiesItems = [
|
|
29996
31501
|
{
|
|
@@ -30233,6 +31738,11 @@ class MobileHandbookPageComponent {
|
|
|
30233
31738
|
constructor(userService) {
|
|
30234
31739
|
this.userService = userService;
|
|
30235
31740
|
}
|
|
31741
|
+
async handleNotificationClick() {
|
|
31742
|
+
const tapped = await this.notificationModal.open();
|
|
31743
|
+
if (tapped)
|
|
31744
|
+
console.log('Notification tapped:', tapped.type, tapped.id);
|
|
31745
|
+
}
|
|
30236
31746
|
handleRefresh(event) {
|
|
30237
31747
|
console.log('Pull-to-refresh triggered');
|
|
30238
31748
|
// Check if offline and complete immediately
|
|
@@ -30248,7 +31758,7 @@ class MobileHandbookPageComponent {
|
|
|
30248
31758
|
}
|
|
30249
31759
|
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MobileHandbookPageComponent, deps: [{ token: UserService }], target: i0.ɵɵFactoryTarget.Component });
|
|
30250
31760
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: MobileHandbookPageComponent, isStandalone: true, selector: "app-mobile-handbook-page", viewQueries: [{ propertyName: "pageComponent", first: true, predicate: ["pageComponent"], descendants: true }], ngImport: i0, template: `
|
|
30251
|
-
<ds-mobile-page-main #pageComponent title="Håndbog" [avatarInitials]="userService.avatarInitials()" [avatarType]="userService.avatarType()" (refresh)="handleRefresh($event)">
|
|
31761
|
+
<ds-mobile-page-main #pageComponent title="Håndbog" [notificationCount]="notificationService.unreadCount()" [avatarInitials]="userService.avatarInitials()" [avatarType]="userService.avatarType()" (notificationClick)="handleNotificationClick()" (refresh)="handleRefresh($event)">
|
|
30252
31762
|
<!-- Offline indicator -->
|
|
30253
31763
|
@if (pageComponent.isOffline()) {
|
|
30254
31764
|
<ds-mobile-offline-banner offline-indicator title="Ingen internetforbindelse" message="Nogle funktioner kan være utilgængelige"> </ds-mobile-offline-banner>
|
|
@@ -30269,12 +31779,12 @@ class MobileHandbookPageComponent {
|
|
|
30269
31779
|
</div>
|
|
30270
31780
|
</ds-mobile-section>
|
|
30271
31781
|
</ds-mobile-page-main>
|
|
30272
|
-
`, isInline: true, styles: [".folders-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:20px;justify-items:center}@media (min-width: 768px){.folders-grid{grid-template-columns:repeat(3,1fr)}}ds-mobile-handbook-folder{width:100%;min-width:0}\n"], dependencies: [{ kind: "component", type: DsMobilePageMainComponent, selector: "ds-mobile-page-main", inputs: ["title", "headerTitle", "headerSubtitle", "firstEntry", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileHandbookFolderComponent, selector: "ds-mobile-handbook-folder", inputs: ["variant", "customColor", "iconName", "itemCount", "label", "items", "loading", "error"] }, { kind: "component", type: DsMobileOfflineBannerComponent, selector: "ds-mobile-offline-banner", inputs: ["icon", "title", "message"] }] });
|
|
31782
|
+
`, 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", "showNotification", "notificationCount", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["notificationClick", "avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileHandbookFolderComponent, selector: "ds-mobile-handbook-folder", inputs: ["variant", "customColor", "iconName", "itemCount", "label", "items", "loading", "error"] }, { kind: "component", type: DsMobileOfflineBannerComponent, selector: "ds-mobile-offline-banner", inputs: ["icon", "title", "message"] }] });
|
|
30273
31783
|
}
|
|
30274
31784
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MobileHandbookPageComponent, decorators: [{
|
|
30275
31785
|
type: Component,
|
|
30276
31786
|
args: [{ selector: 'app-mobile-handbook-page', standalone: true, imports: [DsMobilePageMainComponent, DsMobileSectionComponent, DsMobileHandbookFolderComponent, DsMobileOfflineBannerComponent], template: `
|
|
30277
|
-
<ds-mobile-page-main #pageComponent title="Håndbog" [avatarInitials]="userService.avatarInitials()" [avatarType]="userService.avatarType()" (refresh)="handleRefresh($event)">
|
|
31787
|
+
<ds-mobile-page-main #pageComponent title="Håndbog" [notificationCount]="notificationService.unreadCount()" [avatarInitials]="userService.avatarInitials()" [avatarType]="userService.avatarType()" (notificationClick)="handleNotificationClick()" (refresh)="handleRefresh($event)">
|
|
30278
31788
|
<!-- Offline indicator -->
|
|
30279
31789
|
@if (pageComponent.isOffline()) {
|
|
30280
31790
|
<ds-mobile-offline-banner offline-indicator title="Ingen internetforbindelse" message="Nogle funktioner kan være utilgængelige"> </ds-mobile-offline-banner>
|
|
@@ -30851,21 +32361,51 @@ class MobileHomePageComponent {
|
|
|
30851
32361
|
// (hides tab bar + renders loading screen at the correct DOM level)
|
|
30852
32362
|
pageLoading = inject(PageLoadingService);
|
|
30853
32363
|
// Get recent posts from PostsService - exclude pinned post (post-4) and limit to 3
|
|
30854
|
-
recentPosts = computed(() => this.postsService
|
|
30855
|
-
.
|
|
32364
|
+
recentPosts = computed(() => this.postsService
|
|
32365
|
+
.posts()
|
|
32366
|
+
.filter((post) => post.id !== 'post-4') // Exclude pinned post
|
|
30856
32367
|
.slice(0, 3), ...(ngDevMode ? [{ debugName: "recentPosts" }] : []));
|
|
30857
32368
|
inquiriesService = inject(InquiriesService);
|
|
30858
32369
|
openInquiries = computed(() => this.inquiriesService.openInquiries().slice(0, 3), ...(ngDevMode ? [{ debugName: "openInquiries" }] : []));
|
|
30859
32370
|
recentPeerMessages = computed(() => this.peerMessaging.conversations().slice(0, 3), ...(ngDevMode ? [{ debugName: "recentPeerMessages" }] : []));
|
|
30860
32371
|
allVendors = signal([
|
|
30861
|
-
{
|
|
30862
|
-
|
|
30863
|
-
|
|
32372
|
+
{
|
|
32373
|
+
id: 'v-1',
|
|
32374
|
+
name: 'CleanTeam ApS',
|
|
32375
|
+
category: 'Rengøring',
|
|
32376
|
+
description: 'Trappevask og vinduespolering',
|
|
32377
|
+
phone: '+45 70 20 30 40',
|
|
32378
|
+
logo: '/Assets/dummy-logos/cleanteam-logo.svg',
|
|
32379
|
+
thumbnail: '/Assets/Dummy-photos/clean-team.jpg',
|
|
32380
|
+
fullDescription: '<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>',
|
|
32381
|
+
},
|
|
32382
|
+
{
|
|
32383
|
+
id: 'v-3',
|
|
32384
|
+
name: 'Blik Partner A/S',
|
|
32385
|
+
category: 'VVS',
|
|
32386
|
+
description: 'VVS-service og akut udkald',
|
|
32387
|
+
phone: '+45 33 44 55 66',
|
|
32388
|
+
thumbnail: '/Assets/Dummy-photos/plumbing.jpg',
|
|
32389
|
+
fullDescription: '<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>',
|
|
32390
|
+
},
|
|
32391
|
+
{
|
|
32392
|
+
id: 'v-4',
|
|
32393
|
+
name: 'ElektroTek ApS',
|
|
32394
|
+
category: 'Elektriker',
|
|
32395
|
+
description: 'El-installationer og fejlsøgning',
|
|
32396
|
+
phone: '+45 23 45 67 89',
|
|
32397
|
+
logo: '/Assets/dummy-logos/electrician-logo.svg',
|
|
32398
|
+
thumbnail: '/Assets/Dummy-photos/electrician.jpg',
|
|
32399
|
+
heroImage: '/Assets/Dummy-photos/electrician.jpg',
|
|
32400
|
+
fullDescription: '<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>',
|
|
32401
|
+
},
|
|
30864
32402
|
], ...(ngDevMode ? [{ debugName: "allVendors" }] : []));
|
|
30865
32403
|
previewVendors = computed(() => this.allVendors().slice(0, 3), ...(ngDevMode ? [{ debugName: "previewVendors" }] : []));
|
|
30866
32404
|
modalCtrl = inject(ModalController);
|
|
30867
32405
|
vendorModal = inject(DsMobileServiceVendorModalService);
|
|
30868
32406
|
newInquiryModal = inject(DsMobileNewInquiryModalService);
|
|
32407
|
+
notificationModal = inject(DsMobileNotificationModalService);
|
|
32408
|
+
notificationService = inject(NotificationService);
|
|
30869
32409
|
constructor(router, navCtrl, userService, postsService, postModal, trackingPermissionService, bottomSheet, familyAccessService, peerMessaging, peerChat, lightboxService) {
|
|
30870
32410
|
this.router = router;
|
|
30871
32411
|
this.navCtrl = navCtrl;
|
|
@@ -30893,6 +32433,11 @@ class MobileHomePageComponent {
|
|
|
30893
32433
|
}, delayMs);
|
|
30894
32434
|
});
|
|
30895
32435
|
}
|
|
32436
|
+
async handleNotificationClick() {
|
|
32437
|
+
const tapped = await this.notificationModal.open();
|
|
32438
|
+
if (tapped)
|
|
32439
|
+
console.log('Notification tapped:', tapped.type, tapped.id);
|
|
32440
|
+
}
|
|
30896
32441
|
handleRefresh(event) {
|
|
30897
32442
|
console.log('Pull-to-refresh triggered');
|
|
30898
32443
|
setTimeout(() => {
|
|
@@ -30909,11 +32454,11 @@ class MobileHomePageComponent {
|
|
|
30909
32454
|
...post,
|
|
30910
32455
|
postId: post.id,
|
|
30911
32456
|
avatarType: post.avatarType === 'icon' ? undefined : post.avatarType,
|
|
30912
|
-
focusComment
|
|
32457
|
+
focusComment,
|
|
30913
32458
|
};
|
|
30914
32459
|
await this.postModal.open(postData, {
|
|
30915
32460
|
currentUserName: 'Lars Mikkelsen',
|
|
30916
|
-
currentUserInitials: this.userService.avatarInitials()
|
|
32461
|
+
currentUserInitials: this.userService.avatarInitials(),
|
|
30917
32462
|
});
|
|
30918
32463
|
}
|
|
30919
32464
|
}
|
|
@@ -31001,7 +32546,7 @@ class MobileHomePageComponent {
|
|
|
31001
32546
|
initialBreakpoint: 1,
|
|
31002
32547
|
handle: true,
|
|
31003
32548
|
backdropDismiss: true,
|
|
31004
|
-
cssClass: 'auto-height'
|
|
32549
|
+
cssClass: 'auto-height',
|
|
31005
32550
|
});
|
|
31006
32551
|
const result = await sheet.onWillDismiss();
|
|
31007
32552
|
if (result.role === 'select' && result.data) {
|
|
@@ -31012,7 +32557,7 @@ class MobileHomePageComponent {
|
|
|
31012
32557
|
if (post) {
|
|
31013
32558
|
this.postsService.updatePost(postId, {
|
|
31014
32559
|
isLiked: !post.isLiked,
|
|
31015
|
-
likeCount: post.isLiked ? post.likeCount - 1 : post.likeCount + 1
|
|
32560
|
+
likeCount: post.isLiked ? post.likeCount - 1 : post.likeCount + 1,
|
|
31016
32561
|
});
|
|
31017
32562
|
}
|
|
31018
32563
|
break;
|
|
@@ -31032,216 +32577,189 @@ class MobileHomePageComponent {
|
|
|
31032
32577
|
@if (!pageLoading.isCoveringScreen()) {
|
|
31033
32578
|
<ds-mobile-page-main
|
|
31034
32579
|
class="home-content"
|
|
32580
|
+
[showNotification]="true"
|
|
31035
32581
|
[class.home-content--animating]="pageLoading.isRevealAnimation()"
|
|
31036
32582
|
[firstEntry]="pageLoading.isRevealAnimation()"
|
|
31037
32583
|
#pageComponent
|
|
31038
32584
|
title="Hjem"
|
|
31039
32585
|
headerTitle="Velkommen, Lars"
|
|
32586
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
31040
32587
|
[avatarInitials]="userService.avatarInitials()"
|
|
31041
32588
|
[avatarType]="userService.avatarType()"
|
|
32589
|
+
(notificationClick)="handleNotificationClick()"
|
|
31042
32590
|
(refresh)="handleRefresh($event)"
|
|
32591
|
+
>
|
|
32592
|
+
<!-- Offline indicator -->
|
|
32593
|
+
@if (pageComponent.isOffline()) {
|
|
32594
|
+
<ds-mobile-offline-banner offline-indicator title="Ingen internetforbindelse" message="Nogle funktioner kan være utilgængelige"> </ds-mobile-offline-banner>
|
|
32595
|
+
}
|
|
32596
|
+
|
|
32597
|
+
<!-- Property banner → beboere (prototype IA) -->
|
|
32598
|
+
<div
|
|
32599
|
+
header-content
|
|
32600
|
+
class="property-banner-nav"
|
|
32601
|
+
role="button"
|
|
32602
|
+
tabindex="0"
|
|
32603
|
+
(click)="navigateToTenants()"
|
|
32604
|
+
(keydown.enter)="navigateToTenants()"
|
|
32605
|
+
(keydown.space)="$event.preventDefault(); navigateToTenants()"
|
|
32606
|
+
aria-label="Se beboere på ejendommen"
|
|
31043
32607
|
>
|
|
31044
|
-
|
|
31045
|
-
|
|
31046
|
-
@if (pageComponent.isOffline()) {
|
|
31047
|
-
<ds-mobile-offline-banner
|
|
31048
|
-
offline-indicator
|
|
31049
|
-
title="Ingen internetforbindelse"
|
|
31050
|
-
message="Nogle funktioner kan være utilgængelige">
|
|
31051
|
-
</ds-mobile-offline-banner>
|
|
31052
|
-
}
|
|
31053
|
-
|
|
31054
|
-
<!-- Property banner → beboere (prototype IA) -->
|
|
31055
|
-
<div
|
|
31056
|
-
header-content
|
|
31057
|
-
class="property-banner-nav"
|
|
31058
|
-
role="button"
|
|
31059
|
-
tabindex="0"
|
|
31060
|
-
(click)="navigateToTenants()"
|
|
31061
|
-
(keydown.enter)="navigateToTenants()"
|
|
31062
|
-
(keydown.space)="$event.preventDefault(); navigateToTenants()"
|
|
31063
|
-
aria-label="Se beboere på ejendommen">
|
|
31064
|
-
<ds-mobile-property-banner
|
|
31065
|
-
address="Toftegårds Allé 5A, 2. tv."
|
|
31066
|
-
photoUrl="/Assets/Dummy-photos/building.jpg"
|
|
31067
|
-
[tenantCount]="24">
|
|
31068
|
-
</ds-mobile-property-banner>
|
|
31069
|
-
</div>
|
|
32608
|
+
<ds-mobile-property-banner address="Toftegårds Allé 5A, 2. tv." photoUrl="/Assets/Dummy-photos/building.jpg" [tenantCount]="24"> </ds-mobile-property-banner>
|
|
32609
|
+
</div>
|
|
31070
32610
|
|
|
31071
|
-
|
|
31072
|
-
|
|
31073
|
-
|
|
31074
|
-
|
|
31075
|
-
|
|
31076
|
-
|
|
31077
|
-
|
|
31078
|
-
|
|
31079
|
-
|
|
31080
|
-
|
|
31081
|
-
|
|
32611
|
+
@if (familyAccessService.acceptedInviteContext(); as invite) {
|
|
32612
|
+
<ds-mobile-section [showBorder]="false" padding="20px 20px 0">
|
|
32613
|
+
<div class="welcome-toast">
|
|
32614
|
+
<div class="toast-icon">
|
|
32615
|
+
<ds-icon name="remixUserSmileLine" size="12px" />
|
|
32616
|
+
</div>
|
|
32617
|
+
<div class="welcome-toast-content">
|
|
32618
|
+
<p class="welcome-toast-heading">Du er nu familiemedlem!</p>
|
|
32619
|
+
<p class="welcome-toast-text">
|
|
32620
|
+
Tilknyttet <strong>{{ invite.propertyAddress }}</strong> via <strong>{{ invite.inviterName }}</strong>
|
|
32621
|
+
</p>
|
|
32622
|
+
</div>
|
|
32623
|
+
<button class="toast-dismiss" (click)="familyAccessService.clearAcceptedInviteContext()" aria-label="Luk">
|
|
32624
|
+
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
|
|
32625
|
+
<path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" />
|
|
32626
|
+
</svg>
|
|
32627
|
+
</button>
|
|
31082
32628
|
</div>
|
|
31083
|
-
|
|
31084
|
-
|
|
31085
|
-
|
|
31086
|
-
|
|
31087
|
-
|
|
32629
|
+
</ds-mobile-section>
|
|
32630
|
+
}
|
|
32631
|
+
|
|
32632
|
+
<!-- Recent Community Posts Section (with content) -->
|
|
32633
|
+
<ds-mobile-section headline="Seneste opslag" linkText="Se alle" (linkClick)="navigateToCommunity()">
|
|
32634
|
+
<div class="posts-list">
|
|
32635
|
+
@for (post of recentPosts(); track post.id) {
|
|
32636
|
+
<ds-mobile-interactive-list-item-post
|
|
32637
|
+
[authorName]="post.authorName"
|
|
32638
|
+
[authorRole]="post.authorRole"
|
|
32639
|
+
[timestamp]="post.timestamp"
|
|
32640
|
+
[avatarType]="post.avatarType"
|
|
32641
|
+
[avatarSrc]="post.avatarSrc || ''"
|
|
32642
|
+
[avatarInitials]="post.avatarInitials || ''"
|
|
32643
|
+
[showBadge]="post.showBadge || false"
|
|
32644
|
+
[clickable]="true"
|
|
32645
|
+
[moreActions]="true"
|
|
32646
|
+
(postClick)="openPost(post.id)"
|
|
32647
|
+
(commentClick)="openPost(post.id, true)"
|
|
32648
|
+
(longPress)="handlePostLongPress(post.id)"
|
|
32649
|
+
>
|
|
32650
|
+
<post-content>
|
|
32651
|
+
@if (post.content) {
|
|
32652
|
+
<post-text>{{ post.content }}</post-text>
|
|
32653
|
+
}
|
|
32654
|
+
</post-content>
|
|
32655
|
+
|
|
32656
|
+
<post-actions>
|
|
32657
|
+
<action-like [count]="post.likeCount" [active]="post.isLiked" />
|
|
32658
|
+
<action-comment [count]="post.commentCount" (commentClick)="openPost(post.id, true)" />
|
|
32659
|
+
</post-actions>
|
|
32660
|
+
</ds-mobile-interactive-list-item-post>
|
|
32661
|
+
}
|
|
31088
32662
|
</div>
|
|
31089
32663
|
</ds-mobile-section>
|
|
31090
|
-
}
|
|
31091
|
-
|
|
31092
|
-
<!-- Recent Community Posts Section (with content) -->
|
|
31093
|
-
<ds-mobile-section
|
|
31094
|
-
headline="Seneste opslag"
|
|
31095
|
-
linkText="Se alle"
|
|
31096
|
-
(linkClick)="navigateToCommunity()">
|
|
31097
|
-
|
|
31098
|
-
<div class="posts-list">
|
|
31099
|
-
@for (post of recentPosts(); track post.id) {
|
|
31100
|
-
<ds-mobile-interactive-list-item-post
|
|
31101
|
-
[authorName]="post.authorName"
|
|
31102
|
-
[authorRole]="post.authorRole"
|
|
31103
|
-
[timestamp]="post.timestamp"
|
|
31104
|
-
[avatarType]="post.avatarType"
|
|
31105
|
-
[avatarSrc]="post.avatarSrc || ''"
|
|
31106
|
-
[avatarInitials]="post.avatarInitials || ''"
|
|
31107
|
-
[showBadge]="post.showBadge || false"
|
|
31108
|
-
[clickable]="true"
|
|
31109
|
-
[moreActions]="true"
|
|
31110
|
-
(postClick)="openPost(post.id)"
|
|
31111
|
-
(commentClick)="openPost(post.id, true)"
|
|
31112
|
-
(longPress)="handlePostLongPress(post.id)">
|
|
31113
|
-
|
|
31114
|
-
<post-content>
|
|
31115
|
-
@if (post.content) {
|
|
31116
|
-
<post-text>{{ post.content }}</post-text>
|
|
31117
|
-
}
|
|
31118
|
-
</post-content>
|
|
31119
|
-
|
|
31120
|
-
<post-actions>
|
|
31121
|
-
<action-like [count]="post.likeCount" [active]="post.isLiked" />
|
|
31122
|
-
<action-comment [count]="post.commentCount" (commentClick)="openPost(post.id, true)" />
|
|
31123
|
-
</post-actions>
|
|
31124
|
-
</ds-mobile-interactive-list-item-post>
|
|
31125
|
-
}
|
|
31126
|
-
</div>
|
|
31127
|
-
</ds-mobile-section>
|
|
31128
32664
|
|
|
31129
|
-
|
|
31130
|
-
|
|
31131
|
-
|
|
31132
|
-
|
|
31133
|
-
|
|
31134
|
-
|
|
31135
|
-
|
|
31136
|
-
|
|
31137
|
-
|
|
31138
|
-
|
|
31139
|
-
|
|
31140
|
-
|
|
31141
|
-
|
|
31142
|
-
|
|
31143
|
-
|
|
31144
|
-
|
|
31145
|
-
|
|
31146
|
-
|
|
31147
|
-
|
|
31148
|
-
|
|
31149
|
-
|
|
31150
|
-
|
|
31151
|
-
|
|
31152
|
-
|
|
31153
|
-
|
|
31154
|
-
|
|
31155
|
-
|
|
31156
|
-
|
|
31157
|
-
|
|
31158
|
-
|
|
31159
|
-
|
|
31160
|
-
|
|
32665
|
+
<ds-mobile-section headline="Seneste beskeder" linkText="Se alle" (linkClick)="navigateToMessages()">
|
|
32666
|
+
<div class="messages-preview-list">
|
|
32667
|
+
@for (conv of recentPeerMessages(); track conv.id) {
|
|
32668
|
+
@if (isPeerGroupConversation(conv)) {
|
|
32669
|
+
<ds-mobile-interactive-list-item-message
|
|
32670
|
+
[senderName]="conv.title"
|
|
32671
|
+
[senderRole]="conv.memberIds.length + ' medlemmer'"
|
|
32672
|
+
[timestamp]="conv.timestamp"
|
|
32673
|
+
[message]="conv.lastMessage"
|
|
32674
|
+
[avatarInitials]="''"
|
|
32675
|
+
[avatarType]="'initials'"
|
|
32676
|
+
[groupStackMembers]="peerChat.resolveGroupMembers(conv)"
|
|
32677
|
+
[groupCustomAvatarUrl]="conv.customAvatarUrl ?? ''"
|
|
32678
|
+
groupStackExcludeParticipantId="me"
|
|
32679
|
+
[showAvatarBadge]="false"
|
|
32680
|
+
[unread]="conv.unread"
|
|
32681
|
+
[clickable]="true"
|
|
32682
|
+
(messageClick)="openPeerMessagePreview(conv)"
|
|
32683
|
+
>
|
|
32684
|
+
</ds-mobile-interactive-list-item-message>
|
|
32685
|
+
} @else {
|
|
32686
|
+
<ds-mobile-interactive-list-item-message
|
|
32687
|
+
[senderName]="conv.participant.name"
|
|
32688
|
+
[senderRole]="conv.participant.role ?? ''"
|
|
32689
|
+
[timestamp]="conv.timestamp"
|
|
32690
|
+
[message]="conv.lastMessage"
|
|
32691
|
+
[avatarInitials]="conv.participant.avatarInitials ?? ''"
|
|
32692
|
+
[avatarType]="conv.participant.avatarType ?? 'initials'"
|
|
32693
|
+
[showAvatarBadge]="false"
|
|
32694
|
+
[unread]="conv.unread"
|
|
32695
|
+
[clickable]="true"
|
|
32696
|
+
(messageClick)="openPeerMessagePreview(conv)"
|
|
32697
|
+
>
|
|
32698
|
+
</ds-mobile-interactive-list-item-message>
|
|
32699
|
+
}
|
|
32700
|
+
}
|
|
32701
|
+
</div>
|
|
32702
|
+
</ds-mobile-section>
|
|
32703
|
+
|
|
32704
|
+
<!-- Services preview -->
|
|
32705
|
+
@if (previewVendors().length > 0) {
|
|
32706
|
+
<ds-mobile-section headline="Services" linkText="Se alle" contentGap="0px" (linkClick)="navigateToServices()">
|
|
32707
|
+
@for (vendor of previewVendors(); track vendor.id) {
|
|
32708
|
+
<ds-mobile-interactive-list-item-service
|
|
32709
|
+
[title]="vendor.name"
|
|
32710
|
+
[description]="vendor.description || ''"
|
|
32711
|
+
[logo]="vendor.logo || ''"
|
|
32712
|
+
(serviceClick)="openVendorSheet(vendor)"
|
|
32713
|
+
/>
|
|
32714
|
+
}
|
|
32715
|
+
</ds-mobile-section>
|
|
32716
|
+
}
|
|
32717
|
+
|
|
32718
|
+
<!-- Recent Community Posts Section (empty state) -->
|
|
32719
|
+
<ds-mobile-section>
|
|
32720
|
+
<div class="empty-state">
|
|
32721
|
+
<ds-mobile-illustration variant="post" alt="No posts" />
|
|
32722
|
+
<h3 class="empty-state-title">Ingen opslag endnu</h3>
|
|
32723
|
+
<p class="empty-state-description">Der er ingen opslag i fællesområdet i øjeblikket</p>
|
|
32724
|
+
|
|
32725
|
+
<ds-button variant="secondary" trailingIcon="remixArrowRightSLine" (click)="navigateToCommunity()"> Gå til fællesområdet </ds-button>
|
|
32726
|
+
</div>
|
|
32727
|
+
</ds-mobile-section>
|
|
32728
|
+
|
|
32729
|
+
<!-- Open Inquiries Section (with content) -->
|
|
32730
|
+
<ds-mobile-section headline="Åbne henvendelser" linkText="Se alle" (linkClick)="navigateToInquiries()">
|
|
32731
|
+
<div class="inquiries-list">
|
|
32732
|
+
@for (inquiry of openInquiries(); track inquiry.id) {
|
|
32733
|
+
<ds-mobile-interactive-list-item-inquiry
|
|
32734
|
+
[title]="inquiry.title"
|
|
32735
|
+
[description]="inquiry.description"
|
|
32736
|
+
[status]="inquiry.status"
|
|
32737
|
+
[timestamp]="inquiry.timestamp"
|
|
32738
|
+
[iconName]="'remixTodoLine'"
|
|
31161
32739
|
[clickable]="true"
|
|
31162
|
-
|
|
31163
|
-
|
|
32740
|
+
[showChevron]="false"
|
|
32741
|
+
[enableLongPress]="false"
|
|
32742
|
+
(inquiryClick)="openInquiryDetail(inquiry.id)"
|
|
32743
|
+
>
|
|
32744
|
+
</ds-mobile-interactive-list-item-inquiry>
|
|
31164
32745
|
}
|
|
31165
|
-
|
|
31166
|
-
</div>
|
|
31167
|
-
</ds-mobile-section>
|
|
31168
|
-
|
|
31169
|
-
<!-- Services preview -->
|
|
31170
|
-
@if (previewVendors().length > 0) {
|
|
31171
|
-
<ds-mobile-section
|
|
31172
|
-
headline="Services"
|
|
31173
|
-
linkText="Se alle"
|
|
31174
|
-
contentGap="0px"
|
|
31175
|
-
(linkClick)="navigateToServices()">
|
|
31176
|
-
@for (vendor of previewVendors(); track vendor.id) {
|
|
31177
|
-
<ds-mobile-interactive-list-item-service
|
|
31178
|
-
[title]="vendor.name"
|
|
31179
|
-
[description]="vendor.description || ''"
|
|
31180
|
-
[logo]="vendor.logo || ''"
|
|
31181
|
-
(serviceClick)="openVendorSheet(vendor)"
|
|
31182
|
-
/>
|
|
31183
|
-
}
|
|
32746
|
+
</div>
|
|
31184
32747
|
</ds-mobile-section>
|
|
31185
|
-
}
|
|
31186
32748
|
|
|
31187
|
-
|
|
31188
|
-
|
|
31189
|
-
|
|
31190
|
-
|
|
31191
|
-
|
|
31192
|
-
|
|
31193
|
-
|
|
31194
|
-
<ds-button
|
|
31195
|
-
variant="secondary"
|
|
31196
|
-
trailingIcon="remixArrowRightSLine"
|
|
31197
|
-
(click)="navigateToCommunity()">
|
|
31198
|
-
Gå til fællesområdet
|
|
31199
|
-
</ds-button>
|
|
31200
|
-
</div>
|
|
31201
|
-
</ds-mobile-section>
|
|
31202
|
-
|
|
31203
|
-
<!-- Open Inquiries Section (with content) -->
|
|
31204
|
-
<ds-mobile-section
|
|
31205
|
-
headline="Åbne henvendelser"
|
|
31206
|
-
linkText="Se alle"
|
|
31207
|
-
(linkClick)="navigateToInquiries()">
|
|
31208
|
-
|
|
31209
|
-
<div class="inquiries-list">
|
|
31210
|
-
@for (inquiry of openInquiries(); track inquiry.id) {
|
|
31211
|
-
<ds-mobile-interactive-list-item-inquiry
|
|
31212
|
-
[title]="inquiry.title"
|
|
31213
|
-
[description]="inquiry.description"
|
|
31214
|
-
[status]="inquiry.status"
|
|
31215
|
-
[timestamp]="inquiry.timestamp"
|
|
31216
|
-
[iconName]="'remixTodoLine'"
|
|
31217
|
-
[clickable]="true"
|
|
31218
|
-
[showChevron]="false"
|
|
31219
|
-
[enableLongPress]="false"
|
|
31220
|
-
(inquiryClick)="openInquiryDetail(inquiry.id)">
|
|
31221
|
-
</ds-mobile-interactive-list-item-inquiry>
|
|
31222
|
-
}
|
|
31223
|
-
</div>
|
|
31224
|
-
</ds-mobile-section>
|
|
31225
|
-
|
|
31226
|
-
<!-- Open Inquiries Section (empty state) -->
|
|
31227
|
-
<ds-mobile-section>
|
|
31228
|
-
<div class="empty-state">
|
|
31229
|
-
<ds-mobile-illustration variant="inquiry" alt="No inquiries" />
|
|
31230
|
-
<h3 class="empty-state-title">Ingen åbne henvendelser</h3>
|
|
31231
|
-
<p class="empty-state-description">Du har ingen åbne henvendelser i øjeblikket</p>
|
|
31232
|
-
|
|
31233
|
-
<ds-button
|
|
31234
|
-
variant="secondary"
|
|
31235
|
-
trailingIcon="remixArrowRightSLine"
|
|
31236
|
-
(click)="navigateToInquiries()">
|
|
31237
|
-
Gå til henvendelser
|
|
31238
|
-
</ds-button>
|
|
31239
|
-
</div>
|
|
31240
|
-
</ds-mobile-section>
|
|
31241
|
-
</ds-mobile-page-main>
|
|
31242
|
-
} <!-- end @if (!isCoveringScreen()) -->
|
|
32749
|
+
<!-- Open Inquiries Section (empty state) -->
|
|
32750
|
+
<ds-mobile-section>
|
|
32751
|
+
<div class="empty-state">
|
|
32752
|
+
<ds-mobile-illustration variant="inquiry" alt="No inquiries" />
|
|
32753
|
+
<h3 class="empty-state-title">Ingen åbne henvendelser</h3>
|
|
32754
|
+
<p class="empty-state-description">Du har ingen åbne henvendelser i øjeblikket</p>
|
|
31243
32755
|
|
|
31244
|
-
|
|
32756
|
+
<ds-button variant="secondary" trailingIcon="remixArrowRightSLine" (click)="navigateToInquiries()"> Gå til henvendelser </ds-button>
|
|
32757
|
+
</div>
|
|
32758
|
+
</ds-mobile-section>
|
|
32759
|
+
</ds-mobile-page-main>
|
|
32760
|
+
}
|
|
32761
|
+
<!-- end @if (!isCoveringScreen()) -->
|
|
32762
|
+
`, 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", "showNotification", "notificationCount", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["notificationClick", "avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileIllustrationComponent, selector: "ds-mobile-illustration", inputs: ["variant", "size", "alt"] }, { kind: "component", type: DsMobilePropertyBannerComponent, selector: "ds-mobile-property-banner", inputs: ["address", "photoUrl", "tenantCount"] }, { kind: "component", type: DsMobileInteractiveListItemPostComponent, selector: "ds-mobile-interactive-list-item-post", inputs: ["authorName", "authorRole", "timestamp", "avatarInitials", "avatarType", "avatarSrc", "avatarIconName", "showBadge", "variant", "align", "clickable", "enableLongPress", "moreActions"], outputs: ["postClick", "commentClick", "longPress"] }, { kind: "component", type: DsMobileInteractiveListItemInquiryComponent, selector: "ds-mobile-interactive-list-item-inquiry", inputs: ["title", "description", "status", "statusLabel", "timestamp", "iconName", "iconColor", "variant", "align", "clickable", "showChevron", "enableLongPress", "moreActions"], outputs: ["inquiryClick", "longPress"] }, { kind: "component", type: DsMobileInteractiveListItemMessageComponent, selector: "ds-mobile-interactive-list-item-message", inputs: ["senderName", "senderRole", "timestamp", "message", "avatarInitials", "avatarType", "avatarSrc", "unread", "unreadStyle", "clickable", "align", "showAvatarBadge", "groupStackMembers", "groupCustomAvatarUrl", "groupStackExcludeParticipantId"], outputs: ["messageClick", "longPress"] }, { kind: "component", type: DsMobileInteractiveListItemServiceComponent, selector: "ds-mobile-interactive-list-item-service", inputs: ["title", "description", "logo", "showChevron"], outputs: ["serviceClick"] }, { kind: "component", type: DsMobileOfflineBannerComponent, selector: "ds-mobile-offline-banner", inputs: ["icon", "title", "message"] }, { kind: "component", type: PostContentComponent, selector: "post-content" }, { kind: "component", type: PostTextComponent, selector: "post-text" }, { kind: "component", type: PostActionsComponent, selector: "post-actions" }, { kind: "component", type: ActionLikeComponent, selector: "action-like", inputs: ["active", "count"], outputs: ["activeChange", "countChange", "likeClick"] }, { kind: "component", type: ActionCommentComponent, selector: "action-comment", inputs: ["count"], outputs: ["commentClick"] }] });
|
|
31245
32763
|
}
|
|
31246
32764
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MobileHomePageComponent, decorators: [{
|
|
31247
32765
|
type: Component,
|
|
@@ -31255,14 +32773,13 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
31255
32773
|
DsMobileInteractiveListItemPostComponent,
|
|
31256
32774
|
DsMobileInteractiveListItemInquiryComponent,
|
|
31257
32775
|
DsMobileInteractiveListItemMessageComponent,
|
|
31258
|
-
DsMobileInteractiveListItemBookingComponent,
|
|
31259
32776
|
DsMobileInteractiveListItemServiceComponent,
|
|
31260
32777
|
DsMobileOfflineBannerComponent,
|
|
31261
32778
|
PostContentComponent,
|
|
31262
32779
|
PostTextComponent,
|
|
31263
32780
|
PostActionsComponent,
|
|
31264
32781
|
ActionLikeComponent,
|
|
31265
|
-
ActionCommentComponent
|
|
32782
|
+
ActionCommentComponent,
|
|
31266
32783
|
], template: `
|
|
31267
32784
|
<!-- Full-screen loading state (first entry) — rendered by layout, not here -->
|
|
31268
32785
|
|
|
@@ -31272,216 +32789,189 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
31272
32789
|
@if (!pageLoading.isCoveringScreen()) {
|
|
31273
32790
|
<ds-mobile-page-main
|
|
31274
32791
|
class="home-content"
|
|
32792
|
+
[showNotification]="true"
|
|
31275
32793
|
[class.home-content--animating]="pageLoading.isRevealAnimation()"
|
|
31276
32794
|
[firstEntry]="pageLoading.isRevealAnimation()"
|
|
31277
32795
|
#pageComponent
|
|
31278
32796
|
title="Hjem"
|
|
31279
32797
|
headerTitle="Velkommen, Lars"
|
|
32798
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
31280
32799
|
[avatarInitials]="userService.avatarInitials()"
|
|
31281
32800
|
[avatarType]="userService.avatarType()"
|
|
32801
|
+
(notificationClick)="handleNotificationClick()"
|
|
31282
32802
|
(refresh)="handleRefresh($event)"
|
|
32803
|
+
>
|
|
32804
|
+
<!-- Offline indicator -->
|
|
32805
|
+
@if (pageComponent.isOffline()) {
|
|
32806
|
+
<ds-mobile-offline-banner offline-indicator title="Ingen internetforbindelse" message="Nogle funktioner kan være utilgængelige"> </ds-mobile-offline-banner>
|
|
32807
|
+
}
|
|
32808
|
+
|
|
32809
|
+
<!-- Property banner → beboere (prototype IA) -->
|
|
32810
|
+
<div
|
|
32811
|
+
header-content
|
|
32812
|
+
class="property-banner-nav"
|
|
32813
|
+
role="button"
|
|
32814
|
+
tabindex="0"
|
|
32815
|
+
(click)="navigateToTenants()"
|
|
32816
|
+
(keydown.enter)="navigateToTenants()"
|
|
32817
|
+
(keydown.space)="$event.preventDefault(); navigateToTenants()"
|
|
32818
|
+
aria-label="Se beboere på ejendommen"
|
|
31283
32819
|
>
|
|
31284
|
-
|
|
31285
|
-
|
|
31286
|
-
@if (pageComponent.isOffline()) {
|
|
31287
|
-
<ds-mobile-offline-banner
|
|
31288
|
-
offline-indicator
|
|
31289
|
-
title="Ingen internetforbindelse"
|
|
31290
|
-
message="Nogle funktioner kan være utilgængelige">
|
|
31291
|
-
</ds-mobile-offline-banner>
|
|
31292
|
-
}
|
|
31293
|
-
|
|
31294
|
-
<!-- Property banner → beboere (prototype IA) -->
|
|
31295
|
-
<div
|
|
31296
|
-
header-content
|
|
31297
|
-
class="property-banner-nav"
|
|
31298
|
-
role="button"
|
|
31299
|
-
tabindex="0"
|
|
31300
|
-
(click)="navigateToTenants()"
|
|
31301
|
-
(keydown.enter)="navigateToTenants()"
|
|
31302
|
-
(keydown.space)="$event.preventDefault(); navigateToTenants()"
|
|
31303
|
-
aria-label="Se beboere på ejendommen">
|
|
31304
|
-
<ds-mobile-property-banner
|
|
31305
|
-
address="Toftegårds Allé 5A, 2. tv."
|
|
31306
|
-
photoUrl="/Assets/Dummy-photos/building.jpg"
|
|
31307
|
-
[tenantCount]="24">
|
|
31308
|
-
</ds-mobile-property-banner>
|
|
31309
|
-
</div>
|
|
32820
|
+
<ds-mobile-property-banner address="Toftegårds Allé 5A, 2. tv." photoUrl="/Assets/Dummy-photos/building.jpg" [tenantCount]="24"> </ds-mobile-property-banner>
|
|
32821
|
+
</div>
|
|
31310
32822
|
|
|
31311
|
-
|
|
31312
|
-
|
|
31313
|
-
|
|
31314
|
-
|
|
31315
|
-
|
|
31316
|
-
|
|
31317
|
-
|
|
31318
|
-
|
|
31319
|
-
|
|
31320
|
-
|
|
31321
|
-
|
|
32823
|
+
@if (familyAccessService.acceptedInviteContext(); as invite) {
|
|
32824
|
+
<ds-mobile-section [showBorder]="false" padding="20px 20px 0">
|
|
32825
|
+
<div class="welcome-toast">
|
|
32826
|
+
<div class="toast-icon">
|
|
32827
|
+
<ds-icon name="remixUserSmileLine" size="12px" />
|
|
32828
|
+
</div>
|
|
32829
|
+
<div class="welcome-toast-content">
|
|
32830
|
+
<p class="welcome-toast-heading">Du er nu familiemedlem!</p>
|
|
32831
|
+
<p class="welcome-toast-text">
|
|
32832
|
+
Tilknyttet <strong>{{ invite.propertyAddress }}</strong> via <strong>{{ invite.inviterName }}</strong>
|
|
32833
|
+
</p>
|
|
32834
|
+
</div>
|
|
32835
|
+
<button class="toast-dismiss" (click)="familyAccessService.clearAcceptedInviteContext()" aria-label="Luk">
|
|
32836
|
+
<svg width="16" height="16" viewBox="0 0 16 16" fill="none">
|
|
32837
|
+
<path d="M4 4l8 8M12 4l-8 8" stroke="currentColor" stroke-width="1.5" stroke-linecap="round" />
|
|
32838
|
+
</svg>
|
|
32839
|
+
</button>
|
|
31322
32840
|
</div>
|
|
31323
|
-
|
|
31324
|
-
|
|
31325
|
-
|
|
31326
|
-
|
|
31327
|
-
|
|
32841
|
+
</ds-mobile-section>
|
|
32842
|
+
}
|
|
32843
|
+
|
|
32844
|
+
<!-- Recent Community Posts Section (with content) -->
|
|
32845
|
+
<ds-mobile-section headline="Seneste opslag" linkText="Se alle" (linkClick)="navigateToCommunity()">
|
|
32846
|
+
<div class="posts-list">
|
|
32847
|
+
@for (post of recentPosts(); track post.id) {
|
|
32848
|
+
<ds-mobile-interactive-list-item-post
|
|
32849
|
+
[authorName]="post.authorName"
|
|
32850
|
+
[authorRole]="post.authorRole"
|
|
32851
|
+
[timestamp]="post.timestamp"
|
|
32852
|
+
[avatarType]="post.avatarType"
|
|
32853
|
+
[avatarSrc]="post.avatarSrc || ''"
|
|
32854
|
+
[avatarInitials]="post.avatarInitials || ''"
|
|
32855
|
+
[showBadge]="post.showBadge || false"
|
|
32856
|
+
[clickable]="true"
|
|
32857
|
+
[moreActions]="true"
|
|
32858
|
+
(postClick)="openPost(post.id)"
|
|
32859
|
+
(commentClick)="openPost(post.id, true)"
|
|
32860
|
+
(longPress)="handlePostLongPress(post.id)"
|
|
32861
|
+
>
|
|
32862
|
+
<post-content>
|
|
32863
|
+
@if (post.content) {
|
|
32864
|
+
<post-text>{{ post.content }}</post-text>
|
|
32865
|
+
}
|
|
32866
|
+
</post-content>
|
|
32867
|
+
|
|
32868
|
+
<post-actions>
|
|
32869
|
+
<action-like [count]="post.likeCount" [active]="post.isLiked" />
|
|
32870
|
+
<action-comment [count]="post.commentCount" (commentClick)="openPost(post.id, true)" />
|
|
32871
|
+
</post-actions>
|
|
32872
|
+
</ds-mobile-interactive-list-item-post>
|
|
32873
|
+
}
|
|
31328
32874
|
</div>
|
|
31329
32875
|
</ds-mobile-section>
|
|
31330
|
-
}
|
|
31331
|
-
|
|
31332
|
-
<!-- Recent Community Posts Section (with content) -->
|
|
31333
|
-
<ds-mobile-section
|
|
31334
|
-
headline="Seneste opslag"
|
|
31335
|
-
linkText="Se alle"
|
|
31336
|
-
(linkClick)="navigateToCommunity()">
|
|
31337
|
-
|
|
31338
|
-
<div class="posts-list">
|
|
31339
|
-
@for (post of recentPosts(); track post.id) {
|
|
31340
|
-
<ds-mobile-interactive-list-item-post
|
|
31341
|
-
[authorName]="post.authorName"
|
|
31342
|
-
[authorRole]="post.authorRole"
|
|
31343
|
-
[timestamp]="post.timestamp"
|
|
31344
|
-
[avatarType]="post.avatarType"
|
|
31345
|
-
[avatarSrc]="post.avatarSrc || ''"
|
|
31346
|
-
[avatarInitials]="post.avatarInitials || ''"
|
|
31347
|
-
[showBadge]="post.showBadge || false"
|
|
31348
|
-
[clickable]="true"
|
|
31349
|
-
[moreActions]="true"
|
|
31350
|
-
(postClick)="openPost(post.id)"
|
|
31351
|
-
(commentClick)="openPost(post.id, true)"
|
|
31352
|
-
(longPress)="handlePostLongPress(post.id)">
|
|
31353
|
-
|
|
31354
|
-
<post-content>
|
|
31355
|
-
@if (post.content) {
|
|
31356
|
-
<post-text>{{ post.content }}</post-text>
|
|
31357
|
-
}
|
|
31358
|
-
</post-content>
|
|
31359
|
-
|
|
31360
|
-
<post-actions>
|
|
31361
|
-
<action-like [count]="post.likeCount" [active]="post.isLiked" />
|
|
31362
|
-
<action-comment [count]="post.commentCount" (commentClick)="openPost(post.id, true)" />
|
|
31363
|
-
</post-actions>
|
|
31364
|
-
</ds-mobile-interactive-list-item-post>
|
|
31365
|
-
}
|
|
31366
|
-
</div>
|
|
31367
|
-
</ds-mobile-section>
|
|
31368
32876
|
|
|
31369
|
-
|
|
31370
|
-
|
|
31371
|
-
|
|
31372
|
-
|
|
31373
|
-
|
|
31374
|
-
|
|
31375
|
-
|
|
31376
|
-
|
|
31377
|
-
|
|
31378
|
-
|
|
31379
|
-
|
|
31380
|
-
|
|
31381
|
-
|
|
31382
|
-
|
|
31383
|
-
|
|
31384
|
-
|
|
31385
|
-
|
|
31386
|
-
|
|
31387
|
-
|
|
31388
|
-
|
|
31389
|
-
|
|
31390
|
-
|
|
31391
|
-
|
|
31392
|
-
|
|
31393
|
-
|
|
31394
|
-
|
|
31395
|
-
|
|
31396
|
-
|
|
31397
|
-
|
|
31398
|
-
|
|
31399
|
-
|
|
31400
|
-
|
|
32877
|
+
<ds-mobile-section headline="Seneste beskeder" linkText="Se alle" (linkClick)="navigateToMessages()">
|
|
32878
|
+
<div class="messages-preview-list">
|
|
32879
|
+
@for (conv of recentPeerMessages(); track conv.id) {
|
|
32880
|
+
@if (isPeerGroupConversation(conv)) {
|
|
32881
|
+
<ds-mobile-interactive-list-item-message
|
|
32882
|
+
[senderName]="conv.title"
|
|
32883
|
+
[senderRole]="conv.memberIds.length + ' medlemmer'"
|
|
32884
|
+
[timestamp]="conv.timestamp"
|
|
32885
|
+
[message]="conv.lastMessage"
|
|
32886
|
+
[avatarInitials]="''"
|
|
32887
|
+
[avatarType]="'initials'"
|
|
32888
|
+
[groupStackMembers]="peerChat.resolveGroupMembers(conv)"
|
|
32889
|
+
[groupCustomAvatarUrl]="conv.customAvatarUrl ?? ''"
|
|
32890
|
+
groupStackExcludeParticipantId="me"
|
|
32891
|
+
[showAvatarBadge]="false"
|
|
32892
|
+
[unread]="conv.unread"
|
|
32893
|
+
[clickable]="true"
|
|
32894
|
+
(messageClick)="openPeerMessagePreview(conv)"
|
|
32895
|
+
>
|
|
32896
|
+
</ds-mobile-interactive-list-item-message>
|
|
32897
|
+
} @else {
|
|
32898
|
+
<ds-mobile-interactive-list-item-message
|
|
32899
|
+
[senderName]="conv.participant.name"
|
|
32900
|
+
[senderRole]="conv.participant.role ?? ''"
|
|
32901
|
+
[timestamp]="conv.timestamp"
|
|
32902
|
+
[message]="conv.lastMessage"
|
|
32903
|
+
[avatarInitials]="conv.participant.avatarInitials ?? ''"
|
|
32904
|
+
[avatarType]="conv.participant.avatarType ?? 'initials'"
|
|
32905
|
+
[showAvatarBadge]="false"
|
|
32906
|
+
[unread]="conv.unread"
|
|
32907
|
+
[clickable]="true"
|
|
32908
|
+
(messageClick)="openPeerMessagePreview(conv)"
|
|
32909
|
+
>
|
|
32910
|
+
</ds-mobile-interactive-list-item-message>
|
|
32911
|
+
}
|
|
32912
|
+
}
|
|
32913
|
+
</div>
|
|
32914
|
+
</ds-mobile-section>
|
|
32915
|
+
|
|
32916
|
+
<!-- Services preview -->
|
|
32917
|
+
@if (previewVendors().length > 0) {
|
|
32918
|
+
<ds-mobile-section headline="Services" linkText="Se alle" contentGap="0px" (linkClick)="navigateToServices()">
|
|
32919
|
+
@for (vendor of previewVendors(); track vendor.id) {
|
|
32920
|
+
<ds-mobile-interactive-list-item-service
|
|
32921
|
+
[title]="vendor.name"
|
|
32922
|
+
[description]="vendor.description || ''"
|
|
32923
|
+
[logo]="vendor.logo || ''"
|
|
32924
|
+
(serviceClick)="openVendorSheet(vendor)"
|
|
32925
|
+
/>
|
|
32926
|
+
}
|
|
32927
|
+
</ds-mobile-section>
|
|
32928
|
+
}
|
|
32929
|
+
|
|
32930
|
+
<!-- Recent Community Posts Section (empty state) -->
|
|
32931
|
+
<ds-mobile-section>
|
|
32932
|
+
<div class="empty-state">
|
|
32933
|
+
<ds-mobile-illustration variant="post" alt="No posts" />
|
|
32934
|
+
<h3 class="empty-state-title">Ingen opslag endnu</h3>
|
|
32935
|
+
<p class="empty-state-description">Der er ingen opslag i fællesområdet i øjeblikket</p>
|
|
32936
|
+
|
|
32937
|
+
<ds-button variant="secondary" trailingIcon="remixArrowRightSLine" (click)="navigateToCommunity()"> Gå til fællesområdet </ds-button>
|
|
32938
|
+
</div>
|
|
32939
|
+
</ds-mobile-section>
|
|
32940
|
+
|
|
32941
|
+
<!-- Open Inquiries Section (with content) -->
|
|
32942
|
+
<ds-mobile-section headline="Åbne henvendelser" linkText="Se alle" (linkClick)="navigateToInquiries()">
|
|
32943
|
+
<div class="inquiries-list">
|
|
32944
|
+
@for (inquiry of openInquiries(); track inquiry.id) {
|
|
32945
|
+
<ds-mobile-interactive-list-item-inquiry
|
|
32946
|
+
[title]="inquiry.title"
|
|
32947
|
+
[description]="inquiry.description"
|
|
32948
|
+
[status]="inquiry.status"
|
|
32949
|
+
[timestamp]="inquiry.timestamp"
|
|
32950
|
+
[iconName]="'remixTodoLine'"
|
|
31401
32951
|
[clickable]="true"
|
|
31402
|
-
|
|
31403
|
-
|
|
32952
|
+
[showChevron]="false"
|
|
32953
|
+
[enableLongPress]="false"
|
|
32954
|
+
(inquiryClick)="openInquiryDetail(inquiry.id)"
|
|
32955
|
+
>
|
|
32956
|
+
</ds-mobile-interactive-list-item-inquiry>
|
|
31404
32957
|
}
|
|
31405
|
-
|
|
31406
|
-
</div>
|
|
31407
|
-
</ds-mobile-section>
|
|
31408
|
-
|
|
31409
|
-
<!-- Services preview -->
|
|
31410
|
-
@if (previewVendors().length > 0) {
|
|
31411
|
-
<ds-mobile-section
|
|
31412
|
-
headline="Services"
|
|
31413
|
-
linkText="Se alle"
|
|
31414
|
-
contentGap="0px"
|
|
31415
|
-
(linkClick)="navigateToServices()">
|
|
31416
|
-
@for (vendor of previewVendors(); track vendor.id) {
|
|
31417
|
-
<ds-mobile-interactive-list-item-service
|
|
31418
|
-
[title]="vendor.name"
|
|
31419
|
-
[description]="vendor.description || ''"
|
|
31420
|
-
[logo]="vendor.logo || ''"
|
|
31421
|
-
(serviceClick)="openVendorSheet(vendor)"
|
|
31422
|
-
/>
|
|
31423
|
-
}
|
|
32958
|
+
</div>
|
|
31424
32959
|
</ds-mobile-section>
|
|
31425
|
-
}
|
|
31426
32960
|
|
|
31427
|
-
|
|
31428
|
-
|
|
31429
|
-
|
|
31430
|
-
|
|
31431
|
-
|
|
31432
|
-
|
|
31433
|
-
|
|
31434
|
-
<ds-button
|
|
31435
|
-
variant="secondary"
|
|
31436
|
-
trailingIcon="remixArrowRightSLine"
|
|
31437
|
-
(click)="navigateToCommunity()">
|
|
31438
|
-
Gå til fællesområdet
|
|
31439
|
-
</ds-button>
|
|
31440
|
-
</div>
|
|
31441
|
-
</ds-mobile-section>
|
|
31442
|
-
|
|
31443
|
-
<!-- Open Inquiries Section (with content) -->
|
|
31444
|
-
<ds-mobile-section
|
|
31445
|
-
headline="Åbne henvendelser"
|
|
31446
|
-
linkText="Se alle"
|
|
31447
|
-
(linkClick)="navigateToInquiries()">
|
|
31448
|
-
|
|
31449
|
-
<div class="inquiries-list">
|
|
31450
|
-
@for (inquiry of openInquiries(); track inquiry.id) {
|
|
31451
|
-
<ds-mobile-interactive-list-item-inquiry
|
|
31452
|
-
[title]="inquiry.title"
|
|
31453
|
-
[description]="inquiry.description"
|
|
31454
|
-
[status]="inquiry.status"
|
|
31455
|
-
[timestamp]="inquiry.timestamp"
|
|
31456
|
-
[iconName]="'remixTodoLine'"
|
|
31457
|
-
[clickable]="true"
|
|
31458
|
-
[showChevron]="false"
|
|
31459
|
-
[enableLongPress]="false"
|
|
31460
|
-
(inquiryClick)="openInquiryDetail(inquiry.id)">
|
|
31461
|
-
</ds-mobile-interactive-list-item-inquiry>
|
|
31462
|
-
}
|
|
31463
|
-
</div>
|
|
31464
|
-
</ds-mobile-section>
|
|
31465
|
-
|
|
31466
|
-
<!-- Open Inquiries Section (empty state) -->
|
|
31467
|
-
<ds-mobile-section>
|
|
31468
|
-
<div class="empty-state">
|
|
31469
|
-
<ds-mobile-illustration variant="inquiry" alt="No inquiries" />
|
|
31470
|
-
<h3 class="empty-state-title">Ingen åbne henvendelser</h3>
|
|
31471
|
-
<p class="empty-state-description">Du har ingen åbne henvendelser i øjeblikket</p>
|
|
31472
|
-
|
|
31473
|
-
<ds-button
|
|
31474
|
-
variant="secondary"
|
|
31475
|
-
trailingIcon="remixArrowRightSLine"
|
|
31476
|
-
(click)="navigateToInquiries()">
|
|
31477
|
-
Gå til henvendelser
|
|
31478
|
-
</ds-button>
|
|
31479
|
-
</div>
|
|
31480
|
-
</ds-mobile-section>
|
|
31481
|
-
</ds-mobile-page-main>
|
|
31482
|
-
} <!-- end @if (!isCoveringScreen()) -->
|
|
32961
|
+
<!-- Open Inquiries Section (empty state) -->
|
|
32962
|
+
<ds-mobile-section>
|
|
32963
|
+
<div class="empty-state">
|
|
32964
|
+
<ds-mobile-illustration variant="inquiry" alt="No inquiries" />
|
|
32965
|
+
<h3 class="empty-state-title">Ingen åbne henvendelser</h3>
|
|
32966
|
+
<p class="empty-state-description">Du har ingen åbne henvendelser i øjeblikket</p>
|
|
31483
32967
|
|
|
31484
|
-
|
|
32968
|
+
<ds-button variant="secondary" trailingIcon="remixArrowRightSLine" (click)="navigateToInquiries()"> Gå til henvendelser </ds-button>
|
|
32969
|
+
</div>
|
|
32970
|
+
</ds-mobile-section>
|
|
32971
|
+
</ds-mobile-page-main>
|
|
32972
|
+
}
|
|
32973
|
+
<!-- end @if (!isCoveringScreen()) -->
|
|
32974
|
+
`, 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"] }]
|
|
31485
32975
|
}], ctorParameters: () => [{ type: i1$3.Router }, { type: i1.NavController }, { type: UserService }, { type: PostsService }, { type: DsMobilePostDetailModalService }, { type: TrackingPermissionService }, { type: DsMobileBottomSheetService }, { type: FamilyAccessService }, { type: PeerMessagingService }, { type: PeerChatLauncherService }, { type: DsMobileLightboxService }], propDecorators: { pageComponent: [{
|
|
31486
32976
|
type: ViewChild,
|
|
31487
32977
|
args: ['pageComponent']
|
|
@@ -31493,6 +32983,8 @@ class MobileInquiriesPageComponent {
|
|
|
31493
32983
|
newInquiryModal;
|
|
31494
32984
|
pageComponent;
|
|
31495
32985
|
inquiriesService = inject(InquiriesService);
|
|
32986
|
+
notificationModal = inject(DsMobileNotificationModalService);
|
|
32987
|
+
notificationService = inject(NotificationService);
|
|
31496
32988
|
constructor(userService, navCtrl, newInquiryModal) {
|
|
31497
32989
|
this.userService = userService;
|
|
31498
32990
|
this.navCtrl = navCtrl;
|
|
@@ -31528,6 +33020,11 @@ class MobileInquiriesPageComponent {
|
|
|
31528
33020
|
console.log('Showing actions for inquiry:', inquiryId);
|
|
31529
33021
|
// Show bottom sheet with actions (edit, delete, etc.)
|
|
31530
33022
|
}
|
|
33023
|
+
async handleNotificationClick() {
|
|
33024
|
+
const tapped = await this.notificationModal.open();
|
|
33025
|
+
if (tapped)
|
|
33026
|
+
console.log('Notification tapped:', tapped.type, tapped.id);
|
|
33027
|
+
}
|
|
31531
33028
|
handleRefresh(event) {
|
|
31532
33029
|
console.log('Pull-to-refresh triggered on inquiries page');
|
|
31533
33030
|
// Check if offline and complete immediately
|
|
@@ -31567,8 +33064,10 @@ class MobileInquiriesPageComponent {
|
|
|
31567
33064
|
<ds-mobile-page-main
|
|
31568
33065
|
#pageComponent
|
|
31569
33066
|
title="Henvendelser"
|
|
33067
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
31570
33068
|
[avatarInitials]="userService.avatarInitials()"
|
|
31571
33069
|
[avatarType]="userService.avatarType()"
|
|
33070
|
+
(notificationClick)="handleNotificationClick()"
|
|
31572
33071
|
(refresh)="handleRefresh($event)">
|
|
31573
33072
|
|
|
31574
33073
|
<!-- Offline indicator -->
|
|
@@ -31632,7 +33131,7 @@ class MobileInquiriesPageComponent {
|
|
|
31632
33131
|
ariaLabel="Create new inquiry"
|
|
31633
33132
|
(clicked)="createNewInquiry()">
|
|
31634
33133
|
</ds-mobile-fab>
|
|
31635
|
-
`, isInline: true, styles: [".inquiry-list-wrapper{display:flex;flex-direction:column;margin-top:-12px}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;text-align:center}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;color:var(--color-text-primary);margin-top:-16px;z-index:4}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);color:var(--color-text-secondary);margin:0}\n"], dependencies: [{ kind: "component", type: DsMobilePageMainComponent, selector: "ds-mobile-page-main", inputs: ["title", "headerTitle", "headerSubtitle", "firstEntry", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileIllustrationComponent, selector: "ds-mobile-illustration", inputs: ["variant", "size", "alt"] }, { kind: "component", type: DsMobileInteractiveListItemInquiryComponent, selector: "ds-mobile-interactive-list-item-inquiry", inputs: ["title", "description", "status", "statusLabel", "timestamp", "iconName", "iconColor", "variant", "align", "clickable", "showChevron", "enableLongPress", "moreActions"], outputs: ["inquiryClick", "longPress"] }, { kind: "component", type: DsMobileInlineTabsComponent, selector: "ds-mobile-inline-tabs", inputs: ["tabs", "activeTab"], outputs: ["tabChange"] }, { kind: "component", type: DsMobileOfflineBannerComponent, selector: "ds-mobile-offline-banner", inputs: ["icon", "title", "message"] }, { kind: "component", type: DsMobileFabComponent, selector: "ds-mobile-fab", inputs: ["icon", "position", "size", "ariaLabel", "disabled"], outputs: ["clicked"] }] });
|
|
33134
|
+
`, 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", "showNotification", "notificationCount", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["notificationClick", "avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileIllustrationComponent, selector: "ds-mobile-illustration", inputs: ["variant", "size", "alt"] }, { kind: "component", type: DsMobileInteractiveListItemInquiryComponent, selector: "ds-mobile-interactive-list-item-inquiry", inputs: ["title", "description", "status", "statusLabel", "timestamp", "iconName", "iconColor", "variant", "align", "clickable", "showChevron", "enableLongPress", "moreActions"], outputs: ["inquiryClick", "longPress"] }, { kind: "component", type: DsMobileInlineTabsComponent, selector: "ds-mobile-inline-tabs", inputs: ["tabs", "activeTab"], outputs: ["tabChange"] }, { kind: "component", type: DsMobileOfflineBannerComponent, selector: "ds-mobile-offline-banner", inputs: ["icon", "title", "message"] }, { kind: "component", type: DsMobileFabComponent, selector: "ds-mobile-fab", inputs: ["icon", "position", "size", "ariaLabel", "disabled"], outputs: ["clicked"] }] });
|
|
31636
33135
|
}
|
|
31637
33136
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MobileInquiriesPageComponent, decorators: [{
|
|
31638
33137
|
type: Component,
|
|
@@ -31650,8 +33149,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
31650
33149
|
<ds-mobile-page-main
|
|
31651
33150
|
#pageComponent
|
|
31652
33151
|
title="Henvendelser"
|
|
33152
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
31653
33153
|
[avatarInitials]="userService.avatarInitials()"
|
|
31654
33154
|
[avatarType]="userService.avatarType()"
|
|
33155
|
+
(notificationClick)="handleNotificationClick()"
|
|
31655
33156
|
(refresh)="handleRefresh($event)">
|
|
31656
33157
|
|
|
31657
33158
|
<!-- Offline indicator -->
|
|
@@ -32323,6 +33824,87 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
32323
33824
|
`, styles: [".activity-list{display:flex;flex-direction:column;gap:12px;position:relative}.activity-list ds-mobile-list-item:not(:last-child) [content-leading]:after{content:\"\";position:absolute;top:40px;left:50%;transform:translate(-50%);width:1px;height:calc(100% - 2px);background:var(--border-color-default, #e5e5e5);z-index:0}.activity-icon-wrapper{width:100%;height:100%;border-radius:8px;background:var(--color-background-neutral-secondary, #f5f5f5);display:flex;align-items:center;justify-content:center;flex-shrink:0;position:relative;z-index:1}.avatar-wrapper{position:relative;display:flex;align-items:start;justify-content:center;flex-shrink:0;width:100%;height:100%;z-index:1}.avatar-badge{position:absolute;bottom:-6px;right:-6px;width:20px;height:20px;border-radius:8px;background:var(--color-brand-secondary, #5d5fef);display:flex;align-items:center;justify-content:center;border:2px solid var(--color-background-primary, #ffffff)}.avatar-badge svg{width:10px;position:relative;top:1px;fill:#fff}.activity-content{display:flex;flex-direction:column;gap:4px}.activity-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;line-height:20px;letter-spacing:-.3px;color:var(--text-color-default-primary, #202227);margin:0}.activity-title .actor-name{font-weight:600;color:var(--text-color-default-primary, #202227)}.activity-title .activity-text{color:var(--text-color-default-secondary, #545B66);font-weight:400}.activity-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:400;line-height:20px;letter-spacing:-.3px;color:var(--text-color-default-secondary, #545B66);margin:0}.activity-timestamp{font-family:Brockmann,sans-serif;font-size:var(--font-size-xs);font-weight:400;line-height:1.2;letter-spacing:-.26px;color:var(--text-color-default-tertiary, #737373);display:flex;align-items:center;gap:4px;margin-top:2px}.detail-label{font-family:Brockmann,sans-serif;font-size:var(--font-size-xs);font-weight:400;line-height:1.2;letter-spacing:-.26px;color:var(--text-color-default-tertiary, #737373)}.detail-value{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:400;line-height:24px;letter-spacing:-.3px;color:var(--text-color-default-primary, #202227)}.detail-tag{display:inline-flex;align-items:center;padding:4px 12px;border-radius:12px;background:var(--color-background-neutral-secondary, #f5f5f5);font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);font-weight:500;color:var(--text-color-default-secondary, #525866);margin-top:4px;margin-bottom:10px;width:-moz-fit-content;width:fit-content}.photo-grid{display:grid;grid-template-columns:repeat(6,1fr);gap:8px}.photo-add{width:100%;aspect-ratio:1;border-radius:12px;border:1px dashed var(--border-color-default, #e5e5e5);background:var(--color-background-neutral-secondary, #f5f5f5);display:flex;align-items:center;justify-content:center;cursor:pointer}.photo-item{width:100%;aspect-ratio:1;border-radius:12px;-o-object-fit:cover;object-fit:cover}.empty-messages{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:60px 20px;gap:12px}.empty-messages-image{width:96px;height:96px;-o-object-fit:contain;object-fit:contain}.empty-messages-text{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm, 14px);color:var(--text-color-default-secondary, #71727a);margin:0}\n"] }]
|
|
32324
33825
|
}], ctorParameters: () => [{ type: UserService }, { type: DsMobileLightboxService }, { type: DsMobileChatModalService }] });
|
|
32325
33826
|
|
|
33827
|
+
const STORAGE_KEY = 'ds-notification-prompt-dismissed';
|
|
33828
|
+
const COOLDOWN_MS = 24 * 60 * 60 * 1000; // 24 hours
|
|
33829
|
+
/**
|
|
33830
|
+
* Manages the notification permission prompt lifecycle.
|
|
33831
|
+
*
|
|
33832
|
+
* - Stores the user's "Not now" dismissal timestamp in localStorage
|
|
33833
|
+
* - Re-shows the prompt after a 24-hour cooldown
|
|
33834
|
+
* - Skips the prompt entirely if native permissions are already granted
|
|
33835
|
+
*
|
|
33836
|
+
* Downstream integration: call `checkPermissions()` before checking
|
|
33837
|
+
* `shouldShowPrompt()` to incorporate native permission status.
|
|
33838
|
+
*/
|
|
33839
|
+
class NotificationPromptService {
|
|
33840
|
+
permissionGranted = false;
|
|
33841
|
+
/**
|
|
33842
|
+
* Record that the user dismissed the prompt. Stores the current
|
|
33843
|
+
* timestamp so the prompt can be suppressed for 24 hours.
|
|
33844
|
+
*/
|
|
33845
|
+
dismiss() {
|
|
33846
|
+
try {
|
|
33847
|
+
localStorage.setItem(STORAGE_KEY, JSON.stringify({ dismissedAt: Date.now() }));
|
|
33848
|
+
}
|
|
33849
|
+
catch {
|
|
33850
|
+
// localStorage unavailable (SSR, private browsing quota)
|
|
33851
|
+
}
|
|
33852
|
+
}
|
|
33853
|
+
/**
|
|
33854
|
+
* Whether the prompt should be displayed right now.
|
|
33855
|
+
* Returns false if:
|
|
33856
|
+
* - Native permission is already granted
|
|
33857
|
+
* - The user dismissed less than 24 hours ago
|
|
33858
|
+
*/
|
|
33859
|
+
shouldShowPrompt() {
|
|
33860
|
+
if (this.permissionGranted)
|
|
33861
|
+
return false;
|
|
33862
|
+
try {
|
|
33863
|
+
const raw = localStorage.getItem(STORAGE_KEY);
|
|
33864
|
+
if (!raw)
|
|
33865
|
+
return true;
|
|
33866
|
+
const { dismissedAt } = JSON.parse(raw);
|
|
33867
|
+
return Date.now() - dismissedAt >= COOLDOWN_MS;
|
|
33868
|
+
}
|
|
33869
|
+
catch {
|
|
33870
|
+
return true;
|
|
33871
|
+
}
|
|
33872
|
+
}
|
|
33873
|
+
/**
|
|
33874
|
+
* Call this on app launch to check native notification permission status.
|
|
33875
|
+
* If already granted, the prompt will never be shown.
|
|
33876
|
+
*/
|
|
33877
|
+
async checkPermissions() {
|
|
33878
|
+
try {
|
|
33879
|
+
const { PushNotifications } = await import('@capacitor/push-notifications');
|
|
33880
|
+
const result = await PushNotifications.checkPermissions();
|
|
33881
|
+
this.permissionGranted = result.receive === 'granted';
|
|
33882
|
+
}
|
|
33883
|
+
catch {
|
|
33884
|
+
// Not on native — leave as false so the prompt can still show
|
|
33885
|
+
}
|
|
33886
|
+
}
|
|
33887
|
+
/**
|
|
33888
|
+
* Mark that the user has granted permission (called after a successful
|
|
33889
|
+
* allow flow so the prompt is permanently hidden for this session).
|
|
33890
|
+
*/
|
|
33891
|
+
markGranted() {
|
|
33892
|
+
this.permissionGranted = true;
|
|
33893
|
+
try {
|
|
33894
|
+
localStorage.removeItem(STORAGE_KEY);
|
|
33895
|
+
}
|
|
33896
|
+
catch {
|
|
33897
|
+
// noop
|
|
33898
|
+
}
|
|
33899
|
+
}
|
|
33900
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NotificationPromptService, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
|
|
33901
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NotificationPromptService, providedIn: 'root' });
|
|
33902
|
+
}
|
|
33903
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: NotificationPromptService, decorators: [{
|
|
33904
|
+
type: Injectable,
|
|
33905
|
+
args: [{ providedIn: 'root' }]
|
|
33906
|
+
}] });
|
|
33907
|
+
|
|
32326
33908
|
/**
|
|
32327
33909
|
* Whitelabel Demo Modal Component
|
|
32328
33910
|
*
|
|
@@ -33462,7 +35044,11 @@ class MobileTabsExampleComponent {
|
|
|
33462
35044
|
navCtrl;
|
|
33463
35045
|
whitelabelDemoModal = inject(WhitelabelDemoModalService);
|
|
33464
35046
|
trackingPermissionService = inject(TrackingPermissionService);
|
|
35047
|
+
notificationModal = inject(DsMobileNotificationModalService);
|
|
35048
|
+
notificationService = inject(NotificationService);
|
|
35049
|
+
notificationPrompt = inject(NotificationPromptService);
|
|
33465
35050
|
pageLoading = inject(PageLoadingService);
|
|
35051
|
+
showNotificationPrompt = signal(false, ...(ngDevMode ? [{ debugName: "showNotificationPrompt" }] : []));
|
|
33466
35052
|
trackedProfileMenuItems = computed(() => {
|
|
33467
35053
|
const accountActions = [
|
|
33468
35054
|
{
|
|
@@ -33473,8 +35059,8 @@ class MobileTabsExampleComponent {
|
|
|
33473
35059
|
},
|
|
33474
35060
|
{
|
|
33475
35061
|
action: 'settings',
|
|
33476
|
-
title: '
|
|
33477
|
-
icon: '
|
|
35062
|
+
title: 'Notifikationer',
|
|
35063
|
+
icon: 'remixNotificationLine',
|
|
33478
35064
|
destructive: false,
|
|
33479
35065
|
},
|
|
33480
35066
|
{
|
|
@@ -33542,15 +35128,15 @@ class MobileTabsExampleComponent {
|
|
|
33542
35128
|
this.userService.setProfileMenuItems(this.trackedProfileMenuItems());
|
|
33543
35129
|
});
|
|
33544
35130
|
}
|
|
33545
|
-
ngOnInit() {
|
|
35131
|
+
async ngOnInit() {
|
|
33546
35132
|
console.log('MobileTabsExampleComponent ngOnInit');
|
|
33547
|
-
// Configure user avatar globally - this is now the single source of truth
|
|
33548
35133
|
this.userService.setDisplayName('Lucas Møller');
|
|
33549
35134
|
this.userService.setAddress('Toftegårds Allé 5A, 3. tv.');
|
|
33550
35135
|
this.userService.setAvatarInitials('LM');
|
|
33551
35136
|
this.userService.setAvatarType('initials');
|
|
33552
|
-
// Initial status refresh ensures menu reflects past ATT choice.
|
|
33553
35137
|
void this.trackingPermissionService.refreshTrackingStatus();
|
|
35138
|
+
await this.notificationPrompt.checkPermissions();
|
|
35139
|
+
this.showNotificationPrompt.set(this.notificationPrompt.shouldShowPrompt());
|
|
33554
35140
|
}
|
|
33555
35141
|
tabs = [
|
|
33556
35142
|
{
|
|
@@ -33657,6 +35243,34 @@ class MobileTabsExampleComponent {
|
|
|
33657
35243
|
});
|
|
33658
35244
|
}
|
|
33659
35245
|
}
|
|
35246
|
+
async handleNotificationAllow() {
|
|
35247
|
+
console.log('Notification permission: requesting native dialog...');
|
|
35248
|
+
this.showNotificationPrompt.set(false);
|
|
35249
|
+
try {
|
|
35250
|
+
const { PushNotifications } = await import('@capacitor/push-notifications');
|
|
35251
|
+
const permission = await PushNotifications.requestPermissions();
|
|
35252
|
+
console.log('Push permission result:', permission.receive);
|
|
35253
|
+
if (permission.receive === 'granted') {
|
|
35254
|
+
await PushNotifications.register();
|
|
35255
|
+
this.notificationPrompt.markGranted();
|
|
35256
|
+
console.log('Push notifications registered');
|
|
35257
|
+
}
|
|
35258
|
+
}
|
|
35259
|
+
catch (err) {
|
|
35260
|
+
console.warn('Push notifications not available (web/simulator):', err);
|
|
35261
|
+
}
|
|
35262
|
+
}
|
|
35263
|
+
handleNotificationDismiss() {
|
|
35264
|
+
console.log('Notification permission: dismissed (24hr cooldown)');
|
|
35265
|
+
this.notificationPrompt.dismiss();
|
|
35266
|
+
this.showNotificationPrompt.set(false);
|
|
35267
|
+
}
|
|
35268
|
+
async handleNotificationClick() {
|
|
35269
|
+
const tapped = await this.notificationModal.open();
|
|
35270
|
+
if (tapped) {
|
|
35271
|
+
console.log('Notification tapped:', tapped.type, tapped.id);
|
|
35272
|
+
}
|
|
35273
|
+
}
|
|
33660
35274
|
/** Called by the error overlay retry button — clears error and re-navigates to home */
|
|
33661
35275
|
handleRetry() {
|
|
33662
35276
|
this.pageLoading.hasError.set(false);
|
|
@@ -33678,26 +35292,35 @@ class MobileTabsExampleComponent {
|
|
|
33678
35292
|
</div>
|
|
33679
35293
|
}
|
|
33680
35294
|
|
|
35295
|
+
<!-- Notification permission prompt (session-only, reappears on next launch) -->
|
|
35296
|
+
@if (showNotificationPrompt() && !pageLoading.isCoveringScreen()) {
|
|
35297
|
+
<ds-mobile-notification-prompt
|
|
35298
|
+
(allow)="handleNotificationAllow()"
|
|
35299
|
+
(dismiss)="handleNotificationDismiss()" />
|
|
35300
|
+
}
|
|
35301
|
+
|
|
33681
35302
|
<ion-tabs class="ds-tabs-wrapper">
|
|
33682
35303
|
<!-- Tab bar is hidden during the loading state -->
|
|
33683
35304
|
@if (!pageLoading.isCoveringScreen()) {
|
|
33684
35305
|
<ds-mobile-tab-bar
|
|
33685
35306
|
[tabs]="tabs"
|
|
33686
35307
|
[moreMenuItems]="moreMenuItems"
|
|
35308
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
33687
35309
|
[avatarInitials]="userService.avatarInitials()"
|
|
33688
35310
|
[avatarType]="userService.avatarType()"
|
|
33689
35311
|
[profileMenuItems]="profileMenuItems"
|
|
35312
|
+
(notificationClick)="handleNotificationClick()"
|
|
33690
35313
|
(profileActionSelected)="handleProfileAction($event)"
|
|
33691
35314
|
(moreMenuItemSelected)="handleMoreMenuAction($event)"
|
|
33692
35315
|
>
|
|
33693
35316
|
</ds-mobile-tab-bar>
|
|
33694
35317
|
}
|
|
33695
35318
|
</ion-tabs>
|
|
33696
|
-
`, isInline: true, styles: [":host{display:block;height:100dvh;width:100vw;position:relative}.app-error{position:fixed;inset:0;z-index:9999;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;padding:40px 32px;background:var(--color-header-surface, #2D2356)}.app-error__title{font-family:Brockmann,sans-serif;font-size:var(--font-size-lg, 18px);font-weight:600;color:var(--color-header-content, #fff);text-align:center;margin:0}.app-error__description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);color:#ffffffa6;text-align:center;margin:0 0 8px}.app-error ds-button::ng-deep .btn{border-radius:9999px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: IonTabs, selector: "ion-tabs" }, { kind: "component", type: DsMobileTabBarComponent, selector: "ds-mobile-tab-bar", inputs: ["tabs", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "profileMenuItems", "moreMenuItems", "moreMenuLabel", "moreMenuIcon", "moreMenuIconActive"], outputs: ["avatarClick", "profileActionSelected", "moreMenuItemSelected"] }, { kind: "component", type: DsMobileAppLoadingComponent, selector: "ds-mobile-app-loading", inputs: ["isExiting"], outputs: ["exitComplete"] }, { kind: "component", type: DsButtonComponent, selector: "ds-button", inputs: ["variant", "size", "disabled", "loading", "pressed", "expanded", "leadingIcon", "trailingIcon", "ariaLabel", "iconOnly"], outputs: ["clicked", "focused", "blurred"] }] });
|
|
35319
|
+
`, isInline: true, styles: [":host{display:block;height:100dvh;width:100vw;position:relative}.app-error{position:fixed;inset:0;z-index:9999;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;padding:40px 32px;background:var(--color-header-surface, #2D2356)}.app-error__title{font-family:Brockmann,sans-serif;font-size:var(--font-size-lg, 18px);font-weight:600;color:var(--color-header-content, #fff);text-align:center;margin:0}.app-error__description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);color:#ffffffa6;text-align:center;margin:0 0 8px}.app-error ds-button::ng-deep .btn{border-radius:9999px}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: IonTabs, selector: "ion-tabs" }, { kind: "component", type: DsMobileTabBarComponent, selector: "ds-mobile-tab-bar", inputs: ["tabs", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "profileMenuItems", "notificationCount", "moreMenuItems", "moreMenuLabel", "moreMenuIcon", "moreMenuIconActive"], outputs: ["notificationClick", "avatarClick", "profileActionSelected", "moreMenuItemSelected"] }, { kind: "component", type: DsMobileAppLoadingComponent, selector: "ds-mobile-app-loading", inputs: ["isExiting"], outputs: ["exitComplete"] }, { kind: "component", type: DsMobileNotificationPromptComponent, selector: "ds-mobile-notification-prompt", inputs: ["heading", "subtitle", "allowLabel", "dismissLabel"], outputs: ["allow", "dismiss"] }, { kind: "component", type: DsButtonComponent, selector: "ds-button", inputs: ["variant", "size", "disabled", "loading", "pressed", "expanded", "leadingIcon", "trailingIcon", "ariaLabel", "iconOnly"], outputs: ["clicked", "focused", "blurred"] }] });
|
|
33697
35320
|
}
|
|
33698
35321
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MobileTabsExampleComponent, decorators: [{
|
|
33699
35322
|
type: Component,
|
|
33700
|
-
args: [{ selector: 'app-mobile-tabs-example', standalone: true, imports: [CommonModule, IonTabs, DsMobileTabBarComponent, DsMobileAppLoadingComponent, DsButtonComponent], template: `
|
|
35323
|
+
args: [{ selector: 'app-mobile-tabs-example', standalone: true, imports: [CommonModule, IonTabs, DsMobileTabBarComponent, DsMobileAppLoadingComponent, DsMobileNotificationPromptComponent, DsButtonComponent], template: `
|
|
33701
35324
|
<!-- Full-screen loading screen rendered at layout level so it covers the tab bar.
|
|
33702
35325
|
Kept in DOM during exiting so the exit animation can play. -->
|
|
33703
35326
|
@if (pageLoading.isLoading() || pageLoading.isExiting()) {
|
|
@@ -33712,15 +35335,24 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
33712
35335
|
</div>
|
|
33713
35336
|
}
|
|
33714
35337
|
|
|
35338
|
+
<!-- Notification permission prompt (session-only, reappears on next launch) -->
|
|
35339
|
+
@if (showNotificationPrompt() && !pageLoading.isCoveringScreen()) {
|
|
35340
|
+
<ds-mobile-notification-prompt
|
|
35341
|
+
(allow)="handleNotificationAllow()"
|
|
35342
|
+
(dismiss)="handleNotificationDismiss()" />
|
|
35343
|
+
}
|
|
35344
|
+
|
|
33715
35345
|
<ion-tabs class="ds-tabs-wrapper">
|
|
33716
35346
|
<!-- Tab bar is hidden during the loading state -->
|
|
33717
35347
|
@if (!pageLoading.isCoveringScreen()) {
|
|
33718
35348
|
<ds-mobile-tab-bar
|
|
33719
35349
|
[tabs]="tabs"
|
|
33720
35350
|
[moreMenuItems]="moreMenuItems"
|
|
35351
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
33721
35352
|
[avatarInitials]="userService.avatarInitials()"
|
|
33722
35353
|
[avatarType]="userService.avatarType()"
|
|
33723
35354
|
[profileMenuItems]="profileMenuItems"
|
|
35355
|
+
(notificationClick)="handleNotificationClick()"
|
|
33724
35356
|
(profileActionSelected)="handleProfileAction($event)"
|
|
33725
35357
|
(moreMenuItemSelected)="handleMoreMenuAction($event)"
|
|
33726
35358
|
>
|
|
@@ -33730,393 +35362,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
33730
35362
|
`, styles: [":host{display:block;height:100dvh;width:100vw;position:relative}.app-error{position:fixed;inset:0;z-index:9999;display:flex;flex-direction:column;align-items:center;justify-content:center;gap:8px;padding:40px 32px;background:var(--color-header-surface, #2D2356)}.app-error__title{font-family:Brockmann,sans-serif;font-size:var(--font-size-lg, 18px);font-weight:600;color:var(--color-header-content, #fff);text-align:center;margin:0}.app-error__description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);color:#ffffffa6;text-align:center;margin:0 0 8px}.app-error ds-button::ng-deep .btn{border-radius:9999px}\n"] }]
|
|
33731
35363
|
}], ctorParameters: () => [{ type: UserService }, { type: i1$3.Router }, { type: i1.NavController }] });
|
|
33732
35364
|
|
|
33733
|
-
class DsMobileBookingDetailSheetComponent {
|
|
33734
|
-
modalController;
|
|
33735
|
-
/** `sheet` = bottom sheet. `modal` = `ds-modal-base` shell (active + history bookings). */
|
|
33736
|
-
presentation = 'sheet';
|
|
33737
|
-
data;
|
|
33738
|
-
/** When true the modal sizes to its content instead of filling the screen. */
|
|
33739
|
-
autoHeight = false;
|
|
33740
|
-
get isModalPresentation() {
|
|
33741
|
-
return this.presentation === 'modal';
|
|
33742
|
-
}
|
|
33743
|
-
constructor(modalController) {
|
|
33744
|
-
this.modalController = modalController;
|
|
33745
|
-
}
|
|
33746
|
-
close() {
|
|
33747
|
-
this.modalController.dismiss(null, 'backdrop');
|
|
33748
|
-
}
|
|
33749
|
-
cancelBooking() {
|
|
33750
|
-
this.modalController.dismiss(null, 'cancel');
|
|
33751
|
-
}
|
|
33752
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetComponent, deps: [{ token: i1.ModalController }], target: i0.ɵɵFactoryTarget.Component });
|
|
33753
|
-
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: DsMobileBookingDetailSheetComponent, isStandalone: true, selector: "ds-mobile-booking-detail-sheet", inputs: { presentation: "presentation", data: "data", autoHeight: "autoHeight" }, host: { properties: { "class.presentation-modal": "this.isModalPresentation" } }, ngImport: i0, template: `
|
|
33754
|
-
@if (presentation === 'modal') {
|
|
33755
|
-
<ds-mobile-modal-base
|
|
33756
|
-
[headerTitle]="data.facilityTitle"
|
|
33757
|
-
[closeButtonLabel]="'Luk'"
|
|
33758
|
-
[isAutoHeight]="autoHeight"
|
|
33759
|
-
[keyboardContentBehavior]="'follow'">
|
|
33760
|
-
|
|
33761
|
-
<ds-mobile-section
|
|
33762
|
-
[showBorder]="false"
|
|
33763
|
-
padding="20px 20px 0 20px">
|
|
33764
|
-
<div class="hero-image-container">
|
|
33765
|
-
@if (data.heroImage) {
|
|
33766
|
-
<img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
|
|
33767
|
-
} @else {
|
|
33768
|
-
<div class="hero-image-placeholder">
|
|
33769
|
-
<ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
|
|
33770
|
-
</div>
|
|
33771
|
-
}
|
|
33772
|
-
</div>
|
|
33773
|
-
</ds-mobile-section>
|
|
33774
|
-
|
|
33775
|
-
<ds-mobile-section padding="20px 20px 20px 20px">
|
|
33776
|
-
<div class="booking-summary-card">
|
|
33777
|
-
<div class="details-section">
|
|
33778
|
-
<h3 class="details-heading">Booking detaljer</h3>
|
|
33779
|
-
<div class="info-rows">
|
|
33780
|
-
@if (data.bookingDate) {
|
|
33781
|
-
<div class="info-row">
|
|
33782
|
-
<ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
|
|
33783
|
-
<span>{{ data.bookingDate }}</span>
|
|
33784
|
-
</div>
|
|
33785
|
-
}
|
|
33786
|
-
@if (data.bookingTime) {
|
|
33787
|
-
<div class="info-row">
|
|
33788
|
-
<ds-icon name="remixTimeLine" size="16px" color="tertiary" />
|
|
33789
|
-
<span>{{ data.bookingTime }}</span>
|
|
33790
|
-
</div>
|
|
33791
|
-
}
|
|
33792
|
-
@if (data.price) {
|
|
33793
|
-
<div class="info-row">
|
|
33794
|
-
<ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
|
|
33795
|
-
<span>{{ data.price }}</span>
|
|
33796
|
-
</div>
|
|
33797
|
-
}
|
|
33798
|
-
@if (data.bookingType) {
|
|
33799
|
-
<div class="info-row">
|
|
33800
|
-
<ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
|
|
33801
|
-
<span>{{ data.bookingType }}</span>
|
|
33802
|
-
</div>
|
|
33803
|
-
}
|
|
33804
|
-
@for (req of data.requirements || []; track req) {
|
|
33805
|
-
<div class="info-row">
|
|
33806
|
-
<ds-icon name="remixLockLine" size="16px" color="tertiary" />
|
|
33807
|
-
<span>{{ req }}</span>
|
|
33808
|
-
</div>
|
|
33809
|
-
}
|
|
33810
|
-
</div>
|
|
33811
|
-
</div>
|
|
33812
|
-
</div>
|
|
33813
|
-
</ds-mobile-section>
|
|
33814
|
-
|
|
33815
|
-
@if (data.canCancel) {
|
|
33816
|
-
<div class="booking-action">
|
|
33817
|
-
<div class="booking-actions-row">
|
|
33818
|
-
<ds-button
|
|
33819
|
-
class="cancel-primary"
|
|
33820
|
-
size="md"
|
|
33821
|
-
variant="secondary"
|
|
33822
|
-
(clicked)="cancelBooking()">
|
|
33823
|
-
Annuller booking
|
|
33824
|
-
</ds-button>
|
|
33825
|
-
</div>
|
|
33826
|
-
</div>
|
|
33827
|
-
}
|
|
33828
|
-
</ds-mobile-modal-base>
|
|
33829
|
-
} @else {
|
|
33830
|
-
<ds-mobile-bottom-sheet-wrapper [showDragHandle]="true">
|
|
33831
|
-
<div class="detail-header">
|
|
33832
|
-
<h2 class="detail-title">{{ data.facilityTitle }}</h2>
|
|
33833
|
-
<ds-icon-button
|
|
33834
|
-
icon="remixCloseLine"
|
|
33835
|
-
variant="ghost"
|
|
33836
|
-
size="sm"
|
|
33837
|
-
(clicked)="close()"
|
|
33838
|
-
aria-label="Luk"
|
|
33839
|
-
/>
|
|
33840
|
-
</div>
|
|
33841
|
-
|
|
33842
|
-
<div class="detail-content">
|
|
33843
|
-
<div class="hero-image-container">
|
|
33844
|
-
@if (data.heroImage) {
|
|
33845
|
-
<img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
|
|
33846
|
-
} @else {
|
|
33847
|
-
<div class="hero-image-placeholder">
|
|
33848
|
-
<ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
|
|
33849
|
-
</div>
|
|
33850
|
-
}
|
|
33851
|
-
</div>
|
|
33852
|
-
|
|
33853
|
-
<div class="booking-summary-card">
|
|
33854
|
-
<div class="details-section">
|
|
33855
|
-
<h3 class="details-heading">Booking detaljer</h3>
|
|
33856
|
-
<div class="info-rows">
|
|
33857
|
-
@if (data.bookingDate) {
|
|
33858
|
-
<div class="info-row">
|
|
33859
|
-
<ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
|
|
33860
|
-
<span>{{ data.bookingDate }}</span>
|
|
33861
|
-
</div>
|
|
33862
|
-
}
|
|
33863
|
-
@if (data.bookingTime) {
|
|
33864
|
-
<div class="info-row">
|
|
33865
|
-
<ds-icon name="remixTimeLine" size="16px" color="tertiary" />
|
|
33866
|
-
<span>{{ data.bookingTime }}</span>
|
|
33867
|
-
</div>
|
|
33868
|
-
}
|
|
33869
|
-
@if (data.price) {
|
|
33870
|
-
<div class="info-row">
|
|
33871
|
-
<ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
|
|
33872
|
-
<span>{{ data.price }}</span>
|
|
33873
|
-
</div>
|
|
33874
|
-
}
|
|
33875
|
-
@if (data.bookingType) {
|
|
33876
|
-
<div class="info-row">
|
|
33877
|
-
<ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
|
|
33878
|
-
<span>{{ data.bookingType }}</span>
|
|
33879
|
-
</div>
|
|
33880
|
-
}
|
|
33881
|
-
@for (req of data.requirements || []; track req) {
|
|
33882
|
-
<div class="info-row">
|
|
33883
|
-
<ds-icon name="remixLockLine" size="16px" color="tertiary" />
|
|
33884
|
-
<span>{{ req }}</span>
|
|
33885
|
-
</div>
|
|
33886
|
-
}
|
|
33887
|
-
</div>
|
|
33888
|
-
</div>
|
|
33889
|
-
</div>
|
|
33890
|
-
|
|
33891
|
-
@if (data.canCancel) {
|
|
33892
|
-
<div class="footer-button-container">
|
|
33893
|
-
<div class="booking-actions-column">
|
|
33894
|
-
<ds-button
|
|
33895
|
-
size="md"
|
|
33896
|
-
variant="secondary"
|
|
33897
|
-
(clicked)="cancelBooking()">
|
|
33898
|
-
Annuller booking
|
|
33899
|
-
</ds-button>
|
|
33900
|
-
</div>
|
|
33901
|
-
</div>
|
|
33902
|
-
}
|
|
33903
|
-
</div>
|
|
33904
|
-
</ds-mobile-bottom-sheet-wrapper>
|
|
33905
|
-
}
|
|
33906
|
-
`, isInline: true, styles: [":host{display:block;height:auto;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;box-sizing:border-box}.detail-header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px 8px}.detail-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-lg, 18px);font-weight:600;color:var(--text-color-default-primary, #202227);margin:0;flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding-right:12px}.detail-content{padding:8px 20px 24px;display:flex;flex-direction:column;gap:20px}.hero-image-container{width:100%;aspect-ratio:16 / 9;border-radius:12px;overflow:hidden;background:var(--color-surface-secondary, #f5f5f5)}.hero-image{width:100%;height:100%;object-fit:cover;display:block}.hero-image-placeholder{width:100%;height:100%;min-height:0;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,color-mix(in srgb,var(--color-accent, #6B5FF5) 30%,transparent),color-mix(in srgb,var(--color-accent, #6B5FF5) 60%,transparent))}.booking-summary-card{background:var(--color-background-neutral-secondary, #f5f5f5);border-radius:16px;padding:16px}.details-section{display:flex;flex-direction:column;gap:12px}.details-heading{font-family:Brockmann,sans-serif;font-size:var(--font-size-base, 16px);font-weight:600;color:var(--text-color-default-primary, #202227);margin:0}.info-rows{display:flex;flex-direction:column;gap:8px}.info-row{display:flex;align-items:center;gap:10px;font-family:Brockmann,sans-serif;font-size:var(--font-size-sm, 14px);color:var(--text-color-default-secondary, #545B66);line-height:1.4}.info-row ds-icon{flex-shrink:0}.footer-button-container{width:100%;padding:16px 20px 0}.footer-button-container ::ng-deep ds-button{display:block;width:100%}.footer-button-container ::ng-deep ds-button button{width:100%;border-radius:100px;height:44px;min-height:44px;max-height:44px}.booking-action{padding:16px 20px;padding-bottom:calc(16px + max(8px,env(safe-area-inset-bottom,0px) - 24px));background:var(--color-surface-primary, #ffffff)}.booking-actions-row{display:flex;flex-direction:row;align-items:center;gap:12px;width:100%}.booking-action .cancel-primary{flex:1;min-width:0;display:block}.booking-action .cancel-primary ::ng-deep button{width:100%;border-radius:100px;height:44px;min-height:44px;max-height:44px;padding-left:16px;padding-right:16px}:host.presentation-modal{display:block;height:auto;width:100%;min-height:0;overflow:hidden}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "component", type: DsMobileBottomSheetWrapperComponent, selector: "ds-mobile-bottom-sheet-wrapper", inputs: ["showDragHandle"] }, { kind: "component", type: DsMobileModalBaseComponent, selector: "ds-mobile-modal-base", inputs: ["headerTitleInteractive", "showHeader"], outputs: ["titleClick"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsButtonComponent, selector: "ds-button", inputs: ["variant", "size", "disabled", "loading", "pressed", "expanded", "leadingIcon", "trailingIcon", "ariaLabel", "iconOnly"], outputs: ["clicked", "focused", "blurred"] }, { kind: "component", type: DsIconComponent, selector: "ds-icon", inputs: ["name", "size", "color", "interactive"] }, { kind: "component", type: DsIconButtonComponent, selector: "ds-icon-button", inputs: ["variant", "size", "icon", "disabled", "loading", "pressed", "expanded", "ariaLabel", "tooltip", "tooltipDisabled", "tooltipPlacement"], outputs: ["clicked", "focused", "blurred"] }] });
|
|
33907
|
-
}
|
|
33908
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetComponent, decorators: [{
|
|
33909
|
-
type: Component,
|
|
33910
|
-
args: [{ selector: 'ds-mobile-booking-detail-sheet', standalone: true, imports: [
|
|
33911
|
-
CommonModule,
|
|
33912
|
-
DsMobileBottomSheetWrapperComponent,
|
|
33913
|
-
DsMobileModalBaseComponent,
|
|
33914
|
-
DsMobileSectionComponent,
|
|
33915
|
-
DsButtonComponent,
|
|
33916
|
-
DsIconComponent,
|
|
33917
|
-
DsIconButtonComponent,
|
|
33918
|
-
], template: `
|
|
33919
|
-
@if (presentation === 'modal') {
|
|
33920
|
-
<ds-mobile-modal-base
|
|
33921
|
-
[headerTitle]="data.facilityTitle"
|
|
33922
|
-
[closeButtonLabel]="'Luk'"
|
|
33923
|
-
[isAutoHeight]="autoHeight"
|
|
33924
|
-
[keyboardContentBehavior]="'follow'">
|
|
33925
|
-
|
|
33926
|
-
<ds-mobile-section
|
|
33927
|
-
[showBorder]="false"
|
|
33928
|
-
padding="20px 20px 0 20px">
|
|
33929
|
-
<div class="hero-image-container">
|
|
33930
|
-
@if (data.heroImage) {
|
|
33931
|
-
<img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
|
|
33932
|
-
} @else {
|
|
33933
|
-
<div class="hero-image-placeholder">
|
|
33934
|
-
<ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
|
|
33935
|
-
</div>
|
|
33936
|
-
}
|
|
33937
|
-
</div>
|
|
33938
|
-
</ds-mobile-section>
|
|
33939
|
-
|
|
33940
|
-
<ds-mobile-section padding="20px 20px 20px 20px">
|
|
33941
|
-
<div class="booking-summary-card">
|
|
33942
|
-
<div class="details-section">
|
|
33943
|
-
<h3 class="details-heading">Booking detaljer</h3>
|
|
33944
|
-
<div class="info-rows">
|
|
33945
|
-
@if (data.bookingDate) {
|
|
33946
|
-
<div class="info-row">
|
|
33947
|
-
<ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
|
|
33948
|
-
<span>{{ data.bookingDate }}</span>
|
|
33949
|
-
</div>
|
|
33950
|
-
}
|
|
33951
|
-
@if (data.bookingTime) {
|
|
33952
|
-
<div class="info-row">
|
|
33953
|
-
<ds-icon name="remixTimeLine" size="16px" color="tertiary" />
|
|
33954
|
-
<span>{{ data.bookingTime }}</span>
|
|
33955
|
-
</div>
|
|
33956
|
-
}
|
|
33957
|
-
@if (data.price) {
|
|
33958
|
-
<div class="info-row">
|
|
33959
|
-
<ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
|
|
33960
|
-
<span>{{ data.price }}</span>
|
|
33961
|
-
</div>
|
|
33962
|
-
}
|
|
33963
|
-
@if (data.bookingType) {
|
|
33964
|
-
<div class="info-row">
|
|
33965
|
-
<ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
|
|
33966
|
-
<span>{{ data.bookingType }}</span>
|
|
33967
|
-
</div>
|
|
33968
|
-
}
|
|
33969
|
-
@for (req of data.requirements || []; track req) {
|
|
33970
|
-
<div class="info-row">
|
|
33971
|
-
<ds-icon name="remixLockLine" size="16px" color="tertiary" />
|
|
33972
|
-
<span>{{ req }}</span>
|
|
33973
|
-
</div>
|
|
33974
|
-
}
|
|
33975
|
-
</div>
|
|
33976
|
-
</div>
|
|
33977
|
-
</div>
|
|
33978
|
-
</ds-mobile-section>
|
|
33979
|
-
|
|
33980
|
-
@if (data.canCancel) {
|
|
33981
|
-
<div class="booking-action">
|
|
33982
|
-
<div class="booking-actions-row">
|
|
33983
|
-
<ds-button
|
|
33984
|
-
class="cancel-primary"
|
|
33985
|
-
size="md"
|
|
33986
|
-
variant="secondary"
|
|
33987
|
-
(clicked)="cancelBooking()">
|
|
33988
|
-
Annuller booking
|
|
33989
|
-
</ds-button>
|
|
33990
|
-
</div>
|
|
33991
|
-
</div>
|
|
33992
|
-
}
|
|
33993
|
-
</ds-mobile-modal-base>
|
|
33994
|
-
} @else {
|
|
33995
|
-
<ds-mobile-bottom-sheet-wrapper [showDragHandle]="true">
|
|
33996
|
-
<div class="detail-header">
|
|
33997
|
-
<h2 class="detail-title">{{ data.facilityTitle }}</h2>
|
|
33998
|
-
<ds-icon-button
|
|
33999
|
-
icon="remixCloseLine"
|
|
34000
|
-
variant="ghost"
|
|
34001
|
-
size="sm"
|
|
34002
|
-
(clicked)="close()"
|
|
34003
|
-
aria-label="Luk"
|
|
34004
|
-
/>
|
|
34005
|
-
</div>
|
|
34006
|
-
|
|
34007
|
-
<div class="detail-content">
|
|
34008
|
-
<div class="hero-image-container">
|
|
34009
|
-
@if (data.heroImage) {
|
|
34010
|
-
<img [src]="data.heroImage" [alt]="data.facilityTitle" class="hero-image" />
|
|
34011
|
-
} @else {
|
|
34012
|
-
<div class="hero-image-placeholder">
|
|
34013
|
-
<ds-icon name="remixImageLine" size="48px" color="rgba(255,255,255,0.5)" />
|
|
34014
|
-
</div>
|
|
34015
|
-
}
|
|
34016
|
-
</div>
|
|
34017
|
-
|
|
34018
|
-
<div class="booking-summary-card">
|
|
34019
|
-
<div class="details-section">
|
|
34020
|
-
<h3 class="details-heading">Booking detaljer</h3>
|
|
34021
|
-
<div class="info-rows">
|
|
34022
|
-
@if (data.bookingDate) {
|
|
34023
|
-
<div class="info-row">
|
|
34024
|
-
<ds-icon name="remixCalendarLine" size="16px" color="tertiary" />
|
|
34025
|
-
<span>{{ data.bookingDate }}</span>
|
|
34026
|
-
</div>
|
|
34027
|
-
}
|
|
34028
|
-
@if (data.bookingTime) {
|
|
34029
|
-
<div class="info-row">
|
|
34030
|
-
<ds-icon name="remixTimeLine" size="16px" color="tertiary" />
|
|
34031
|
-
<span>{{ data.bookingTime }}</span>
|
|
34032
|
-
</div>
|
|
34033
|
-
}
|
|
34034
|
-
@if (data.price) {
|
|
34035
|
-
<div class="info-row">
|
|
34036
|
-
<ds-icon name="remixPriceTag3Line" size="16px" color="tertiary" />
|
|
34037
|
-
<span>{{ data.price }}</span>
|
|
34038
|
-
</div>
|
|
34039
|
-
}
|
|
34040
|
-
@if (data.bookingType) {
|
|
34041
|
-
<div class="info-row">
|
|
34042
|
-
<ds-icon name="remixCheckboxCircleLine" size="16px" color="tertiary" />
|
|
34043
|
-
<span>{{ data.bookingType }}</span>
|
|
34044
|
-
</div>
|
|
34045
|
-
}
|
|
34046
|
-
@for (req of data.requirements || []; track req) {
|
|
34047
|
-
<div class="info-row">
|
|
34048
|
-
<ds-icon name="remixLockLine" size="16px" color="tertiary" />
|
|
34049
|
-
<span>{{ req }}</span>
|
|
34050
|
-
</div>
|
|
34051
|
-
}
|
|
34052
|
-
</div>
|
|
34053
|
-
</div>
|
|
34054
|
-
</div>
|
|
34055
|
-
|
|
34056
|
-
@if (data.canCancel) {
|
|
34057
|
-
<div class="footer-button-container">
|
|
34058
|
-
<div class="booking-actions-column">
|
|
34059
|
-
<ds-button
|
|
34060
|
-
size="md"
|
|
34061
|
-
variant="secondary"
|
|
34062
|
-
(clicked)="cancelBooking()">
|
|
34063
|
-
Annuller booking
|
|
34064
|
-
</ds-button>
|
|
34065
|
-
</div>
|
|
34066
|
-
</div>
|
|
34067
|
-
}
|
|
34068
|
-
</div>
|
|
34069
|
-
</ds-mobile-bottom-sheet-wrapper>
|
|
34070
|
-
}
|
|
34071
|
-
`, styles: [":host{display:block;height:auto;min-height:0;overflow-y:auto;-webkit-overflow-scrolling:touch;box-sizing:border-box}.detail-header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px 8px}.detail-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-lg, 18px);font-weight:600;color:var(--text-color-default-primary, #202227);margin:0;flex:1;min-width:0;white-space:nowrap;overflow:hidden;text-overflow:ellipsis;padding-right:12px}.detail-content{padding:8px 20px 24px;display:flex;flex-direction:column;gap:20px}.hero-image-container{width:100%;aspect-ratio:16 / 9;border-radius:12px;overflow:hidden;background:var(--color-surface-secondary, #f5f5f5)}.hero-image{width:100%;height:100%;object-fit:cover;display:block}.hero-image-placeholder{width:100%;height:100%;min-height:0;display:flex;align-items:center;justify-content:center;background:linear-gradient(135deg,color-mix(in srgb,var(--color-accent, #6B5FF5) 30%,transparent),color-mix(in srgb,var(--color-accent, #6B5FF5) 60%,transparent))}.booking-summary-card{background:var(--color-background-neutral-secondary, #f5f5f5);border-radius:16px;padding:16px}.details-section{display:flex;flex-direction:column;gap:12px}.details-heading{font-family:Brockmann,sans-serif;font-size:var(--font-size-base, 16px);font-weight:600;color:var(--text-color-default-primary, #202227);margin:0}.info-rows{display:flex;flex-direction:column;gap:8px}.info-row{display:flex;align-items:center;gap:10px;font-family:Brockmann,sans-serif;font-size:var(--font-size-sm, 14px);color:var(--text-color-default-secondary, #545B66);line-height:1.4}.info-row ds-icon{flex-shrink:0}.footer-button-container{width:100%;padding:16px 20px 0}.footer-button-container ::ng-deep ds-button{display:block;width:100%}.footer-button-container ::ng-deep ds-button button{width:100%;border-radius:100px;height:44px;min-height:44px;max-height:44px}.booking-action{padding:16px 20px;padding-bottom:calc(16px + max(8px,env(safe-area-inset-bottom,0px) - 24px));background:var(--color-surface-primary, #ffffff)}.booking-actions-row{display:flex;flex-direction:row;align-items:center;gap:12px;width:100%}.booking-action .cancel-primary{flex:1;min-width:0;display:block}.booking-action .cancel-primary ::ng-deep button{width:100%;border-radius:100px;height:44px;min-height:44px;max-height:44px;padding-left:16px;padding-right:16px}:host.presentation-modal{display:block;height:auto;width:100%;min-height:0;overflow:hidden}\n"] }]
|
|
34072
|
-
}], ctorParameters: () => [{ type: i1.ModalController }], propDecorators: { presentation: [{
|
|
34073
|
-
type: Input
|
|
34074
|
-
}], data: [{
|
|
34075
|
-
type: Input
|
|
34076
|
-
}], autoHeight: [{
|
|
34077
|
-
type: Input
|
|
34078
|
-
}], isModalPresentation: [{
|
|
34079
|
-
type: HostBinding,
|
|
34080
|
-
args: ['class.presentation-modal']
|
|
34081
|
-
}] } });
|
|
34082
|
-
|
|
34083
|
-
class DsMobileBookingDetailSheetService extends BaseModalService {
|
|
34084
|
-
bottomSheet;
|
|
34085
|
-
constructor(modalController, bottomSheet) {
|
|
34086
|
-
super(modalController);
|
|
34087
|
-
this.bottomSheet = bottomSheet;
|
|
34088
|
-
}
|
|
34089
|
-
/**
|
|
34090
|
-
* Bottom-sheet presentation (draggable breakpoints). Prefer `openAsModal` for booking lists.
|
|
34091
|
-
*/
|
|
34092
|
-
async open(data) {
|
|
34093
|
-
const modal = await this.bottomSheet.create({
|
|
34094
|
-
component: DsMobileBookingDetailSheetComponent,
|
|
34095
|
-
componentProps: { data },
|
|
34096
|
-
autoHeight: true,
|
|
34097
|
-
backdropDismiss: true,
|
|
34098
|
-
backdropBlur: true,
|
|
34099
|
-
});
|
|
34100
|
-
const result = await modal.onWillDismiss();
|
|
34101
|
-
return { role: result.role, data: result.data ?? undefined };
|
|
34102
|
-
}
|
|
34103
|
-
/** `ds-modal-base` shell — used for active and past bookings. Auto-heights to content. */
|
|
34104
|
-
async openAsModal(data) {
|
|
34105
|
-
const modal = await this.createModal(DsMobileBookingDetailSheetComponent, { data, presentation: 'modal', autoHeight: true }, { keyboardClose: true, autoHeight: true });
|
|
34106
|
-
await modal.present();
|
|
34107
|
-
const result = await modal.onWillDismiss();
|
|
34108
|
-
return { role: result.role, data: result.data ?? undefined };
|
|
34109
|
-
}
|
|
34110
|
-
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetService, deps: [{ token: i1.ModalController }, { token: DsMobileBottomSheetService }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
34111
|
-
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetService, providedIn: 'root' });
|
|
34112
|
-
}
|
|
34113
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: DsMobileBookingDetailSheetService, decorators: [{
|
|
34114
|
-
type: Injectable,
|
|
34115
|
-
args: [{
|
|
34116
|
-
providedIn: 'root',
|
|
34117
|
-
}]
|
|
34118
|
-
}], ctorParameters: () => [{ type: i1.ModalController }, { type: DsMobileBottomSheetService }] });
|
|
34119
|
-
|
|
34120
35365
|
class DsMobileBookingCancelConfirmationComponent {
|
|
34121
35366
|
facilityTitle;
|
|
34122
35367
|
facilityThumbnail;
|
|
@@ -34217,6 +35462,8 @@ class MobileBookingPageComponent {
|
|
|
34217
35462
|
userService;
|
|
34218
35463
|
pageComponent;
|
|
34219
35464
|
bookingsSwiper;
|
|
35465
|
+
notificationModal = inject(DsMobileNotificationModalService);
|
|
35466
|
+
notificationService = inject(NotificationService);
|
|
34220
35467
|
cancellingBookingId = signal(null, ...(ngDevMode ? [{ debugName: "cancellingBookingId" }] : []));
|
|
34221
35468
|
lang = signal(resolveLanguage(), ...(ngDevMode ? [{ debugName: "lang" }] : []));
|
|
34222
35469
|
historyLinkText = computed(() => HISTORY_LINK[this.lang()] ?? HISTORY_LINK['da'], ...(ngDevMode ? [{ debugName: "historyLinkText" }] : []));
|
|
@@ -34422,6 +35669,11 @@ class MobileBookingPageComponent {
|
|
|
34422
35669
|
}
|
|
34423
35670
|
], ...(ngDevMode ? [{ debugName: "availableFacilities" }] : []));
|
|
34424
35671
|
visibleFacilities = computed(() => this.availableFacilities().filter((f) => !f.archived), ...(ngDevMode ? [{ debugName: "visibleFacilities" }] : []));
|
|
35672
|
+
async handleNotificationClick() {
|
|
35673
|
+
const tapped = await this.notificationModal.open();
|
|
35674
|
+
if (tapped)
|
|
35675
|
+
console.log('Notification tapped:', tapped.type, tapped.id);
|
|
35676
|
+
}
|
|
34425
35677
|
handleRefresh(event) {
|
|
34426
35678
|
console.log('Pull-to-refresh triggered');
|
|
34427
35679
|
// Check if offline and complete immediately
|
|
@@ -34712,8 +35964,10 @@ class MobileBookingPageComponent {
|
|
|
34712
35964
|
<ds-mobile-page-main
|
|
34713
35965
|
#pageComponent
|
|
34714
35966
|
[title]="'Bookinger'"
|
|
35967
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
34715
35968
|
[avatarInitials]="userService.avatarInitials()"
|
|
34716
35969
|
[avatarType]="userService.avatarType()"
|
|
35970
|
+
(notificationClick)="handleNotificationClick()"
|
|
34717
35971
|
(refresh)="handleRefresh($event)">
|
|
34718
35972
|
|
|
34719
35973
|
@if (pageComponent.isOffline()) {
|
|
@@ -34818,7 +36072,7 @@ class MobileBookingPageComponent {
|
|
|
34818
36072
|
ariaLabel="Opret facilitet"
|
|
34819
36073
|
(clicked)="openFacilityCreationModal()">
|
|
34820
36074
|
</ds-mobile-fab>
|
|
34821
|
-
`, isInline: true, styles: [".bookings-swiper-wrapper{padding:0;position:relative}.swiper-nav-buttons{display:contents}.swiper-nav-button{position:absolute;top:50%;transform:translateY(-50%);z-index:10}.swiper-nav-button:first-child{left:-48px}.swiper-nav-button:last-child{right:-48px}::ng-deep .swiper-nav-button button{border-radius:50%!important;width:48px!important;height:48px!important;padding:0!important}@media (max-width: 767px){.swiper-nav-buttons{display:none}}::ng-deep .bookings-swiper .swiper-slide{width:100%;max-width:600px;height:auto;pointer-events:auto}@media (min-width: 768px){::ng-deep .bookings-swiper .swiper-slide{max-width:100%}}::ng-deep .bookings-swiper .swiper-slide ds-mobile-interactive-list-item-booking{width:100%;pointer-events:auto}.booking-slide-content{position:relative;width:100%}\n"], dependencies: [{ kind: "component", type: DsMobilePageMainComponent, selector: "ds-mobile-page-main", inputs: ["title", "headerTitle", "headerSubtitle", "firstEntry", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileInteractiveListItemBookingComponent, selector: "ds-mobile-interactive-list-item-booking", inputs: ["thumbnail", "facilityTitle", "description", "bookingDate", "bookingTime", "availabilityStatus", "statusLabel", "variant", "align", "clickable", "showChevron", "enableLongPress", "moreActions"], outputs: ["bookingClick", "longPress"] }, { kind: "component", type: DsMobileSwiperComponent, selector: "ds-mobile-swiper", inputs: ["slideWidth", "gap", "pagination", "autoHeight", "progressiveOpacity", "progressiveScale"] }, { kind: "component", type: DsIconButtonComponent, selector: "ds-icon-button", inputs: ["variant", "size", "icon", "disabled", "loading", "pressed", "expanded", "ariaLabel", "tooltip", "tooltipDisabled", "tooltipPlacement"], outputs: ["clicked", "focused", "blurred"] }, { kind: "component", type: DsMobileOfflineBannerComponent, selector: "ds-mobile-offline-banner", inputs: ["icon", "title", "message"] }, { kind: "component", type: DsMobileFabComponent, selector: "ds-mobile-fab", inputs: ["icon", "position", "size", "ariaLabel", "disabled"], outputs: ["clicked"] }, { kind: "component", type: DsMobileLoaderOverlayComponent, selector: "ds-mobile-loader-overlay", inputs: ["spinnerSize", "borderRadius"] }] });
|
|
36075
|
+
`, 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", "showNotification", "notificationCount", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["notificationClick", "avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileInteractiveListItemBookingComponent, selector: "ds-mobile-interactive-list-item-booking", inputs: ["thumbnail", "facilityTitle", "description", "bookingDate", "bookingTime", "availabilityStatus", "statusLabel", "variant", "align", "clickable", "showChevron", "enableLongPress", "moreActions"], outputs: ["bookingClick", "longPress"] }, { kind: "component", type: DsMobileSwiperComponent, selector: "ds-mobile-swiper", inputs: ["slideWidth", "gap", "pagination", "autoHeight", "progressiveOpacity", "progressiveScale"] }, { kind: "component", type: DsIconButtonComponent, selector: "ds-icon-button", inputs: ["variant", "size", "icon", "disabled", "loading", "pressed", "expanded", "ariaLabel", "tooltip", "tooltipDisabled", "tooltipPlacement"], outputs: ["clicked", "focused", "blurred"] }, { kind: "component", type: DsMobileOfflineBannerComponent, selector: "ds-mobile-offline-banner", inputs: ["icon", "title", "message"] }, { kind: "component", type: DsMobileFabComponent, selector: "ds-mobile-fab", inputs: ["icon", "position", "size", "ariaLabel", "disabled"], outputs: ["clicked"] }, { kind: "component", type: DsMobileLoaderOverlayComponent, selector: "ds-mobile-loader-overlay", inputs: ["spinnerSize", "borderRadius"] }] });
|
|
34822
36076
|
}
|
|
34823
36077
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: MobileBookingPageComponent, decorators: [{
|
|
34824
36078
|
type: Component,
|
|
@@ -34835,8 +36089,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
34835
36089
|
<ds-mobile-page-main
|
|
34836
36090
|
#pageComponent
|
|
34837
36091
|
[title]="'Bookinger'"
|
|
36092
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
34838
36093
|
[avatarInitials]="userService.avatarInitials()"
|
|
34839
36094
|
[avatarType]="userService.avatarType()"
|
|
36095
|
+
(notificationClick)="handleNotificationClick()"
|
|
34840
36096
|
(refresh)="handleRefresh($event)">
|
|
34841
36097
|
|
|
34842
36098
|
@if (pageComponent.isOffline()) {
|
|
@@ -36726,9 +37982,16 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
36726
37982
|
class TenantChatPageComponent {
|
|
36727
37983
|
modalCtrl = inject(ModalController);
|
|
36728
37984
|
userService = inject(UserService);
|
|
37985
|
+
notificationModal = inject(DsMobileNotificationModalService);
|
|
37986
|
+
notificationService = inject(NotificationService);
|
|
36729
37987
|
peerMessaging = inject(PeerMessagingService);
|
|
36730
37988
|
peerChat = inject(PeerChatLauncherService);
|
|
36731
37989
|
isPeerGroupConversation = isPeerGroupConversation;
|
|
37990
|
+
async handleNotificationClick() {
|
|
37991
|
+
const tapped = await this.notificationModal.open();
|
|
37992
|
+
if (tapped)
|
|
37993
|
+
console.log('Notification tapped:', tapped.type, tapped.id);
|
|
37994
|
+
}
|
|
36732
37995
|
handleRefresh(event) {
|
|
36733
37996
|
setTimeout(() => event.target.complete(), 1000);
|
|
36734
37997
|
}
|
|
@@ -36755,8 +38018,10 @@ class TenantChatPageComponent {
|
|
|
36755
38018
|
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: TenantChatPageComponent, isStandalone: true, selector: "app-tenant-chat-page", host: { classAttribute: "ion-page" }, ngImport: i0, template: `
|
|
36756
38019
|
<ds-mobile-page-main
|
|
36757
38020
|
title="Beskeder"
|
|
38021
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
36758
38022
|
[avatarInitials]="userService.avatarInitials()"
|
|
36759
38023
|
[avatarType]="userService.avatarType()"
|
|
38024
|
+
(notificationClick)="handleNotificationClick()"
|
|
36760
38025
|
(refresh)="handleRefresh($event)">
|
|
36761
38026
|
|
|
36762
38027
|
<ds-mobile-section contentGap="0px" padding="12px 20px 20px 20px" [showBorder]="false">
|
|
@@ -36815,7 +38080,7 @@ class TenantChatPageComponent {
|
|
|
36815
38080
|
ariaLabel="Vælg beboer at skrive med"
|
|
36816
38081
|
(clicked)="goToTenants()">
|
|
36817
38082
|
</ds-mobile-fab>
|
|
36818
|
-
`, isInline: true, styles: [".empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:64px 20px;text-align:center}.empty-state-image{width:96px;height:96px;margin-bottom:24px;opacity:.4}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;color:var(--color-text-primary);margin:0 0 8px}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);color:var(--color-text-secondary);margin:0}\n"], dependencies: [{ kind: "component", type: DsMobilePageMainComponent, selector: "ds-mobile-page-main", inputs: ["title", "headerTitle", "headerSubtitle", "firstEntry", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileInteractiveListItemMessageComponent, selector: "ds-mobile-interactive-list-item-message", inputs: ["senderName", "senderRole", "timestamp", "message", "avatarInitials", "avatarType", "avatarSrc", "unread", "unreadStyle", "clickable", "align", "showAvatarBadge", "groupStackMembers", "groupCustomAvatarUrl", "groupStackExcludeParticipantId"], outputs: ["messageClick", "longPress"] }, { kind: "component", type: DsMobileFabComponent, selector: "ds-mobile-fab", inputs: ["icon", "position", "size", "ariaLabel", "disabled"], outputs: ["clicked"] }] });
|
|
38083
|
+
`, 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", "showNotification", "notificationCount", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["notificationClick", "avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileInteractiveListItemMessageComponent, selector: "ds-mobile-interactive-list-item-message", inputs: ["senderName", "senderRole", "timestamp", "message", "avatarInitials", "avatarType", "avatarSrc", "unread", "unreadStyle", "clickable", "align", "showAvatarBadge", "groupStackMembers", "groupCustomAvatarUrl", "groupStackExcludeParticipantId"], outputs: ["messageClick", "longPress"] }, { kind: "component", type: DsMobileFabComponent, selector: "ds-mobile-fab", inputs: ["icon", "position", "size", "ariaLabel", "disabled"], outputs: ["clicked"] }] });
|
|
36819
38084
|
}
|
|
36820
38085
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: TenantChatPageComponent, decorators: [{
|
|
36821
38086
|
type: Component,
|
|
@@ -36829,8 +38094,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
36829
38094
|
}, template: `
|
|
36830
38095
|
<ds-mobile-page-main
|
|
36831
38096
|
title="Beskeder"
|
|
38097
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
36832
38098
|
[avatarInitials]="userService.avatarInitials()"
|
|
36833
38099
|
[avatarType]="userService.avatarType()"
|
|
38100
|
+
(notificationClick)="handleNotificationClick()"
|
|
36834
38101
|
(refresh)="handleRefresh($event)">
|
|
36835
38102
|
|
|
36836
38103
|
<ds-mobile-section contentGap="0px" padding="12px 20px 20px 20px" [showBorder]="false">
|
|
@@ -36972,6 +38239,8 @@ const MOCK_VENDORS = [
|
|
|
36972
38239
|
class ServicesPageComponent {
|
|
36973
38240
|
pageComponent;
|
|
36974
38241
|
vendorModal = inject(DsMobileServiceVendorModalService);
|
|
38242
|
+
notificationModal = inject(DsMobileNotificationModalService);
|
|
38243
|
+
notificationService = inject(NotificationService);
|
|
36975
38244
|
newInquiryModal = inject(DsMobileNewInquiryModalService);
|
|
36976
38245
|
inquiriesService = inject(InquiriesService);
|
|
36977
38246
|
navCtrl = inject(NavController);
|
|
@@ -37018,6 +38287,11 @@ class ServicesPageComponent {
|
|
|
37018
38287
|
},
|
|
37019
38288
|
});
|
|
37020
38289
|
}
|
|
38290
|
+
async handleNotificationClick() {
|
|
38291
|
+
const tapped = await this.notificationModal.open();
|
|
38292
|
+
if (tapped)
|
|
38293
|
+
console.log('Notification tapped:', tapped.type, tapped.id);
|
|
38294
|
+
}
|
|
37021
38295
|
handleRefresh(event) {
|
|
37022
38296
|
setTimeout(() => {
|
|
37023
38297
|
event.target?.complete?.();
|
|
@@ -37028,8 +38302,10 @@ class ServicesPageComponent {
|
|
|
37028
38302
|
<ds-mobile-page-main
|
|
37029
38303
|
#pageComponent
|
|
37030
38304
|
[title]="lbl.pageTitle"
|
|
38305
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
37031
38306
|
[avatarInitials]="userService.avatarInitials()"
|
|
37032
38307
|
[avatarType]="userService.avatarType()"
|
|
38308
|
+
(notificationClick)="handleNotificationClick()"
|
|
37033
38309
|
(refresh)="handleRefresh($event)"
|
|
37034
38310
|
>
|
|
37035
38311
|
@if (pageComponent.isOffline()) {
|
|
@@ -37061,7 +38337,7 @@ class ServicesPageComponent {
|
|
|
37061
38337
|
</ds-mobile-section>
|
|
37062
38338
|
}
|
|
37063
38339
|
</ds-mobile-page-main>
|
|
37064
|
-
`, isInline: true, styles: [".empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:40px 20px;text-align:center}.empty-state-title{font-family:Brockmann,sans-serif;font-size:var(--font-size-base);font-weight:600;color:var(--color-text-primary);margin-top:-16px;z-index:4}.empty-state-description{font-family:Brockmann,sans-serif;font-size:var(--font-size-sm);color:var(--color-text-secondary);margin:0}\n"], dependencies: [{ kind: "component", type: DsMobilePageMainComponent, selector: "ds-mobile-page-main", inputs: ["title", "headerTitle", "headerSubtitle", "firstEntry", "avatarType", "avatarInitials", "avatarSrc", "avatarIconName", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileIllustrationComponent, selector: "ds-mobile-illustration", inputs: ["variant", "size", "alt"] }, { kind: "component", type: DsMobileInteractiveListItemServiceComponent, selector: "ds-mobile-interactive-list-item-service", inputs: ["title", "description", "logo", "showChevron"], outputs: ["serviceClick"] }, { kind: "component", type: DsMobileOfflineBannerComponent, selector: "ds-mobile-offline-banner", inputs: ["icon", "title", "message"] }] });
|
|
38340
|
+
`, 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", "showNotification", "notificationCount", "showRefresh", "showCondensedHeader", "scrollThreshold", "headerFadeDistance", "contentPadding", "profileMenuItems"], outputs: ["notificationClick", "avatarClick", "profileActionSelected", "refresh", "scroll"] }, { kind: "component", type: DsMobileSectionComponent, selector: "ds-mobile-section", inputs: ["headline", "icon", "linkText", "padding", "paddingDesktop", "gap", "contentGap", "showBorder", "overflow"], outputs: ["linkClick"] }, { kind: "component", type: DsMobileIllustrationComponent, selector: "ds-mobile-illustration", inputs: ["variant", "size", "alt"] }, { kind: "component", type: DsMobileInteractiveListItemServiceComponent, selector: "ds-mobile-interactive-list-item-service", inputs: ["title", "description", "logo", "showChevron"], outputs: ["serviceClick"] }, { kind: "component", type: DsMobileOfflineBannerComponent, selector: "ds-mobile-offline-banner", inputs: ["icon", "title", "message"] }] });
|
|
37065
38341
|
}
|
|
37066
38342
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: ServicesPageComponent, decorators: [{
|
|
37067
38343
|
type: Component,
|
|
@@ -37075,8 +38351,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
37075
38351
|
<ds-mobile-page-main
|
|
37076
38352
|
#pageComponent
|
|
37077
38353
|
[title]="lbl.pageTitle"
|
|
38354
|
+
[notificationCount]="notificationService.unreadCount()"
|
|
37078
38355
|
[avatarInitials]="userService.avatarInitials()"
|
|
37079
38356
|
[avatarType]="userService.avatarType()"
|
|
38357
|
+
(notificationClick)="handleNotificationClick()"
|
|
37080
38358
|
(refresh)="handleRefresh($event)"
|
|
37081
38359
|
>
|
|
37082
38360
|
@if (pageComponent.isOffline()) {
|
|
@@ -37114,6 +38392,122 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
37114
38392
|
args: ['pageComponent']
|
|
37115
38393
|
}] } });
|
|
37116
38394
|
|
|
38395
|
+
const PREFS = [
|
|
38396
|
+
{ key: 'messages', label: 'Beskeder', description: 'Nye beskeder fra beboere og administration' },
|
|
38397
|
+
{ key: 'bookings', label: 'Bookinger', description: 'Bekræftelser, aflysninger og påmindelser' },
|
|
38398
|
+
{ key: 'community', label: 'Fællesskab', description: 'Opslag, kommentarer og omtaler' },
|
|
38399
|
+
{ key: 'inquiries', label: 'Henvendelser', description: 'Opdateringer på dine henvendelser' },
|
|
38400
|
+
{ key: 'services', label: 'Service', description: 'Opdateringer fra serviceleverandører' },
|
|
38401
|
+
{ key: 'handbook', label: 'Håndbog', description: 'Ændringer i beboerhåndbogen' },
|
|
38402
|
+
{ key: 'system', label: 'System', description: 'Meddelelser, invitationer og familieadgang' },
|
|
38403
|
+
];
|
|
38404
|
+
class SettingsModalComponent {
|
|
38405
|
+
notificationService = inject(NotificationService);
|
|
38406
|
+
prefs = PREFS;
|
|
38407
|
+
enabledSignals = new Map(PREFS.map(p => [p.key, computed(() => this.notificationService.isPushEnabled(p.key))]));
|
|
38408
|
+
isEnabled(key) {
|
|
38409
|
+
return this.enabledSignals.get(key);
|
|
38410
|
+
}
|
|
38411
|
+
toggle(key) {
|
|
38412
|
+
const current = this.notificationService.isPushEnabled(key);
|
|
38413
|
+
this.notificationService.setPushEnabled(key, !current);
|
|
38414
|
+
Haptics.impact({ style: ImpactStyle.Light }).catch(() => {
|
|
38415
|
+
if ('vibrate' in navigator)
|
|
38416
|
+
navigator.vibrate(10);
|
|
38417
|
+
});
|
|
38418
|
+
}
|
|
38419
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: SettingsModalComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
|
|
38420
|
+
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "20.3.16", type: SettingsModalComponent, isStandalone: true, selector: "app-settings-modal", ngImport: i0, template: `
|
|
38421
|
+
<ds-mobile-modal-base headerTitle="Notifikationer" [showHeader]="true">
|
|
38422
|
+
|
|
38423
|
+
<div class="settings-content">
|
|
38424
|
+
@for (pref of prefs; track pref.key; let isFirst = $first; let isLast = $last) {
|
|
38425
|
+
<ds-mobile-list-item
|
|
38426
|
+
[showDivider]="!isLast"
|
|
38427
|
+
[flushTop]="isFirst"
|
|
38428
|
+
[interactive]="true"
|
|
38429
|
+
[enableLongPress]="false"
|
|
38430
|
+
[moreActions]="false"
|
|
38431
|
+
[title]="pref.label"
|
|
38432
|
+
[subtitle]="pref.description"
|
|
38433
|
+
(itemClick)="toggle(pref.key)"
|
|
38434
|
+
>
|
|
38435
|
+
<ds-mobile-toggle
|
|
38436
|
+
content-trailing
|
|
38437
|
+
[checked]="isEnabled(pref.key)()"
|
|
38438
|
+
(changed)="toggle(pref.key)"
|
|
38439
|
+
/>
|
|
38440
|
+
</ds-mobile-list-item>
|
|
38441
|
+
}
|
|
38442
|
+
</div>
|
|
38443
|
+
|
|
38444
|
+
</ds-mobile-modal-base>
|
|
38445
|
+
`, isInline: true, styles: [".settings-content{padding:20px}\n"], dependencies: [{ 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: DsMobileToggleComponent, selector: "ds-mobile-toggle", inputs: ["checked", "disabled"], outputs: ["checkedChange", "changed"] }] });
|
|
38446
|
+
}
|
|
38447
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: SettingsModalComponent, decorators: [{
|
|
38448
|
+
type: Component,
|
|
38449
|
+
args: [{ selector: 'app-settings-modal', standalone: true, imports: [
|
|
38450
|
+
DsMobileModalBaseComponent,
|
|
38451
|
+
DsMobileListItemComponent,
|
|
38452
|
+
DsMobileToggleComponent,
|
|
38453
|
+
], template: `
|
|
38454
|
+
<ds-mobile-modal-base headerTitle="Notifikationer" [showHeader]="true">
|
|
38455
|
+
|
|
38456
|
+
<div class="settings-content">
|
|
38457
|
+
@for (pref of prefs; track pref.key; let isFirst = $first; let isLast = $last) {
|
|
38458
|
+
<ds-mobile-list-item
|
|
38459
|
+
[showDivider]="!isLast"
|
|
38460
|
+
[flushTop]="isFirst"
|
|
38461
|
+
[interactive]="true"
|
|
38462
|
+
[enableLongPress]="false"
|
|
38463
|
+
[moreActions]="false"
|
|
38464
|
+
[title]="pref.label"
|
|
38465
|
+
[subtitle]="pref.description"
|
|
38466
|
+
(itemClick)="toggle(pref.key)"
|
|
38467
|
+
>
|
|
38468
|
+
<ds-mobile-toggle
|
|
38469
|
+
content-trailing
|
|
38470
|
+
[checked]="isEnabled(pref.key)()"
|
|
38471
|
+
(changed)="toggle(pref.key)"
|
|
38472
|
+
/>
|
|
38473
|
+
</ds-mobile-list-item>
|
|
38474
|
+
}
|
|
38475
|
+
</div>
|
|
38476
|
+
|
|
38477
|
+
</ds-mobile-modal-base>
|
|
38478
|
+
`, styles: [".settings-content{padding:20px}\n"] }]
|
|
38479
|
+
}] });
|
|
38480
|
+
|
|
38481
|
+
class SettingsModalService {
|
|
38482
|
+
modalController;
|
|
38483
|
+
constructor(modalController) {
|
|
38484
|
+
this.modalController = modalController;
|
|
38485
|
+
}
|
|
38486
|
+
async open() {
|
|
38487
|
+
const modal = await this.modalController.create({
|
|
38488
|
+
component: SettingsModalComponent,
|
|
38489
|
+
cssClass: 'ds-modal-base',
|
|
38490
|
+
mode: 'ios',
|
|
38491
|
+
presentingElement: document.querySelector('ion-router-outlet') || undefined,
|
|
38492
|
+
backdropDismiss: true,
|
|
38493
|
+
showBackdrop: true,
|
|
38494
|
+
animated: true,
|
|
38495
|
+
});
|
|
38496
|
+
await modal.present();
|
|
38497
|
+
}
|
|
38498
|
+
async close(data) {
|
|
38499
|
+
return this.modalController.dismiss(data);
|
|
38500
|
+
}
|
|
38501
|
+
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: SettingsModalService, deps: [{ token: i1.ModalController }], target: i0.ɵɵFactoryTarget.Injectable });
|
|
38502
|
+
static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: SettingsModalService, providedIn: 'root' });
|
|
38503
|
+
}
|
|
38504
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImport: i0, type: SettingsModalService, decorators: [{
|
|
38505
|
+
type: Injectable,
|
|
38506
|
+
args: [{
|
|
38507
|
+
providedIn: 'root',
|
|
38508
|
+
}]
|
|
38509
|
+
}], ctorParameters: () => [{ type: i1.ModalController }] });
|
|
38510
|
+
|
|
37117
38511
|
/**
|
|
37118
38512
|
* Services Barrel File
|
|
37119
38513
|
*
|
|
@@ -37137,5 +38531,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.3.16", ngImpo
|
|
|
37137
38531
|
* Generated bundle index. Do not edit.
|
|
37138
38532
|
*/
|
|
37139
38533
|
|
|
37140
|
-
export { AcceptInvitePageComponent, ActionCommentComponent, ActionLikeComponent, AvatarUploadPageComponent, BaseModalService, ContentRowComponent, CreateAccountPageComponent, DEFAULT_SERVICE_PAGE_LABELS, DsAppIconComponent, DsAvatarWithBadgeComponent, DsLogoComponent, DsMobileAccessSheetComponent, DsMobileActionListItemComponent, DsMobileActionsBottomSheetComponent, DsMobileAddGroupTenantsModalComponent, DsMobileAppLoadingComponent, DsMobileAttachmentPreviewComponent, DsMobileBookingConfirmationWrapperComponent, DsMobileBookingModalComponent, DsMobileBookingModalService, DsMobileBookingSummaryComponent, DsMobileBottomSheetHeaderComponent, DsMobileBottomSheetService, DsMobileBottomSheetWrapperComponent, DsMobileCapacitySheetComponent, DsMobileCardInlineBannerComponent, DsMobileCardInlineComponent, DsMobileCardInlineContactComponent, DsMobileCardInlineFileComponent, DsMobileChatModalComponent, DsMobileChatModalService, DsMobileActionsBottomSheetComponent as DsMobileCommentActionsBottomSheetComponent, DsMobileCommentComponent, DsMobileCommunityAdminPickerComponent, DsMobileCommunityAdminsModalComponent, DsMobileConfirmationSheetComponent, DsMobileContactListItemComponent, DsMobileContentComponent, DsMobileCreateGroupModalComponent, DsMobileDropdownComponent, DsMobileEditGroupModalComponent, DsMobileEmptyStateComponent, DsMobileFabComponent, DsMobileFacilityArchiveConfirmationComponent, DsMobileFacilityCreationConfirmationWrapperComponent, DsMobileFacilityCreationModalComponent, DsMobileFacilityCreationModalService, DsMobileFacilityDeleteConfirmationComponent, DsMobileFacilityDetailModalComponent, DsMobileFacilityDetailModalService, DsMobileFileAttachmentComponent, DsMobileGlassSpinnerComponent, DsMobileGroupAvatarStackComponent, DsMobileGroupMembersModalComponent, DsMobileHandbookDetailModalComponent, DsMobileHandbookDetailModalService, DsMobileHandbookFolderComponent, DsMobileHandbookFolderMiniComponent, DsMobileHeaderContentComponent, DsMobileHeaderContentTileComponent, DsMobileIllustrationComponent, DsMobileImagePlaceholderComponent, DsMobileInlinePhotoComponent, DsMobileInlineTabsComponent, DsMobileInteractiveListItemBookingComponent, DsMobileInteractiveListItemInquiryComponent, DsMobileInteractiveListItemMessageComponent, DsMobileInteractiveListItemPostComponent, DsMobileLightboxImageComponent as DsMobileLightboxComponent, DsMobileLightboxFooterComponent, DsMobileLightboxHeaderComponent, DsMobileLightboxImageComponent, DsMobileLightboxImageWithDescriptionComponent, DsMobileLightboxPdfComponent, DsMobileLightboxService, DsMobileListItemComponent, DsMobileListItemStaticComponent, DsMobileListSearchComponent, DsMobileLoaderOverlayComponent, DsMobileLongPressDirective, DsMobileMediaActionsPanelComponent, DsMobileMessageBubbleComponent, DsMobileMessageComposerComponent, DsMobileModalBaseComponent, DsMobileModalService, DsMobileNewInquiryModalComponent, DsMobileNewInquiryModalService, DsMobileOfflineBannerComponent, DsMobilePageDetailsComponent, DsMobilePageMainComponent, DsMobilePillComponent, DsMobileActionsBottomSheetComponent as DsMobilePostActionsBottomSheetComponent, DsMobilePostComposerComponent, DsMobilePostCreateBottomSheetComponent, DsMobilePostDetailModalComponent, DsMobilePostDetailModalService, DsMobilePriceSheetComponent, DsMobileProfileActionsSheetComponent, DsMobilePromptBottomSheetComponent, DsMobilePropertyBannerComponent, DsMobileRichTextEditorComponent, DsMobileSectionComponent, DsMobileServiceVendorModalService, DsMobileServiceVendorSheetComponent, DsMobileSwiperComponent, DsMobileSwiperWithNavComponent, DsMobileSystemMessageBannerComponent, DsMobileTabBarComponent, DsMobileTabsComponent, DsMobileTenantPickerModalComponent, DsMobileWhenCanBookSheetComponent, DsMobileWhoCanBookSheetComponent, DsTextInputComponent, FamilyAccessPageComponent, FamilyAccessService, InquiriesService, InviteSuccessPageComponent, MediaPickerService, MobileBookingPageComponent, MobileCommunityPageComponent, MobileHandbookPageComponent, MobileHomePageComponent, MobileInquiriesPageComponent, MobileInquiryDetailPageComponent, MobileModalBase, MobilePageBase, MobilePostDetailPageComponent, MobileTabsExampleComponent, PageLoadingService, PostActionsComponent, PostAttachmentsComponent, PostContentComponent, PostCreatePageComponent, PostMediaComponent, PostPdfAttachmentComponent, PostTextComponent, PostsService, SectionHeaderComponent, ServicesPageComponent, SignInPageComponent, SignInToAcceptPageComponent, TenantChatPageComponent, TileContentComponent, TileIconComponent, TileLabelComponent, TileValueComponent, TrackingPermissionService, UserService, WhitelabelDemoModalComponent, WhitelabelDemoModalService, WhitelabelService, customBackTransition, customPageTransition };
|
|
38534
|
+
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, DsMobileToggleComponent, 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, SettingsModalService, SignInPageComponent, SignInToAcceptPageComponent, TenantChatPageComponent, TileContentComponent, TileIconComponent, TileLabelComponent, TileValueComponent, TrackingPermissionService, UserService, VENDOR_MODAL_SERVICE, WhitelabelDemoModalComponent, WhitelabelDemoModalService, WhitelabelService, customBackTransition, customPageTransition, dateBucket };
|
|
37141
38535
|
//# sourceMappingURL=propbinder-mobile-design.mjs.map
|